summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <halfline@gmail.com>2019-05-31 15:21:58 +0000
committerRay Strode <halfline@gmail.com>2019-05-31 15:21:58 +0000
commite22706820233a2f390853239e6abf0b7dca32bc9 (patch)
tree36f8c06c0115bc0c06799b7c7f05895591f09f52
parent6ad8dc5f830bbb176cf3a6ce2b091692eb0f7d49 (diff)
parent5b7cf8ccf39871c9765471118ed8e3c74ce6cb04 (diff)
downloadgdm-e22706820233a2f390853239e6abf0b7dca32bc9.tar.gz
Merge branch 'x-gdm-sessionregisters' into 'master'
Allow sessions to register with GDM Closes #483 See merge request GNOME/gdm!67
-rw-r--r--common/gdm-common.h2
-rw-r--r--configure.ac6
-rw-r--r--daemon/gdm-display.c44
-rw-r--r--daemon/gdm-local-display-factory.c100
-rw-r--r--daemon/gdm-manager.c30
-rw-r--r--daemon/gdm-manager.xml3
-rw-r--r--daemon/gdm-server.c2
-rw-r--r--daemon/gdm-session-worker.c2
-rw-r--r--daemon/gdm-session.c47
-rw-r--r--daemon/gdm-session.h1
-rw-r--r--daemon/gdm-wayland-session.c81
-rw-r--r--daemon/gdm-x-session.c81
12 files changed, 292 insertions, 107 deletions
diff --git a/common/gdm-common.h b/common/gdm-common.h
index 07812b10..58814aa2 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -27,6 +27,8 @@
#include <pwd.h>
#include <errno.h>
+#define REGISTER_SESSION_TIMEOUT 10
+
#define VE_IGNORE_EINTR(expr) \
do { \
errno = 0; \
diff --git a/configure.ac b/configure.ac
index e54017f2..0a1c6c19 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1416,12 +1416,12 @@ AC_ARG_WITH(initial-vt,
AS_HELP_STRING([--with-initial-vt=<nr>],
[Initial virtual terminal to use]))
if ! test -z "$with_initial_vt"; then
- GDM_INITIAL_VT="$with_initial_vt"
+ GDM_INITIAL_VT=$with_initial_vt
else
- GDM_INITIAL_VT="1"
+ GDM_INITIAL_VT=1
fi
AC_SUBST(GDM_INITIAL_VT)
-AC_DEFINE_UNQUOTED(GDM_INITIAL_VT, "$GDM_INITIAL_VT", [Initial Virtual Terminal])
+AC_DEFINE_UNQUOTED(GDM_INITIAL_VT, $GDM_INITIAL_VT, [Initial Virtual Terminal])
# Set configuration choices.
#
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index a8747785..8f4fbc71 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -66,7 +66,6 @@ typedef struct _GdmDisplayPrivate
char *x11_display_name;
int status;
time_t creation_time;
- GTimer *server_timer;
char *x11_cookie;
gsize x11_cookie_size;
@@ -93,6 +92,7 @@ typedef struct _GdmDisplayPrivate
guint allow_timed_login : 1;
guint have_existing_user_accounts : 1;
guint doing_initial_setup : 1;
+ guint session_registered : 1;
} GdmDisplayPrivate;
enum {
@@ -115,6 +115,7 @@ enum {
PROP_ALLOW_TIMED_LOGIN,
PROP_HAVE_EXISTING_USER_ACCOUNTS,
PROP_DOING_INITIAL_SETUP,
+ PROP_SESSION_REGISTERED,
};
static void gdm_display_class_init (GdmDisplayClass *klass);
@@ -598,8 +599,6 @@ gdm_display_manage (GdmDisplay *self)
}
}
- g_timer_start (priv->server_timer);
-
if (g_strcmp0 (priv->session_class, "greeter") == 0) {
if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) {
GDM_DISPLAY_GET_CLASS (self)->manage (self);
@@ -671,7 +670,6 @@ gboolean
gdm_display_unmanage (GdmDisplay *self)
{
GdmDisplayPrivate *priv;
- gdouble elapsed;
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
@@ -681,8 +679,6 @@ gdm_display_unmanage (GdmDisplay *self)
gdm_display_disconnect (self);
- g_timer_stop (priv->server_timer);
-
if (priv->user_access_file != NULL) {
gdm_display_access_file_close (priv->user_access_file);
g_object_unref (priv->user_access_file);
@@ -695,9 +691,8 @@ gdm_display_unmanage (GdmDisplay *self)
priv->access_file = NULL;
}
- elapsed = g_timer_elapsed (priv->server_timer, NULL);
- if (elapsed < 3) {
- g_warning ("GdmDisplay: display lasted %lf seconds", elapsed);
+ if (!priv->session_registered) {
+ g_warning ("GdmDisplay: Session never registered, failing");
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
} else {
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
@@ -872,6 +867,17 @@ _gdm_display_set_is_local (GdmDisplay *self,
}
static void
+_gdm_display_set_session_registered (GdmDisplay *self,
+ gboolean registered)
+{
+ GdmDisplayPrivate *priv;
+
+ priv = gdm_display_get_instance_private (self);
+ g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no");
+ priv->session_registered = registered;
+}
+
+static void
_gdm_display_set_launch_environment (GdmDisplay *self,
GdmLaunchEnvironment *launch_environment)
{
@@ -959,6 +965,9 @@ gdm_display_set_property (GObject *object,
case PROP_IS_INITIAL:
_gdm_display_set_is_initial (self, g_value_get_boolean (value));
break;
+ case PROP_SESSION_REGISTERED:
+ _gdm_display_set_session_registered (self, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1031,6 +1040,9 @@ gdm_display_get_property (GObject *object,
case PROP_DOING_INITIAL_SETUP:
g_value_set_boolean (value, priv->doing_initial_setup);
break;
+ case PROP_SESSION_REGISTERED:
+ g_value_set_boolean (value, priv->session_registered);
+ break;
case PROP_ALLOW_TIMED_LOGIN:
g_value_set_boolean (value, priv->allow_timed_login);
break;
@@ -1356,6 +1368,14 @@ gdm_display_class_init (GdmDisplayClass *klass)
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
+ PROP_SESSION_REGISTERED,
+ g_param_spec_boolean ("session-registered",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class,
PROP_LAUNCH_ENVIRONMENT,
g_param_spec_object ("launch-environment",
NULL,
@@ -1381,7 +1401,6 @@ gdm_display_init (GdmDisplay *self)
priv = gdm_display_get_instance_private (self);
priv->creation_time = time (NULL);
- priv->server_timer = g_timer_new ();
}
static void
@@ -1419,10 +1438,6 @@ gdm_display_finalize (GObject *object)
g_object_unref (priv->user_access_file);
}
- if (priv->server_timer != NULL) {
- g_timer_destroy (priv->server_timer);
- }
-
G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object);
}
@@ -1720,7 +1735,6 @@ void
gdm_display_stop_greeter_session (GdmDisplay *self)
{
GdmDisplayPrivate *priv;
- GError *error = NULL;
priv = gdm_display_get_instance_private (self);
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 98daca48..ee41308b 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -64,9 +64,8 @@ struct _GdmLocalDisplayFactory
guint seat_removed_id;
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
- char *tty_of_active_vt;
+ unsigned int active_vt;
guint active_vt_watch_id;
- guint wait_to_finish_timeout_id;
#endif
};
@@ -299,6 +298,25 @@ finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory,
}
static void
+on_session_registered_cb (GObject *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GdmDisplay *display = GDM_DISPLAY (gobject);
+ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data);
+ gboolean registered;
+
+ g_object_get (display, "session-registered", &registered, NULL);
+
+ if (!registered)
+ return;
+
+ g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill");
+
+ finish_waiting_displays_on_seat (factory, "seat0");
+}
+
+static void
on_display_status_changed (GdmDisplay *display,
GParamSpec *arg1,
GdmLocalDisplayFactory *factory)
@@ -376,6 +394,13 @@ on_display_status_changed (GdmDisplay *display,
case GDM_DISPLAY_PREPARED:
break;
case GDM_DISPLAY_MANAGED:
+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
+ g_signal_connect_object (display,
+ "notify::session-registered",
+ G_CALLBACK (on_session_registered_cb),
+ factory,
+ 0);
+#endif
break;
case GDM_DISPLAY_WAITING_TO_FINISH:
break;
@@ -604,14 +629,6 @@ lookup_by_session_id (const char *id,
}
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
-static gboolean
-wait_to_finish_timeout (GdmLocalDisplayFactory *factory)
-{
- finish_waiting_displays_on_seat (factory, "seat0");
- factory->wait_to_finish_timeout_id = 0;
- return G_SOURCE_REMOVE;
-}
-
static void
maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
@@ -643,16 +660,8 @@ maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
}
g_debug ("GdmLocalDisplayFactory: killing login window once its unused");
- g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
- /* We stop the greeter after a timeout to avoid flicker */
- if (factory->wait_to_finish_timeout_id != 0)
- g_source_remove (factory->wait_to_finish_timeout_id);
-
- factory->wait_to_finish_timeout_id =
- g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT,
- (GSourceFunc)wait_to_finish_timeout,
- factory);
+ g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
}
static gboolean
@@ -661,13 +670,12 @@ on_vt_changed (GIOChannel *source,
GdmLocalDisplayFactory *factory)
{
GIOStatus status;
- static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT;
- g_autofree char *tty_of_previous_vt = NULL;
g_autofree char *tty_of_active_vt = NULL;
g_autofree char *login_session_id = NULL;
g_autofree char *active_session_id = NULL;
+ unsigned int previous_vt, new_vt;
const char *session_type = NULL;
- int ret;
+ int ret, n_returned;
g_debug ("GdmLocalDisplayFactory: received VT change event");
g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL);
@@ -703,38 +711,43 @@ on_vt_changed (GIOChannel *source,
g_strchomp (tty_of_active_vt);
+ errno = 0;
+ n_returned = sscanf (tty_of_active_vt, "tty%u", &new_vt);
+
+ if (n_returned != 1 || errno != 0) {
+ g_critical ("GdmLocalDisplayFactory: Couldn't read active VT (got '%s')",
+ tty_of_active_vt);
+ return G_SOURCE_CONTINUE;
+ }
+
/* don't do anything if we're on the same VT we were before */
- if (g_strcmp0 (tty_of_active_vt, factory->tty_of_active_vt) == 0) {
+ if (new_vt == factory->active_vt) {
g_debug ("GdmLocalDisplayFactory: VT changed to the same VT, ignoring");
return G_SOURCE_CONTINUE;
}
- tty_of_previous_vt = g_steal_pointer (&factory->tty_of_active_vt);
- factory->tty_of_active_vt = g_steal_pointer (&tty_of_active_vt);
+ previous_vt = factory->active_vt;
+ factory->active_vt = new_vt;
/* don't do anything at start up */
- if (tty_of_previous_vt == NULL) {
- g_debug ("GdmLocalDisplayFactory: VT is %s at startup",
- factory->tty_of_active_vt);
+ if (previous_vt == 0) {
+ g_debug ("GdmLocalDisplayFactory: VT is %u at startup",
+ factory->active_vt);
return G_SOURCE_CONTINUE;
}
- g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s",
- tty_of_previous_vt, factory->tty_of_active_vt);
+ g_debug ("GdmLocalDisplayFactory: VT changed from %u to %u",
+ previous_vt, factory->active_vt);
/* if the old VT was running a wayland login screen kill it
*/
if (gdm_get_login_window_session_id ("seat0", &login_session_id)) {
- unsigned int vt;
-
- ret = sd_session_get_vt (login_session_id, &vt);
- if (ret == 0 && vt != 0) {
- g_autofree char *tty_of_login_window_vt = NULL;
-
- tty_of_login_window_vt = g_strdup_printf ("tty%u", vt);
+ unsigned int login_window_vt;
- g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt);
- if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) {
+ ret = sd_session_get_vt (login_session_id, &login_window_vt);
+ if (ret == 0 && login_window_vt != 0) {
+ g_debug ("GdmLocalDisplayFactory: VT of login window is %u", login_window_vt);
+ if (login_window_vt == previous_vt) {
GdmDisplayStore *store;
GdmDisplay *display;
@@ -744,7 +757,6 @@ on_vt_changed (GIOChannel *source,
display = gdm_display_store_find (store,
lookup_by_session_id,
(gpointer) login_session_id);
-
if (display != NULL)
maybe_stop_greeter_in_background (factory, display);
} else {
@@ -757,7 +769,7 @@ on_vt_changed (GIOChannel *source,
* on it (unless a login screen is already running elsewhere, then
* jump to that login screen)
*/
- if (strcmp (factory->tty_of_active_vt, tty_of_initial_vt) != 0) {
+ if (factory->active_vt != GDM_INITIAL_VT) {
g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring");
return G_SOURCE_CONTINUE;
}
@@ -827,16 +839,10 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
factory->seat_removed_id = 0;
}
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
- if (factory->wait_to_finish_timeout_id != 0) {
- g_source_remove (factory->wait_to_finish_timeout_id);
- factory->wait_to_finish_timeout_id = 0;
- }
if (factory->active_vt_watch_id) {
g_source_remove (factory->active_vt_watch_id);
factory->active_vt_watch_id = 0;
}
-
- g_clear_pointer (&factory->tty_of_active_vt, g_free);
#endif
}
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 980aa62d..23e3b85d 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -804,6 +804,35 @@ gdm_manager_handle_register_display (GdmDBusManager *manager,
}
static gboolean
+gdm_manager_handle_register_session (GdmDBusManager *manager,
+ GDBusMethodInvocation *invocation,
+ GVariant *details)
+{
+ GdmManager *self = GDM_MANAGER (manager);
+ GdmDisplay *display;
+ const char *sender;
+ GDBusConnection *connection;
+
+ sender = g_dbus_method_invocation_get_sender (invocation);
+ connection = g_dbus_method_invocation_get_connection (invocation);
+
+ get_display_and_details_for_bus_sender (self, connection, sender, &display,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ g_debug ("GdmManager: trying to register new session on display %p", display);
+
+ if (display != NULL)
+ g_object_set (G_OBJECT (display), "session-registered", TRUE, NULL);
+ else
+ g_debug ("GdmManager: No display, not registering");
+
+ gdm_dbus_manager_complete_register_session (GDM_DBUS_MANAGER (manager),
+ invocation);
+
+ return TRUE;
+}
+
+static gboolean
gdm_manager_handle_open_session (GdmDBusManager *manager,
GDBusMethodInvocation *invocation)
{
@@ -1159,6 +1188,7 @@ static void
manager_interface_init (GdmDBusManagerIface *interface)
{
interface->handle_register_display = gdm_manager_handle_register_display;
+ interface->handle_register_session = gdm_manager_handle_register_session;
interface->handle_open_session = gdm_manager_handle_open_session;
interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
}
diff --git a/daemon/gdm-manager.xml b/daemon/gdm-manager.xml
index f11f3fb7..92ef1d02 100644
--- a/daemon/gdm-manager.xml
+++ b/daemon/gdm-manager.xml
@@ -4,6 +4,9 @@
<method name="RegisterDisplay">
<arg name="details" direction="in" type="a{ss}"/>
</method>
+ <method name="RegisterSession">
+ <arg name="details" direction="in" type="a{sv}"/>
+ </method>
<method name="OpenSession">
<arg name="address" direction="out" type="s"/>
</method>
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index 7962de22..1ba00d45 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -753,7 +753,7 @@ gdm_server_start (GdmServer *server)
/* Hardcode the VT for the initial X server, but nothing else */
if (server->is_initial) {
- vtarg = "vt" GDM_INITIAL_VT;
+ vtarg = "vt" G_STRINGIFY (GDM_INITIAL_VT);
}
/* fork X server process */
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 640cdbb6..a5f90c4b 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2224,7 +2224,7 @@ set_up_for_new_vt (GdmSessionWorker *worker)
}
if (worker->priv->display_is_initial) {
- session_vt = atoi (GDM_INITIAL_VT);
+ session_vt = GDM_INITIAL_VT;
} else {
if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) {
g_debug ("GdmSessionWorker: couldn't open new VT: %m");
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 6a116a85..d0e09b53 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -2837,6 +2837,7 @@ gdm_session_start_session (GdmSession *self,
gboolean allow_remote_connections = FALSE;
char *command;
char *program;
+ gboolean register_session;
g_return_if_fail (GDM_IS_SESSION (self));
g_return_if_fail (self->session_conversation == NULL);
@@ -2862,6 +2863,8 @@ gdm_session_start_session (GdmSession *self,
run_launcher = TRUE;
}
+ register_session = !gdm_session_session_registers (self);
+
if (self->selected_program == NULL) {
gboolean run_xsession_script;
@@ -2879,12 +2882,14 @@ gdm_session_start_session (GdmSession *self,
if (run_launcher) {
if (is_x11) {
- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s %s\"%s\"",
+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"",
+ register_session ? "--register-session " : "",
run_xsession_script? "--run-script " : "",
allow_remote_connections? "--allow-remote-connections " : "",
command);
} else {
- program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"",
+ program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
+ register_session ? "--register-session " : "",
command);
}
} else if (run_xsession_script) {
@@ -2897,10 +2902,12 @@ gdm_session_start_session (GdmSession *self,
} else {
if (run_launcher) {
if (is_x11) {
- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"",
+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"%s\"",
+ register_session ? "--register-session " : "",
self->selected_program);
} else {
- program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"",
+ program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
+ register_session ? "--register-session " : "",
self->selected_program);
}
} else {
@@ -3178,6 +3185,38 @@ update_session_type (GdmSession *self)
}
gboolean
+gdm_session_session_registers (GdmSession *self)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GKeyFile) key_file = NULL;
+ gboolean session_registers = FALSE;
+ g_autofree char *filename = NULL;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
+
+ filename = get_session_filename (self);
+
+ key_file = load_key_file_for_file (self, filename, NULL);
+
+ session_registers = g_key_file_get_boolean (key_file,
+ G_KEY_FILE_DESKTOP_GROUP,
+ "X-GDM-SessionRegisters",
+ &error);
+ if (!session_registers &&
+ error != NULL &&
+ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) {
+ g_warning ("GdmSession: Couldn't read session file '%s'", filename);
+ return FALSE;
+ }
+
+ g_debug ("GdmSession: '%s' %s self", filename,
+ session_registers ? "registers" : "does not register");
+
+ return session_registers;
+}
+
+gboolean
gdm_session_bypasses_xsession (GdmSession *self)
{
GError *error;
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 98acb4f6..3b64ecd2 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -76,6 +76,7 @@ const char *gdm_session_get_display_device (GdmSession *sessi
const char *gdm_session_get_display_seat_id (GdmSession *session);
const char *gdm_session_get_session_id (GdmSession *session);
gboolean gdm_session_bypasses_xsession (GdmSession *session);
+gboolean gdm_session_session_registers (GdmSession *session);
GdmSessionDisplayMode gdm_session_get_display_mode (GdmSession *session);
#ifdef ENABLE_WAYLAND_SUPPORT
diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
index 94f49e19..35679b19 100644
--- a/daemon/gdm-wayland-session.c
+++ b/daemon/gdm-wayland-session.c
@@ -45,6 +45,7 @@ typedef struct
GSubprocess *bus_subprocess;
GDBusConnection *bus_connection;
+ GdmDBusManager *display_manager_proxy;
char *bus_address;
char **environment;
@@ -53,6 +54,8 @@ typedef struct
char *session_command;
int session_exit_status;
+ guint register_session_id;
+
GMainLoop *main_loop;
guint32 debug_enabled : 1;
@@ -385,29 +388,14 @@ static gboolean
register_display (State *state,
GCancellable *cancellable)
{
- GdmDBusManager *manager = NULL;
GError *error = NULL;
gboolean registered = FALSE;
GVariantBuilder details;
- manager = gdm_dbus_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- "org.gnome.DisplayManager",
- "/org/gnome/DisplayManager/Manager",
- cancellable,
- &error);
-
- if (!manager) {
- g_debug ("could not contact display manager: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
g_variant_builder_add (&details, "{ss}", "session-type", "wayland");
- registered = gdm_dbus_manager_call_register_display_sync (manager,
+ registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy,
g_variant_builder_end (&details),
cancellable,
&error);
@@ -416,8 +404,6 @@ register_display (State *state,
g_error_free (error);
}
-out:
- g_clear_object (&manager);
return registered;
}
@@ -439,6 +425,7 @@ clear_state (State **out_state)
g_clear_object (&state->session_subprocess);
g_clear_pointer (&state->environment, g_strfreev);
g_clear_pointer (&state->main_loop, g_main_loop_unref);
+ g_clear_handle_id (&state->register_session_id, g_source_remove);
*out_state = NULL;
}
@@ -454,6 +441,49 @@ on_sigterm (State *state)
return G_SOURCE_CONTINUE;
}
+static gboolean
+register_session_timeout_cb (gpointer user_data)
+{
+ State *state;
+ GError *error = NULL;
+
+ state = (State *) user_data;
+
+ gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
+ g_variant_new ("a{sv}", NULL),
+ state->cancellable,
+ &error);
+
+ if (error != NULL) {
+ g_warning ("Could not register session: %s", error->message);
+ g_error_free (error);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+connect_to_display_manager (State *state)
+{
+ g_autoptr (GError) error = NULL;
+
+ state->display_manager_proxy = gdm_dbus_manager_proxy_new_for_bus_sync (
+ G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ "org.gnome.DisplayManager",
+ "/org/gnome/DisplayManager/Manager",
+ state->cancellable,
+ &error);
+
+ if (state->display_manager_proxy == NULL) {
+ g_printerr ("gdm-wayland-session: could not contact display manager: %s\n",
+ error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
int
main (int argc,
char **argv)
@@ -464,7 +494,10 @@ main (int argc,
gboolean debug = FALSE;
gboolean ret;
int exit_status = EX_OK;
+ static gboolean register_session = FALSE;
+
static GOptionEntry entries [] = {
+ { "register-session", 0, 0, G_OPTION_ARG_NONE, &register_session, "Register session after a delay", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
{ NULL }
};
@@ -528,6 +561,9 @@ main (int argc,
goto out;
}
+ if (!connect_to_display_manager (state))
+ goto out;
+
ret = register_display (state, state->cancellable);
if (!ret) {
@@ -536,6 +572,15 @@ main (int argc,
goto out;
}
+ if (register_session) {
+ g_debug ("gdm-wayland-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT);
+ state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT,
+ register_session_timeout_cb,
+ state);
+ } else {
+ g_debug ("gdm-wayland-session: Session will register itself");
+ }
+
g_main_loop_run (state->main_loop);
/* Only use exit status of session if we're here because it exit */
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
index 3b2fcef4..58865a6c 100644
--- a/daemon/gdm-x-session.c
+++ b/daemon/gdm-x-session.c
@@ -51,6 +51,7 @@ typedef struct
GSubprocess *bus_subprocess;
GDBusConnection *bus_connection;
+ GdmDBusManager *display_manager_proxy;
char *bus_address;
char **environment;
@@ -59,6 +60,8 @@ typedef struct
char *session_command;
int session_exit_status;
+ guint register_session_id;
+
GMainLoop *main_loop;
guint32 debug_enabled : 1;
@@ -737,30 +740,15 @@ static gboolean
register_display (State *state,
GCancellable *cancellable)
{
- GdmDBusManager *manager = NULL;
GError *error = NULL;
gboolean registered = FALSE;
GVariantBuilder details;
- manager = gdm_dbus_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- "org.gnome.DisplayManager",
- "/org/gnome/DisplayManager/Manager",
- cancellable,
- &error);
-
- if (!manager) {
- g_debug ("could not contact display manager: %s", error->message);
- g_error_free (error);
- goto out;
- }
-
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
g_variant_builder_add (&details, "{ss}", "session-type", "x11");
g_variant_builder_add (&details, "{ss}", "x11-display-name", state->display_name);
- registered = gdm_dbus_manager_call_register_display_sync (manager,
+ registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy,
g_variant_builder_end (&details),
cancellable,
&error);
@@ -769,8 +757,6 @@ register_display (State *state,
g_error_free (error);
}
-out:
- g_clear_object (&manager);
return registered;
}
@@ -795,6 +781,7 @@ clear_state (State **out_state)
g_clear_pointer (&state->auth_file, g_free);
g_clear_pointer (&state->display_name, g_free);
g_clear_pointer (&state->main_loop, g_main_loop_unref);
+ g_clear_handle_id (&state->register_session_id, g_source_remove);
*out_state = NULL;
}
@@ -810,6 +797,49 @@ on_sigterm (State *state)
return G_SOURCE_CONTINUE;
}
+static gboolean
+register_session_timeout_cb (gpointer user_data)
+{
+ State *state;
+ GError *error = NULL;
+
+ state = (State *) user_data;
+
+ gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy,
+ g_variant_new ("a{sv}", NULL),
+ state->cancellable,
+ &error);
+
+ if (error != NULL) {
+ g_warning ("Could not register session: %s", error->message);
+ g_error_free (error);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+connect_to_display_manager (State *state)
+{
+ g_autoptr (GError) error = NULL;
+
+ state->display_manager_proxy = gdm_dbus_manager_proxy_new_for_bus_sync (
+ G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ "org.gnome.DisplayManager",
+ "/org/gnome/DisplayManager/Manager",
+ state->cancellable,
+ &error);
+
+ if (state->display_manager_proxy == NULL) {
+ g_printerr ("gdm-x-session: could not contact display manager: %s\n",
+ error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
int
main (int argc,
char **argv)
@@ -822,9 +852,12 @@ main (int argc,
gboolean debug = FALSE;
gboolean ret;
int exit_status = EX_OK;
+ static gboolean register_session = FALSE;
+
static GOptionEntry entries [] = {
{ "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL },
{ "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL },
+ { "register-session", 0, 0, G_OPTION_ARG_NONE, &register_session, "Register session after a delay", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
{ NULL }
};
@@ -896,6 +929,9 @@ main (int argc,
goto out;
}
+ if (!connect_to_display_manager (state))
+ goto out;
+
ret = register_display (state, state->cancellable);
if (!ret) {
@@ -912,6 +948,15 @@ main (int argc,
goto out;
}
+ if (register_session) {
+ g_debug ("gdm-x-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT);
+ state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT,
+ register_session_timeout_cb,
+ state);
+ } else {
+ g_debug ("gdm-x-session: Session will register itself");
+ }
+
g_main_loop_run (state->main_loop);
/* Only use exit status of session if we're here because it exit */