single instance (was Re: Minutes of the GTK+ meeting at GUADEC)
- From: Havoc Pennington <hp redhat com>
- To: Kristian Rietveld <kris gtk org>
- Cc: gtk-devel-list gnome org
- Subject: single instance (was Re: Minutes of the GTK+ meeting at GUADEC)
- Date: Fri, 10 Aug 2007 16:58:04 -0400
Hi,
Kristian Rietveld wrote:
GUnique was brought up as a possible feature for 2.14, a small discussion
about its usefulness as "stand-alone" feature emerged. It doesn't make all
that much sense without an application window class, subsequently an
application window class doesn't make much sense without session
management. Basically, you start questioning whether you want to introduce
a document based window/application model (like Cocoa has) -- getting this
done requires a good amount of work and discussion because it possibly
takes over a lot. In the end we concluded that all of this would be more
useful as a higher level library including all these pieces.
I don't buy this really, though obviously I missed the conversation ;-)
I would expect a basic API like the following, though a high-level app
window thing could be useful too.
void
handle_application_launch(GdkScreen *screen,
GtkLaunch *launch,
void *data)
{
GSList *urls;
GtkWindow *document_window;
urls = gtk_launch_get_property(launch, "urls");
foreach (url in urls) {
/* get a GtkWindow with startup notification stuff
* from the launch properly configured; in real life
* you'd probably have an application window subclass,
* or a GtkAppWindow, or whatever, but those things
* would build on this.
*/
if (already have window for url) {
document_window = window we already have;
gtk_window_present_from_launch(document_window, launch);
} else {
document_window = gtk_window_new_for_launch(screen, launch);
gtk_window_show (document_window);
}
}
}
void
handle_lost_single_instance(void *data)
{
exit(0);
}
int
main(int argc, char **argv)
{
gtk_init_single_instance(argc, argv, "org.gnome.MyAppBusName",
0, /* flags or something */
handle_application_launch, NULL,
handle_lost_single_instance, NULL);
gtk_main();
return 0;
}
Where init_single_instance will try to send the launch details to the
bus name, which will be activated if necessary; if that fails, then it
would try to get the bus name itself, and if it gets it, calls
handle_application_launch within the current process. If the bus name is
never obtained or is later lost, handle_lost_single_instance is called.
This can implement a --replace option automatically.
Details forwarded to the existing bus name would include env variables
and command line options, as needed, there are some tricky bits to sort
that out.
init_single_instance need not open the X display until it knows it needs
to call handle_application_launch().
The whole connect-to-bus-and-wait-for-bus-name thing can be done
asynchronously, so if the app wanted to do something else after
init_single_instance then it could. gtk_init_single_instance() would
"fire off" the bus name request, then return, so in gtk_main() either
handle_application_launch or handle_lost_single_instance ends up getting
called. This means that initial app startup and later opening of a new
window uses *the same codepath*
Standard API could be offered to "simulate" a launch within the process,
for e.g. a New... or Open menu item, which ideally ends up just calling
handle_application_launch():
gtk_launch_open_document(GdkScreen *screen, const char * bus_name,
const char *url);
or whatever. Heck this could also work fine with other apps, it could
just happen to send the dbus message to itself if the current app owned
the bus name.
Obviously there is some API fine-tuning, e.g. maybe a struct of handlers
is better than a bunch of function args for gtk_init_single_instance, as
one drop in the fine-tuning bucket. Or another example is that having to
do the full gtk_init is a pain, ideally there's a
gtk_launch_set_handlers() that is separate and the gtk_init thing is
just a convenience API.
Anyway this is a ton of good functionality for an app, and something
everyone is getting wrong hand-coding, so I would not wait for an
AppWindow widget and stuff.
Havoc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]