Add area screenshots and preserve stacking on hover focus
This commit is contained in:
1 parent
8dc895448d
commit
5d6c610fec
9 files changed
+98
-15
No files matched your search
@@ -24,6 +24,7 @@ and native Settings app.
|
|||||||
- Built-in bar and control center
|
- Built-in bar and control center
|
||||||
- Native Settings app
|
- Native Settings app
|
||||||
- Desktop widgets
|
- Desktop widgets
|
||||||
|
- Area screenshots saved to disk and copied to the clipboard
|
||||||
- Themes, blur and gradient borders
|
- Themes, blur and gradient borders
|
||||||
- Multi-monitor support and fractional scaling
|
- Multi-monitor support and fractional scaling
|
||||||
- Live configuration reload
|
- Live configuration reload
|
||||||
@@ -50,6 +51,7 @@ Requirements (Fedora package names):
|
|||||||
- Default terminal: `foot` (or configure another terminal).
|
- Default terminal: `foot` (or configure another terminal).
|
||||||
- Optional: `zenity` for wallpaper browsing, `swayidle` for idle actions,
|
- Optional: `zenity` for wallpaper browsing, `swayidle` for idle actions,
|
||||||
and `swaylock` or `swaylock-effects` for locking.
|
and `swaylock` or `swaylock-effects` for locking.
|
||||||
|
- Screenshots: `grim`, `slurp`, and `wl-clipboard`.
|
||||||
|
|
||||||
For a login-screen session alongside your existing desktop:
|
For a login-screen session alongside your existing desktop:
|
||||||
|
|
||||||
@@ -77,8 +79,14 @@ Built-in defaults (your configuration can override them):
|
|||||||
| Super + Shift + F | True fullscreen |
|
| Super + Shift + F | True fullscreen |
|
||||||
| Super + Tab | Open workspace and window overview |
|
| Super + Tab | Open workspace and window overview |
|
||||||
| Super + M | Switch scrolling / tree layout |
|
| Super + M | Switch scrolling / tree layout |
|
||||||
|
| Super + Shift + S | Select a screenshot area |
|
||||||
| Super + Shift + E | Log out immediately—save your work first |
|
| Super + Shift + E | Log out immediately—save your work first |
|
||||||
|
|
||||||
|
In an installed session, screenshots are saved to `Pictures/Screenshots` and
|
||||||
|
copied to the clipboard. Press Escape to cancel the selection.
|
||||||
|
When focus follows the mouse is enabled, hovering changes keyboard focus without
|
||||||
|
raising the window; clicking raises it within its layer.
|
||||||
|
|
||||||
## Make it yours
|
## Make it yours
|
||||||
|
|
||||||
Open **Control Center → Settings**, or run `ferese-settings`.
|
Open **Control Center → Settings**, or run `ferese-settings`.
|
||||||
|
|||||||
@@ -895,7 +895,13 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn bindings(&self, input: &InputSettings) -> Result<Vec<Binding>, ConfigError> {
|
pub fn bindings(&self, input: &InputSettings) -> Result<Vec<Binding>, ConfigError> {
|
||||||
let mut commands = HashMap::from([("terminal".to_owned(), vec!["foot".to_owned()])]);
|
let mut commands = HashMap::from([
|
||||||
|
("terminal".to_owned(), vec!["foot".to_owned()]),
|
||||||
|
(
|
||||||
|
"screenshot".to_owned(),
|
||||||
|
vec!["ferese-screenshot".to_owned()],
|
||||||
|
),
|
||||||
|
]);
|
||||||
commands.extend(self.commands.clone());
|
commands.extend(self.commands.clone());
|
||||||
validate_commands(&commands)?;
|
validate_commands(&commands)?;
|
||||||
|
|
||||||
@@ -1398,6 +1404,7 @@ fn parse_workspace(argument: &str) -> Result<u8, ConfigError> {
|
|||||||
fn default_bindings() -> Vec<BindingConfig> {
|
fn default_bindings() -> Vec<BindingConfig> {
|
||||||
let mut bindings = vec![
|
let mut bindings = vec![
|
||||||
binding("Super+Enter", "spawn", Some("terminal")),
|
binding("Super+Enter", "spawn", Some("terminal")),
|
||||||
|
binding("Super+Shift+S", "spawn", Some("screenshot")),
|
||||||
binding("Super+Q", "close", None),
|
binding("Super+Q", "close", None),
|
||||||
binding("Super+F", "toggle-maximized", None),
|
binding("Super+F", "toggle-maximized", None),
|
||||||
binding("Super+Shift+F", "toggle-fullscreen", None),
|
binding("Super+Shift+F", "toggle-fullscreen", None),
|
||||||
@@ -2069,7 +2076,7 @@ mod tests {
|
|||||||
let input = config.input_settings().unwrap();
|
let input = config.input_settings().unwrap();
|
||||||
let bindings = config.bindings(&input).unwrap();
|
let bindings = config.bindings(&input).unwrap();
|
||||||
|
|
||||||
assert_eq!(bindings.len(), 42);
|
assert_eq!(bindings.len(), 43);
|
||||||
for (shift, action) in [
|
for (shift, action) in [
|
||||||
(false, BindingAction::ToggleMaximized),
|
(false, BindingAction::ToggleMaximized),
|
||||||
(true, BindingAction::ToggleFullscreen),
|
(true, BindingAction::ToggleFullscreen),
|
||||||
@@ -2089,6 +2096,12 @@ mod tests {
|
|||||||
&& binding.trigger == BindingTrigger::Keysym(keysyms::KEY_Return)
|
&& binding.trigger == BindingTrigger::Keysym(keysyms::KEY_Return)
|
||||||
&& binding.action == BindingAction::Spawn(vec!["foot".to_owned()])
|
&& binding.action == BindingAction::Spawn(vec!["foot".to_owned()])
|
||||||
}));
|
}));
|
||||||
|
assert!(bindings.iter().any(|binding| {
|
||||||
|
binding.modifiers.logo
|
||||||
|
&& binding.modifiers.shift
|
||||||
|
&& binding.trigger == BindingTrigger::Keysym(keysyms::KEY_s)
|
||||||
|
&& binding.action == BindingAction::Spawn(vec!["ferese-screenshot".to_owned()])
|
||||||
|
}));
|
||||||
assert!(bindings.iter().any(|binding| {
|
assert!(bindings.iter().any(|binding| {
|
||||||
binding.modifiers.logo
|
binding.modifiers.logo
|
||||||
&& binding.trigger == BindingTrigger::Keysym(keysyms::KEY_Tab)
|
&& binding.trigger == BindingTrigger::Keysym(keysyms::KEY_Tab)
|
||||||
@@ -2105,7 +2118,7 @@ mod tests {
|
|||||||
|
|
||||||
let input = replaced.input_settings().unwrap();
|
let input = replaced.input_settings().unwrap();
|
||||||
let bindings = replaced.bindings(&input).unwrap();
|
let bindings = replaced.bindings(&input).unwrap();
|
||||||
assert_eq!(bindings.len(), 42);
|
assert_eq!(bindings.len(), 43);
|
||||||
assert!(bindings.iter().any(|binding| {
|
assert!(bindings.iter().any(|binding| {
|
||||||
binding.action
|
binding.action
|
||||||
== BindingAction::Spawn(vec![
|
== BindingAction::Spawn(vec![
|
||||||
@@ -2117,7 +2130,7 @@ mod tests {
|
|||||||
|
|
||||||
let input = unbound.input_settings().unwrap();
|
let input = unbound.input_settings().unwrap();
|
||||||
let bindings = unbound.bindings(&input).unwrap();
|
let bindings = unbound.bindings(&input).unwrap();
|
||||||
assert_eq!(bindings.len(), 41);
|
assert_eq!(bindings.len(), 42);
|
||||||
assert!(
|
assert!(
|
||||||
!bindings
|
!bindings
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
+14
-6
@@ -217,7 +217,7 @@ impl Ferese {
|
|||||||
crate::dimming::DimAnimation::new(f64::from(opacity)),
|
crate::dimming::DimAnimation::new(f64::from(opacity)),
|
||||||
));
|
));
|
||||||
pointer.unset_grab(self, serial, event.time() as u32);
|
pointer.unset_grab(self, serial, event.time() as u32);
|
||||||
self.focus_window_at(pointer.current_location(), serial);
|
self.focus_window_at(pointer.current_location(), serial, true);
|
||||||
crate::backends::direct::render_all(self);
|
crate::backends::direct::render_all(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ impl Ferese {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
|
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
|
||||||
self.focus_window_at(pointer.current_location(), serial);
|
self.focus_window_at(pointer.current_location(), serial, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer.button(
|
pointer.button(
|
||||||
@@ -320,7 +320,7 @@ impl Ferese {
|
|||||||
let Some(location) = self.absolute_event_position(&event) else {
|
let Some(location) = self.absolute_event_position(&event) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
self.focus_window_at(location, SERIAL_COUNTER.next_serial());
|
self.focus_window_at(location, SERIAL_COUNTER.next_serial(), true);
|
||||||
let touch = self.seat.get_touch().expect("seat has touch capability");
|
let touch = self.seat.get_touch().expect("seat has touch capability");
|
||||||
let serial = SERIAL_COUNTER.next_serial();
|
let serial = SERIAL_COUNTER.next_serial();
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ impl Ferese {
|
|||||||
Some(event.position_transformed(geometry.size) + geometry.loc.to_f64())
|
Some(event.position_transformed(geometry.size) + geometry.loc.to_f64())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_window_at(&mut self, position: Point<f64, Logical>, serial: Serial) {
|
fn focus_window_at(&mut self, position: Point<f64, Logical>, serial: Serial, raise: bool) {
|
||||||
if self.session_lock.active {
|
if self.session_lock.active {
|
||||||
self.focus_output_at(position);
|
self.focus_output_at(position);
|
||||||
self.focus_lock_surface();
|
self.focus_lock_surface();
|
||||||
@@ -412,7 +412,15 @@ impl Ferese {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.focused_window = focused;
|
self.focused_window = focused;
|
||||||
self.raise_window(&window, true);
|
if raise {
|
||||||
|
self.raise_window(&window, true);
|
||||||
|
} else {
|
||||||
|
// Hover transfers keyboard focus without changing the persistent
|
||||||
|
// stack: an exposed window must not cover the floats above it.
|
||||||
|
for mapped in self.space.elements() {
|
||||||
|
mapped.set_activated(mapped == &window);
|
||||||
|
}
|
||||||
|
}
|
||||||
let surface = window
|
let surface = window
|
||||||
.toplevel()
|
.toplevel()
|
||||||
.expect("mapped window has a toplevel")
|
.expect("mapped window has a toplevel")
|
||||||
@@ -455,7 +463,7 @@ impl Ferese {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.focus_window_at(position, SERIAL_COUNTER.next_serial());
|
self.focus_window_at(position, SERIAL_COUNTER.next_serial(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clamp_pointer_position(&self, requested: Point<f64, Logical>) -> Point<f64, Logical> {
|
fn clamp_pointer_position(&self, requested: Point<f64, Logical>) -> Point<f64, Logical> {
|
||||||
|
|||||||
+10
-2
@@ -127,7 +127,7 @@ angle = 135.0
|
|||||||
|
|
||||||
| `[input]` key | Type | Default | Meaning |
|
| `[input]` key | Type | Default | Meaning |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `focus_follows_mouse` | boolean | `false` | Focus windows under the pointer |
|
| `focus_follows_mouse` | boolean | `false` | Focus windows under the pointer without raising them; click to raise |
|
||||||
| `xkb_layout` | nonempty string | `"us"` | XKB layout |
|
| `xkb_layout` | nonempty string | `"us"` | XKB layout |
|
||||||
| `xkb_variant` | string | `""` | XKB variant |
|
| `xkb_variant` | string | `""` | XKB variant |
|
||||||
| `xkb_options` | string array | `[]` | XKB options |
|
| `xkb_options` | string array | `[]` | XKB options |
|
||||||
@@ -178,7 +178,13 @@ Super+Shift+H/J/K/L move; Super+Ctrl+H/J/K/L resize; Super+1–9 workspace;
|
|||||||
Super+Shift+1–9 move to workspace; Super+R width cycle; Super+C center;
|
Super+Shift+1–9 move to workspace; Super+R width cycle; Super+C center;
|
||||||
Super+[/] consume/expel; Super+F maximize; Super+Shift+F fullscreen;
|
Super+[/] consume/expel; Super+F maximize; Super+Shift+F fullscreen;
|
||||||
Super+M layout; Super+Shift+Space floating; Super+Tab overview;
|
Super+M layout; Super+Shift+Space floating; Super+Tab overview;
|
||||||
Super+Shift+E immediate logout.
|
Super+Shift+S area screenshot; Super+Shift+E immediate logout.
|
||||||
|
|
||||||
|
The screenshot shortcut runs `ferese-screenshot`: drag to select an area, or
|
||||||
|
press Escape to cancel. Captures are saved under your Pictures directory in
|
||||||
|
`Screenshots` and copied to the clipboard as PNG images. It requires `grim`,
|
||||||
|
`slurp`, and `wl-copy` (from `wl-clipboard`). Override the `screenshot` command
|
||||||
|
to use another screenshot tool.
|
||||||
|
|
||||||
## Window rules
|
## Window rules
|
||||||
|
|
||||||
@@ -273,5 +279,7 @@ ending the session from another TTY.
|
|||||||
These are launch-time environment switches, not TOML keys. Enable only for
|
These are launch-time environment switches, not TOML keys. Enable only for
|
||||||
trusted clients: `FERESE_ENABLE_INPUT_METHOD=1`,
|
trusted clients: `FERESE_ENABLE_INPUT_METHOD=1`,
|
||||||
`FERESE_ENABLE_SHORTCUT_INHIBIT=1`, `FERESE_ENABLE_SCREENCOPY=1`.
|
`FERESE_ENABLE_SHORTCUT_INHIBIT=1`, `FERESE_ENABLE_SCREENCOPY=1`.
|
||||||
|
The installed session launcher enables screencopy for screenshots unless
|
||||||
|
`FERESE_ENABLE_SCREENCOPY=0` is explicitly set in its environment.
|
||||||
Text input is available by default; Ctrl+Alt+Escape releases an active shortcut
|
Text input is available by default; Ctrl+Alt+Escape releases an active shortcut
|
||||||
inhibitor. Use `feresectl --help` for runtime control commands.
|
inhibitor. Use `feresectl --help` for runtime control commands.
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
On Fedora with SDDM, install a Rust toolchain (1.93 or newer), native build
|
On Fedora with SDDM, install a Rust toolchain (1.93 or newer), native build
|
||||||
dependencies, `desktop-file-utils`, D-Bus and `foot`. Wallpaper browsing also
|
dependencies, `desktop-file-utils`, D-Bus and `foot`. Wallpaper browsing also
|
||||||
needs `zenity`; locking needs swaylock or swaylock-effects.
|
needs `zenity`; locking needs swaylock or swaylock-effects.
|
||||||
|
Area screenshots need `grim`, `slurp`, and `wl-clipboard`.
|
||||||
|
|
||||||
From the checkout, run as your normal user:
|
From the checkout, run as your normal user:
|
||||||
|
|
||||||
@@ -35,6 +36,11 @@ its DRM backend inside an active graphical session.
|
|||||||
Logs are stored in `${XDG_STATE_HOME:-~/.local/state}/ferese/`. Keep an existing
|
Logs are stored in `${XDG_STATE_HOME:-~/.local/state}/ferese/`. Keep an existing
|
||||||
desktop available while testing scaling, monitor hotplug, suspend and locking.
|
desktop available while testing scaling, monitor hotplug, suspend and locking.
|
||||||
|
|
||||||
|
The session launcher enables the screencopy protocol for screenshot tools.
|
||||||
|
Set `FERESE_ENABLE_SCREENCOPY=0` in the session environment to disable it.
|
||||||
|
When enabled, Wayland clients can capture the unlocked desktop. Capture remains
|
||||||
|
blocked while the session is locked. Launcher changes take effect at next login.
|
||||||
|
|
||||||
## Logout and recovery
|
## Logout and recovery
|
||||||
|
|
||||||
Save your work before **Super+Shift+E** or `feresectl exit`: logout is immediate.
|
Save your work before **Super+Shift+E** or `feresectl exit`: logout is immediate.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Unspecified monitors use automatic placement and preferred modes.
|
# Unspecified monitors use automatic placement and preferred modes.
|
||||||
[commands]
|
[commands]
|
||||||
terminal = ["foot"]
|
terminal = ["foot"]
|
||||||
|
screenshot = ["ferese-screenshot"]
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
xkb_layout = "us"
|
xkb_layout = "us"
|
||||||
@@ -17,7 +18,7 @@ opacity = 0.95
|
|||||||
text_primary = "#F0F3FA"
|
text_primary = "#F0F3FA"
|
||||||
text_muted = "#AAB4C7"
|
text_muted = "#AAB4C7"
|
||||||
|
|
||||||
# Super+Enter opens Foot. Super+Shift+E logs out.
|
# Super+Enter opens Foot. Super+Shift+S selects a screenshot. Super+Shift+E logs out.
|
||||||
# See README.md for monitor profiles and additional bindings.
|
# See README.md for monitor profiles and additional bindings.
|
||||||
|
|
||||||
[[window_rules]]
|
[[window_rules]]
|
||||||
|
|||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Select an area, save it in Pictures/Screenshots, and copy it to the clipboard.
|
||||||
|
set -euo pipefail
|
||||||
|
umask 077
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "ferese-screenshot: $*" >&2
|
||||||
|
if command -v notify-send >/dev/null; then
|
||||||
|
notify-send --app-name=Ferese --urgency=critical 'Screenshot failed' "$*" || true
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for tool in slurp grim wl-copy flock; do
|
||||||
|
command -v "$tool" >/dev/null || fail "Required command not found: $tool"
|
||||||
|
done
|
||||||
|
: "${XDG_RUNTIME_DIR:?A Wayland login session is required}"
|
||||||
|
exec 9>"$XDG_RUNTIME_DIR/ferese-screenshot.lock"
|
||||||
|
flock -n 9 || exit 0
|
||||||
|
|
||||||
|
# Escape cancels without creating a file or changing the clipboard.
|
||||||
|
geometry=$(slurp) || exit 0
|
||||||
|
[[ -n $geometry ]] || exit 0
|
||||||
|
pictures=$(xdg-user-dir PICTURES 2>/dev/null) || pictures="$HOME/Pictures"
|
||||||
|
directory=${pictures:-$HOME/Pictures}/Screenshots
|
||||||
|
mkdir -p -- "$directory" || fail 'Could not create the screenshot directory.'
|
||||||
|
file=$(mktemp "$directory/Screenshot-$(date +%Y-%m-%d_%H-%M-%S)-XXXXXX.png") || fail 'Could not create the screenshot file.'
|
||||||
|
trap 'rm -f -- "$file"' EXIT
|
||||||
|
grim -g "$geometry" "$file" || fail 'Could not capture the screen. Log back into Ferese after enabling screen capture.'
|
||||||
|
trap - EXIT
|
||||||
|
# Do not pass the selector lock to wl-copy's background clipboard process.
|
||||||
|
wl-copy --type image/png <"$file" 9>&- || fail "Saved to $file, but could not copy to the clipboard."
|
||||||
|
if command -v notify-send >/dev/null; then
|
||||||
|
notify-send --app-name=Ferese 'Screenshot saved and copied' "$file" || true
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$file"
|
||||||
@@ -26,6 +26,8 @@ export XDG_SESSION_DESKTOP=ferese
|
|||||||
export XDG_SESSION_TYPE=wayland
|
export XDG_SESSION_TYPE=wayland
|
||||||
export MOZ_ENABLE_WAYLAND=1
|
export MOZ_ENABLE_WAYLAND=1
|
||||||
export QT_QPA_PLATFORM=wayland
|
export QT_QPA_PLATFORM=wayland
|
||||||
|
# Used by the area screenshot shortcut; explicitly set 0 to disable capture.
|
||||||
|
export FERESE_ENABLE_SCREENCOPY=${FERESE_ENABLE_SCREENCOPY:-1}
|
||||||
export PATH="$release_dir:$PATH"
|
export PATH="$release_dir:$PATH"
|
||||||
unset WAYLAND_SOCKET
|
unset WAYLAND_SOCKET
|
||||||
if [[ $backend == drm ]]; then
|
if [[ $backend == drm ]]; then
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ session_entry=/usr/share/wayland-sessions/ferese.desktop
|
|||||||
[[ ! -e $release_dir ]] || { echo "Release already exists: $release_dir" >&2; exit 1; }
|
[[ ! -e $release_dir ]] || { echo "Release already exists: $release_dir" >&2; exit 1; }
|
||||||
|
|
||||||
# Refuse to overwrite unrelated installations.
|
# Refuse to overwrite unrelated installations.
|
||||||
for name in ferese ferese-shell ferese-settings feresectl ferese-session ferese-lock; do
|
for name in ferese ferese-shell ferese-settings feresectl ferese-session ferese-lock ferese-screenshot; do
|
||||||
link=/usr/local/bin/$name
|
link=/usr/local/bin/$name
|
||||||
if [[ -e $link || -L $link ]]; then
|
if [[ -e $link || -L $link ]]; then
|
||||||
[[ -L $link && $(readlink -- "$link") == "$install_root/current/$name" ]] || {
|
[[ -L $link && $(readlink -- "$link") == "$install_root/current/$name" ]] || {
|
||||||
@@ -54,6 +54,7 @@ for name in ferese ferese-shell ferese-settings feresectl; do
|
|||||||
done
|
done
|
||||||
install -m 0755 -- "$repo_dir/packaging/ferese-session" "$release_dir/ferese-session"
|
install -m 0755 -- "$repo_dir/packaging/ferese-session" "$release_dir/ferese-session"
|
||||||
install -m 0755 -- "$repo_dir/packaging/ferese-lock" "$release_dir/ferese-lock"
|
install -m 0755 -- "$repo_dir/packaging/ferese-lock" "$release_dir/ferese-lock"
|
||||||
|
install -m 0755 -- "$repo_dir/packaging/ferese-screenshot" "$release_dir/ferese-screenshot"
|
||||||
install -m 0644 -- "$repo_dir/packaging/config.toml" "$release_dir/config.example.toml"
|
install -m 0644 -- "$repo_dir/packaging/config.toml" "$release_dir/config.example.toml"
|
||||||
|
|
||||||
if [[ -L $install_root/current ]]; then
|
if [[ -L $install_root/current ]]; then
|
||||||
@@ -61,7 +62,7 @@ if [[ -L $install_root/current ]]; then
|
|||||||
fi
|
fi
|
||||||
ln -s -- "releases/$release_id" "$install_root/current-$release_id"
|
ln -s -- "releases/$release_id" "$install_root/current-$release_id"
|
||||||
mv -Tf -- "$install_root/current-$release_id" "$install_root/current"
|
mv -Tf -- "$install_root/current-$release_id" "$install_root/current"
|
||||||
for name in ferese ferese-shell ferese-settings feresectl ferese-session ferese-lock; do
|
for name in ferese ferese-shell ferese-settings feresectl ferese-session ferese-lock ferese-screenshot; do
|
||||||
ln -sfn -- "$install_root/current/$name" "/usr/local/bin/$name"
|
ln -sfn -- "$install_root/current/$name" "/usr/local/bin/$name"
|
||||||
done
|
done
|
||||||
install -m 0644 -- "$repo_dir/packaging/ferese.desktop" "$session_entry"
|
install -m 0644 -- "$repo_dir/packaging/ferese.desktop" "$session_entry"
|
||||||
|
|||||||
Reference in new issue
Block a user