Re: GUnique [Was: gnome-utils branched for GNOME 2.16]



Elijah Newren wrote:
http://live.gnome.org/DesktopAppsAsDBusServices

(Crappy write-up, but I just haven't had time to sort it out. Sorry!)

GUnique already uses D-Bus (with bacon as a backup).  So, how is your
proposal different than GUnique?  (Other than startup-notification not
being mentioned in your proposal yet?)


A nice thing in that writeup is that the dbus usage is more "human readable", libgunique is basically using dbus as a complicated socket:

http://cvs.gnome.org/viewcvs/libguniqueapp/libguniqueapp/guniqueapp-dbus.c?rev=1.2&view=markup

It does:

 interface GUniqueAppInterface {
bool SendMessage(int command, String data, String startup_id, unsigned int workspace);
 }

(implemented by object /Factory, where command is an enum { ACTIVATE, NEW, OPEN, CUSTOM })

The "clean" way to do it I think might be something like:

 interface UniqueApplication {
   void Open(Array<String> uris, Dict<String,Variant> properties);
   void New(...);
   void Activate(...);
 }

Where e.g. the startup notification stuff is in the properties. Really the uris could also be in the properties, just figuring that's the most common property. Anyway, the exact interface isn't the point just that it has methods for each operation instead of a single SendMessage.

maybe something like:
 interface Launchable {
   void Launch(Array<String> uris, Dict<String,Variant> properties);
 }

(dbus convention nitpicks: no "Interface" or "IFace" in interface name, namespace /org/gnome on object path, lowercase object path, exceptions rather than boolean return, no need for GUnique namespace in interface name since the interface already has org.gnome.)

Anyway, if you think about e.g. Python scripting, it's going to be a bit nicer to say something like
  app.Launch(uri)
than
  app.SendMessage(2, uri)
(imagine if all dbus APIs looked like the second one)

Though I guess either way, you have essentially zero chance of getting this right without using libstartup-notification ... which might be the bigger picture point.

Also important to libdbus human-readability is the bus name the app owns, so it'd be nice to have org.gnome.GEdit rather than
org.gnome.GUniqueApp.gedit

There's a kind of impedance mismatch between dbus and some more basic ipc... with dbus you can have the bus launch things. So if you have a .service file, you can just unconditionally do:

 app = new Proxy("org.gnome.GEdit");
 app.Launch(uris, props);

And gedit will be started if it isn't already, and reused otherwise, with no race conditions.

This also works with methods other than Launch, so say the app has a method like SpellCheck, you can do:
 app = new Proxy("org.gnome.GEdit");
 results = app.SpellCheck(stuff);

It's a stupid example but you get the idea...

Anyhow, one thing that is enabled here would be something like this in the .desktop file:

 DBus-Launchable=org.gnome.GEdit
 Exec=dbus-send-to-launchable org.gnome.GEdit %u

Where the point is that the Exec= line is for backward compat, but the panel or whatever could also just invoke the Launch method on org.gnome.GEdit directly, i.e. the DBus-Launchable= field means that the bus name supports the standard UniqueApp/Launchable interface.

Not sure that's really worth doing, but I guess an observation is that with dbus the "client" mode can just be generic, because the client doesn't have to be able to become the factory - the bus can start a factory. While with gunique right now, I believe the assumption is that the launching app is the same app that's being launched and can thus become the factory if there isn't a factory yet. Third parties have to launch by fork/exec rather than by invoking a dbus method.

Havoc




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