diff --git a/src/x11/meta-startup-notification-x11.c b/src/x11/meta-startup-notification-x11.c index 03cd1b20e..75dd4aa3c 100644 --- a/src/x11/meta-startup-notification-x11.c +++ b/src/x11/meta-startup-notification-x11.c @@ -19,6 +19,8 @@ #include "config.h" #include "meta-startup-notification-x11.h" +#include + #include "core/display-private.h" #include "core/startup-notification-private.h" #include "meta/meta-x11-errors.h" @@ -296,3 +298,72 @@ meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display, return sn_display_process_event (x11_sn->sn_display, xevent); } + +typedef void (* SetAppIdFunc) (SnLauncherContext *context, + const char *app_id); + +gchar * +meta_x11_startup_notification_launch (MetaX11Display *x11_display, + GAppInfo *app_info, + uint32_t timestamp, + int workspace) +{ + gchar *startup_id = NULL; +#ifdef HAVE_STARTUP_NOTIFICATION + MetaX11StartupNotification *x11_sn = x11_display->startup_notification; + SnLauncherContext *sn_launcher; + int screen; + + screen = meta_x11_display_get_screen_number (x11_display); + sn_launcher = sn_launcher_context_new (x11_sn->sn_display, screen); + + sn_launcher_context_set_name (sn_launcher, g_app_info_get_name (app_info)); + sn_launcher_context_set_workspace (sn_launcher, workspace); + sn_launcher_context_set_binary_name (sn_launcher, + g_app_info_get_executable (app_info)); + + if (G_IS_DESKTOP_APP_INFO (app_info)) + { + const char *application_id; + SetAppIdFunc func = NULL; + GModule *self; + + application_id = + g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (app_info)); + self = g_module_open (NULL, G_MODULE_BIND_MASK); + + /* This here is a terrible workaround to bypass a libsn bug that is not + * likely to get fixed at this point. + * sn_launcher_context_set_application_id is correctly defined in the + * sn-launcher.h file, but it's mistakenly called + * sn_launcher_set_application_id in the C file. + * + * We look up the symbol instead, but still prefer the correctly named + * function, if one were ever to be added. + */ + if (!g_module_symbol (self, "sn_launcher_context_set_application_id", + (gpointer *) &func)) + { + g_module_symbol (self, "sn_launcher_set_application_id", + (gpointer *) &func); + } + + if (func) + func (sn_launcher, application_id); + + g_module_close (self); + } + + sn_launcher_context_initiate (sn_launcher, + g_get_prgname (), + g_app_info_get_name (app_info), + timestamp); + + startup_id = g_strdup (sn_launcher_context_get_startup_id (sn_launcher)); + + /* Fire and forget, we have a SnMonitor in addition */ + sn_launcher_context_unref (sn_launcher); +#endif /* HAVE_STARTUP_NOTIFICATION */ + + return startup_id; +} diff --git a/src/x11/meta-startup-notification-x11.h b/src/x11/meta-startup-notification-x11.h index 050d20caf..b46a45e5d 100644 --- a/src/x11/meta-startup-notification-x11.h +++ b/src/x11/meta-startup-notification-x11.h @@ -36,4 +36,9 @@ void meta_x11_startup_notification_release (MetaX11Display *x11_display); gboolean meta_x11_startup_notification_handle_xevent (MetaX11Display *x11_display, XEvent *xevent); +gchar * meta_x11_startup_notification_launch (MetaX11Display *x11_display, + GAppInfo *app_info, + uint32_t timestamp, + int workspace); + #endif /* META_X11_STARTUP_NOTIFICATION_H */