MetaWayland: implement spawning dbus and gnome-session

If we launch gnome-session ourselves after setting up XWayland,
we then get gnome-settings-daemon and all the required session
stuff, which means we can run a full regular gnome session.
This commit is contained in:
Giovanni Campagna 2013-08-08 17:07:54 +02:00
parent bbf07c9b17
commit e9434732d4
4 changed files with 119 additions and 6 deletions

View File

@ -299,6 +299,13 @@ GType meta_monitor_manager_get_type (void);
void meta_monitor_manager_initialize (void);
MetaMonitorManager *meta_monitor_manager_get (void);
void meta_monitor_manager_init_dbus (MetaMonitorManager *manager,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean meta_monitor_manager_init_dbus_finish (MetaMonitorManager *manager,
GAsyncResult *result,
GError **error);
MetaMonitorInfo *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
unsigned int *n_infos);

View File

@ -61,7 +61,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYP
static void free_output_array (MetaOutput *old_outputs,
int n_old_outputs);
static void invalidate_logical_config (MetaMonitorManager *manager);
static void initialize_dbus_interface (MetaMonitorManager *manager);
static void
read_current_dummy (MetaMonitorManager *manager)
@ -525,7 +524,6 @@ meta_monitor_manager_constructed (GObject *object)
}
make_logical_config (manager);
initialize_dbus_interface (manager);
manager->in_init = FALSE;
}
@ -1321,7 +1319,8 @@ on_bus_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
MetaMonitorManager *manager = user_data;
GTask *task = user_data;
MetaMonitorManager *manager = g_task_get_task_data (task);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (manager),
connection,
@ -1334,7 +1333,11 @@ on_name_acquired (GDBusConnection *connection,
const char *name,
gpointer user_data)
{
GTask *task = user_data;
meta_topic (META_DEBUG_DBUS, "Acquired name %s\n", name);
g_task_return_boolean (task, TRUE);
}
static void
@ -1345,9 +1348,14 @@ on_name_lost (GDBusConnection *connection,
meta_topic (META_DEBUG_DBUS, "Lost or failed to acquire name %s\n", name);
}
static void
initialize_dbus_interface (MetaMonitorManager *manager)
void
meta_monitor_manager_init_dbus (MetaMonitorManager *manager,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task = g_task_new (manager, NULL, callback, user_data);
g_task_set_task_data (task, g_object_ref (manager), g_object_unref);
manager->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
"org.gnome.Mutter.DisplayConfig",
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
@ -1356,10 +1364,18 @@ initialize_dbus_interface (MetaMonitorManager *manager)
on_bus_acquired,
on_name_acquired,
on_name_lost,
g_object_ref (manager),
task,
g_object_unref);
}
gboolean
meta_monitor_manager_init_dbus_finish (MetaMonitorManager *manager,
GAsyncResult *result,
GError **error)
{
return g_task_propagate_boolean (G_TASK (result), error);
}
static MetaMonitorManager *global_manager;
void

View File

@ -690,6 +690,11 @@ meta_screen_new (MetaDisplay *display,
&screen->rect.width,
&screen->rect.height);
#ifdef HAVE_WAYLAND
if (!meta_is_wayland_compositor ())
#endif
meta_monitor_manager_init_dbus (manager, NULL, NULL);
screen->current_cursor = -1; /* invalid/unset */
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);

View File

@ -32,6 +32,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <wayland-server.h>
@ -1255,6 +1257,55 @@ bind_shell (struct wl_client *client,
wl_resource_set_implementation (resource, &meta_wayland_shell_interface, data, NULL);
}
static void
gnome_session_died (GPid pid,
gint status,
gpointer user_data)
{
if (!WIFEXITED (status))
g_error ("gnome-session crashed; aborting");
else
{
/* A clean exit of gnome-session implies a logout, exit cleanly */
meta_quit (META_EXIT_SUCCESS);
}
}
static void
start_gnome_session (MetaWaylandCompositor *compositor)
{
GPid pid;
char *args[6];
GError *error;
args[0] = "setsid";
args[1] = "gnome-session";
args[2] = "--session";
args[3] = "gnome-wayland";
args[4] = "--debug";
args[5] = NULL;
error = NULL;
if (g_spawn_async (NULL, /* cwd */
args,
NULL,
G_SPAWN_SEARCH_PATH |
G_SPAWN_DO_NOT_REAP_CHILD,
NULL,
NULL,
&pid,
&error))
{
g_message ("forked gnome-session, pid %d\n", pid);
g_child_watch_add (pid, gnome_session_died, NULL);
}
else
{
g_error ("Failed to fork gnome-session server: %s", error->message);
}
}
static void
stage_destroy_cb (void)
{
@ -1565,6 +1616,21 @@ on_monitors_changed (MetaMonitorManager *monitors,
compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
}
static void
on_display_config_ready (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
gboolean ok;
ok = meta_monitor_manager_init_dbus_finish (META_MONITOR_MANAGER (object), result, NULL);
g_assert (ok);
/* Now we have X and DBus, and our stuff is on the bus.
The only thing missing is gnome-session! */
start_gnome_session (user_data);
}
void
meta_wayland_init (void)
{
@ -1575,6 +1641,8 @@ meta_wayland_init (void)
CoglRenderer *cogl_renderer;
int weston_launch_fd;
MetaMonitorManager *monitors;
GDBusConnection *session_bus;
char *session_bus_address;
memset (compositor, 0, sizeof (MetaWaylandCompositor));
@ -1728,6 +1796,23 @@ meta_wayland_init (void)
g_error ("Failed to start X Wayland");
putenv (g_strdup_printf ("DISPLAY=:%d", compositor->xwayland_display_index));
/* Now xwayland is ready. Get ourselves a dbus daemon. This will autolaunch
if no bus is found.
*/
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
if (!session_bus)
meta_fatal ("Could not connect to the session bus\n");
session_bus_address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, NULL);
putenv (g_strdup_printf ("DBUS_SESSION_BUS_ADDRESS=%s", session_bus_address));
g_free (session_bus_address);
/* Now get our interface on the dbus (or gnome-settings-daemon will refuse
to start, which in turn will stall gnome-session from launching the rest
of the session)
*/
meta_monitor_manager_init_dbus (monitors, on_display_config_ready, compositor);
}
void