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