[gtk/wip/matthiasc/popup2: 353/353] popup: Add a close keybinding, make grabs work
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup2: 353/353] popup: Add a close keybinding, make grabs work
- Date: Sun, 7 Apr 2019 16:53:02 +0000 (UTC)
commit 4b6cef7f18ab56391acebb0aa08aec31d64435a8
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Mar 19 12:35:52 2019 -0400
popup: Add a close keybinding, make grabs work
Making grabs work turned out to be a tricky timing thing.
We can't call move_to_rect in realize, since that will
already determine the surface type as a side-effect. Instead,
call seat_grab just-in-time in map, and call surface_show
in the grab prepare func.
gtk/gtkpopup.c | 51 +++++++++++++++++++++++++++++++++++++++++++--------
gtk/gtkpopup.h | 1 +
2 files changed, 44 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkpopup.c b/gtk/gtkpopup.c
index b1eeea5412..b957142399 100644
--- a/gtk/gtkpopup.c
+++ b/gtk/gtkpopup.c
@@ -52,6 +52,7 @@ typedef struct {
enum {
ACTIVATE_FOCUS,
ACTIVATE_DEFAULT,
+ CLOSE,
LAST_SIGNAL
};
@@ -184,7 +185,6 @@ surface_size_changed (GtkWindow *window,
guint width,
guint height)
{
- g_print ("new surface size %d %d\n", width, height);
}
static void
@@ -224,12 +224,6 @@ gtk_popup_realize (GtkWidget *widget)
priv->surface = gdk_surface_new_popup (priv->display, &parent_rect);
gdk_surface_set_transient_for (priv->surface, gtk_widget_get_surface (priv->relative_to));
gdk_surface_set_type_hint (priv->surface, GDK_SURFACE_TYPE_HINT_POPUP_MENU);
- gdk_surface_move_to_rect (priv->surface,
- &parent_rect,
- GDK_GRAVITY_SOUTH,
- GDK_GRAVITY_NORTH,
- GDK_ANCHOR_FLIP_Y,
- 0, 10);
gtk_widget_set_surface (widget, priv->surface);
g_signal_connect_swapped (priv->surface, "notify::state", G_CALLBACK (surface_state_changed), widget);
@@ -289,12 +283,35 @@ gtk_popup_hide (GtkWidget *widget)
gtk_widget_unmap (widget);
}
+static void
+grab_prepare_func (GdkSeat *seat,
+ GdkSurface *surface,
+ gpointer data)
+{
+ gdk_surface_show (surface);
+}
+
static void
gtk_popup_map (GtkWidget *widget)
{
GtkPopup *popup = GTK_POPUP (widget);
GtkPopupPrivate *priv = gtk_popup_get_instance_private (popup);
GtkWidget *child;
+ GdkRectangle parent_rect;
+
+ gdk_seat_grab (gdk_display_get_default_seat (priv->display),
+ priv->surface,
+ GDK_SEAT_CAPABILITY_ALL,
+ TRUE,
+ NULL, NULL, grab_prepare_func, NULL);
+
+ gtk_widget_get_surface_allocation (priv->relative_to, &parent_rect);
+ gdk_surface_move_to_rect (priv->surface,
+ &parent_rect,
+ GDK_GRAVITY_SOUTH,
+ GDK_GRAVITY_NORTH,
+ GDK_ANCHOR_FLIP_Y,
+ 0, 10);
GTK_WIDGET_CLASS (gtk_popup_parent_class)->map (widget);
@@ -302,7 +319,6 @@ gtk_popup_map (GtkWidget *widget)
if (child != NULL && gtk_widget_get_visible (child))
gtk_widget_map (child);
- gdk_surface_show (priv->surface);
gdk_surface_focus (priv->surface, gtk_get_current_event_time ());
}
@@ -316,6 +332,7 @@ gtk_popup_unmap (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_popup_parent_class)->unmap (widget);
gdk_surface_hide (priv->surface);
+ gdk_seat_ungrab (gdk_display_get_default_seat (priv->display));
child = gtk_bin_get_child (GTK_BIN (widget));
if (child != NULL)
@@ -456,6 +473,12 @@ gtk_popup_activate_focus (GtkPopup *popup)
gtk_root_activate_focus (GTK_ROOT (popup));
}
+static void
+gtk_popup_close (GtkPopup *popup)
+{
+ gtk_widget_hide (GTK_WIDGET (popup));
+}
+
static void
add_tab_bindings (GtkBindingSet *binding_set,
GdkModifierType modifiers,
@@ -497,6 +520,7 @@ gtk_popup_class_init (GtkPopupClass *klass)
klass->activate_default = gtk_popup_activate_default;
klass->activate_focus = gtk_popup_activate_focus;
+ klass->close = gtk_popup_close;
gtk_root_install_properties (object_class, 1);
@@ -520,6 +544,16 @@ gtk_popup_class_init (GtkPopupClass *klass)
G_TYPE_NONE,
0);
+ signals[CLOSE] =
+ g_signal_new (I_("close"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkPopupClass, close),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
+
binding_set = gtk_binding_set_by_class (klass);
add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
@@ -533,6 +567,7 @@ gtk_popup_class_init (GtkPopupClass *klass)
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "activate-default", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0, "activate-default", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "activate-default", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
}
GtkWidget *
diff --git a/gtk/gtkpopup.h b/gtk/gtkpopup.h
index c90f3597a4..f3755d4296 100644
--- a/gtk/gtkpopup.h
+++ b/gtk/gtkpopup.h
@@ -52,6 +52,7 @@ struct _GtkPopupClass
void (* activate_focus) (GtkPopup *popup);
void (* activate_default) (GtkPopup *popup);
+ void (* close) (GtkPopup *popup);
};
GDK_AVAILABLE_IN_ALL
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]