summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Lane <iainl@gnome.org>2018-10-11 17:35:22 +0100
committerIain Lane <iainl@gnome.org>2018-10-16 14:07:34 +0100
commit9032bf05269103c50ce04444eba26e22c03ef762 (patch)
tree556e08ac64616297c662828009149143c93b09b7
parente59639b672e694b654dda075e28ec688332802cb (diff)
downloadgdm-wip/can-graphical-support.tar.gz
local-display-factory: Don't try sd_seat_can_graphicalwip/can-graphical-support
I've been seeing cases where this function returns FALSE when the seat actually can host a graphical session - when loginctl says "yes". In this case we think we can't, so we don't start up - but we actually can, so logind never sends a PropertiesChanged signal that we can react on to start the greeter. That's a bad situation. Actually creating the proxy retrieves the value of the property for us automatically, so we can just fetch it from there instead of using the libsystemd API.
-rw-r--r--daemon/gdm-local-display-factory.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 5430085e..c6180643 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -90,10 +90,11 @@ static void on_display_status_changed (GdmDisplay
static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory);
-static gboolean create_seat_proxy (GdmLocalDisplayFactory *self,
- const char *seat_id,
- const char *seat_path);
+static GDBusProxy *create_seat_proxy (GdmLocalDisplayFactory *self,
+ const char *seat_id,
+ const char *seat_path);
+static gboolean seat_proxy_can_graphical (GDBusProxy *seat_proxy);
static gpointer local_display_factory_object = NULL;
static gboolean lookup_by_session_id (const char *id,
GdmDisplay *display,
@@ -552,6 +553,7 @@ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
while (g_variant_iter_loop (&iter, "(&s&o)", &seat, &path)) {
gboolean is_initial;
+ g_autoptr (GDBusProxy) proxy = NULL;
const char *session_type = NULL;
if (g_strcmp0 (seat, "seat0") == 0) {
@@ -562,12 +564,13 @@ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
is_initial = FALSE;
}
- if (!create_seat_proxy (factory, seat, path))
- continue;
+ proxy = create_seat_proxy (factory, seat, path);
- if (!sd_seat_can_graphical (seat)) {
+ if (!seat_proxy_can_graphical (proxy)) {
g_debug ("GdmLocalDisplayFactory: seat %s not ready for graphical displays", seat);
continue;
+ } else {
+ g_debug ("GdmLocalDisplayFactory: seat %s ready for graphical displays", seat);
}
create_display (factory, seat, session_type, is_initial);
@@ -621,7 +624,7 @@ on_seat_proxy_properties_changed (GDBusProxy *proxy,
}
}
-static gboolean
+static GDBusProxy *
create_seat_proxy (GdmLocalDisplayFactory *self,
const char *seat,
const char *path)
@@ -632,6 +635,13 @@ create_seat_proxy (GdmLocalDisplayFactory *self,
g_debug ("GdmLocalDisplayFactory: creating seat proxy for seat '%s' with path '%s'",
seat, path);
+ proxy = G_DBUS_PROXY (g_hash_table_lookup (self->priv->seat_proxies, seat));
+
+ if (proxy != NULL) {
+ g_debug ("GdmLocalDisplayFactory: we already had one, re-using that");
+ return g_object_ref (g_steal_pointer (&proxy));
+ }
+
proxy = g_dbus_proxy_new_sync (self->priv->connection,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
@@ -644,7 +654,7 @@ create_seat_proxy (GdmLocalDisplayFactory *self,
if (proxy == NULL) {
g_debug ("GdmLocalDisplayFactory: failed to get proxy to seat '%s' from logind: %s",
seat, error->message);
- return FALSE;
+ return NULL;
}
g_hash_table_insert (self->priv->seat_proxies, g_strdup (seat), g_object_ref (proxy));
@@ -655,7 +665,28 @@ create_seat_proxy (GdmLocalDisplayFactory *self,
self,
0);
- return TRUE;
+ return g_steal_pointer (&proxy);
+}
+
+static gboolean
+seat_proxy_can_graphical (GDBusProxy *seat_proxy)
+{
+ g_autoptr (GVariant) can_graphical = NULL;
+
+ if (seat_proxy == NULL) {
+ g_critical ("GdmLocalDisplayFactory: couldn't create seat proxy, can't find out if it can support graphical sessions");
+ return FALSE;
+ }
+
+ can_graphical = g_dbus_proxy_get_cached_property (seat_proxy, "CanGraphical");
+
+ if (can_graphical == NULL) {
+ g_debug ("GdmLocalDisplayFactory: can't read CanGraphical property for '%s'",
+ g_dbus_proxy_get_object_path (seat_proxy));
+ return FALSE;
+ }
+
+ return g_variant_get_boolean (can_graphical);
}
static void
@@ -668,18 +699,20 @@ on_seat_new (GDBusConnection *connection,
gpointer user_data)
{
GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data);
+ g_autoptr (GDBusProxy) proxy = NULL;
const char *seat, *path;
g_variant_get (parameters, "(&s&o)", &seat, &path);
g_debug ("GdmLocalDisplayFactory: new seat '%s' available", seat);
- if (!create_seat_proxy (factory, seat, path))
- return;
+ proxy = create_seat_proxy (factory, seat, path);
- if (!sd_seat_can_graphical (seat)) {
+ if (!seat_proxy_can_graphical (proxy)) {
g_debug ("GdmLocalDisplayFactory: but not yet ready for graphical displays");
return;
+ } else {
+ g_debug ("GdmLocalDisplayFactory: which is ready for graphical displays");
}
create_display (factory, seat, NULL, FALSE);
@@ -780,6 +813,9 @@ on_vt_changed (GIOChannel *source,
g_autofree char *tty_of_active_vt = NULL;
g_autofree char *login_session_id = NULL;
g_autofree char *active_session_id = NULL;
+ gpointer proxy = NULL;
+ g_autoptr (GDBusProxy) seat_proxy = NULL;
+ g_autoptr (GVariant) can_graphical = NULL;
const char *session_type = NULL;
int ret;
@@ -876,7 +912,16 @@ on_vt_changed (GIOChannel *source,
return G_SOURCE_CONTINUE;
}
- if (!sd_seat_can_graphical ("seat0")) {
+ proxy = g_hash_table_lookup (factory->priv->seat_proxies, "seat0");
+
+ if (proxy == NULL) {
+ g_critical ("GdmLocalDisplayFactory: could not find a proxy for 'seat0'");
+ return G_SOURCE_CONTINUE;
+ }
+
+ seat_proxy = G_DBUS_PROXY (proxy);
+
+ if (!seat_proxy_can_graphical (seat_proxy)) {
g_debug ("GdmLocalDisplayFactory: seat0 not yet ready for graphical displays");
return G_SOURCE_CONTINUE;
}