[gtk/nested-popover-menu] Fix up keynav in popover menus
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/nested-popover-menu] Fix up keynav in popover menus
- Date: Mon, 2 Sep 2019 08:14:51 +0000 (UTC)
commit e7974f35fda282ad01fb8345399cb09c16b2eeea
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Sep 2 09:13:33 2019 +0100
Fix up keynav in popover menus
Both arrow keys and activating a submenu-bearing
model button works as expected now.
gtk/gtkmodelbutton.c | 68 ++++++++++++++++++++++++++++++++++---------------
gtk/gtkpopover.c | 16 +++++++++++-
gtk/gtkpopovermenu.c | 22 +++++++++++++---
gtk/gtkpopovermenubar.c | 6 ++++-
4 files changed, 87 insertions(+), 25 deletions(-)
---
diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c
index c798b1d42d..90518252f1 100644
--- a/gtk/gtkmodelbutton.c
+++ b/gtk/gtkmodelbutton.c
@@ -935,6 +935,8 @@ close_menu (GtkModelButton *button)
}
}
+static void open_submenu (GtkPopover *popover);
+
static void
gtk_model_button_clicked (GtkButton *button)
{
@@ -946,7 +948,14 @@ gtk_model_button_clicked (GtkButton *button)
}
else if (model_button->popover != NULL)
{
- gtk_popover_popup (GTK_POPOVER (model_button->popover));
+ GtkPopoverMenu *menu;
+ GtkWidget *submenu;
+
+ menu = (GtkPopoverMenu *)gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER_MENU);
+ submenu = model_button->popover;
+ gtk_popover_popup (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, submenu);
+ gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
}
else if (model_button->role == GTK_BUTTON_ROLE_NORMAL)
{
@@ -1031,7 +1040,14 @@ gtk_model_button_focus (GtkWidget *widget,
button->role == GTK_BUTTON_ROLE_NORMAL &&
button->popover != NULL)
{
- gtk_popover_popup (GTK_POPOVER (button->popover));
+ GtkPopoverMenu *menu;
+ GtkWidget *submenu;
+
+ menu = GTK_POPOVER_MENU (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER_MENU));
+ submenu = button->popover;
+ gtk_popover_popup (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, submenu);
+ gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
return TRUE;
}
}
@@ -1191,34 +1207,46 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
}
static void
-close_submenus (GtkPopoverMenu *menu)
+close_submenus (GtkPopover *popover)
{
- GtkWidget *submenu;
+ GtkPopoverMenu *menu;
- submenu = gtk_popover_menu_get_open_submenu (menu);
- if (submenu)
+ if (GTK_IS_POPOVER_MENU (popover))
{
- close_submenus (GTK_POPOVER_MENU (submenu));
- gtk_popover_popdown (GTK_POPOVER (submenu));
- gtk_popover_menu_set_open_submenu (menu, NULL);
+ GtkWidget *submenu;
+
+ menu = GTK_POPOVER_MENU (popover);
+ submenu = gtk_popover_menu_get_open_submenu (menu);
+ if (submenu)
+ {
+ close_submenus (GTK_POPOVER (submenu));
+ gtk_popover_popdown (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, NULL);
+ }
}
}
static void
-open_submenu (GtkPopoverMenu *menu)
+open_submenu (GtkPopover *popover)
{
GtkWidget *active_item;
+ GtkPopoverMenu *menu;
- active_item = gtk_popover_menu_get_active_item (menu);
- if (GTK_IS_MODEL_BUTTON (active_item) &&
- GTK_MODEL_BUTTON (active_item)->popover)
+ if (GTK_IS_POPOVER_MENU (popover))
{
- GtkWidget *submenu;
+ menu = GTK_POPOVER_MENU (popover);
- submenu = GTK_MODEL_BUTTON (active_item)->popover;
- gtk_popover_popup (GTK_POPOVER (submenu));
- gtk_popover_menu_set_open_submenu (menu, submenu);
- gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
+ active_item = gtk_popover_menu_get_active_item (menu);
+ if (GTK_IS_MODEL_BUTTON (active_item) &&
+ GTK_MODEL_BUTTON (active_item)->popover)
+ {
+ GtkWidget *submenu;
+
+ submenu = GTK_MODEL_BUTTON (active_item)->popover;
+ gtk_popover_popup (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, submenu);
+ gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
+ }
}
}
@@ -1247,11 +1275,11 @@ enter_cb (GtkEventController *controller,
active_item = gtk_popover_menu_get_active_item (GTK_POPOVER_MENU (popover));
if (popover && (is || contains) && active_item != target)
{
- close_submenus (GTK_POPOVER_MENU (popover));
+ close_submenus (GTK_POPOVER (popover));
gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
- open_submenu (GTK_POPOVER_MENU (popover));
+ open_submenu (GTK_POPOVER (popover));
}
}
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 031e606c4c..db23eef002 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -107,6 +107,7 @@
#include "config.h"
#include "gtkpopoverprivate.h"
+#include "gtkpopovermenuprivate.h"
#include "gtknative.h"
#include "gtkwidgetprivate.h"
#include "gtkeventcontrollerkey.h"
@@ -362,6 +363,19 @@ gtk_popover_focus_out (GtkWidget *widget)
{
}
+static void
+close_menu (GtkPopover *popover)
+{
+ while (popover)
+ {
+ gtk_popover_popdown (popover);
+ if (GTK_IS_POPOVER_MENU (popover))
+ popover = gtk_popover_menu_get_parent_menu (GTK_POPOVER_MENU (popover));
+ else
+ popover = NULL;
+ }
+}
+
static gboolean
gtk_popover_key_pressed (GtkWidget *widget,
guint keyval,
@@ -370,7 +384,7 @@ gtk_popover_key_pressed (GtkWidget *widget,
{
if (keyval == GDK_KEY_Escape)
{
- gtk_popover_popdown (GTK_POPOVER (widget));
+ close_menu (GTK_POPOVER (widget));
return TRUE;
}
diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c
index bf3b701217..e059024460 100644
--- a/gtk/gtkpopovermenu.c
+++ b/gtk/gtkpopovermenu.c
@@ -203,14 +203,19 @@ static void
focus_out (GtkEventController *controller,
GdkCrossingMode mode,
GdkNotifyType detail,
- GtkPopover *popover)
+ GtkPopoverMenu *menu)
{
gboolean contains_focus;
g_object_get (controller, "contains-focus", &contains_focus, NULL);
if (!contains_focus)
- gtk_popover_popdown (popover);
+ {
+ if (menu->parent_menu &&
+ GTK_POPOVER_MENU (menu->parent_menu)->open_submenu == menu)
+ GTK_POPOVER_MENU (menu->parent_menu)->open_submenu = NULL;
+ gtk_popover_popdown (GTK_POPOVER (menu));
+ }
}
static void
@@ -345,10 +350,21 @@ gtk_popover_menu_focus (GtkWidget *widget,
}
else
{
+ if (GTK_POPOVER_MENU (widget)->open_submenu)
+ {
+ if (gtk_widget_child_focus (GTK_POPOVER_MENU (widget)->open_submenu, direction))
+ return TRUE;
+ return FALSE;
+ }
+
if (gtk_widget_focus_move (widget, direction))
return TRUE;
- if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
+ if (direction == GTK_DIR_LEFT || direction == GTK_DIR_RIGHT)
+ {
+ return FALSE;
+ }
+ else if (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN)
{
GtkWidget *p;
diff --git a/gtk/gtkpopovermenubar.c b/gtk/gtkpopovermenubar.c
index a406b24956..031bb60c80 100644
--- a/gtk/gtkpopovermenubar.c
+++ b/gtk/gtkpopovermenubar.c
@@ -314,7 +314,11 @@ gtk_popover_menu_bar_item_size_allocate (GtkWidget *widget,
static void
gtk_popover_menu_bar_item_activate (GtkPopoverMenuBarItem *item)
{
- gtk_popover_popup (GTK_POPOVER (item->popover));
+ GtkPopoverMenuBar *bar;
+
+ bar = GTK_POPOVER_MENU_BAR (gtk_widget_get_ancestor (GTK_WIDGET (item), GTK_TYPE_POPOVER_MENU_BAR));
+
+ set_active_item (bar, item, TRUE);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]