X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fstartupnotify.c;h=002bd2dc0521991af7dd9b9b73d9f2de06003eba;hb=556eb7b7fb20b3b0db03b6d92259ad3bb16dccde;hp=f296c76d241b312f493042d530fb01f23542f5ee;hpb=16f46c296d1fcd3f27fc62a18e71c55fb3fd3e88;p=chaz%2Fopenbox diff --git a/openbox/startupnotify.c b/openbox/startupnotify.c index f296c76d..002bd2dc 100644 --- a/openbox/startupnotify.c +++ b/openbox/startupnotify.c @@ -1,7 +1,8 @@ /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- startupnotify.c for the Openbox window manager - Copyright (c) 2003 Ben Jansens + Copyright (c) 2006 Mikael Magnusson + Copyright (c) 2003-2007 Dana Jansens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,14 +18,24 @@ */ #include "startupnotify.h" +#include "gettext.h" +#include "event.h" + +#include #ifndef USE_LIBSN void sn_startup(gboolean reconfig) {} void sn_shutdown(gboolean reconfig) {} gboolean sn_app_starting() { return FALSE; } -void sn_app_started(gchar *wmclass) {} +Time sn_app_started(const gchar *id, const gchar *wmclass) +{ + return CurrentTime; +} gboolean sn_get_desktop(gchar *id, guint *desktop) { return FALSE; } +void sn_setup_spawn_environment(gchar *program, gchar *name, + gchar *icon_name, gint desktop) {} +void sn_spawn_cancel() {} #else @@ -35,18 +46,12 @@ gboolean sn_get_desktop(gchar *id, guint *desktop) { return FALSE; } #define SN_API_NOT_YET_FROZEN #include -typedef struct { - SnStartupSequence *seq; - gboolean feedback; -} ObWaitData; - static SnDisplay *sn_display; static SnMonitorContext *sn_context; -static GSList *sn_waits; /* list of ObWaitDatas */ +static SnLauncherContext *sn_launcher; +static GSList *sn_waits; /* list of SnStartupSequences we're waiting on */ -static ObWaitData* wait_data_new(SnStartupSequence *seq); -static void wait_data_free(ObWaitData *d); -static ObWaitData* wait_find(const gchar *id); +static SnStartupSequence* sequence_find(const gchar *id); static void sn_handler(const XEvent *e, gpointer data); static void sn_event_func(SnMonitorEvent *event, gpointer data); @@ -55,9 +60,13 @@ void sn_startup(gboolean reconfig) { if (reconfig) return; + /* unset this so we don't pass it on unknowingly */ + unsetenv("DESKTOP_STARTUP_ID"); + sn_display = sn_display_new(ob_display, NULL, NULL); sn_context = sn_monitor_context_new(sn_display, ob_screen, sn_event_func, NULL, NULL); + sn_launcher = sn_launcher_context_new(sn_display, ob_screen); ob_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL); } @@ -71,78 +80,45 @@ void sn_shutdown(gboolean reconfig) ob_main_loop_x_remove(ob_main_loop, sn_handler); for (it = sn_waits; it; it = g_slist_next(it)) - wait_data_free(it->data); + sn_startup_sequence_unref((SnStartupSequence*)it->data); g_slist_free(sn_waits); sn_waits = NULL; screen_set_root_cursor(); + sn_launcher_context_unref(sn_launcher); sn_monitor_context_unref(sn_context); sn_display_unref(sn_display); } -static ObWaitData* wait_data_new(SnStartupSequence *seq) -{ - ObWaitData *d = g_new(ObWaitData, 1); - d->seq = seq; - d->feedback = TRUE; - - sn_startup_sequence_ref(d->seq); - - return d; -} - -static void wait_data_free(ObWaitData *d) +static SnStartupSequence* sequence_find(const gchar *id) { - if (d) { - sn_startup_sequence_unref(d->seq); - - g_free(d); - } -} - -static ObWaitData* wait_find(const gchar *id) -{ - ObWaitData *ret = NULL; + SnStartupSequence*ret = NULL; GSList *it; for (it = sn_waits; it; it = g_slist_next(it)) { - ObWaitData *d = it->data; - if (!strcmp(id, sn_startup_sequence_get_id(d->seq))) { - ret = d; + SnStartupSequence *seq = it->data; + if (!strcmp(id, sn_startup_sequence_get_id(seq))) { + ret = seq; break; } } return ret; } -gboolean sn_app_starting() +gboolean sn_app_starting(void) { - GSList *it; - - for (it = sn_waits; it; it = g_slist_next(it)) { - ObWaitData *d = it->data; - if (d->feedback) - return TRUE; - } - return FALSE; + return sn_waits != NULL; } static gboolean sn_wait_timeout(gpointer data) { - ObWaitData *d = data; - d->feedback = FALSE; + SnStartupSequence *seq = data; + sn_waits = g_slist_remove(sn_waits, seq); screen_set_root_cursor(); return FALSE; /* don't repeat */ } -static void sn_wait_destroy(gpointer data) -{ - ObWaitData *d = data; - sn_waits = g_slist_remove(sn_waits, d); - wait_data_free(d); -} - static void sn_handler(const XEvent *e, gpointer data) { XEvent ec; @@ -154,18 +130,20 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data) { SnStartupSequence *seq; gboolean change = FALSE; - ObWaitData *d; if (!(seq = sn_monitor_event_get_startup_sequence(ev))) return; switch (sn_monitor_event_get_type(ev)) { case SN_MONITOR_EVENT_INITIATED: - d = wait_data_new(seq); - sn_waits = g_slist_prepend(sn_waits, d); - /* 30 second timeout for apps to start */ - ob_main_loop_timeout_add(ob_main_loop, 30 * G_USEC_PER_SEC, - sn_wait_timeout, d, sn_wait_destroy); + sn_startup_sequence_ref(seq); + sn_waits = g_slist_prepend(sn_waits, seq); + /* 20 second timeout for apps to start if the launcher doesn't + have a timeout */ + ob_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC, + sn_wait_timeout, seq, + g_direct_equal, + (GDestroyNotify)sn_startup_sequence_unref); change = TRUE; break; case SN_MONITOR_EVENT_CHANGED: @@ -174,9 +152,10 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data) break; case SN_MONITOR_EVENT_COMPLETED: case SN_MONITOR_EVENT_CANCELED: - if ((d = wait_find(sn_startup_sequence_get_id(seq)))) { - d->feedback = FALSE; - ob_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout, d); + if ((seq = sequence_find(sn_startup_sequence_get_id(seq)))) { + sn_waits = g_slist_remove(sn_waits, seq); + ob_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout, + seq, FALSE); change = TRUE; } break; @@ -186,27 +165,54 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data) screen_set_root_cursor(); } -void sn_app_started(gchar *wmclass) +Time sn_app_started(const gchar *id, const gchar *wmclass) { GSList *it; + Time t = CurrentTime; + + if (!id && !wmclass) + return t; for (it = sn_waits; it; it = g_slist_next(it)) { - ObWaitData *d = it->data; - if (sn_startup_sequence_get_wmclass(d->seq) && - !strcmp(sn_startup_sequence_get_wmclass(d->seq), wmclass)) - { - sn_startup_sequence_complete(d->seq); + SnStartupSequence *seq = it->data; + gboolean found = FALSE; + const gchar *seqid, *seqclass, *seqname, *seqbin; + seqid = sn_startup_sequence_get_id(seq); + seqclass = sn_startup_sequence_get_wmclass(seq); + seqname = sn_startup_sequence_get_name(seq); + seqbin = sn_startup_sequence_get_binary_name(seq); + + if (id && seqid) { + /* if the app has a startup id, then look for that for highest + accuracy */ + if (!strcmp(seqid, id)) + found = TRUE; + } else { + seqclass = sn_startup_sequence_get_wmclass(seq); + seqname = sn_startup_sequence_get_name(seq); + seqbin = sn_startup_sequence_get_binary_name(seq); + + if ((seqname && !g_ascii_strcasecmp(seqname, wmclass)) || + (seqbin && !g_ascii_strcasecmp(seqbin, wmclass)) || + (seqclass && !strcmp(seqclass, wmclass))) + found = TRUE; + } + + if (found) { + sn_startup_sequence_complete(seq); + t = sn_startup_sequence_get_timestamp(seq); break; } } + return t; } gboolean sn_get_desktop(gchar *id, guint *desktop) { - ObWaitData *d; + SnStartupSequence *seq; - if (id && (d = wait_find(id))) { - gint desk = sn_startup_sequence_get_workspace(d->seq); + if (id && (seq = sequence_find(id))) { + gint desk = sn_startup_sequence_get_workspace(seq); if (desk != -1) { *desktop = desk; return TRUE; @@ -215,4 +221,52 @@ gboolean sn_get_desktop(gchar *id, guint *desktop) return FALSE; } +static gboolean sn_launch_wait_timeout(gpointer data) +{ + SnLauncherContext *sn = data; + sn_launcher_context_complete(sn); + return FALSE; /* don't repeat */ +} + +void sn_setup_spawn_environment(gchar *program, gchar *name, + gchar *icon_name, gint desktop) +{ + gchar *desc; + const char *id; + + desc = g_strdup_printf(_("Running %s\n"), program); + + if (sn_launcher_context_get_initiated(sn_launcher)) { + sn_launcher_context_unref(sn_launcher); + sn_launcher = sn_launcher_context_new(sn_display, ob_screen); + } + + sn_launcher_context_set_name(sn_launcher, name ? name : program); + sn_launcher_context_set_description(sn_launcher, desc); + sn_launcher_context_set_icon_name(sn_launcher, icon_name ? + icon_name : program); + sn_launcher_context_set_binary_name(sn_launcher, program); + if (desktop >= 0 && (unsigned) desktop < screen_num_desktops) + sn_launcher_context_set_workspace(sn_launcher, (signed) desktop); + sn_launcher_context_initiate(sn_launcher, "openbox", program, + event_curtime); + id = sn_launcher_context_get_startup_id(sn_launcher); + + /* 20 second timeout for apps to start */ + sn_launcher_context_ref(sn_launcher); + ob_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC, + sn_launch_wait_timeout, sn_launcher, + g_direct_equal, + (GDestroyNotify)sn_launcher_context_unref); + + setenv("DESKTOP_STARTUP_ID", id, TRUE); + + g_free(desc); +} + +void sn_spawn_cancel(void) +{ + sn_launcher_context_complete(sn_launcher); +} + #endif