From d1596b2582c7dbf4535d7b57faf6f7a1e3c84129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Fri, 14 Jun 2024 10:13:26 -0700 Subject: [PATCH 1/8] LocaleManager: set system locale and keyboard via dbus --- src/LocaleManager.vala | 111 +++++++++-------------------------------- 1 file changed, 23 insertions(+), 88 deletions(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index 8bb547d3..00edef01 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -26,14 +26,14 @@ public interface AccountProxy : GLib.Object { public interface Locale1Proxy : GLib.Object { public abstract string[] locale { owned get; } - public abstract void set_locale (string[] arg_0, bool arg_1) throws GLib.Error; + public abstract void set_locale (string[] locale, bool interactive) throws GLib.Error; public abstract void set_x11_keyboard ( - string arg_0, - string arg_1, - string arg_2, - string arg_3, - bool arg_4, - bool arg_5 + string layout, + string model, + string variant, + string options, + bool convert, + bool interactive ) throws GLib.Error; } @@ -167,70 +167,6 @@ namespace SwitchboardPlugLocale { return get_system_locale () ?? "en_US.UTF-8"; } - private void localectl_set_locale (string locale, string? format = null) throws GLib.Error { - debug ("setting system-wide locale via localectl"); - if (Utils.get_permission ().allowed) { - string output; - int status; - string cli = "/usr/bin/localectl"; - string command = "set-locale"; - - try { - if (format == null) { - Process.spawn_sync (null, - {"pkexec", cli, command, locale}, - Environ.get (), - SpawnFlags.SEARCH_PATH, - null, out output, - null, out status); - if (output != "") { - critical ("localectl failed to set locale"); - } - } else { - Process.spawn_sync (null, - {"pkexec", cli, command, locale, "LC_TIME=%s".printf (format), - "LC_NUMERIC=%s".printf (format), "LC_MONETARY=%s".printf (format), - "LC_MEASUREMENT=%s".printf (format)}, - Environ.get (), - SpawnFlags.SEARCH_PATH, - null, out output, - null, out status); - if (output != "") { - critical ("localectl failed to set locale"); - } - } - } catch (Error e) { - critical ("localectl failed to set locale"); - throw e; - } - } - } - - private void localectl_set_x11_keymap (string layouts, string variants) throws GLib.Error { - if (Utils.get_permission ().allowed) { - string output; - int status; - string cli = "/usr/bin/localectl"; - string command = "set-x11-keymap"; - - try { - Process.spawn_sync (null, - {"pkexec", cli, command, layouts, "", variants}, - Environ.get (), - SpawnFlags.SEARCH_PATH, - null, out output, - null, out status); - - if (output != "") { - critical ("localectl failed to set x11 keymap"); - } - } catch (Error e) { - critical ("localectl failed to set x11 keymap"); - throw e; - } - } - } - public string? get_system_locale () { foreach (unowned var locale in locale1_proxy.locale) { if (locale.has_prefix ("LANG=")) { @@ -242,20 +178,17 @@ namespace SwitchboardPlugLocale { } public void apply_to_system (string language, string? format) { - /* - * This is a temporary solution for setting the system-wide locale. - * I am assuming systemd in version 204 (which we currently ship from Ubuntu repositories) - * is broken as SetLocale does not recognize the aquired polkit permission. Maybe that is - * intended, but I do not believe this. May be fixed in a later version of systemd and should - * be reversed (TODO) when introducing a newer version of systemd to elementary OS. - */ + string[] locale = {"LANG=%s".printf (language)}; - try { - localectl_set_locale ("LANG=%s".printf (language), format); - } catch (Error e) { - warning (e.message); + if (format != null) { + locale += "LC_TIME=%s".printf (format); + locale += "LC_NUMERIC=%s".printf (format); + locale += "LC_MONETARY=%s".printf (format); + locale += "LC_MEASUREMENT=%s".printf (format); } + locale1_proxy.set_locale (locale, true); + string layouts = ""; string variants = ""; @@ -281,12 +214,14 @@ namespace SwitchboardPlugLocale { } } - try { - /* TODO: temporary solution for systemd-localed polkit problem */ - localectl_set_x11_keymap (layouts, variants); - } catch (Error e) { - warning (e.message); - } + locale1_proxy.set_x11_keyboard ( + layouts, + "", + variants, + "", + true, + true + ); } private static LocaleManager? instance = null; From 5c2733e05d7cda4acfd7f789e604994ebd83f182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Fri, 14 Jun 2024 10:22:20 -0700 Subject: [PATCH 2/8] async --- src/LocaleManager.vala | 8 ++++---- src/Widgets/LocaleSetting.vala | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index 00edef01..53ff88a6 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -26,8 +26,8 @@ public interface AccountProxy : GLib.Object { public interface Locale1Proxy : GLib.Object { public abstract string[] locale { owned get; } - public abstract void set_locale (string[] locale, bool interactive) throws GLib.Error; - public abstract void set_x11_keyboard ( + public abstract async void set_locale (string[] locale, bool interactive) throws GLib.Error; + public abstract async void set_x11_keyboard ( string layout, string model, string variant, @@ -177,7 +177,7 @@ namespace SwitchboardPlugLocale { return null; } - public void apply_to_system (string language, string? format) { + public async void apply_to_system (string language, string? format) { string[] locale = {"LANG=%s".printf (language)}; if (format != null) { @@ -187,7 +187,7 @@ namespace SwitchboardPlugLocale { locale += "LC_MEASUREMENT=%s".printf (format); } - locale1_proxy.set_locale (locale, true); + yield locale1_proxy.set_locale (locale, true); string layouts = ""; string variants = ""; diff --git a/src/Widgets/LocaleSetting.vala b/src/Widgets/LocaleSetting.vala index b2dae6c2..164fca72 100644 --- a/src/Widgets/LocaleSetting.vala +++ b/src/Widgets/LocaleSetting.vala @@ -333,7 +333,7 @@ namespace SwitchboardPlugLocale.Widgets { var selected_locale = get_selected_locale (); var selected_format = get_format (); debug ("Setting system language to '%s' and format to '%s'", selected_locale, selected_format); - lm.apply_to_system (selected_locale, selected_format); + lm.apply_to_system.begin (selected_locale, selected_format); restart_infobar.revealed = true; } From 2bc81d0fbd4874f1315443bc50acb3666a60eda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Fri, 14 Jun 2024 10:31:08 -0700 Subject: [PATCH 3/8] Handle errors --- src/LocaleManager.vala | 46 +++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index 53ff88a6..a69ea4ab 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -187,7 +187,21 @@ namespace SwitchboardPlugLocale { locale += "LC_MEASUREMENT=%s".printf (format); } - yield locale1_proxy.set_locale (locale, true); + try { + yield locale1_proxy.set_locale (locale, true); + } catch (Error e) { + var dialog = new Granite.MessageDialog ( + _("Can't set system locale"), + e.message, + new ThemedIcon ("preferences-desktop-locale") + ) { + badge_icon = new ThemedIcon ("dialog-error"), + modal = true, + transient_for = ((Gtk.Application) Application.get_default ()).active_window + }; + dialog.present (); + dialog.response.connect (dialog.destroy); + } string layouts = ""; string variants = ""; @@ -214,14 +228,28 @@ namespace SwitchboardPlugLocale { } } - locale1_proxy.set_x11_keyboard ( - layouts, - "", - variants, - "", - true, - true - ); + try { + yield locale1_proxy.set_x11_keyboard ( + layouts, + "", + variants, + "", + true, + true + ); + } catch (Error e) { + var dialog = new Granite.MessageDialog ( + _("Can't set system keyboard"), + e.message, + new ThemedIcon ("preferences-desktop-locale") + ) { + badge_icon = new ThemedIcon ("dialog-error"), + modal = true, + transient_for = ((Gtk.Application) Application.get_default ()).active_window + }; + dialog.present (); + dialog.response.connect (dialog.destroy); + } } private static LocaleManager? instance = null; From 95f66a76fcce6e72ac7c6c10c233d14370d358c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Fri, 14 Jun 2024 10:39:23 -0700 Subject: [PATCH 4/8] Don't pre-emp dbus asking for permission --- src/Widgets/LocaleSetting.vala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Widgets/LocaleSetting.vala b/src/Widgets/LocaleSetting.vala index 164fca72..ab843ae5 100644 --- a/src/Widgets/LocaleSetting.vala +++ b/src/Widgets/LocaleSetting.vala @@ -201,13 +201,7 @@ namespace SwitchboardPlugLocale.Widgets { restart_infobar.revealed = true; }); - set_system_button.clicked.connect (() => { - if (!Utils.allowed_permission ()) { - return; - } - - on_applied_to_system (); - }); + set_system_button.clicked.connect (on_applied_to_system); installer.check_missing_finished.connect (on_check_missing_finished); } From dbd4dfb09193db99095493e20711dbbb4ae8df81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sat, 15 Jun 2024 17:00:45 -0700 Subject: [PATCH 5/8] Remove extra policy settings --- data/locale.policy.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/locale.policy.in b/data/locale.policy.in index 4f405201..6dc08693 100644 --- a/data/locale.policy.in +++ b/data/locale.policy.in @@ -15,8 +15,7 @@ no auth_admin_keep - /usr/bin/localectl - org.freedesktop.locale1.set-locale org.debian.apt.install-or-remove-packages + org.debian.apt.install-or-remove-packages From d298e6926968d09689e4577bc58a452623ed8ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sat, 15 Jun 2024 17:19:00 -0700 Subject: [PATCH 6/8] Don't throw error if permission denied --- src/LocaleManager.vala | 14 +++++++++++++- src/Widgets/LocaleSetting.vala | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index a69ea4ab..a4eef1b5 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -177,7 +177,7 @@ namespace SwitchboardPlugLocale { return null; } - public async void apply_to_system (string language, string? format) { + public async bool apply_to_system (string language, string? format) { string[] locale = {"LANG=%s".printf (language)}; if (format != null) { @@ -190,6 +190,10 @@ namespace SwitchboardPlugLocale { try { yield locale1_proxy.set_locale (locale, true); } catch (Error e) { + if (e.matches (GLib.DBusError.quark (), GLib.DBusError.ACCESS_DENIED)) { + return false; + } + var dialog = new Granite.MessageDialog ( _("Can't set system locale"), e.message, @@ -238,6 +242,10 @@ namespace SwitchboardPlugLocale { true ); } catch (Error e) { + if (e.matches (GLib.DBusError.quark (), GLib.DBusError.ACCESS_DENIED)) { + return false; + } + var dialog = new Granite.MessageDialog ( _("Can't set system keyboard"), e.message, @@ -249,7 +257,11 @@ namespace SwitchboardPlugLocale { }; dialog.present (); dialog.response.connect (dialog.destroy); + + return false; } + + return true; } private static LocaleManager? instance = null; diff --git a/src/Widgets/LocaleSetting.vala b/src/Widgets/LocaleSetting.vala index ab843ae5..9f223a86 100644 --- a/src/Widgets/LocaleSetting.vala +++ b/src/Widgets/LocaleSetting.vala @@ -327,9 +327,9 @@ namespace SwitchboardPlugLocale.Widgets { var selected_locale = get_selected_locale (); var selected_format = get_format (); debug ("Setting system language to '%s' and format to '%s'", selected_locale, selected_format); - lm.apply_to_system.begin (selected_locale, selected_format); - - restart_infobar.revealed = true; + lm.apply_to_system.begin (selected_locale, selected_format, (obj, res) => { + restart_infobar.revealed = lm.apply_to_system.end (res); + }); } private class Locale : Object { From 5d92fa810e4d61fad3c16a3ada8c85c7fc8402cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 17 Jun 2024 09:57:25 -0700 Subject: [PATCH 7/8] Throw error and handle in locale setting --- src/LocaleManager.vala | 38 +++------------------------------- src/Widgets/LocaleSetting.vala | 21 ++++++++++++++++++- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index a4eef1b5..cfc3eb21 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -177,7 +177,7 @@ namespace SwitchboardPlugLocale { return null; } - public async bool apply_to_system (string language, string? format) { + public async void apply_to_system (string language, string? format) throws GLib.DBusError { string[] locale = {"LANG=%s".printf (language)}; if (format != null) { @@ -190,21 +190,7 @@ namespace SwitchboardPlugLocale { try { yield locale1_proxy.set_locale (locale, true); } catch (Error e) { - if (e.matches (GLib.DBusError.quark (), GLib.DBusError.ACCESS_DENIED)) { - return false; - } - - var dialog = new Granite.MessageDialog ( - _("Can't set system locale"), - e.message, - new ThemedIcon ("preferences-desktop-locale") - ) { - badge_icon = new ThemedIcon ("dialog-error"), - modal = true, - transient_for = ((Gtk.Application) Application.get_default ()).active_window - }; - dialog.present (); - dialog.response.connect (dialog.destroy); + throw (e); } string layouts = ""; @@ -242,26 +228,8 @@ namespace SwitchboardPlugLocale { true ); } catch (Error e) { - if (e.matches (GLib.DBusError.quark (), GLib.DBusError.ACCESS_DENIED)) { - return false; - } - - var dialog = new Granite.MessageDialog ( - _("Can't set system keyboard"), - e.message, - new ThemedIcon ("preferences-desktop-locale") - ) { - badge_icon = new ThemedIcon ("dialog-error"), - modal = true, - transient_for = ((Gtk.Application) Application.get_default ()).active_window - }; - dialog.present (); - dialog.response.connect (dialog.destroy); - - return false; + throw (e); } - - return true; } private static LocaleManager? instance = null; diff --git a/src/Widgets/LocaleSetting.vala b/src/Widgets/LocaleSetting.vala index 9f223a86..fb6c05db 100644 --- a/src/Widgets/LocaleSetting.vala +++ b/src/Widgets/LocaleSetting.vala @@ -328,7 +328,26 @@ namespace SwitchboardPlugLocale.Widgets { var selected_format = get_format (); debug ("Setting system language to '%s' and format to '%s'", selected_locale, selected_format); lm.apply_to_system.begin (selected_locale, selected_format, (obj, res) => { - restart_infobar.revealed = lm.apply_to_system.end (res); + try { + lm.apply_to_system.end (res); + restart_infobar.revealed = true; + } catch (Error e) { + if (e.matches (GLib.DBusError.quark (), GLib.DBusError.ACCESS_DENIED)) { + return; + } + + var dialog = new Granite.MessageDialog ( + _("Can't set system locale"), + e.message, + new ThemedIcon ("preferences-desktop-locale") + ) { + badge_icon = new ThemedIcon ("dialog-error"), + modal = true, + transient_for = ((Gtk.Application) Application.get_default ()).active_window + }; + dialog.present (); + dialog.response.connect (dialog.destroy); + } }); } From f64da9faba668ff3970b97937d8a3129dc0c57d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Tue, 18 Jun 2024 09:58:00 -0700 Subject: [PATCH 8/8] Update src/LocaleManager.vala Co-authored-by: Ryo Nakano --- src/LocaleManager.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LocaleManager.vala b/src/LocaleManager.vala index cfc3eb21..a6390ed6 100644 --- a/src/LocaleManager.vala +++ b/src/LocaleManager.vala @@ -177,7 +177,7 @@ namespace SwitchboardPlugLocale { return null; } - public async void apply_to_system (string language, string? format) throws GLib.DBusError { + public async void apply_to_system (string language, string? format) throws GLib.Error { string[] locale = {"LANG=%s".printf (language)}; if (format != null) {