summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErnestas Kulik <ernestask@gnome.org>2017-08-21 16:13:24 +0300
committerErnestas Kulik <ernestask@gnome.org>2017-08-23 20:57:09 +0300
commit921cd365a92cf4c9a4edaeab00fa4966c09da93b (patch)
tree956e534ecb74ab24c251c5c7a60da14f7bac632c
parent3ec65acf4bb60ef2f0cf870f3f50e3555a5af371 (diff)
downloadnautilus-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
-rw-r--r--src/nautilus-toolbar.c125
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);
}