aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'widgets')
-rw-r--r--widgets/misc/e-dateedit.c199
-rw-r--r--widgets/misc/e-map.c2
-rw-r--r--widgets/table/e-cell-combo.c167
-rw-r--r--widgets/table/e-cell-combo.h3
4 files changed, 285 insertions, 86 deletions
diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c
index e24d4137cb..dce571b57a 100644
--- a/widgets/misc/e-dateedit.c
+++ b/widgets/misc/e-dateedit.c
@@ -62,6 +62,9 @@ struct _EDateEditPrivate {
GtkWidget *none_button; /* This will only be visible if a
* 'None' date/time is permitted. */
+ GdkDevice *grabbed_keyboard;
+ GdkDevice *grabbed_pointer;
+
gboolean show_date;
gboolean show_time;
gboolean use_24_hour_format;
@@ -140,14 +143,15 @@ static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget,
static void e_date_edit_grab_focus (GtkWidget *widget);
static gint on_date_entry_key_press (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit);
static gint on_date_entry_key_release (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit);
static void on_date_button_clicked (GtkWidget *widget,
EDateEdit *dedit);
-static void e_date_edit_show_date_popup (EDateEdit *dedit);
+static void e_date_edit_show_date_popup (EDateEdit *dedit,
+ GdkEvent *event);
static void position_date_popup (EDateEdit *dedit);
static void on_date_popup_none_button_clicked (GtkWidget *button,
EDateEdit *dedit);
@@ -177,10 +181,10 @@ static gboolean e_date_edit_parse_time (EDateEdit *dedit,
static void on_date_edit_time_selected (GtkComboBox *combo,
EDateEdit *dedit);
static gint on_time_entry_key_press (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit);
static gint on_time_entry_key_release (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit);
static gint on_date_entry_focus_out (GtkEntry *entry,
GdkEventFocus *event,
@@ -339,6 +343,22 @@ date_edit_dispose (GObject *object)
dedit->priv->cal_popup = NULL;
}
+ if (dedit->priv->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (
+ dedit->priv->grabbed_keyboard,
+ GDK_CURRENT_TIME);
+ g_object_unref (dedit->priv->grabbed_keyboard);
+ dedit->priv->grabbed_keyboard = NULL;
+ }
+
+ if (dedit->priv->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ dedit->priv->grabbed_pointer,
+ GDK_CURRENT_TIME);
+ g_object_unref (dedit->priv->grabbed_pointer);
+ dedit->priv->grabbed_pointer = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_date_edit_parent_class)->dispose (object);
}
@@ -1354,19 +1374,31 @@ static void
on_date_button_clicked (GtkWidget *widget,
EDateEdit *dedit)
{
- e_date_edit_show_date_popup (dedit);
+ GdkEvent *event;
+
+ /* Obtain the GdkEvent that triggered
+ * the date button's "clicked" signal. */
+ event = gtk_get_current_event ();
+ e_date_edit_show_date_popup (dedit, event);
}
static void
-e_date_edit_show_date_popup (EDateEdit *dedit)
+e_date_edit_show_date_popup (EDateEdit *dedit,
+ GdkEvent *event)
{
EDateEditPrivate *priv;
ECalendar *calendar;
+ GdkDevice *event_device;
+ GdkDevice *assoc_device;
+ GdkDevice *keyboard_device;
+ GdkDevice *pointer_device;
GdkWindow *window;
+ GdkGrabStatus grab_status;
struct tm mtm;
const gchar *date_text;
GDate selected_day;
gboolean clear_selection = FALSE;
+ guint event_time;
priv = dedit->priv;
calendar = E_CALENDAR (priv->calendar);
@@ -1398,14 +1430,63 @@ e_date_edit_show_date_popup (EDateEdit *dedit)
gtk_grab_add (priv->cal_popup);
window = gtk_widget_get_window (priv->cal_popup);
- gdk_pointer_grab (
- window, TRUE,
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK,
- NULL, NULL, GDK_CURRENT_TIME);
- gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
- gdk_window_focus (window, GDK_CURRENT_TIME);
+
+ g_return_if_fail (priv->grabbed_keyboard == NULL);
+ g_return_if_fail (priv->grabbed_pointer == NULL);
+
+ event_device = gdk_event_get_device (event);
+ assoc_device = gdk_device_get_associated_device (event_device);
+
+ event_time = gdk_event_get_time (event);
+
+ if (gdk_device_get_source (event_device) == GDK_SOURCE_KEYBOARD) {
+ keyboard_device = event_device;
+ pointer_device = assoc_device;
+ } else {
+ keyboard_device = assoc_device;
+ pointer_device = event_device;
+ }
+
+ if (keyboard_device != NULL) {
+ grab_status = gdk_device_grab (
+ keyboard_device,
+ window,
+ GDK_OWNERSHIP_WINDOW,
+ TRUE,
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK,
+ NULL,
+ event_time);
+ if (grab_status == GDK_GRAB_SUCCESS) {
+ priv->grabbed_keyboard =
+ g_object_ref (keyboard_device);
+ }
+ }
+
+ if (pointer_device != NULL) {
+ grab_status = gdk_device_grab (
+ pointer_device,
+ window,
+ GDK_OWNERSHIP_WINDOW,
+ TRUE,
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL,
+ event_time);
+ if (grab_status == GDK_GRAB_SUCCESS) {
+ priv->grabbed_pointer =
+ g_object_ref (pointer_device);
+ } else if (priv->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (
+ priv->grabbed_keyboard,
+ event_time);
+ g_object_unref (priv->grabbed_keyboard);
+ priv->grabbed_keyboard = NULL;
+ }
+ }
+
+ gdk_window_focus (window, event_time);
}
/* This positions the date popup below and to the left of the arrow button,
@@ -1516,19 +1597,13 @@ on_date_popup_key_press (GtkWidget *widget,
GdkEventKey *event,
EDateEdit *dedit)
{
- GdkWindow *window;
-
- window = gtk_widget_get_window (dedit->priv->cal_popup);
-
- if (event->keyval != GDK_KEY_Escape) {
- gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
- return FALSE;
+ if (event->keyval == GDK_KEY_Escape) {
+ g_signal_stop_emission_by_name (widget, "key_press_event");
+ hide_date_popup (dedit);
+ return TRUE;
}
- g_signal_stop_emission_by_name (widget, "key_press_event");
- hide_date_popup (dedit);
-
- return TRUE;
+ return FALSE;
}
/* A mouse button has been pressed while the date popup is showing.
@@ -1583,8 +1658,22 @@ hide_date_popup (EDateEdit *dedit)
{
gtk_widget_hide (dedit->priv->cal_popup);
gtk_grab_remove (dedit->priv->cal_popup);
- gdk_pointer_ungrab (GDK_CURRENT_TIME);
- gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+ if (dedit->priv->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (
+ dedit->priv->grabbed_keyboard,
+ GDK_CURRENT_TIME);
+ g_object_unref (dedit->priv->grabbed_keyboard);
+ dedit->priv->grabbed_keyboard = NULL;
+ }
+
+ if (dedit->priv->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ dedit->priv->grabbed_pointer,
+ GDK_CURRENT_TIME);
+ g_object_unref (dedit->priv->grabbed_pointer);
+ dedit->priv->grabbed_pointer = NULL;
+ }
}
/* Clears the time popup and rebuilds it using the lower_hour, upper_hour
@@ -1737,21 +1826,26 @@ on_date_edit_time_selected (GtkComboBox *combo,
static gint
on_date_entry_key_press (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit)
{
- if (event->state & GDK_MOD1_MASK
- && (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down
- || event->keyval == GDK_KEY_Return)) {
- g_signal_stop_emission_by_name (
- widget, "key_press_event");
- e_date_edit_show_date_popup (dedit);
+ GdkModifierType event_state = 0;
+ guint event_keyval = 0;
+
+ gdk_event_get_keyval (key_event, &event_keyval);
+ gdk_event_get_state (key_event, &event_state);
+
+ if (event_state & GDK_MOD1_MASK
+ && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down
+ || event_keyval == GDK_KEY_Return)) {
+ g_signal_stop_emission_by_name (widget, "key_press_event");
+ e_date_edit_show_date_popup (dedit, key_event);
return TRUE;
}
/* If the user hits the return key emit a "date_changed" signal if
* needed. But let the signal carry on. */
- if (event->keyval == GDK_KEY_Return) {
+ if (event_keyval == GDK_KEY_Return) {
e_date_edit_check_date_changed (dedit);
return FALSE;
}
@@ -1761,20 +1855,25 @@ on_date_entry_key_press (GtkWidget *widget,
static gint
on_time_entry_key_press (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit)
{
GtkWidget *child;
+ GdkModifierType event_state = 0;
+ guint event_keyval = 0;
+
+ gdk_event_get_keyval (key_event, &event_keyval);
+ gdk_event_get_state (key_event, &event_state);
child = gtk_bin_get_child (GTK_BIN (dedit->priv->time_combo));
/* I'd like to use Alt+Up/Down for popping up the list, like Win32,
* but the combo steals any Up/Down keys, so we use Alt + Return. */
#if 0
- if (event->state & GDK_MOD1_MASK
- && (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down)) {
+ if (event_state & GDK_MOD1_MASK
+ && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down)) {
#else
- if (event->state & GDK_MOD1_MASK && event->keyval == GDK_KEY_Return) {
+ if (event_state & GDK_MOD1_MASK && event_keyval == GDK_KEY_Return) {
#endif
g_signal_stop_emission_by_name (widget, "key_press_event");
g_signal_emit_by_name (child, "activate", 0);
@@ -1783,10 +1882,8 @@ on_time_entry_key_press (GtkWidget *widget,
/* Stop the return key from emitting the activate signal, and check
* if we need to emit a "time_changed" signal. */
- if (event->keyval == GDK_KEY_Return) {
- g_signal_stop_emission_by_name (
- widget,
- "key_press_event");
+ if (event_keyval == GDK_KEY_Return) {
+ g_signal_stop_emission_by_name (widget, "key_press_event");
e_date_edit_check_time_changed (dedit);
return TRUE;
}
@@ -1796,7 +1893,7 @@ on_time_entry_key_press (GtkWidget *widget,
static gint
on_date_entry_key_release (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit)
{
e_date_edit_check_date_changed (dedit);
@@ -1805,13 +1902,15 @@ on_date_entry_key_release (GtkWidget *widget,
static gint
on_time_entry_key_release (GtkWidget *widget,
- GdkEventKey *event,
+ GdkEvent *key_event,
EDateEdit *dedit)
{
- if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down) {
- g_signal_stop_emission_by_name (
- widget,
- "key_release_event");
+ guint event_keyval = 0;
+
+ gdk_event_get_keyval (key_event, &event_keyval);
+
+ if (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down) {
+ g_signal_stop_emission_by_name (widget, "key_release_event");
e_date_edit_check_time_changed (dedit);
return TRUE;
}
diff --git a/widgets/misc/e-map.c b/widgets/misc/e-map.c
index ebccf385d7..b90c4f2e7b 100644
--- a/widgets/misc/e-map.c
+++ b/widgets/misc/e-map.c
@@ -735,7 +735,7 @@ e_map_button_release (GtkWidget *widget,
if (event->button != 1)
return FALSE;
- gdk_pointer_ungrab (event->time);
+ gdk_device_ungrab (event->device, event->time);
return TRUE;
}
diff --git a/widgets/table/e-cell-combo.c b/widgets/table/e-cell-combo.c
index cc72e90a20..b3e1c524cf 100644
--- a/widgets/table/e-cell-combo.c
+++ b/widgets/table/e-cell-combo.c
@@ -101,7 +101,7 @@ static gint e_cell_combo_button_release (GtkWidget *popup_window,
GdkEvent *button_event,
ECellCombo *ecc);
static gint e_cell_combo_key_press (GtkWidget *popup_window,
- GdkEventKey *event,
+ GdkEvent *key_event,
ECellCombo *ecc);
static void e_cell_combo_update_cell (ECellCombo *ecc);
static void e_cell_combo_restart_edit (ECellCombo *ecc);
@@ -221,9 +221,22 @@ e_cell_combo_dispose (GObject *object)
{
ECellCombo *ecc = E_CELL_COMBO (object);
- if (ecc->popup_window)
+ if (ecc->popup_window != NULL) {
gtk_widget_destroy (ecc->popup_window);
- ecc->popup_window = NULL;
+ ecc->popup_window = NULL;
+ }
+
+ if (ecc->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (ecc->grabbed_keyboard, GDK_CURRENT_TIME);
+ g_object_unref (ecc->grabbed_keyboard);
+ ecc->grabbed_keyboard = NULL;
+ }
+
+ if (ecc->grabbed_pointer != NULL) {
+ gdk_device_ungrab (ecc->grabbed_pointer, GDK_CURRENT_TIME);
+ g_object_unref (ecc->grabbed_pointer);
+ ecc->grabbed_pointer = NULL;
+ }
G_OBJECT_CLASS (e_cell_combo_parent_class)->dispose (object);
}
@@ -260,9 +273,15 @@ e_cell_combo_do_popup (ECellPopup *ecp,
{
ECellCombo *ecc = E_CELL_COMBO (ecp);
GtkTreeSelection *selection;
+ GdkGrabStatus grab_status;
GdkWindow *window;
- guint32 time;
- gint error_code;
+ GdkDevice *keyboard;
+ GdkDevice *pointer;
+ GdkDevice *event_device;
+ guint32 event_time;
+
+ g_return_val_if_fail (ecc->grabbed_keyboard == NULL, FALSE);
+ g_return_val_if_fail (ecc->grabbed_pointer == NULL, FALSE);
selection = gtk_tree_view_get_selection (
GTK_TREE_VIEW (ecc->popup_tree_view));
@@ -276,27 +295,65 @@ e_cell_combo_do_popup (ECellPopup *ecp,
g_signal_handlers_unblock_by_func (
selection, e_cell_combo_selection_changed, ecc);
- if (event->type == GDK_BUTTON_PRESS)
- time = event->button.time;
- else
- time = event->key.time;
-
window = gtk_widget_get_window (ecc->popup_tree_view);
- error_code = gdk_pointer_grab (
- window, TRUE,
- GDK_ENTER_NOTIFY_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON1_MOTION_MASK,
- NULL, NULL, time);
+ event_device = gdk_event_get_device (event);
+ event_time = gdk_event_get_time (event);
- if (error_code != 0)
- g_warning ("Failed to get pointer grab (%i)", error_code);
+ if (gdk_device_get_source (event_device) == GDK_SOURCE_KEYBOARD) {
+ keyboard = event_device;
+ pointer = gdk_device_get_associated_device (event_device);
+ } else {
+ keyboard = gdk_device_get_associated_device (event_device);
+ pointer = event_device;
+ }
+
+ if (pointer != NULL) {
+ grab_status = gdk_device_grab (
+ pointer,
+ window,
+ GDK_OWNERSHIP_NONE,
+ TRUE,
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON1_MOTION_MASK,
+ NULL,
+ event_time);
+
+ if (grab_status != GDK_GRAB_SUCCESS)
+ return FALSE;
+
+ ecc->grabbed_pointer = g_object_ref (pointer);
+ }
gtk_grab_add (ecc->popup_window);
- gdk_keyboard_grab (window, TRUE, time);
+
+ if (keyboard != NULL) {
+ grab_status = gdk_device_grab (
+ keyboard,
+ window,
+ GDK_OWNERSHIP_NONE,
+ TRUE,
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK,
+ NULL,
+ event_time);
+
+ if (grab_status != GDK_GRAB_SUCCESS) {
+ if (ecc->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ ecc->grabbed_pointer,
+ event_time);
+ g_object_unref (ecc->grabbed_pointer);
+ ecc->grabbed_pointer = NULL;
+ }
+ return FALSE;
+ }
+
+ ecc->grabbed_keyboard = g_object_ref (keyboard);
+ }
return TRUE;
}
@@ -597,8 +654,19 @@ e_cell_combo_button_press (GtkWidget *popup_window,
}
gtk_grab_remove (ecc->popup_window);
- gdk_pointer_ungrab (event_time);
- gdk_keyboard_ungrab (event_time);
+
+ if (ecc->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (ecc->grabbed_keyboard, event_time);
+ g_object_unref (ecc->grabbed_keyboard);
+ ecc->grabbed_keyboard = NULL;
+ }
+
+ if (ecc->grabbed_pointer != NULL) {
+ gdk_device_ungrab (ecc->grabbed_pointer, event_time);
+ g_object_unref (ecc->grabbed_pointer);
+ ecc->grabbed_pointer = NULL;
+ }
+
gtk_widget_hide (ecc->popup_window);
e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
@@ -639,9 +707,21 @@ e_cell_combo_button_release (GtkWidget *popup_window,
/* The button was released inside the list, so we hide the popup and
* update the cell to reflect the new selection. */
+
gtk_grab_remove (ecc->popup_window);
- gdk_pointer_ungrab (event_time);
- gdk_keyboard_ungrab (event_time);
+
+ if (ecc->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (ecc->grabbed_keyboard, event_time);
+ g_object_unref (ecc->grabbed_keyboard);
+ ecc->grabbed_keyboard = NULL;
+ }
+
+ if (ecc->grabbed_pointer != NULL) {
+ gdk_device_ungrab (ecc->grabbed_pointer, event_time);
+ g_object_unref (ecc->grabbed_pointer);
+ ecc->grabbed_pointer = NULL;
+ }
+
gtk_widget_hide (ecc->popup_window);
e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
@@ -657,30 +737,47 @@ e_cell_combo_button_release (GtkWidget *popup_window,
* pressed we hide the popup, and do not change the cell contents. */
static gint
e_cell_combo_key_press (GtkWidget *popup_window,
- GdkEventKey *event,
+ GdkEvent *key_event,
ECellCombo *ecc)
{
+ guint event_keyval = 0;
+ guint32 event_time;
+
+ gdk_event_get_keyval (key_event, &event_keyval);
+ event_time = gdk_event_get_time (key_event);
+
/* If the Escape key is pressed we hide the popup. */
- if (event->keyval != GDK_KEY_Escape
- && event->keyval != GDK_KEY_Return
- && event->keyval != GDK_KEY_KP_Enter
- && event->keyval != GDK_KEY_ISO_Enter
- && event->keyval != GDK_KEY_3270_Enter)
+ if (event_keyval != GDK_KEY_Escape
+ && event_keyval != GDK_KEY_Return
+ && event_keyval != GDK_KEY_KP_Enter
+ && event_keyval != GDK_KEY_ISO_Enter
+ && event_keyval != GDK_KEY_3270_Enter)
return FALSE;
- if (event->keyval == GDK_KEY_Escape &&
+ if (event_keyval == GDK_KEY_Escape &&
(!ecc->popup_window || !gtk_widget_get_visible (ecc->popup_window)))
return FALSE;
gtk_grab_remove (ecc->popup_window);
- gdk_pointer_ungrab (event->time);
- gdk_keyboard_ungrab (event->time);
+
+ if (ecc->grabbed_keyboard != NULL) {
+ gdk_device_ungrab (ecc->grabbed_keyboard, event_time);
+ g_object_unref (ecc->grabbed_keyboard);
+ ecc->grabbed_keyboard = NULL;
+ }
+
+ if (ecc->grabbed_pointer != NULL) {
+ gdk_device_ungrab (ecc->grabbed_pointer, event_time);
+ g_object_unref (ecc->grabbed_pointer);
+ ecc->grabbed_pointer = NULL;
+ }
+
gtk_widget_hide (ecc->popup_window);
e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
d (g_print ("%s: popup_shown = FALSE\n", __FUNCTION__));
- if (event->keyval != GDK_KEY_Escape)
+ if (event_keyval != GDK_KEY_Escape)
e_cell_combo_update_cell (ecc);
e_cell_combo_restart_edit (ecc);
diff --git a/widgets/table/e-cell-combo.h b/widgets/table/e-cell-combo.h
index ec77dcd6f0..3d2fb339de 100644
--- a/widgets/table/e-cell-combo.h
+++ b/widgets/table/e-cell-combo.h
@@ -63,6 +63,9 @@ struct _ECellCombo {
GtkWidget *popup_window;
GtkWidget *popup_scrolled_window;
GtkWidget *popup_tree_view;
+
+ GdkDevice *grabbed_keyboard;
+ GdkDevice *grabbed_pointer;
};
struct _ECellComboClass {