Commit 964a768b authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

Fix menu merging in the respect that only directories are merged and if a

Fri Feb 16 21:35:14 2001  George Lebl <jirka@5z.com>

	* menu-fentry.[ch], menu.c:  Fix menu merging in the respect that
	  only directories are merged and if a dir is in the .order file
	  it is not neccesairly on disk, so don't merge it until you find
	  it.  When directory disappears make sure to reread the
	  whole menu, and stat everything at most every 3 seconds.
	  fix dir_list corruption, and other cleanups
parent c4d733e0
Fri Feb 16 21:35:14 2001 George Lebl <jirka@5z.com>
* menu-fentry.[ch], menu.c: Fix menu merging in the respect that
only directories are merged and if a dir is in the .order file
it is not neccesairly on disk, so don't merge it until you find
it. When directory disappears make sure to reread the
whole menu, and stat everything at most every 3 seconds.
fix dir_list corruption, and other cleanups
Fri Feb 16 00:42:53 2001 George Lebl <jirka@5z.com> Fri Feb 16 00:42:53 2001 George Lebl <jirka@5z.com>
* floating-widget.c: The menu position function follows the * floating-widget.c: The menu position function follows the
......
Fri Feb 16 21:35:14 2001 George Lebl <jirka@5z.com>
* menu-fentry.[ch], menu.c: Fix menu merging in the respect that
only directories are merged and if a dir is in the .order file
it is not neccesairly on disk, so don't merge it until you find
it. When directory disappears make sure to reread the
whole menu, and stat everything at most every 3 seconds.
fix dir_list corruption, and other cleanups
Fri Feb 16 00:42:53 2001 George Lebl <jirka@5z.com> Fri Feb 16 00:42:53 2001 George Lebl <jirka@5z.com>
* floating-widget.c: The menu position function follows the * floating-widget.c: The menu position function follows the
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
/*#define PANEL_DEBUG 1*/ /*#define PANEL_DEBUG 1*/
/* the minimum number of seconds between stats of files */
#define STAT_EVERY 3
static GSList *dir_list = NULL; static GSList *dir_list = NULL;
static GMemChunk *file_chunk = NULL; static GMemChunk *file_chunk = NULL;
...@@ -42,9 +45,44 @@ init_fr_chunks (void) ...@@ -42,9 +45,44 @@ init_fr_chunks (void)
dir_chunk = g_mem_chunk_create (DirRec, 16, G_ALLOC_AND_FREE); dir_chunk = g_mem_chunk_create (DirRec, 16, G_ALLOC_AND_FREE);
} }
static GSList *
prepend_mfile (GSList *list, const char *name, gboolean merged,
gboolean verified)
{
MFile *mfile = g_new0 (MFile, 1);
mfile->name = g_strdup (name);
mfile->merged = merged;
mfile->verified = verified;
return g_slist_prepend (list, mfile);
}
/* merged is 1/0/-1 (-1 is don't care) */
static MFile *
find_mfile (GSList *list, const char *string, int merged)
{
GSList *li;
g_return_val_if_fail (string != NULL, NULL);
for (li = list; li != NULL; li = li->next) {
MFile *mfile = li->data;
if (mfile->name != NULL &&
strcmp (mfile->name, string) == 0 &&
(merged < 0 ||
(merged ? 1 : 0) == (mfile->merged ? 1 : 0)))
return mfile;
}
return NULL;
}
/*reads in the order file and makes a list*/ /*reads in the order file and makes a list*/
static GSList * static GSList *
get_presorted_from(GSList *list, const char *dir) get_presorted_from(GSList *list, const char *dir, gboolean merged)
{ {
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
char *fname = g_concat_dir_and_file(dir, ".order"); char *fname = g_concat_dir_and_file(dir, ".order");
...@@ -55,11 +93,20 @@ get_presorted_from(GSList *list, const char *dir) ...@@ -55,11 +93,20 @@ get_presorted_from(GSList *list, const char *dir)
return list; return list;
} }
while(fgets(buf, PATH_MAX+1, fp)!=NULL) { while(fgets(buf, PATH_MAX+1, fp)!=NULL) {
MFile *mfile;
char *p = strchr(buf, '\n'); char *p = strchr(buf, '\n');
if(p) if(p)
*p = '\0'; *p = '\0';
if( ! string_is_in_list(list, buf))
list = g_slist_prepend(list, g_strdup(buf)); if(is_ext (buf, ".desktop") ||
is_ext (buf, ".kdelnk")) {
mfile = find_mfile (list, buf, merged ? 1 : 0);
} else {
mfile = find_mfile (list, buf, -1);
}
if (mfile == NULL)
list = prepend_mfile (list, buf, merged, FALSE);
} }
fclose(fp); fclose(fp);
g_free(fname); g_free(fname);
...@@ -105,7 +152,7 @@ fr_get_mergedir (const char *dir) ...@@ -105,7 +152,7 @@ fr_get_mergedir (const char *dir)
} }
static GSList * static GSList *
read_directory (GSList *list, const char *menudir) read_directory (GSList *list, const char *menudir, gboolean merged)
{ {
DIR *dir; DIR *dir;
struct dirent *dent; struct dirent *dent;
...@@ -113,10 +160,34 @@ read_directory (GSList *list, const char *menudir) ...@@ -113,10 +160,34 @@ read_directory (GSList *list, const char *menudir)
dir = opendir (menudir); dir = opendir (menudir);
if (dir != NULL) { if (dir != NULL) {
while((dent = readdir (dir)) != NULL) { while((dent = readdir (dir)) != NULL) {
/* Skip over dot files, and duplicates */ MFile *mfile;
if (dent->d_name [0] != '.' &&
! string_is_in_list(list, dent->d_name)) if (dent->d_name[0] == '.')
list = g_slist_prepend(list, g_strdup(dent->d_name)); continue;
if(is_ext (dent->d_name, ".desktop") ||
is_ext (dent->d_name, ".kdelnk")) {
mfile = find_mfile (list, dent->d_name,
merged ? 1 : 0);
} else {
mfile = find_mfile (list, dent->d_name, -1);
/* if this is a bogus unmerged dir,
* then append it again for the merged */
if (mfile != NULL &&
merged &&
! mfile->merged &&
! mfile->verified)
mfile = NULL;
}
if (mfile == NULL)
list = prepend_mfile (list, dent->d_name,
merged, TRUE);
/* if this is the same merge foo and we've
* already foudn it in the presorted, just verify it */
else if ((mfile->merged ? 1 : 0) == (merged ? 1 : 0))
mfile->verified = TRUE;
} }
closedir(dir); closedir(dir);
...@@ -125,20 +196,42 @@ read_directory (GSList *list, const char *menudir) ...@@ -125,20 +196,42 @@ read_directory (GSList *list, const char *menudir)
return list; return list;
} }
void
free_mfile (MFile *mfile)
{
if (mfile != NULL) {
g_free (mfile->name);
mfile->name = NULL;
g_free (mfile);
}
}
void
free_mfile_list (GSList *list)
{
GSList *li;
for (li = list; li != NULL; li = li->next) {
free_mfile (li->data);
li->data = NULL;
}
g_slist_free (list);
}
GSList * GSList *
get_files_from_menudir(const char *menudir) get_mfiles_from_menudir (const char *menudir)
{ {
GSList *list = NULL; GSList *list = NULL;
char *mergedir; char *mergedir;
mergedir = fr_get_mergedir (menudir); mergedir = fr_get_mergedir (menudir);
list = get_presorted_from(list, menudir); list = get_presorted_from (list, menudir, FALSE /*merged*/);
list = read_directory(list, menudir); list = read_directory (list, menudir, FALSE /*merged*/);
if(mergedir != NULL) { if (mergedir != NULL) {
list = get_presorted_from(list, mergedir); list = get_presorted_from (list, mergedir, TRUE /*merged*/);
list = read_directory(list, mergedir); list = read_directory (list, mergedir, TRUE /*merged*/);
g_free (mergedir); g_free (mergedir);
} }
...@@ -229,10 +322,10 @@ fr_free (FileRec *fr, gboolean free_fr) ...@@ -229,10 +322,10 @@ fr_free (FileRec *fr, gboolean free_fr)
g_slist_free (dr->tryexecs); g_slist_free (dr->tryexecs);
dr->tryexecs = NULL; dr->tryexecs = NULL;
} }
dir_list = g_slist_remove (dir_list, fr);
} }
if (free_fr) { if (free_fr) {
dir_list = g_slist_remove (dir_list, fr);
if (fr->type == FILE_REC_DIR) if (fr->type == FILE_REC_DIR)
g_chunk_free (fr, dir_chunk); g_chunk_free (fr, dir_chunk);
else else
...@@ -274,32 +367,31 @@ fr_fill_dir(FileRec *fr, int sublevels) ...@@ -274,32 +367,31 @@ fr_fill_dir(FileRec *fr, int sublevels)
mergedir = fr_get_mergedir (fr->name); mergedir = fr_get_mergedir (fr->name);
flist = get_files_from_menudir(fr->name); flist = get_mfiles_from_menudir(fr->name);
while (flist != NULL) { while (flist != NULL) {
gboolean merged; gboolean merged;
char *short_name = flist->data; MFile *mfile = flist->data;
char *name = g_concat_dir_and_file(fr->name, short_name); char *name;
GSList *tmp = flist; GSList *tmp = flist;
flist = flist->next; flist = flist->next;
g_slist_free_1(tmp); g_slist_free_1(tmp);
merged = FALSE; if ( ! mfile->merged) {
name = g_concat_dir_and_file (fr->name, mfile->name);
} else if (mergedir != NULL) {
name = g_concat_dir_and_file (mergedir, mfile->name);
} else {
free_mfile (mfile);
continue;
}
merged = mfile->merged;
if (stat (name, &s) == -1) { if (stat (name, &s) == -1) {
g_free(name); g_free(name);
if (mergedir) { free_mfile (mfile);
name = g_concat_dir_and_file(mergedir, short_name); continue;
if (stat (name, &s) == -1) {
g_free(name);
g_free(short_name);
continue;
}
merged = TRUE;
} else {
g_free(short_name);
continue;
}
} }
g_free(short_name); free_mfile (mfile);
if (S_ISDIR (s.st_mode)) { if (S_ISDIR (s.st_mode)) {
if (merged) if (merged)
...@@ -388,7 +480,7 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat, ...@@ -388,7 +480,7 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat,
} }
fr = (FileRec *)dr; fr = (FileRec *)dr;
if (fr->last_stat < curtime-1) { if (fr->last_stat < curtime-STAT_EVERY) {
if (dstat == NULL) { if (dstat == NULL) {
if (stat (mdir, &s) == -1) { if (stat (mdir, &s) == -1) {
fr_free (fr, TRUE); fr_free (fr, TRUE);
...@@ -423,7 +515,7 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat, ...@@ -423,7 +515,7 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat,
s.st_mtime = 0; s.st_mtime = 0;
fname = g_concat_dir_and_file (mdir, ".directory"); fname = g_concat_dir_and_file (mdir, ".directory");
if (dr->dentrylast_stat >= curtime-1 || if (dr->dentrylast_stat >= curtime-STAT_EVERY ||
stat (fname, &s) != -1) { stat (fname, &s) != -1) {
GnomeDesktopEntry *dentry; GnomeDesktopEntry *dentry;
dentry = gnome_desktop_entry_load(fname); dentry = gnome_desktop_entry_load(fname);
...@@ -452,7 +544,9 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat, ...@@ -452,7 +544,9 @@ fr_read_dir (DirRec *dr, const char *mdir, struct stat *dstat,
} }
g_free (fname); g_free (fname);
dir_list = g_slist_prepend (dir_list, fr); /* add if missing from list of directories */
if (g_slist_find (dir_list, fr) == NULL)
dir_list = g_slist_prepend (dir_list, fr);
/*if this is a fake structure, so we don't actually look into /*if this is a fake structure, so we don't actually look into
the directory*/ the directory*/
...@@ -529,7 +623,7 @@ fr_check_and_reread (FileRec *fr) ...@@ -529,7 +623,7 @@ fr_check_and_reread (FileRec *fr)
curtime = time (NULL); curtime = time (NULL);
if ( ! reread && if ( ! reread &&
fr->last_stat < curtime-1) { fr->last_stat < curtime-STAT_EVERY) {
if(stat(fr->name, &ds)==-1) { if(stat(fr->name, &ds)==-1) {
fr_free (fr, TRUE); fr_free (fr, TRUE);
return NULL; return NULL;
...@@ -559,11 +653,19 @@ fr_check_and_reread (FileRec *fr) ...@@ -559,11 +653,19 @@ fr_check_and_reread (FileRec *fr)
ddr = (DirRec *)ffr; ddr = (DirRec *)ffr;
p = g_concat_dir_and_file(ffr->name, p = g_concat_dir_and_file(ffr->name,
".directory"); ".directory");
if (ddr->dentrylast_stat >= curtime-1) { if (ddr->dentrylast_stat >= curtime-STAT_EVERY) {
g_free (p); g_free (p);
break; break;
} }
dr->dentrylast_stat = curtime;
if(stat(p,&s)==-1) { if(stat(p,&s)==-1) {
/* perhaps the directory is gone */
if ( ! panel_file_exists (ffr->name)) {
reread = TRUE;
break;
}
/* if not, we're just now missing a
* desktop file */
if(dr->dentrymtime) { if(dr->dentrymtime) {
g_free(ffr->icon); g_free(ffr->icon);
ffr->icon = NULL; ffr->icon = NULL;
...@@ -600,18 +702,18 @@ fr_check_and_reread (FileRec *fr) ...@@ -600,18 +702,18 @@ fr_check_and_reread (FileRec *fr)
ffr->comment = NULL; ffr->comment = NULL;
} }
ddr->dentrymtime = s.st_mtime; ddr->dentrymtime = s.st_mtime;
dr->dentrylast_stat = curtime;
any_change = TRUE; any_change = TRUE;
} }
g_free(p); g_free(p);
break; break;
case FILE_REC_FILE: case FILE_REC_FILE:
if (ffr->last_stat >= curtime-1) if (ffr->last_stat >= curtime-STAT_EVERY)
break; break;
if(stat(ffr->name,&s)==-1) { if(stat(ffr->name,&s)==-1) {
reread = TRUE; reread = TRUE;
break; break;
} }
ffr->last_stat = curtime;
if(ffr->mtime != s.st_mtime) { if(ffr->mtime != s.st_mtime) {
GnomeDesktopEntry *dentry; GnomeDesktopEntry *dentry;
dentry = gnome_desktop_entry_load(ffr->name); dentry = gnome_desktop_entry_load(ffr->name);
...@@ -637,7 +739,6 @@ fr_check_and_reread (FileRec *fr) ...@@ -637,7 +739,6 @@ fr_check_and_reread (FileRec *fr)
break; break;
} }
ffr->mtime = s.st_mtime; ffr->mtime = s.st_mtime;
ffr->last_stat = curtime;
any_change = TRUE; any_change = TRUE;
} }
if (ffr->tryexec_path != NULL && if (ffr->tryexec_path != NULL &&
...@@ -646,12 +747,13 @@ fr_check_and_reread (FileRec *fr) ...@@ -646,12 +747,13 @@ fr_check_and_reread (FileRec *fr)
} }
break; break;
case FILE_REC_EXTRA: case FILE_REC_EXTRA:
if (ffr->last_stat >= curtime-1) if (ffr->last_stat >= curtime-STAT_EVERY)
break; break;
r = stat(ffr->name,&s); r = stat(ffr->name,&s);
if((r==-1 && ffr->mtime) || if((r==-1 && ffr->mtime) ||
(r!=-1 && ffr->mtime != s.st_mtime)) (r!=-1 && ffr->mtime != s.st_mtime))
reread = TRUE; reread = TRUE;
ffr->last_stat = curtime;
break; break;
} }
} }
......
...@@ -9,6 +9,7 @@ BEGIN_GNOME_DECLS ...@@ -9,6 +9,7 @@ BEGIN_GNOME_DECLS
typedef struct _MenuFinfo MenuFinfo; typedef struct _MenuFinfo MenuFinfo;
typedef struct _FileRec FileRec; typedef struct _FileRec FileRec;
typedef struct _DirRec DirRec; typedef struct _DirRec DirRec;
typedef struct _MFile MFile;
struct _MenuFinfo { struct _MenuFinfo {
char *menudir; char *menudir;
...@@ -21,6 +22,12 @@ struct _MenuFinfo { ...@@ -21,6 +22,12 @@ struct _MenuFinfo {
FileRec *fr; FileRec *fr;
}; };
struct _MFile {
char *name;
gboolean merged;
gboolean verified;
};
enum { enum {
FILE_REC_FILE, /*.desktop file record*/ FILE_REC_FILE, /*.desktop file record*/
FILE_REC_DIR, /*directory*/ FILE_REC_DIR, /*directory*/
...@@ -54,7 +61,7 @@ struct _DirRec { ...@@ -54,7 +61,7 @@ struct _DirRec {
char * get_applet_goad_id_from_dentry(GnomeDesktopEntry *ii); char * get_applet_goad_id_from_dentry(GnomeDesktopEntry *ii);
GSList * get_files_from_menudir(const char *menudir); GSList * get_mfiles_from_menudir(const char *menudir);
FileRec * fr_read_dir(DirRec *dr, const char *mdir, struct stat *dstat, struct stat *merge_dstat, int sublevels); FileRec * fr_read_dir(DirRec *dr, const char *mdir, struct stat *dstat, struct stat *merge_dstat, int sublevels);
FileRec * fr_replace(FileRec *fr); FileRec * fr_replace(FileRec *fr);
...@@ -65,6 +72,10 @@ char * fr_get_mergedir (const char *dir); ...@@ -65,6 +72,10 @@ char * fr_get_mergedir (const char *dir);
void fr_force_reread(void); void fr_force_reread(void);
void init_fr_chunks (void); void init_fr_chunks (void);
void free_mfile (MFile *mfile);
void free_mfile_list (GSList *list);
END_GNOME_DECLS END_GNOME_DECLS
#endif #endif
...@@ -202,7 +202,7 @@ about_cb (GtkWidget *widget, gpointer data) ...@@ -202,7 +202,7 @@ about_cb (GtkWidget *widget, gpointer data)
#endif #endif
about = gnome_about_new ( _("The GNOME Panel"), VERSION, about = gnome_about_new ( _("The GNOME Panel"), VERSION,
"(C) 1997-2000 the Free Software Foundation", _("(C) 1997-2000 the Free Software Foundation"),
(const gchar **)authors, (const gchar **)authors,
_("This program is responsible for launching " _("This program is responsible for launching "
"other applications, embedding small applets " "other applications, embedding small applets "
...@@ -983,6 +983,7 @@ add_drawers_from_dir (const char *dirname, const char *name, ...@@ -983,6 +983,7 @@ add_drawers_from_dir (const char *dirname, const char *name,
char *pixmap_name; char *pixmap_name;
char *p; char *p;
char *filename = NULL; char *filename = NULL;
char *mergedir;
GSList *list, *li; GSList *list, *li;
if(!panel_file_exists(dirname)) if(!panel_file_exists(dirname))
...@@ -1015,27 +1016,27 @@ add_drawers_from_dir (const char *dirname, const char *name, ...@@ -1015,27 +1016,27 @@ add_drawers_from_dir (const char *dirname, const char *name,
drawer = info->data; drawer = info->data;
g_assert(drawer); g_assert(drawer);
newpanel = PANEL_WIDGET(BASEP_WIDGET(drawer->drawer)->panel); newpanel = PANEL_WIDGET(BASEP_WIDGET(drawer->drawer)->panel);
mergedir = fr_get_mergedir(dirname);
list = get_files_from_menudir(dirname); list = get_mfiles_from_menudir(dirname);
for(li = list; li!= NULL; li = li->next) { for(li = list; li!= NULL; li = li->next) {
MFile *mfile = li->data;
struct stat s; struct stat s;
GnomeDesktopEntry *dentry; GnomeDesktopEntry *dentry;
g_free (filename); g_free (filename);
filename = g_concat_dir_and_file(dirname, li->data); if ( ! mfile->merged) {
filename = g_concat_dir_and_file(dirname, mfile->name);
} else if (mergedir != NULL) {
filename = g_concat_dir_and_file(mergedir, mfile->name);
} else {
filename = NULL;
continue;
}
if (stat (filename, &s) != 0) { if (stat (filename, &s) != 0) {
char *mergedir = fr_get_mergedir(dirname); continue;
if(mergedir != NULL) {
g_free(filename);
filename = g_concat_dir_and_file(mergedir, li->data);
g_free(mergedir);
if (stat (filename, &s) != 0) {
continue;
}
} else {
continue;
}
} }
if (S_ISDIR (s.st_mode)) { if (S_ISDIR (s.st_mode)) {
...@@ -1066,9 +1067,9 @@ add_drawers_from_dir (const char *dirname, const char *name, ...@@ -1066,9 +1067,9 @@ add_drawers_from_dir (const char *dirname, const char *name,
} }
} }
g_free (filename); g_free (filename);
g_free (mergedir);
g_slist_foreach (list, (GFunc)g_free, NULL); free_mfile_list (list);
g_slist_free (list);
} }
/*add a drawer with the contents of a menu to the panel*/ /*add a drawer with the contents of a menu to the panel*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment