diff --git a/README.md b/README.md index b8366e9..700b5d2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@
Install · Configure · + Screenshots · Documentation
@@ -14,7 +15,9 @@ Ferese is a Linux desktop with scrolling columns, tree tiling, and floating windows. It includes a top bar, Settings, notifications, desktop widgets, a lock screen, and screen sharing. Change themes and settings without restarting. - + + +[View all screenshots](docs/screenshots.md). ## Features @@ -25,7 +28,6 @@ lock screen, and screen sharing. Change themes and settings without restarting. - Clock and sticky-note widgets. - Screenshots with Satty editing, screen sharing, and top-bar recording. - ## Install @@ -47,8 +49,6 @@ See [Installation](docs/installation.md) for previews, updates, and recovery. Open **Control Center → Settings**, or edit `~/.config/ferese/config.kdl`. Changes reload automatically; invalid edits keep the last working configuration. - - See the [configuration reference](docs/configuration.md) and [example config](packaging/config.kdl). diff --git a/docs/README.md b/docs/README.md index e934802..279682e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,8 @@ - [Configuration](configuration.md): KDL syntax, layouts, input, shortcuts, and displays. - [Why Ferese](why-ferese.md): layouts and the shared desktop theme. +- [Screenshots](screenshots.md): desktop themes, overview and shell controls. + ## Use the desktop - [Shortcuts and gestures](shortcuts.md): keyboard navigation, Super-drag, resize, and window grouping. diff --git a/docs/images/ferese-desktop.png b/docs/images/ferese-desktop.png deleted file mode 100644 index 06af81c..0000000 Binary files a/docs/images/ferese-desktop.png and /dev/null differ diff --git a/docs/images/ferese-desktop.webp b/docs/images/ferese-desktop.webp deleted file mode 100644 index 3ef5cd5..0000000 Binary files a/docs/images/ferese-desktop.webp and /dev/null differ diff --git a/docs/images/ferese-gruvbox.webp b/docs/images/ferese-gruvbox.webp deleted file mode 100644 index 34b1afe..0000000 Binary files a/docs/images/ferese-gruvbox.webp and /dev/null differ diff --git a/docs/images/ferese-overview.webp b/docs/images/ferese-overview.webp deleted file mode 100644 index 8d75a18..0000000 Binary files a/docs/images/ferese-overview.webp and /dev/null differ diff --git a/docs/images/screenshots/ferese-blue-overview.png b/docs/images/screenshots/ferese-blue-overview.png new file mode 100644 index 0000000..84db90d Binary files /dev/null and b/docs/images/screenshots/ferese-blue-overview.png differ diff --git a/docs/images/screenshots/ferese-main-hero.png b/docs/images/screenshots/ferese-main-hero.png new file mode 100644 index 0000000..dab9bf0 Binary files /dev/null and b/docs/images/screenshots/ferese-main-hero.png differ diff --git a/docs/images/screenshots/power-confirmation.png b/docs/images/screenshots/power-confirmation.png new file mode 100644 index 0000000..c9e9172 Binary files /dev/null and b/docs/images/screenshots/power-confirmation.png differ diff --git a/docs/images/screenshots/power-controls.png b/docs/images/screenshots/power-controls.png new file mode 100644 index 0000000..9e5722e Binary files /dev/null and b/docs/images/screenshots/power-controls.png differ diff --git a/docs/images/screenshots/rose-pine-desktop.png b/docs/images/screenshots/rose-pine-desktop.png new file mode 100644 index 0000000..f7d92ed Binary files /dev/null and b/docs/images/screenshots/rose-pine-desktop.png differ diff --git a/docs/images/screenshots/rose-pine-overview.png b/docs/images/screenshots/rose-pine-overview.png new file mode 100644 index 0000000..52df186 Binary files /dev/null and b/docs/images/screenshots/rose-pine-overview.png differ diff --git a/docs/images/screenshots/shortcut-guide.png b/docs/images/screenshots/shortcut-guide.png new file mode 100644 index 0000000..21632f2 Binary files /dev/null and b/docs/images/screenshots/shortcut-guide.png differ diff --git a/docs/installation.md b/docs/installation.md index dc061f7..3d8bffe 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -306,6 +306,9 @@ greeter's configuration. Reinstalling restores the desktop session entry. ## Screen sharing and recording -The installer includes Ferese’s native ScreenCast portal. See +The installer includes Ferese’s native ScreenCast portal. It backs up the old +user service override that points to `~/.local/libexec/ferese`, so new sessions +use the installed release. Custom overrides are preserved and reported before +building. See [Screen sharing](screen-sharing.md) for consent, PipeWire setup, supported sources, and current recording limitations. diff --git a/docs/screenshots.md b/docs/screenshots.md new file mode 100644 index 0000000..8b2fd5a --- /dev/null +++ b/docs/screenshots.md @@ -0,0 +1,45 @@ +# Screenshots + +Captured on September 30, 2026. Select an image to view it at full size. + +## Ferese Blue + +Settings and Control Center with the default wallpaper. + +[](images/screenshots/ferese-main-hero.png) + +## Rosé Pine + +Theme previews, Control Center and the desktop clock. + +[](images/screenshots/rose-pine-desktop.png) + +## Workspace overview + +Windows and workspaces over a custom wallpaper. + +[](images/screenshots/rose-pine-overview.png) + +## Power controls + +Power profiles and restart, power off and suspend actions. + +[](images/screenshots/power-controls.png) + +## Ferese Blue overview + +Application previews and workspace selection. + +[](images/screenshots/ferese-blue-overview.png) + +## Shortcut guide + +The login guide shows the configured keyboard shortcuts. + +[](images/screenshots/shortcut-guide.png) + +## Power confirmation + +A centered confirmation dialog with background blur. + +[](images/screenshots/power-confirmation.png) diff --git a/docs/why-ferese.md b/docs/why-ferese.md index 7dbebc0..8dd30fb 100644 --- a/docs/why-ferese.md +++ b/docs/why-ferese.md @@ -10,7 +10,7 @@ Scrolling columns let you keep windows at useful widths and move through them horizontally. Tree tiling divides the screen into nested splits. Floating windows work alongside either layout, and overview shows windows across workspaces. - + ## Change the desktop together @@ -18,7 +18,7 @@ Choose a theme in Settings, then adjust the wallpaper, colors, font, corners, and motion. Changes apply live. Window corners and shell corners can be set independently. - + For example, this changes shell corners: diff --git a/portal/src/picker.rs b/portal/src/picker.rs index 86b1a24..dc7119f 100644 --- a/portal/src/picker.rs +++ b/portal/src/picker.rs @@ -310,7 +310,12 @@ impl cosmic::Application for Picker { .class(if selected { ferese_theme::accent_button() } else { - ferese_theme::controls::navigation_style(self.palette, false) + ferese_theme::controls::notification_button( + self.palette.text, + self.palette.text.scale_alpha(0.06), + self.palette.radius.min(9.), + false, + ) }) .padding(8) .width(Length::Fill) diff --git a/scripts/build-site.py b/scripts/build-site.py index 1c0a653..3a28b29 100644 --- a/scripts/build-site.py +++ b/scripts/build-site.py @@ -13,6 +13,7 @@ OUTPUT = ROOT / 'build' / 'site' REPO = 'https://github.com/ferese-wm/ferese' PAGES = [ ('index', 'Introduction', ROOT / 'site/content/index.md'), + ('screenshots', 'Screenshots', ROOT / 'docs/screenshots.md'), ('why-ferese', 'Why Ferese', ROOT / 'docs/why-ferese.md'), ('installation', 'Installation', ROOT / 'docs/installation.md'), ('configuration', 'Configuration', ROOT / 'docs/configuration.md'), @@ -27,7 +28,9 @@ PAGES = [ ('development', 'Development', ROOT / 'docs/development.md'), ] md = MarkdownIt('commonmark', {'html': False}).enable('table') -OUTPUT.mkdir(parents=True, exist_ok=True) +if OUTPUT.exists(): + shutil.rmtree(OUTPUT) +OUTPUT.mkdir(parents=True) for name in ('index.html', 'styles.css', 'app.js'): shutil.copy2(ROOT / 'site' / name, OUTPUT / name) (OUTPUT / 'assets').mkdir(exist_ok=True) @@ -46,7 +49,10 @@ def rewrite_link(href, source): basename = Path(url.path).stem if url.path.endswith('.md') and basename in {page[0] for page in PAGES}: return f'{basename}.html' + (f'#{url.fragment}' if url.fragment else '') - destination = (source.parent / url.path).resolve().relative_to(ROOT) + path = (source.parent / url.path).resolve() + if path.is_relative_to(ROOT / 'docs/images'): + return '../assets/' + path.relative_to(ROOT / 'docs/images').as_posix() + destination = path.relative_to(ROOT) return f'{REPO}/blob/main/{destination}' + (f'#{url.fragment}' if url.fragment else '') diff --git a/scripts/install.sh b/scripts/install.sh index 3c16577..cdea6ae 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -21,6 +21,27 @@ authentication is requested only after a successful build. EOF } +check_user_portal_override() { + local override=$1 user_home=$2 + [[ -f $override ]] || return 0 + if ! cmp -s -- <(printf '%s\n' '[Service]' 'ExecStart=' \ + "ExecStart=$user_home/.local/libexec/ferese/xdg-desktop-portal-ferese") "$override"; then + echo "Custom portal override takes precedence over the installation: $override" >&2 + echo 'Update its ExecStart to /usr/local/lib/ferese/current/xdg-desktop-portal-ferese before installing.' >&2 + return 1 + fi +} + +backup_user_portal_override() { + local override=$1 user_home=$2 release=$3 + [[ -f $override ]] || return 0 + check_user_portal_override "$override" "$user_home" || return 1 + local backup="$override.before-$release" + [[ ! -e $backup ]] || { echo "Portal override backup already exists: $backup" >&2; return 1; } + mv -- "$override" "$backup" + echo "Backed up old development portal override: $backup" +} + fail() { echo "ferese installer: $*" >&2; exit 1; } repo_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) release_id="$(date -u +%Y%m%d-%H%M%S)-$$" @@ -49,6 +70,10 @@ for tool in desktop-file-validate dbus-run-session; do command -v "$tool" >/dev/null || fail "required command not found: $tool" done desktop-file-validate "$repo_dir/packaging/ferese.desktop" +user_portal_override="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/xdg-desktop-portal-ferese.service.d/override.conf" +if ((EUID != 0)); then + check_user_portal_override "$user_portal_override" "$HOME" || fail 'portal service override needs attention' +fi build=(cargo build --manifest-path "$repo_dir/Cargo.toml" --target-dir "$repo_dir/target" --release --locked @@ -83,4 +108,8 @@ for name in ferese ferese-shell ferese-settings feresectl ferese-lock ferese-pol [[ -x $repo_dir/target/release/$name ]] || fail "missing release binary: $name" done "${installer[@]}" +if ((EUID != 0)) && [[ -f $user_portal_override ]]; then + backup_user_portal_override "$user_portal_override" "$HOME" "$release_id" || fail 'could not update portal override' + systemctl --user daemon-reload || fail 'could not reload the user portal service configuration' +fi echo 'Installation complete. Log out and select Ferese at your login screen, or run ferese-session from a local TTY.' diff --git a/scripts/tests/test_portal_install.py b/scripts/tests/test_portal_install.py index 1a70129..30b808b 100644 --- a/scripts/tests/test_portal_install.py +++ b/scripts/tests/test_portal_install.py @@ -57,6 +57,41 @@ class PortalInstallTest(unittest.TestCase): 'replace_portal_config': str(replace).lower()}, capture_output=True, text=True) + def user_override(self, content, backup=False): + script = (REPO / 'scripts/install.sh').read_text() + helpers = script[script.index('check_user_portal_override()'):script.index('fail() {')] + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + override = root / 'override.conf' + if content is not None: + override.write_text(content.replace('USER_HOME', directory)) + command = 'backup_user_portal_override' if backup else 'check_user_portal_override' + result = subprocess.run(['bash', '-eu', '-c', helpers + + f'\n{command} "$TEST_ROOT/override.conf" "$TEST_ROOT" test-release'], + env={'TEST_ROOT': directory}, capture_output=True, text=True) + saved = root / 'override.conf.before-test-release' + return result, override.exists(), saved.read_text() if saved.exists() else None + + def test_user_development_override_is_backed_up(self): + content = '[Service]\nExecStart=\nExecStart=USER_HOME/.local/libexec/ferese/xdg-desktop-portal-ferese\n' + result, exists, saved = self.user_override(content, backup=True) + self.assertEqual(result.returncode, 0, result.stderr) + self.assertFalse(exists) + self.assertIn('/.local/libexec/ferese/xdg-desktop-portal-ferese', saved) + + def test_custom_user_override_is_preserved_and_reported(self): + result, exists, saved = self.user_override('[Service]\nExecStart=/custom/portal\n', backup=True) + self.assertNotEqual(result.returncode, 0) + self.assertTrue(exists) + self.assertIsNone(saved) + self.assertIn('takes precedence', result.stderr) + + def test_missing_user_override_needs_no_backup(self): + result, exists, saved = self.user_override(None, backup=True) + self.assertEqual(result.returncode, 0, result.stderr) + self.assertFalse(exists) + self.assertIsNone(saved) + def test_existing_development_install_requires_explicit_replacement(self): portal = ('[portal]\nDBusName=org.freedesktop.impl.portal.desktop.ferese\n' 'Interfaces=org.freedesktop.impl.portal.ScreenCast;\nUseIn=Ferese;\n') diff --git a/site/content/index.md b/site/content/index.md index ecb71ad..c8ea377 100644 --- a/site/content/index.md +++ b/site/content/index.md @@ -3,6 +3,8 @@ Ferese is a Linux Wayland desktop with scrolling columns, tree tiling, floating windows, and a shared theme for its desktop tools. +[Browse screenshots](screenshots.md) of the desktop, themes and shell controls. + ## Get started 1. [Install Ferese](installation.md), or try a [nested preview](installation.md#preview-and-logs). diff --git a/site/index.html b/site/index.html index 8a3510b..8d49990 100644 --- a/site/index.html +++ b/site/index.html @@ -19,7 +19,7 @@