x11: Add method to launch applications, using SnLauncher

The method spawns a launch request that will get caught by the
SnMonitor we have in place to handle X11 startup notification
messages.
This commit is contained in:
Carlos Garnacho 2018-12-13 18:59:14 +01:00 committed by Jonas Ådahl
parent 60d22b7cd0
commit ca67d52cac
2 changed files with 76 additions and 0 deletions

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "meta-startup-notification-x11.h"
#include <gio/gdesktopappinfo.h>
#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;
}

View File

@ -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 */