From 4fc4cab98d454afbfd0d2f48548b5b481e8e7c82 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Thu, 29 Jul 2010 14:49:10 -0700 Subject: [PATCH] XQuartz: Make application switching work better for the no-spaces case We still have the issue with not raising the frontmost window for the case when spaces is enabled, and the AppleSpacesSwitchOnActivate preference is disabled. Signed-off-by: Jeremy Huddleston --- hw/xquartz/X11Application.m | 28 +++++++++++++++++++++------- hw/xquartz/xpr/xprEvent.c | 2 +- miext/rootless/rootless.h | 4 ++-- miext/rootless/rootlessWindow.c | 12 +++++++++--- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 805ed9933..36c39e50c 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -337,7 +337,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { case NSApplicationActivatedEventType: for_x = NO; if ([self modalWindow] == nil) { - BOOL switch_on_activate, ok; + BOOL order_all_windows = YES, workspaces, ok; for_appkit = NO; /* FIXME: hack to avoid having to pass the event to appkit, @@ -347,13 +347,27 @@ static void message_kit_thread (SEL selector, NSObject *arg) { [self activateX:YES]; /* Get the Spaces preference for SwitchOnActivate */ - (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences")); - switch_on_activate = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok); - if(!ok) - switch_on_activate = YES; + (void)CFPreferencesAppSynchronize(CFSTR("com.apple.dock")); + workspaces = CFPreferencesGetAppBooleanValue(CFSTR("workspaces"), CFSTR("com.apple.dock"), &ok); + if (!ok) + workspaces = NO; + + if (workspaces) { + (void)CFPreferencesAppSynchronize(CFSTR(".GlobalPreferences")); + order_all_windows = CFPreferencesGetAppBooleanValue(CFSTR("AppleSpacesSwitchOnActivate"), CFSTR(".GlobalPreferences"), &ok); + if (!ok) + order_all_windows = YES; + } - if ([e data2] & 0x10 && switch_on_activate) // 0x10 is set when we use cmd-tab or the dock icon - DarwinSendDDXEvent(kXquartzBringAllToFront, 0); + /* TODO: In the workspaces && !AppleSpacesSwitchOnActivate case, the windows are ordered + * correctly, but we need to activate the top window on this space if there is + * none active. + * + * If there are no active windows, and there are minimized windows, we should + * be restoring one of them. + */ + if ([e data2] & 0x10) // 0x10 is set when we use cmd-tab or the dock icon + DarwinSendDDXEvent(kXquartzBringAllToFront, 1, order_all_windows); } break; diff --git a/hw/xquartz/xpr/xprEvent.c b/hw/xquartz/xpr/xprEvent.c index 6245cce42..342b54c53 100644 --- a/hw/xquartz/xpr/xprEvent.c +++ b/hw/xquartz/xpr/xprEvent.c @@ -73,7 +73,7 @@ Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) { case kXquartzBringAllToFront: DEBUG_LOG("kXquartzBringAllToFront\n"); - RootlessOrderAllWindows(); + RootlessOrderAllWindows(e->data[0]); return TRUE; default: return FALSE; diff --git a/miext/rootless/rootless.h b/miext/rootless/rootless.h index 00eac4e8a..dc4213f1e 100644 --- a/miext/rootless/rootless.h +++ b/miext/rootless/rootless.h @@ -444,7 +444,7 @@ void RootlessUpdateScreenPixmap(ScreenPtr pScreen); void RootlessRepositionWindows(ScreenPtr pScreen); /* - * Bring all windows to the front of the Aqua stack + * Bring all windows to the front of the native stack */ -void RootlessOrderAllWindows (void); +void RootlessOrderAllWindows (Bool include_unhitable); #endif /* _ROOTLESS_H */ diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c index bef8a2f98..c1c6bdbfd 100644 --- a/miext/rootless/rootlessWindow.c +++ b/miext/rootless/rootlessWindow.c @@ -581,10 +581,15 @@ RootlessReorderWindow(WindowPtr pWin) RootlessStopDrawing(pWin, FALSE); - /* Find the next window above this one that has a mapped frame. */ + /* Find the next window above this one that has a mapped frame. + * Only include cases where the windows are in the same category of + * hittability to ensure offscreen windows dont get restacked + * relative to onscreen ones (but that the offscreen ones maintain + * their stacking order if they are explicitly asked to Reorder + */ newPrevW = pWin->prevSib; - while (newPrevW && (WINREC(newPrevW) == NULL || !newPrevW->realized)) + while (newPrevW && (WINREC(newPrevW) == NULL || !newPrevW->realized || newPrevW->rootlessUnhittable != pWin->rootlessUnhittable)) newPrevW = newPrevW->prevSib; newPrev = newPrevW != NULL ? WINREC(newPrevW) : NULL; @@ -1502,7 +1507,7 @@ RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width) * (i.e in front of Aqua windows) -- called when X11.app is given focus */ void -RootlessOrderAllWindows (void) +RootlessOrderAllWindows (Bool include_unhitable) { int i; WindowPtr pWin; @@ -1519,6 +1524,7 @@ RootlessOrderAllWindows (void) for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib) { if (!pWin->realized) continue; if (RootlessEnsureFrame(pWin) == NULL) continue; + if (!include_unhitable && pWin->rootlessUnhittable) continue; RootlessReorderWindow (pWin); } }