Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 67 additions & 17 deletions crates/agility-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1695,23 +1695,48 @@ fn spawn_detached_exec(exec_cmd: &str, in_terminal: bool) -> bool {
return false;
}

let mut cmd = Command::new("sh");
if in_terminal {
let term = if is_command_available("alacritty") {
"alacritty -e"
} else if is_command_available("kitty") {
"kitty -e"
} else if is_command_available("foot") {
"foot -e"
} else if is_command_available("xfce4-terminal") {
"xfce4-terminal -e"
let has_systemd_run = is_command_available("systemd-run");

let mut cmd = if has_systemd_run {
let mut c = Command::new("systemd-run");
c.args(["--user", "--scope", "--slice=app.slice", "-q", "--"]);
if in_terminal {
let term = if is_command_available("alacritty") {
"alacritty"
} else if is_command_available("kitty") {
"kitty"
} else if is_command_available("foot") {
"foot"
} else if is_command_available("xfce4-terminal") {
"xfce4-terminal"
} else {
"xterm"
};
c.args([term, "-e", "sh", "-c", &cleaned]);
} else {
"xterm -e"
};
cmd.args(["-c", &format!("{term} {cleaned} &")]);
c.args(["sh", "-c", &cleaned]);
}
c
} else {
cmd.args(["-c", &format!("{cleaned} &")]);
}
let mut c = Command::new("sh");
if in_terminal {
let term = if is_command_available("alacritty") {
"alacritty -e"
} else if is_command_available("kitty") {
"kitty -e"
} else if is_command_available("foot") {
"foot -e"
} else if is_command_available("xfce4-terminal") {
"xfce4-terminal -e"
} else {
"xterm -e"
};
c.args(["-c", &format!("{term} {cleaned} &")]);
} else {
c.args(["-c", &format!("{cleaned} &")]);
}
c
};

#[cfg(unix)]
{
Expand Down Expand Up @@ -1756,10 +1781,14 @@ fn resolve_cli_wallpaper(path_str: &str) -> Option<std::path::PathBuf> {
let mut search_dirs = Vec::new();

if let Ok(home) = std::env::var("HOME") {
search_dirs.push(Path::new(&home).join(".local/share/agility-shell/wallpapers"));
search_dirs.push(Path::new(&home).join(".config/agility-shell/wallpapers"));
search_dirs.push(Path::new(&home).join("Pictures/Wallpapers"));
search_dirs.push(Path::new(&home).join("Pictures"));
}
if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
search_dirs.push(Path::new(&data_home).join("agility-shell/wallpapers"));
}
search_dirs.push(Path::new("/usr/share/agility-shell/wallpapers").to_path_buf());
search_dirs.push(Path::new("wallpapers").to_path_buf());

Expand All @@ -1776,10 +1805,14 @@ fn resolve_cli_wallpaper(path_str: &str) -> Option<std::path::PathBuf> {
fn list_cli_wallpapers() -> Vec<std::path::PathBuf> {
let mut search_dirs = Vec::new();
if let Ok(home) = std::env::var("HOME") {
search_dirs.push(Path::new(&home).join(".local/share/agility-shell/wallpapers"));
search_dirs.push(Path::new(&home).join(".config/agility-shell/wallpapers"));
search_dirs.push(Path::new(&home).join("Pictures/Wallpapers"));
search_dirs.push(Path::new(&home).join("Pictures"));
}
if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
search_dirs.push(Path::new(&data_home).join("agility-shell/wallpapers"));
}
search_dirs.push(Path::new("/usr/share/agility-shell/wallpapers").to_path_buf());
search_dirs.push(Path::new("wallpapers").to_path_buf());

Expand Down Expand Up @@ -1984,10 +2017,27 @@ async fn apply_cli_wallpaper(
let _ = Command::new("awww-daemon").spawn();
}

// Dispatch awww img
// Dispatch awww img with ultra-fast bilinear filter and 60fps step
if is_command_available("awww") {
let mut cmd = Command::new("awww");
cmd.args(["img", &abs_str, "--resize", "crop"]);
let t_type = transition.unwrap_or("grow");
let dur_str = format!("{:.2}", duration.unwrap_or(0.2));
cmd.args([
"img",
&abs_str,
"--resize",
"crop",
"--filter",
"Bilinear",
"--transition-type",
t_type,
"--transition-duration",
&dur_str,
"--transition-step",
"180",
"--transition-fps",
"60",
]);
let _ = cmd.spawn();
}

Expand Down
67 changes: 51 additions & 16 deletions crates/agilityd/src/modules/launcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,28 +338,63 @@ impl LauncherService {
return false;
}

let mut cmd = Command::new("sh");
if in_terminal {
// Pick terminal emulator or fallback to standard x-terminal-emulator
let term = if which("alacritty") {
"alacritty -e"
} else if which("kitty") {
"kitty -e"
} else if which("foot") {
"foot -e"
} else if which("xfce4-terminal") {
"xfce4-terminal -e"
let has_systemd_run = which("systemd-run");

let mut cmd = if has_systemd_run {
let mut c = Command::new("systemd-run");
c.args(["--user", "--scope", "--slice=app.slice", "-q", "--"]);
if in_terminal {
let term = if which("alacritty") {
"alacritty"
} else if which("kitty") {
"kitty"
} else if which("foot") {
"foot"
} else if which("xfce4-terminal") {
"xfce4-terminal"
} else {
"xterm"
};
c.args([term, "-e", "sh", "-c", &cleaned]);
} else {
"xterm -e"
};
cmd.args(["-c", &format!("{term} {cleaned} &")]);
c.args(["sh", "-c", &cleaned]);
}
c
} else {
cmd.args(["-c", &format!("{cleaned} &")]);
let mut c = Command::new("sh");
if in_terminal {
let term = if which("alacritty") {
"alacritty -e"
} else if which("kitty") {
"kitty -e"
} else if which("foot") {
"foot -e"
} else if which("xfce4-terminal") {
"xfce4-terminal -e"
} else {
"xterm -e"
};
c.args(["-c", &format!("{term} {cleaned} &")]);
} else {
c.args(["-c", &format!("{cleaned} &")]);
}
c
};

#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
unsafe {
cmd.pre_exec(|| {
libc::setsid();
Ok(())
});
}
}

match cmd.spawn() {
Ok(_) => {
info!("Successfully launched application: {cleaned}");
info!("Successfully launched application in isolated app.slice: {cleaned}");
true
}
Err(e) => {
Expand Down
22 changes: 21 additions & 1 deletion crates/agilityd/src/modules/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ pub fn resolve_wallpaper_path(path_str: &str) -> Option<PathBuf> {
let mut search_dirs = Vec::new();

if let Ok(home) = std::env::var("HOME") {
search_dirs.push(PathBuf::from(&home).join(".local/share/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from(&home).join(".config/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from(&home).join("Pictures/Wallpapers"));
search_dirs.push(PathBuf::from(&home).join("Pictures"));
}
if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
search_dirs.push(PathBuf::from(&data_home).join("agility-shell/wallpapers"));
}
search_dirs.push(PathBuf::from("/usr/share/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from("wallpapers"));

Expand All @@ -76,10 +80,14 @@ pub fn resolve_wallpaper_path(path_str: &str) -> Option<PathBuf> {
pub fn list_all_wallpapers() -> Vec<PathBuf> {
let mut search_dirs = Vec::new();
if let Ok(home) = std::env::var("HOME") {
search_dirs.push(PathBuf::from(&home).join(".local/share/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from(&home).join(".config/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from(&home).join("Pictures/Wallpapers"));
search_dirs.push(PathBuf::from(&home).join("Pictures"));
}
if let Ok(data_home) = std::env::var("XDG_DATA_HOME") {
search_dirs.push(PathBuf::from(&data_home).join("agility-shell/wallpapers"));
}
search_dirs.push(PathBuf::from("/usr/share/agility-shell/wallpapers"));
search_dirs.push(PathBuf::from("wallpapers"));

Expand Down Expand Up @@ -300,7 +308,7 @@ impl ThemeService {

// 1. Instantly dispatch wallpaper setter (awww / swww) in < 5ms
let t_type = transition_type.unwrap_or("grow");
let t_dur = duration.unwrap_or(0.25);
let t_dur = duration.unwrap_or(0.20);
Self::dispatch_wallpaper_backend(&abs_str, t_type, t_dur);

// Immediate responsive token return with new wallpaper
Expand Down Expand Up @@ -624,10 +632,18 @@ impl ThemeService {
let _ = Command::new("awww")
.arg("img")
.arg(path)
.arg("--resize")
.arg("crop")
.arg("--filter")
.arg("Bilinear")
.arg("--transition-type")
.arg(transition_type)
.arg("--transition-duration")
.arg(&dur_str)
.arg("--transition-step")
.arg("180")
.arg("--transition-fps")
.arg("60")
.spawn();
return;
}
Expand Down Expand Up @@ -660,6 +676,10 @@ impl ThemeService {
.arg(transition_type)
.arg("--transition-duration")
.arg(&dur_str)
.arg("--transition-step")
.arg("180")
.arg("--transition-fps")
.arg("60")
.spawn();
return;
}
Expand Down
5 changes: 5 additions & 0 deletions quickshell/agility/Core/Services/SettingsService.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Item {
property string pillPopupStyle: "center"
property string pillWidgetLayout: "distributed"
property bool barAutoHide: false
property bool barOpenOnHover: false
property string barGlassMode: "solid"
property int barGlassOpacity: 85
property bool appletActiveWindow: true
Expand Down Expand Up @@ -291,6 +292,7 @@ Item {
"pillPopupStyle": settingsService.pillPopupStyle,
"pillWidgetLayout": settingsService.pillWidgetLayout,
"barAutoHide": settingsService.barAutoHide,
"barOpenOnHover": settingsService.barOpenOnHover,
"barGlassMode": settingsService.barGlassMode,
"barGlassOpacity": settingsService.barGlassOpacity,
"appletActiveWindow": settingsService.appletActiveWindow,
Expand Down Expand Up @@ -490,6 +492,9 @@ cp ~/.cache/quickshell/settings_prefs.json /var/tmp/sddm-theme/settings_prefs.js
if (prefs.barAutoHide !== undefined)
settingsService.barAutoHide = Boolean(prefs.barAutoHide);

if (prefs.barOpenOnHover !== undefined)
settingsService.barOpenOnHover = Boolean(prefs.barOpenOnHover);

if (prefs.barGlassMode !== undefined)
settingsService.barGlassMode = prefs.barGlassMode;
if (prefs.barGlassOpacity !== undefined)
Expand Down
21 changes: 20 additions & 1 deletion quickshell/agility/Core/Services/WallpaperManager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ QtObject {
property bool enableTransitions: HyprlandService.wpEnableTransitions
property bool autoShuffle: HyprlandService.wpAutoShuffle
property int shuffleInterval: HyprlandService.wpShuffleInterval
property Process fastAwwwProc
property Process wallpaperApplyProc
property Process wallpaperSaveProc
property Process wallpaperLoader
Expand Down Expand Up @@ -49,8 +50,23 @@ QtObject {
HyprlandService.wpAutoShuffle = false;
SettingsService.saveSettings();
}

// Fast path: Immediately apply wallpaper with awww directly (< 250ms visual switch)
fastAwwwProc.running = false;
fastAwwwProc.command = [
"awww", "img", rawPath,
"--resize", "crop",
"--filter", "Bilinear",
"--transition-type", (enableTransitions && SystemInfoService.powerProfile !== "power-saver" && transitionType) ? transitionType : "grow",
"--transition-duration", "0.2",
"--transition-step", "180",
"--transition-fps", "60"
];
fastAwwwProc.startDetached();

// Daemon sync: extracts palette, generates blur, writes cache
wallpaperApplyProc.running = false;
let cmd = ["agl", "wallpaper", rawPath];
let cmd = ["agl", "wallpaper", rawPath, "--duration", "0.2"];
if (enableTransitions && SystemInfoService.powerProfile !== "power-saver" && transitionType) {
cmd.push("--transition", transitionType);
}
Expand Down Expand Up @@ -83,6 +99,9 @@ QtObject {
}
}

fastAwwwProc: Process {
}

wallpaperApplyProc: Process {
}

Expand Down
25 changes: 25 additions & 0 deletions quickshell/agility/Modules/Bar/Components/BarButton.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,38 @@ Rectangle {
iconColor: (!root.hasBackground && mouseArea.containsMouse) ? Theme.accent : root.iconColor
}

Timer {
id: hoverTimer

interval: 160
repeat: false
onTriggered: {
if (SettingsService.barOpenOnHover && mouseArea.containsMouse) {
if (root.widgetId !== "" && root.widgetId !== "powerMenu") {
if (!AppState.isWidgetOpen(root.widgetId))
AppState.openWidget(root.widgetId);
} else if (root.widget && !root.widget.isOpen) {
root.widget.isOpen = true;
}
}
}
}

MouseArea {
id: mouseArea

anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
if (SettingsService.barOpenOnHover)
hoverTimer.restart();
}
onExited: {
hoverTimer.stop();
}
onClicked: {
hoverTimer.stop();
if (root.widgetId !== "")
AppState.toggleWidget(root.widgetId);
else if (root.widget)
Expand Down
Loading
Loading