Ken Thomases : winemac: If an app opens a window shortly after its systray icon is clicked, activate it.

Alexandre Julliard julliard at winehq.org
Thu Apr 25 14:25:18 CDT 2013


Module: wine
Branch: master
Commit: 1c7a2ba33b8601ee2758a55f97f40d10bbc35a5d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1c7a2ba33b8601ee2758a55f97f40d10bbc35a5d

Author: Ken Thomases <ken at codeweavers.com>
Date:   Wed Apr 24 16:10:10 2013 -0500

winemac: If an app opens a window shortly after its systray icon is clicked, activate it.

The Mac driver doesn't normally steal focus, but a click on the systray icon
counts as the user giving permission.

---

 dlls/winemac.drv/cocoa_window.m |    8 +++++---
 dlls/winemac.drv/macdrv.h       |    1 +
 dlls/winemac.drv/macdrv_cocoa.h |    2 +-
 dlls/winemac.drv/systray.c      |    8 ++++++++
 dlls/winemac.drv/window.c       |   10 +++++++++-
 5 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index e89dee5..65d7bc5 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -856,7 +856,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         macdrv_release_event(event);
     }
 
-    - (void) makeFocused
+    - (void) makeFocused:(BOOL)activate
     {
         WineApplicationController* controller = [WineApplicationController sharedController];
         NSArray* screens;
@@ -889,6 +889,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             if (front && [front levelWhenActive] > [self levelWhenActive])
                 [self setLevelWhenActive:[front levelWhenActive]];
         }
+        if (activate)
+            [NSApp activateIgnoringOtherApps:YES];
         [self orderFront:nil];
         [controller wineWindow:self ordered:NSWindowAbove relativeTo:nil];
         causing_becomeKeyWindow = TRUE;
@@ -1804,12 +1806,12 @@ void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha)
  * orders it front and, if its frame was not within the desktop bounds,
  * Cocoa will typically move it on-screen.
  */
-void macdrv_give_cocoa_window_focus(macdrv_window w)
+void macdrv_give_cocoa_window_focus(macdrv_window w, int activate)
 {
     WineWindow* window = (WineWindow*)w;
 
     OnMainThread(^{
-        [window makeFocused];
+        [window makeFocused:activate];
     });
 }
 
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index bdbe8d1..aec7a02 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -88,6 +88,7 @@ enum macdrv_window_messages
     WM_MACDRV_UPDATE_DESKTOP_RECT,
     WM_MACDRV_RESET_DEVICE_METRICS,
     WM_MACDRV_DISPLAYCHANGE,
+    WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS,
 };
 
 struct macdrv_thread_data
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index 2c0ee9d..39f229d 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -353,7 +353,7 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
                                         CGFloat keyBlue) DECLSPEC_HIDDEN;
 extern void macdrv_clear_window_color_key(macdrv_window w) DECLSPEC_HIDDEN;
 extern void macdrv_window_use_per_pixel_alpha(macdrv_window w, int use_per_pixel_alpha) DECLSPEC_HIDDEN;
-extern void macdrv_give_cocoa_window_focus(macdrv_window w) DECLSPEC_HIDDEN;
+extern void macdrv_give_cocoa_window_focus(macdrv_window w, int activate) DECLSPEC_HIDDEN;
 extern macdrv_view macdrv_create_view(macdrv_window w, CGRect rect) DECLSPEC_HIDDEN;
 extern void macdrv_dispose_view(macdrv_view v) DECLSPEC_HIDDEN;
 extern void macdrv_set_view_window_and_frame(macdrv_view v, macdrv_window w, CGRect rect) DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/systray.c b/dlls/winemac.drv/systray.c
index b45e311..dc0f99b 100644
--- a/dlls/winemac.drv/systray.c
+++ b/dlls/winemac.drv/systray.c
@@ -325,6 +325,14 @@ void macdrv_status_item_clicked(const macdrv_event *event)
         {
             UINT down;
 
+            if (!SendMessageW(icon->owner, WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS, 0, 0) &&
+                GetLastError() == ERROR_INVALID_WINDOW_HANDLE)
+            {
+                WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id);
+                delete_icon(icon);
+                return;
+            }
+
             if (event->status_item_clicked.count == 1)
             {
                 down = WM_LBUTTONDOWN;
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c
index 987aa34..3353749 100644
--- a/dlls/winemac.drv/window.c
+++ b/dlls/winemac.drv/window.c
@@ -42,6 +42,8 @@ static CRITICAL_SECTION win_data_section = { &critsect_debug, -1, 0, 0, 0, 0 };
 
 static CFMutableDictionaryRef win_datas;
 
+DWORD activate_on_focus_time;
+
 
 void CDECL macdrv_SetFocus(HWND hwnd);
 
@@ -855,8 +857,9 @@ void CDECL macdrv_SetFocus(HWND hwnd)
 
     if (data->cocoa_window && data->on_screen)
     {
+        BOOL activate = activate_on_focus_time && (GetTickCount() - activate_on_focus_time < 2000);
         /* Set Mac focus */
-        macdrv_give_cocoa_window_focus(data->cocoa_window);
+        macdrv_give_cocoa_window_focus(data->cocoa_window, activate);
     }
 
     release_win_data(data);
@@ -1226,6 +1229,11 @@ LRESULT CDECL macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
         }
         SendMessageW(hwnd, WM_DISPLAYCHANGE, wp, lp);
         return 0;
+    case WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS:
+        activate_on_focus_time = GetTickCount();
+        if (!activate_on_focus_time) activate_on_focus_time = 1;
+        TRACE("WM_MACDRV_ACTIVATE_ON_FOLLOWING_FOCUS time %u\n", activate_on_focus_time);
+        break;
     }
 
     FIXME("unrecognized window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp);




More information about the wine-cvs mailing list