| 93 static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); |
93 static gboolean pidgin_status_box_expose_event (GtkWidget *widget, GdkEventExpose *event); |
| 94 #endif |
94 #endif |
| 95 static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); |
95 static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); |
| 96 static void pidgin_status_box_redisplay_buddy_icon(PidginStatusBox *status_box); |
96 static void pidgin_status_box_redisplay_buddy_icon(PidginStatusBox *status_box); |
| 97 static void pidgin_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); |
97 static void pidgin_status_box_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); |
| 98 static void pidgin_status_box_popup(PidginStatusBox *box); |
98 static void pidgin_status_box_popup(PidginStatusBox *box, GdkEvent *event); |
| 99 static void pidgin_status_box_popdown(PidginStatusBox *box); |
99 static void pidgin_status_box_popdown(PidginStatusBox *box, GdkEvent *event); |
| 100 |
100 |
| 101 static void do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift); |
101 static void do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift); |
| 102 static void icon_choose_cb(const char *filename, gpointer data); |
102 static void icon_choose_cb(const char *filename, gpointer data); |
| 103 static void remove_buddy_icon_cb(GtkWidget *w, PidginStatusBox *box); |
103 static void remove_buddy_icon_cb(GtkWidget *w, PidginStatusBox *box); |
| 104 static void choose_buddy_icon_cb(GtkWidget *w, PidginStatusBox *box); |
104 static void choose_buddy_icon_cb(GtkWidget *w, PidginStatusBox *box); |
| 1379 NULL); |
1379 NULL); |
| 1380 } |
1380 } |
| 1381 } |
1381 } |
| 1382 |
1382 |
| 1383 static gboolean |
1383 static gboolean |
| 1384 popup_grab_on_window (GdkWindow *window, |
1384 popup_grab_on_window(GdkWindow *window, GdkEvent *event) |
| 1385 guint32 activate_time) |
1385 { |
| 1386 { |
1386 guint32 activate_time = gdk_event_get_time(event); |
| 1387 if ((gdk_pointer_grab (window, TRUE, |
1387 #if GTK_CHECK_VERSION(3,0,0) |
| 1388 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
1388 GdkDevice *device = gdk_event_get_device(event); |
| 1389 GDK_POINTER_MOTION_MASK, |
1389 GdkGrabStatus status; |
| 1390 NULL, NULL, activate_time) == 0)) |
1390 |
| 1391 { |
1391 status = gdk_device_grab(device, window, GDK_OWNERSHIP_WINDOW, TRUE, |
| 1392 if (gdk_keyboard_grab (window, TRUE, activate_time) == 0) |
1392 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
| |
1393 GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | |
| |
1394 GDK_KEY_RELEASE_MASK, NULL, activate_time); |
| |
1395 if (status == GDK_GRAB_SUCCESS) { |
| |
1396 status = gdk_device_grab(gdk_device_get_associated_device(device), |
| |
1397 window, GDK_OWNERSHIP_WINDOW, TRUE, |
| |
1398 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
| |
1399 GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | |
| |
1400 GDK_KEY_RELEASE_MASK, NULL, activate_time); |
| |
1401 if (status == GDK_GRAB_SUCCESS) |
| |
1402 return TRUE; |
| |
1403 else |
| |
1404 gdk_device_ungrab(device, activate_time); |
| |
1405 } |
| |
1406 |
| |
1407 return FALSE; |
| |
1408 #else |
| |
1409 if ((gdk_pointer_grab(window, TRUE, |
| |
1410 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
| |
1411 GDK_POINTER_MOTION_MASK, |
| |
1412 NULL, NULL, activate_time) == 0)) |
| |
1413 { |
| |
1414 if (gdk_keyboard_grab(window, TRUE, activate_time) == 0) |
| 1393 return TRUE; |
1415 return TRUE; |
| 1394 else { |
1416 else { |
| 1395 gdk_display_pointer_ungrab (gdk_window_get_display (window), activate_time); |
1417 gdk_display_pointer_ungrab(gdk_window_get_display(window), |
| |
1418 activate_time); |
| 1396 return FALSE; |
1419 return FALSE; |
| 1397 } |
1420 } |
| 1398 } |
1421 } |
| 1399 |
1422 |
| 1400 return FALSE; |
1423 return FALSE; |
| 1401 } |
1424 #endif |
| 1402 |
1425 } |
| 1403 |
1426 |
| 1404 static void |
1427 |
| 1405 pidgin_status_box_popup(PidginStatusBox *box) |
1428 static void |
| |
1429 pidgin_status_box_popup(PidginStatusBox *box, GdkEvent *event) |
| 1406 { |
1430 { |
| 1407 int width, height, x, y; |
1431 int width, height, x, y; |
| 1408 pidgin_status_box_list_position (box, &x, &y, &width, &height); |
1432 pidgin_status_box_list_position (box, &x, &y, &width, &height); |
| 1409 |
1433 |
| 1410 gtk_widget_set_size_request (box->popup_window, width, height); |
1434 gtk_widget_set_size_request (box->popup_window, width, height); |
| 1411 gtk_window_move (GTK_WINDOW (box->popup_window), x, y); |
1435 gtk_window_move (GTK_WINDOW (box->popup_window), x, y); |
| 1412 gtk_widget_show(box->popup_window); |
1436 gtk_widget_show(box->popup_window); |
| 1413 gtk_widget_grab_focus (box->tree_view); |
1437 gtk_widget_grab_focus (box->tree_view); |
| 1414 if (!popup_grab_on_window (gtk_widget_get_window(box->popup_window), |
1438 if (!popup_grab_on_window(gtk_widget_get_window(box->popup_window), event)) { |
| 1415 GDK_CURRENT_TIME)) { |
|
| 1416 gtk_widget_hide (box->popup_window); |
1439 gtk_widget_hide (box->popup_window); |
| 1417 return; |
1440 return; |
| 1418 } |
1441 } |
| 1419 gtk_grab_add (box->popup_window); |
1442 gtk_grab_add (box->popup_window); |
| 1420 /*box->popup_in_progress = TRUE;*/ |
1443 /*box->popup_in_progress = TRUE;*/ |
| 1427 gtk_tree_path_free(path); |
1450 gtk_tree_path_free(path); |
| 1428 } |
1451 } |
| 1429 } |
1452 } |
| 1430 |
1453 |
| 1431 static void |
1454 static void |
| 1432 pidgin_status_box_popdown(PidginStatusBox *box) |
1455 pidgin_status_box_popdown(PidginStatusBox *box, GdkEvent *event) |
| 1433 { |
1456 { |
| |
1457 guint32 time; |
| |
1458 #if GTK_CHECK_VERSION(3,0,0) |
| |
1459 GdkDevice *device; |
| |
1460 #endif |
| 1434 gtk_widget_hide(box->popup_window); |
1461 gtk_widget_hide(box->popup_window); |
| 1435 box->popup_in_progress = FALSE; |
1462 box->popup_in_progress = FALSE; |
| 1436 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->toggle_button), |
1463 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), FALSE); |
| 1437 FALSE); |
1464 gtk_grab_remove(box->popup_window); |
| 1438 gtk_grab_remove (box->popup_window); |
1465 time = gdk_event_get_time(event); |
| 1439 gdk_pointer_ungrab(GDK_CURRENT_TIME); |
1466 #if GTK_CHECK_VERSION(3,0,0) |
| 1440 gdk_keyboard_ungrab(GDK_CURRENT_TIME); |
1467 device = gdk_event_get_device(event); |
| |
1468 gdk_device_ungrab(device, time); |
| |
1469 gdk_device_ungrab(gdk_device_get_associated_device(device), time); |
| |
1470 #else |
| |
1471 gdk_pointer_ungrab(time); |
| |
1472 gdk_keyboard_ungrab(time); |
| |
1473 #endif |
| 1441 } |
1474 } |
| 1442 |
1475 |
| 1443 static gboolean |
1476 static gboolean |
| 1444 toggle_key_press_cb(GtkWidget *widget, GdkEventKey *event, PidginStatusBox *box) |
1477 toggle_key_press_cb(GtkWidget *widget, GdkEventKey *event, PidginStatusBox *box) |
| 1445 { |
1478 { |
| 1572 { |
1605 { |
| 1573 buddy_icon_set_cb(value, (PidginStatusBox*) data); |
1606 buddy_icon_set_cb(value, (PidginStatusBox*) data); |
| 1574 } |
1607 } |
| 1575 |
1608 |
| 1576 static void |
1609 static void |
| 1577 treeview_activate_current_selection(PidginStatusBox *status_box, GtkTreePath *path) |
1610 treeview_activate_current_selection(PidginStatusBox *status_box, GtkTreePath *path, GdkEvent *event) |
| 1578 { |
1611 { |
| 1579 if (status_box->active_row) |
1612 if (status_box->active_row) |
| 1580 gtk_tree_row_reference_free(status_box->active_row); |
1613 gtk_tree_row_reference_free(status_box->active_row); |
| 1581 |
1614 |
| 1582 status_box->active_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(status_box->dropdown_store), path); |
1615 status_box->active_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(status_box->dropdown_store), path); |
| 1583 pidgin_status_box_popdown (status_box); |
1616 pidgin_status_box_popdown(status_box, event); |
| 1584 pidgin_status_box_changed(status_box); |
1617 pidgin_status_box_changed(status_box); |
| 1585 } |
1618 } |
| 1586 |
1619 |
| 1587 static void tree_view_delete_current_selection_cb(gpointer data) |
1620 static void tree_view_delete_current_selection_cb(gpointer data) |
| 1588 { |
1621 { |
| 1643 |
1676 |
| 1644 if (ewidget != status_box->tree_view) { |
1677 if (ewidget != status_box->tree_view) { |
| 1645 if (ewidget == status_box->toggle_button && |
1678 if (ewidget == status_box->toggle_button && |
| 1646 status_box->popup_in_progress && |
1679 status_box->popup_in_progress && |
| 1647 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (status_box->toggle_button))) { |
1680 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (status_box->toggle_button))) { |
| 1648 pidgin_status_box_popdown (status_box); |
1681 pidgin_status_box_popdown(status_box, (GdkEvent *)event); |
| 1649 return TRUE; |
1682 return TRUE; |
| 1650 } else if (ewidget == status_box->toggle_button) { |
1683 } else if (ewidget == status_box->toggle_button) { |
| 1651 status_box->popup_in_progress = TRUE; |
1684 status_box->popup_in_progress = TRUE; |
| 1652 } |
1685 } |
| 1653 |
1686 |
| 1654 /* released outside treeview */ |
1687 /* released outside treeview */ |
| 1655 if (ewidget != status_box->toggle_button) { |
1688 if (ewidget != status_box->toggle_button) { |
| 1656 pidgin_status_box_popdown (status_box); |
1689 pidgin_status_box_popdown(status_box, (GdkEvent *)event); |
| 1657 return TRUE; |
1690 return TRUE; |
| 1658 } |
1691 } |
| 1659 |
1692 |
| 1660 return FALSE; |
1693 return FALSE; |
| 1661 } |
1694 } |
| 1678 treeview_key_press_event(GtkWidget *widget, |
1711 treeview_key_press_event(GtkWidget *widget, |
| 1679 GdkEventKey *event, PidginStatusBox *box) |
1712 GdkEventKey *event, PidginStatusBox *box) |
| 1680 { |
1713 { |
| 1681 if (box->popup_in_progress) { |
1714 if (box->popup_in_progress) { |
| 1682 if (event->keyval == GDK_KEY_Escape) { |
1715 if (event->keyval == GDK_KEY_Escape) { |
| 1683 pidgin_status_box_popdown(box); |
1716 pidgin_status_box_popdown(box, (GdkEvent *)event); |
| 1684 return TRUE; |
1717 return TRUE; |
| 1685 } else { |
1718 } else { |
| 1686 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(box->tree_view)); |
1719 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(box->tree_view)); |
| 1687 GtkTreeIter iter; |
1720 GtkTreeIter iter; |
| 1688 GtkTreePath *path; |
1721 GtkTreePath *path; |
| 1689 |
1722 |
| 1690 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) { |
1723 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) { |
| 1691 gboolean ret = TRUE; |
1724 gboolean ret = TRUE; |
| 1692 path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter); |
1725 path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter); |
| 1693 if (event->keyval == GDK_KEY_Return) { |
1726 if (event->keyval == GDK_KEY_Return) { |
| 1694 treeview_activate_current_selection(box, path); |
1727 treeview_activate_current_selection(box, path, (GdkEvent *)event); |
| 1695 } else if (event->keyval == GDK_KEY_Delete) { |
1728 } else if (event->keyval == GDK_KEY_Delete) { |
| 1696 tree_view_delete_current_selection(box, path); |
1729 tree_view_delete_current_selection(box, path, (GdkEvent *)event); |
| 1697 } else |
1730 } else |
| 1698 ret = FALSE; |
1731 ret = FALSE; |
| 1699 |
1732 |
| 1700 gtk_tree_path_free (path); |
1733 gtk_tree_path_free (path); |
| 1701 return ret; |
1734 return ret; |