mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
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.
This commit is contained in:
parent
ca67d52cac
commit
f033d0e846
258
src/core/meta-launch-context.c
Normal file
258
src/core/meta-launch-context.c
Normal file
@ -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 <gio/gdesktopappinfo.h>
|
||||||
|
|
||||||
|
#include "core/display-private.h"
|
||||||
|
#include "meta/meta-launch-context.h"
|
||||||
|
#include "x11/meta-startup-notification-x11.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;
|
||||||
|
}
|
@ -631,3 +631,21 @@ meta_startup_notification_get_sequences (MetaStartupNotification *sn)
|
|||||||
{
|
{
|
||||||
return sn->startup_sequences;
|
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);
|
||||||
|
}
|
||||||
|
@ -334,6 +334,7 @@ mutter_sources = [
|
|||||||
'core/meta-inhibit-shortcuts-dialog.c',
|
'core/meta-inhibit-shortcuts-dialog.c',
|
||||||
'core/meta-inhibit-shortcuts-dialog-default.c',
|
'core/meta-inhibit-shortcuts-dialog-default.c',
|
||||||
'core/meta-inhibit-shortcuts-dialog-default-private.h',
|
'core/meta-inhibit-shortcuts-dialog-default-private.h',
|
||||||
|
'core/meta-launch-context.c',
|
||||||
'core/meta-sound-player.c',
|
'core/meta-sound-player.c',
|
||||||
'core/meta-workspace-manager.c',
|
'core/meta-workspace-manager.c',
|
||||||
'core/meta-workspace-manager-private.h',
|
'core/meta-workspace-manager-private.h',
|
||||||
|
@ -18,6 +18,7 @@ mutter_public_headers = [
|
|||||||
'meta-dnd.h',
|
'meta-dnd.h',
|
||||||
'meta-idle-monitor.h',
|
'meta-idle-monitor.h',
|
||||||
'meta-inhibit-shortcuts-dialog.h',
|
'meta-inhibit-shortcuts-dialog.h',
|
||||||
|
'meta-launch-context.h',
|
||||||
'meta-monitor-manager.h',
|
'meta-monitor-manager.h',
|
||||||
'meta-plugin.h',
|
'meta-plugin.h',
|
||||||
'meta-remote-access-controller.h',
|
'meta-remote-access-controller.h',
|
||||||
|
35
src/meta/meta-launch-context.h
Normal file
35
src/meta/meta-launch-context.h
Normal file
@ -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 */
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef META_STARTUP_NOTIFICATION_H
|
#ifndef META_STARTUP_NOTIFICATION_H
|
||||||
#define 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_SEQUENCE (meta_startup_sequence_get_type ())
|
||||||
#define META_TYPE_STARTUP_NOTIFICATION (meta_startup_notification_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);
|
GSList * meta_startup_notification_get_sequences (MetaStartupNotification *sn);
|
||||||
|
|
||||||
|
MetaLaunchContext *
|
||||||
|
meta_startup_notification_create_launcher (MetaStartupNotification *sn);
|
||||||
|
|
||||||
GType meta_startup_sequence_get_type (void);
|
GType meta_startup_sequence_get_type (void);
|
||||||
|
|
||||||
const char * meta_startup_sequence_get_id (MetaStartupSequence *sequence);
|
const char * meta_startup_sequence_get_id (MetaStartupSequence *sequence);
|
||||||
|
Loading…
Reference in New Issue
Block a user