pidgin/gtkstatusbox.c

changeset 33270
a6493d38dc28
parent 33257
eb15b7f78e32
child 33271
53bf180b9eb1
equal deleted inserted replaced
33269:1ea2edfac5e9 33270:a6493d38dc28
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);
1134 } 1134 }
1135 1135
1136 static gboolean 1136 static gboolean
1137 combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview) 1137 combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview)
1138 { 1138 {
1139 pidgin_status_box_popup(PIDGIN_STATUS_BOX(w)); 1139 pidgin_status_box_popup(PIDGIN_STATUS_BOX(w), (GdkEvent *)event);
1140 return TRUE; 1140 return TRUE;
1141 } 1141 }
1142 1142
1143 static gboolean 1143 static gboolean
1144 webview_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview) 1144 webview_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview)
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 {
1447 case GDK_KEY_Return: 1480 case GDK_KEY_Return:
1448 case GDK_KEY_KP_Enter: 1481 case GDK_KEY_KP_Enter:
1449 case GDK_KEY_KP_Space: 1482 case GDK_KEY_KP_Space:
1450 case GDK_KEY_space: 1483 case GDK_KEY_space:
1451 if (!box->popup_in_progress) { 1484 if (!box->popup_in_progress) {
1452 pidgin_status_box_popup (box); 1485 pidgin_status_box_popup(box, (GdkEvent *)event);
1453 box->popup_in_progress = TRUE; 1486 box->popup_in_progress = TRUE;
1454 } else { 1487 } else {
1455 pidgin_status_box_popdown(box); 1488 pidgin_status_box_popdown(box, (GdkEvent *)event);
1456 } 1489 }
1457 return TRUE; 1490 return TRUE;
1458 default: 1491 default:
1459 return FALSE; 1492 return FALSE;
1460 } 1493 }
1462 1495
1463 static gboolean 1496 static gboolean
1464 toggled_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *box) 1497 toggled_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *box)
1465 { 1498 {
1466 if (!box->popup_in_progress) 1499 if (!box->popup_in_progress)
1467 pidgin_status_box_popup (box); 1500 pidgin_status_box_popup(box, (GdkEvent *)event);
1468 else 1501 else
1469 pidgin_status_box_popdown(box); 1502 pidgin_status_box_popdown(box, (GdkEvent *)event);
1470 return TRUE; 1503 return TRUE;
1471 } 1504 }
1472 1505
1473 static void 1506 static void
1474 buddy_icon_set_cb(const char *filename, PidginStatusBox *box) 1507 buddy_icon_set_cb(const char *filename, PidginStatusBox *box)
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 {
1594 if (purple_savedstatus_get_current() != saved) 1627 if (purple_savedstatus_get_current() != saved)
1595 purple_savedstatus_delete_by_status(saved); 1628 purple_savedstatus_delete_by_status(saved);
1596 } 1629 }
1597 1630
1598 static void 1631 static void
1599 tree_view_delete_current_selection(PidginStatusBox *status_box, GtkTreePath *path) 1632 tree_view_delete_current_selection(PidginStatusBox *status_box, GtkTreePath *path, GdkEvent *event)
1600 { 1633 {
1601 GtkTreeIter iter; 1634 GtkTreeIter iter;
1602 gpointer data; 1635 gpointer data;
1603 PurpleSavedStatus *saved; 1636 PurpleSavedStatus *saved;
1604 gchar *msg; 1637 gchar *msg;
1629 _("Delete"), tree_view_delete_current_selection_cb, 1662 _("Delete"), tree_view_delete_current_selection_cb,
1630 _("Cancel"), NULL); 1663 _("Cancel"), NULL);
1631 1664
1632 g_free(msg); 1665 g_free(msg);
1633 1666
1634 pidgin_status_box_popdown(status_box); 1667 pidgin_status_box_popdown(status_box, event);
1635 } 1668 }
1636 1669
1637 static gboolean 1670 static gboolean
1638 treeview_button_release_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *status_box) 1671 treeview_button_release_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *status_box)
1639 { 1672 {
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 }
1666 NULL, NULL, NULL); 1699 NULL, NULL, NULL);
1667 1700
1668 if (!ret) 1701 if (!ret)
1669 return TRUE; /* clicked outside window? */ 1702 return TRUE; /* clicked outside window? */
1670 1703
1671 treeview_activate_current_selection(status_box, path); 1704 treeview_activate_current_selection(status_box, path, (GdkEvent *)event);
1672 gtk_tree_path_free (path); 1705 gtk_tree_path_free (path);
1673 1706
1674 return TRUE; 1707 return TRUE;
1675 } 1708 }
1676 1709
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;

mercurial