mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-16 22:31:03 +02:00
Merge pull request #984 from JakeStanger/fix/hyprland-grimblast-crash
refactor: update hyprland-rs, remove `expect`s from hyprland client code
This commit is contained in:
commit
88190f0d4a
3 changed files with 233 additions and 102 deletions
118
Cargo.lock
generated
118
Cargo.lock
generated
|
@ -168,6 +168,28 @@ dependencies = [
|
||||||
"syn 2.0.99",
|
"syn 2.0.99",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-stream"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
|
||||||
|
dependencies = [
|
||||||
|
"async-stream-impl",
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-stream-impl"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote 1.0.39",
|
||||||
|
"syn 2.0.99",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.87"
|
version = "0.1.87"
|
||||||
|
@ -655,13 +677,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.19"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f"
|
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_more-impl"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote 1.0.39",
|
"quote 1.0.39",
|
||||||
"syn 2.0.99",
|
"syn 2.0.99",
|
||||||
|
"unicode-xid 0.2.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1542,17 +1574,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyprland"
|
name = "hyprland"
|
||||||
version = "0.4.0-alpha.3"
|
version = "0.4.0-beta.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2de3f836e02af5a12f374d3a986867c1dc487a63a6d19477d66c7de50f715895"
|
checksum = "dc9c1413b6f0fd10b2e4463479490e30b2497ae4449f044da16053f5f2cb03b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
|
"async-stream",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
"either",
|
||||||
|
"futures-lite",
|
||||||
"hyprland-macros",
|
"hyprland-macros",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"paste",
|
"paste",
|
||||||
"regex",
|
"phf",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
|
@ -2457,6 +2492,48 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||||
|
dependencies = [
|
||||||
|
"phf_macros",
|
||||||
|
"phf_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_generator"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||||
|
dependencies = [
|
||||||
|
"phf_shared",
|
||||||
|
"rand",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_macros"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
|
||||||
|
dependencies = [
|
||||||
|
"phf_generator",
|
||||||
|
"phf_shared",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote 1.0.39",
|
||||||
|
"syn 2.0.99",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "phf_shared"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||||
|
dependencies = [
|
||||||
|
"siphasher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.1.10"
|
version = "1.1.10"
|
||||||
|
@ -2607,6 +2684,21 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.10"
|
version = "0.5.10"
|
||||||
|
@ -3038,6 +3130,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -3160,7 +3258,7 @@ checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 0.3.15",
|
"quote 0.3.15",
|
||||||
"synom",
|
"synom",
|
||||||
"unicode-xid",
|
"unicode-xid 0.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3200,7 +3298,7 @@ version = "0.11.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid 0.0.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3656,6 +3754,12 @@ version = "0.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-config"
|
name = "universal-config"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
|
@ -10,6 +10,7 @@ keywords = ["gtk", "bar", "wayland", "wlroots", "gtk-layer-shell"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [
|
default = [
|
||||||
|
"bindmode+all",
|
||||||
"cli",
|
"cli",
|
||||||
"cairo",
|
"cairo",
|
||||||
"clipboard",
|
"clipboard",
|
||||||
|
@ -19,7 +20,6 @@ default = [
|
||||||
"focused",
|
"focused",
|
||||||
"http",
|
"http",
|
||||||
"ipc",
|
"ipc",
|
||||||
"bindmode+all",
|
|
||||||
"keyboard+all",
|
"keyboard+all",
|
||||||
"launcher",
|
"launcher",
|
||||||
"label",
|
"label",
|
||||||
|
@ -182,7 +182,7 @@ libpulse-binding = { version = "2.30.1", optional = true }
|
||||||
futures-lite = { version = "2.6.0", optional = true } # network_manager, upower, workspaces, keyboard
|
futures-lite = { version = "2.6.0", optional = true } # network_manager, upower, workspaces, keyboard
|
||||||
zbus = { version = "5.6.0", default-features = false, features = ["tokio"], optional = true } # network_manager, notifications, upower
|
zbus = { version = "5.6.0", default-features = false, features = ["tokio"], optional = true } # network_manager, notifications, upower
|
||||||
swayipc-async = { version = "2.0.4", optional = true } # workspaces, keyboard
|
swayipc-async = { version = "2.0.4", optional = true } # workspaces, keyboard
|
||||||
hyprland = { version = "0.4.0-alpha.3", features = ["silent"], optional = true } # workspaces, keyboard
|
hyprland = { version = "0.4.0-beta.2", optional = true } # workspaces, keyboard
|
||||||
rustix = { version = "1.0.7", default-features = false, features = ["std", "fs", "pipe", "event"], optional = true } # clipboard, input
|
rustix = { version = "1.0.7", default-features = false, features = ["std", "fs", "pipe", "event"], optional = true } # clipboard, input
|
||||||
serde_json = { version = "1.0.140", optional = true } # ipc, niri
|
serde_json = { version = "1.0.140", optional = true } # ipc, niri
|
||||||
|
|
||||||
|
@ -193,4 +193,4 @@ schemars = { version = "0.8.22", optional = true }
|
||||||
clap = { version = "4.5.38", features = ["derive"] }
|
clap = { version = "4.5.38", features = ["derive"] }
|
||||||
clap_complete = "4.5.50"
|
clap_complete = "4.5.50"
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
|
@ -1,3 +1,7 @@
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
use super::{BindModeClient, BindModeUpdate};
|
||||||
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
|
use super::{KeyboardLayoutClient, KeyboardLayoutUpdate};
|
||||||
use super::{Visibility, Workspace, WorkspaceUpdate};
|
use super::{Visibility, Workspace, WorkspaceUpdate};
|
||||||
use crate::{arc_mut, lock, send, spawn_blocking};
|
use crate::{arc_mut, lock, send, spawn_blocking};
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
@ -8,12 +12,7 @@ use hyprland::event_listener::EventListener;
|
||||||
use hyprland::prelude::*;
|
use hyprland::prelude::*;
|
||||||
use hyprland::shared::{HyprDataVec, WorkspaceType};
|
use hyprland::shared::{HyprDataVec, WorkspaceType};
|
||||||
use tokio::sync::broadcast::{Receiver, Sender, channel};
|
use tokio::sync::broadcast::{Receiver, Sender, channel};
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info, warn};
|
||||||
|
|
||||||
#[cfg(feature = "bindmode+hyprland")]
|
|
||||||
use super::{BindModeClient, BindModeUpdate};
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
|
||||||
use super::{KeyboardLayoutClient, KeyboardLayoutUpdate};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TxRx<T> {
|
struct TxRx<T> {
|
||||||
|
@ -74,45 +73,55 @@ impl Client {
|
||||||
|
|
||||||
// cache the active workspace since Hyprland doesn't give us the prev active
|
// cache the active workspace since Hyprland doesn't give us the prev active
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
Self::listen_workspace_events(workspace_tx, &mut event_listener, &lock);
|
Self::listen_workspace_events(&workspace_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
Self::listen_keyboard_events(keyboard_layout_tx, &mut event_listener, &lock);
|
Self::listen_keyboard_events(&keyboard_layout_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
#[cfg(feature = "bindmode+hyprland")]
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
Self::listen_bindmode_events(bindmode_tx, &mut event_listener, &lock);
|
Self::listen_bindmode_events(&bindmode_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
event_listener
|
if let Err(err) = event_listener.start_listener() {
|
||||||
.start_listener()
|
error!("Failed to start listener: {err:#}");
|
||||||
.expect("Failed to start listener");
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
fn listen_workspace_events(
|
fn listen_workspace_events(
|
||||||
tx: Sender<WorkspaceUpdate>,
|
tx: &Sender<WorkspaceUpdate>,
|
||||||
event_listener: &mut EventListener,
|
event_listener: &mut EventListener,
|
||||||
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
||||||
) {
|
) {
|
||||||
let active = Self::get_active_workspace().expect("Failed to get active workspace");
|
let active = Self::get_active_workspace().map_or_else(
|
||||||
let active = arc_mut!(Some(active));
|
|err| {
|
||||||
|
error!("Failed to get active workspace: {err:#?}");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Some,
|
||||||
|
);
|
||||||
|
let active = arc_mut!(active);
|
||||||
|
|
||||||
{
|
{
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
let active = active.clone();
|
let active = active.clone();
|
||||||
|
|
||||||
event_listener.add_workspace_added_handler(move |workspace_type| {
|
event_listener.add_workspace_added_handler(move |event| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
debug!("Added workspace: {workspace_type:?}");
|
debug!("Added workspace: {event:?}");
|
||||||
|
|
||||||
let workspace_name = get_workspace_name(workspace_type);
|
let workspace_name = get_workspace_name(event.name);
|
||||||
let prev_workspace = lock!(active);
|
let prev_workspace = lock!(active);
|
||||||
|
|
||||||
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
||||||
|
|
||||||
if let Some(workspace) = workspace {
|
match workspace {
|
||||||
send!(tx, WorkspaceUpdate::Add(workspace));
|
Ok(Some(workspace)) => {
|
||||||
|
send!(tx, WorkspaceUpdate::Add(workspace));
|
||||||
|
}
|
||||||
|
Err(e) => error!("Failed to get workspace: {e:#}"),
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -122,30 +131,29 @@ impl Client {
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
let active = active.clone();
|
let active = active.clone();
|
||||||
|
|
||||||
event_listener.add_workspace_change_handler(move |workspace_type| {
|
event_listener.add_workspace_changed_handler(move |event| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
|
|
||||||
let mut prev_workspace = lock!(active);
|
let mut prev_workspace = lock!(active);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Received workspace change: {:?} -> {workspace_type:?}",
|
"Received workspace change: {:?} -> {event:?}",
|
||||||
prev_workspace.as_ref().map(|w| &w.id)
|
prev_workspace.as_ref().map(|w| &w.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
let workspace_name = get_workspace_name(workspace_type);
|
let workspace_name = get_workspace_name(event.name);
|
||||||
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
||||||
|
|
||||||
workspace.map_or_else(
|
match workspace {
|
||||||
|| {
|
Ok(Some(workspace)) if !workspace.visibility.is_focused() => {
|
||||||
|
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
error!("Unable to locate workspace");
|
error!("Unable to locate workspace");
|
||||||
},
|
}
|
||||||
|workspace| {
|
Err(e) => error!("Failed to get workspace: {e:#}"),
|
||||||
// there may be another type of update so dispatch that regardless of focus change
|
_ => {}
|
||||||
if !workspace.visibility.is_focused() {
|
}
|
||||||
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +162,12 @@ impl Client {
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
let active = active.clone();
|
let active = active.clone();
|
||||||
|
|
||||||
event_listener.add_active_monitor_change_handler(move |event_data| {
|
event_listener.add_active_monitor_changed_handler(move |event_data| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
let workspace_type = event_data.workspace;
|
let Some(workspace_type) = event_data.workspace_name else {
|
||||||
|
warn!("Received active monitor change with no workspace name");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let mut prev_workspace = lock!(active);
|
let mut prev_workspace = lock!(active);
|
||||||
|
|
||||||
|
@ -168,11 +179,15 @@ impl Client {
|
||||||
let workspace_name = get_workspace_name(workspace_type);
|
let workspace_name = get_workspace_name(workspace_type);
|
||||||
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
||||||
|
|
||||||
if let Some((false, workspace)) = workspace.map(|w| (w.visibility.is_focused(), w))
|
match workspace {
|
||||||
{
|
Ok(Some(workspace)) if !workspace.visibility.is_focused() => {
|
||||||
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
||||||
} else {
|
}
|
||||||
error!("unable to locate workspace: {workspace_name}");
|
Ok(None) => {
|
||||||
|
error!("Unable to locate workspace");
|
||||||
|
}
|
||||||
|
Err(e) => error!("Failed to get workspace: {e:#}"),
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -183,7 +198,7 @@ impl Client {
|
||||||
|
|
||||||
event_listener.add_workspace_moved_handler(move |event_data| {
|
event_listener.add_workspace_moved_handler(move |event_data| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
let workspace_type = event_data.workspace;
|
let workspace_type = event_data.name;
|
||||||
debug!("Received workspace move: {workspace_type:?}");
|
debug!("Received workspace move: {workspace_type:?}");
|
||||||
|
|
||||||
let mut prev_workspace = lock!(active);
|
let mut prev_workspace = lock!(active);
|
||||||
|
@ -191,12 +206,15 @@ impl Client {
|
||||||
let workspace_name = get_workspace_name(workspace_type);
|
let workspace_name = get_workspace_name(workspace_type);
|
||||||
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
let workspace = Self::get_workspace(&workspace_name, prev_workspace.as_ref());
|
||||||
|
|
||||||
if let Some(workspace) = workspace {
|
match workspace {
|
||||||
send!(tx, WorkspaceUpdate::Move(workspace.clone()));
|
Ok(Some(workspace)) if !workspace.visibility.is_focused() => {
|
||||||
|
|
||||||
if !workspace.visibility.is_focused() {
|
|
||||||
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
Self::send_focus_change(&mut prev_workspace, workspace, &tx);
|
||||||
}
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
error!("Unable to locate workspace");
|
||||||
|
}
|
||||||
|
Err(e) => error!("Failed to get workspace: {e:#}"),
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -205,15 +223,15 @@ impl Client {
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
|
||||||
event_listener.add_workspace_rename_handler(move |data| {
|
event_listener.add_workspace_renamed_handler(move |data| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
debug!("Received workspace rename: {data:?}");
|
debug!("Received workspace rename: {data:?}");
|
||||||
|
|
||||||
send!(
|
send!(
|
||||||
tx,
|
tx,
|
||||||
WorkspaceUpdate::Rename {
|
WorkspaceUpdate::Rename {
|
||||||
id: data.workspace_id as i64,
|
id: data.id as i64,
|
||||||
name: data.workspace_name
|
name: data.name
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -223,10 +241,10 @@ impl Client {
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
|
||||||
event_listener.add_workspace_destroy_handler(move |data| {
|
event_listener.add_workspace_deleted_handler(move |data| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
debug!("Received workspace destroy: {data:?}");
|
debug!("Received workspace destroy: {data:?}");
|
||||||
send!(tx, WorkspaceUpdate::Remove(data.workspace_id as i64));
|
send!(tx, WorkspaceUpdate::Remove(data.id as i64));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +252,7 @@ impl Client {
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
|
||||||
event_listener.add_urgent_state_handler(move |address| {
|
event_listener.add_urgent_state_changed_handler(move |address| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
debug!("Received urgent state: {address:?}");
|
debug!("Received urgent state: {address:?}");
|
||||||
|
|
||||||
|
@ -265,14 +283,14 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
fn listen_keyboard_events(
|
fn listen_keyboard_events(
|
||||||
keyboard_layout_tx: Sender<KeyboardLayoutUpdate>,
|
keyboard_layout_tx: &Sender<KeyboardLayoutUpdate>,
|
||||||
event_listener: &mut EventListener,
|
event_listener: &mut EventListener,
|
||||||
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
||||||
) {
|
) {
|
||||||
let tx = keyboard_layout_tx.clone();
|
let tx = keyboard_layout_tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
|
||||||
event_listener.add_keyboard_layout_change_handler(move |layout_event| {
|
event_listener.add_layout_changed_handler(move |layout_event| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
|
|
||||||
let layout = if layout_event.layout_name.is_empty() {
|
let layout = if layout_event.layout_name.is_empty() {
|
||||||
|
@ -319,14 +337,14 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(feature = "bindmode+hyprland")]
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
fn listen_bindmode_events(
|
fn listen_bindmode_events(
|
||||||
bindmode_tx: Sender<BindModeUpdate>,
|
bindmode_tx: &Sender<BindModeUpdate>,
|
||||||
event_listener: &mut EventListener,
|
event_listener: &mut EventListener,
|
||||||
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
||||||
) {
|
) {
|
||||||
let tx = bindmode_tx.clone();
|
let tx = bindmode_tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
|
||||||
event_listener.add_sub_map_change_handler(move |bind_mode| {
|
event_listener.add_sub_map_changed_handler(move |bind_mode| {
|
||||||
let _lock = lock!(lock);
|
let _lock = lock!(lock);
|
||||||
debug!("Received bind mode: {bind_mode:?}");
|
debug!("Received bind mode: {bind_mode:?}");
|
||||||
|
|
||||||
|
@ -369,21 +387,20 @@ impl Client {
|
||||||
|
|
||||||
/// Gets a workspace by name from the server, given the active workspace if known.
|
/// Gets a workspace by name from the server, given the active workspace if known.
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
fn get_workspace(name: &str, active: Option<&Workspace>) -> Option<Workspace> {
|
fn get_workspace(name: &str, active: Option<&Workspace>) -> Result<Option<Workspace>> {
|
||||||
Workspaces::get()
|
let workspace = Workspaces::get()?.into_iter().find_map(|w| {
|
||||||
.expect("Failed to get workspaces")
|
if w.name == name {
|
||||||
.into_iter()
|
let vis = Visibility::from((&w, active.map(|w| w.name.as_ref()), &|w| {
|
||||||
.find_map(|w| {
|
create_is_visible()(w)
|
||||||
if w.name == name {
|
}));
|
||||||
let vis = Visibility::from((&w, active.map(|w| w.name.as_ref()), &|w| {
|
|
||||||
create_is_visible()(w)
|
|
||||||
}));
|
|
||||||
|
|
||||||
Some(Workspace::from((vis, w)))
|
Some(Workspace::from((vis, w)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
Ok(workspace)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the active workspace from the server.
|
/// Gets the active workspace from the server.
|
||||||
|
@ -409,17 +426,22 @@ impl super::WorkspaceClient for Client {
|
||||||
let active_id = HWorkspace::get_active().ok().map(|active| active.name);
|
let active_id = HWorkspace::get_active().ok().map(|active| active.name);
|
||||||
let is_visible = create_is_visible();
|
let is_visible = create_is_visible();
|
||||||
|
|
||||||
let workspaces = Workspaces::get()
|
match Workspaces::get() {
|
||||||
.expect("Failed to get workspaces")
|
Ok(workspaces) => {
|
||||||
.into_iter()
|
let workspaces = workspaces
|
||||||
.map(|w| {
|
.into_iter()
|
||||||
let vis = Visibility::from((&w, active_id.as_deref(), &is_visible));
|
.map(|w| {
|
||||||
|
let vis = Visibility::from((&w, active_id.as_deref(), &is_visible));
|
||||||
|
Workspace::from((vis, w))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
Workspace::from((vis, w))
|
send!(self.workspace.tx, WorkspaceUpdate::Init(workspaces));
|
||||||
})
|
}
|
||||||
.collect();
|
Err(e) => {
|
||||||
|
error!("Failed to get workspaces: {e:#}");
|
||||||
send!(self.workspace.tx, WorkspaceUpdate::Init(workspaces));
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rx
|
rx
|
||||||
}
|
}
|
||||||
|
@ -428,8 +450,12 @@ impl super::WorkspaceClient for Client {
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
impl KeyboardLayoutClient for Client {
|
impl KeyboardLayoutClient for Client {
|
||||||
fn set_next_active(&self) {
|
fn set_next_active(&self) {
|
||||||
let device = Devices::get()
|
let Ok(devices) = Devices::get() else {
|
||||||
.expect("Failed to get devices")
|
error!("Failed to get devices");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let device = devices
|
||||||
.keyboards
|
.keyboards
|
||||||
.iter()
|
.iter()
|
||||||
.find(|k| k.main)
|
.find(|k| k.main)
|
||||||
|
@ -449,17 +475,18 @@ impl KeyboardLayoutClient for Client {
|
||||||
fn subscribe(&self) -> Receiver<KeyboardLayoutUpdate> {
|
fn subscribe(&self) -> Receiver<KeyboardLayoutUpdate> {
|
||||||
let rx = self.keyboard_layout.tx.subscribe();
|
let rx = self.keyboard_layout.tx.subscribe();
|
||||||
|
|
||||||
let layout = Devices::get()
|
match Devices::get().map(|devices| {
|
||||||
.expect("Failed to get devices")
|
devices
|
||||||
.keyboards
|
.keyboards
|
||||||
.iter()
|
.iter()
|
||||||
.find(|k| k.main)
|
.find(|k| k.main)
|
||||||
.map(|k| k.active_keymap.clone());
|
.map(|k| k.active_keymap.clone())
|
||||||
|
}) {
|
||||||
if let Some(layout) = layout {
|
Ok(Some(layout)) => {
|
||||||
send!(self.keyboard_layout.tx, KeyboardLayoutUpdate(layout));
|
send!(self.keyboard_layout.tx, KeyboardLayoutUpdate(layout));
|
||||||
} else {
|
}
|
||||||
error!("Failed to get current keyboard layout hyprland");
|
Ok(None) => error!("Failed to get current keyboard layout hyprland"),
|
||||||
|
Err(err) => error!("Failed to get devices: {err:#?}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
rx
|
rx
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue