| 46 */ |
46 */ |
| 47 static HWND systray_hwnd = NULL; |
47 static HWND systray_hwnd = NULL; |
| 48 /* additional two cached_icons entries for pending and connecting icons */ |
48 /* additional two cached_icons entries for pending and connecting icons */ |
| 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 */ |
| |
52 static GtkWidget *dummy_button = NULL; |
| |
53 static GtkWidget *dummy_window = NULL; |
| 51 static NOTIFYICONDATA _nicon_data; |
54 static NOTIFYICONDATA _nicon_data; |
| |
55 |
| |
56 static gboolean dummy_button_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { |
| |
57 pidgin_docklet_clicked(event->button); |
| |
58 return TRUE; |
| |
59 } |
| 52 |
60 |
| 53 static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { |
61 static LRESULT CALLBACK systray_mainmsg_handler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { |
| 54 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 */ |
| 55 |
63 |
| 56 switch(msg) { |
64 switch(msg) { |
| 79 else if(lparam == WM_RBUTTONUP) |
89 else if(lparam == WM_RBUTTONUP) |
| 80 type = 3; |
90 type = 3; |
| 81 else |
91 else |
| 82 break; |
92 break; |
| 83 |
93 |
| 84 pidgin_docklet_clicked(type); |
94 gtk_widget_show_all(dummy_window); |
| |
95 event = gdk_event_new(GDK_BUTTON_PRESS); |
| |
96 event_btn = (GdkEventButton *) event; |
| |
97 event_btn->window = g_object_ref (gdk_get_default_root_window()); |
| |
98 event_btn->send_event = TRUE; |
| |
99 event_btn->time = GetTickCount(); |
| |
100 event_btn->axes = NULL; |
| |
101 event_btn->state = 0; |
| |
102 event_btn->button = type; |
| |
103 event_btn->device = gdk_display_get_default ()->core_pointer; |
| |
104 event->any.window = g_object_ref(dummy_window->window); |
| |
105 gdk_window_set_user_data(event->any.window, dummy_button); |
| |
106 |
| |
107 gtk_main_do_event((GdkEvent *)event); |
| |
108 gtk_widget_hide(dummy_window); |
| |
109 gdk_event_free((GdkEvent *)event); |
| |
110 |
| 85 break; |
111 break; |
| 86 } |
112 } |
| 87 default: |
113 default: |
| 88 if (msg == taskbarRestartMsg) { |
114 if (msg == taskbarRestartMsg) { |
| 89 /* explorer crashed and left us hanging... |
115 /* explorer crashed and left us hanging... |
| 548 static void winpidgin_tray_create() { |
574 static void winpidgin_tray_create() { |
| 549 OSVERSIONINFO osinfo; |
575 OSVERSIONINFO osinfo; |
| 550 /* dummy window to process systray messages */ |
576 /* dummy window to process systray messages */ |
| 551 systray_hwnd = systray_create_hiddenwin(); |
577 systray_hwnd = systray_create_hiddenwin(); |
| 552 |
578 |
| |
579 dummy_window = gtk_window_new(GTK_WINDOW_POPUP); |
| |
580 dummy_button = gtk_button_new(); |
| |
581 gtk_container_add(GTK_CONTAINER(dummy_window), dummy_button); |
| |
582 |
| |
583 /* We trigger the click event indirectly so that gtk_get_current_event_state() is TRUE when the event is handled */ |
| |
584 g_signal_connect(G_OBJECT(dummy_button), "button-press-event", |
| |
585 G_CALLBACK(dummy_button_cb), NULL); |
| |
586 |
| 553 image = gtk_image_new(); |
587 image = gtk_image_new(); |
| 554 #if GLIB_CHECK_VERSION(2,10,0) |
588 #if GLIB_CHECK_VERSION(2,10,0) |
| 555 g_object_ref_sink(image); |
589 g_object_ref_sink(image); |
| 556 #else |
590 #else |
| 557 g_object_ref(image); |
591 g_object_ref(image); |