Use Rust 1.95 consistently throughout the workspace
This commit is contained in:
1 parent
50c5f94007
commit
bfec60848d
12 files changed
+146
-110
No files matched your search
+1
-1
@@ -21,7 +21,7 @@ resolver = "3"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
rust-version = "1.98"
|
rust-version = "1.95"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
bitflags = "2.9.4"
|
bitflags = "2.9.4"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name = "ferese-config"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.95"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jiff.workspace = true
|
jiff.workspace = true
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name = "ferese-theme"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.95"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
jiff.workspace = true
|
jiff.workspace = true
|
||||||
|
|||||||
+74
-46
@@ -9,14 +9,14 @@ For a full session, you’ll need a Wayland-capable graphics driver and a local
|
|||||||
session with seat access through logind or seatd. A nested preview runs inside your
|
session with seat access through logind or seatd. A nested preview runs inside your
|
||||||
existing Wayland desktop.
|
existing Wayland desktop.
|
||||||
|
|
||||||
To build Ferese, install **Rust 1.95 or newer**, a C/C++ toolchain, CMake, pkg-config
|
To build Ferese, install **Rust 1.95.0**, a C/C++ toolchain, CMake, pkg-config,
|
||||||
and the libraries below. The installer builds the Ferese components once those system
|
Python 3.9 or newer, and the libraries below. Once those packages are installed,
|
||||||
packages are in place.
|
the installer builds the Ferese components.
|
||||||
|
|
||||||
### Fedora
|
### Fedora
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo dnf install git curl gcc gcc-c++ make cmake pkgconf-pkg-config \
|
sudo dnf install python3 git curl gcc gcc-c++ make cmake pkgconf-pkg-config \
|
||||||
wayland-devel libxkbcommon-devel libinput-devel systemd-devel libseat-devel \
|
wayland-devel libxkbcommon-devel libinput-devel systemd-devel libseat-devel \
|
||||||
mesa-libgbm-devel mesa-libEGL-devel libdrm-devel fontconfig-devel \
|
mesa-libgbm-devel mesa-libEGL-devel libdrm-devel fontconfig-devel \
|
||||||
freetype-devel expat-devel dbus-daemon dbus-tools desktop-file-utils foot pam \
|
freetype-devel expat-devel dbus-daemon dbus-tools desktop-file-utils foot pam \
|
||||||
@@ -28,7 +28,7 @@ sudo dnf install git curl gcc gcc-c++ make cmake pkgconf-pkg-config \
|
|||||||
### Arch Linux
|
### Arch Linux
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo pacman -S --needed base-devel git curl cmake pkgconf wayland libxkbcommon \
|
sudo pacman -S --needed python base-devel git curl cmake pkgconf wayland libxkbcommon \
|
||||||
libinput systemd seatd mesa libdrm fontconfig freetype2 expat dbus \
|
libinput systemd seatd mesa libdrm fontconfig freetype2 expat dbus \
|
||||||
desktop-file-utils foot pam clang pipewire libpipewire wireplumber polkit \
|
desktop-file-utils foot pam clang pipewire libpipewire wireplumber polkit \
|
||||||
xdg-desktop-portal xdg-desktop-portal-gtk \
|
xdg-desktop-portal xdg-desktop-portal-gtk \
|
||||||
@@ -39,7 +39,7 @@ sudo pacman -S --needed base-devel git curl cmake pkgconf wayland libxkbcommon \
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install build-essential git curl cmake pkg-config libwayland-dev \
|
sudo apt install python3 build-essential git curl cmake pkg-config libwayland-dev \
|
||||||
libxkbcommon-dev libinput-dev libudev-dev libseat-dev libgbm-dev libegl-dev \
|
libxkbcommon-dev libinput-dev libudev-dev libseat-dev libgbm-dev libegl-dev \
|
||||||
libdrm-dev libfontconfig1-dev libfreetype-dev libexpat1-dev dbus-bin \
|
libdrm-dev libfontconfig1-dev libfreetype-dev libexpat1-dev dbus-bin \
|
||||||
dbus-user-session desktop-file-utils foot libpam0g clang libclang-dev \
|
dbus-user-session desktop-file-utils foot libpam0g clang libclang-dev \
|
||||||
@@ -56,22 +56,17 @@ libraries.
|
|||||||
|
|
||||||
### Rust toolchain
|
### Rust toolchain
|
||||||
|
|
||||||
Check your toolchain:
|
Install Rust through [rustup.rs](https://rustup.rs/). The checkout's
|
||||||
|
`rust-toolchain.toml` selects the required compiler and rustfmt automatically.
|
||||||
|
All workspace crates inherit their minimum Rust version from the root `Cargo.toml`.
|
||||||
|
|
||||||
|
From inside the checkout, verify the selected toolchain:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rustc --version
|
rustup show active-toolchain
|
||||||
cargo --version
|
cargo --version
|
||||||
```
|
```
|
||||||
|
|
||||||
If you don’t have Rust yet, follow the instructions at [rustup.rs](https://rustup.rs/)
|
|
||||||
and reopen your terminal, then select the required toolchain for this checkout after
|
|
||||||
cloning:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rustup toolchain install 1.95.0
|
|
||||||
rustup override set 1.95.0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build and install
|
## Build and install
|
||||||
|
|
||||||
Run these commands as your normal user:
|
Run these commands as your normal user:
|
||||||
@@ -233,11 +228,22 @@ git pull --ff-only
|
|||||||
Log out and back in to use the new release. A running session keeps its existing
|
Log out and back in to use the new release. A running session keeps its existing
|
||||||
processes and release paths until it restarts.
|
processes and release paths until it restarts.
|
||||||
|
|
||||||
Each release records the portal configuration it ships so later upgrades can identify
|
The installer prepares a complete release bundle before asking for administrator
|
||||||
it. Installation stops if it encounters modified or untracked administrator files.
|
access. Its manifest records the source commit, dirty-tree status, build features,
|
||||||
To replace Ferese portal configuration from an earlier development install, build first
|
file modes and SHA-256 checksums. The installer verifies the bundle again after
|
||||||
and run `./scripts/install.sh --skip-build --replace-portal-config`, which backs up the
|
copying it into a root-owned staging directory. These checks detect changed or incomplete
|
||||||
existing files in the new release’s `portal-config.previous/` directory.
|
bundles; they are not a publisher signature.
|
||||||
|
|
||||||
|
The installer reports system installation and user setup separately. If user setup
|
||||||
|
fails after installation, retry it as your normal user:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 scripts/installer/install.py user-setup
|
||||||
|
```
|
||||||
|
|
||||||
|
This backs up the exact old development portal override when present and reloads
|
||||||
|
user systemd configuration. It preserves custom overrides and does not restart the
|
||||||
|
running desktop or portal.
|
||||||
|
|
||||||
Installer options:
|
Installer options:
|
||||||
|
|
||||||
@@ -245,17 +251,39 @@ Installer options:
|
|||||||
./scripts/install.sh --dry-run
|
./scripts/install.sh --dry-run
|
||||||
./scripts/install.sh --offline --release-id my-build
|
./scripts/install.sh --offline --release-id my-build
|
||||||
./scripts/install.sh --resize-metrics
|
./scripts/install.sh --resize-metrics
|
||||||
./scripts/install.sh --skip-build
|
./scripts/install.sh --bundle-only ./target/bundles/my-build --release-id my-build
|
||||||
|
./scripts/install.sh --bundle ./target/bundles/my-build
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `--dry-run` to see the planned commands, `--offline` when dependencies are already
|
`--bundle` replaces `--skip-build` and installs a complete bundle instead of loose
|
||||||
cached, or `--skip-build` after building every component from the revision you want to
|
files in `target/release/`. Build options cannot be combined with `--bundle`.
|
||||||
install. The latter uses binaries already in `target/release/`, and
|
The front-end dry run prints commands. To inspect the filesystem changes planned
|
||||||
`./scripts/install.sh --help` lists all available options.
|
for an existing bundle, run:
|
||||||
|
|
||||||
Use `--resize-metrics` to enable resize-barrier counters and duration histograms in
|
```sh
|
||||||
the release build. Ferese prints the measurements to its session log on normal exit.
|
./scripts/install-session.sh install ./target/bundles/my-build --dry-run
|
||||||
This option requires building and cannot be combined with `--skip-build`.
|
```
|
||||||
|
|
||||||
|
Modified administrator files stop installation before activation. To explicitly
|
||||||
|
replace Ferese's portal definition and preferences, use
|
||||||
|
`./scripts/install.sh --bundle ./target/bundles/my-build --replace-portal-config`.
|
||||||
|
Transaction backups live under `/usr/local/lib/ferese/transactions/`; each
|
||||||
|
`journal.json` maps the numbered backups to their original paths. Existing PAM
|
||||||
|
policies are preserved.
|
||||||
|
|
||||||
|
A lock prevents concurrent installations. The installer records recovery data
|
||||||
|
before changing system files, then updates integration files and switches `current`
|
||||||
|
last. If an operation fails, it restores the previous files. After an interruption,
|
||||||
|
recovery runs on the next install, or you can run it yourself:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ./scripts/install-session.sh recover
|
||||||
|
```
|
||||||
|
|
||||||
|
Recovery stops if a recorded file was subsequently changed by an administrator.
|
||||||
|
Inspect the conflict and the retained `.transaction/journal.json` before restoring
|
||||||
|
the recorded old or new contents and retrying. Multi-file installation is
|
||||||
|
recoverable, not a single atomic filesystem operation.
|
||||||
|
|
||||||
## Logout and recovery
|
## Logout and recovery
|
||||||
|
|
||||||
@@ -274,30 +302,30 @@ then choose another desktop at the next login.
|
|||||||
|
|
||||||
### Roll back a release
|
### Roll back a release
|
||||||
|
|
||||||
While Ferese is stopped, inspect the retained releases:
|
Stop the Ferese session, then run from the checkout:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
readlink /usr/local/lib/ferese/current
|
sudo ./scripts/install-session.sh rollback
|
||||||
readlink /usr/local/lib/ferese/previous
|
# Or select a retained bundle by its release ID:
|
||||||
ls /usr/local/lib/ferese/releases/
|
sudo ./scripts/install-session.sh rollback my-build
|
||||||
```
|
```
|
||||||
|
|
||||||
If `previous` exists and points to the release you want, switch back:
|
Rollback restores both the binaries and that release's session, systemd, portal
|
||||||
|
and icon files. It refuses to overwrite modified administrator files and preserves
|
||||||
|
existing PAM policy. Log in again to use the selected release. After rollback,
|
||||||
|
`previous` points to the release you just left.
|
||||||
|
|
||||||
|
Releases installed before bundle manifests can be upgraded using their retained
|
||||||
|
ownership records, but cannot be selected by this rollback command. Keep the old
|
||||||
|
release directory until you have validated the first bundled installation.
|
||||||
|
|
||||||
|
To remove managed commands and desktop integration while retaining release bundles,
|
||||||
|
transaction backups, PAM policy and user configuration:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo sh -eu -c '
|
sudo ./scripts/install-session.sh uninstall
|
||||||
cd /usr/local/lib/ferese
|
|
||||||
previous_release=$(readlink previous)
|
|
||||||
test -x "$previous_release/ferese-session"
|
|
||||||
ln -sfn -- "$previous_release" current-rollback
|
|
||||||
mv -Tf -- current-rollback current
|
|
||||||
'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Log in again to use the selected binaries, with your config and PAM policy still in
|
|
||||||
place. If you also need to recover a configuration edit, Settings keeps a backup when
|
|
||||||
saving, as described in [Saving and validation](configuration.md#saving-and-validation).
|
|
||||||
|
|
||||||
### Remove the login option
|
### Remove the login option
|
||||||
|
|
||||||
To hide Ferese from login managers while keeping its releases and your config:
|
To hide Ferese from login managers while keeping its releases and your config:
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ name = "xdg-desktop-portal-ferese"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.95"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "xdg-desktop-portal-ferese"
|
name = "xdg-desktop-portal-ferese"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
[toolchain]
|
||||||
|
channel = "1.95.0"
|
||||||
|
profile = "minimal"
|
||||||
|
components = ["rustfmt"]
|
||||||
@@ -1,4 +1,2 @@
|
|||||||
max_width = 120
|
max_width = 120
|
||||||
imports_granularity = "Module"
|
|
||||||
group_imports = "StdExternalCrate"
|
|
||||||
reorder_imports = true
|
reorder_imports = true
|
||||||
@@ -3,7 +3,7 @@ name = "ferese-lock"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.95"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(box_patterns)]
|
|
||||||
|
|
||||||
mod appearance;
|
mod appearance;
|
||||||
mod auth;
|
mod auth;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
@@ -264,9 +262,7 @@ impl cosmic::Application for Locker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Event(box Event::Keyboard(iced::keyboard::Event::ModifiersChanged(modifiers))) => {
|
Message::Event(event) => return self.handle_event(*event),
|
||||||
self.caps_lock = modifiers.contains(iced::keyboard::Modifiers::CAPS_LOCK);
|
|
||||||
}
|
|
||||||
Message::Tick => {
|
Message::Tick => {
|
||||||
let now = jiff::Zoned::now();
|
let now = jiff::Zoned::now();
|
||||||
self.clock = now.strftime(self.appearance.clock_format()).to_string();
|
self.clock = now.strftime(self.appearance.clock_format()).to_string();
|
||||||
@@ -315,56 +311,8 @@ impl cosmic::Application for Locker {
|
|||||||
self.status = "Password not accepted. Try again.";
|
self.status = "Password not accepted. Try again.";
|
||||||
return focus();
|
return focus();
|
||||||
}
|
}
|
||||||
Message::Event(box Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::Output(
|
|
||||||
event,
|
|
||||||
output,
|
|
||||||
)))) if !self.preview => {
|
|
||||||
if matches!(event, wayland::OutputEvent::Removed) {
|
|
||||||
if let Some(id) = self.outputs.remove(&output) {
|
|
||||||
return session_lock::destroy_lock_surface(id);
|
|
||||||
}
|
|
||||||
} else if !self.outputs.contains_key(&output) {
|
|
||||||
let id = window::Id::unique();
|
|
||||||
self.outputs.insert(output.clone(), id);
|
|
||||||
if self.started {
|
|
||||||
return session_lock::get_lock_surface(id, output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::Event(box Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::SessionLock(
|
|
||||||
event,
|
|
||||||
)))) if !self.preview => match event {
|
|
||||||
wayland::SessionLockEvent::Locked => {
|
|
||||||
if self.confirmation.observe() {
|
|
||||||
use std::io::Write;
|
|
||||||
if std::env::var_os("FERESE_LOCK_READY").is_some() {
|
|
||||||
let _ = writeln!(std::io::stdout().lock(), "FERESE_LOCKED");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !self.started {
|
|
||||||
self.started = true;
|
|
||||||
return Task::batch(
|
|
||||||
self.outputs
|
|
||||||
.iter()
|
|
||||||
.map(|(output, id)| session_lock::get_lock_surface(*id, output.clone())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wayland::SessionLockEvent::Focused(..) => return focus(),
|
|
||||||
wayland::SessionLockEvent::Unlocked if self.state == AuthState::Unlocking => {
|
|
||||||
return iced::exit();
|
|
||||||
}
|
|
||||||
wayland::SessionLockEvent::Finished | wayland::SessionLockEvent::NotSupported => {
|
|
||||||
eprintln!("ferese-lock: compositor refused the lock");
|
|
||||||
return iced::exit();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
Message::Event(box Event::Window(window::Event::Opened { .. })) => {
|
|
||||||
return focus();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +335,64 @@ fn focus() -> Task<Message> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Locker {
|
impl Locker {
|
||||||
|
fn handle_event(&mut self, event: Event) -> Task<Message> {
|
||||||
|
match event {
|
||||||
|
Event::Keyboard(iced::keyboard::Event::ModifiersChanged(modifiers)) => {
|
||||||
|
self.caps_lock = modifiers.contains(iced::keyboard::Modifiers::CAPS_LOCK);
|
||||||
|
}
|
||||||
|
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::Output(event, output)))
|
||||||
|
if !self.preview =>
|
||||||
|
{
|
||||||
|
if matches!(event, wayland::OutputEvent::Removed) {
|
||||||
|
if let Some(id) = self.outputs.remove(&output) {
|
||||||
|
return session_lock::destroy_lock_surface(id);
|
||||||
|
}
|
||||||
|
} else if !self.outputs.contains_key(&output) {
|
||||||
|
let id = window::Id::unique();
|
||||||
|
self.outputs.insert(output.clone(), id);
|
||||||
|
if self.started {
|
||||||
|
return session_lock::get_lock_surface(id, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::PlatformSpecific(PlatformSpecific::Wayland(wayland::Event::SessionLock(event))) if !self.preview => {
|
||||||
|
match event {
|
||||||
|
wayland::SessionLockEvent::Locked => {
|
||||||
|
if self.confirmation.observe() {
|
||||||
|
use std::io::Write;
|
||||||
|
if std::env::var_os("FERESE_LOCK_READY").is_some() {
|
||||||
|
let _ = writeln!(std::io::stdout().lock(), "FERESE_LOCKED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !self.started {
|
||||||
|
self.started = true;
|
||||||
|
return Task::batch(
|
||||||
|
self.outputs
|
||||||
|
.iter()
|
||||||
|
.map(|(output, id)| session_lock::get_lock_surface(*id, output.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wayland::SessionLockEvent::Focused(..) => return focus(),
|
||||||
|
wayland::SessionLockEvent::Unlocked if self.state == AuthState::Unlocking => {
|
||||||
|
return iced::exit();
|
||||||
|
}
|
||||||
|
wayland::SessionLockEvent::Finished | wayland::SessionLockEvent::NotSupported => {
|
||||||
|
eprintln!("ferese-lock: compositor refused the lock");
|
||||||
|
return iced::exit();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::Window(window::Event::Opened { .. }) => {
|
||||||
|
return focus();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
fn label<'a>(
|
fn label<'a>(
|
||||||
&self,
|
&self,
|
||||||
label: impl Into<std::borrow::Cow<'a, str>> + 'a,
|
label: impl Into<std::borrow::Cow<'a, str>> + 'a,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name = "ferese-polkit-agent"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.95"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-config = { path = "../../crates/ferese-config" }
|
ferese-config = { path = "../../crates/ferese-config" }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name = "ferese-settings"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.93"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-theme = { path = "../../crates/ferese-theme" }
|
ferese-theme = { path = "../../crates/ferese-theme" }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name = "ferese-shell"
|
|||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version = "1.93"
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||||
|
|||||||
Reference in new issue
Block a user