Weird behavior of QT windows on Linux
-
I have a main window (QMainWindow) which has a child widget (QDialog) and a window (another QDialog) on top of them (without a parent). When I hit the Minimize button on the first widget, the widget is minimized together with the main window (like it was modal). If I then close the second widget, the main window is restored
This happens only when the second widget is visible and only on Linux. I tested it with two window managers (IceWM and openbox) -- the behavior is the same. On Windows only the widget is minimized (as should be)
So the issue seems to be X related
-
In the sample code below the widgets are shown by first double-clicking on the main window and then double-clicking on the dialog itself
main.cpp
#include "main_window.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); }
main_window.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "dialog.h" class MainWindow : public QMainWindow { Q_OBJECT public: WindowDialog *first; MainWindow(QWidget *parent = nullptr); protected slots: void mouseDoubleClickEvent(QMouseEvent*); }; #endif // MAINWINDOW_H
main_window.cpp
#include "main_window.h" void MainWindow::mouseDoubleClickEvent(QMouseEvent *event) { if (first == 0) { first = new WindowDialog(this); first->setMinimumSize(300, 200); first->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); first->setWindowTitle("First dialog"); first->show(); } else { if (first->isHidden() || first->isMinimized()) { first->setWindowState(Qt::WindowState::WindowActive); first->show(); first->activateWindow(); } } } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { first = 0; showMaximized(); }
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> class WindowDialog : public QDialog { Q_OBJECT public: WindowDialog *final; explicit WindowDialog(QWidget *parent = nullptr); signals: protected slots: void mouseDoubleClickEvent(QMouseEvent*); }; #endif // DIALOG_H
dialog.cpp
#include "dialog.h" void WindowDialog::mouseDoubleClickEvent(QMouseEvent *event) { if (final == 0) { final = new WindowDialog(); // no parent final->setMaximumSize(200, 100); final->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); final->setWindowTitle("Next dialog"); final->show(); } else { if (final->isHidden() || final->isMinimized()) { final->setWindowState(Qt::WindowState::WindowActive); final->show(); final->activateWindow(); } } } WindowDialog::WindowDialog(QWidget *parent) : QDialog{parent} { final = 0; }
-
So how can I correct this behavior?
Put simply, the first widget (a child of MainWindow) shouldn't be on top of other windows (other than the main window) and the main window shouldn't get minimized along with it. It's okay if the child is minimized with the parent, but not the other way around
-
So how can I correct this behavior?
Put simply, the first widget (a child of MainWindow) shouldn't be on top of other windows (other than the main window) and the main window shouldn't get minimized along with it. It's okay if the child is minimized with the parent, but not the other way around
-
I have a main window (QMainWindow) which has a child widget (QDialog) and a window (another QDialog) on top of them (without a parent). When I hit the Minimize button on the first widget, the widget is minimized together with the main window (like it was modal). If I then close the second widget, the main window is restored
This happens only when the second widget is visible and only on Linux. I tested it with two window managers (IceWM and openbox) -- the behavior is the same. On Windows only the widget is minimized (as should be)
So the issue seems to be X related
@deisik said in Weird behavior of QT windows on Linux:
So the issue seems to be X related
Your somewhat unorthodox code works just fine here on Kubuntu 22.04, Qt 6.8, and
vendor string: The X.Org Foundation vendor release number: 12101011 X.Org version: 21.1.11
So this is either a windows manager difference or that you are not actually using X11 but Wayland.
-
Can you reproduce the weird/incorrect behavior also when not messing around with WindowStates and WindowFlags?!
Maybe it's related to that -
I'm not sure what you mean by "messing around with WindowStates and WindowFlags"
Anyway, it's not related to that
@deisik said in Weird behavior of QT windows on Linux:
I'm not sure what you mean by "messing around with WindowStates and WindowFlags"
Setting states manually in combination with the
show()
,hide()
, etc API function might break something on certain systems, but if it works the same... just an idea...As @ChrisW67 pointed out, are you sure that you don't use Wayland?!
The behavior you describe would fit in there. -
@deisik said in Weird behavior of QT windows on Linux:
So the issue seems to be X related
Your somewhat unorthodox code works just fine here on Kubuntu 22.04, Qt 6.8, and
vendor string: The X.Org Foundation vendor release number: 12101011 X.Org version: 21.1.11
So this is either a windows manager difference or that you are not actually using X11 but Wayland.
-
@deisik said in Weird behavior of QT windows on Linux:
I'm not sure what you mean by "messing around with WindowStates and WindowFlags"
Setting states manually in combination with the
show()
,hide()
, etc API function might break something on certain systems, but if it works the same... just an idea...As @ChrisW67 pointed out, are you sure that you don't use Wayland?!
The behavior you describe would fit in there.They are for convenience only, and they are irrelevant
But I found something else
The main window goes down together with its child only if the second dialog has focus AND I click on the minimize button of the first dialog (a child of the main window)
If I, on the hand, first click on the main window (so that it gets focus) and then minimize its child, only the child gets minimized
It feels like the minimize event is being processed by the main window in the first case, and then both the parent and the child are minimized (which is a correct behavior)
-
Regardless, the idea is to have a window which is always above the main window and at the same time always below all other windows (the emphasis on always here)
@deisik said in Weird behavior of QT windows on Linux:
the idea is to have a window which is always above the main window and at the same time always below all other windows other than the main window (the emphasis on always here)
Why not create some sort of overlay directly for your
QMainWindow
? -
@deisik said in Weird behavior of QT windows on Linux:
the idea is to have a window which is always above the main window and at the same time always below all other windows other than the main window (the emphasis on always here)
Why not create some sort of overlay directly for your
QMainWindow
?