diff options
author | Ernestas Kulik <ernestask@gnome.org> | 2017-08-21 16:13:24 +0300 |
---|---|---|
committer | Ernestas Kulik <ernestask@gnome.org> | 2017-08-23 20:57:09 +0300 |
commit | 921cd365a92cf4c9a4edaeab00fa4966c09da93b (patch) | |
tree | 956e534ecb74ab24c251c5c7a60da14f7bac632c /src/nautilus-toolbar.c | |
parent | 3ec65acf4bb60ef2f0cf870f3f50e3555a5af371 (diff) | |
download | nautilus-921cd365a92cf4c9a4edaeab00fa4966c09da93b.tar.gz |
toolbar: hide location entry on lost focus
This solves the issue of the location entry remaining in the toolbar
if the user inadvertently (or not) tab-focuses a different widget.
https://bugzilla.gnome.org/show_bug.cgi?id=92509
Diffstat (limited to 'src/nautilus-toolbar.c')
-rw-r--r-- | src/nautilus-toolbar.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c index c8c58341c..a6d01b8cb 100644 --- a/src/nautilus-toolbar.c +++ b/src/nautilus-toolbar.c @@ -69,6 +69,7 @@ struct _NautilusToolbar GtkWidget *location_entry; gboolean show_location_entry; + gboolean location_entry_should_auto_hide; guint popup_timeout_id; guint start_operations_timeout_id; @@ -868,6 +869,51 @@ undo_manager_changed (NautilusToolbar *self) update_menu_item (self->redo_button, self, "redo", redo_active, redo_label); } +static gboolean +on_location_entry_populate_popup (GtkEntry *entry, + GtkWidget *widget, + gpointer user_data) +{ + NautilusToolbar *toolbar; + + toolbar = user_data; + + toolbar->location_entry_should_auto_hide = FALSE; + + return GDK_EVENT_PROPAGATE; +} + +static gboolean +on_location_entry_focus_out_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + NautilusToolbar *toolbar; + + toolbar = user_data; + + if (toolbar->location_entry_should_auto_hide) + { + nautilus_toolbar_set_show_location_entry (toolbar, FALSE); + } + + return GDK_EVENT_PROPAGATE; +} + +static gboolean +on_location_entry_focus_in_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + NautilusToolbar *toolbar; + + toolbar = user_data; + + toolbar->location_entry_should_auto_hide = TRUE; + + return GDK_EVENT_PROPAGATE; +} + static void nautilus_toolbar_init (NautilusToolbar *self) { @@ -878,6 +924,8 @@ nautilus_toolbar_init (NautilusToolbar *self) builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-toolbar-menu.ui"); menu_popover = GTK_WIDGET (gtk_builder_get_object (builder, "menu_popover")); + + self->window = NULL; self->view_menu_zoom_section = GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_zoom_section")); self->view_menu_undo_redo_section = GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_undo_redo_section")); self->view_menu_extended_section = GTK_WIDGET (gtk_builder_get_object (builder, "view_menu_extended_section")); @@ -918,6 +966,12 @@ nautilus_toolbar_init (NautilusToolbar *self) (GCallback) gtk_widget_grab_focus, NULL); g_signal_connect_swapped (self->operations_popover, "closed", (GCallback) gtk_widget_grab_focus, self); + g_signal_connect (self->location_entry, "populate-popup", + G_CALLBACK (on_location_entry_populate_popup), self); + g_signal_connect (self->location_entry, "focus-out-event", + G_CALLBACK (on_location_entry_focus_out_event), self); + g_signal_connect (self->location_entry, "focus-in-event", + G_CALLBACK (on_location_entry_focus_in_event), self); gtk_widget_show_all (GTK_WIDGET (self)); toolbar_update_appearance (self); @@ -962,6 +1016,58 @@ nautilus_toolbar_get_property (GObject *object, } } +/* The working assumption being made here is, if the location entry is visible, + * the user must have switched windows while having keyboard focus on the entry + * (because otherwise it would be invisible), + * so we focus the entry explicitly to reset the “should auto-hide” flag. + */ +static gboolean +on_window_focus_in_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + NautilusToolbar *toolbar; + + toolbar = user_data; + + if (g_settings_get_boolean (nautilus_preferences, + NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) + { + return GDK_EVENT_PROPAGATE; + } + + if (toolbar->show_location_entry) + { + gtk_widget_grab_focus (toolbar->location_entry); + } + + return GDK_EVENT_PROPAGATE; +} + +/* The location entry in general is hidden when it loses focus, + * but hiding it when switching windows could be undesirable, as the user + * might want to copy a path from somewhere. This here prevents that from happening. + */ +static gboolean +on_window_focus_out_event (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + NautilusToolbar *toolbar; + + toolbar = user_data; + + if (g_settings_get_boolean (nautilus_preferences, + NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) + { + return GDK_EVENT_PROPAGATE; + } + + toolbar->location_entry_should_auto_hide = FALSE; + + return GDK_EVENT_PROPAGATE; +} + static void nautilus_toolbar_set_property (GObject *object, guint property_id, @@ -974,7 +1080,21 @@ nautilus_toolbar_set_property (GObject *object, { case PROP_WINDOW: { + if (self->window != NULL) + { + g_signal_handlers_disconnect_by_func (self->window, + on_window_focus_in_event, self); + g_signal_handlers_disconnect_by_func (self->window, + on_window_focus_out_event, self); + } self->window = g_value_get_object (value); + if (self->window != NULL) + { + g_signal_connect (self->window, "focus-in-event", + G_CALLBACK (on_window_focus_in_event), self); + g_signal_connect (self->window, "focus-out-event", + G_CALLBACK (on_window_focus_out_event), self); + } } break; @@ -1008,6 +1128,11 @@ nautilus_toolbar_finalize (GObject *obj) g_signal_handlers_disconnect_by_data (self->progress_manager, self); g_clear_object (&self->progress_manager); + g_signal_handlers_disconnect_by_func (self->window, + on_window_focus_in_event, self); + g_signal_handlers_disconnect_by_func (self->window, + on_window_focus_out_event, self); + G_OBJECT_CLASS (nautilus_toolbar_parent_class)->finalize (obj); } |