diff --git a/data/io.elementary.SettingsDaemon.AccountsService.xml b/data/io.elementary.SettingsDaemon.AccountsService.xml index 96e41267..efe8372f 100644 --- a/data/io.elementary.SettingsDaemon.AccountsService.xml +++ b/data/io.elementary.SettingsDaemon.AccountsService.xml @@ -108,6 +108,14 @@ + + + + + + + + diff --git a/src/AccountsService.vala b/src/AccountsService.vala index 856f288b..d75392b4 100644 --- a/src/AccountsService.vala +++ b/src/AccountsService.vala @@ -57,6 +57,8 @@ public interface SettingsDaemon.AccountsService : Object { public abstract int cursor_size { get; set; } public abstract bool locate_pointer { get; set; } public abstract double text_scaling_factor { get; set; } + public abstract int picture_options { get; set; } + public abstract string primary_color { owned get; set; } public abstract string document_font_name { owned get; set; } public abstract string font_name { owned get; set; } public abstract string monospace_font_name { owned get; set; } @@ -80,6 +82,11 @@ public interface PantheonShell.Pantheon.AccountsService : Object { public abstract int prefers_color_scheme { get; set; } } +[DBus (name = "org.freedesktop.DisplayManager.AccountsService")] +public interface DisplayManager.AccountsService : Object { + public abstract string background_file { owned get; set; } +} + [DBus (name = "org.freedesktop.Accounts")] public interface SettingsDaemon.FDO.Accounts : Object { public abstract string find_user_by_name (string username) throws GLib.Error; diff --git a/src/Application.vala b/src/Application.vala index 130df744..b7336241 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -34,6 +34,8 @@ public class SettingsDaemon.Application : GLib.Application { private PantheonShell.Pantheon.AccountsService pantheon_accounts_service; + private DisplayManager.AccountsService display_manager_accounts_service; + private Backends.KeyboardSettings keyboard_settings; private Backends.MouseSettings mouse_settings; @@ -154,10 +156,27 @@ public class SettingsDaemon.Application : GLib.Application { if (accounts_service != null) { keyboard_settings = new Backends.KeyboardSettings (accounts_service); mouse_settings = new Backends.MouseSettings (accounts_service); - interface_settings = new Backends.InterfaceSettings (accounts_service); night_light_settings = new Backends.NightLightSettings (accounts_service); } + try { + var act_service = yield GLib.Bus.get_proxy (GLib.BusType.SYSTEM, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts"); + var user_path = act_service.find_user_by_name (GLib.Environment.get_user_name ()); + + display_manager_accounts_service = yield GLib.Bus.get_proxy (GLib.BusType.SYSTEM, + "org.freedesktop.Accounts", + user_path, + GLib.DBusProxyFlags.GET_INVALIDATED_PROPERTIES); + } catch (Error e) { + warning ("Unable to get AccountsService proxy, background file might be incorrect"); + } + + if (accounts_service != null && display_manager_accounts_service != null) { + interface_settings = new Backends.InterfaceSettings (accounts_service, display_manager_accounts_service); + } + try { var act_service = yield GLib.Bus.get_proxy (GLib.BusType.SYSTEM, "org.freedesktop.Accounts", diff --git a/src/Backends/InterfaceSettings.vala b/src/Backends/InterfaceSettings.vala index 1a368b18..6053d5e2 100644 --- a/src/Backends/InterfaceSettings.vala +++ b/src/Backends/InterfaceSettings.vala @@ -24,20 +24,31 @@ public class SettingsDaemon.Backends.InterfaceSettings : GLib.Object { private const string CURSOR_SIZE = "cursor-size"; private const string LOCATE_POINTER = "locate-pointer"; private const string TEXT_SCALING_FACTOR = "text-scaling-factor"; + + private const string PICTURE_OPTIONS = "picture-options"; + private const string PRIMARY_COLOR = "primary-color"; + private const string PICTURE_URI = "picture-uri"; + private const string DOCUMENT_FONT_NAME = "document-font-name"; private const string FONT_NAME = "font-name"; private const string MONOSPACE_FONT_NAME = "monospace-font-name"; public unowned AccountsService accounts_service { get; construct; } + public unowned DisplayManager.AccountsService display_manager_accounts_service { get; construct; } private GLib.Settings interface_settings; + private GLib.Settings background_settings; - public InterfaceSettings (AccountsService accounts_service) { - Object (accounts_service: accounts_service); + public InterfaceSettings (AccountsService accounts_service, DisplayManager.AccountsService display_manager_accounts_service) { + Object ( + accounts_service: accounts_service, + display_manager_accounts_service: display_manager_accounts_service + ); } construct { interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); + background_settings = new GLib.Settings ("org.gnome.desktop.background"); sync_gsettings_to_accountsservice (); @@ -54,6 +65,18 @@ public class SettingsDaemon.Backends.InterfaceSettings : GLib.Object { sync_gsettings_to_accountsservice (); } }); + + background_settings.changed.connect ((key) => { + if (key == PICTURE_OPTIONS || + key == PRIMARY_COLOR) { + sync_gsettings_to_accountsservice (); + return; + } + + if (key == PICTURE_URI) { + sync_background_to_greeter (); + } + }); } private void sync_gsettings_to_accountsservice () { @@ -63,8 +86,71 @@ public class SettingsDaemon.Backends.InterfaceSettings : GLib.Object { accounts_service.cursor_size = interface_settings.get_int (CURSOR_SIZE); accounts_service.locate_pointer = interface_settings.get_boolean (LOCATE_POINTER); accounts_service.text_scaling_factor = interface_settings.get_double (TEXT_SCALING_FACTOR); + + accounts_service.picture_options = background_settings.get_enum (PICTURE_OPTIONS); + accounts_service.primary_color = background_settings.get_string (PRIMARY_COLOR); + accounts_service.document_font_name = interface_settings.get_string (DOCUMENT_FONT_NAME); accounts_service.font_name = interface_settings.get_string (FONT_NAME); accounts_service.monospace_font_name = interface_settings.get_string (MONOSPACE_FONT_NAME); } + + private void sync_background_to_greeter () { + var source = File.new_for_uri (background_settings.get_string (PICTURE_URI)); + + if (!source.query_exists ()) { + debug ("Wallpaper path is invalid"); + display_manager_accounts_service.background_file = ""; + return; + } + + var wallpaper_name = "wallpaper"; + + var greeter_data_dir = Environment.get_variable ("XDG_GREETER_DATA_DIR") ?? Path.build_filename ("/var/lib/lightdm-data", Environment.get_user_name ()); + var folder = File.new_for_path (greeter_data_dir); + var dest = folder.get_child (wallpaper_name); + + try { + if (!folder.query_exists ()) { + folder.make_directory_with_parents (); + } + + if (FileUtils.test (dest.get_path (), IS_DIR)) { + debug ("Migrating to new wallpaper directory"); + remove_directory (dest); + } + + source.copy (dest, OVERWRITE | ALL_METADATA); + // Ensure wallpaper is readable by greeter user (owner rw, others r) + FileUtils.chmod (dest.get_path (), 0604); + + display_manager_accounts_service.background_file = dest.get_path (); + } catch (IOError.IS_DIRECTORY e) { + critical ("Migration failed %s", e.message); + display_manager_accounts_service.background_file = ""; + } catch (Error e) { + warning (e.message); + display_manager_accounts_service.background_file = ""; + } + } + + private void remove_directory (File directory) { + try { + var enumerator = directory.enumerate_children ( + FileAttribute.STANDARD_NAME, NOFOLLOW_SYMLINKS + ); + + FileInfo file_info; + while ((file_info = enumerator.next_file ()) != null) { + var file = directory.get_child (file_info.get_name ()); + if (file_info.get_file_type () == DIRECTORY) { + remove_directory (file); + } + file.delete (); + } + directory.delete (); + } catch (Error e) { + critical ("Couldn't remove directory %s: %s", directory.get_path (), e.message); + } + } }