[gtk/BUG_popover_focus_from_another_window_GTK4] popover: fix focus when inside an unfocused window
- From: Nelson Benítez León <nbenitez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/BUG_popover_focus_from_another_window_GTK4] popover: fix focus when inside an unfocused window
- Date: Sat, 31 Aug 2019 06:16:11 +0000 (UTC)
commit 23011e3ffee69a5a6e8ff74659757b532c9d7404
Author: Nelson Benítez León <nbenitezl gmail com>
Date: Fri Aug 30 22:49:15 2019 -0400
popover: fix focus when inside an unfocused window
Fix popovers to properly gain focus when clicked
inside an unfocused window.
We use the GTK_PHASE_CAPTURE of the 'pressed' event
to early detect that the popover is being clicked
inside an inactive window, this allow us to present
the window (and be focused) before the normal signal
handlers for the popover click/pressed events are run
which would ultimately give focus to popover widget.
This fix works for both modal and 'non modal' popovers,
although for GTK4 we only benefit from the 'non modal'
case, as GTK4 (contrary to GTK3) hides the modal popovers
when the focus is changed to another application's window,
so it's only possible for a 'non modal' popover to be
clicked inside an unfocused window.
Fixes issue #1871
gtk/gtkpopover.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 3c211b0874..83bcb9e42b 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -110,6 +110,7 @@
#include "gtknative.h"
#include "gtkwidgetprivate.h"
#include "gtkeventcontrollerkey.h"
+#include "gtkgestureclick.h"
#include "gtkcssnodeprivate.h"
#include "gtkbindings.h"
#include "gtkenums.h"
@@ -544,6 +545,20 @@ node_style_changed_cb (GtkCssNode *node,
gtk_widget_queue_draw (widget);
}
+static void
+gtk_popover_click_gesture_pressed (GtkGestureClick *gesture,
+ gint n_press,
+ gdouble widget_x,
+ gdouble widget_y,
+ GtkPopover *popover)
+{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+ GtkWindow *rel_window = GTK_WINDOW (gtk_widget_get_root (priv->relative_to));
+
+ if (!gtk_window_is_active (rel_window) && gtk_widget_is_drawable (GTK_WIDGET (popover)))
+ gtk_window_present_with_time (rel_window, gtk_get_current_event_time ());
+}
+
static void
gtk_popover_init (GtkPopover *popover)
{
@@ -551,6 +566,7 @@ gtk_popover_init (GtkPopover *popover)
GtkWidget *widget = GTK_WIDGET (popover);
GtkEventController *controller;
GtkStyleContext *context;
+ GtkGesture *click_gesture;
priv->position = GTK_POS_BOTTOM;
priv->final_position = GTK_POS_BOTTOM;
@@ -572,6 +588,15 @@ gtk_popover_init (GtkPopover *popover)
G_CALLBACK (node_style_changed_cb), popover, 0);
g_object_unref (priv->arrow_node);
+ click_gesture = gtk_gesture_click_new ();
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (click_gesture), 0);
+ gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (click_gesture), TRUE);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (click_gesture),
+ GTK_PHASE_CAPTURE);
+ g_signal_connect (click_gesture, "pressed",
+ G_CALLBACK (gtk_popover_click_gesture_pressed), popover);
+ gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (click_gesture));
+
priv->contents_widget = gtk_gizmo_new ("contents",
measure_contents,
allocate_contents,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]