summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hertzfeld <andy@src.gnome.org>2001-02-09 01:32:53 +0000
committerAndy Hertzfeld <andy@src.gnome.org>2001-02-09 01:32:53 +0000
commit4979687b9e750d04001bb6d362aa9558c7974d61 (patch)
tree5e35b8c2292d6590daf610fc1b70c0c8f9ae49e5
parent3ded80626185f5c4956e4fec240c6a652f17aea4 (diff)
downloadnautilus-4979687b9e750d04001bb6d362aa9558c7974d61.tar.gz
fixed bug 6369, sluggish keyboard response in location bar. I improved
* src/nautilus-location-bar.c,h: (get_file_info_list), (try_to_expand_path), (editable_key_press_callback), (real_activate), (destroy), (nautilus_location_bar_initialize), (nautilus_location_bar_new), (nautilus_location_bar_set_location), (nautilus_location_bar_get_location), (nautilus_location_bar_update_label): fixed bug 6369, sluggish keyboard response in location bar. I improved this in two different ways: the expansion code is deferred to idle time now, so it doesn't get in the way of fast typing. Also, the file info list is cached in memory, so it doesn't have to load it again for every keystroke. I also made the instance variables private, instead of being exposed in the .h file.
-rw-r--r--ChangeLog16
-rw-r--r--src/nautilus-location-bar.c132
-rw-r--r--src/nautilus-location-bar.h7
3 files changed, 119 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index f7249de5f..8b8a78fdf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2001-02-08 Andy Hertzfeld <andy@eazel.com>
+
+ * src/nautilus-location-bar.c,h: (get_file_info_list),
+ (try_to_expand_path), (editable_key_press_callback),
+ (real_activate), (destroy), (nautilus_location_bar_initialize),
+ (nautilus_location_bar_new), (nautilus_location_bar_set_location),
+ (nautilus_location_bar_get_location),
+ (nautilus_location_bar_update_label):
+
+ fixed bug 6369, sluggish keyboard response in location bar. I improved
+ this in two different ways: the expansion code is deferred to idle
+ time now, so it doesn't get in the way of fast typing. Also, the
+ file info list is cached in memory, so it doesn't have to load it
+ again for every keystroke. I also made the instance variables
+ private, instead of being exposed in the .h file.
+
2001-02-08 Robey Pointer <robey@eazel.com>
* components/services/install/nautilus-view/nautilus-service-instal
diff --git a/src/nautilus-location-bar.c b/src/nautilus-location-bar.c
index c991c4e4b..9a70f8bdf 100644
--- a/src/nautilus-location-bar.c
+++ b/src/nautilus-location-bar.c
@@ -23,6 +23,7 @@
* Author: Maciej Stachowiak <mjs@eazel.com>
* Ettore Perazzoli <ettore@gnu.org>
* Michael Meeks <michael@nuclecu.unam.mx>
+ * Andy Hertzfeld <andy@eazel.com>
*
*/
@@ -62,6 +63,18 @@ static const char untranslated_go_to_label[] = N_("Go To:");
#define LOCATION_LABEL _(untranslated_location_label)
#define GO_TO_LABEL _(untranslated_go_to_label)
+struct NautilusLocationBarDetails {
+ GtkLabel *label;
+ GtkEntry *entry;
+
+ char *last_location;
+
+ char *current_directory;
+ GList *file_info_list;
+
+ uint idle_id;
+};
+
enum {
NAUTILUS_DND_MC_DESKTOP_ICON,
NAUTILUS_DND_URI_LIST,
@@ -246,17 +259,42 @@ accumulate_name(char *full_name, char *candidate_name)
return result_name;
}
+/* utility routine to load the file info list for the current directory, if necessary */
+static void
+get_file_info_list (NautilusLocationBar *bar, const char* dir_name)
+{
+ GnomeVFSResult result;
+ if (nautilus_strcmp (bar->details->current_directory, dir_name) != 0) {
+ g_free (bar->details->current_directory);
+ if (bar->details->file_info_list) {
+ gnome_vfs_file_info_list_free (bar->details->file_info_list);
+ bar->details->file_info_list = NULL;
+ }
+
+ bar->details->current_directory = g_strdup (dir_name);
+ result = gnome_vfs_directory_list_load (&bar->details->file_info_list, dir_name,
+ GNOME_VFS_FILE_INFO_DEFAULT, NULL);
+ if (result != GNOME_VFS_OK) {
+ if (bar->details->file_info_list) {
+ gnome_vfs_file_info_list_free (bar->details->file_info_list);
+ bar->details->file_info_list = NULL;
+ }
+ }
+ }
+}
+
/* routine that performs the tab expansion using gnome-vfs. Extract the directory name and
incomplete basename, then iterate through the directory trying to complete it. If we
find something, add it to the entry */
-static void
-try_to_expand_path (GtkEditable *editable)
+static gboolean
+try_to_expand_path (NautilusLocationBar *bar)
{
- GnomeVFSResult result;
GnomeVFSFileInfo *current_file_info;
- GList *list, *element;
+ GList *element;
GnomeVFSURI *uri;
+ GtkEditable *editable;
+
int base_length;
int current_path_length;
int offset;
@@ -268,18 +306,20 @@ try_to_expand_path (GtkEditable *editable)
char *expand_text;
char *expand_name;
+ editable = GTK_EDITABLE (bar->details->entry);
user_location = gtk_editable_get_chars (editable, 0, -1);
+ bar->details->idle_id = 0;
/* if it's just '~' or '~/', don't expand because slash shouldn't be appended */
if (nautilus_strcmp (user_location, "~") == 0
|| nautilus_strcmp (user_location, "~/") == 0) {
- return;
+ return FALSE;
}
current_path = nautilus_make_uri_from_input (user_location);
if (!nautilus_istr_has_prefix (current_path, "file://")) {
g_free (current_path);
- return;
+ return FALSE;
}
current_path_length = strlen(current_path);
@@ -297,29 +337,27 @@ try_to_expand_path (GtkEditable *editable)
if (base_name == NULL) {
gnome_vfs_uri_unref (uri);
g_free (current_path);
- return;
+ return FALSE;
}
base_length = strlen (base_name);
dir_name = gnome_vfs_uri_extract_dirname (uri);
- /* get file info for the directory */
-
- result = gnome_vfs_directory_list_load (&list, dir_name,
- GNOME_VFS_FILE_INFO_DEFAULT, NULL);
- if (result != GNOME_VFS_OK) {
+ /* get file info for the directory, if it hasn't changed since last time */
+ get_file_info_list (bar, dir_name);
+ if (bar->details->file_info_list == NULL) {
g_free (dir_name);
g_free (base_name);
gnome_vfs_uri_unref (uri);
g_free (current_path);
- return;
+ return FALSE;
}
/* iterate through the directory, keeping the intersection of all the names that
have the current basename as a prefix. */
expand_text = NULL;
- for (element = list; element != NULL; element = element->next) {
+ for (element = bar->details->file_info_list; element != NULL; element = element->next) {
current_file_info = element->data;
if (nautilus_str_has_prefix (current_file_info->name, base_name)) {
if (current_file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
@@ -344,7 +382,8 @@ try_to_expand_path (GtkEditable *editable)
g_free (base_name);
g_free (current_path);
g_free (user_location);
- gnome_vfs_file_info_list_free (list);
+
+ return FALSE;
}
/* Until we have a more elegant solution, this is how we figure out if
@@ -397,6 +436,8 @@ editable_key_press_callback (GtkObject *object,
g_assert (n_args == 1);
g_assert (args != NULL);
+ bar = NAUTILUS_LOCATION_BAR (data);
+
editable = GTK_EDITABLE (object);
event = GTK_VALUE_POINTER (args[0]);
return_value_location = GTK_RETLOC_BOOL (args[1]);
@@ -408,14 +449,15 @@ editable_key_press_callback (GtkObject *object,
}
/* Only do an expand if we just handled a key that inserted
- * characters.
+ * characters. Do the expand at idle time to avoid slowing down typing
+ * when the directory is large.
*/
if (*return_value_location
+ && bar->details->idle_id <= 0
&& entry_would_have_inserted_characters (event)) {
- try_to_expand_path (editable);
+ bar->details->idle_id = gtk_idle_add ( (GtkFunction) try_to_expand_path, bar);
}
- bar = NAUTILUS_LOCATION_BAR (data);
nautilus_location_bar_update_label (bar);
}
@@ -427,7 +469,7 @@ real_activate (NautilusNavigationBar *navigation_bar)
bar = NAUTILUS_LOCATION_BAR (navigation_bar);
/* Put the keyboard focus in the text field when switching to this mode */
- gtk_widget_grab_focus (GTK_WIDGET (bar->entry));
+ gtk_widget_grab_focus (GTK_WIDGET (bar->details->entry));
}
static void
@@ -437,8 +479,21 @@ destroy (GtkObject *object)
bar = NAUTILUS_LOCATION_BAR (object);
- g_free (bar->last_location);
-
+ /* cancel the pending idle call, if any */
+ if (bar->details->idle_id > 0) {
+ gtk_idle_remove (bar->details->idle_id);
+ }
+
+ if (bar->details->file_info_list) {
+ gnome_vfs_file_info_list_free (bar->details->file_info_list);
+
+ }
+
+ g_free (bar->details->current_directory);
+
+ g_free (bar->details->last_location);
+ g_free (bar->details);
+
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}
@@ -466,6 +521,8 @@ nautilus_location_bar_initialize (NautilusLocationBar *bar)
GtkWidget *event_box;
GtkWidget *hbox;
+ bar->details = g_new0 (NautilusLocationBarDetails, 1);
+
hbox = gtk_hbox_new (0, FALSE);
event_box = gtk_event_box_new ();
@@ -520,8 +577,8 @@ nautilus_location_bar_initialize (NautilusLocationBar *bar)
gtk_widget_show_all (hbox);
- bar->label = GTK_LABEL (label);
- bar->entry = GTK_ENTRY (entry);
+ bar->details->label = GTK_LABEL (label);
+ bar->details->entry = GTK_ENTRY (entry);
}
@@ -536,7 +593,7 @@ nautilus_location_bar_new (NautilusWindow *window)
/* Clipboard */
nautilus_clipboard_set_up_editable
- (GTK_EDITABLE (location_bar->entry),
+ (GTK_EDITABLE (location_bar->details->entry),
nautilus_window_get_ui_container (window),
TRUE);
@@ -559,14 +616,25 @@ nautilus_location_bar_set_location (NautilusNavigationBar *navigation_bar,
* thus should not emit the LOCATION_CHANGED signal.*/
formatted_location = nautilus_format_uri_for_display (location);
- nautilus_entry_set_text (NAUTILUS_ENTRY (bar->entry),
+ nautilus_entry_set_text (NAUTILUS_ENTRY (bar->details->entry),
formatted_location);
g_free (formatted_location);
+ /* free up the cached file info from the previous location */
+ if (bar->details->current_directory) {
+ g_free (bar->details->current_directory);
+ bar->details->current_directory = NULL;
+ }
+
+ if (bar->details->file_info_list) {
+ gnome_vfs_file_info_list_free (bar->details->file_info_list);
+ bar->details->file_info_list = NULL;
+ }
+
/* remember the original location for later comparison */
- g_free (bar->last_location);
- bar->last_location = g_strdup (location);
+ g_free (bar->details->last_location);
+ bar->details->last_location = g_strdup (location);
nautilus_location_bar_update_label (bar);
}
@@ -590,7 +658,7 @@ nautilus_location_bar_get_location (NautilusNavigationBar *navigation_bar)
bar = NAUTILUS_LOCATION_BAR (navigation_bar);
- user_location = gtk_editable_get_chars (GTK_EDITABLE (bar->entry), 0, -1);
+ user_location = gtk_editable_get_chars (GTK_EDITABLE (bar->details->entry), 0, -1);
best_uri = nautilus_make_uri_from_input (user_location);
g_free (user_location);
return best_uri;
@@ -607,13 +675,13 @@ nautilus_location_bar_update_label (NautilusLocationBar *bar)
{
char *current_text, *current_location;
- current_text = gtk_entry_get_text (GTK_ENTRY (bar->entry));
+ current_text = gtk_entry_get_text (GTK_ENTRY (bar->details->entry));
current_location = nautilus_make_uri_from_input (current_text);
- if (nautilus_uris_match (bar->last_location, current_location)) {
- gtk_label_set_text (GTK_LABEL (bar->label), LOCATION_LABEL);
+ if (nautilus_uris_match (bar->details->last_location, current_location)) {
+ gtk_label_set_text (GTK_LABEL (bar->details->label), LOCATION_LABEL);
} else {
- gtk_label_set_text (GTK_LABEL (bar->label), GO_TO_LABEL);
+ gtk_label_set_text (GTK_LABEL (bar->details->label), GO_TO_LABEL);
}
g_free (current_location);
}
diff --git a/src/nautilus-location-bar.h b/src/nautilus-location-bar.h
index 1f419a473..d4e72537e 100644
--- a/src/nautilus-location-bar.h
+++ b/src/nautilus-location-bar.h
@@ -44,12 +44,11 @@
#define NAUTILUS_IS_LOCATION_BAR(obj) \
GTK_CHECK_TYPE (obj, NAUTILUS_TYPE_LOCATION_BAR)
+typedef struct NautilusLocationBarDetails NautilusLocationBarDetails;
+
typedef struct NautilusLocationBar {
NautilusNavigationBar parent;
-
- GtkLabel *label;
- GtkEntry *entry;
- char *last_location;
+ NautilusLocationBarDetails *details;
} NautilusLocationBar;
typedef struct {