[mutter/wip/carlosg/launch-context: 2/2] core: Add MetaLaunchContext
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/launch-context: 2/2] core: Add MetaLaunchContext
- Date: Thu, 13 Dec 2018 20:48:38 +0000 (UTC)
commit 7dab1e956d8df9c6a7f5eeb3d7e7797f98fce418
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Dec 13 19:02:19 2018 +0100
core: Add MetaLaunchContext
This is a GAppLaunchContext subclass meant to replace usage of
GdkAppLaunchContext in gnome-shell.
Launch contexts get created from the MetaStartupNotification as
they are closely related. The messaging underneath depends on
the availability of a X11 display, if there is one we go through
it (and libsn). If there is none, we still create startup sequences
manually for wayland clients.
src/Makefile.am | 2 +
src/core/meta-launch-context.c | 258 +++++++++++++++++++++++++++++++++++
src/core/startup-notification.c | 18 +++
src/meson.build | 1 +
src/meta/meson.build | 1 +
src/meta/meta-launch-context.h | 35 +++++
src/meta/meta-startup-notification.h | 6 +
7 files changed, 321 insertions(+)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index ce5904678..bb1ba86a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -291,6 +291,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
meta/meta-inhibit-shortcuts-dialog.h \
core/meta-inhibit-shortcuts-dialog-default.c \
core/meta-inhibit-shortcuts-dialog-default-private.h \
+ core/meta-launch-context.c \
core/delete.c \
core/display.c \
core/display-private.h \
@@ -571,6 +572,7 @@ libmutterinclude_headers = \
meta/meta-cursor-tracker.h \
meta/meta-dnd.h \
meta/meta-idle-monitor.h \
+ meta/meta-launch-context.h \
meta/meta-plugin.h \
meta/meta-monitor-manager.h \
meta/meta-remote-access-controller.h \
diff --git a/src/core/meta-launch-context.c b/src/core/meta-launch-context.c
new file mode 100644
index 000000000..05fc7152f
--- /dev/null
+++ b/src/core/meta-launch-context.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2018 Red Hat
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+#include "config.h"
+
+#include "core/display-private.h"
+#include "meta/meta-launch-context.h"
+#include "x11/meta-startup-notification-x11.h"
+
+#include <gio/gdesktopappinfo.h>
+
+typedef struct _MetaLaunchContext MetaLaunchContext;
+
+struct _MetaLaunchContext
+{
+ GAppLaunchContext parent_instance;
+ MetaDisplay *display;
+ MetaWorkspace *workspace;
+ uint32_t timestamp;
+};
+
+G_DEFINE_TYPE (MetaLaunchContext, meta_launch_context,
+ G_TYPE_APP_LAUNCH_CONTEXT)
+
+enum
+{
+ PROP_DISPLAY = 1,
+ PROP_WORKSPACE,
+ PROP_TIMESTAMP,
+ N_PROPS
+};
+
+static GParamSpec *props[N_PROPS] = { 0, };
+
+static void
+meta_launch_context_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MetaLaunchContext *context = META_LAUNCH_CONTEXT (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ context->display = g_value_get_object (value);
+ break;
+ case PROP_WORKSPACE:
+ meta_launch_context_set_workspace (context,
+ g_value_get_object (value));
+ break;
+ case PROP_TIMESTAMP:
+ meta_launch_context_set_timestamp (context,
+ g_value_get_uint (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meta_launch_context_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MetaLaunchContext *context = META_LAUNCH_CONTEXT (object);
+
+ switch (prop_id)
+ {
+ case PROP_DISPLAY:
+ g_value_set_object (value, context->display);
+ break;
+ case PROP_WORKSPACE:
+ g_value_set_object (value, context->workspace);
+ break;
+ case PROP_TIMESTAMP:
+ g_value_set_uint (value, context->timestamp);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+meta_launch_context_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (meta_launch_context_parent_class)->finalize (object);
+}
+
+static void
+meta_launch_context_constructed (GObject *object)
+{
+ MetaLaunchContext *context = META_LAUNCH_CONTEXT (object);
+
+ G_OBJECT_CLASS (meta_launch_context_parent_class)->constructed (object);
+
+ g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
+ "DISPLAY", getenv ("DISPLAY"));
+ g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (context),
+ "WAYLAND_DISPLAY", getenv ("WAYLAND_DISPLAY"));
+}
+
+static gchar *
+meta_launch_context_get_startup_notify_id (GAppLaunchContext *launch_context,
+ GAppInfo *info,
+ GList *files)
+{
+ MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
+ MetaDisplay *display = context->display;
+ int workspace_idx = -1;
+ gchar *startup_id;
+
+ if (context->workspace)
+ workspace_idx = meta_workspace_index (context->workspace);
+
+ if (display->x11_display)
+ {
+
+ /* If there is a X11 display, we prefer going entirely through
+ * libsn, as SnMonitor expects to keep a view of the full lifetime
+ * of the startup sequence. We can't avoid it when launching and
+ * expect that a "remove" message from a X11 client will be handled.
+ */
+ startup_id =
+ meta_x11_startup_notification_launch (display->x11_display,
+ info,
+ workspace_idx,
+ context->timestamp);
+ }
+
+ if (!startup_id)
+ {
+ const gchar *application_id = NULL;
+ MetaStartupNotification *sn;
+ MetaStartupSequence *seq;
+
+ startup_id = g_uuid_string_random ();
+
+ /* Fallback through inserting our own startup sequence, this
+ * will be enough for wayland clients.
+ */
+ if (G_IS_DESKTOP_APP_INFO (info))
+ {
+ application_id =
+ g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (info));
+ }
+
+ sn = meta_display_get_startup_notification (context->display);
+ seq = g_object_new (META_TYPE_STARTUP_SEQUENCE,
+ "id", startup_id,
+ "application-id", application_id,
+ "name", g_app_info_get_name (info),
+ "workspace", workspace_idx,
+ "timestamp", context->timestamp,
+ NULL);
+
+ meta_startup_notification_add_sequence (sn, seq);
+ g_object_unref (seq);
+ }
+
+ return startup_id;
+}
+
+static void
+meta_launch_context_launch_failed (GAppLaunchContext *launch_context,
+ const gchar *startup_notify_id)
+{
+ MetaLaunchContext *context = META_LAUNCH_CONTEXT (launch_context);
+ MetaStartupNotification *sn;
+ MetaStartupSequence *seq;
+
+ sn = meta_display_get_startup_notification (context->display);
+ seq = meta_startup_notification_lookup_sequence (sn, startup_notify_id);
+
+ if (seq)
+ {
+ meta_startup_sequence_complete (seq);
+ meta_startup_notification_remove_sequence (sn, seq);
+ }
+}
+
+static void
+meta_launch_context_class_init (MetaLaunchContextClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GAppLaunchContextClass *ctx_class = G_APP_LAUNCH_CONTEXT_CLASS (klass);
+
+ object_class->finalize = meta_launch_context_finalize;
+ object_class->constructed = meta_launch_context_constructed;
+ object_class->set_property = meta_launch_context_set_property;
+ object_class->get_property = meta_launch_context_get_property;
+
+ ctx_class->get_startup_notify_id = meta_launch_context_get_startup_notify_id;
+ ctx_class->launch_failed = meta_launch_context_launch_failed;
+
+ props[PROP_DISPLAY] =
+ g_param_spec_object ("display",
+ "display",
+ "Display",
+ META_TYPE_DISPLAY,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ props[PROP_WORKSPACE] =
+ g_param_spec_object ("workspace",
+ "workspace",
+ "Workspace",
+ META_TYPE_WORKSPACE,
+ G_PARAM_READWRITE);
+ props[PROP_TIMESTAMP] =
+ g_param_spec_uint ("timestamp",
+ "timestamp",
+ "Timestamp",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class, N_PROPS, props);
+}
+
+static void
+meta_launch_context_init (MetaLaunchContext *context)
+{
+}
+
+void
+meta_launch_context_set_workspace (MetaLaunchContext *context,
+ MetaWorkspace *workspace)
+{
+ g_return_if_fail (META_IS_LAUNCH_CONTEXT (context));
+ g_return_if_fail (META_IS_WORKSPACE (workspace));
+
+ g_set_object (&context->workspace, workspace);
+}
+
+void
+meta_launch_context_set_timestamp (MetaLaunchContext *context,
+ uint32_t timestamp)
+{
+ g_return_if_fail (META_IS_LAUNCH_CONTEXT (context));
+
+ context->timestamp = timestamp;
+}
diff --git a/src/core/startup-notification.c b/src/core/startup-notification.c
index 43260d59b..546891065 100644
--- a/src/core/startup-notification.c
+++ b/src/core/startup-notification.c
@@ -631,3 +631,21 @@ meta_startup_notification_get_sequences (MetaStartupNotification *sn)
{
return sn->startup_sequences;
}
+
+/**
+ * meta_startup_notification_create_launcher:
+ * @sn: a #MetaStartupNotification
+ *
+ * Creates an app launch context.
+ *
+ * Returns: (transfer full): a launch context.
+ **/
+MetaLaunchContext *
+meta_startup_notification_create_launcher (MetaStartupNotification *sn)
+{
+ MetaDisplay *display = sn->display;
+
+ return g_object_new (META_TYPE_LAUNCH_CONTEXT,
+ "display", sn->display,
+ NULL);
+}
diff --git a/src/meson.build b/src/meson.build
index 963d70d48..7c641a2db 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -331,6 +331,7 @@ mutter_sources = [
'core/meta-inhibit-shortcuts-dialog.c',
'core/meta-inhibit-shortcuts-dialog-default.c',
'core/meta-inhibit-shortcuts-dialog-default-private.h',
+ 'core/meta-launch-context.c',
'core/meta-workspace-manager.c',
'core/meta-workspace-manager-private.h',
'core/place.c',
diff --git a/src/meta/meson.build b/src/meta/meson.build
index bdd77a08e..299fd2cf1 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -18,6 +18,7 @@ mutter_public_headers = [
'meta-dnd.h',
'meta-idle-monitor.h',
'meta-inhibit-shortcuts-dialog.h',
+ 'meta-launch-context.h',
'meta-monitor-manager.h',
'meta-plugin.h',
'meta-remote-access-controller.h',
diff --git a/src/meta/meta-launch-context.h b/src/meta/meta-launch-context.h
new file mode 100644
index 000000000..eb4414ce7
--- /dev/null
+++ b/src/meta/meta-launch-context.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 Red Hat
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+#ifndef META_LAUNCH_CONTEXT_H
+#define META_LAUNCH_CONTEXT_H
+
+#include <meta/workspace.h>
+
+G_DECLARE_FINAL_TYPE (MetaLaunchContext, meta_launch_context, META, LAUNCH_CONTEXT, GAppLaunchContext)
+
+#define META_TYPE_LAUNCH_CONTEXT (meta_launch_context_get_type ())
+
+void meta_launch_context_set_timestamp (MetaLaunchContext *context,
+ uint32_t timestamp);
+void meta_launch_context_set_workspace (MetaLaunchContext *context,
+ MetaWorkspace *workspace);
+
+#endif /* META_LAUNCH_CONTEXT_H */
diff --git a/src/meta/meta-startup-notification.h b/src/meta/meta-startup-notification.h
index 5b4d51559..da48e1615 100644
--- a/src/meta/meta-startup-notification.h
+++ b/src/meta/meta-startup-notification.h
@@ -19,6 +19,8 @@
#ifndef META_STARTUP_NOTIFICATION_H
#define META_STARTUP_NOTIFICATION_H
+#include <meta/meta-launch-context.h>
+
#define META_TYPE_STARTUP_SEQUENCE (meta_startup_sequence_get_type ())
#define META_TYPE_STARTUP_NOTIFICATION (meta_startup_notification_get_type ())
@@ -32,6 +34,9 @@ GType meta_startup_notification_get_type (void);
*/
GSList * meta_startup_notification_get_sequences (MetaStartupNotification *sn);
+MetaLaunchContext *
+ meta_startup_notification_create_launcher (MetaStartupNotification *sn);
+
GType meta_startup_sequence_get_type (void);
const char * meta_startup_sequence_get_id (MetaStartupSequence *sequence);
@@ -45,4 +50,5 @@ const char * meta_startup_sequence_get_wmclass (MetaStartupSequence *sequ
void meta_startup_sequence_complete (MetaStartupSequence *sequence);
+
#endif /* META_STARTUP_NOTIFICATION_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]