Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync wallpaper to greeter #72

Merged
merged 23 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions data/io.elementary.SettingsDaemon.AccountsService.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@
<annotation name="org.freedesktop.Accounts.DefaultValue" value="1.0"/>
</property>

<property name="PictureOptions" type="i" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="5"/>
</property>

<property name="PrimaryColor" type="s" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="#000000"/>
</property>

<property name="DocumentFontName" type="s" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="Open Sans 10"/>
</property>
Expand Down
7 changes: 7 additions & 0 deletions src/AccountsService.vala
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -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;
Expand Down
21 changes: 20 additions & 1 deletion src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<FDO.Accounts> (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<FDO.Accounts> (GLib.BusType.SYSTEM,
"org.freedesktop.Accounts",
Expand Down
90 changes: 88 additions & 2 deletions src/Backends/InterfaceSettings.vala
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();

Expand All @@ -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 () {
Expand All @@ -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);
}
}
}