Mercurial > pidgin.yaz
comparison src/buddy.c @ 4840:a701ef925850
[gaim-migrate @ 5165]
Some tray icon fixes from Robert "the monarch" McQueen:
"- put back code for saving and restoring the position of the blist
- some robustness fixes to avoid crashes or ending up with a gaim
process with no visible windows
- trivial tweaks to docklet debug output
- hidden Trojan horses"
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Mar 2003 16:58:09 +0000 |
parents | 3411fdaa54fa |
children | 7cdea492a16b |
comparison
equal
deleted
inserted
replaced
4839:7d8d3470e7d5 | 4840:a701ef925850 |
---|---|
54 #include "win32dep.h" | 54 #include "win32dep.h" |
55 #endif | 55 #endif |
56 | 56 |
57 static struct gaim_gtk_buddy_list *gtkblist = NULL; | 57 static struct gaim_gtk_buddy_list *gtkblist = NULL; |
58 | 58 |
59 /* Docklet nonsense */ | 59 /* part of the best damn Docklet code this side of Tahiti */ |
60 static gboolean gaim_gtk_blist_obscured = FALSE; | 60 static gboolean gaim_gtk_blist_obscured = FALSE; |
61 | 61 |
62 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); | 62 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
63 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); | 63 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); |
64 static char *gaim_get_tooltip_text(struct buddy *b); | 64 static char *gaim_get_tooltip_text(struct buddy *b); |
67 | 67 |
68 /*************************************************** | 68 /*************************************************** |
69 * Callbacks * | 69 * Callbacks * |
70 ***************************************************/ | 70 ***************************************************/ |
71 | 71 |
72 static void gaim_gtk_blist_destroy_cb() | 72 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) |
73 { | 73 { |
74 if (docklet_count) | 74 if (docklet_count) |
75 gaim_blist_set_visible(FALSE); | 75 gaim_blist_set_visible(FALSE); |
76 else | 76 else |
77 do_quit(); | 77 do_quit(); |
78 | |
79 /* we handle everything, event should not propogate further */ | |
80 return TRUE; | |
81 } | |
82 | |
83 static gboolean gtk_blist_save_prefs_cb(gpointer data) | |
84 { | |
85 save_prefs(); | |
86 | |
87 /* only run once */ | |
88 return FALSE; | |
89 } | |
90 | |
91 static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) | |
92 { | |
93 /* unfortunately GdkEventConfigure ignores the window gravity, but * | |
94 * the only way we have of setting the position doesn't. we have to * | |
95 * call get_position and get_size because they do pay attention to * | |
96 * the gravity. this is inefficient and I agree it sucks, but it's * | |
97 * more likely to work correctly. - Robot101 */ | |
98 gint x, y; | |
99 | |
100 /* check for visibility because when we aren't visible, this will * | |
101 * give us bogus (0,0) coordinates. - xOr */ | |
102 if (GTK_WIDGET_VISIBLE(w)) { | |
103 gtk_window_get_position(GTK_WINDOW(w), &x, &y); | |
104 | |
105 if (x != blist_pos.x || | |
106 y != blist_pos.y || | |
107 event->width != blist_pos.width || | |
108 event->height != blist_pos.height) { | |
109 blist_pos.x = x; | |
110 blist_pos.y = y; | |
111 blist_pos.width = event->width; | |
112 blist_pos.height = event->height; | |
113 | |
114 if (!g_main_context_find_source_by_user_data(NULL, >k_blist_save_prefs_cb)) { | |
115 g_timeout_add(5000, gtk_blist_save_prefs_cb, >k_blist_save_prefs_cb); | |
116 } | |
117 } | |
118 } | |
119 | |
120 /* continue to handle event normally */ | |
121 return FALSE; | |
122 } | |
123 | |
124 static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) | |
125 { | |
126 if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) | |
127 gaim_gtk_blist_obscured = TRUE; | |
128 else | |
129 gaim_gtk_blist_obscured = FALSE; | |
130 | |
131 /* continue to handle event normally */ | |
132 return FALSE; | |
78 } | 133 } |
79 | 134 |
80 static void gtk_blist_menu_info_cb(GtkWidget *w, struct buddy *b) | 135 static void gtk_blist_menu_info_cb(GtkWidget *w, struct buddy *b) |
81 { | 136 { |
82 serv_get_info(b->account->gc, b->name); | 137 serv_get_info(b->account->gc, b->name); |
883 g_free(esc); | 938 g_free(esc); |
884 | 939 |
885 return text; | 940 return text; |
886 } | 941 } |
887 | 942 |
943 static void gaim_gtk_blist_restore_position() | |
944 { | |
945 /* if the window exists, is hidden, we're saving positions, and the position is sane... */ | |
946 if(gtkblist && gtkblist->window && | |
947 !GTK_WIDGET_VISIBLE(gtkblist->window) && | |
948 blist_options & OPT_BLIST_SAVED_WINDOWS && | |
949 blist_pos.width != 0) { | |
950 /* ...check position is on screen... */ | |
951 if (blist_pos.x >= gdk_screen_width()) | |
952 blist_pos.x = gdk_screen_width() - 100; | |
953 else if (blist_pos.x < 0) | |
954 blist_pos.x = 100; | |
955 | |
956 if (blist_pos.y >= gdk_screen_height()) | |
957 blist_pos.y = gdk_screen_height() - 100; | |
958 else if (blist_pos.y < 0) | |
959 blist_pos.y = 100; | |
960 | |
961 /* ...and move it back. */ | |
962 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_pos.x, blist_pos.y); | |
963 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_pos.width, blist_pos.height); | |
964 } | |
965 } | |
966 | |
967 | |
888 /********************************************************************************** | 968 /********************************************************************************** |
889 * Public API Functions * | 969 * Public API Functions * |
890 **********************************************************************************/ | 970 **********************************************************************************/ |
891 static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist) | 971 static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist) |
892 { | 972 { |
938 } | 1018 } |
939 | 1019 |
940 gtkblist = GAIM_GTK_BLIST(list); | 1020 gtkblist = GAIM_GTK_BLIST(list); |
941 | 1021 |
942 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 1022 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
1023 gtk_window_set_gravity(GTK_WINDOW(gtkblist->window), GDK_GRAVITY_NORTH_WEST); | |
1024 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); | |
943 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); | 1025 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
944 | 1026 |
945 gtkblist->vbox = gtk_vbox_new(FALSE, 6); | 1027 gtkblist->vbox = gtk_vbox_new(FALSE, 6); |
946 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | 1028 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); |
947 | 1029 |
948 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gaim_gtk_blist_destroy_cb), NULL); | 1030 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
1031 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); | |
1032 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); | |
1033 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); | |
949 | 1034 |
950 /******************************* Menu bar *************************************/ | 1035 /******************************* Menu bar *************************************/ |
951 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | 1036 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); |
952 gtk_item_factory_set_translate_func (ift, | 1037 gtk_item_factory_set_translate_func (ift, |
953 item_factory_translate_func, | 1038 item_factory_translate_func, |
1061 gtk_size_group_add_widget(sg, button); | 1146 gtk_size_group_add_widget(sg, button); |
1062 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | 1147 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); |
1063 | 1148 |
1064 /* OK... let's show this bad boy. */ | 1149 /* OK... let's show this bad boy. */ |
1065 gaim_gtk_blist_refresh(list); | 1150 gaim_gtk_blist_refresh(list); |
1151 gaim_gtk_blist_restore_position(); | |
1066 gtk_widget_show_all(gtkblist->window); | 1152 gtk_widget_show_all(gtkblist->window); |
1067 | 1153 |
1068 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gtkblist->treeview), GTK_TREE_VIEW_COLUMN(expcol)); | 1154 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gtkblist->treeview), GTK_TREE_VIEW_COLUMN(expcol)); |
1069 gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(expcol), FALSE); | 1155 gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(expcol), FALSE); |
1070 | 1156 |
1355 gtkblist->timeout = 0; | 1441 gtkblist->timeout = 0; |
1356 } | 1442 } |
1357 | 1443 |
1358 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) | 1444 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1359 { | 1445 { |
1446 if (!(gtkblist && gtkblist->window)) | |
1447 return; | |
1448 | |
1360 if (show) { | 1449 if (show) { |
1450 gaim_gtk_blist_restore_position(); | |
1361 gtk_window_present(GTK_WINDOW(gtkblist->window)); | 1451 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
1362 } else { | 1452 } else { |
1363 if (!connections || docklet_count) { | 1453 if (!connections || docklet_count) { |
1364 #ifdef _WIN32 | 1454 #ifdef _WIN32 |
1365 wgaim_systray_minimize(gtkblist->window); | 1455 wgaim_systray_minimize(gtkblist->window); |
1373 | 1463 |
1374 void gaim_gtk_blist_docklet_toggle() { | 1464 void gaim_gtk_blist_docklet_toggle() { |
1375 /* Useful for the docklet plugin and also for the win32 tray icon*/ | 1465 /* Useful for the docklet plugin and also for the win32 tray icon*/ |
1376 /* This is called when one of those is clicked--it will show/hide the | 1466 /* This is called when one of those is clicked--it will show/hide the |
1377 buddy list/login window--depending on which is active */ | 1467 buddy list/login window--depending on which is active */ |
1378 if (connections && gtkblist) { | 1468 if (connections) { |
1379 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | 1469 if (gtkblist && gtkblist->window) { |
1380 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | 1470 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { |
1471 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1472 } else { | |
1473 #if _WIN32 | |
1474 wgaim_systray_maximize(gtkblist->window); | |
1475 #endif | |
1476 gaim_blist_set_visible(TRUE); | |
1477 } | |
1381 } else { | 1478 } else { |
1382 #if _WIN32 | 1479 /* we're logging in or something... do nothing */ |
1383 wgaim_systray_maximize(gtkblist->window); | 1480 /* or should I make the blist? */ |
1384 #endif | 1481 debug_printf("docklet_toggle called with connections but no blist!\n"); |
1385 gaim_blist_set_visible(TRUE); | 1482 } |
1386 } | 1483 } else if (mainwindow) { |
1387 } else if (connections) { | 1484 if (GTK_WIDGET_VISIBLE(mainwindow)) { |
1388 /* we're logging in or something... do nothing */ | |
1389 debug_printf("docklet_toggle called with connections but no blist!\n"); | |
1390 } else { | |
1391 if (mainwindow && GTK_WIDGET_VISIBLE(mainwindow)) { | |
1392 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { | 1485 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { |
1393 gtk_window_present(GTK_WINDOW(mainwindow)); | 1486 gtk_window_present(GTK_WINDOW(mainwindow)); |
1394 } else { | 1487 } else { |
1395 #if _WIN32 | 1488 #if _WIN32 |
1396 wgaim_systray_minimize(mainwindow); | 1489 wgaim_systray_minimize(mainwindow); |
1401 #if _WIN32 | 1494 #if _WIN32 |
1402 wgaim_systray_maximize(mainwindow); | 1495 wgaim_systray_maximize(mainwindow); |
1403 #endif | 1496 #endif |
1404 show_login(); | 1497 show_login(); |
1405 } | 1498 } |
1499 } else { | |
1500 show_login(); | |
1406 } | 1501 } |
1407 } | 1502 } |
1408 | 1503 |
1409 void gaim_gtk_blist_docklet_add() | 1504 void gaim_gtk_blist_docklet_add() |
1410 { | 1505 { |
1415 { | 1510 { |
1416 docklet_count--; | 1511 docklet_count--; |
1417 if (!docklet_count) { | 1512 if (!docklet_count) { |
1418 if (connections) { | 1513 if (connections) { |
1419 gaim_blist_set_visible(TRUE); | 1514 gaim_blist_set_visible(TRUE); |
1420 } else if(gtkblist && gtkblist->window) { | 1515 } else if (mainwindow) { |
1421 gtk_window_present(GTK_WINDOW(gtkblist->window)); | 1516 gtk_window_present(GTK_WINDOW(mainwindow)); |
1517 } else { | |
1518 show_login(); | |
1422 } | 1519 } |
1423 } | 1520 } |
1424 } | 1521 } |
1425 | 1522 |
1426 static struct gaim_blist_ui_ops blist_ui_ops = | 1523 static struct gaim_blist_ui_ops blist_ui_ops = |