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, &gtk_blist_save_prefs_cb)) {
115 g_timeout_add(5000, gtk_blist_save_prefs_cb, &gtk_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 =