diff --git a/po/POTFILES b/po/POTFILES index eb1a914..24cf219 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -5,7 +5,6 @@ src/DBus/LockInterface.vala src/DBus/SeatInterface.vala src/DBus/SensorProxy.vala src/DBus/SessionInterface.vala -src/DBus/SystemInterface.vala src/DBus/UserInterface.vala src/Services/UserManager.vala src/Widgets/AvatarButton.vala diff --git a/src/DBus/Login1Manager.vala b/src/DBus/Login1Manager.vala new file mode 100644 index 0000000..9667a00 --- /dev/null +++ b/src/DBus/Login1Manager.vala @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024-2026 elementary, Inc. (https://elementary.io) + */ + +public class QuickSettings.Login1Manager : Object { + public struct UserInfo { + uint32 uid; + string user_name; + ObjectPath? user_object; + } + + [DBus (name = "org.freedesktop.login1.Manager")] + public interface Login1ManagerInterface : Object { + public abstract void suspend (bool interactive) throws GLib.Error; + public abstract void reboot (bool interactive) throws GLib.Error; + public abstract void power_off (bool interactive) throws GLib.Error; + public abstract void reboot_with_flags (uint64 flags) throws GLib.Error; + public abstract void power_off_with_flags (uint64 flags) throws GLib.Error; + + public abstract UserInfo[] list_users () throws GLib.Error; + public abstract string can_suspend () throws GLib.Error; + } + + public Login1ManagerInterface proxy { get; private set; } + + private static GLib.Once instance; + public static unowned Login1Manager get_default () { + return instance.once (() => new Login1Manager ()); + } + + private Login1Manager () {} + + construct { + try { + proxy = Bus.get_proxy_sync ( + SYSTEM, + "org.freedesktop.login1", + "/org/freedesktop/login1" + ); + } catch (Error e) { + critical (e.message); + } + } +} diff --git a/src/DBus/SystemInterface.vala b/src/DBus/SystemInterface.vala deleted file mode 100644 index 6a61c08..0000000 --- a/src/DBus/SystemInterface.vala +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) - */ - -struct UserInfo { - uint32 uid; - string user_name; - ObjectPath? user_object; -} - -[DBus (name = "org.freedesktop.login1.Manager")] -interface QuickSettings.SystemInterface : Object { - public abstract void suspend (bool interactive) throws GLib.Error; - public abstract void reboot (bool interactive) throws GLib.Error; - public abstract void power_off (bool interactive) throws GLib.Error; - public abstract void reboot_with_flags (uint64 flags) throws GLib.Error; - public abstract void power_off_with_flags (uint64 flags) throws GLib.Error; - - public abstract UserInfo[] list_users () throws GLib.Error; - public abstract string can_suspend () throws GLib.Error; -} diff --git a/src/Services/UserManager.vala b/src/Services/UserManager.vala index fba800c..725c37a 100644 --- a/src/Services/UserManager.vala +++ b/src/Services/UserManager.vala @@ -21,44 +21,35 @@ public enum UserState { } public class QuickSettings.UserManager : Object { - private const string LOGIN_IFACE = "org.freedesktop.login1"; - private const string LOGIN_PATH = "/org/freedesktop/login1"; - - private static string active_user_real_name; - private static SystemInterface? login_proxy; - - private static async void init_login_proxy () { - try { - login_proxy = yield Bus.get_proxy (BusType.SYSTEM, LOGIN_IFACE, LOGIN_PATH, DBusProxyFlags.NONE); - } catch (IOError e) { - critical ("Failed to create login1 dbus proxy: %s", e.message); - } - } + private static string? active_user_real_name; public static async UserState get_user_state (uid_t uuid) { - if (login_proxy == null) { - yield init_login_proxy (); - } - try { - UserInfo[] users = login_proxy.list_users (); + var users = Login1Manager.get_default ().proxy.list_users (); if (users == null) { return UserState.OFFLINE; } - foreach (UserInfo user in users) { - if (((uid_t) user.uid) == uuid) { - if (user.user_object == null) { - return UserState.OFFLINE; - } - UserInterface? user_interface = yield Bus.get_proxy (BusType.SYSTEM, LOGIN_IFACE, user.user_object, DBusProxyFlags.NONE); - if (user_interface == null) { - return UserState.OFFLINE; - } - return UserState.to_enum (user_interface.state); + foreach (var user in users) { + if (((uid_t) user.uid) != uuid) { + continue; + } + + if (user.user_object == null) { + return UserState.OFFLINE; + } + + var user_interface = yield Bus.get_proxy ( + SYSTEM, + "org.freedesktop.login1", + user.user_object + ); + if (user_interface == null) { + return UserState.OFFLINE; } - } + return UserState.to_enum (user_interface.state); + } } catch (GLib.Error e) { critical ("Failed to get user state: %s", e.message); } @@ -67,13 +58,9 @@ public class QuickSettings.UserManager : Object { } public static async UserState get_guest_state () { - if (login_proxy == null) { - return UserState.OFFLINE; - } - try { - UserInfo[] users = login_proxy.list_users (); - foreach (UserInfo user in users) { + var users = Login1Manager.get_default ().proxy.list_users (); + foreach (var user in users) { var state = yield get_user_state (user.uid); if (user.user_name.has_prefix ("guest-") && state == UserState.ACTIVE) { diff --git a/src/Widgets/SessionBox.vala b/src/Widgets/SessionBox.vala index adba17a..a510547 100644 --- a/src/Widgets/SessionBox.vala +++ b/src/Widgets/SessionBox.vala @@ -8,7 +8,6 @@ public class QuickSettings.SessionBox : Gtk.Box { private EndSessionDialog? current_dialog = null; private Gtk.Popover? popover; - private SystemInterface system_interface; public SessionBox (Wingpanel.IndicatorManager.ServerType server_type) { Object (server_type: server_type); @@ -69,18 +68,14 @@ public class QuickSettings.SessionBox : Gtk.Box { show_dialog (EndSessionDialogType.RESTART); }); - setup_system_interface.begin ((obj, res) => { - system_interface = setup_system_interface.end (res); - - suspend_button.clicked.connect (() => { - popover.popdown (); + suspend_button.clicked.connect (() => { + popover.popdown (); - try { - system_interface.suspend (true); - } catch (GLib.Error e) { - critical ("Unable to suspend: %s", e.message); - } - }); + try { + Login1Manager.get_default ().proxy.suspend (true); + } catch (GLib.Error e) { + critical ("Unable to suspend: %s", e.message); + } }); var keybinding_settings = new Settings ("org.gnome.settings-daemon.plugins.media-keys"); @@ -111,15 +106,6 @@ public class QuickSettings.SessionBox : Gtk.Box { }); } - private async SystemInterface? setup_system_interface () { - try { - return yield Bus.get_proxy (BusType.SYSTEM, "org.freedesktop.login1", "/org/freedesktop/login1"); - } catch (IOError e) { - critical ("Unable to connect to the login interface: %s", e.message); - return null; - } - } - private async LockInterface? setup_lock_interface () { try { return yield Bus.get_proxy (BusType.SESSION, "org.gnome.ScreenSaver", "/org/gnome/ScreenSaver"); @@ -162,7 +148,7 @@ public class QuickSettings.SessionBox : Gtk.Box { try { // See https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html for flags values // #define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0) == 1 - system_interface.power_off_with_flags (1); + Login1Manager.get_default ().proxy.power_off_with_flags (1); } catch (Error e) { warning ("Unable to shutdown: %s", e.message); } @@ -172,7 +158,7 @@ public class QuickSettings.SessionBox : Gtk.Box { try { // See https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html for flags values // #define SD_LOGIND_KEXEC_REBOOT (UINT64_C(1) << 1) == 2 - system_interface.reboot_with_flags (2); + Login1Manager.get_default ().proxy.reboot_with_flags (2); } catch (Error e) { warning ("Unable to reboot: %s", e.message); } diff --git a/src/meson.build b/src/meson.build index 7a0cd82..c32beb5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,10 +12,10 @@ sources = [ 'PopoverWidget.vala', 'DBus' / 'EndSessionDialogServer.vala', 'DBus' / 'LockInterface.vala', + 'DBus' / 'Login1Manager.vala', 'DBus' / 'SeatInterface.vala', 'DBus' / 'SensorProxy.vala', 'DBus' / 'SessionInterface.vala', - 'DBus' / 'SystemInterface.vala', 'DBus' / 'UserInterface.vala', 'Services' / 'UserManager.vala', 'Widgets' / 'AvatarButton.vala',