summaryrefslogtreecommitdiff
path: root/daemon/gdm-local-display-factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/gdm-local-display-factory.c')
-rw-r--r--daemon/gdm-local-display-factory.c118
1 files changed, 76 insertions, 42 deletions
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 0b7e8928..e8fb4779 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -513,8 +513,10 @@ on_display_status_changed (GdmDisplay *display,
int status;
int num;
char *seat_id = NULL;
+ char *seat_active_session = NULL;
char *session_type = NULL;
char *session_class = NULL;
+ char *session_id = NULL;
gboolean is_initial = TRUE;
gboolean is_local = TRUE;
@@ -531,8 +533,11 @@ on_display_status_changed (GdmDisplay *display,
"is-local", &is_local,
"session-type", &session_type,
"session-class", &session_class,
+ "session-id", &session_id,
NULL);
+ sd_seat_get_active (seat_id, &seat_active_session, NULL);
+
status = gdm_display_get_status (display);
g_debug ("GdmLocalDisplayFactory: display status changed: %d", status);
@@ -545,17 +550,18 @@ on_display_status_changed (GdmDisplay *display,
}
gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory));
- /* if this is a local display, do a full resync. Only
- * seats without displays will get created anyway. This
- * ensures we get a new login screen when the user logs out,
- * if there isn't one.
+ /* if this is a local display, ensure that we get a login
+ * screen when the user logs out.
*/
if (is_local &&
- (g_strcmp0 (session_class, "greeter") != 0 || factory->active_vt == GDM_INITIAL_VT)) {
+ ((g_strcmp0 (session_class, "greeter") != 0 &&
+ (!seat_active_session || g_strcmp0(session_id, seat_active_session) == 0)) ||
+ factory->active_vt == GDM_INITIAL_VT ||
+ g_strcmp0 (seat_id, "seat0") != 0)) {
/* reset num failures */
factory->num_failures = 0;
- gdm_local_display_factory_sync_seats (factory);
+ ensure_display_for_seat (factory, seat_id);
}
break;
case GDM_DISPLAY_FAILED:
@@ -596,8 +602,10 @@ on_display_status_changed (GdmDisplay *display,
}
g_free (seat_id);
+ g_free (seat_active_session);
g_free (session_type);
g_free (session_class);
+ g_free (session_id);
}
static gboolean
@@ -633,6 +641,21 @@ lookup_prepared_display_by_seat_id (const char *id,
return lookup_by_seat_id (id, display, user_data);
}
+static gboolean
+lookup_managed_display_by_seat_id (const char *id,
+ GdmDisplay *display,
+ gpointer user_data)
+{
+ int status;
+
+ status = gdm_display_get_status (display);
+
+ if (status != GDM_DISPLAY_MANAGED)
+ return FALSE;
+
+ return lookup_by_seat_id (id, display, user_data);
+}
+
#ifdef HAVE_UDEV
static gboolean
udev_is_settled (GdmLocalDisplayFactory *factory)
@@ -747,7 +770,7 @@ get_display_for_seat (GdmLocalDisplayFactory *factory,
if (is_seat0)
display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
else
- display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
+ display = gdm_display_store_find (store, lookup_managed_display_by_seat_id, (gpointer) seat_id);
return display;
}
@@ -758,6 +781,7 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
{
gboolean seat_supports_graphics;
gboolean is_seat0;
+ gboolean falling_back;
g_auto (GStrv) session_types = NULL;
const char *legacy_session_types[] = { "x11", NULL };
GdmDisplay *display = NULL;
@@ -767,13 +791,6 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: display for seat %s requested", seat_id);
- /* Ensure we don't create the same display more than once */
- display = get_display_for_seat (factory, seat_id);
- if (display != NULL) {
- g_debug ("GdmLocalDisplayFactory: display for %s already created", seat_id);
- return;
- }
-
/* If we already have a login window, switch to it */
if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
GdmDisplay *display;
@@ -828,24 +845,16 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
}
is_seat0 = g_strcmp0 (seat_id, "seat0") == 0;
- if (is_seat0) {
- gboolean falling_back;
- falling_back = factory->num_failures > 0;
- session_types = gdm_local_display_factory_get_session_types (factory, falling_back);
+ falling_back = factory->num_failures > 0;
+ session_types = gdm_local_display_factory_get_session_types (factory, falling_back);
- if (session_types == NULL) {
- g_debug ("GdmLocalDisplayFactory: Both Wayland and Xorg are unavailable");
- seat_supports_graphics = FALSE;
- } else {
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
- session_types[0], falling_back? " fallback" : "");
- }
+ if (session_types == NULL) {
+ g_debug ("GdmLocalDisplayFactory: Both Wayland and Xorg are unavailable");
+ seat_supports_graphics = FALSE;
} else {
- g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
- /* Force legacy X11 for all auxiliary seats */
- seat_supports_graphics = TRUE;
- session_types = g_strdupv ((char **) legacy_session_types);
+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
+ session_types[0], falling_back? " fallback" : "");
}
/* For seat0, we have a fallback logic to still try starting it after
@@ -902,18 +911,23 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
session_types[0], seat_id);
+ /* Ensure we don't create the same display more than once */
+ display = get_display_for_seat (factory, seat_id);
+ if (display != NULL) {
+ g_debug ("GdmLocalDisplayFactory: display for %s already created", seat_id);
+ return;
+ }
+
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
#ifdef ENABLE_USER_DISPLAY_SERVER
if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
g_strcmp0 (preferred_display_server, "xorg") == 0) {
- if (is_seat0) {
- display = gdm_local_display_new ();
- g_object_set (G_OBJECT (display),
- "session-type", session_types[0],
- "supported-session-types", session_types,
- NULL);
- }
+ display = gdm_local_display_new ();
+ g_object_set (G_OBJECT (display),
+ "session-type", session_types[0],
+ "supported-session-types", session_types,
+ NULL);
}
#endif
@@ -1037,19 +1051,39 @@ on_seat_properties_changed (GDBusConnection *connection,
const gchar *seat = NULL;
g_autoptr(GVariant) changed_props = NULL;
g_autoptr(GVariant) changed_prop = NULL;
+ g_autoptr(GVariant) reply = NULL;
+ g_autoptr(GVariant) reply_value = NULL;
+ g_autoptr(GError) error = NULL;
g_autofree const gchar **invalidated_props = NULL;
gboolean changed = FALSE;
int ret;
- /* Extract seat id, i.e. the last element of the object path. */
- seat = strrchr (object_path, '/');
- if (seat == NULL)
+ /* Acquire seat name */
+ reply = g_dbus_connection_call_sync (connection,
+ sender_name,
+ object_path,
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)",
+ "org.freedesktop.login1.Seat",
+ "Id"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error);
+
+ if (reply == NULL) {
+ g_debug ("could not acquire seat name: %s", error->message);
return;
- seat += 1;
+ }
+
+ g_variant_get (reply, "(v)", &reply_value);
- /* Valid seat IDs must start with seat, i.e. ignore "auto" */
- if (!g_str_has_prefix (seat, "seat"))
+ seat = g_variant_get_string (reply_value, NULL);
+
+ if (seat == NULL) {
+ g_debug ("seat name is not string");
return;
+ }
g_variant_get (parameters, "(s@a{sv}^a&s)", NULL, &changed_props, &invalidated_props);