diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-08-19 15:55:10 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-08-19 15:55:10 -0400 |
commit | 78eaad614a567049e7461e4a4f36d7381e4f06ba (patch) | |
tree | 4982a7ff1eee221c631a3399d7379c5f14e3e41f | |
parent | 3a8e45963f6463743d5b00d130a21b7ec2ff3616 (diff) | |
download | gtk+-78eaad614a567049e7461e4a4f36d7381e4f06ba.tar.gz |
emojichooser: Fix arrow keynav
When some of the Emoji have been filtered out by
a search term, arrow keynav would behave oddly and
get stuck in invisible sections. Fix this by ignoring
any filtered out children when moving between
sections for arrow keynav.
Fixes: #5076
-rw-r--r-- | gtk/gtkemojichooser.c | 162 |
1 files changed, 110 insertions, 52 deletions
diff --git a/gtk/gtkemojichooser.c b/gtk/gtkemojichooser.c index adeb485c6c..103b2cc4f5 100644 --- a/gtk/gtkemojichooser.c +++ b/gtk/gtkemojichooser.c @@ -1043,6 +1043,34 @@ gtk_emoji_chooser_show (GtkWidget *widget) } static EmojiSection * +find_section (GtkEmojiChooser *chooser, + GtkWidget *box) +{ + if (box == chooser->recent.box) + return &chooser->recent; + else if (box == chooser->people.box) + return &chooser->people; + else if (box == chooser->body.box) + return &chooser->body; + else if (box == chooser->nature.box) + return &chooser->nature; + else if (box == chooser->food.box) + return &chooser->food; + else if (box == chooser->travel.box) + return &chooser->travel; + else if (box == chooser->activities.box) + return &chooser->activities; + else if (box == chooser->objects.box) + return &chooser->objects; + else if (box == chooser->symbols.box) + return &chooser->symbols; + else if (box == chooser->flags.box) + return &chooser->flags; + else + return NULL; +} + +static EmojiSection * find_next_section (GtkEmojiChooser *chooser, GtkWidget *box, gboolean down) @@ -1113,81 +1141,111 @@ keynav_failed (GtkWidget *box, GtkWidget *focus; GtkWidget *child; GtkWidget *sibling; + GtkAllocation alloc; int i; int column; - int n_columns = 7; int child_x; focus = gtk_root_get_focus (gtk_widget_get_root (box)); if (focus == NULL) return FALSE; - /* determine the number of columns */ - child_x = -1; - for (i = 0; i < 20; i++) - { - GtkAllocation alloc; - - gtk_widget_get_allocation (GTK_WIDGET (gtk_flow_box_get_child_at_index (GTK_FLOW_BOX (box), i)), - &alloc); - if (alloc.x > child_x) - child_x = alloc.x; - else - { - n_columns = i; - break; - } - } - - n_columns = MAX (n_columns, 1); - child = gtk_widget_get_ancestor (focus, GTK_TYPE_EMOJI_CHOOSER_CHILD); - i = 0; + column = 0; + child_x = G_MAXINT; for (sibling = gtk_widget_get_first_child (box); - sibling != child; + sibling; sibling = gtk_widget_get_next_sibling (sibling)) - i++; + { + if (!gtk_widget_get_child_visible (sibling)) + continue; - column = i % n_columns; + gtk_widget_get_allocation (sibling, &alloc); + + if (alloc.x < child_x) + column = 0; + else + column++; + + child_x = alloc.x; + + if (sibling == child) + break; + } if (direction == GTK_DIR_DOWN) - { - next = find_next_section (chooser, box, TRUE); - if (next == NULL) - return FALSE; - - i = 0; - for (sibling = gtk_widget_get_first_child (next->box); - sibling; - sibling = gtk_widget_get_next_sibling (sibling), i++) + { + next = find_section (chooser, box); + while (TRUE) { - if (i == column) + next = find_next_section (chooser, next->box, TRUE); + if (next == NULL) + return FALSE; + + i = 0; + child_x = G_MAXINT; + for (sibling = gtk_widget_get_first_child (next->box); + sibling; + sibling = gtk_widget_get_next_sibling (sibling)) { - gtk_widget_grab_focus (sibling); - return TRUE; + if (!gtk_widget_get_child_visible (sibling)) + continue; + + gtk_widget_get_allocation (sibling, &alloc); + + if (alloc.x < child_x) + i = 0; + else + i++; + + child_x = alloc.x; + + if (i == column) + { + gtk_widget_grab_focus (sibling); + return TRUE; + } } } } else if (direction == GTK_DIR_UP) { - next = find_next_section (chooser, box, FALSE); - if (next == NULL) - return FALSE; - - i = 0; - child = NULL; - for (sibling = gtk_widget_get_first_child (next->box); - sibling; - sibling = gtk_widget_get_next_sibling (sibling), i++) - { - if ((i % n_columns) == column) - child = sibling; - } - if (child) + next = find_section (chooser, box); + while (TRUE) { - gtk_widget_grab_focus (child); - return TRUE; + next = find_next_section (chooser, next->box, FALSE); + if (next == NULL) + return FALSE; + + i = 0; + child_x = G_MAXINT; + child = NULL; + for (sibling = gtk_widget_get_first_child (next->box); + sibling; + sibling = gtk_widget_get_next_sibling (sibling)) + { + if (!gtk_widget_get_child_visible (sibling)) + continue; + + gtk_widget_get_allocation (sibling, &alloc); + + if (alloc.x < child_x) + i = 0; + else + i++; + + child_x = alloc.x; + + if (i == column) + child = sibling; + } + + if (child) + { + gtk_widget_grab_focus (child); + return TRUE; + } } } |