| 38 * 22:23:25 <deryni> seanegan: To what? |
38 * 22:23:25 <deryni> seanegan: To what? |
| 39 * 22:23:42 <seanegan> deryni: I dunno. Flash it between the regular icon and |
39 * 22:23:42 <seanegan> deryni: I dunno. Flash it between the regular icon and |
| 40 * blank or something. |
40 * blank or something. |
| 41 * 22:23:53 <deryni> Also I think gaim might re-set that sort of frequently, |
41 * 22:23:53 <deryni> Also I think gaim might re-set that sort of frequently, |
| 42 * but I'd have to look. |
42 * but I'd have to look. |
| 43 * 22:25:16 <seanegan> deryni: I keep my conversations in one workspace and am |
43 * 22:25:16 <seanegan> deryni: I keep my conversations in one workspace and am |
| 44 * frequently in an another, and the icon flashing in the pager would be a |
44 * frequently in an another, and the icon flashing in the pager would be a |
| 45 * neat visual clue. |
45 * neat visual clue. |
| 46 */ |
46 */ |
| 47 |
47 |
| 48 /* |
48 /* |
| 109 |
110 |
| 110 static GaimPlugin *my_plugin = NULL; |
111 static GaimPlugin *my_plugin = NULL; |
| 111 |
112 |
| 112 /* notification set/unset */ |
113 /* notification set/unset */ |
| 113 static int notify(GaimConversation *conv, gboolean increment); |
114 static int notify(GaimConversation *conv, gboolean increment); |
| 114 static void notify_win(GaimConvWindow *gaimwin); |
115 static void notify_win(GaimGtkWindow *gaimwin); |
| 115 static void unnotify(GaimConversation *conv, gboolean reset); |
116 static void unnotify(GaimConversation *conv, gboolean reset); |
| 116 static int unnotify_cb(GtkWidget *widget, gpointer data, GaimConversation *conv); |
117 static int unnotify_cb(GtkWidget *widget, gpointer data, GaimConversation *conv); |
| 117 |
118 |
| 118 /* gtk widget callbacks for prefs panel */ |
119 /* gtk widget callbacks for prefs panel */ |
| 119 static void type_toggle_cb(GtkWidget *widget, gpointer data); |
120 static void type_toggle_cb(GtkWidget *widget, gpointer data); |
| 122 static gboolean options_entry_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data); |
123 static gboolean options_entry_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data); |
| 123 static void apply_method(); |
124 static void apply_method(); |
| 124 static void apply_notify(); |
125 static void apply_notify(); |
| 125 |
126 |
| 126 /* string function */ |
127 /* string function */ |
| 127 static void handle_string(GaimConvWindow *gaimwin); |
128 static void handle_string(GaimGtkWindow *gaimwin); |
| 128 |
129 |
| 129 /* count function */ |
130 /* count function */ |
| 130 static void handle_count(GaimConvWindow *gaimwin); |
131 static void handle_count(GaimGtkWindow *gaimwin); |
| 131 |
132 |
| 132 /* urgent function */ |
133 /* urgent function */ |
| 133 static void handle_urgent(GaimConvWindow *gaimwin, gboolean add); |
134 static void handle_urgent(GaimGtkWindow *gaimwin, gboolean add); |
| 134 |
135 |
| 135 /* raise function */ |
136 /* raise function */ |
| 136 static void handle_raise(GaimConvWindow *gaimwin); |
137 static void handle_raise(GaimGtkWindow *gaimwin); |
| 137 |
138 |
| 138 /****************************************/ |
139 /****************************************/ |
| 139 /* Begin doing stuff below this line... */ |
140 /* Begin doing stuff below this line... */ |
| 140 /****************************************/ |
141 /****************************************/ |
| 141 static int |
142 static int |
| 142 count_messages(GaimConvWindow *gaimwin) |
143 count_messages(GaimGtkWindow *gaimwin) |
| 143 { |
144 { |
| 144 gint count = 0; |
145 gint count = 0; |
| 145 GList *convs = NULL; |
146 GList *convs = NULL, *l; |
| 146 |
147 |
| 147 for (convs = gaim_conv_window_get_conversations(gaimwin); |
148 for (convs = gaimwin->gtkconvs; convs != NULL; convs = convs->next) { |
| 148 convs != NULL; convs = convs->next) { |
149 GaimGtkConversation *conv = convs->data; |
| 149 GaimConversation *conv = convs->data; |
150 for (l = conv->convs; l != NULL; l = l->next) { |
| 150 count += GPOINTER_TO_INT(gaim_conversation_get_data(conv, "notify-message-count")); |
151 count += GPOINTER_TO_INT(gaim_conversation_get_data(l->data, "notify-message-count")); |
| |
152 } |
| 151 } |
153 } |
| 152 |
154 |
| 153 return count; |
155 return count; |
| 154 } |
156 } |
| 155 |
157 |
| 156 static int |
158 static int |
| 157 notify(GaimConversation *conv, gboolean increment) |
159 notify(GaimConversation *conv, gboolean increment) |
| 158 { |
160 { |
| 159 GaimConvWindow *gaimwin = NULL; |
161 GaimGtkWindow *gaimwin = NULL; |
| 160 gint count; |
162 gint count; |
| 161 gboolean has_focus; |
163 gboolean has_focus; |
| 162 |
164 |
| 163 if (conv == NULL) |
165 if (conv == NULL) |
| 164 return 0; |
166 return 0; |
| 165 |
167 |
| 166 /* We want to remove the notifications, but not reset the counter */ |
168 /* We want to remove the notifications, but not reset the counter */ |
| 167 unnotify(conv, FALSE); |
169 unnotify(conv, FALSE); |
| 168 |
170 |
| 169 gaimwin = gaim_conversation_get_window(conv); |
171 gaimwin = GAIM_GTK_CONVERSATION(conv)->win; |
| 170 |
172 |
| 171 /* If we aren't doing notifications for this type of conversation, return */ |
173 /* If we aren't doing notifications for this type of conversation, return */ |
| 172 if (((gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) && |
174 if (((gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) && |
| 173 !gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_im")) || |
175 !gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_im")) || |
| 174 ((gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) && |
176 ((gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) && |
| 175 !gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_chat"))) |
177 !gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_chat"))) |
| 176 return 0; |
178 return 0; |
| 177 |
179 |
| 178 g_object_get(G_OBJECT(GAIM_GTK_WINDOW(gaimwin)->window), |
180 g_object_get(G_OBJECT(gaimwin->window), |
| 179 "has-toplevel-focus", &has_focus, NULL); |
181 "has-toplevel-focus", &has_focus, NULL); |
| 180 |
182 |
| 181 if (gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_focused") || |
183 if (gaim_prefs_get_bool("/plugins/gtk/X11/notify/type_focused") || |
| 182 !has_focus) { |
184 !has_focus) { |
| 183 if (increment) { |
185 if (increment) { |
| 210 |
212 |
| 211 static void |
213 static void |
| 212 unnotify(GaimConversation *conv, gboolean reset) |
214 unnotify(GaimConversation *conv, gboolean reset) |
| 213 { |
215 { |
| 214 GaimConversation *active_conv = NULL; |
216 GaimConversation *active_conv = NULL; |
| 215 GaimConvWindow *gaimwin = NULL; |
217 GaimGtkWindow *gaimwin = NULL; |
| 216 |
218 |
| 217 g_return_if_fail(conv != NULL); |
219 g_return_if_fail(conv != NULL); |
| 218 |
220 |
| 219 gaimwin = gaim_conversation_get_window(conv); |
221 gaimwin = GAIM_GTK_CONVERSATION(conv)->win; |
| 220 active_conv = gaim_conv_window_get_active_conversation(gaimwin); |
222 active_conv = gaim_gtk_conv_window_get_active_conversation(gaimwin); |
| 221 |
223 |
| 222 /* reset the conversation window title */ |
224 /* reset the conversation window title */ |
| 223 gaim_conversation_autoset_title(active_conv); |
225 gaim_conversation_autoset_title(active_conv); |
| 224 |
226 |
| 225 if (reset) { |
227 if (reset) { |
| 291 GaimGtkWindow *gtkwin = NULL; |
293 GaimGtkWindow *gtkwin = NULL; |
| 292 GSList *window_ids = NULL, *imhtml_ids = NULL, *entry_ids = NULL; |
294 GSList *window_ids = NULL, *imhtml_ids = NULL, *entry_ids = NULL; |
| 293 guint id; |
295 guint id; |
| 294 |
296 |
| 295 gtkconv = GAIM_GTK_CONVERSATION(conv); |
297 gtkconv = GAIM_GTK_CONVERSATION(conv); |
| 296 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); |
298 if (!gtkconv) { |
| |
299 gaim_debug_misc("notify", "Failed to find gtkconv\n"); |
| |
300 return 0; |
| |
301 } |
| |
302 |
| |
303 gtkwin = gtkconv->win; |
| 297 |
304 |
| 298 if (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_focus")) { |
305 if (gaim_prefs_get_bool("/plugins/gtk/X11/notify/notify_focus")) { |
| 299 /* TODO should really find a way to make this work no matter where the |
306 /* TODO should really find a way to make this work no matter where the |
| 300 * focus is inside the conv window, without having to bind to |
307 * focus is inside the conv window, without having to bind to |
| 301 * focus-in-event on the g(d|t)kwindow */ |
308 * focus-in-event on the g(d|t)kwindow */ |
| 341 GaimGtkConversation *gtkconv = NULL; |
348 GaimGtkConversation *gtkconv = NULL; |
| 342 GaimGtkWindow *gtkwin = NULL; |
349 GaimGtkWindow *gtkwin = NULL; |
| 343 GSList *ids = NULL; |
350 GSList *ids = NULL; |
| 344 |
351 |
| 345 gtkconv = GAIM_GTK_CONVERSATION(conv); |
352 gtkconv = GAIM_GTK_CONVERSATION(conv); |
| 346 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); |
353 if (!gtkconv) |
| |
354 return; |
| |
355 gtkwin = gtkconv->win; |
| 347 |
356 |
| 348 ids = gaim_conversation_get_data(conv, "notify-window-signals"); |
357 ids = gaim_conversation_get_data(conv, "notify-window-signals"); |
| 349 for (; ids != NULL; ids = ids->next) |
358 for (; ids != NULL; ids = ids->next) |
| 350 g_signal_handler_disconnect(gtkwin->window, GPOINTER_TO_INT(ids->data)); |
359 g_signal_handler_disconnect(gtkwin->window, GPOINTER_TO_INT(ids->data)); |
| 351 |
360 |
| 412 } |
411 } |
| 413 |
412 |
| 414 static void |
413 static void |
| 415 deleting_conv(GaimConversation *conv) |
414 deleting_conv(GaimConversation *conv) |
| 416 { |
415 { |
| 417 GaimConvWindow *gaimwin = NULL; |
416 GaimGtkWindow *gaimwin = NULL; |
| 418 |
417 |
| 419 detach_signals(conv); |
418 detach_signals(conv); |
| 420 |
419 |
| 421 unnotify(conv, TRUE); |
420 unnotify(conv, TRUE); |
| 422 |
421 |
| 423 gaimwin = gaim_conversation_get_window(conv); |
422 gaimwin = GAIM_GTK_CONVERSATION(conv)->win; |
| |
423 #if 0 |
| |
424 /* i think this line crashes */ |
| 424 if (count_messages(gaimwin)) |
425 if (count_messages(gaimwin)) |
| 425 notify_win(gaimwin); |
426 notify_win(gaimwin); |
| |
427 #endif |
| 426 } |
428 } |
| 427 |
429 |
| 428 #if 0 |
430 #if 0 |
| 429 static void |
431 static void |
| 430 conversation_dragging(GaimConversation *active_conv, |
432 conversation_dragging(GaimConversation *active_conv, |
| 431 GaimConvWindow *old_gaimwin, |
433 GaimGtkWindow *old_gaimwin, |
| 432 GaimConvWindow *new_gaimwin) |
434 GaimGtkWindow *new_gaimwin) |
| 433 { |
435 { |
| 434 if (old_gaimwin != new_gaimwin) { |
436 if (old_gaimwin != new_gaimwin) { |
| 435 if (old_gaimwin == NULL) { |
437 if (old_gaimwin == NULL) { |
| 436 /* |
438 /* |
| 437 gaim_conversation_autoset_title(active_conv); |
439 gaim_conversation_autoset_title(active_conv); |
| 473 } |
475 } |
| 474 } |
476 } |
| 475 #endif |
477 #endif |
| 476 |
478 |
| 477 static void |
479 static void |
| 478 handle_string(GaimConvWindow *gaimwin) |
480 handle_string(GaimGtkWindow *gaimwin) |
| 479 { |
481 { |
| 480 GtkWindow *window = NULL; |
482 GtkWindow *window = NULL; |
| 481 gchar newtitle[256]; |
483 gchar newtitle[256]; |
| 482 |
484 |
| 483 g_return_if_fail(gaimwin != NULL); |
485 g_return_if_fail(gaimwin != NULL); |
| 484 |
486 |
| 485 window = GTK_WINDOW(GAIM_GTK_WINDOW(gaimwin)->window); |
487 window = GTK_WINDOW(gaimwin->window); |
| 486 g_return_if_fail(window != NULL); |
488 g_return_if_fail(window != NULL); |
| 487 |
489 |
| 488 g_snprintf(newtitle, sizeof(newtitle), "%s%s", |
490 g_snprintf(newtitle, sizeof(newtitle), "%s%s", |
| 489 gaim_prefs_get_string("/plugins/gtk/X11/notify/title_string"), |
491 gaim_prefs_get_string("/plugins/gtk/X11/notify/title_string"), |
| 490 gtk_window_get_title(window)); |
492 gtk_window_get_title(window)); |
| 491 gtk_window_set_title(window, newtitle); |
493 gtk_window_set_title(window, newtitle); |
| 492 } |
494 } |
| 493 |
495 |
| 494 static void |
496 static void |
| 495 handle_count(GaimConvWindow *gaimwin) |
497 handle_count(GaimGtkWindow *gaimwin) |
| 496 { |
498 { |
| 497 GtkWindow *window; |
499 GtkWindow *window; |
| 498 char newtitle[256]; |
500 char newtitle[256]; |
| 499 |
501 |
| 500 g_return_if_fail(gaimwin != NULL); |
502 g_return_if_fail(gaimwin != NULL); |
| 501 |
503 |
| 502 window = GTK_WINDOW(GAIM_GTK_WINDOW(gaimwin)->window); |
504 window = GTK_WINDOW(gaimwin->window); |
| 503 g_return_if_fail(window != NULL); |
505 g_return_if_fail(window != NULL); |
| 504 |
506 |
| 505 g_snprintf(newtitle, sizeof(newtitle), "[%d] %s", |
507 g_snprintf(newtitle, sizeof(newtitle), "[%d] %s", |
| 506 count_messages(gaimwin), gtk_window_get_title(window)); |
508 count_messages(gaimwin), gtk_window_get_title(window)); |
| 507 gtk_window_set_title(window, newtitle); |
509 gtk_window_set_title(window, newtitle); |
| 508 } |
510 } |
| 509 |
511 |
| 510 static void |
512 static void |
| 511 handle_urgent(GaimConvWindow *gaimwin, gboolean add) |
513 handle_urgent(GaimGtkWindow *win, gboolean add) |
| 512 { |
514 { |
| 513 XWMHints *hints; |
515 XWMHints *hints; |
| 514 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaimwin); |
516 |
| 515 |
517 g_return_if_fail(win != NULL); |
| 516 g_return_if_fail(gtkwin != NULL); |
518 g_return_if_fail(win->window != NULL); |
| 517 g_return_if_fail(gtkwin->window != NULL); |
519 g_return_if_fail(win->window->window != NULL); |
| 518 g_return_if_fail(gtkwin->window->window != NULL); |
520 |
| 519 |
521 hints = XGetWMHints(GDK_WINDOW_XDISPLAY(win->window->window), |
| 520 hints = XGetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), |
522 GDK_WINDOW_XWINDOW(win->window->window)); |
| 521 GDK_WINDOW_XWINDOW(gtkwin->window->window)); |
|
| 522 if (add) |
523 if (add) |
| 523 hints->flags |= XUrgencyHint; |
524 hints->flags |= XUrgencyHint; |
| 524 else |
525 else |
| 525 hints->flags &= ~XUrgencyHint; |
526 hints->flags &= ~XUrgencyHint; |
| 526 XSetWMHints(GDK_WINDOW_XDISPLAY(gtkwin->window->window), |
527 XSetWMHints(GDK_WINDOW_XDISPLAY(win->window->window), |
| 527 GDK_WINDOW_XWINDOW(gtkwin->window->window), hints); |
528 GDK_WINDOW_XWINDOW(win->window->window), hints); |
| 528 XFree(hints); |
529 XFree(hints); |
| 529 } |
530 } |
| 530 |
531 |
| 531 static void |
532 static void |
| 532 handle_raise(GaimConvWindow *gaimwin) |
533 handle_raise(GaimGtkWindow *gaimwin) |
| 533 { |
534 { |
| 534 gaim_conv_window_raise(gaimwin); |
535 gaim_gtk_conv_window_raise(gaimwin); |
| 535 } |
536 } |
| 536 |
537 |
| 537 static void |
538 static void |
| 538 type_toggle_cb(GtkWidget *widget, gpointer data) |
539 type_toggle_cb(GtkWidget *widget, gpointer data) |
| 539 { |
540 { |
| 594 } |
595 } |
| 595 |
596 |
| 596 static void |
597 static void |
| 597 apply_method() { |
598 apply_method() { |
| 598 GList *convs = gaim_get_conversations(); |
599 GList *convs = gaim_get_conversations(); |
| 599 GaimConvWindow *gaimwin = NULL; |
600 GaimGtkWindow *gaimwin = NULL; |
| 600 |
601 |
| 601 for (convs = gaim_get_conversations(); convs != NULL; convs = convs->next) { |
602 for (convs = gaim_get_conversations(); convs != NULL; convs = convs->next) { |
| 602 GaimConversation *conv = (GaimConversation *)convs->data; |
603 GaimConversation *conv = (GaimConversation *)convs->data; |
| 603 |
604 |
| 604 /* remove notifications */ |
605 /* remove notifications */ |
| 605 unnotify(conv, FALSE); |
606 unnotify(conv, FALSE); |
| 606 |
607 |
| 607 gaimwin = gaim_conversation_get_window(conv); |
608 gaimwin = GAIM_GTK_CONVERSATION(conv)->win; |
| 608 if (GPOINTER_TO_INT(gaim_conversation_get_data(conv, "notify-message-count")) != 0) |
609 if (GPOINTER_TO_INT(gaim_conversation_get_data(conv, "notify-message-count")) != 0) |
| 609 /* reattach appropriate notifications */ |
610 /* reattach appropriate notifications */ |
| 610 notify(conv, FALSE); |
611 notify(conv, FALSE); |
| 611 } |
612 } |
| 612 } |
613 } |