# HG changeset patch # User Daniel Atallah # Date 1187149264 0 # Node ID 39df1370839e651ff0155279ba78dcf75e5f08d5 # Parent fcc5d2de3b7421e3bed60f813a5104bd446a3a35 Fix the docked buddy list to consistently not have a taskbar entry thanks to some tips from "imiganai." This took *way* too long because of how arcane dealing with Windows on Windows is (the unnecessary complexity of our gtkappbar implementation doesn't help). Hopefully this doesn't break anything. Fixes #575. diff -r fcc5d2de3b74 -r 39df1370839e pidgin/plugins/win32/winprefs/gtkappbar.c --- a/pidgin/plugins/win32/winprefs/gtkappbar.c Wed Aug 15 03:40:42 2007 +0000 +++ b/pidgin/plugins/win32/winprefs/gtkappbar.c Wed Aug 15 03:41:04 2007 +0000 @@ -41,6 +41,8 @@ typedef HMONITOR WINAPI purple_MonitorFromWindow(HWND, DWORD); typedef BOOL WINAPI purple_GetMonitorInfo(HMONITOR, LPMONITORINFO); +static void gtk_appbar_do_dock(GtkAppBar *ab, UINT side); + /* Retrieve the rectangular display area from the specified monitor * Return TRUE if successful, otherwise FALSE */ @@ -154,9 +156,8 @@ #endif /** Set the window style to be the "Tool Window" style - small header, no min/max buttons */ static void set_toolbar(HWND hwnd, gboolean val) { - LONG style=0; + LONG style = GetWindowLong(hwnd, GWL_EXSTYLE); - style = GetWindowLong(hwnd, GWL_EXSTYLE); if(val && !(style & WS_EX_TOOLWINDOW)) style |= WS_EX_TOOLWINDOW; else if(!val && style & WS_EX_TOOLWINDOW) @@ -199,6 +200,7 @@ ab->registered = FALSE; ab->docked = FALSE; + ab->undocking = FALSE; ab->docking = FALSE; return TRUE; @@ -264,7 +266,7 @@ } /** Let any callbacks know that we have docked or undocked */ static void gtk_appbar_dispatch_dock_cbs(GtkAppBar *ab, gboolean val) { - GList *lst = ab->dock_cbs; + GSList *lst = ab->dock_cbs; while(lst) { GtkAppBarDockCB dock_cb = lst->data; @@ -311,15 +313,10 @@ } else if(side < 0) { gtk_appbar_unregister(ab, msg->hwnd); + ab->undocking = TRUE; rc->bottom = rc->top + ab->undocked_height; } - /* Switch to toolbar/regular caption*/ - if(ab->docking) - set_toolbar(msg->hwnd, TRUE); - else if(!ab->docked) - set_toolbar(msg->hwnd, FALSE); - return GDK_FILTER_CONTINUE; } @@ -393,14 +390,19 @@ purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "wnd_exitsizemove\n"); if(ab->docking) { - gtk_appbar_setpos(ab, msg->hwnd); - ab->docking = FALSE; - ab->docked = TRUE; - gtk_appbar_dispatch_dock_cbs(ab, TRUE); - } - else if(!ab->docked) { - gtk_appbar_unregister(ab, msg->hwnd); - gtk_appbar_dispatch_dock_cbs(ab, FALSE); + gtk_appbar_setpos(ab, msg->hwnd); + ab->docking = FALSE; + ab->docked = TRUE; + ShowWindow(msg->hwnd, SW_HIDE); + set_toolbar(msg->hwnd, TRUE); + ShowWindow(msg->hwnd, SW_SHOW); + gtk_appbar_dispatch_dock_cbs(ab, TRUE); + } else if(ab->undocking) { + ShowWindow(msg->hwnd, SW_HIDE); + set_toolbar(msg->hwnd, FALSE); + ShowWindow(msg->hwnd, SW_SHOW); + gtk_appbar_dispatch_dock_cbs(ab, FALSE); + ab->undocking = FALSE; } return GDK_FILTER_CONTINUE; @@ -414,12 +416,11 @@ ab->iconized = FALSE; purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "shown\n"); ab->docked = FALSE; - gtk_appbar_dock(ab, ab->side); + gtk_appbar_do_dock(ab, ab->side); } else if(!msg->wParam && ab->docked) { purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "hidden\n"); gtk_appbar_unregister(ab, GDK_WINDOW_HWND(ab->win->window)); - set_toolbar(GDK_WINDOW_HWND(ab->win->window), FALSE); ab->docked = TRUE; ab->iconized = TRUE; } @@ -441,7 +442,7 @@ else if(msg->wParam == SIZE_RESTORED) { purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "Restore\n"); if (!ab->iconized && ab->docked) { - gtk_appbar_dock(ab, ab->side); + gtk_appbar_do_dock(ab, ab->side); } } return GDK_FILTER_CONTINUE; @@ -572,10 +573,10 @@ return GDK_FILTER_CONTINUE; } -void gtk_appbar_dock(GtkAppBar *ab, UINT side) { +static void gtk_appbar_do_dock(GtkAppBar *ab, UINT side) { RECT orig, windowRect; - purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "gtk_appbar_dock\n"); + purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "gtk_appbar_do_dock\n"); if(!ab || !IsWindow(GDK_WINDOW_HWND(ab->win->window))) return; @@ -592,14 +593,32 @@ ab->docked_rect.right - ab->docked_rect.left, ab->docked_rect.bottom - ab->docked_rect.top, TRUE); gtk_appbar_setpos(ab, GDK_WINDOW_HWND(ab->win->window)); - set_toolbar(GDK_WINDOW_HWND(ab->win->window), TRUE); ab->docked = TRUE; } +void gtk_appbar_dock(GtkAppBar *ab, UINT side) { + HWND hwnd; + + g_return_if_fail(ab != NULL); + + hwnd = GDK_WINDOW_HWND(ab->win->window); + + g_return_if_fail(IsWindow(hwnd)); + + ab->iconized = IsIconic(hwnd); + + if (!ab->docked && !ab->iconized) + ShowWindow(hwnd, SW_HIDE); + gtk_appbar_do_dock(ab, side); + set_toolbar(hwnd, TRUE); + if (!ab->iconized) + ShowWindow(hwnd, SW_SHOW); +} + void gtk_appbar_add_dock_cb(GtkAppBar *ab, GtkAppBarDockCB dock_cb) { if(!ab) return; - ab->dock_cbs = g_list_append(ab->dock_cbs, dock_cb); + ab->dock_cbs = g_slist_prepend(ab->dock_cbs, dock_cb); } GtkAppBar *gtk_appbar_add(GtkWidget *win) { @@ -623,10 +642,13 @@ } void gtk_appbar_remove(GtkAppBar *ab) { + HWND hwnd; purple_debug(PURPLE_DEBUG_INFO, "gtkappbar", "gtk_appbar_remove\n"); if(!ab) return; + + hwnd = GDK_WINDOW_HWND(ab->win->window); gdk_window_remove_filter(ab->win->window, gtk_appbar_event_filter, ab); @@ -634,9 +656,16 @@ gtk_window_resize(GTK_WINDOW(ab->win), ab->docked_rect.right - ab->docked_rect.left, ab->undocked_height); - set_toolbar(GDK_WINDOW_HWND(ab->win->window), FALSE); + if (!ab->iconized) + ShowWindow(hwnd, SW_HIDE); + set_toolbar(hwnd, FALSE); + if (!ab->iconized) + ShowWindow(hwnd, SW_SHOW); } - gtk_appbar_unregister(ab, GDK_WINDOW_HWND(ab->win->window)); + gtk_appbar_unregister(ab, hwnd); - g_free(ab); + while (ab->dock_cbs) + ab->dock_cbs = g_slist_remove(ab->dock_cbs, ab->dock_cbs->data); + + g_free(ab); } diff -r fcc5d2de3b74 -r 39df1370839e pidgin/plugins/win32/winprefs/gtkappbar.h --- a/pidgin/plugins/win32/winprefs/gtkappbar.h Wed Aug 15 03:40:42 2007 +0000 +++ b/pidgin/plugins/win32/winprefs/gtkappbar.h Wed Aug 15 03:41:04 2007 +0000 @@ -25,22 +25,26 @@ #ifndef _GTKAPPBAR_H_ #define _GTKAPPBAR_H_ +#include +#include + typedef struct { - GtkWidget *win; + GtkWidget *win; /** The rectangle of the screen area used for docking */ - RECT docked_rect; + RECT docked_rect; /** The height of the window prior to docking */ - UINT undocked_height; + UINT undocked_height; /** The side of the screen to which the window is docked*/ - UINT side; + UINT side; /** Is the window currently docked? */ - gboolean docked; + gboolean docked; /** Is the window currently in the process of docking? */ - gboolean docking; + gboolean docking; + gboolean undocking; /** Is the window currently registered as an appbar */ - gboolean registered; + gboolean registered; /** Callback functions to notify of dock state change */ - GList *dock_cbs; + GSList *dock_cbs; /** Is the window currently iconized? */ gboolean iconized; } GtkAppBar;