summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2022-05-10 12:57:03 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2022-05-10 12:57:03 +0300
commit17f0b6e7466fae79ac9d3edaa9995cf50c85887b (patch)
tree4d74b7598a48e84df4f7b0bda1199af589be0fda
parent64ac7fc58f87971f12d2957433788567448a61cc (diff)
downloadgnome-settings-daemon-wip/muktupavels/multi-seat.tar.gz
power: don't show notifications for devices assigned to other seatswip/muktupavels/multi-seat
Devices that can be assigned to a seat has tag - seat and such devices are always assigned to one seat. If device is not assigned to other seat it is implicitly assigned to seat0. https://www.freedesktop.org/software/systemd/man/sd-login.html https://www.freedesktop.org/wiki/Software/systemd/multiseat/
-rw-r--r--plugins/power/gsd-power-manager.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/plugins/power/gsd-power-manager.c b/plugins/power/gsd-power-manager.c
index 757986e3..9c084a4e 100644
--- a/plugins/power/gsd-power-manager.c
+++ b/plugins/power/gsd-power-manager.c
@@ -32,6 +32,10 @@
#include <glib-unix.h>
#include <gio/gunixfdlist.h>
+#if HAVE_GUDEV
+#include <gudev/gudev.h>
+#endif
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-rr.h>
#include <libgnome-desktop/gnome-idle-monitor.h>
@@ -199,6 +203,7 @@ struct _GsdPowerManager
/* systemd stuff */
GDBusProxy *logind_proxy;
+ char *logind_seat;
gint inhibit_lid_switch_fd;
gboolean inhibit_lid_switch_taken;
gint inhibit_suspend_fd;
@@ -262,6 +267,84 @@ notify_close_if_showing (NotifyNotification **notification)
g_clear_object (notification);
}
+#if HAVE_GUDEV
+static char *
+get_seat_from_device (GUdevDevice *device)
+{
+ const char *const *tags;
+ GUdevDevice *parent;
+
+ tags = g_udev_device_get_tags (device);
+
+ if (g_strv_contains (tags, "seat")) {
+ int i;
+
+ for (i = 0; tags[i] != NULL; i++) {
+ if (g_str_has_prefix (tags[i], "seat") && strlen (tags[i]) > 4)
+ return g_strdup (tags[i]);
+ }
+
+ return g_strdup ("seat0");
+ }
+
+ parent = g_udev_device_get_parent (device);
+
+ if (parent != NULL) {
+ char *seat;
+
+ seat = get_seat_from_device (parent);
+ g_object_unref (parent);
+
+ return seat;
+ }
+
+ return NULL;
+}
+
+static gboolean
+is_device_available_to_seat (GsdPowerManager *manager, UpDevice *device)
+{
+ gboolean available;
+ char *native_path;
+ GUdevClient *client;
+ GUdevDevice *udev_device;
+
+ available = TRUE;
+ native_path = NULL;
+
+ if (manager->logind_seat == NULL || *manager->logind_seat == '\0')
+ return TRUE;
+
+ g_object_get (device, "native-path", &native_path, NULL);
+
+ client = g_udev_client_new (NULL);
+ udev_device = g_udev_client_query_by_sysfs_path (client, native_path);
+
+ /* Native path for power_supply devices is name not sysfs path. */
+ if (udev_device == NULL)
+ udev_device = g_udev_client_query_by_subsystem_and_name (client, "power_supply", native_path);
+
+ g_free (native_path);
+
+ if (udev_device != NULL) {
+ char *seat;
+
+ seat = get_seat_from_device (udev_device);
+ g_object_unref (udev_device);
+
+ /* NULL/empty seat means that device is available to all seats */
+ if (seat != NULL && *seat != '\0' && g_strcmp0 (seat, manager->logind_seat) != 0)
+ available = FALSE;
+
+ g_free (seat);
+ }
+
+ g_object_unref (client);
+
+ return available;
+}
+#endif
+
static void
engine_device_add (GsdPowerManager *manager, UpDevice *device)
{
@@ -274,6 +357,12 @@ engine_device_add (GsdPowerManager *manager, UpDevice *device)
kind == UP_DEVICE_KIND_UPS ||
kind == UP_DEVICE_KIND_LINE_POWER)
return;
+
+#if HAVE_GUDEV
+ if (!is_device_available_to_seat (manager, device))
+ return;
+#endif
+
g_ptr_array_add (manager->devices_array, g_object_ref (device));
g_signal_connect (device, "notify::warning-level",
@@ -3044,6 +3133,41 @@ iio_proxy_vanished_cb (GDBusConnection *connection,
g_clear_object (&manager->iio_proxy);
}
+static char *
+get_logind_seat (GsdPowerManager *manager)
+{
+ GDBusConnection *connection;
+ GVariant *variant;
+ GVariant *inner;
+ char *seat;
+
+ connection = g_dbus_proxy_get_connection (manager->logind_proxy);
+ variant = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/seat/auto",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)",
+ "org.freedesktop.login1.Seat",
+ "Id"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+
+ if (variant == NULL)
+ return NULL;
+
+ g_variant_get (variant, "(v)", &inner);
+ g_variant_unref (variant);
+
+ seat = g_variant_dup_string (inner, NULL);
+ g_variant_unref (inner);
+
+ return seat;
+}
+
gboolean
gsd_power_manager_start (GsdPowerManager *manager,
GError **error)
@@ -3072,6 +3196,8 @@ gsd_power_manager_start (GsdPowerManager *manager,
return FALSE;
}
+ manager->logind_seat = get_logind_seat (manager);
+
/* coldplug the list of screens */
gnome_rr_screen_new_async (gdk_screen_get_default (),
on_rr_screen_acquired, manager);
@@ -3140,6 +3266,7 @@ gsd_power_manager_stop (GsdPowerManager *manager)
}
g_clear_object (&manager->logind_proxy);
+ g_clear_pointer (&manager->logind_seat, g_free);
g_clear_object (&manager->rr_screen);
g_clear_pointer (&manager->devices_array, g_ptr_array_unref);