Fix macOS bug where tray window causes spaces to switch
authorBrian Kendall <brian@briankendall.net>
Mon, 30 Nov 2020 18:24:41 +0000 (13:24 -0500)
committerKevin Ottens (Rebase PR Action) <er-vin@users.noreply.github.com>
Wed, 2 Dec 2020 06:54:16 +0000 (06:54 +0000)
Signed-off-by: Brian Kendall <brian@briankendall.net>
src/gui/systray.cpp
src/gui/systray.h
src/gui/systray.mm

index 7e5c0bb314d2b6bf4c6c826a63c9d483617f3dd9..422c41b88a5db98141164e51d1086a5ff6720e8e 100644 (file)
@@ -267,6 +267,14 @@ void Systray::forceWindowInit(QQuickWindow *window) const
     // this shouldn't flicker
     window->show();
     window->hide();
+    
+#ifdef Q_OS_MAC
+    // On macOS we need to designate the tray window as visible on all spaces and
+    // at the menu bar level, otherwise showing it can cause the current spaces to
+    // change, or the window could be obscured by another window that shouldn't
+    // normally cover a menu.
+    OCC::setTrayWindowLevelAndVisibleOnAllSpaces(window);
+#endif
 }
 
 QScreen *Systray::currentScreen() const
index 13f79ed01bd46c9d7e1a6279807d77a6b3052cc7..df15154ba006b63a37168513a2fb55429436c66e 100644 (file)
 class QScreen;
 class QQmlApplicationEngine;
 class QQuickWindow;
+class QWindow;
 
 namespace OCC {
 
 #ifdef Q_OS_OSX
 bool canOsXSendUserNotification();
 void sendOsXUserNotification(const QString &title, const QString &message);
+void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window);
 #endif
 
 /**
index 95e0a11a73094c59c20c203c400a08236eeb6bbf..a4d35eb23773005697034b72842bc917eba7ee38 100644 (file)
@@ -1,4 +1,5 @@
 #include <QString>
+#include <QWindow>
 #import <Cocoa/Cocoa.h>
 
 @interface NotificationCenterDelegate : NSObject
@@ -41,4 +42,13 @@ void sendOsXUserNotification(const QString &title, const QString &message)
     [notification release];
 }
 
+void setTrayWindowLevelAndVisibleOnAllSpaces(QWindow *window)
+{
+    NSView *nativeView = (NSView *)window->winId();
+    NSWindow *nativeWindow = (NSWindow *)[nativeView window];
+    [nativeWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorIgnoresCycle |
+                  NSWindowCollectionBehaviorTransient];
+    [nativeWindow setLevel:NSMainMenuWindowLevel];
+}
+
 }