diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2022-05-10 17:04:38 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2022-05-10 17:04:38 +0300 |
commit | 304e9d3f5e1e0922d5abe8e3e3d27e8c68640821 (patch) | |
tree | 6225737937d7425f68893248bea34eeb44e13b8e | |
parent | aa7ebe5d7c054288accdfb751c09929301c0d8a2 (diff) | |
download | gnome-control-center-wip/muktupavels/multi-seat.tar.gz |
power: don't show devices from 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-- | panels/power/cc-power-panel.c | 136 | ||||
-rw-r--r-- | panels/power/meson.build | 3 |
2 files changed, 137 insertions, 2 deletions
diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index 0a988b5d4..6b44c43e9 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -25,6 +25,7 @@ #include <glib/gi18n.h> #include <gnome-settings-daemon/gsd-enums.h> #include <gio/gdesktopappinfo.h> +#include <gudev/gudev.h> #include "shell/cc-object-storage.h" #include "cc-battery-row.h" @@ -77,6 +78,7 @@ struct _CcPowerPanel GPtrArray *devices; gboolean has_batteries; char *chassis_type; + char *logind_seat; GDBusProxy *iio_proxy; guint iio_proxy_watch_id; @@ -145,6 +147,51 @@ get_chassis_type (GCancellable *cancellable) return g_variant_dup_string (inner, NULL); } +static char * +get_logind_seat (GCancellable *cancellable) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GDBusConnection) connection = NULL; + g_autoptr(GVariant) variant = NULL; + g_autoptr(GVariant) inner = NULL; + + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, + cancellable, + &error); + if (connection == NULL) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("system bus not available: %s", error->message); + + return NULL; + } + + 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, + cancellable, + &error); + + if (variant == NULL) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_debug ("Failed to get seat name: %s", error->message); + + return NULL; + } + + g_variant_get (variant, "(v)", &inner); + return g_variant_dup_string (inner, NULL); +} + static void load_custom_css (CcPowerPanel *self, const char *path) @@ -170,10 +217,95 @@ add_battery (CcPowerPanel *panel, UpDevice *device, gboolean primary) gtk_widget_set_visible (GTK_WIDGET (panel->battery_section), TRUE); } +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 (CcPowerPanel *self, UpDevice *device) +{ + gboolean available; + char *native_path; + GUdevClient *client; + GUdevDevice *udev_device; + + available = TRUE; + native_path = NULL; + + if (self->logind_seat == NULL || *self->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, self->logind_seat) != 0) + available = FALSE; + + g_free (seat); + } + + g_object_unref (client); + + return available; +} + static void add_device (CcPowerPanel *self, UpDevice *device) { - CcBatteryRow *row = cc_battery_row_new (device, FALSE); + CcBatteryRow *row; + + if (!is_device_available_to_seat (self, device)) + return; + + row = cc_battery_row_new (device, FALSE); cc_battery_row_set_level_sizegroup (row, self->level_sizegroup); cc_battery_row_set_row_sizegroup (row, self->row_sizegroup); @@ -1416,6 +1548,7 @@ cc_power_panel_dispose (GObject *object) g_signal_handlers_disconnect_by_func (self->power_button_row, power_button_row_changed_cb, self); g_clear_pointer (&self->chassis_type, g_free); + g_clear_pointer (&self->logind_seat, g_free); g_clear_object (&self->gsd_settings); g_clear_object (&self->session_settings); g_clear_object (&self->interface_settings); @@ -1497,6 +1630,7 @@ cc_power_panel_init (CcPowerPanel *self) load_custom_css (self, "/org/gnome/control-center/power/power-profiles.css"); self->chassis_type = get_chassis_type (cc_panel_get_cancellable (CC_PANEL (self))); + self->logind_seat = get_logind_seat (cc_panel_get_cancellable (CC_PANEL (self))); self->up_client = up_client_new (); diff --git a/panels/power/meson.build b/panels/power/meson.build index 1cafe2a1b..7ad25c129 100644 --- a/panels/power/meson.build +++ b/panels/power/meson.build @@ -38,7 +38,8 @@ sources += gnome.compile_resources( deps = common_deps + [ gnome_settings_dep, - upower_glib_dep + upower_glib_dep, + gudev_dep, ] panels_libs += static_library( |