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 }