pythonpyqtvirtual-desktopmate-desktop

QMainWindow visibility issue when switching virtual desktop


My application has a QSystemTrayIcon that toggles the QMainWindow visibility when left-clicked.

   def tray_icon_activated_cb(reason):
        if reason == QtWidgets.QSystemTrayIcon.Trigger:
            self.main_window.setVisible(not self.main_window.isVisible())
    self.activated.connect(tray_icon_activated_cb)

It works correctly, except if I switch virtual desktop while the QMainWindow is visible.

For instance:

On virtual desktop 1, window hidden
Click
On virtual desktop 1, window visible
Click
On virtual desktop 1, window hidden
Change desktop
On virtual desktop 2, window hidden
Click
On virtual desktop 2, window visible
Click
On virtual desktop 2, window hidden
Change desktop
On virtual desktop 1, window hidden
Click
On virtual desktop 1, window visible
Change desktop
On virtual desktop 2, window hidden
Click
On virtual desktop 2, window hidden  <- wrong
Change desktop
On virtual desktop 1, window hidden
Click
On virtual desktop 1, window hidden  <-- still wrong

I only get the QMainWindow back by restarting the application.

I added prints in method above and could check that we go through

self.main_window.setVisible(not self.main_window.isVisible())

because self.main_window.isVisible() returns True and False alternatively.

I just don't know where that QMainWindow is visible.

Debian Stretch, Mate 1.16.2, Python 3.5.3. I can reproduce with both PyQt4 and PyQt5.


Solution

  • It appears the window is minimized when hidden then shown from another desktop, but I could not see that because it does not appear in the taskbar, as it has following flags:

    self.setWindowFlags(QtCore.Qt.Tool |
                        QtCore.Qt.FramelessWindowHint |
                        QtCore.Qt.WindowStaysOnTopHint)
    

    I fixed the issue by unminimizing it explicitly on show event:

    def showEvent(self, event):
        super().showEvent(event)
        # Ensure the window is not minimized on virtual desktop change
        self.showNormal()