=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: winemac.drv: Implement systray version 1-4 notifications.

Alexandre Julliard julliard at winehq.org
Thu May 11 15:07:29 CDT 2017


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Thu May 11 13:34:59 2017 -0500

winemac.drv: Implement systray version 1-4 notifications.

Signed-off-by: Ken Thomases <ken at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 c38dc51..23d7805 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 3ffeb01..c4d3a53 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 16d2e6c..9351d77 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;
         }
     }




More information about the wine-cvs mailing list