diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a1dfc96..b5a7475 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -121,7 +121,7 @@ other-checks: image: alpine script: - apk add --no-cache git - - git ls-files 'src/*.rs' 'src/*.ui' 'data/*.ui' 'data/*.desktop.in*' '*.metainfo.xml.in*' > po/POTFILES.in + - git ls-files 'src/*.rs' 'src/*.ui' 'data/*.ui' 'data/*.desktop.in*' '*.gschema.xml.in' '*.metainfo.xml.in*' > po/POTFILES.in - git diff --exit-code pages: @@ -147,4 +147,4 @@ nightly@aarch64: extends: ".publish_nightly" stage: deploy dependencies: - - flatpak@aarch64 \ No newline at end of file + - flatpak@aarch64 diff --git a/data/meson.build b/data/meson.build index ef6b855..fced285 100644 --- a/data/meson.build +++ b/data/meson.build @@ -90,6 +90,26 @@ appstream_file = i18n.merge_file( subdir('icons') +# GSchema +gschema_conf = configuration_data() +gschema_conf.set('app-id', app_id) +gschema_conf.set('gettext-package', meson.project_name()) +configure_file( + input: '@0@.gschema.xml.in'.format(base_id), + output: '@0@.gschema.xml'.format(app_id), + configuration: gschema_conf, + install: true, + install_dir: iv_datadir / 'glib-2.0' / 'schemas' +) + +# Validate GSchema +test( + 'validate-gschema', glib_compile_schemas, + args: [ + '--strict', '--dry-run', meson.current_source_dir() + ] +) + # Post install gnome.post_install() diff --git a/data/org.gnome.Loupe.gschema.xml.in b/data/org.gnome.Loupe.gschema.xml.in new file mode 100644 index 0000000..13ac2ea --- /dev/null +++ b/data/org.gnome.Loupe.gschema.xml.in @@ -0,0 +1,9 @@ + + + + + false + Show the image properties sidebar + + + diff --git a/meson.build b/meson.build index b3c5b6a..a1f0fd1 100644 --- a/meson.build +++ b/meson.build @@ -15,6 +15,7 @@ dependency('gweather4', version: '>=4.0.0') dependency('lcms2', version: '>=2.12.0') cargo = find_program('cargo', required: true) +glib_compile_schemas = find_program('glib-compile-schemas', required: true) iv_prefix = get_option('prefix') iv_bindir = iv_prefix / get_option('bindir') @@ -35,6 +36,7 @@ if get_option('profile') != 'release' endif endif +base_id = 'org.gnome.Loupe' app_id = 'org.gnome.Loupe@0@'.format(profile) iv_version = meson.project_version() + version_suffix @@ -66,6 +68,7 @@ endif gnome.post_install( gtk_update_icon_cache: true, update_desktop_database: true, + glib_compile_schemas: true, ) meson.add_dist_script( diff --git a/po/POTFILES.in b/po/POTFILES.in index 7d5f361..b94f546 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,5 @@ data/org.gnome.Loupe.desktop.in.in +data/org.gnome.Loupe.gschema.xml.in data/org.gnome.Loupe.metainfo.xml.in.in data/resources/gtk/help-overlay.ui src/about.rs diff --git a/src/application.rs b/src/application.rs index 6f40d63..586f167 100644 --- a/src/application.rs +++ b/src/application.rs @@ -33,8 +33,18 @@ mod imp { // The basic struct that holds our // state and widgets - #[derive(Default, Debug)] - pub struct LpApplication {} + #[derive(Debug)] + pub struct LpApplication { + pub settings: gio::Settings, + } + + impl Default for LpApplication { + fn default() -> Self { + Self { + settings: gio::Settings::new(config::APP_ID), + } + } + } // Sets up the basics for the GObject // The `#[glib::object_subclass] macro implements @@ -209,4 +219,17 @@ impl LpApplication { } }); } + + pub fn settings(&self) -> gio::Settings { + self.imp().settings.clone() + } +} + +impl Default for LpApplication { + fn default() -> Self { + gio::Application::default() + .unwrap() + .downcast::() + .unwrap() + } } diff --git a/src/window.rs b/src/window.rs index 10d1690..94639f0 100644 --- a/src/window.rs +++ b/src/window.rs @@ -35,6 +35,7 @@ use gtk::CompositeTemplate; use std::cell::{Cell, OnceCell, RefCell}; use std::path::{Path, PathBuf}; +use crate::application::LpApplication; use crate::config; use crate::util::{Direction, Position}; use crate::widgets::{LpDragOverlay, LpImage, LpImageView, LpPropertiesView}; @@ -275,6 +276,10 @@ mod imp { .connect_pressed(clone!(@weak obj => move |_,_,_,_| { obj.image_view().navigate(Direction::Back); })); + self.properties_button + .connect_toggled(clone!(@weak obj => move |_| { + obj.on_properties_button_toggled(); + })); if config::PROFILE == ".Devel" { obj.add_css_class("devel"); @@ -764,10 +769,14 @@ impl LpWindow { ); if has_image { + let settings = LpApplication::default().settings(); + imp.properties_button + .set_active(settings.boolean("show-properties")); imp.stack.set_visible_child(&*imp.image_view); imp.image_view.grab_focus(); self.schedule_hide_controls(); } else { + imp.properties_button.set_active(false); imp.stack.set_visible_child(&*imp.status_page); imp.status_page.grab_focus(); // Leave fullscreen since status page has no controls to leave it @@ -775,6 +784,22 @@ impl LpWindow { } } + /// When the image-properties sidebar is displayed or hidden, we should update the + /// "show-properties" setting. + fn on_properties_button_toggled(&self) { + let imp = self.imp(); + // When no image is shown, we skip this update as the sidebar should always be hidden. + // This can happen when deleting a picture. + if imp.image_view.current_page().is_none() { + return; + } + let settings = LpApplication::default().settings(); + let result = settings.set_boolean("show-properties", imp.properties_button.is_active()); + if let Err(err) = result { + log::warn!("Failed to save show-properties state, {}", err); + } + } + pub fn update_title(&self) { let title = self .imp()