1
0
mirror of https://gitlab.gnome.org/GNOME/nautilus synced 2024-06-30 23:46:35 +00:00

toolbar: Handle modal-like entry focus

When the location entry is shown, we remember the previous focus widget
to restore the focus back into it when the location entry is hidden.

This only happens before or after asking the toolbar to show/hide it,
so, we can instead have the toolbar handle this behavior itself.

Replace the setter with explicit open and close methods which handle
the focus. These can also be conveniently used as callbacks.

This way, when the toolbar gets reused in the upcoming FileChooser
window, this behavior will also exist there.

Part of: https://gitlab.gnome.org/GNOME/nautilus/-/work_items/3431
This commit is contained in:
António Fernandes 2024-05-12 20:34:29 +01:00
parent a58739f30d
commit 911e366ca9
4 changed files with 47 additions and 70 deletions

View File

@ -51,6 +51,7 @@ struct _NautilusToolbar
GtkWidget *search_button_placeholder;
gboolean show_location_entry;
GtkWidget *focus_before_location_entry;
GtkWidget *sidebar_button;
gboolean show_sidebar_button;
@ -110,11 +111,43 @@ toolbar_update_appearance (NautilusToolbar *self)
search_global ? self->history_controls_placeholder : self->history_controls);
}
static void
on_location_entry_close (GtkWidget *close_button,
NautilusToolbar *self)
void
nautilus_toolbar_open_location_entry (NautilusToolbar *self)
{
nautilus_toolbar_set_show_location_entry (self, FALSE);
if (self->show_location_entry)
{
return;
}
/* Remember focus widget. */
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (self));
GtkWidget *focus_widget = (root != NULL) ? gtk_root_get_focus (root) : NULL;
g_set_weak_pointer (&self->focus_before_location_entry, focus_widget);
self->show_location_entry = TRUE;
toolbar_update_appearance (self);
gtk_widget_grab_focus (self->location_entry);
}
void
nautilus_toolbar_close_location_entry (NautilusToolbar *self)
{
if (!self->show_location_entry)
{
return;
}
self->show_location_entry = FALSE;
toolbar_update_appearance (self);
if (self->focus_before_location_entry != NULL)
{
/* Restore focus widget. */
gtk_widget_grab_focus (self->focus_before_location_entry);
g_clear_weak_pointer (&self->focus_before_location_entry);
}
}
static void
@ -142,7 +175,7 @@ on_location_entry_focus_leave (GtkEventControllerFocus *controller,
return;
}
nautilus_toolbar_set_show_location_entry (toolbar, FALSE);
nautilus_toolbar_close_location_entry (toolbar);
}
static void
@ -279,6 +312,8 @@ nautilus_toolbar_finalize (GObject *obj)
{
NautilusToolbar *self = NAUTILUS_TOOLBAR (obj);
g_clear_weak_pointer (&self->focus_before_location_entry);
g_signal_handlers_disconnect_by_func (nautilus_preferences,
toolbar_update_appearance, self);
@ -340,7 +375,7 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button);
gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button_placeholder);
gtk_widget_class_bind_template_callback (widget_class, on_location_entry_close);
gtk_widget_class_bind_template_callback (widget_class, nautilus_toolbar_close_location_entry);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TOOLBAR);
}
@ -364,17 +399,6 @@ nautilus_toolbar_get_location_entry (NautilusToolbar *self)
return self->location_entry;
}
void
nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
gboolean show_location_entry)
{
if (show_location_entry != self->show_location_entry)
{
self->show_location_entry = show_location_entry;
toolbar_update_appearance (self);
}
}
static void
box_remove_all_children (GtkBox *box)
{

View File

@ -39,8 +39,8 @@ GtkWidget *nautilus_toolbar_new (void);
GtkWidget *nautilus_toolbar_get_path_bar (NautilusToolbar *self);
GtkWidget *nautilus_toolbar_get_location_entry (NautilusToolbar *self);
void nautilus_toolbar_set_show_location_entry (NautilusToolbar *self,
gboolean show_location_entry);
void nautilus_toolbar_open_location_entry (NautilusToolbar *self);
void nautilus_toolbar_close_location_entry (NautilusToolbar *self);
void nautilus_toolbar_set_active_slot (NautilusToolbar *toolbar,
NautilusWindowSlot *slot);

View File

@ -120,9 +120,6 @@ struct _NautilusWindow
GtkWidget *network_address_bar;
/* focus widget before the location bar has been shown temporarily */
GtkWidget *last_focus_widget;
guint sidebar_width_handler_id;
gulong bookmarks_id;
gulong starred_id;
@ -631,33 +628,6 @@ nautilus_window_open_location_full (NautilusWindow *window,
nautilus_window_slot_open_location_full (target_slot, location, flags, selection);
}
static void
unset_focus_widget (NautilusWindow *window)
{
if (window->last_focus_widget != NULL)
{
g_object_remove_weak_pointer (G_OBJECT (window->last_focus_widget),
(gpointer *) &window->last_focus_widget);
window->last_focus_widget = NULL;
}
}
static void
remember_focus_widget (NautilusWindow *window)
{
GtkWidget *focus_widget;
focus_widget = gtk_window_get_focus (GTK_WINDOW (window));
if (focus_widget != NULL)
{
unset_focus_widget (window);
window->last_focus_widget = focus_widget;
g_object_add_weak_pointer (G_OBJECT (focus_widget),
(gpointer *) &(window->last_focus_widget));
}
}
static gboolean
nautilus_window_grab_focus (GtkWidget *widget)
{
@ -673,23 +643,11 @@ nautilus_window_grab_focus (GtkWidget *widget)
return GTK_WIDGET_CLASS (nautilus_window_parent_class)->grab_focus (widget);
}
static void
restore_focus_widget (NautilusWindow *window)
{
if (window->last_focus_widget != NULL)
{
gtk_widget_grab_focus (window->last_focus_widget);
unset_focus_widget (window);
}
}
static void
location_entry_cancel_callback (GtkWidget *widget,
NautilusWindow *window)
{
nautilus_toolbar_set_show_location_entry (NAUTILUS_TOOLBAR (window->toolbar), FALSE);
restore_focus_widget (window);
nautilus_toolbar_close_location_entry (NAUTILUS_TOOLBAR (window->toolbar));
}
static void
@ -697,9 +655,7 @@ location_entry_location_changed_callback (GtkWidget *widget,
GFile *location,
NautilusWindow *window)
{
nautilus_toolbar_set_show_location_entry (NAUTILUS_TOOLBAR (window->toolbar), FALSE);
restore_focus_widget (window);
nautilus_toolbar_close_location_entry (NAUTILUS_TOOLBAR (window->toolbar));
nautilus_window_open_location_full (window, location, 0, NULL, NULL);
}
@ -1080,12 +1036,9 @@ nautilus_window_ensure_location_entry (NautilusWindow *window)
{
GtkWidget *location_entry;
remember_focus_widget (window);
nautilus_toolbar_set_show_location_entry (NAUTILUS_TOOLBAR (window->toolbar), TRUE);
nautilus_toolbar_open_location_entry (NAUTILUS_TOOLBAR (window->toolbar));
location_entry = nautilus_toolbar_get_location_entry (NAUTILUS_TOOLBAR (window->toolbar));
gtk_widget_grab_focus (location_entry);
return location_entry;
}

View File

@ -39,7 +39,7 @@
<object class="GtkButton">
<property name="icon-name">window-close-symbolic</property>
<property name="tooltip_text" translatable="yes">Cancel</property>
<signal name="clicked" handler="on_location_entry_close"/>
<signal name="clicked" handler="nautilus_toolbar_close_location_entry" swapped="true"/>
</object>
</child>
</object>