From: Matthias Clasen Date: Fri, 19 Aug 2022 19:55:10 +0000 (-0400) Subject: emojichooser: Fix arrow keynav X-Git-Tag: archive/raspbian/4.8.3+ds-2+rpi1~3^2~20^2~3^2~74^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=78eaad614a567049e7461e4a4f36d7381e4f06ba;p=gtk4.git 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 --- diff --git a/gtk/gtkemojichooser.c b/gtk/gtkemojichooser.c index adeb485c6c..103b2cc4f5 100644 --- a/gtk/gtkemojichooser.c +++ b/gtk/gtkemojichooser.c @@ -1042,6 +1042,34 @@ gtk_emoji_chooser_show (GtkWidget *widget) gtk_editable_set_text (GTK_EDITABLE (chooser->search_entry), ""); } +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, @@ -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; + } } }