The point here is to make the default implementation close to winex11, supporting a standalone systray window, and then refactor the interface to remove the duplicated code from the user drivers.
-- v2: explorer: Display the individual systray icon windows. explorer: Create individual windows for the systray icons. explorer: Split systray add/remove from show/hide_icon. explorer: Remove unnecessary displayed icon array.
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/systray.c | 49 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index 6253b65cf35..cf1457eca43 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -93,9 +93,7 @@ static struct list taskbar_buttons = LIST_INIT( taskbar_buttons );
static HWND tray_window;
-static unsigned int alloc_displayed; static unsigned int nb_displayed; -static struct icon **displayed; /* array of currently displayed icons */
static BOOL hide_systray, enable_shell; static int icon_cx, icon_cy, tray_width, tray_height; @@ -298,10 +296,16 @@ static void update_tooltip_position( struct icon *icon ) /* find the icon located at a certain point in the tray window */ static struct icon *icon_from_point( int x, int y ) { - if (y < 0 || y >= icon_cy) return NULL; - x = tray_width - x; - if (x < 0 || x >= icon_cx * nb_displayed) return NULL; - return displayed[x / icon_cx]; + struct icon *icon; + POINT pt = {x, y}; + + LIST_FOR_EACH_ENTRY(icon, &icon_list, struct icon, entry) + { + RECT rect = get_icon_rect( icon ); + if (PtInRect(&rect, pt)) return icon; + } + + return NULL; }
/* invalidate the portion of the tray window that contains the specified icons */ @@ -323,17 +327,7 @@ static BOOL show_icon(struct icon *icon)
if (icon->display != -1) return TRUE; /* already displayed */
- if (nb_displayed >= alloc_displayed) - { - unsigned int new_count = max( alloc_displayed * 2, 32 ); - struct icon **ptr; - if (!(ptr = realloc( displayed, new_count * sizeof(*ptr) ))) return FALSE; - displayed = ptr; - alloc_displayed = new_count; - } - - icon->display = nb_displayed; - displayed[nb_displayed++] = icon; + icon->display = nb_displayed++; update_tooltip_position( icon ); invalidate_icons( nb_displayed-1, nb_displayed-1 );
@@ -347,18 +341,19 @@ static BOOL show_icon(struct icon *icon) /* make an icon invisible */ static BOOL hide_icon(struct icon *icon) { - unsigned int i; + struct icon *ptr;
TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner );
if (icon->display == -1) return TRUE; /* already hidden */
assert( nb_displayed ); - for (i = icon->display; i < nb_displayed - 1; i++) + LIST_FOR_EACH_ENTRY( ptr, &icon_list, struct icon, entry ) { - displayed[i] = displayed[i + 1]; - displayed[i]->display = i; - update_tooltip_position( displayed[i] ); + if (ptr == icon) continue; + if (ptr->display < icon->display) continue; + ptr->display--; + update_tooltip_position( ptr ); } nb_displayed--; invalidate_icons( icon->display, nb_displayed ); @@ -786,16 +781,16 @@ static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
case WM_PAINT: { - unsigned int i; + struct icon *icon; PAINTSTRUCT ps; HDC hdc;
hdc = BeginPaint( hwnd, &ps ); - for (i = 0; i < nb_displayed; i++) + LIST_FOR_EACH_ENTRY( icon, &icon_list, struct icon, entry ) { - RECT dummy, rect = get_icon_rect( displayed[i] ); - if (IntersectRect( &dummy, &rect, &ps.rcPaint )) - DrawIconEx( hdc, rect.left + ICON_BORDER, rect.top + ICON_BORDER, displayed[i]->image, + RECT dummy, rect = get_icon_rect( icon ); + if (icon->display != -1 && IntersectRect( &dummy, &rect, &ps.rcPaint )) + DrawIconEx( hdc, rect.left + ICON_BORDER, rect.top + ICON_BORDER, icon->image, icon_cx - 2*ICON_BORDER, icon_cy - 2*ICON_BORDER, 0, 0, DI_DEFAULTSIZE|DI_NORMAL); }
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/systray.c | 54 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index cf1457eca43..8a1b6a8ea3c 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -320,32 +320,24 @@ static void invalidate_icons( unsigned int start, unsigned int end ) InvalidateRect( tray_window, &rect, TRUE ); }
-/* make an icon visible */ -static BOOL show_icon(struct icon *icon) +/* add an icon to the system tray window */ +static void systray_add_icon( struct icon *icon ) { - TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner ); - - if (icon->display != -1) return TRUE; /* already displayed */ + if (icon->display != -1) return; /* already added */
icon->display = nb_displayed++; - update_tooltip_position( icon ); - invalidate_icons( nb_displayed-1, nb_displayed-1 ); + invalidate_icons( icon->display, icon->display );
if (nb_displayed == 1 && !hide_systray) do_show_systray(); - - create_tooltip(icon); - update_balloon( icon ); - return TRUE; + TRACE( "added %u now %d icons\n", icon->id, nb_displayed ); }
-/* make an icon invisible */ -static BOOL hide_icon(struct icon *icon) +/* remove an icon from the stand-alone tray */ +static void systray_remove_icon( struct icon *icon ) { struct icon *ptr;
- TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner ); - - if (icon->display == -1) return TRUE; /* already hidden */ + if (icon->display == -1) return; /* already removed */
assert( nb_displayed ); LIST_FOR_EACH_ENTRY( ptr, &icon_list, struct icon, entry ) @@ -355,11 +347,37 @@ static BOOL hide_icon(struct icon *icon) ptr->display--; update_tooltip_position( ptr ); } - nb_displayed--; + + if (!--nb_displayed && !enable_shell) do_hide_systray(); + TRACE( "removed %u now %d icons\n", icon->id, nb_displayed ); + invalidate_icons( icon->display, nb_displayed ); icon->display = -1; +} + +/* make an icon visible */ +static BOOL show_icon(struct icon *icon) +{ + TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner ); + + if (icon->display != -1) return TRUE; /* already displayed */ + + systray_add_icon( icon ); + + update_tooltip_position( icon ); + create_tooltip( icon ); + update_balloon( icon ); + return TRUE; +} + +/* make an icon invisible */ +static BOOL hide_icon(struct icon *icon) +{ + TRACE( "id=0x%x, hwnd=%p\n", icon->id, icon->owner ); + + if (icon->display == -1) return TRUE; /* already hidden */
- if (!nb_displayed && !enable_shell) do_hide_systray(); + systray_remove_icon( icon );
update_balloon( icon ); update_tooltip_position( icon );
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/systray.c | 99 ++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 19 deletions(-)
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index 8a1b6a8ea3c..a36aa101525 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -64,6 +64,7 @@ struct icon struct list entry; HICON image; /* the image to render */ HWND owner; /* the HWND passed in to the Shell_NotifyIcon call */ + HWND window; /* the adaptor window */ HWND tooltip; /* Icon tooltip */ UINT state; /* state flags */ UINT id; /* the unique id given by the app */ @@ -115,6 +116,25 @@ static HWND balloon_window;
#define WM_POPUPSYSTEMMENU 0x0313
+static LRESULT WINAPI shell_traywnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); +static LRESULT WINAPI tray_icon_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); + +static WNDCLASSEXW shell_traywnd_class = +{ + .cbSize = sizeof(WNDCLASSEXW), + .style = CS_DBLCLKS | CS_HREDRAW, + .lpfnWndProc = shell_traywnd_proc, + .hbrBackground = (HBRUSH)COLOR_WINDOW, + .lpszClassName = L"Shell_TrayWnd", +}; +static WNDCLASSEXW tray_icon_class = +{ + .cbSize = sizeof(WNDCLASSEXW), + .style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, + .lpfnWndProc = tray_icon_wndproc, + .lpszClassName = L"__wine_tray_icon", +}; + static void do_hide_systray(void); static void do_show_systray(void);
@@ -280,6 +300,13 @@ static void update_tooltip_text(struct icon *icon) SendMessageW(icon->tooltip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti); }
+/* get the position of an icon in the stand-alone tray */ +static POINT get_icon_pos( struct icon *icon ) +{ + RECT rect = get_icon_rect( icon ); + return *(POINT *)▭ +} + /* synchronize tooltip position with tooltip window */ static void update_tooltip_position( struct icon *icon ) { @@ -293,6 +320,33 @@ static void update_tooltip_position( struct icon *icon ) if (balloon_icon == icon) set_balloon_position( icon ); }
+/* window procedure for the individual tray icon window */ +static LRESULT WINAPI tray_icon_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + struct icon *icon = (struct icon *)GetWindowLongPtrW( hwnd, GWLP_USERDATA ); + + TRACE( "hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix\n", hwnd, msg, wparam, lparam ); + + switch (msg) + { + case WM_NCCREATE: + { + /* set the icon data for the window from the data passed into CreateWindow */ + const CREATESTRUCTW *info = (const CREATESTRUCTW *)lparam; + icon = info->lpCreateParams; + SetWindowLongPtrW( hwnd, GWLP_USERDATA, (LONG_PTR)icon ); + break; + } + + case WM_CREATE: + icon->window = hwnd; + create_tooltip( icon ); + break; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + /* find the icon located at a certain point in the tray window */ static struct icon *icon_from_point( int x, int y ) { @@ -336,6 +390,7 @@ static void systray_add_icon( struct icon *icon ) static void systray_remove_icon( struct icon *icon ) { struct icon *ptr; + POINT pos;
if (icon->display == -1) return; /* already removed */
@@ -346,6 +401,8 @@ static void systray_remove_icon( struct icon *icon ) if (ptr->display < icon->display) continue; ptr->display--; update_tooltip_position( ptr ); + pos = get_icon_pos( ptr ); + SetWindowPos( ptr->window, 0, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER ); }
if (!--nb_displayed && !enable_shell) do_hide_systray(); @@ -365,7 +422,6 @@ static BOOL show_icon(struct icon *icon) systray_add_icon( icon );
update_tooltip_position( icon ); - create_tooltip( icon ); update_balloon( icon ); return TRUE; } @@ -455,17 +511,23 @@ static BOOL add_icon(NOTIFYICONDATAW *nid) icon->owner = nid->hWnd; icon->display = -1;
+ CreateWindowW( tray_icon_class.lpszClassName, NULL, WS_CHILD, + 0, 0, icon_cx, icon_cy, tray_window, NULL, NULL, icon ); + if (!icon->window) ERR( "Failed to create systray icon window\n" ); + list_add_tail(&icon_list, &icon->entry);
return modify_icon( icon, nid ); }
/* Deletes tray icon window and icon record */ -static BOOL delete_icon(struct icon *icon) +static BOOL delete_icon( struct icon *icon ) { - hide_icon(icon); - list_remove(&icon->entry); - DestroyIcon(icon->image); + hide_icon( icon ); + list_remove( &icon->entry ); + DestroyWindow( icon->tooltip ); + DestroyWindow( icon->window ); + DestroyIcon( icon->image ); free( icon ); return TRUE; } @@ -777,7 +839,7 @@ static void do_show_systray(void) sync_taskbar_buttons(); }
-static LRESULT WINAPI tray_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +static LRESULT WINAPI shell_traywnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { switch (msg) { @@ -904,38 +966,37 @@ void handle_parent_notify( HWND hwnd, WPARAM wp ) /* this function creates the listener window */ void initialize_systray( HMODULE graphics_driver, BOOL using_root, BOOL arg_enable_shell ) { - WNDCLASSEXW class; RECT work_rect, primary_rect, taskbar_rect;
if (using_root && graphics_driver) wine_notify_icon = (void *)GetProcAddress( graphics_driver, "wine_notify_icon" );
+ shell_traywnd_class.hIcon = LoadIconW( 0, (const WCHAR *)IDI_WINLOGO ); + shell_traywnd_class.hCursor = LoadCursorW( 0, (const WCHAR *)IDC_ARROW ); + tray_icon_class.hIcon = shell_traywnd_class.hIcon; + tray_icon_class.hCursor = shell_traywnd_class.hCursor; + icon_cx = GetSystemMetrics( SM_CXSMICON ) + 2*ICON_BORDER; icon_cy = GetSystemMetrics( SM_CYSMICON ) + 2*ICON_BORDER; hide_systray = using_root; enable_shell = arg_enable_shell;
/* register the systray listener window class */ - ZeroMemory(&class, sizeof(class)); - class.cbSize = sizeof(class); - class.style = CS_DBLCLKS | CS_HREDRAW; - class.lpfnWndProc = tray_wndproc; - class.hInstance = NULL; - class.hIcon = LoadIconW(0, (LPCWSTR)IDI_WINLOGO); - class.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW); - class.hbrBackground = (HBRUSH) COLOR_WINDOW; - class.lpszClassName = L"Shell_TrayWnd"; - - if (!RegisterClassExW(&class)) + if (!RegisterClassExW( &shell_traywnd_class )) { ERR( "Could not register SysTray window class\n" ); return; } + if (!wine_notify_icon && !RegisterClassExW( &tray_icon_class )) + { + ERR( "Could not register Wine SysTray window classes\n" ); + return; + }
SystemParametersInfoW( SPI_GETWORKAREA, 0, &work_rect, 0 ); SetRect( &primary_rect, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) ); SubtractRect( &taskbar_rect, &primary_rect, &work_rect );
- tray_window = CreateWindowExW( WS_EX_NOACTIVATE, class.lpszClassName, NULL, WS_POPUP, taskbar_rect.left, + tray_window = CreateWindowExW( WS_EX_NOACTIVATE, shell_traywnd_class.lpszClassName, NULL, WS_POPUP, taskbar_rect.left, taskbar_rect.top, taskbar_rect.right - taskbar_rect.left, taskbar_rect.bottom - taskbar_rect.top, 0, 0, 0, 0 ); if (!tray_window)
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/systray.c | 180 ++++++++++++++---------------------- 1 file changed, 71 insertions(+), 109 deletions(-)
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index a36aa101525..60b407afa6c 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -119,6 +119,10 @@ static HWND balloon_window; static LRESULT WINAPI shell_traywnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ); static LRESULT WINAPI tray_icon_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );
+static BOOL show_icon( struct icon *icon ); +static BOOL hide_icon( struct icon *icon ); +static BOOL delete_icon( struct icon *icon ); + static WNDCLASSEXW shell_traywnd_class = { .cbSize = sizeof(WNDCLASSEXW), @@ -320,6 +324,30 @@ static void update_tooltip_position( struct icon *icon ) if (balloon_icon == icon) set_balloon_position( icon ); }
+static BOOL notify_owner( struct icon *icon, UINT msg, LPARAM lparam ) +{ + WPARAM wp = icon->id; + LPARAM lp = msg; + + if (icon->version >= NOTIFYICON_VERSION_4) + { + POINT pt = {.x = (short)LOWORD(lparam), .y = (short)HIWORD(lparam)}; + ClientToScreen( icon->window, &pt ); + wp = MAKEWPARAM( pt.x, pt.y ); + lp = MAKELPARAM( msg, icon->id ); + } + + TRACE( "relaying 0x%x\n", msg ); + if (!SendNotifyMessageW( icon->owner, icon->callback_message, wp, lp ) && + (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) + { + WARN( "application window was destroyed, removing icon %u\n", icon->id ); + delete_icon( icon ); + return FALSE; + } + return TRUE; +} + /* window procedure for the individual tray icon window */ static LRESULT WINAPI tray_icon_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { @@ -342,45 +370,60 @@ static LRESULT WINAPI tray_icon_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPA icon->window = hwnd; create_tooltip( icon ); break; - }
- return DefWindowProcW( hwnd, msg, wparam, lparam ); -} - -/* find the icon located at a certain point in the tray window */ -static struct icon *icon_from_point( int x, int y ) -{ - struct icon *icon; - POINT pt = {x, y}; - - LIST_FOR_EACH_ENTRY(icon, &icon_list, struct icon, entry) + case WM_PAINT: { - RECT rect = get_icon_rect( icon ); - if (PtInRect(&rect, pt)) return icon; + PAINTSTRUCT ps; + RECT rc; + HDC hdc; + int cx = GetSystemMetrics( SM_CXSMICON ); + int cy = GetSystemMetrics( SM_CYSMICON ); + + hdc = BeginPaint( hwnd, &ps ); + GetClientRect( hwnd, &rc ); + TRACE( "painting rect %s\n", wine_dbgstr_rect( &rc ) ); + DrawIconEx( hdc, (rc.left + rc.right - cx) / 2, (rc.top + rc.bottom - cy) / 2, + icon->image, cx, cy, 0, 0, DI_DEFAULTSIZE | DI_NORMAL ); + EndPaint( hwnd, &ps ); + return 0; }
- return NULL; -} - -/* invalidate the portion of the tray window that contains the specified icons */ -static void invalidate_icons( unsigned int start, unsigned int end ) -{ - RECT rect; + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + { + MSG message = {.hwnd = hwnd, .message = msg, .wParam = wparam, .lParam = lparam}; + SendMessageW( icon->tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message ); + if (!notify_owner( icon, msg, lparam )) break; + if (icon->version > 0) + { + if (msg == WM_LBUTTONUP) notify_owner( icon, NIN_SELECT, lparam ); + if (msg == WM_RBUTTONUP) notify_owner( icon, WM_CONTEXTMENU, lparam ); + } + break; + } + }
- rect.left = tray_width - (end + 1) * icon_cx; - rect.top = (tray_height - icon_cy) / 2; - rect.right = tray_width - start * icon_cx; - rect.bottom = rect.top + icon_cy; - InvalidateRect( tray_window, &rect, TRUE ); + return DefWindowProcW( hwnd, msg, wparam, lparam ); }
/* add an icon to the system tray window */ static void systray_add_icon( struct icon *icon ) { + POINT pos; + if (icon->display != -1) return; /* already added */
icon->display = nb_displayed++; - invalidate_icons( icon->display, icon->display ); + pos = get_icon_pos( icon ); + SetWindowPos( icon->window, 0, pos.x, pos.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
if (nb_displayed == 1 && !hide_systray) do_show_systray(); TRACE( "added %u now %d icons\n", icon->id, nb_displayed ); @@ -408,7 +451,6 @@ static void systray_remove_icon( struct icon *icon ) if (!--nb_displayed && !enable_shell) do_hide_systray(); TRACE( "removed %u now %d icons\n", icon->id, nb_displayed );
- invalidate_icons( icon->display, nb_displayed ); icon->display = -1; }
@@ -433,6 +475,7 @@ static BOOL hide_icon(struct icon *icon)
if (icon->display == -1) return TRUE; /* already hidden */
+ ShowWindow( icon->window, SW_HIDE ); systray_remove_icon( icon );
update_balloon( icon ); @@ -461,7 +504,7 @@ static BOOL modify_icon( struct icon *icon, NOTIFYICONDATAW *nid ) { if (icon->image) DestroyIcon(icon->image); icon->image = CopyIcon(nid->hIcon); - if (icon->display != -1) invalidate_icons( icon->display, icon->display ); + if (icon->display != -1) InvalidateRect( icon->window, NULL, TRUE ); }
if (nid->uFlags & NIF_MESSAGE) @@ -787,29 +830,6 @@ static void do_hide_systray(void) ShowWindow( tray_window, SW_HIDE ); }
-static BOOL notify_owner( struct icon *icon, UINT msg, POINT pt ) -{ - WPARAM wp = icon->id; - LPARAM lp = msg; - - if (icon->version >= NOTIFYICON_VERSION_4) - { - ClientToScreen( tray_window, &pt ); - wp = MAKEWPARAM( pt.x, pt.y ); - lp = MAKELPARAM( msg, icon->id ); - } - - TRACE( "relaying 0x%x\n", msg ); - if (!SendNotifyMessageW( icon->owner, icon->callback_message, wp, lp ) && - (GetLastError() == ERROR_INVALID_WINDOW_HANDLE)) - { - WARN( "application window was destroyed, removing icon %u\n", icon->id ); - delete_icon( icon ); - return FALSE; - } - return TRUE; -} - static void do_show_systray(void) { SIZE size; @@ -859,64 +879,6 @@ static LRESULT WINAPI shell_traywnd_proc( HWND hwnd, UINT msg, WPARAM wparam, LP } break;
- case WM_PAINT: - { - struct icon *icon; - PAINTSTRUCT ps; - HDC hdc; - - hdc = BeginPaint( hwnd, &ps ); - LIST_FOR_EACH_ENTRY( icon, &icon_list, struct icon, entry ) - { - RECT dummy, rect = get_icon_rect( icon ); - if (icon->display != -1 && IntersectRect( &dummy, &rect, &ps.rcPaint )) - DrawIconEx( hdc, rect.left + ICON_BORDER, rect.top + ICON_BORDER, icon->image, - icon_cx - 2*ICON_BORDER, icon_cy - 2*ICON_BORDER, - 0, 0, DI_DEFAULTSIZE|DI_NORMAL); - } - EndPaint( hwnd, &ps ); - break; - } - - case WM_MOUSEMOVE: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - { - MSG message; - POINT pt = { (short)LOWORD(lparam), (short)HIWORD(lparam) }; - struct icon *icon = icon_from_point( pt.x, pt.y ); - if (!icon) break; - - message.hwnd = hwnd; - message.message = msg; - message.wParam = wparam; - message.lParam = lparam; - SendMessageW( icon->tooltip, TTM_RELAYEVENT, 0, (LPARAM)&message ); - - if (!notify_owner( icon, msg, pt )) break; - - if (icon->version > 0) - { - switch (msg) - { - case WM_RBUTTONUP: - notify_owner( icon, WM_CONTEXTMENU, pt ); - break; - case WM_LBUTTONUP: - notify_owner( icon, NIN_SELECT, pt ); - break; - } - } - break; - } - case WM_CLOSE: /* don't destroy the tray window, just hide it */ ShowWindow( hwnd, SW_HIDE );
v2: Don't introduce standalone systray window yet, changing the taskbar window size breaks some tests.