Mercurial > pidgin.yaz
comparison pidgin/win32/gtkdocklet-win32.c @ 29934:b5b20df96c20
Use the Post W2K Windows System Tray icon stuff - allows for 128 chars instead of 64 - also support non-ASCII stuff in the tooltip. Fixes #11461
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Fri, 05 Mar 2010 05:44:25 +0000 |
parents | 99ab74fb312c |
children | a8cc50c2279f |
comparison
equal
deleted
inserted
replaced
29933:daa02d44df13 | 29934:b5b20df96c20 |
---|---|
19 * You should have received a copy of the GNU General Public License | 19 * You should have received a copy of the GNU General Public License |
20 * along with this program; if not, write to the Free Software | 20 * along with this program; if not, write to the Free Software |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
22 * 02111-1301, USA. | 22 * 02111-1301, USA. |
23 */ | 23 */ |
24 | 24 #define _WIN32_IE 0x0500 |
25 #include <windows.h> | 25 #include <windows.h> |
26 #include <gdk/gdkwin32.h> | 26 #include <gdk/gdkwin32.h> |
27 #include <gdk/gdk.h> | 27 #include <gdk/gdk.h> |
28 | 28 |
29 #include "internal.h" | 29 #include "internal.h" |
49 static HICON cached_icons[PURPLE_STATUS_NUM_PRIMITIVES + 2]; | 49 static HICON cached_icons[PURPLE_STATUS_NUM_PRIMITIVES + 2]; |
50 static GtkWidget *image = NULL; | 50 static GtkWidget *image = NULL; |
51 /* This is used to trigger click events on so they appear to GTK+ as if they are triggered by input */ | 51 /* This is used to trigger click events on so they appear to GTK+ as if they are triggered by input */ |
52 static GtkWidget *dummy_button = NULL; | 52 static GtkWidget *dummy_button = NULL; |
53 static GtkWidget *dummy_window = NULL; | 53 static GtkWidget *dummy_window = NULL; |
54 static NOTIFYICONDATA _nicon_data; | 54 static NOTIFYICONDATAW _nicon_data; |
55 | 55 |
56 static gboolean dummy_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { | 56 static gboolean dummy_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { |
57 pidgin_docklet_clicked(event->button); | 57 pidgin_docklet_clicked(event->button); |
58 return TRUE; | 58 return TRUE; |
59 } | 59 } |
62 static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */ | 62 static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */ |
63 | 63 |
64 switch(msg) { | 64 switch(msg) { |
65 case WM_CREATE: | 65 case WM_CREATE: |
66 purple_debug_info("docklet", "WM_CREATE\n"); | 66 purple_debug_info("docklet", "WM_CREATE\n"); |
67 taskbarRestartMsg = RegisterWindowMessage("TaskbarCreated"); | 67 taskbarRestartMsg = RegisterWindowMessageW(L"TaskbarCreated"); |
68 break; | 68 break; |
69 | 69 |
70 case WM_TIMER: | 70 case WM_TIMER: |
71 purple_debug_info("docklet", "WM_TIMER\n"); | 71 purple_debug_info("docklet", "WM_TIMER\n"); |
72 break; | 72 break; |
112 } | 112 } |
113 default: | 113 default: |
114 if (msg == taskbarRestartMsg) { | 114 if (msg == taskbarRestartMsg) { |
115 /* explorer crashed and left us hanging... | 115 /* explorer crashed and left us hanging... |
116 This will put the systray icon back in it's place, when it restarts */ | 116 This will put the systray icon back in it's place, when it restarts */ |
117 Shell_NotifyIcon(NIM_ADD, &_nicon_data); | 117 Shell_NotifyIconW(NIM_ADD, &_nicon_data); |
118 } | 118 } |
119 break; | 119 break; |
120 }/* end switch */ | 120 }/* end switch */ |
121 | 121 |
122 return DefWindowProc(hwnd, msg, wparam, lparam); | 122 return DefWindowProc(hwnd, msg, wparam, lparam); |
123 } | 123 } |
124 | 124 |
125 /* Create hidden window to process systray messages */ | 125 /* Create hidden window to process systray messages */ |
126 static HWND systray_create_hiddenwin() { | 126 static HWND systray_create_hiddenwin() { |
127 WNDCLASSEX wcex; | 127 WNDCLASSEXW wcex; |
128 LPCTSTR wname; | 128 wchar_t *wname; |
129 | 129 |
130 wname = TEXT("WinpidginSystrayWinCls"); | 130 wname = L"WinpidginSystrayWinCls"; |
131 | 131 |
132 wcex.cbSize = sizeof(wcex); | 132 wcex.cbSize = sizeof(wcex); |
133 wcex.style = 0; | 133 wcex.style = 0; |
134 wcex.lpfnWndProc = systray_mainmsg_handler; | 134 wcex.lpfnWndProc = systray_mainmsg_handler; |
135 wcex.cbClsExtra = 0; | 135 wcex.cbClsExtra = 0; |
140 wcex.hbrBackground = NULL; | 140 wcex.hbrBackground = NULL; |
141 wcex.lpszMenuName = NULL; | 141 wcex.lpszMenuName = NULL; |
142 wcex.lpszClassName = wname; | 142 wcex.lpszClassName = wname; |
143 wcex.hIconSm = NULL; | 143 wcex.hIconSm = NULL; |
144 | 144 |
145 RegisterClassEx(&wcex); | 145 RegisterClassExW(&wcex); |
146 | 146 |
147 /* Create the window */ | 147 /* Create the window */ |
148 return (CreateWindow(wname, "", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, winpidgin_exe_hinstance(), 0)); | 148 return (CreateWindowW(wname, L"", 0, 0, 0, 0, 0, GetDesktopWindow(), NULL, winpidgin_exe_hinstance(), 0)); |
149 } | 149 } |
150 | 150 |
151 static void systray_init_icon(HWND hWnd) { | 151 static void systray_init_icon(HWND hWnd) { |
152 wchar_t *w; | |
152 ZeroMemory(&_nicon_data, sizeof(_nicon_data)); | 153 ZeroMemory(&_nicon_data, sizeof(_nicon_data)); |
153 _nicon_data.cbSize = sizeof(NOTIFYICONDATA); | 154 _nicon_data.cbSize = sizeof(NOTIFYICONDATAW); |
154 _nicon_data.hWnd = hWnd; | 155 _nicon_data.hWnd = hWnd; |
155 _nicon_data.uID = 0; | 156 _nicon_data.uID = 0; |
156 _nicon_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; | 157 _nicon_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; |
157 _nicon_data.uCallbackMessage = WM_TRAYMESSAGE; | 158 _nicon_data.uCallbackMessage = WM_TRAYMESSAGE; |
158 _nicon_data.hIcon = NULL; | 159 _nicon_data.hIcon = NULL; |
159 lstrcpy(_nicon_data.szTip, PIDGIN_NAME); | 160 w = g_utf8_to_utf16(PIDGIN_NAME, -1, NULL, NULL, NULL); |
160 Shell_NotifyIcon(NIM_ADD, &_nicon_data); | 161 wcsncpy(_nicon_data.szTip, w, sizeof(_nicon_data.szTip) / sizeof(wchar_t)); |
162 g_free(w); | |
163 Shell_NotifyIconW(NIM_ADD, &_nicon_data); | |
161 pidgin_docklet_embedded(); | 164 pidgin_docklet_embedded(); |
162 } | 165 } |
163 | 166 |
164 /* This is ganked from GTK+. | 167 /* This is ganked from GTK+. |
165 * When we can use GTK+ 2.10 and the GtkStatusIcon stuff, this will no longer be necesary */ | 168 * When we can use GTK+ 2.10 and the GtkStatusIcon stuff, this will no longer be necesary */ |
484 | 487 |
485 static void systray_change_icon(HICON hicon) { | 488 static void systray_change_icon(HICON hicon) { |
486 g_return_if_fail(hicon != NULL); | 489 g_return_if_fail(hicon != NULL); |
487 | 490 |
488 _nicon_data.hIcon = hicon; | 491 _nicon_data.hIcon = hicon; |
489 Shell_NotifyIcon(NIM_MODIFY, &_nicon_data); | 492 Shell_NotifyIconW(NIM_MODIFY, &_nicon_data); |
490 } | 493 } |
491 | 494 |
492 static void systray_remove_nid(void) { | 495 static void systray_remove_nid(void) { |
493 Shell_NotifyIcon(NIM_DELETE, &_nicon_data); | 496 Shell_NotifyIconW(NIM_DELETE, &_nicon_data); |
494 } | 497 } |
495 | 498 |
496 static void winpidgin_tray_update_icon(PurpleStatusPrimitive status, | 499 static void winpidgin_tray_update_icon(PurpleStatusPrimitive status, |
497 gboolean connecting, gboolean pending) { | 500 gboolean connecting, gboolean pending) { |
498 | 501 |
545 systray_change_icon(cached_icons[icon_index]); | 548 systray_change_icon(cached_icons[icon_index]); |
546 } | 549 } |
547 | 550 |
548 static void winpidgin_tray_blank_icon() { | 551 static void winpidgin_tray_blank_icon() { |
549 _nicon_data.hIcon = NULL; | 552 _nicon_data.hIcon = NULL; |
550 Shell_NotifyIcon(NIM_MODIFY, &_nicon_data); | 553 Shell_NotifyIconW(NIM_MODIFY, &_nicon_data); |
551 } | 554 } |
552 | 555 |
553 static void winpidgin_tray_set_tooltip(gchar *tooltip) { | 556 static void winpidgin_tray_set_tooltip(gchar *tooltip) { |
554 if (tooltip) { | 557 const char *value = tooltip; |
555 char *locenc = NULL; | 558 wchar_t *w; |
556 locenc = g_locale_from_utf8(tooltip, -1, NULL, NULL, NULL); | 559 if (value == NULL) { |
557 lstrcpyn(_nicon_data.szTip, locenc, sizeof(_nicon_data.szTip) / sizeof(TCHAR)); | 560 value = PIDGIN_NAME; |
558 g_free(locenc); | 561 } |
559 } else { | 562 w = g_utf8_to_utf16(value, -1, NULL, NULL, NULL); |
560 lstrcpy(_nicon_data.szTip, PIDGIN_NAME); | 563 wcsncpy(_nicon_data.szTip, w, sizeof(_nicon_data.szTip) / sizeof(wchar_t)); |
561 } | 564 g_free(w); |
562 Shell_NotifyIcon(NIM_MODIFY, &_nicon_data); | 565 Shell_NotifyIconW(NIM_MODIFY, &_nicon_data); |
563 } | 566 } |
564 | 567 |
565 static void winpidgin_tray_minimize(PidginBuddyList *gtkblist) { | 568 static void winpidgin_tray_minimize(PidginBuddyList *gtkblist) { |
566 MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window)); | 569 MinimizeWndToTray(GDK_WINDOW_HWND(gtkblist->window->window)); |
567 } | 570 } |