GNOME Bugzilla – Bug 415070
.desktop file launcher (GnomeDesktopItem replacement) for gtk
Last modified: 2010-04-23 03:54:06 UTC
Split out of bug 339225: See http://svn.gnome.org/viewcvs/libegg/trunk/libegg/smclient/egglauncher.h?view=markup for the current API. This includes all of the #defines from Vincent's patch, but also most of the rest of the GnomeDesktopItem functionality; I think any application doing much of interest with desktop files is going to link against gtk anyway, so having the #defines there shouldn't be a problem. EggLauncher uses GKeyFile for parsing, letting EggLauncher's own API be more centered around being a launcher for a particular instance of an application. Essentially, the whole API is just gnome_desktop_item_launch_on_screen_with_env exploded into a bunch of much simpler (and more-easily-extended-in-the-future) methods. Since it doesn't depend on gnome-vfs, it has to do its own simple URI handling (converting between file: URIs and paths in some cases), but eventually that would be handled by gvfs methods. Since it doesn't depend on gnome-vfs or gconf, it uses "xdg-open" to open Type=Link .desktop files, and "xdg-terminal" to launch Terminal=true ones. (This is arguably preferable to using gnome-vfs anyway, since you generally want to launch the right browser/terminal for the currently- running desktop, not the right browser/terminal for GNOME.) It *does* depend on libstartup-notification at the moment, but it could be rewritten to implement that by hand. It's a little vague about cross-platformness; it probably doesn't handle Windows filenames correctly, and the xdg-utils obviously aren't going to exist on Windows. But do we really care about launching desktop files on Windows anyway? This might be an X11-specific API? What do you think? Vincent replied: > It does make sense to kill GnomeDesktopItem, IMHO. I'm not good at > commenting on API, but it looks okay. Maybe some people would like to > have it look a bit more like the g_spawn API? > > I believe we should still define the macros in glib, though, since there > might be some non-graphical programs wanting to parse .desktop files. > > Also, I'm not really fond of using xdg-open and xdg-terminal, but this > can be fixed later. To which I say: > Maybe some people would like to > have it look a bit more like the g_spawn API? The problem is that there are way way way too many options, and C doesn't have keyword arguments. With GnomeDesktopItem, the launch options are spread out across the choice of launch method (gnome_desktop_item_launch, gnome_desktop_item_launch_with_env, or gnome_desktop_item_launch_on_screen), the GnomeDesktopItemLaunchFlags you pass to that method, and methods that can be called separately before launching (gnome_desktop_item_set_launch_time). And there's still no way to launch something on a specific screen while setting specific environment variables. So EggLauncher's API was designed to simplify it all, and at the same time make it more extensible. > I believe we should still define the macros in glib ok, i've now split this out as a separate bug
Matthias said in bug 339225: > Dan, using xdg wrappers in this way sounds like a recipe for infinite > recursion... > > xdg wrappers are (presumably) implemented using native desktop technology. > If the native desktop technology starts to call back into xdg wrappers, bad > things will happen... There'd be a chance of infinite recursion if the API used raw command lines, but since it only handles .desktop files, any recursion would involve a simpler case, so it would terminate eventually. The worst case is if you have a "Link to foo.txt" (link-to-foo.desktop), and you double-click on it, EggLauncher would run "xdg-open foo.txt", and then xdg-open might create an EggLauncher for vi.desktop, causing it to execute "xdg-terminal vi foo.txt", which in turn might create an EggLauncher for gnome-terminal.desktop, and run "gnome-terminal -e vi foo.txt". But there's no situation where you'd use either xdg-terminal or xdg-open more than once. Eventually of course, we'd want EggLauncher to be able to handle this directly rather than using xdg wrappers. Maybe instead of xdg-terminal we could use an xsetting. Not using xdg-open will require figuring out what to do with gnome-vfs-mime though.
> > Maybe some people would like to > > have it look a bit more like the g_spawn API? > > The problem is that there are way way way too many options, and C doesn't > have keyword arguments... I guess another possibility would be to do it sort of g_object_new-style: gtk_desktop_file_launch ( desktop_file, urls, &error, GTK_DESKTOP_FILE_SCREEN, gtk_widget_get_screen (foo), GTK_DESKTOP_FILE_SETENV, "FOO", "bar", GTK_DESKTOP_FILE_SETENV, "BAZ", "quux", GTK_DESKTOP_FILE_LAUNCH_TIME, evt->time, GTK_DESKTOP_FILE_RETURN_PID, &pid, NULL); or something. That's probably better than how I did it, and I think it's a lot clearer than g_spawn_async and gdk_spawn_on_screen, because you don't have to count how many NULLs to put in around the arguments that you actually care about. (And again, it's more extensible, doesn't require a separate "_with_pipes" version, etc.)
Yes, that does look nicer that g_spawn. Have you contemplated at all if and how this api overlaps with mimetype/appinfo parts of alex' gvfs work ?
> Have you contemplated at all if and how this api overlaps with mimetype/appinfo > parts of alex' gvfs work ? Yeah, we discussed it on gtk-devel-list last week. We agreed that GDesktopAppInfo doesn't cover all uses of desktop files, and that GAppInfo in general would work better in gtk than in glib. So if we have a GtkDesktopFile that people like, GDesktopAppInfo could be implemented in terms of that. (Actually, they'd both use each other, since GtkDesktopFile would use GAppInfo to find the right applications to handle Type=Link .desktop files with.) I'll attach an updated proposed API later.
Created attachment 86534 [details] new eggdesktopfile.c updated eggdesktopfile.c. Includes an egg_desktop_file_launch() like described in comment #2, plus egg_set_desktop_file() to set the app desktop file (which in turn calls g_set_application_name() and gtk_window_set_default_icon_name()). There are FIXMEs pointing out where it should be calling into gvfs.
Created attachment 86535 [details] header
Created attachment 86536 [details] [review] gtk patch for additional startup notification functionality patch to gtk to add gdk_x11_display_broadcast_sn_message, for eggdesktopfile to use rather than libstartup-notification
Looking at the gdk patch first. No objections in principle, but a few comments: I'd like to avoid the shorthand sn in the function name, if possible. How about gdk_x11_display_broadcast_startup_message ? It would be nice to link to the startup notification spec and add some hints about possible values and uses of this function to the docs (eg mention that it is only needed on the "launcher" side of the SN proctocol)
Created attachment 87238 [details] [review] updated gtk startup notification patch Updated name and docs as suggested. I also updated the actual doc build to include the new function and a few other new startup-notification-related functions that hadn't been added to gdk-sections.txt yet. Also, after reading bug 136571, I moved the trusted_client check from gdk_notify_startup_complete to broadcast_xmessage, so it applies to all of the startup notification functions.
Loooks good, thanks.
committed
I'm currently playing around with patching gnome-panel, nautilus, etc to use EggDesktopFile instead of GnomeDesktopItem, to see what API additions/tweaks are needed.
Is gdk_x11_display_broadcast_startup_message meant to be wrapped by language bindings? If so, we'd need a separate array-based variant of it, I think.
Prompted by bkor's recent blog post, here's a status update on this: (In reply to comment #12) > I'm currently playing around with patching gnome-panel, nautilus, etc to use > EggDesktopFile instead of GnomeDesktopItem, to see what API additions/tweaks > are needed. The big problem is the some apps need to modify desktop files (eg, editing a launcher in nautilus or the panel). EggDesktopFile is read-only, so they'd have to use the set methods on the underlying GKeyFile. But then that causes problems because the EggDesktopFile would get out of sync with the keyfile. Possible fixes: 1. Don't expose the keyfile and instead just add set methods to EggDesktopFile (pretty much duplicating the whole GKeyFile API). 2. Make EggDesktopFile not preparse and cache the keyfile keys, but just recompute things every time it needs them (possibly slow, but maybe it doesn't matter?) 3. Make EggDesktopFile still cache keys, but verify that the keyfile hasn't changed every time it uses one of the cached values (complicated) And then once that's figured out someone just needs to convince people to try it. (I'm not actively hacking on this these days...)
just my 2p. most of the times, applications/libraries just need a DesktopFile opened in read-only mode. would it be possible to add a flags field to the EggDesktopFile constructors, like EGG_DESKTOP_FILE_READ_ONLY? this way we can optimise for the read-only usage and just load+cache the values from the keyfile. on the other hand, nautilus and gnome-panel can open in read-write mode and not cache anything.
Having just linked to here from http://live.gnome.org/SessionManagement/Todo, let me add a few updates: (In reply to comment #4) > > Have you contemplated at all if and how this api overlaps with mimetype/appinfo > > parts of alex' gvfs work ? > > Yeah, we discussed it on gtk-devel-list last week. That thread is here: http://mail.gnome.org/archives/gtk-devel-list/2007-March/msg00263.html (In reply to comment #13) > Is gdk_x11_display_broadcast_startup_message meant to be wrapped by language > bindings? If so, we'd need a separate array-based variant of it, I think. It is unlikely that a language binding would need to wrap this; it is only expected to be used by other fairly-low-level code. (In reply to comment #14) > Prompted by bkor's recent blog post (actually it was pbor, not bkor: http://www.advogato.org/person/pbor/diary/57.html) > 2. Make EggDesktopFile not preparse and cache the keyfile keys, but > just recompute things every time it needs them (possibly slow, but > maybe it doesn't matter?) I think this probably makes the most sense; the apps that use EggDesktopFile are only likely to use the Exec info in it once, so parsing it on-demand isn't likely to cause any extra work (and is just noise compared to actually execing the program anyway).
How does this bug relate to the GAppLaunchContext code in glib >= 2.15?
(In reply to comment #17) > How does this bug relate to the GAppLaunchContext code in glib >= 2.15? EggDesktopFile is an implementation of the .desktop file spec. GAppInfo / GAppLaunchContext are an application-launching interface which make use of .desktop files in their unix implementation. So, eg, you could not implement the panel menus or autostart using GAppInfo/GAppLaunchContext, because they don't expose all of the .desktop file keys that are needed for those things. In a perfect world, EggDesktopFile would have been finished first, and then GDesktopAppInfo implemented on top of it, but oh well. At any rate, if this does go into glib/gtk, we should try to make it share code with GAppInfo/GAppLaunchContext where possible.
I think most of the things that eggdesktopfile had over gappinfo can nowadays be done with gdesktopappinfo, it gained some apis over time. What I am looking at doing to finally put this to rest is to add a g_desktop_app_info_get_keyfile() which gives you access to the underlying desktop file.
GDesktopAppInfo is a kinda small object, designed to keep only the info you need to launch the app. Keeping the full keyfile is a lot larger. Especially if you keep the translations.
Alternatively, we could allow to get the filename of the desktop file backing the appinfo.
(In reply to comment #19) > I think most of the things that eggdesktopfile had over gappinfo can nowadays > be done with gdesktopappinfo, it gained some apis over time. Yeah, even the panel uses GDesktopAppInfo now. eggsmclient-xsmp still needs egg_set_desktop_file() and egg_desktop_file_parse_exec(), but of course, that all depends on what happens with EggSMClient... But anyway, probably we should just close this as WONTFIX and update LibgnomeMustDie to point to GDesktopAppInfo instead?
(In reply to comment #22) > But anyway, probably we should just close this as WONTFIX and update > LibgnomeMustDie to point to GDesktopAppInfo instead? neither LibgnomeMustDie nor ProjectRidley even mentions GnomeDesktopItem, so there's nothing to update