diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c index 75872b0aea..9ddfd4d4cc 100644 --- a/programs/explorer/systray.c +++ b/programs/explorer/systray.c @@ -64,6 +64,7 @@ struct icon HWND tooltip; /* Icon tooltip */ UINT id; /* the unique id given by the app */ UINT callback_message; + BOOL hidden; /* icon display state */ }; static struct tray tray; @@ -182,69 +183,24 @@ static void set_tooltip(struct icon *icon, WCHAR *szTip, BOOL modify) SendMessageW(icon->tooltip, TTM_ADDTOOLW, 0, (LPARAM)&ti); } -static BOOL modify_icon(NOTIFYICONDATAW *nid, BOOL modify_tooltip) +static BOOL display_icon(struct icon *icon, BOOL hide) { - struct icon *icon; - - WINE_TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd); - - /* demarshal the request from the NID */ - icon = get_icon(nid->hWnd, nid->uID); - if (!icon) - { - WINE_WARN("Invalid icon ID (0x%x) for HWND %p\n", nid->uID, nid->hWnd); - return FALSE; - } - - if (nid->uFlags & NIF_ICON) - { - if (icon->image) DestroyIcon(icon->image); - icon->image = CopyIcon(nid->hIcon); - - RedrawWindow(icon->window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); - } - - if (nid->uFlags & NIF_MESSAGE) - { - icon->callback_message = nid->uCallbackMessage; - } - if (nid->uFlags & NIF_TIP) - { - set_tooltip(icon, nid->szTip, modify_tooltip); - } - if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE) - { - WINE_FIXME("balloon tip title %s, message %s\n", wine_dbgstr_w(nid->szInfoTitle), wine_dbgstr_w(nid->szInfo)); - } - return TRUE; -} - -static BOOL add_icon(NOTIFYICONDATAW *nid) -{ - HMODULE x11drv = GetModuleHandleA( "winex11.drv" ); + HMODULE x11drv = GetModuleHandleA("winex11.drv"); RECT rect; - struct icon *icon; static const WCHAR adaptor_windowname[] = /* Wine System Tray Adaptor */ {'W','i','n','e',' ','S','y','s','t','e','m',' ','T','r','a','y',' ','A','d','a','p','t','o','r',0}; static BOOL tooltps_initialized = FALSE; - WINE_TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd); + WINE_TRACE("id=0x%x, hwnd=%p, hide=%d\n", icon->id, icon->owner, hide); - if ((icon = get_icon(nid->hWnd, nid->uID))) + if (icon->hidden == hide || (!icon->hidden) == (!hide)) return TRUE; + icon->hidden = hide; + if (hide) { - WINE_WARN("duplicate tray icon add, buggy app?\n"); - return FALSE; + DestroyWindow(icon->window); + DestroyWindow(icon->tooltip); + return TRUE; } - if (!(icon = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*icon)))) - { - WINE_ERR("out of memory\n"); - return FALSE; - } - - icon->id = nid->uID; - icon->owner = nid->hWnd; - icon->image = NULL; - rect.left = 0; rect.top = 0; rect.right = GetSystemMetrics(SM_CXSMICON) + ICON_BORDER; @@ -261,8 +217,8 @@ static BOOL add_icon(NOTIFYICONDATAW *nid) NULL, NULL, NULL, icon); if (x11drv) { - void (*make_systray_window)(HWND) = (void *)GetProcAddress( x11drv, "wine_make_systray_window" ); - if (make_systray_window) make_systray_window( icon->window ); + void (*make_systray_window)(HWND) = (void *)GetProcAddress(x11drv, "wine_make_systray_window"); + if (make_systray_window) make_systray_window(icon->window); } if (!hide_systray) @@ -287,6 +243,80 @@ static BOOL add_icon(NOTIFYICONDATAW *nid) CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, icon->window, NULL, NULL, NULL); + return TRUE; +} + +static BOOL modify_icon(NOTIFYICONDATAW *nid, BOOL modify_tooltip) +{ + struct icon *icon; + + WINE_TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd); + + /* demarshal the request from the NID */ + icon = get_icon(nid->hWnd, nid->uID); + if (!icon) + { + WINE_WARN("Invalid icon ID (0x%x) for HWND %p\n", nid->uID, nid->hWnd); + return FALSE; + } + + if (nid->uFlags & NIF_STATE) + { + if (nid->dwStateMask & NIS_HIDDEN) + display_icon(icon, !!(nid->dwState & NIS_HIDDEN)); + else + display_icon(icon, FALSE); + } + else + display_icon(icon, FALSE); + + if (nid->uFlags & NIF_ICON) + { + if (icon->image) DestroyIcon(icon->image); + icon->image = CopyIcon(nid->hIcon); + + if (!icon->hidden) + RedrawWindow(icon->window, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); + } + + if (nid->uFlags & NIF_MESSAGE) + { + icon->callback_message = nid->uCallbackMessage; + } + if (nid->uFlags & NIF_TIP) + { + set_tooltip(icon, nid->szTip, modify_tooltip); + } + if (nid->uFlags & NIF_INFO && nid->cbSize >= NOTIFYICONDATAA_V2_SIZE) + { + WINE_FIXME("balloon tip title %s, message %s\n", wine_dbgstr_w(nid->szInfoTitle), wine_dbgstr_w(nid->szInfo)); + } + return TRUE; +} + +static BOOL add_icon(NOTIFYICONDATAW *nid) +{ + struct icon *icon; + + WINE_TRACE("id=0x%x, hwnd=%p\n", nid->uID, nid->hWnd); + + if ((icon = get_icon(nid->hWnd, nid->uID))) + { + WINE_WARN("duplicate tray icon add, buggy app?\n"); + return FALSE; + } + + if (!(icon = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*icon)))) + { + WINE_ERR("out of memory\n"); + return FALSE; + } + + icon->id = nid->uID; + icon->owner = nid->hWnd; + icon->image = NULL; + icon->window = NULL; + icon->hidden = TRUE; list_add_tail(&tray.icons, &icon->entry); @@ -305,8 +335,7 @@ static BOOL delete_icon(const NOTIFYICONDATAW *nid) return FALSE; } - DestroyWindow(icon->tooltip); - DestroyWindow(icon->window); + display_icon(icon, TRUE); return TRUE; }