summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-08-19 15:55:10 -0400
committerMatthias Clasen <mclasen@redhat.com>2022-08-19 15:55:10 -0400
commit78eaad614a567049e7461e4a4f36d7381e4f06ba (patch)
tree4982a7ff1eee221c631a3399d7379c5f14e3e41f
parent3a8e45963f6463743d5b00d130a21b7ec2ff3616 (diff)
downloadgtk+-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.c162
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;
+ }
}
}