From 7003ec34c9578bf90f9198b3d8dc64ec65d2b249 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Thu, 11 May 2017 13:34:59 -0500 Subject: [PATCH] winemac.drv: Implement systray version 1-4 notifications. Signed-off-by: Ken Thomases Signed-off-by: Alexandre Julliard --- dlls/winemac.drv/cocoa_status_item.m | 11 +++++++ dlls/winemac.drv/macdrv_cocoa.h | 4 +++ dlls/winemac.drv/systray.c | 60 ++++++++++++++++++++++++++---------- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/dlls/winemac.drv/cocoa_status_item.m b/dlls/winemac.drv/cocoa_status_item.m index c38dc51a93d..23d78059585 100644 --- a/dlls/winemac.drv/cocoa_status_item.m +++ b/dlls/winemac.drv/cocoa_status_item.m @@ -110,12 +110,17 @@ { macdrv_event* event; NSUInteger typeMask = NSEventMaskFromType([nsevent type]); + CGPoint point = CGEventGetLocation([nsevent CGEvent]); + + point = cgpoint_win_from_mac(point); event = macdrv_create_event(STATUS_ITEM_MOUSE_BUTTON, nil); event->status_item_mouse_button.item = (macdrv_status_item)self; event->status_item_mouse_button.button = [nsevent buttonNumber]; event->status_item_mouse_button.down = (typeMask & (NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask)) != 0; event->status_item_mouse_button.count = [nsevent clickCount]; + event->status_item_mouse_button.x = floor(point.x); + event->status_item_mouse_button.y = floor(point.y); [queue postEvent:event]; macdrv_release_event(event); } @@ -164,8 +169,14 @@ - (void) mouseMoved:(NSEvent*)nsevent { macdrv_event* event; + CGPoint point = CGEventGetLocation([nsevent CGEvent]); + + point = cgpoint_win_from_mac(point); + event = macdrv_create_event(STATUS_ITEM_MOUSE_MOVE, nil); event->status_item_mouse_move.item = (macdrv_status_item)self; + event->status_item_mouse_move.x = floor(point.x); + event->status_item_mouse_move.y = floor(point.y); [queue postEvent:event]; macdrv_release_event(event); } diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 3ffeb018717..c4d3a53713e 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -371,9 +371,13 @@ typedef struct macdrv_event { int button; int down; int count; + int x; + int y; } status_item_mouse_button; struct { macdrv_status_item item; + int x; + int y; } status_item_mouse_move; struct { int no_activate; diff --git a/dlls/winemac.drv/systray.c b/dlls/winemac.drv/systray.c index 16d2e6c0fa8..9351d7796f5 100644 --- a/dlls/winemac.drv/systray.c +++ b/dlls/winemac.drv/systray.c @@ -46,6 +46,7 @@ struct tray_icon WCHAR tiptext[128]; /* tooltip text */ DWORD state; /* state flags */ macdrv_status_item status_item; + UINT version; }; static struct list icon_list = LIST_INIT(icon_list); @@ -263,6 +264,13 @@ int CDECL wine_notify_icon(DWORD msg, NOTIFYICONDATAW *data) case 0xdead: /* Wine extension: owner window has died */ cleanup_icons(data->hWnd); break; + case NIM_SETVERSION: + if ((icon = get_icon(data->hWnd, data->uID))) + { + icon->version = data->uVersion; + ret = TRUE; + } + break; default: FIXME("unhandled tray message: %u\n", msg); break; @@ -270,6 +278,27 @@ int CDECL wine_notify_icon(DWORD msg, NOTIFYICONDATAW *data) return ret; } +static BOOL notify_owner(struct tray_icon *icon, UINT msg, int x, int y) +{ + WPARAM wp = icon->id; + LPARAM lp = msg; + + if (icon->version >= NOTIFY_VERSION_4) + { + wp = MAKEWPARAM(x, y); + lp = MAKELPARAM(msg, icon->id); + } + + TRACE("posting msg 0x%04x to hwnd %p id 0x%x\n", msg, icon->owner, icon->id); + if (!PostMessageW(icon->owner, icon->callback_message, wp, lp) && + (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) + { + WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id); + delete_icon(icon); + return FALSE; + } + return TRUE; +} /*********************************************************************** * macdrv_status_item_mouse_button @@ -280,9 +309,10 @@ void macdrv_status_item_mouse_button(const macdrv_event *event) { struct tray_icon *icon; - TRACE("item %p button %d down %d count %d\n", event->status_item_mouse_button.item, + TRACE("item %p button %d down %d count %d pos %d,%d\n", event->status_item_mouse_button.item, event->status_item_mouse_button.button, event->status_item_mouse_button.down, - event->status_item_mouse_button.count); + event->status_item_mouse_button.count, event->status_item_mouse_button.x, + event->status_item_mouse_button.y); LIST_FOR_EACH_ENTRY(icon, &icon_list, struct tray_icon, entry) { @@ -313,13 +343,15 @@ void macdrv_status_item_mouse_button(const macdrv_event *event) return; } - TRACE("posting msg 0x%04x to hwnd %p id 0x%x\n", msg, icon->owner, icon->id); - if (!PostMessageW(icon->owner, icon->callback_message, icon->id, msg) && - GetLastError() == ERROR_INVALID_WINDOW_HANDLE) - { - WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id); - delete_icon(icon); + if (!notify_owner(icon, msg, event->status_item_mouse_button.x, event->status_item_mouse_button.y)) return; + + if (icon->version) + { + if (msg == WM_LBUTTONUP) + notify_owner(icon, NIN_SELECT, event->status_item_mouse_button.x, event->status_item_mouse_button.y); + else if (msg == WM_RBUTTONUP) + notify_owner(icon, WM_CONTEXTMENU, event->status_item_mouse_button.x, event->status_item_mouse_button.y); } break; @@ -337,20 +369,14 @@ void macdrv_status_item_mouse_move(const macdrv_event *event) { struct tray_icon *icon; - TRACE("item %p\n", event->status_item_mouse_move.item); + TRACE("item %p pos %d,%d\n", event->status_item_mouse_move.item, + event->status_item_mouse_move.x, event->status_item_mouse_move.y); LIST_FOR_EACH_ENTRY(icon, &icon_list, struct tray_icon, entry) { if (icon->status_item == event->status_item_mouse_move.item) { - if (!PostMessageW(icon->owner, icon->callback_message, icon->id, WM_MOUSEMOVE) && - GetLastError() == ERROR_INVALID_WINDOW_HANDLE) - { - WARN("window %p was destroyed, removing icon 0x%x\n", icon->owner, icon->id); - delete_icon(icon); - return; - } - + notify_owner(icon, WM_MOUSEMOVE, event->status_item_mouse_move.x, event->status_item_mouse_move.y); break; } } -- 2.11.4.GIT