Skip to content

Commit

Permalink
Hide window and dock icon on macOS when tray enabled.
Browse files Browse the repository at this point in the history
Transforms application into a UIElement agent app when
minimize to tray is enabled and the window is hidden.
This hides the dock icon and removes the application
from the Cmd+Tab listing. The changes work well together
with macOS's inbuilt hide feature.

Also fixes the buggy tray icon context menu trigger behaviour.
macOS triggers the tray context menu also on normal left
click, which causes the window to toggle at the same time
as the menu. To fix this, window toggling has been disabled
altogether on macOS and users will be shown only the context
menu from now on.

Fixes #1334
  • Loading branch information
phoerious committed May 26, 2020
1 parent b17b968 commit 45344bb
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 20 deletions.
47 changes: 28 additions & 19 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,16 @@ void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason)

void MainWindow::processTrayIconTrigger()
{
#ifdef Q_OS_MACOS
// Do not toggle the window on macOS and just show the context menu instead.
// Right click detection doesn't seem to be working anyway
// and anything else will only trigger the context menu AND
// toggle the window at the same time, which is confusing at best.
// Showing only a context menu for tray icons seems to be best
// practice on macOS anyway, so this is probably fine.
return;
#endif

if (m_trayIconTriggerReason == QSystemTrayIcon::DoubleClick) {
// Always toggle window on double click
toggleWindow();
Expand All @@ -1379,7 +1389,7 @@ void MainWindow::processTrayIconTrigger()
// clicking the tray icon removes focus from main window.
if (isHidden() || (Clock::currentMilliSecondsSinceEpoch() - m_lastFocusOutTime) <= 500) {
#else
// If on Linux or macOS, check if the window has focus.
// If on Linux, check if the window has focus.
if (hasFocus() || isHidden() || windowHandle()->isActive()) {
#endif
toggleWindow();
Expand All @@ -1393,41 +1403,40 @@ void MainWindow::show()
{
#ifndef Q_OS_WIN
m_lastShowTime = Clock::currentMilliSecondsSinceEpoch();
#endif
#ifdef Q_OS_MACOS
// Unset minimize state to avoid weird fly-in effects
setWindowState(windowState() & ~Qt::WindowMinimized);
macUtils()->toggleForegroundApp(true);
#endif
QMainWindow::show();
}

bool MainWindow::shouldHide()
void MainWindow::hide()
{
#ifndef Q_OS_WIN
qint64 current_time = Clock::currentMilliSecondsSinceEpoch();

if (current_time - m_lastShowTime < 50) {
return false;
return;
}
#endif
return true;
}

void MainWindow::hide()
{
if (shouldHide()) {
QMainWindow::hide();
}
QMainWindow::hide();
#ifdef Q_OS_MACOS
macUtils()->toggleForegroundApp(false);
#endif
}

void MainWindow::hideWindow()
{
saveWindowInformation();
if (QGuiApplication::platformName() != "xcb") {
// In X11 the window should NOT be minimized and hidden (i.e. not
// shown) at the same time (which would happen if both minimize on
// startup and minimize to tray are set) since otherwise it causes
// problems on restore as seen on issue #1595. Hiding it is enough.
setWindowState(windowState() | Qt::WindowMinimized);
}

// Only hide if tray icon is active, otherwise window will be gone forever
if (isTrayIconEnabled()) {
// On X11, the window should NOT be minimized and hidden at the same time. See issue #1595.
// On macOS, we are skipping minimization as well to avoid playing the magic lamp animation.
if (QGuiApplication::platformName() != "xcb" && QGuiApplication::platformName() != "cocoa") {
setWindowState(windowState() | Qt::WindowMinimized);
}
hide();
} else {
showMinimized();
Expand Down
1 change: 0 additions & 1 deletion src/gui/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ private slots:

static const QString BaseWindowTitle;

bool shouldHide();
void saveWindowInformation();
bool saveLastDatabases();
void updateTrayIcon();
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/macutils/AppKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class AppKit : public QObject
bool isDarkMode();
bool enableAccessibility();
bool enableScreenRecording();
void toggleForegroundApp(bool foreground);

signals:
void lockDatabases();
Expand Down
1 change: 1 addition & 0 deletions src/gui/osutils/macutils/AppKitImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@
- (void) userSwitchHandler:(NSNotification*) notification;
- (bool) enableAccessibility;
- (bool) enableScreenRecording;
- (void) toggleForegroundApp:(bool) foreground;

@end
15 changes: 15 additions & 0 deletions src/gui/osutils/macutils/AppKitImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ - (bool) enableScreenRecording
return YES;
}

- (void) toggleForegroundApp:(bool) foreground
{
ProcessSerialNumber psn = {0, kCurrentProcess};
if (foreground) {
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
} else {
TransformProcessType(&psn, kProcessTransformToUIElementApplication);
}
}

@end

//
Expand Down Expand Up @@ -215,3 +225,8 @@ - (bool) enableScreenRecording
{
return [static_cast<id>(self) enableScreenRecording];
}

void AppKit::toggleForegroundApp(bool foreground)
{
[static_cast<id>(self) toggleForegroundApp:foreground];
}
11 changes: 11 additions & 0 deletions src/gui/osutils/macutils/MacUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,14 @@ bool MacUtils::isCapslockEnabled()
{
return (CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState) & kCGEventFlagMaskAlphaShift) != 0;
}

/**
* Toggle application state between foreground app and UIElement app.
* Foreground apps have dock icons, UIElement apps do not.
*
* @param foreground whether app is foreground app
*/
void MacUtils::toggleForegroundApp(bool foreground)
{
m_appkit->toggleForegroundApp(foreground);
}
1 change: 1 addition & 0 deletions src/gui/osutils/macutils/MacUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MacUtils : public OSUtilsBase
bool isHidden();
bool enableAccessibility();
bool enableScreenRecording();
void toggleForegroundApp(bool foreground);

signals:
void lockDatabases();
Expand Down

0 comments on commit 45344bb

Please sign in to comment.