Refresh screenshot galleries and repair portal upgrades
Use the September 30 hero on the website and README, add a shared screenshot gallery, and remove the old showcase images. Build image links locally and clean generated site output. Back up the known development portal override during installation and report custom overrides before building. Keep source selections clear while letting blur show through unselected rows.
No files matched your search
@@ -7,6 +7,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="docs/installation.md">Install</a> ·
|
<a href="docs/installation.md">Install</a> ·
|
||||||
<a href="docs/configuration.md">Configure</a> ·
|
<a href="docs/configuration.md">Configure</a> ·
|
||||||
|
<a href="docs/screenshots.md">Screenshots</a> ·
|
||||||
<a href="docs/README.md">Documentation</a>
|
<a href="docs/README.md">Documentation</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -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
|
windows. It includes a top bar, Settings, notifications, desktop widgets, a
|
||||||
lock screen, and screen sharing. Change themes and settings without restarting.
|
lock screen, and screen sharing. Change themes and settings without restarting.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
[View all screenshots](docs/screenshots.md).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -25,7 +28,6 @@ lock screen, and screen sharing. Change themes and settings without restarting.
|
|||||||
- Clock and sticky-note widgets.
|
- Clock and sticky-note widgets.
|
||||||
- Screenshots with Satty editing, screen sharing, and top-bar recording.
|
- Screenshots with Satty editing, screen sharing, and top-bar recording.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Install
|
## 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`.
|
Open **Control Center → Settings**, or edit `~/.config/ferese/config.kdl`.
|
||||||
Changes reload automatically; invalid edits keep the last working configuration.
|
Changes reload automatically; invalid edits keep the last working configuration.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
See the [configuration reference](docs/configuration.md) and
|
See the [configuration reference](docs/configuration.md) and
|
||||||
[example config](packaging/config.kdl).
|
[example config](packaging/config.kdl).
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
- [Configuration](configuration.md): KDL syntax, layouts, input, shortcuts, and displays.
|
- [Configuration](configuration.md): KDL syntax, layouts, input, shortcuts, and displays.
|
||||||
- [Why Ferese](why-ferese.md): layouts and the shared desktop theme.
|
- [Why Ferese](why-ferese.md): layouts and the shared desktop theme.
|
||||||
|
|
||||||
|
- [Screenshots](screenshots.md): desktop themes, overview and shell controls.
|
||||||
|
|
||||||
## Use the desktop
|
## Use the desktop
|
||||||
|
|
||||||
- [Shortcuts and gestures](shortcuts.md): keyboard navigation, Super-drag, resize, and window grouping.
|
- [Shortcuts and gestures](shortcuts.md): keyboard navigation, Super-drag, resize, and window grouping.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 305 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 898 KiB |
|
After Width: | Height: | Size: 372 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 323 KiB |
@@ -306,6 +306,9 @@ greeter's configuration. Reinstalling restores the desktop session entry.
|
|||||||
|
|
||||||
## Screen sharing and recording
|
## 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,
|
[Screen sharing](screen-sharing.md) for consent, PipeWire setup, supported sources,
|
||||||
and current recording limitations.
|
and current recording limitations.
|
||||||
@@ -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)
|
||||||
@@ -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
|
horizontally. Tree tiling divides the screen into nested splits. Floating windows
|
||||||
work alongside either layout, and overview shows windows across workspaces.
|
work alongside either layout, and overview shows windows across workspaces.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Change the desktop together
|
## 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
|
and motion. Changes apply live. Window corners and shell corners can be set
|
||||||
independently.
|
independently.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
For example, this changes shell corners:
|
For example, this changes shell corners:
|
||||||
|
|
||||||
|
|||||||
@@ -310,7 +310,12 @@ impl cosmic::Application for Picker {
|
|||||||
.class(if selected {
|
.class(if selected {
|
||||||
ferese_theme::accent_button()
|
ferese_theme::accent_button()
|
||||||
} else {
|
} 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)
|
.padding(8)
|
||||||
.width(Length::Fill)
|
.width(Length::Fill)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ OUTPUT = ROOT / 'build' / 'site'
|
|||||||
REPO = 'https://github.com/ferese-wm/ferese'
|
REPO = 'https://github.com/ferese-wm/ferese'
|
||||||
PAGES = [
|
PAGES = [
|
||||||
('index', 'Introduction', ROOT / 'site/content/index.md'),
|
('index', 'Introduction', ROOT / 'site/content/index.md'),
|
||||||
|
('screenshots', 'Screenshots', ROOT / 'docs/screenshots.md'),
|
||||||
('why-ferese', 'Why Ferese', ROOT / 'docs/why-ferese.md'),
|
('why-ferese', 'Why Ferese', ROOT / 'docs/why-ferese.md'),
|
||||||
('installation', 'Installation', ROOT / 'docs/installation.md'),
|
('installation', 'Installation', ROOT / 'docs/installation.md'),
|
||||||
('configuration', 'Configuration', ROOT / 'docs/configuration.md'),
|
('configuration', 'Configuration', ROOT / 'docs/configuration.md'),
|
||||||
@@ -27,7 +28,9 @@ PAGES = [
|
|||||||
('development', 'Development', ROOT / 'docs/development.md'),
|
('development', 'Development', ROOT / 'docs/development.md'),
|
||||||
]
|
]
|
||||||
md = MarkdownIt('commonmark', {'html': False}).enable('table')
|
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'):
|
for name in ('index.html', 'styles.css', 'app.js'):
|
||||||
shutil.copy2(ROOT / 'site' / name, OUTPUT / name)
|
shutil.copy2(ROOT / 'site' / name, OUTPUT / name)
|
||||||
(OUTPUT / 'assets').mkdir(exist_ok=True)
|
(OUTPUT / 'assets').mkdir(exist_ok=True)
|
||||||
@@ -46,7 +49,10 @@ def rewrite_link(href, source):
|
|||||||
basename = Path(url.path).stem
|
basename = Path(url.path).stem
|
||||||
if url.path.endswith('.md') and basename in {page[0] for page in PAGES}:
|
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 '')
|
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 '')
|
return f'{REPO}/blob/main/{destination}' + (f'#{url.fragment}' if url.fragment else '')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,27 @@ authentication is requested only after a successful build.
|
|||||||
EOF
|
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; }
|
fail() { echo "ferese installer: $*" >&2; exit 1; }
|
||||||
repo_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
repo_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||||||
release_id="$(date -u +%Y%m%d-%H%M%S)-$$"
|
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"
|
command -v "$tool" >/dev/null || fail "required command not found: $tool"
|
||||||
done
|
done
|
||||||
desktop-file-validate "$repo_dir/packaging/ferese.desktop"
|
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"
|
build=(cargo build --manifest-path "$repo_dir/Cargo.toml"
|
||||||
--target-dir "$repo_dir/target" --release --locked
|
--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"
|
[[ -x $repo_dir/target/release/$name ]] || fail "missing release binary: $name"
|
||||||
done
|
done
|
||||||
"${installer[@]}"
|
"${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.'
|
echo 'Installation complete. Log out and select Ferese at your login screen, or run ferese-session from a local TTY.'
|
||||||
@@ -57,6 +57,41 @@ class PortalInstallTest(unittest.TestCase):
|
|||||||
'replace_portal_config': str(replace).lower()},
|
'replace_portal_config': str(replace).lower()},
|
||||||
capture_output=True, text=True)
|
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):
|
def test_existing_development_install_requires_explicit_replacement(self):
|
||||||
portal = ('[portal]\nDBusName=org.freedesktop.impl.portal.desktop.ferese\n'
|
portal = ('[portal]\nDBusName=org.freedesktop.impl.portal.desktop.ferese\n'
|
||||||
'Interfaces=org.freedesktop.impl.portal.ScreenCast;\nUseIn=Ferese;\n')
|
'Interfaces=org.freedesktop.impl.portal.ScreenCast;\nUseIn=Ferese;\n')
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
Ferese is a Linux Wayland desktop with scrolling columns, tree tiling, floating
|
Ferese is a Linux Wayland desktop with scrolling columns, tree tiling, floating
|
||||||
windows, and a shared theme for its desktop tools.
|
windows, and a shared theme for its desktop tools.
|
||||||
|
|
||||||
|
[Browse screenshots](screenshots.md) of the desktop, themes and shell controls.
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
1. [Install Ferese](installation.md), or try a [nested preview](installation.md#preview-and-logs).
|
1. [Install Ferese](installation.md), or try a [nested preview](installation.md#preview-and-logs).
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta
|
<meta
|
||||||
property="og:image"
|
property="og:image"
|
||||||
content="https://ferese-wm.github.io/ferese/assets/ferese-desktop.png"
|
content="https://ferese-wm.github.io/ferese/assets/screenshots/ferese-main-hero.png"
|
||||||
/>
|
/>
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<title>Ferese — Wayland desktop</title>
|
<title>Ferese — Wayland desktop</title>
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
>
|
>
|
||||||
<nav aria-label="Main navigation">
|
<nav aria-label="Main navigation">
|
||||||
<a href="./" aria-current="page">Overview</a
|
<a href="./" aria-current="page">Overview</a
|
||||||
|
><a href="docs/screenshots.html">Screenshots</a
|
||||||
><a href="docs/">Documentation</a
|
><a href="docs/">Documentation</a
|
||||||
><a href="https://github.com/ferese-wm/ferese"
|
><a href="https://github.com/ferese-wm/ferese"
|
||||||
>GitHub <svg class="link-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M7 17 17 7M7 7h10v10"/></svg></a
|
>GitHub <svg class="link-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M7 17 17 7M7 7h10v10"/></svg></a
|
||||||
@@ -63,14 +64,14 @@
|
|||||||
</section>
|
</section>
|
||||||
<figure class="product-screenshot page-width">
|
<figure class="product-screenshot page-width">
|
||||||
<a
|
<a
|
||||||
href="assets/ferese-desktop.webp"
|
href="assets/screenshots/ferese-main-hero.png"
|
||||||
aria-label="View the full-resolution Ferese desktop screenshot"
|
aria-label="View the full-resolution Ferese desktop screenshot"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="assets/ferese-desktop.webp"
|
src="assets/screenshots/ferese-main-hero.png"
|
||||||
width="2880"
|
width="2880"
|
||||||
height="1800"
|
height="1800"
|
||||||
alt="Ferese Blue desktop with the default wallpaper, Settings, Control Center and clock widget"
|
alt="Ferese Blue desktop with Settings, Control Center and the default wallpaper"
|
||||||
fetchpriority="high"
|
fetchpriority="high"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||