at Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
* gtkfilesel.c: Maintain a list of directories like /afs we know contain only directories, and avoid stat'ing files in those directories. (Because stat'ing all files in /afs is extremely expensive) To support automounters, try to open directories, even if we couldn't find them when reading their parent directory.
This commit is contained in:
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
Sat Sep 12 10:44:06 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtkfilesel.c: Maintain a list of directories like
|
||||||
|
/afs we know contain only directories, and avoid
|
||||||
|
stat'ing files in those directories. (Because
|
||||||
|
stat'ing all files in /afs is extremely expensive)
|
||||||
|
|
||||||
|
To support automounters, try to open directories,
|
||||||
|
even if we couldn't find them when reading their
|
||||||
|
parent directory.
|
||||||
|
|
||||||
|
Thu Sep 3 10:29:03 1998 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
|
* gtk.m4: Conditionalize check for GTK_MAJOR_VERSION,
|
||||||
|
to allow the same gtk.m4 to work for 1.0.x and
|
||||||
|
1.1.x.
|
||||||
|
|
||||||
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
Fri Sep 11 15:25:10 1998 Lars Hamann <lars@gtk.org>
|
||||||
|
|
||||||
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
* gtk/gtkclist.c (gtk_clist_set_selectable): new function
|
||||||
|
4
TODO
4
TODO
@ -39,6 +39,8 @@ Bugs:
|
|||||||
|
|
||||||
* Expose events aren't being generated correctly for DND demo
|
* Expose events aren't being generated correctly for DND demo
|
||||||
|
|
||||||
|
* MappingNotify events produce warnings.
|
||||||
|
|
||||||
Additions:
|
Additions:
|
||||||
* implement keyboard navigation in menus
|
* implement keyboard navigation in menus
|
||||||
|
|
||||||
@ -272,4 +274,4 @@ Text/Edit widget:
|
|||||||
|
|
||||||
- "changed" emitted when doing deletes on empty Text widget.
|
- "changed" emitted when doing deletes on empty Text widget.
|
||||||
|
|
||||||
- Delete IC in editable->unrealize, not editable->finalize?
|
- Delete IC in editable->unrealize, not editable->finalize?
|
||||||
|
2
gtk.m4
2
gtk.m4
@ -89,6 +89,7 @@ main ()
|
|||||||
printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
|
printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
|
||||||
printf("*** before re-running configure\n");
|
printf("*** before re-running configure\n");
|
||||||
}
|
}
|
||||||
|
#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
|
||||||
else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
|
else if ((gtk_major_version != GTK_MAJOR_VERSION) ||
|
||||||
(gtk_minor_version != GTK_MINOR_VERSION) ||
|
(gtk_minor_version != GTK_MINOR_VERSION) ||
|
||||||
(gtk_micro_version != GTK_MICRO_VERSION))
|
(gtk_micro_version != GTK_MICRO_VERSION))
|
||||||
@ -98,6 +99,7 @@ main ()
|
|||||||
printf("*** library (version %d.%d.%d)\n",
|
printf("*** library (version %d.%d.%d)\n",
|
||||||
gtk_major_version, gtk_minor_version, gtk_micro_version);
|
gtk_major_version, gtk_minor_version, gtk_micro_version);
|
||||||
}
|
}
|
||||||
|
#endif /* defined (GTK_MAJOR_VERSION) ... */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((gtk_major_version > major) ||
|
if ((gtk_major_version > major) ||
|
||||||
|
134
gtk/gtkfilesel.c
134
gtk/gtkfilesel.c
@ -245,13 +245,18 @@ static gchar* cmpl_completion_fullname (gchar*, CompletionState* cm
|
|||||||
static CompletionDir* open_ref_dir (gchar* text_to_complete,
|
static CompletionDir* open_ref_dir (gchar* text_to_complete,
|
||||||
gchar** remaining_text,
|
gchar** remaining_text,
|
||||||
CompletionState* cmpl_state);
|
CompletionState* cmpl_state);
|
||||||
|
static gboolean check_dir (gchar *dir_name,
|
||||||
|
struct stat *result,
|
||||||
|
gboolean *stat_subdirs);
|
||||||
static CompletionDir* open_dir (gchar* dir_name,
|
static CompletionDir* open_dir (gchar* dir_name,
|
||||||
CompletionState* cmpl_state);
|
CompletionState* cmpl_state);
|
||||||
static CompletionDir* open_user_dir (gchar* text_to_complete,
|
static CompletionDir* open_user_dir (gchar* text_to_complete,
|
||||||
CompletionState *cmpl_state);
|
CompletionState *cmpl_state);
|
||||||
static CompletionDir* open_relative_dir (gchar* dir_name, CompletionDir* dir,
|
static CompletionDir* open_relative_dir (gchar* dir_name, CompletionDir* dir,
|
||||||
CompletionState *cmpl_state);
|
CompletionState *cmpl_state);
|
||||||
static CompletionDirSent* open_new_dir (gchar* dir_name, struct stat* sbuf);
|
static CompletionDirSent* open_new_dir (gchar* dir_name,
|
||||||
|
struct stat* sbuf,
|
||||||
|
gboolean stat_subdirs);
|
||||||
static gint correct_dir_fullname (CompletionDir* cmpl_dir);
|
static gint correct_dir_fullname (CompletionDir* cmpl_dir);
|
||||||
static gint correct_parent (CompletionDir* cmpl_dir,
|
static gint correct_parent (CompletionDir* cmpl_dir,
|
||||||
struct stat *sbuf);
|
struct stat *sbuf);
|
||||||
@ -1890,7 +1895,7 @@ open_relative_dir(gchar* dir_name,
|
|||||||
|
|
||||||
/* after the cache lookup fails, really open a new directory */
|
/* after the cache lookup fails, really open a new directory */
|
||||||
static CompletionDirSent*
|
static CompletionDirSent*
|
||||||
open_new_dir(gchar* dir_name, struct stat* sbuf)
|
open_new_dir(gchar* dir_name, struct stat* sbuf, gboolean stat_subdirs)
|
||||||
{
|
{
|
||||||
CompletionDirSent* sent;
|
CompletionDirSent* sent;
|
||||||
DIR* directory;
|
DIR* directory;
|
||||||
@ -1968,12 +1973,17 @@ open_new_dir(gchar* dir_name, struct stat* sbuf)
|
|||||||
path_buf[path_buf_len] = '/';
|
path_buf[path_buf_len] = '/';
|
||||||
strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name);
|
strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name);
|
||||||
|
|
||||||
if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))
|
if (stat_subdirs)
|
||||||
sent->entries[i].is_dir = 1;
|
{
|
||||||
|
if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))
|
||||||
|
sent->entries[i].is_dir = 1;
|
||||||
|
else
|
||||||
|
/* stat may fail, and we don't mind, since it could be a
|
||||||
|
* dangling symlink. */
|
||||||
|
sent->entries[i].is_dir = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* stat may fail, and we don't mind, since it could be a
|
sent->entries[i].is_dir = 1;
|
||||||
* dangling symlink. */
|
|
||||||
sent->entries[i].is_dir = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir);
|
qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir);
|
||||||
@ -1983,19 +1993,69 @@ open_new_dir(gchar* dir_name, struct stat* sbuf)
|
|||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
check_dir(gchar *dir_name, struct stat *result, gboolean *stat_subdirs)
|
||||||
|
{
|
||||||
|
/* A list of directories that we know only contain other directories.
|
||||||
|
* Trying to stat every file in these directories would be very
|
||||||
|
* expensive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
gchar *name;
|
||||||
|
gboolean present;
|
||||||
|
struct stat statbuf;
|
||||||
|
} no_stat_dirs[] = {
|
||||||
|
{ "/afs", FALSE, { 0 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
static gint n_no_stat_dirs = sizeof(no_stat_dirs) / sizeof(no_stat_dirs[0]);
|
||||||
|
static gboolean initialized = FALSE;
|
||||||
|
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
initialized = TRUE;
|
||||||
|
for (i=0; i<n_no_stat_dirs; i++)
|
||||||
|
{
|
||||||
|
if (stat(no_stat_dirs[i].name, &no_stat_dirs[i].statbuf) == 0)
|
||||||
|
no_stat_dirs[i].present = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stat(dir_name, result) < 0)
|
||||||
|
{
|
||||||
|
cmpl_errno = errno;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*stat_subdirs = TRUE;
|
||||||
|
for (i=0; i<n_no_stat_dirs; i++)
|
||||||
|
{
|
||||||
|
if (no_stat_dirs[i].present &&
|
||||||
|
(no_stat_dirs[i].statbuf.st_dev == result->st_dev) &&
|
||||||
|
(no_stat_dirs[i].statbuf.st_ino == result->st_ino))
|
||||||
|
{
|
||||||
|
*stat_subdirs = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* open a directory by absolute pathname */
|
/* open a directory by absolute pathname */
|
||||||
static CompletionDir*
|
static CompletionDir*
|
||||||
open_dir(gchar* dir_name, CompletionState* cmpl_state)
|
open_dir(gchar* dir_name, CompletionState* cmpl_state)
|
||||||
{
|
{
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
|
gboolean stat_subdirs;
|
||||||
CompletionDirSent *sent;
|
CompletionDirSent *sent;
|
||||||
GList* cdsl;
|
GList* cdsl;
|
||||||
|
|
||||||
if(stat(dir_name, &sbuf) < 0)
|
if (!check_dir (dir_name, &sbuf, &stat_subdirs))
|
||||||
{
|
return NULL;
|
||||||
cmpl_errno = errno;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cdsl = cmpl_state->directory_sent_storage;
|
cdsl = cmpl_state->directory_sent_storage;
|
||||||
|
|
||||||
@ -2011,7 +2071,7 @@ open_dir(gchar* dir_name, CompletionState* cmpl_state)
|
|||||||
cdsl = cdsl->next;
|
cdsl = cdsl->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
sent = open_new_dir(dir_name, &sbuf);
|
sent = open_new_dir(dir_name, &sbuf, stat_subdirs);
|
||||||
|
|
||||||
if (sent) {
|
if (sent) {
|
||||||
cmpl_state->directory_sent_storage =
|
cmpl_state->directory_sent_storage =
|
||||||
@ -2317,13 +2377,14 @@ find_completion_dir(gchar* text_to_complete,
|
|||||||
{
|
{
|
||||||
gchar* first_slash = strchr(text_to_complete, '/');
|
gchar* first_slash = strchr(text_to_complete, '/');
|
||||||
CompletionDir* dir = cmpl_state->reference_dir;
|
CompletionDir* dir = cmpl_state->reference_dir;
|
||||||
|
CompletionDir* next;
|
||||||
*remaining_text = text_to_complete;
|
*remaining_text = text_to_complete;
|
||||||
|
|
||||||
while(first_slash)
|
while(first_slash)
|
||||||
{
|
{
|
||||||
gint len = first_slash - *remaining_text;
|
gint len = first_slash - *remaining_text;
|
||||||
gint found = 0;
|
gint found = 0;
|
||||||
gint found_index = -1;
|
gchar *found_name = NULL; /* Quiet gcc */
|
||||||
gint i;
|
gint i;
|
||||||
gchar* pat_buf = g_new (gchar, len + 1);
|
gchar* pat_buf = g_new (gchar, len + 1);
|
||||||
|
|
||||||
@ -2344,40 +2405,37 @@ find_completion_dir(gchar* text_to_complete,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
found_index = i;
|
found_name = dir->sent->entries[i].entry_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(found)
|
if (!found)
|
||||||
{
|
{
|
||||||
CompletionDir* next = open_relative_dir(dir->sent->entries[found_index].entry_name,
|
/* Perhaps we are trying to open an automount directory */
|
||||||
dir, cmpl_state);
|
found_name = pat_buf;
|
||||||
|
|
||||||
if(!next)
|
|
||||||
{
|
|
||||||
g_free (pat_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
next->cmpl_parent = dir;
|
|
||||||
|
|
||||||
dir = next;
|
|
||||||
|
|
||||||
if(!correct_dir_fullname(dir))
|
|
||||||
{
|
|
||||||
g_free(pat_buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*remaining_text = first_slash + 1;
|
|
||||||
first_slash = strchr(*remaining_text, '/');
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
next = open_relative_dir(found_name, dir, cmpl_state);
|
||||||
|
|
||||||
|
if(!next)
|
||||||
{
|
{
|
||||||
g_free (pat_buf);
|
g_free (pat_buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next->cmpl_parent = dir;
|
||||||
|
|
||||||
|
dir = next;
|
||||||
|
|
||||||
|
if(!correct_dir_fullname(dir))
|
||||||
|
{
|
||||||
|
g_free(pat_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*remaining_text = first_slash + 1;
|
||||||
|
first_slash = strchr(*remaining_text, '/');
|
||||||
|
|
||||||
g_free (pat_buf);
|
g_free (pat_buf);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user