From b9db72dc8af70767a05fea73fb8ebacf0c5db6b8 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 9 Oct 2011 18:21:59 +0100 Subject: [PATCH] Implement support for startup notifications This only sets up startup notifications for the 'exec' commands and directives. Monitoring startups follows later. --- common.mk | 2 ++ include/i3.h | 8 ++++++++ src/main.c | 10 ++++++++++ src/util.c | 23 +++++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/common.mk b/common.mk index bc831615..9bf427e0 100644 --- a/common.mk +++ b/common.mk @@ -57,6 +57,7 @@ CFLAGS += $(call cflags_for_lib, x11) CFLAGS += $(call cflags_for_lib, yajl) CFLAGS += $(call cflags_for_lib, libev) CFLAGS += $(call cflags_for_lib, libpcre) +CFLAGS += $(call cflags_for_lib, libstartup-notification-1.0) CPPFLAGS += -DI3_VERSION=\"${GIT_VERSION}\" CPPFLAGS += -DSYSCONFDIR=\"${SYSCONFDIR}\" CPPFLAGS += -DTERM_EMU=\"$(TERM_EMU)\" @@ -84,6 +85,7 @@ LIBS += $(call ldflags_for_lib, x11,X11) LIBS += $(call ldflags_for_lib, yajl,yajl) LIBS += $(call ldflags_for_lib, libev,ev) LIBS += $(call ldflags_for_lib, libpcre,pcre) +LIBS += $(call ldflags_for_lib, libstartup-notification-1.0,startup-notification-1) # Please test if -Wl,--as-needed works on your platform and send me a patch. # it is known not to work on Darwin (Mac OS X) diff --git a/include/i3.h b/include/i3.h index f2b97824..089dfcba 100644 --- a/include/i3.h +++ b/include/i3.h @@ -12,6 +12,9 @@ #include +#define SN_API_NOT_YET_FROZEN 1 +#include + #include "queue.h" #include "data.h" #include "xcb.h" @@ -21,6 +24,11 @@ extern xcb_connection_t *conn; extern int conn_screen; +/** The last timestamp we got from X11 (timestamps are included in some events + * and are used for some things, like determining a unique ID in startup + * notification). */ +extern xcb_timestamp_t last_timestamp; +extern SnDisplay *sndisplay; extern xcb_key_symbols_t *keysyms; extern char **start_argv; extern Display *xlibdpy, *xkbdpy; diff --git a/src/main.c b/src/main.c index 6020f109..f985810e 100644 --- a/src/main.c +++ b/src/main.c @@ -22,6 +22,14 @@ xcb_connection_t *conn; /* The screen (0 when you are using DISPLAY=:0) of the connection 'conn' */ int conn_screen; +/* Display handle for libstartup-notification */ +SnDisplay *sndisplay; + +/* The last timestamp we got from X11 (timestamps are included in some events + * and are used for some things, like determining a unique ID in startup + * notification). */ +xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME; + xcb_screen_t *root_screen; xcb_window_t root; uint8_t root_depth; @@ -362,6 +370,8 @@ int main(int argc, char *argv[]) { if (xcb_connection_has_error(conn)) errx(EXIT_FAILURE, "Cannot open display\n"); + sndisplay = sn_xcb_display_new(conn, NULL, NULL); + /* Initialize the libev event loop. This needs to be done before loading * the config file because the parser will install an ev_child watcher * for the nagbar when config errors are found. */ diff --git a/src/util.c b/src/util.c index 30371bcd..d0e8e947 100644 --- a/src/util.c +++ b/src/util.c @@ -21,6 +21,9 @@ #include #include +#define SN_API_NOT_YET_FROZEN 1 +#include + #include "all.h" static iconv_t conversion_descriptor = 0; @@ -69,11 +72,31 @@ bool update_if_necessary(uint32_t *destination, const uint32_t new_value) { * */ void start_application(const char *command) { + /* Create a startup notification context to monitor the progress of this + * startup. */ + SnLauncherContext *context; + context = sn_launcher_context_new(sndisplay, conn_screen); + sn_launcher_context_set_name(context, "i3"); + sn_launcher_context_set_description(context, "exec command in i3"); + /* Chop off everything starting from the first space (if there are any + * spaces in the command), since we don’t want the parameters. */ + char *first_word = sstrdup(command); + char *space = strchr(first_word, ' '); + if (space) + *space = '\0'; + sn_launcher_context_initiate(context, "i3", first_word, last_timestamp); + free(first_word); + + LOG("startup id = %s\n", sn_launcher_context_get_startup_id(context)); + LOG("executing: %s\n", command); if (fork() == 0) { /* Child process */ setsid(); if (fork() == 0) { + /* Setup the environment variable(s) */ + sn_launcher_context_setup_child_process(context); + /* Stores the path of the shell */ static const char *shell = NULL; -- 2.39.5