Re: Menu and /etc/X11/applnk - again



> > Why doesn't the version of the panel in the CVS archive read
> > /etc/X11/applnk like the one from the Red Hat distribution does?
> >
> > I've tried to change the code to support this, but I'm not able to
> > figure out how. Is there a way to combine different directory structures
> > into one menu in the first place?
>
>         I can't answer your question, but I can suggest a path where
> you might find the answer. RH often patches the GNOME code to make it
> do RH-specific things. These patches are part of the source RPMs. If
> you want to find out what changes they've made, then try downloading
> the RH source RPM (or copy it from your CD) and installing it. There
> will be one or more tarballs and some patches.

Good idea! I have now been able to build a panel that will read /etc/X11/applnk
from the latest CVS sources by applying the changes from
gnome-core-1.0.6-mergerhmenus.patch included in the RedHat SRPM for gnome-core
1.0.55. Some manual intervention was necessary, though, mainly because the menu
code was split into several C files quite recently.

An updated diff is included below, in case someone finds it useful.

--
Toralf Lund <toralf@kscanners.no>   +47 66 85 51 22
Kongsberg Scanners AS               +47 66 85 51 00 (switchboard)
http://www.kscanners.no/~toralf     +47 66 85 51 01 (fax)


? panel/distdir
? panel/doc/distdir
? panel/doc/C/distdir
? panel/doc/C/figs/distdir
? panel/doc/tmpl/distdir
? panel/help/distdir
? panel/help/C/distdir
? panel/help/C/figs/distdir
? panel/help/C/figures/distdir
? panel/help/C/figures/figs/distdir
? panel/help/C/figures/newfigs/distdir
? panel/help/C/figures/newtest/distdir
? panel/help/C/figures/old/distdir
? panel/help/de/distdir
? panel/help/de/figures/distdir
? panel/help/it/distdir
? panel/help/it/figures/distdir
? panel/menu/distdir
Index: panel/menu-fentry.c
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu-fentry.c,v
retrieving revision 1.13
diff -r1.13 menu-fentry.c
30a31,92
> typedef struct _OrderEntry OrderEntry;
>  
> struct _OrderEntry {
> 	char *name;
>  	char *location;
> };
> 
> 
> /* Form a pretty name from a pathname */
> gchar *
> make_fullname (gchar *pathname)
> {
> 	char *p;
> 	char *itemname;
> 	itemname = g_strdup(g_basename(pathname));
> 	p = strrchr(itemname,'.');
> 	if(p) *p = '\0';
> 	return itemname;
> }
>  
> gint 
> fr_compare (gconstpointer a, gconstpointer b)
> {
> 	const FileRec *fr_a = a;
> 	const FileRec *fr_b = b;
> 	char *name_a;
>  	char *name_b;
> 	gint result;
> 
> 	if (fr_a->fullname)
> 		name_a = fr_a->fullname;
> 	else
> 		name_a = make_fullname (fr_a->name);
> 
> 	if (fr_b->fullname)
> 		name_b = fr_b->fullname;
> 	else
> 		name_b = make_fullname (fr_b->name);
> 
> 	result = g_strcasecmp (name_a, name_b);
>  
> 	if (!fr_a->fullname)
> 		g_free (name_a);
> 	if (!fr_b->fullname)
> 		g_free (name_b);
> 	
> 	return result;
> }
> 
> 
> static OrderEntry *
> find_order_entry (GSList *list, gchar *name)
> {
> 	while (list) {
> 		OrderEntry *entry = list->data;
> 		if (strcmp (name, entry->name) == 0)
> 			return entry;
> 		list = list->next;
> 	}
> 	return NULL;
> }
> 
51a114
> 	        OrderEntry *entry;
54c117,122
< 		list = g_slist_prepend(list,g_strdup(buf));
---
> 
>  		entry = g_new (OrderEntry, 1);
>  		entry->name = g_strdup(buf);
>  		entry->location = NULL;
>  		
> 		list = g_slist_prepend(list, entry);
60a129,167
> /* Find the files in the given directory that are not in
>  * the presort list pres or extra_files, and fill in entry->location 
>  * fields in the pres list. The full names are prepended in reverse
>  * order to 'result', and basenames to extra_files.
>  */
> static void
> get_additional_files_from (char *menudir, GSList *pres,
> 			   GSList **result, GSList **extra_files)
>   {
> 	DIR *dir = NULL;
>   	struct dirent *dent;
> 
> 	/* Get the files from the GNOME directory */
> 	if (menudir)
> 		dir = opendir (menudir);
>   	
> 	if (dir != NULL) {
> 		while((dent = readdir (dir)) != NULL) {
> 			OrderEntry *entry;
> 			
> 			/* Skip over dot files */
> 			if (dent->d_name [0] == '.')
> 				continue;
> 			entry = find_order_entry(pres,dent->d_name);
> 			if (entry) {
> 				if (!entry->location)
> 					entry->location = g_concat_dir_and_file (menudir, dent->d_name);
> 			} else if (!string_is_in_list (*extra_files, dent->d_name)) {
> 				*extra_files = g_slist_prepend(*extra_files, g_strdup (dent->d_name));
> 				*result = g_slist_prepend (*result, g_concat_dir_and_file (menudir, dent->d_name));
> 			}
> 		}
> 		closedir(dir);
> 	}
> }
> 
> /* Returns a list of all files in a given directory, omitting
>  * . files, and including files from the shadow directory
>  */
62c169
< get_files_from_menudir(char *menudir)
---
> get_files_from_menudir(char *menudir, gint *n_sorted)
64,80c171,203
< 	struct dirent *dent;
< 	DIR *dir;
< 	GSList *out = NULL;
< 	GSList *pres = NULL;
< 	
< 	dir = opendir (menudir);
< 	if (dir == NULL)
< 		return NULL;
< 	
< 	pres = get_presorted_from(menudir);
< 	
< 	while((dent = readdir (dir)) != NULL) {
< 		/* Skip over dot files */
< 		if (dent->d_name [0] == '.')
< 			continue;
< 		if(!string_is_in_list(pres,dent->d_name))
< 			out = g_slist_prepend(out,g_strdup(dent->d_name));
---
> 	GSList *out;
> 	GSList *extras;
> 	GSList *tmp_out;
> 	GSList *pres;
> 	GSList *pres2;
> 	GSList *tmp_list;
> 	char *maindir;
> 	char *shadowdir;
> 
> 	shadow_menudir (menudir, &maindir, &shadowdir);
>   	
> 	/* Form an order list from the two directories .order files
> 	 */
> 	if (shadowdir) {
> 		pres = get_presorted_from(shadowdir);
> 		pres2 = get_presorted_from(maindir);
> 
> 		tmp_list = pres2;
> 		while (tmp_list) {
> 			OrderEntry *entry = tmp_list->data;
> 			
> 			if (!find_order_entry(pres, entry->name))
> 				pres = g_slist_append (pres, entry);
> 			else {
> 				g_free (entry->name);
> 				g_free (entry);
> 			}
> 			tmp_list = tmp_list->next;
> 		}
> 		g_slist_free (pres2);
> 		
> 	} else {
> 		pres = get_presorted_from(maindir);
83,84c206,307
< 	closedir(dir);
< 	return g_slist_concat(pres,g_slist_reverse(out));
---
> 	/* Add unordered files
> 	 */
> 	out = NULL;
> 	extras = NULL;
> 	if (shadowdir)
> 		get_additional_files_from (shadowdir, pres, &out, &extras);
> 	get_additional_files_from (maindir, pres, &out, &extras);
> 	g_slist_foreach (extras, (GFunc)g_free, NULL);
> 	g_slist_free (extras);
> 
> 	out = g_slist_reverse (out);
> 
> 	/* Add the files in the order list
> 	 */
> 	tmp_out = NULL;
> 	tmp_list = pres;
> 	while (tmp_list) {
> 		OrderEntry *entry = tmp_list->data;
> 
> 		if (entry->location)
> 			tmp_out = g_slist_prepend (tmp_out, entry->location);
> 		g_free (entry->name);
> 		g_free (entry);
> 
> 		tmp_list = tmp_list->next;
> 	}
> 	g_slist_free (pres);
> 
> 	if (n_sorted)
> 		*n_sorted = g_slist_length (tmp_out);
> 	out = g_slist_concat (g_slist_reverse (tmp_out), out);
>   	
> 	if (shadowdir && shadowdir != menudir)
> 		g_free (shadowdir);
> 	if (maindir && maindir != menudir)
> 		g_free (maindir);
> 
> 	return out;
> }
> 
> /* Get the modification time for a menu directory, taking
>  * into account shadowing. Returns FALSE if neither the
>  * directory nor it's shadow exists.
>  */
> static gboolean
> get_menudir_modtime(char *menudir, time_t *result)
> {
> 	char *shadowdir;
> 	char *maindir;
> 	struct stat s;
> 	gboolean found = FALSE;
> 
> 	shadow_menudir (menudir, &maindir, &shadowdir);
> 
> 	if (stat (maindir, &s) != -1) {
> 		found = TRUE;
> 		*result = s.st_mtime;
> 	}
> 
> 	if (shadowdir && stat (shadowdir, &s) != -1) {
> 		if (!found) {
> 			found = TRUE;
> 			*result = s.st_mtime;
> 		} else
> 			*result = MAX (*result, s.st_mtime);
>   	}
>   
> 	if (shadowdir && shadowdir != menudir)
> 		g_free (shadowdir);
> 	if (maindir && maindir != menudir)
> 		g_free (maindir);
> 
> 	return found;
> }
> 
> /* Locate the .directory entry for the given menu directory */
> gchar *
> get_menudir_dot_directory(char *menudir)
> {
> 	gchar *fname = g_concat_dir_and_file(menudir, ".directory");
> 	gchar *mainfile, *shadow;
> 
> 	shadow_menudir (fname, &mainfile, &shadow);
> 
> 	if (shadow && g_file_exists (shadow)) {
> 		if (mainfile)
> 			g_free (mainfile);
> 		return shadow;
> 	}
> 
> 	if (g_file_exists (mainfile)) {
> 		if (shadow)
> 			g_free (shadow);
> 		return mainfile;
> 	}
> 	
> 	if (mainfile)
> 		g_free (mainfile);
> 	if (shadow)
> 		g_free (shadow);
> 	
> 	return NULL;
157c380
< 	GSList *flist;
---
> 	GSList *flist, *unsorted;
162c385,386
< 	
---
> 	gint index, n_sorted;
> 
176c400,402
< 	flist = get_files_from_menudir(fr->name);
---
> 	flist = get_files_from_menudir(fr->name, &n_sorted);
> 	unsorted = NULL;
> 	index = 0;	
178c404
< 		char *name = g_concat_dir_and_file(fr->name,flist->data);
---
> 		char *name = flist->data;
180d405
< 		g_free(flist->data);
183,187c408,412
< 		
< 		if (stat (name, &s) == -1) {
< 			g_free(name);
< 			continue;
< 		}
---
> 
> 		ffr = NULL;	
>   		
> 		if (stat (name, &s) == -1)
> 			goto next;
191,193d415
< 			g_free(name);
< 			if(ffr)
< 				dr->recs = g_slist_prepend(dr->recs,ffr);
198,202c420,421
< 				   strcmp(p, ".kdelnk") != 0)) {
< 				g_free(name);
< 				continue;
< 			}
< 
---
> 				   strcmp(p, ".kdelnk") != 0))
> 				goto next;
207a427
> 				name = NULL;
218,221c438
< 
< 				dr->recs = g_slist_prepend(dr->recs,ffr);
< 			} else
< 				g_free(name);
---
> 			}
223,224c440,457
< 	}
< 	dr->recs = g_slist_reverse(dr->recs);
---
> 	next:
> 		if (ffr) {
> 			if (index >= n_sorted)
> 				unsorted = g_slist_prepend (unsorted, ffr);
> 			else
>   				dr->recs = g_slist_prepend(dr->recs,ffr);
> 
> 			index++;
> 		} else {
> 			if (index < n_sorted)
> 				n_sorted--;
>   		}
> 
> 		if (name)
> 			g_free(name);
>   	}
> 	dr->recs = g_slist_concat (g_slist_reverse (dr->recs),
> 				   g_slist_sort (unsorted, fr_compare));
248c481,482
< 			if (stat (mdir, &s) == -1) {
---
> 			time_t mtime;
> 			if (!get_menudir_modtime(mdir, &mtime)) {
253c487
< 			fr->mtime = s.st_mtime;
---
> 			fr->mtime = mtime;
264c498
< 	fname = g_concat_dir_and_file(mdir,".directory");
---
> 	fname =  get_menudir_dot_directory(mdir);
266c500
< 	    stat (fname, &s) != -1) {
---
> 	    (fname && stat (fname, &s) != -1)) {
288c522,523
< 	g_free(fname);
---
> 	if (fname)
> 		g_free(fname);
332d566
< 		struct stat ds;
335c569,570
< 			if(stat(fr->name,&ds)==-1) {
---
> 			time_t mtime;
> 			if (!get_menudir_modtime(fr->name, &mtime)) {
339c574
< 			if(ds.st_mtime != fr->mtime)
---
> 			if(mtime != fr->mtime)
352,354c587,588
< 				p = g_concat_dir_and_file(ffr->name,
< 							  ".directory");
< 				if (ddr->dentrylast_stat >= curtime-1) {
---
> 				p = get_menudir_dot_directory(ffr->name);
> 				if(p && stat(p,&s)==-1) {
372,373c606,609
< 					GnomeDesktopEntry *dentry;
< 					dentry = gnome_desktop_entry_load(p);
---
> 					GnomeDesktopEntry *dentry = NULL;
> 					if (p)
> 						dentry = gnome_desktop_entry_load(p);
> 
Index: panel/menu-fentry.h
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu-fentry.h,v
retrieving revision 1.3
diff -r1.3 menu-fentry.h
50c50,53
< GSList * get_files_from_menudir(char *menudir);
---
> GSList * get_files_from_menudir(char *menudir, gint *n_sorted);
> gchar * get_menudir_dot_directory(char *menudir);
> gint fr_compare (gconstpointer a, gconstpointer b);
> gchar * make_fullname (gchar *pathname);
Index: panel/menu-properties.c
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu-properties.c,v
retrieving revision 1.13
diff -r1.13 menu-properties.c
70c70
< 		GnomeDesktopEntry *item_info;
---
> 		GnomeDesktopEntry *item_info = NULL;
72,74c72,74
< 		dentry_name = g_concat_dir_and_file (menudir,
< 						     ".directory");
< 		item_info = gnome_desktop_entry_load (dentry_name);
---
>  		dentry_name = get_menudir_dot_directory (menudir);
>  		if (dentry_name)
>  			item_info = gnome_desktop_entry_load (dentry_name);
Index: panel/menu-rh.c
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu-rh.c,v
retrieving revision 1.4
diff -r1.4 menu-rh.c
29a30,57
> shadow_menudir(char *dir, char **menudir, char **shadowdir)
> {
> 	static char *appsdir = NULL;
> 	static guint appsdir_len = 0;
> 	static guint shadowdir_len = 0;
> 	
> 	if (!appsdir) {
> 		appsdir = gnome_datadir_file("gnome/apps");
> 		appsdir_len = strlen (appsdir);
> 		shadowdir_len = strlen (REDHAT_SHADOW_DIR);
> 	}
> 
> 	if (strncmp (appsdir, dir, appsdir_len) == 0) {
> 		*menudir = dir;
> 		*shadowdir = g_strconcat (REDHAT_SHADOW_DIR, dir + appsdir_len, NULL);
> 	} else if (strncmp (REDHAT_SHADOW_DIR, dir, shadowdir_len) == 0) {
> 	        *menudir = g_strconcat (appsdir, dir + shadowdir_len, NULL);
> 		*shadowdir = dir;
> 	} else {
> 		*menudir = dir;
> 		*shadowdir = NULL;
> 	}
> }
> 
> 
> 
> 
> void
311a340
> 
Index: panel/menu-rh.h
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu-rh.h,v
retrieving revision 1.1
diff -r1.1 menu-rh.h
7a8
> void shadow_menudir(char *dir, char **menudir, char **shadowdir);
9a11,12
> /* The directory which we shadow the apps/ for Red Hat */
> #define REDHAT_SHADOW_DIR "/etc/X11/applnk"
Index: panel/menu.c
===================================================================
RCS file: /cvs/gnome/gnome-core/panel/menu.c,v
retrieving revision 1.307
diff -r1.307 menu.c
73a74,76
> 
>   
> 
736c739
< 	GnomeDesktopEntry *item_info;
---
> 	GnomeDesktopEntry *item_info = NULL;
747,749c750,752
< 	dentry_name = g_concat_dir_and_file (dirname,
< 					     ".directory");
< 	item_info = gnome_desktop_entry_load (dentry_name);
---
> 	dentry_name = get_menudir_dot_directory(".directory");
> 	if (dentry_name)
> 		item_info = gnome_desktop_entry_load (dentry_name);
774c777
< 	list = get_files_from_menudir(dirname);
---
> 	list = get_files_from_menudir(dirname, NULL);
780c783
< 		filename = g_concat_dir_and_file(dirname, li->data);
---
> 		filename = li->data;
2087,2090c2090
< 		char *p;
< 		itemname = g_strdup(g_basename(fr->name));
< 		p = strrchr(itemname, '.');
< 		if(p) *p = '\0';
---
> 		itemname = make_fullname (fr->name);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]