I'm using Qt 5.4.0 on linux (X11) and I need to determine, if my window is active. So, I wrote example code, given below. If that code compiled on windows, it logs "false" in console only when window isn't really active. But on linux (X11), it also logs "false" when I start to drag or resize window. Why this happen and how to fix that on linux? I want to know, when my window is really inactive, and when it's active, but being dragged/resized.
code snippet (C++):
void MainWindow::changeEvent(QEvent *e) {
if (e->type() == QEvent::ActivationChange) {
if (this->isActiveWindow()) {
std::cout << "True" << std::endl;
} else {
std::cout << "False" << std::endl;
}
}
}
same code, on PyQt5:
import sys
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import QWidget, QApplication
class TransparentWidget(QWidget):
def __init__(self):
super(TransparentWidget, self).__init__()
def changeEvent(self, e):
if e.type() == QEvent.ActivationChange:
print(self.isActiveWindow())
if __name__ == '__main__':
app = QApplication(sys.argv)
transparent_widget = TransparentWidget()
transparent_widget.show()
app.exec_()
It probably registers 'false' because on X the window you see is actually two windows: the window where you paint your contents and a slighly larger window, which is the parent window of yours and contains the border.
The reason is that X11 doesn't have a concept of a "decorated border" with close/max/min buttons, titlebar, nice gradient colors, rounded borders etc. (native X11 windows can have a border, but only as a solid color or texture). Those controls are provided by your window manager. What happens is that if you create a window, the window manager creates an extra X11 window which is slightly larger than yours and places your window as a child on this new window. From then on, the two windows are intimately linked: resizing your window will resize the parent window and vice versa.
This is all handled by the window manager. For example, if you want to resize the window and click on the border, the click goes not to your window but to the window manager, which then determines where the click was and decides what to do with it. So at that moment your own window is not active anymore, which explains why isActiveWindow() returns false.
With Microsoft Windows the border is an integral part of the window itself, so that's why it remains 'active'.
Anyway, to find out if your window is 'active' or not, you should use the QFocusEvent. By looking at the gotFocus() and lostFocus() values you should be able to track when you window is active or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With