From 418bbb268547e4111d7435286fa632d74f098863 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 22 Jun 2020 12:31:15 -0400 Subject: [PATCH 1/4] entrycompletion: Name the controllers This helps with debugging. --- gtk/gtkentrycompletion.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index e2128842db..8fdc9d0739 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -2335,10 +2335,12 @@ connect_completion_signals (GtkEntryCompletion *completion) GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (priv->entry)); controller = priv->entry_key_controller = gtk_event_controller_key_new (); + gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect (controller, "key-pressed", G_CALLBACK (gtk_entry_completion_key_pressed), completion); gtk_widget_add_controller (GTK_WIDGET (text), controller); controller = priv->entry_focus_controller = gtk_event_controller_focus_new (); + gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect_swapped (controller, "leave", G_CALLBACK (text_focus_out), completion); gtk_widget_add_controller (GTK_WIDGET (text), controller); From 9faaa5e8be929393edbd27d8ac38e228b3af43b8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 22 Jun 2020 12:46:12 -0400 Subject: [PATCH 2/4] Fix change notification for event controllers We were adding event controllers at the end, but announcing a change at the beginning, in gtk_widget_add_controller. Fix that by emitting ::items-changed for the position where we actually inserted the controller. --- gtk/gtkwidget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 55127a2ed7..2cedb2508f 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -11412,7 +11412,7 @@ gtk_widget_add_controller (GtkWidget *widget, g_ptr_array_add (priv->controllers, controller); if (priv->controller_observer) - gtk_list_list_model_item_added_at (priv->controller_observer, 0); + gtk_list_list_model_item_added_at (priv->controller_observer, priv->controllers->len - 1); } /** From 692cc42e1023ec439d2fa1a0b9456e8cbfe1cec8 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 22 Jun 2020 12:47:27 -0400 Subject: [PATCH 3/4] Add gtk_widget_prepend_controller Add a variant of gtk_widget_add_controller that inserts the controller at the beginning, instead of the end. This will be used in entry completion to make sure the entry completion key event handling supersedes the entry one while the popup is open. Keep this private for now, until we determine if it needs to be public api. --- gtk/gtkwidget.c | 17 +++++++++++++++++ gtk/gtkwidgetprivate.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 2cedb2508f..61ae38f0b5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -11415,6 +11415,23 @@ gtk_widget_add_controller (GtkWidget *widget, gtk_list_list_model_item_added_at (priv->controller_observer, priv->controllers->len - 1); } +void +gtk_widget_prepend_controller (GtkWidget *widget, + GtkEventController *controller) +{ + GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + + GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget); + + if (G_UNLIKELY (!priv->controllers)) + priv->controllers = g_ptr_array_new (); + + g_ptr_array_insert (priv->controllers, 0, controller); + + if (priv->controller_observer) + gtk_list_list_model_item_added_at (priv->controller_observer, 0); +} + /** * gtk_widget_remove_controller: * @widget: a #GtkWidget diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index e7688a65cd..d281dd0f43 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -346,6 +346,9 @@ gboolean gtk_widget_run_controllers (GtkWidget double x, double y, GtkPropagationPhase phase); + +void gtk_widget_prepend_controller (GtkWidget *widget, + GtkEventController *controller); void gtk_widget_handle_crossing (GtkWidget *widget, const GtkCrossingData *crossing, double x, From 53a30eaa12e44a2ee5da7c9bc9a23a8bfeb733dc Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 22 Jun 2020 12:48:42 -0400 Subject: [PATCH 4/4] entry completion: Make keynav work again Use gtk_widget_prepend_controller to supersede entry keynav while the popup is open. This fixes selecting completions with the keyboard - the Enter keypress was ending up triggering GtkText::activate instead of inserting the selected completion into the entry. --- gtk/gtkentrycompletion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index 8fdc9d0739..d2f849a213 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -2338,7 +2338,7 @@ connect_completion_signals (GtkEntryCompletion *completion) gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect (controller, "key-pressed", G_CALLBACK (gtk_entry_completion_key_pressed), completion); - gtk_widget_add_controller (GTK_WIDGET (text), controller); + gtk_widget_prepend_controller (GTK_WIDGET (text), controller); controller = priv->entry_focus_controller = gtk_event_controller_focus_new (); gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect_swapped (controller, "leave", G_CALLBACK (text_focus_out), completion);