Skip to content

Commit

Permalink
feat: improve icon detection for flatpak apps
Browse files Browse the repository at this point in the history
fix: only show Notification when not in debug(dev) mode
Signed-off-by: Enrico Stemmer <[email protected]>
  • Loading branch information
H3rmt committed Jan 15, 2025
1 parent 452173e commit 50af3e1
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 40 deletions.
9 changes: 4 additions & 5 deletions src/config/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::config::config_structs::{
SimpleBindConfig, ToKey,
};
use rand::Rng;
use std::borrow::Cow;
use std::env;
use std::path::PathBuf;
use tracing::trace;
Expand Down Expand Up @@ -75,7 +74,7 @@ fn generate_other(params: &mut Vec<String>, other: &Other) {
}
fn generate_simple(
keyword_list: &mut Vec<(&str, String)>,
current_exe: &Cow<str>,
current_exe: &str,
simple: SimpleBindConfig,
) {
let mut params = Vec::<String>::new();
Expand All @@ -99,7 +98,7 @@ fn generate_simple(

fn generate_press(
keyword_list: &mut Vec<(&str, String)>,
current_exe: &Cow<str>,
current_exe: &str,
press: PressBindConfig,
submap_name: String,
) {
Expand Down Expand Up @@ -194,7 +193,7 @@ fn generate_press(

fn generate_hold(
keyword_list: &mut Vec<(&str, String)>,
current_exe: &Cow<str>,
current_exe: &str,
hold: HoldBindConfig,
submap_name: String,
) {
Expand Down Expand Up @@ -333,7 +332,7 @@ fn generate_hold(
fn generate_daemon_start(
keyword_list: &mut Vec<(&str, String)>,
general: General,
current_exe: &Cow<str>,
current_exe: &str,
) {
let mut params = Vec::<String>::new();
let mut envs = Vec::<String>::new();
Expand Down
4 changes: 2 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn load() -> anyhow::Result<Config> {

fn get_path() -> Option<PathBuf> {
env::var_os("HYPRSWITCH_CONFIG")
.map(|val| PathBuf::from(val))
.map(PathBuf::from)
.or_else(|| {
get_config_dir().map(|mut path| {
path.push("hyprswitch/config.ron");
Expand All @@ -43,7 +43,7 @@ fn get_path() -> Option<PathBuf> {

fn get_config_dir() -> Option<PathBuf> {
env::var_os("XDG_CONFIG_HOME")
.map(|val| PathBuf::from(val))
.map(PathBuf::from)
.or_else(|| {
env::var_os("HOME")
.map(|home| PathBuf::from(format!("{}/.config", home.to_string_lossy())))
Expand Down
1 change: 1 addition & 0 deletions src/daemon/gui/launcher/launcher.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
.launcher-list {
margin-left: 2px;
margin-right: 2px;
margin-bottom: 1px;
}

.launcher-item {
Expand Down
10 changes: 7 additions & 3 deletions src/daemon/gui/launcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use anyhow::Context;
use gtk4::gdk::Key;
use gtk4::glib::{clone, Propagation};
use gtk4::prelude::{BoxExt, EditableExt, GtkWindowExt, WidgetExt};
use gtk4::{gio, glib, Align, Application, ApplicationWindow, Entry, EventControllerKey, IconSize, Image, Label, ListBox, ListBoxRow, Orientation, SelectionMode};
use gtk4::{
gio, glib, Align, Application, ApplicationWindow, Entry, EventControllerKey, IconSize, Image,
Label, ListBox, ListBoxRow, Orientation, SelectionMode,
};
use gtk4_layer_shell::{Layer, LayerShell};
use std::ops::Deref;
use std::path::Path;
Expand Down Expand Up @@ -157,7 +160,7 @@ pub(super) fn update_launcher(
}
}
},
selected.map_or(false, |s| s == index as u16),
selected == Some(index as u16),
);
list.append(&widget);
execs.push((exec.clone(), path.clone(), *terminal));
Expand All @@ -181,7 +184,8 @@ fn create_launch_widget(

if let Some(icon_path) = icon_path {
let icon = Image::builder().icon_size(IconSize::Large).build();
apply_texture_path(&gio::File::for_path(icon_path), &icon, true).warn("Failed to apply icon");
apply_texture_path(&gio::File::for_path(icon_path), &icon, true)
.warn("Failed to apply icon");
hbox.append(&icon);
}

Expand Down
20 changes: 16 additions & 4 deletions src/daemon/gui/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ fn collect_desktop_files() -> Vec<DirEntry> {
Ok(dir) => {
for entry in dir.flatten() {
let path = entry.path();
if path.is_file() && path.extension().map_or(false, |e| e == "desktop") {
if path.is_file() && path.extension().is_some_and(|e| e == "desktop") {
res.push(entry);
}
}
Expand Down Expand Up @@ -173,6 +173,20 @@ fn fill_desktop_file_map(
.lines()
.find(|l| l.starts_with("Exec="))
.map(|l| l.trim_start_matches("Exec="))
.map(|l| {
// is a flatpak and isn't a PWA
// (PWAs work out of the box by using the class = to the icon-name)
// else chromium/chrome/etc would be detected as exec
if l.contains("flatpak")
&& l.contains("--command")
&& !l.contains("--app-id")
{
// trim all text until --command
l.split("--command=").last().unwrap_or(l)
} else {
l
}
})
.and_then(|l| l.split(' ').next())
.and_then(|l| l.split('/').last())
.map(|n| n.replace('"', ""));
Expand Down Expand Up @@ -234,9 +248,7 @@ fn fill_desktop_file_map(
.map(|l| l.trim_start_matches("Terminal="))
.map(|l| l == "true")
.unwrap_or(false);
if ttype.map_or(false, |t| t == "Application")
&& no_display.map_or(true, |n| !n)
{
if ttype == Some("Application") && no_display.map_or(true, |n| !n) {
if let (Some(name), Some(exec)) = (name, exec) {
let mut exec = String::from(exec);
for repl in &["%f", "%F", "%u", "%U"] {
Expand Down
21 changes: 14 additions & 7 deletions src/daemon/gui/windows/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub fn init_windows(
workspaces
};

let regex = Regex::new(r"<span[^>]*>(.*?)</span>").expect("Failed to create regex");
for (wid, workspace) in workspaces {
let workspace_fixed = Fixed::builder()
.width_request(scale(workspace.width as i16, size_factor))
Expand All @@ -41,9 +42,7 @@ pub fn init_windows(
let id_string = wid.to_string();
let title = if show_title && !workspace.name.trim().is_empty() {
if *REMOVE_HTML_FROM_WORKSPACE_NAME {
Regex::new(r"<span[^>]*>(.*?)</span>")
.unwrap()
.replace_all(&workspace.name, "$1")
regex.replace_all(&workspace.name, "$1")
} else {
Cow::from(&workspace.name)
}
Expand Down Expand Up @@ -112,12 +111,20 @@ pub fn init_windows(
let client_overlay = Overlay::builder()
.css_classes(vec!["client", "background"])
.child(&client_frame)
.width_request(scale(client.width, size_factor))
.height_request(scale(client.height, size_factor))
.build();
client_overlay.set_size_request(
scale(client.width, size_factor),
scale(client.height, size_factor),
);
client_overlay.add_controller(click_client(&share, address));
// client_frame.connect_show(|a| {
// warn!("a showing client, {a:?}, {}", a.allocated_height());
// glib::spawn_future_local(clone!(
// #[strong]
// a,
// async move {
// warn!("showing client, {a:?}, {}", a.height());
// }
// ));
// });
client_overlay
};
workspace_fixed.put(
Expand Down
17 changes: 10 additions & 7 deletions src/daemon/handle_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::daemon::handle_fns::{close, init, switch};
use crate::envs::ASYNC_SOCKET;
use crate::{get_socket_path_buff, Share, Transfer, TransferType, ACTIVE};
use anyhow::Context;
use notify_rust::{Notification, Urgency};
use rand::Rng;
use std::fs::remove_file;
use std::io::{BufRead, BufReader, Write};
Expand Down Expand Up @@ -53,11 +52,12 @@ pub(super) fn start_handler_blocking(share: &Share) {
thread::spawn(move || {
handle_client(stream, arc_share).context("Failed to handle client")
.unwrap_or_else(|e| {
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!("Hyprswitch ({}) Error", option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?")))
.body(&format!("Failed to handle client (restarting the hyprswitch daemon will most likely fix the issue) {:?}", e))
.timeout(10000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();

warn!("{:?}", e)
Expand All @@ -66,11 +66,12 @@ pub(super) fn start_handler_blocking(share: &Share) {
} else {
handle_client(stream, arc_share).context("Failed to handle client")
.unwrap_or_else(|e| {
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!("Hyprswitch ({}) Error", option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?")))
.body(&format!("Failed to handle client (restarting the hyprswitch daemon will most likely fix the issue) {:?}", e))
.timeout(10000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();

warn!("{:?}", e)
Expand Down Expand Up @@ -128,15 +129,16 @@ pub(super) fn handle_client_transfer(
transfer.version,
env!("CARGO_PKG_VERSION")
);
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!(
"Hyprswitch daemon ({}) and client ({}) dont match, please restart the daemon or your Hyprland session",
env!("CARGO_PKG_VERSION"),
transfer.version
))
.body(VERSION_OUT_OF_SYNC)
.timeout(20000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();
return_success(false, &mut stream)?;

Expand Down Expand Up @@ -247,6 +249,7 @@ fn return_success(success: bool, stream: &mut UnixStream) -> anyhow::Result<()>
Ok(())
}

#[cfg(not(debug_assertions))]
const VERSION_OUT_OF_SYNC: &str = r"
This is most likely caused by updating hyprswitch and not restarting the hyprswitch daemon.
You must manually start the new version (run `pkill hyprswitch && hyprswitch init &` in a terminal)
Expand Down
9 changes: 5 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use async_channel::{Receiver, Sender};
use hyprland::data::Version as HyprlandVersion;
use hyprland::prelude::HyprData;
use hyprland::shared::{Address, MonitorId, WorkspaceId};
use notify_rust::{Notification, Urgency};
use semver::Version;
use serde::{Deserialize, Serialize};
use std::env::var;
Expand Down Expand Up @@ -314,22 +313,24 @@ pub fn check_version() -> anyhow::Result<()> {
);

let parsed_version = Version::parse(
&*version
&version
.version
.unwrap_or(version.tag.trim_start_matches('v').to_string()),
)
.context("Unable to parse Hyprland Version")?;

if parsed_version.lt(&MIN_VERSION) {
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!(
"Hyprswitch ({}) Error",
option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?")
))
.body("Hyprland version too old or unknown")
.timeout(5000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();
warn!("Hyprland version too old or unknown: {parsed_version:?} < {MIN_VERSION:?}",);
}

Ok(())
Expand Down
15 changes: 7 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use hyprswitch::{
check_version, cli, Active, Command, Config, GuiConfig, InitConfig, Submap, SubmapConfig,
ACTIVE, DRY,
};
use notify_rust::{Notification, Urgency};
use std::process::exit;
use std::sync::Mutex;
use tracing::level_filters::LevelFilter;
Expand All @@ -22,11 +21,12 @@ fn main() -> anyhow::Result<()> {
e.to_string().starts_with("Used to send commands to the daemon (used in keymap that gets generated by gui)") ||
e.to_string().starts_with("Switch without using the GUI / Daemon (switches directly)") ||
e.to_string().starts_with("Close the GUI, executes the command to switch window") || e.to_string() == format!("hyprswitch {}\n", option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?"))) {
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!("Hyprswitch ({}) Error", option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?")))
.body("Unable to parse CLI Arguments (visit https://github.com/H3rmt/hyprswitch/blob/main/README.md to see all CLI Args)")
.timeout(10000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();
}
eprintln!("{}", e);
Expand Down Expand Up @@ -120,11 +120,12 @@ fn main() -> anyhow::Result<()> {
.context("Failed to send check command to daemon")?;

if !hyprswitch::client::daemon_running() {
let _ = Notification::new()
#[cfg(not(debug_assertions))]
let _ = notify_rust::Notification::new()
.summary(&format!("Hyprswitch ({}) Error", option_env!("CARGO_PKG_VERSION").unwrap_or("?.?.?")))
.body("Daemon not running (add ``exec-once = hyprswitch init &`` to your Hyprland config or run ``hyprswitch init &`` it in a terminal)\nvisit https://github.com/H3rmt/hyprswitch/wiki/Examples to see Example configs")
.timeout(10000)
.hint(notify_rust::Hint::Urgency(Urgency::Critical))
.hint(notify_rust::Hint::Urgency(notify_rust::Urgency::Critical))
.show();
return Err(anyhow::anyhow!("Daemon not running"));
}
Expand Down Expand Up @@ -218,9 +219,7 @@ fn main() -> anyhow::Result<()> {
.with_context(|| format!("Failed to get icon name for class {class}"))?;
println!(
"Icon: {:?} from desktop file cache: {:?} found by {:?}",
name.0,
name.2,
name.1
name.0, name.2, name.1
);
if theme.has_icon(&class) {
println!("Theme contains icon for class {class}");
Expand Down

0 comments on commit 50af3e1

Please sign in to comment.