Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When calling isActive() on window while dragging/resizing it, false returns. (X11, Qt 5.4.0)

Tags:

c++

linux

x11

qt

pyqt

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_()
like image 765
BOOtak Avatar asked Nov 10 '22 17:11

BOOtak


1 Answers

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.

like image 180
JvO Avatar answered Nov 15 '22 04:11

JvO