From 1c7a2ba33b8601ee2758a55f97f40d10bbc35a5d Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Wed, 24 Apr 2013 16:10:10 -0500 Subject: [PATCH] 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 e89dee5004..65d7bc5856 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 bdbe8d177f..aec7a02635 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 2c0ee9d2eb..39f229dde6 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 b45e3118b4..dc0f99b7c5 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 987aa348d8..3353749399 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); -- 2.32.0.93.g670b81a890