From 07c24430e7b9a5b60f40df43451ceee366cbfafc Mon Sep 17 00:00:00 2001 From: Jason Perlow Date: Fri, 25 Sep 2026 12:00:30 -0400 Subject: [PATCH 1/2] feat(wallpaper): add favorites history and panel controls Persist bounded wallpaper history and favorites, and expose navigation, rotation, and favorite actions in the panel. Assisted-by: Codex:gpt-5 Assisted-by: Codex:gpt-5.6-sol AI-Scope: Rebased and integrated Phase 1 wallpaper favorites, history, panel controls, tests, and the generic rotation-state path. --- meson.build | 29 +++++++ src/components/panel/panel.vala | 113 +++++++++++++++++++++++++++- src/core/wallpaper_favorites.vala | 45 +++++++++++ src/core/wallpaper_history.vala | 102 +++++++++++++++++++++++++ src/core/wallpaper_manager.vala | 3 + tests/dev.sinty.desktop.gschema.xml | 9 +++ tests/wallpaper_favorites_test.vala | 45 +++++++++++ tests/wallpaper_history_test.vala | 57 ++++++++++++++ 8 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 src/core/wallpaper_favorites.vala create mode 100644 src/core/wallpaper_history.vala create mode 100644 tests/dev.sinty.desktop.gschema.xml create mode 100644 tests/wallpaper_favorites_test.vala create mode 100644 tests/wallpaper_history_test.vala diff --git a/meson.build b/meson.build index 584f41e..c7ef2c9 100644 --- a/meson.build +++ b/meson.build @@ -411,6 +411,8 @@ singularity_core_sources = files( 'src/core/wallpaper_rotation_state.vala', 'src/core/wallpaper_rotator.vala', 'src/core/artist_pack_manager.vala', + 'src/core/wallpaper_history.vala', + 'src/core/wallpaper_favorites.vala', 'src/core/wallpaper_sidecar.vala', 'src/core/wallpaper_browse_cache.vala', 'src/core/wallpaper_thumbnail_cache.vala', @@ -923,6 +925,33 @@ wallpaper_rotation_state_test = executable('wallpaper-rotation-state-test', ) test('wallpaper-rotation-state', wallpaper_rotation_state_test) +glib_compile_schemas = find_program('glib-compile-schemas') +wallpaper_test_schema = custom_target('wallpaper-test-schema', + input: 'tests/dev.sinty.desktop.gschema.xml', + output: 'gschemas.compiled', + command: [glib_compile_schemas, '--strict', '--targetdir', meson.current_build_dir(), + join_paths(meson.current_source_dir(), 'tests')], + build_by_default: true, +) +wallpaper_test_env = environment() +wallpaper_test_env.set('GSETTINGS_SCHEMA_DIR', meson.current_build_dir()) + +wallpaper_history_test = executable('wallpaper-history-test', + sources: ['src/core/wallpaper_history.vala', 'tests/wallpaper_history_test.vala'], + dependencies: [dependency('gobject-2.0'), dependency('gio-2.0'), dependency('gio-unix-2.0'), gee_dep], +) +test('wallpaper-history', wallpaper_history_test, + depends: wallpaper_test_schema, + env: wallpaper_test_env) + +wallpaper_favorites_test = executable('wallpaper-favorites-test', + sources: ['src/core/wallpaper_favorites.vala', 'tests/wallpaper_favorites_test.vala'], + dependencies: [dependency('gobject-2.0'), dependency('gio-2.0'), dependency('gio-unix-2.0'), gee_dep], +) +test('wallpaper-favorites', wallpaper_favorites_test, + depends: wallpaper_test_schema, + env: wallpaper_test_env) + wallpaper_gallery_test = executable('wallpaper-gallery-test', sources: ['src/core/wallpaper_gallery.vala', 'src/core/dynamic_wallpaper.vala', 'tests/wallpaper_gallery_test.vala'], dependencies: [dependency('gobject-2.0'), dependency('gio-2.0'), gee_dep, json_dep, cc.find_library('m')], diff --git a/src/components/panel/panel.vala b/src/components/panel/panel.vala index 43ace97..c7dca35 100644 --- a/src/components/panel/panel.vala +++ b/src/components/panel/panel.vala @@ -5,6 +5,109 @@ using Singularity.Widgets; namespace Singularity { + private class WallpaperIndicator : Gtk.Box { + private GLib.Settings settings; + private WallpaperHistory history; + private WallpaperFavorites favorites; + private WallpaperRotationState rotation_state; + private Button previous_button; + private Button next_button; + private Button pause_button; + private Button favorite_button; + private string? navigation_target = null; + + public WallpaperIndicator(GLib.Settings settings) { + Object(orientation: Orientation.HORIZONTAL, spacing: 0); + valign = Align.CENTER; + this.settings = settings; + history = new WallpaperHistory(settings); + favorites = new WallpaperFavorites(settings); + rotation_state = new WallpaperRotationState( + WallpaperRotationState.default_config_dir()); + + var button = new MenuButton(); + button.add_css_class("flat"); + button.tooltip_text = _("Wallpaper controls"); + var icon = new Image.from_icon_name("preferences-desktop-wallpaper-symbolic"); + icon.pixel_size = 16; + button.child = icon; + append(button); + + var controls = new Box(Orientation.HORIZONTAL, 6); + controls.margin_top = 10; + controls.margin_bottom = 10; + controls.margin_start = 12; + controls.margin_end = 12; + + previous_button = new Button.from_icon_name("go-previous-symbolic"); + previous_button.tooltip_text = _("Previous wallpaper"); + previous_button.clicked.connect(() => navigate(history.go_back())); + controls.append(previous_button); + + next_button = new Button.from_icon_name("go-next-symbolic"); + next_button.tooltip_text = _("Next wallpaper"); + next_button.clicked.connect(() => navigate(history.go_forward())); + controls.append(next_button); + + pause_button = new Button(); + pause_button.clicked.connect(() => { + rotation_state.set_rotate_enabled(!rotation_state.get_rotate_enabled()); + update_controls(); + }); + controls.append(pause_button); + + favorite_button = new Button(); + favorite_button.clicked.connect(() => { + string? path = WallpaperManager.get_default().wallpaper_path; + if (path != null) favorites.toggle_favorite(path); + }); + controls.append(favorite_button); + + var popover = new Popover(); + popover.child = controls; + button.popover = popover; + popover.notify["visible"].connect(() => { + if (popover.visible) update_controls(); + }); + + var manager = WallpaperManager.get_default(); + manager.wallpaper_path_changed.connect((path) => { + if (navigation_target == path) navigation_target = null; + else history.record(path); + update_controls(); + }); + favorites.favorites_changed.connect(update_controls); + if (manager.wallpaper_path != null && history.current_path != manager.wallpaper_path) + history.record(manager.wallpaper_path); + update_controls(); + } + + private void navigate(string? path) { + if (path == null) return; + navigation_target = path; + settings.delay(); + SettingsSafety.set_string(settings, "background-picture-uri", + File.new_for_path(path).get_uri()); + SettingsSafety.set_string(settings, "background-attribution-title", ""); + SettingsSafety.set_string(settings, "background-attribution-author", ""); + settings.apply(); + update_controls(); + } + + private void update_controls() { + previous_button.sensitive = history.can_go_back(); + next_button.sensitive = history.can_go_forward(); + bool rotating = rotation_state.get_rotate_enabled(); + pause_button.icon_name = rotating ? "media-playback-pause-symbolic" : "media-playback-start-symbolic"; + pause_button.tooltip_text = rotating ? _("Pause wallpaper rotation") : _("Resume wallpaper rotation"); + string? path = WallpaperManager.get_default().wallpaper_path; + bool is_favorite = path != null && favorites.is_favorite(path); + favorite_button.icon_name = is_favorite ? "starred-symbolic" : "non-starred-symbolic"; + favorite_button.tooltip_text = is_favorite ? _("Remove from favorites") : _("Add to favorites"); + favorite_button.sensitive = path != null; + } + } + private class TilingPositionIndicator : Gtk.Fixed { private const int TRACK_WIDTH = 58; private const int TRACK_HEIGHT = 18; @@ -751,6 +854,8 @@ namespace Singularity { clock_box.append(clock_btn); clock_box.append(clock_suffix_box); layout_items["clock"] = clock_box; + if (is_primary && !is_greeter_mode) + layout_items["wallpaper"] = new WallpaperIndicator(_settings); reload_bar_layout(); _settings.changed["panel-layout-left"].connect(() => { if (!saving_bar_layout) reload_bar_layout(); @@ -769,8 +874,8 @@ namespace Singularity { center_box, right_box, layout_items, - { "overview", "workspaces", "tiling-position", "app-title", "global-menu", "system", "notifications", "clock" }, - { _("Overview"), _("Workspaces"), _("Scrolling Position"), _("App Title"), _("Global Menu"), _("System Status"), _("Notifications"), _("Clock") } + { "overview", "workspaces", "tiling-position", "app-title", "global-menu", "system", "notifications", "clock", "wallpaper" }, + { _("Overview"), _("Workspaces"), _("Scrolling Position"), _("App Title"), _("Global Menu"), _("System Status"), _("Notifications"), _("Clock"), _("Wallpaper") } ); layout_editor.move_requested.connect((item_id, section, index) => { if (bar_layout != null && bar_layout.move(item_id, section, index)) save_bar_layout(); @@ -1121,13 +1226,13 @@ namespace Singularity { private void reload_bar_layout() { string[] item_ids = { "overview", "workspaces", "tiling-position", "app-title", "global-menu", - "system", "notifications", "clock" + "system", "notifications", "clock", "wallpaper" }; bar_layout = new BarLayout( item_ids, { "overview", "workspaces", "app-title", "global-menu" }, { "tiling-position" }, - { "system", "notifications", "clock" }, + { "system", "notifications", "clock", "wallpaper" }, _settings.get_strv("panel-layout-left"), _settings.get_strv("panel-layout-center"), _settings.get_strv("panel-layout-right") diff --git a/src/core/wallpaper_favorites.vala b/src/core/wallpaper_favorites.vala new file mode 100644 index 0000000..892fe3f --- /dev/null +++ b/src/core/wallpaper_favorites.vala @@ -0,0 +1,45 @@ +using GLib; +using Gee; + +namespace Singularity { + + public class WallpaperFavorites : Object { + private const string FAVORITES_KEY = "wallpaper-favorites"; + private GLib.Settings settings; + private ArrayList favorites = new ArrayList(); + + public signal void favorites_changed(); + + public WallpaperFavorites(GLib.Settings? settings = null) { + this.settings = settings ?? new GLib.Settings("dev.sinty.desktop"); + SettingsSchema? schema = this.settings.settings_schema; + if (schema == null || !schema.has_key(FAVORITES_KEY)) return; + foreach (string path in this.settings.get_strv(FAVORITES_KEY)) { + if (path != "" && !favorites.contains(path)) favorites.add(path); + } + } + + private void save() { + SettingsSchema? schema = settings.settings_schema; + if (schema == null || !schema.has_key(FAVORITES_KEY)) return; + settings.set_strv(FAVORITES_KEY, list_favorites()); + } + + public bool is_favorite(string path) { + return path != "" && favorites.contains(path); + } + + public void toggle_favorite(string path) { + if (path == "") return; + if (!favorites.remove(path)) favorites.add(path); + save(); + favorites_changed(); + } + + public string[] list_favorites() { + string[] result = {}; + foreach (string path in favorites) result += path; + return result; + } + } +} diff --git a/src/core/wallpaper_history.vala b/src/core/wallpaper_history.vala new file mode 100644 index 0000000..0b26b16 --- /dev/null +++ b/src/core/wallpaper_history.vala @@ -0,0 +1,102 @@ +using GLib; +using Gee; + +namespace Singularity { + + public class WallpaperHistory : Object { + public const int MAX_ENTRIES = 200; + private const string BACK_KEY = "wallpaper-history-back"; + private const string FORWARD_KEY = "wallpaper-history-forward"; + private const string CURRENT_KEY = "wallpaper-history-current"; + + private GLib.Settings settings; + private ArrayList back = new ArrayList(); + private ArrayList forward = new ArrayList(); + private int max_entries; + public string? current_path { get; private set; default = null; } + public int size { get { return back.size + forward.size + (current_path != null ? 1 : 0); } } + + public WallpaperHistory(GLib.Settings? settings = null, int max_entries = MAX_ENTRIES) { + this.settings = settings ?? new GLib.Settings("dev.sinty.desktop"); + this.max_entries = int.max(1, max_entries); + load(); + } + + private bool has_key(string key) { + SettingsSchema? schema = settings.settings_schema; + return schema != null && schema.has_key(key); + } + + private void load_stack(ArrayList destination, string key) { + if (!has_key(key)) return; + foreach (string path in settings.get_strv(key)) { + if (path != "") destination.add(path); + } + } + + private void load() { + load_stack(back, BACK_KEY); + load_stack(forward, FORWARD_KEY); + if (has_key(CURRENT_KEY)) { + string saved = settings.get_string(CURRENT_KEY); + if (saved != "") current_path = saved; + } + trim_to_limit(); + } + + private string[] stack_to_array(ArrayList stack) { + string[] result = {}; + foreach (string path in stack) result += path; + return result; + } + + private void save() { + settings.delay(); + if (has_key(BACK_KEY)) settings.set_strv(BACK_KEY, stack_to_array(back)); + if (has_key(FORWARD_KEY)) settings.set_strv(FORWARD_KEY, stack_to_array(forward)); + if (has_key(CURRENT_KEY)) settings.set_string(CURRENT_KEY, current_path ?? ""); + settings.apply(); + } + + private void trim_to_limit() { + while (size > max_entries) { + if (back.size > 0) back.remove_at(0); + else if (forward.size > 0) forward.remove_at(0); + else break; + } + } + + public void record(string path) { + if (path == "" || path == current_path) return; + if (current_path != null) back.add(current_path); + current_path = path; + forward.clear(); + trim_to_limit(); + save(); + } + + public bool can_go_back() { + return current_path != null && back.size > 0; + } + + public bool can_go_forward() { + return current_path != null && forward.size > 0; + } + + public string? go_back() { + if (!can_go_back()) return null; + forward.add(current_path); + current_path = back.remove_at(back.size - 1); + save(); + return current_path; + } + + public string? go_forward() { + if (!can_go_forward()) return null; + back.add(current_path); + current_path = forward.remove_at(forward.size - 1); + save(); + return current_path; + } + } +} diff --git a/src/core/wallpaper_manager.vala b/src/core/wallpaper_manager.vala index fbc32d8..7b6236d 100644 --- a/src/core/wallpaper_manager.vala +++ b/src/core/wallpaper_manager.vala @@ -31,6 +31,8 @@ namespace Singularity { public string attribution_author { get; private set; default = ""; } public signal void wallpaper_changed(); + // Emitted only after a different image becomes the displayed wallpaper. + public signal void wallpaper_path_changed(string new_path); public static WallpaperManager get_default() { if (_instance == null) { @@ -245,6 +247,7 @@ namespace Singularity { if (pb_small != null) preview_texture = Texture.for_pixbuf(pb_small); message("Wallpaper loaded: %s", load_path); wallpaper_changed(); + wallpaper_path_changed(load_path); return false; }); }); diff --git a/tests/dev.sinty.desktop.gschema.xml b/tests/dev.sinty.desktop.gschema.xml new file mode 100644 index 0000000..36cb48e --- /dev/null +++ b/tests/dev.sinty.desktop.gschema.xml @@ -0,0 +1,9 @@ + + + + [] + [] + '' + [] + + diff --git a/tests/wallpaper_favorites_test.vala b/tests/wallpaper_favorites_test.vala new file mode 100644 index 0000000..98d006d --- /dev/null +++ b/tests/wallpaper_favorites_test.vala @@ -0,0 +1,45 @@ +using GLib; +using Singularity; + +private GLib.Settings make_settings(GLib.SettingsBackend? backend = null) { + var schema = SettingsSchemaSource.get_default().lookup("dev.sinty.desktop", true); + assert(schema != null); + return new GLib.Settings.full(schema, + backend ?? SettingsBackend.memory_settings_backend_new(), null); +} + +private void test_toggle_and_list() { + var favorites = new WallpaperFavorites(make_settings()); + int changes = 0; + favorites.favorites_changed.connect(() => changes++); + favorites.toggle_favorite("/a"); + favorites.toggle_favorite("/b"); + assert(favorites.is_favorite("/a")); + assert(favorites.list_favorites().length == 2); + favorites.toggle_favorite("/a"); + assert(!favorites.is_favorite("/a")); + assert(favorites.list_favorites()[0] == "/b"); + assert(changes == 3); +} + +private void test_persistence_roundtrip() { + var backend = SettingsBackend.memory_settings_backend_new(); + var first = new WallpaperFavorites(make_settings(backend)); + first.toggle_favorite("/a"); + first.toggle_favorite("/b"); + + var restored = new WallpaperFavorites(make_settings(backend)); + assert(restored.is_favorite("/a")); + assert(restored.is_favorite("/b")); + restored.toggle_favorite("/a"); + var again = new WallpaperFavorites(make_settings(backend)); + assert(!again.is_favorite("/a")); + assert(again.is_favorite("/b")); +} + +public int main(string[] args) { + Test.init(ref args); + Test.add_func("/wallpaper-favorites/toggle-and-list", test_toggle_and_list); + Test.add_func("/wallpaper-favorites/persistence-roundtrip", test_persistence_roundtrip); + return Test.run(); +} diff --git a/tests/wallpaper_history_test.vala b/tests/wallpaper_history_test.vala new file mode 100644 index 0000000..7f313fa --- /dev/null +++ b/tests/wallpaper_history_test.vala @@ -0,0 +1,57 @@ +using GLib; +using Singularity; + +private GLib.Settings make_settings(GLib.SettingsBackend? backend = null) { + var schema = SettingsSchemaSource.get_default().lookup("dev.sinty.desktop", true); + assert(schema != null); + return new GLib.Settings.full(schema, + backend ?? SettingsBackend.memory_settings_backend_new(), null); +} + +private void test_back_forward_semantics() { + var history = new WallpaperHistory(make_settings()); + history.record("/a"); + history.record("/b"); + history.record("/c"); + assert(history.go_back() == "/b"); + assert(history.go_back() == "/a"); + assert(history.go_forward() == "/b"); + history.record("/d"); + assert(!history.can_go_forward()); + assert(history.go_back() == "/b"); +} + +private void test_bounded_size() { + var history = new WallpaperHistory(make_settings(), 3); + history.record("/a"); + history.record("/b"); + history.record("/c"); + history.record("/d"); + assert(history.size == 3); + assert(history.go_back() == "/c"); + assert(history.go_back() == "/b"); + assert(history.go_back() == null); +} + +private void test_persistence_roundtrip() { + var backend = SettingsBackend.memory_settings_backend_new(); + var first = new WallpaperHistory(make_settings(backend)); + first.record("/a"); + first.record("/b"); + first.record("/c"); + assert(first.go_back() == "/b"); + + var restored = new WallpaperHistory(make_settings(backend)); + assert(restored.current_path == "/b"); + assert(restored.go_back() == "/a"); + assert(restored.go_forward() == "/b"); + assert(restored.go_forward() == "/c"); +} + +public int main(string[] args) { + Test.init(ref args); + Test.add_func("/wallpaper-history/back-forward-semantics", test_back_forward_semantics); + Test.add_func("/wallpaper-history/bounded-size", test_bounded_size); + Test.add_func("/wallpaper-history/persistence-roundtrip", test_persistence_roundtrip); + return Test.run(); +} From ef2d00aa61a4c858d0fb6e4c87efdc07de443e5e Mon Sep 17 00:00:00 2001 From: mirkobrombin Date: Wed, 14 Oct 2026 12:51:05 +0200 Subject: [PATCH 2/2] fix: keep wallpaper history in a state file and leave the panel item off by default --- meson.build | 4 +- src/components/panel/panel.vala | 5 ++- src/core/wallpaper_history.vala | 63 ++++++++++++++++------------- src/core/wallpaper_manager.vala | 1 - tests/dev.sinty.desktop.gschema.xml | 3 -- tests/wallpaper_history_test.vala | 21 +++++----- 6 files changed, 50 insertions(+), 47 deletions(-) diff --git a/meson.build b/meson.build index c7ef2c9..3108943 100644 --- a/meson.build +++ b/meson.build @@ -940,9 +940,7 @@ wallpaper_history_test = executable('wallpaper-history-test', sources: ['src/core/wallpaper_history.vala', 'tests/wallpaper_history_test.vala'], dependencies: [dependency('gobject-2.0'), dependency('gio-2.0'), dependency('gio-unix-2.0'), gee_dep], ) -test('wallpaper-history', wallpaper_history_test, - depends: wallpaper_test_schema, - env: wallpaper_test_env) +test('wallpaper-history', wallpaper_history_test) wallpaper_favorites_test = executable('wallpaper-favorites-test', sources: ['src/core/wallpaper_favorites.vala', 'tests/wallpaper_favorites_test.vala'], diff --git a/src/components/panel/panel.vala b/src/components/panel/panel.vala index c7dca35..cc9efa5 100644 --- a/src/components/panel/panel.vala +++ b/src/components/panel/panel.vala @@ -20,7 +20,8 @@ namespace Singularity { Object(orientation: Orientation.HORIZONTAL, spacing: 0); valign = Align.CENTER; this.settings = settings; - history = new WallpaperHistory(settings); + history = new WallpaperHistory(Path.build_filename( + WallpaperRotationState.default_config_dir(), "history.ini")); favorites = new WallpaperFavorites(settings); rotation_state = new WallpaperRotationState( WallpaperRotationState.default_config_dir()); @@ -1232,7 +1233,7 @@ namespace Singularity { item_ids, { "overview", "workspaces", "app-title", "global-menu" }, { "tiling-position" }, - { "system", "notifications", "clock", "wallpaper" }, + { "system", "notifications", "clock" }, _settings.get_strv("panel-layout-left"), _settings.get_strv("panel-layout-center"), _settings.get_strv("panel-layout-right") diff --git a/src/core/wallpaper_history.vala b/src/core/wallpaper_history.vala index 0b26b16..e267ac9 100644 --- a/src/core/wallpaper_history.vala +++ b/src/core/wallpaper_history.vala @@ -5,57 +5,64 @@ namespace Singularity { public class WallpaperHistory : Object { public const int MAX_ENTRIES = 200; - private const string BACK_KEY = "wallpaper-history-back"; - private const string FORWARD_KEY = "wallpaper-history-forward"; - private const string CURRENT_KEY = "wallpaper-history-current"; + private const string GROUP = "History"; - private GLib.Settings settings; + private string path; private ArrayList back = new ArrayList(); private ArrayList forward = new ArrayList(); private int max_entries; public string? current_path { get; private set; default = null; } public int size { get { return back.size + forward.size + (current_path != null ? 1 : 0); } } - public WallpaperHistory(GLib.Settings? settings = null, int max_entries = MAX_ENTRIES) { - this.settings = settings ?? new GLib.Settings("dev.sinty.desktop"); + public WallpaperHistory(string path, int max_entries = MAX_ENTRIES) { + this.path = path; this.max_entries = int.max(1, max_entries); load(); } - private bool has_key(string key) { - SettingsSchema? schema = settings.settings_schema; - return schema != null && schema.has_key(key); - } - - private void load_stack(ArrayList destination, string key) { - if (!has_key(key)) return; - foreach (string path in settings.get_strv(key)) { - if (path != "") destination.add(path); + private void load_stack(KeyFile file, ArrayList destination, string key) { + try { + foreach (string entry in file.get_string_list(GROUP, key)) { + if (entry != "") destination.add(entry); + } + } catch (Error e) { } } private void load() { - load_stack(back, BACK_KEY); - load_stack(forward, FORWARD_KEY); - if (has_key(CURRENT_KEY)) { - string saved = settings.get_string(CURRENT_KEY); + var file = new KeyFile(); + try { + file.load_from_file(path, KeyFileFlags.NONE); + } catch (Error e) { + return; + } + load_stack(file, back, "back"); + load_stack(file, forward, "forward"); + try { + string saved = file.get_string(GROUP, "current"); if (saved != "") current_path = saved; + } catch (Error e) { } trim_to_limit(); } private string[] stack_to_array(ArrayList stack) { string[] result = {}; - foreach (string path in stack) result += path; + foreach (string entry in stack) result += entry; return result; } private void save() { - settings.delay(); - if (has_key(BACK_KEY)) settings.set_strv(BACK_KEY, stack_to_array(back)); - if (has_key(FORWARD_KEY)) settings.set_strv(FORWARD_KEY, stack_to_array(forward)); - if (has_key(CURRENT_KEY)) settings.set_string(CURRENT_KEY, current_path ?? ""); - settings.apply(); + var file = new KeyFile(); + file.set_string_list(GROUP, "back", stack_to_array(back)); + file.set_string_list(GROUP, "forward", stack_to_array(forward)); + file.set_string(GROUP, "current", current_path ?? ""); + try { + DirUtils.create_with_parents(Path.get_dirname(path), 0700); + FileUtils.set_contents(path, file.to_data()); + } catch (Error e) { + warning("Wallpaper history could not be saved: %s", e.message); + } } private void trim_to_limit() { @@ -66,10 +73,10 @@ namespace Singularity { } } - public void record(string path) { - if (path == "" || path == current_path) return; + public void record(string entry) { + if (entry == "" || entry == current_path) return; if (current_path != null) back.add(current_path); - current_path = path; + current_path = entry; forward.clear(); trim_to_limit(); save(); diff --git a/src/core/wallpaper_manager.vala b/src/core/wallpaper_manager.vala index 7b6236d..4ffabdc 100644 --- a/src/core/wallpaper_manager.vala +++ b/src/core/wallpaper_manager.vala @@ -31,7 +31,6 @@ namespace Singularity { public string attribution_author { get; private set; default = ""; } public signal void wallpaper_changed(); - // Emitted only after a different image becomes the displayed wallpaper. public signal void wallpaper_path_changed(string new_path); public static WallpaperManager get_default() { diff --git a/tests/dev.sinty.desktop.gschema.xml b/tests/dev.sinty.desktop.gschema.xml index 36cb48e..755faa1 100644 --- a/tests/dev.sinty.desktop.gschema.xml +++ b/tests/dev.sinty.desktop.gschema.xml @@ -1,9 +1,6 @@ - [] - [] - '' [] diff --git a/tests/wallpaper_history_test.vala b/tests/wallpaper_history_test.vala index 7f313fa..59c2182 100644 --- a/tests/wallpaper_history_test.vala +++ b/tests/wallpaper_history_test.vala @@ -1,15 +1,16 @@ using GLib; using Singularity; -private GLib.Settings make_settings(GLib.SettingsBackend? backend = null) { - var schema = SettingsSchemaSource.get_default().lookup("dev.sinty.desktop", true); - assert(schema != null); - return new GLib.Settings.full(schema, - backend ?? SettingsBackend.memory_settings_backend_new(), null); +private string history_path() { + try { + return Path.build_filename(DirUtils.make_tmp("wallpaper-history-XXXXXX"), "history.ini"); + } catch (Error e) { + error("temporary directory: %s", e.message); + } } private void test_back_forward_semantics() { - var history = new WallpaperHistory(make_settings()); + var history = new WallpaperHistory(history_path()); history.record("/a"); history.record("/b"); history.record("/c"); @@ -22,7 +23,7 @@ private void test_back_forward_semantics() { } private void test_bounded_size() { - var history = new WallpaperHistory(make_settings(), 3); + var history = new WallpaperHistory(history_path(), 3); history.record("/a"); history.record("/b"); history.record("/c"); @@ -34,14 +35,14 @@ private void test_bounded_size() { } private void test_persistence_roundtrip() { - var backend = SettingsBackend.memory_settings_backend_new(); - var first = new WallpaperHistory(make_settings(backend)); + string path = history_path(); + var first = new WallpaperHistory(path); first.record("/a"); first.record("/b"); first.record("/c"); assert(first.go_back() == "/b"); - var restored = new WallpaperHistory(make_settings(backend)); + var restored = new WallpaperHistory(path); assert(restored.current_path == "/b"); assert(restored.go_back() == "/a"); assert(restored.go_forward() == "/b");