mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-01 18:51:04 +02:00
Merge pull request #391 from JakeStanger/fix/workspace-issues
Workspace Issues Fixes
This commit is contained in:
commit
651a27b143
21 changed files with 50 additions and 35 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1220,9 +1220,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glib"
|
name = "glib"
|
||||||
version = "0.18.4"
|
version = "0.18.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "951bbd7fdc5c044ede9f05170f05a3ae9479239c3afdfe2d22d537a3add15c4e"
|
checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
|
|
@ -65,7 +65,7 @@ workspaces = ["futures-util"]
|
||||||
# core
|
# core
|
||||||
gtk = "0.18.1"
|
gtk = "0.18.1"
|
||||||
gtk-layer-shell = "0.8.0"
|
gtk-layer-shell = "0.8.0"
|
||||||
glib = "0.18.4"
|
glib = "0.18.5"
|
||||||
tokio = { version = "1.35.1", features = [
|
tokio = { version = "1.35.1", features = [
|
||||||
"macros",
|
"macros",
|
||||||
"rt-multi-thread",
|
"rt-multi-thread",
|
||||||
|
|
|
@ -84,7 +84,6 @@ impl EventClient {
|
||||||
},
|
},
|
||||||
|workspace| {
|
|workspace| {
|
||||||
// there may be another type of update so dispatch that regardless of focus change
|
// there may be another type of update so dispatch that regardless of focus change
|
||||||
send!(tx, WorkspaceUpdate::Update(workspace.clone()));
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,13 +116,17 @@ pub enum WorkspaceUpdate {
|
||||||
Init(Vec<Workspace>),
|
Init(Vec<Workspace>),
|
||||||
Add(Workspace),
|
Add(Workspace),
|
||||||
Remove(String),
|
Remove(String),
|
||||||
Update(Workspace),
|
|
||||||
Move(Workspace),
|
Move(Workspace),
|
||||||
/// Declares focus moved from the old workspace to the new.
|
/// Declares focus moved from the old workspace to the new.
|
||||||
Focus {
|
Focus {
|
||||||
old: Option<Workspace>,
|
old: Option<Workspace>,
|
||||||
new: Workspace,
|
new: Workspace,
|
||||||
},
|
},
|
||||||
|
/// An update was triggered by the compositor but this was not mapped by Ironbar.
|
||||||
|
///
|
||||||
|
/// This is purely used for ergonomics within the compositor clients
|
||||||
|
/// and should be ignored by consumers.
|
||||||
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WorkspaceClient {
|
pub trait WorkspaceClient {
|
||||||
|
|
|
@ -31,8 +31,11 @@ impl SwayEventClient {
|
||||||
|
|
||||||
while let Some(event) = events.next().await {
|
while let Some(event) = events.next().await {
|
||||||
trace!("event: {:?}", event);
|
trace!("event: {:?}", event);
|
||||||
if let Event::Workspace(ev) = event? {
|
if let Event::Workspace(event) = event? {
|
||||||
workspace_tx.send(WorkspaceUpdate::from(*ev))?;
|
let event = WorkspaceUpdate::from(*event);
|
||||||
|
if !matches!(event, WorkspaceUpdate::Unknown) {
|
||||||
|
workspace_tx.send(event)?;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +175,7 @@ impl From<WorkspaceEvent> for WorkspaceUpdate {
|
||||||
WorkspaceChange::Move => {
|
WorkspaceChange::Move => {
|
||||||
Self::Move(event.current.expect("Missing current workspace").into())
|
Self::Move(event.current.expect("Missing current workspace").into())
|
||||||
}
|
}
|
||||||
_ => Self::Update(event.current.expect("Missing current workspace").into()),
|
_ => Self::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use serde::Deserialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use self::common::{CommonConfig, TransitionType};
|
pub use self::common::{CommonConfig, TransitionType};
|
||||||
pub use self::truncate::{EllipsizeMode, TruncateMode};
|
pub use self::truncate::TruncateMode;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl DynamicBool {
|
||||||
_ => self,
|
_ => self,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel(32);
|
let (tx, rx) = mpsc::channel(32);
|
||||||
|
|
||||||
glib_recv_mpsc!(rx, val => f(val));
|
glib_recv_mpsc!(rx, val => f(val));
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ where
|
||||||
let tokens = parse_input(input);
|
let tokens = parse_input(input);
|
||||||
|
|
||||||
let label_parts = arc_mut!(vec![]);
|
let label_parts = arc_mut!(vec![]);
|
||||||
let (tx, mut rx) = mpsc::channel(32);
|
let (tx, rx) = mpsc::channel(32);
|
||||||
|
|
||||||
for (i, segment) in tokens.into_iter().enumerate() {
|
for (i, segment) in tokens.into_iter().enumerate() {
|
||||||
match segment {
|
match segment {
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl<'a> ImageProvider<'a> {
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
if let ImageLocation::Remote(url) = &self.location {
|
if let ImageLocation::Remote(url) = &self.location {
|
||||||
let url = url.clone();
|
let url = url.clone();
|
||||||
let (tx, mut rx) = mpsc::channel(64);
|
let (tx, rx) = mpsc::channel(64);
|
||||||
|
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
let bytes = Self::get_bytes_from_http(url).await;
|
let bytes = Self::get_bytes_from_http(url).await;
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl Ipc {
|
||||||
///
|
///
|
||||||
/// Once started, the server will begin accepting connections.
|
/// Once started, the server will begin accepting connections.
|
||||||
pub fn start(&self, application: &Application, ironbar: Rc<Ironbar>) {
|
pub fn start(&self, application: &Application, ironbar: Rc<Ironbar>) {
|
||||||
let (cmd_tx, mut cmd_rx) = mpsc::channel(32);
|
let (cmd_tx, cmd_rx) = mpsc::channel(32);
|
||||||
let (res_tx, mut res_rx) = mpsc::channel(32);
|
let (res_tx, mut res_rx) = mpsc::channel(32);
|
||||||
|
|
||||||
let path = self.path.clone();
|
let path = self.path.clone();
|
||||||
|
|
|
@ -58,13 +58,15 @@ macro_rules! try_send {
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! glib_recv {
|
macro_rules! glib_recv {
|
||||||
($rx:expr, $val:ident => $expr:expr) => {
|
($rx:expr, $val:ident => $expr:expr) => {{
|
||||||
glib::spawn_future_local(async move {
|
glib::spawn_future_local(async move {
|
||||||
while let Ok($val) = $rx.recv().await {
|
// re-delcare in case ie `context.subscribe()` is passed directly
|
||||||
|
let mut rx = $rx;
|
||||||
|
while let Ok($val) = rx.recv().await {
|
||||||
$expr
|
$expr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns a `GLib` future on the local thread, and calls `rx.recv()`
|
/// Spawns a `GLib` future on the local thread, and calls `rx.recv()`
|
||||||
|
@ -83,13 +85,15 @@ macro_rules! glib_recv {
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! glib_recv_mpsc {
|
macro_rules! glib_recv_mpsc {
|
||||||
($rx:expr, $val:ident => $expr:expr) => {
|
($rx:expr, $val:ident => $expr:expr) => {{
|
||||||
glib::spawn_future_local(async move {
|
glib::spawn_future_local(async move {
|
||||||
while let Some($val) = $rx.recv().await {
|
// re-delcare in case ie `context.subscribe()` is passed directly
|
||||||
|
let mut rx = $rx;
|
||||||
|
while let Some($val) = rx.recv().await {
|
||||||
$expr
|
$expr
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locks a `Mutex`.
|
/// Locks a `Mutex`.
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl Module<Button> for ClipboardModule {
|
||||||
fn into_popup(
|
fn into_popup(
|
||||||
self,
|
self,
|
||||||
tx: mpsc::Sender<Self::ReceiveMessage>,
|
tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||||
mut rx: broadcast::Receiver<Self::SendMessage>,
|
rx: broadcast::Receiver<Self::SendMessage>,
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Option<gtk::Box>
|
) -> Option<gtk::Box>
|
||||||
where
|
where
|
||||||
|
|
|
@ -110,7 +110,7 @@ impl Module<Button> for ClockModule {
|
||||||
let format = self.format.clone();
|
let format = self.format.clone();
|
||||||
let locale = Locale::try_from(self.locale.as_str()).unwrap_or(Locale::POSIX);
|
let locale = Locale::try_from(self.locale.as_str()).unwrap_or(Locale::POSIX);
|
||||||
|
|
||||||
let mut rx = context.subscribe();
|
let rx = context.subscribe();
|
||||||
glib_recv!(rx, date => {
|
glib_recv!(rx, date => {
|
||||||
let date_string = format!("{}", date.format_localized(&format, locale));
|
let date_string = format!("{}", date.format_localized(&format, locale));
|
||||||
label.set_label(&date_string);
|
label.set_label(&date_string);
|
||||||
|
@ -126,7 +126,7 @@ impl Module<Button> for ClockModule {
|
||||||
fn into_popup(
|
fn into_popup(
|
||||||
self,
|
self,
|
||||||
_tx: mpsc::Sender<Self::ReceiveMessage>,
|
_tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||||
mut rx: broadcast::Receiver<Self::SendMessage>,
|
rx: broadcast::Receiver<Self::SendMessage>,
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Option<gtk::Box> {
|
) -> Option<gtk::Box> {
|
||||||
let container = gtk::Box::new(Orientation::Vertical, 0);
|
let container = gtk::Box::new(Orientation::Vertical, 0);
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl CustomWidget for ProgressWidget {
|
||||||
let script = Script::from(value);
|
let script = Script::from(value);
|
||||||
let progress = progress.clone();
|
let progress = progress.clone();
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel(128);
|
let (tx, rx) = mpsc::channel(128);
|
||||||
|
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
script
|
script
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl CustomWidget for SliderWidget {
|
||||||
let script = Script::from(value);
|
let script = Script::from(value);
|
||||||
let scale = scale.clone();
|
let scale = scale.clone();
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel(128);
|
let (tx, rx) = mpsc::channel(128);
|
||||||
|
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
script
|
script
|
||||||
|
|
|
@ -337,7 +337,7 @@ impl Module<gtk::Box> for LauncherModule {
|
||||||
let mut buttons = IndexMap::<String, ItemButton>::new();
|
let mut buttons = IndexMap::<String, ItemButton>::new();
|
||||||
|
|
||||||
let tx = context.tx.clone();
|
let tx = context.tx.clone();
|
||||||
let mut rx = context.subscribe();
|
let rx = context.subscribe();
|
||||||
glib_recv!(rx, event => {
|
glib_recv!(rx, event => {
|
||||||
match event {
|
match event {
|
||||||
LauncherUpdate::AddItem(item) => {
|
LauncherUpdate::AddItem(item) => {
|
||||||
|
@ -428,7 +428,7 @@ impl Module<gtk::Box> for LauncherModule {
|
||||||
fn into_popup(
|
fn into_popup(
|
||||||
self,
|
self,
|
||||||
controller_tx: mpsc::Sender<Self::ReceiveMessage>,
|
controller_tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||||
mut rx: broadcast::Receiver<Self::SendMessage>,
|
rx: broadcast::Receiver<Self::SendMessage>,
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Option<gtk::Box> {
|
) -> Option<gtk::Box> {
|
||||||
const MAX_WIDTH: i32 = 250;
|
const MAX_WIDTH: i32 = 250;
|
||||||
|
|
|
@ -256,7 +256,7 @@ fn register_popup_content(
|
||||||
/// and communicating update messages between controllers and widgets/popups.
|
/// and communicating update messages between controllers and widgets/popups.
|
||||||
fn setup_receiver<TSend>(
|
fn setup_receiver<TSend>(
|
||||||
tx: broadcast::Sender<TSend>,
|
tx: broadcast::Sender<TSend>,
|
||||||
mut rx: mpsc::Receiver<ModuleUpdateEvent<TSend>>,
|
rx: mpsc::Receiver<ModuleUpdateEvent<TSend>>,
|
||||||
popup: Rc<RefCell<Popup>>,
|
popup: Rc<RefCell<Popup>>,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
id: usize,
|
id: usize,
|
||||||
|
|
|
@ -214,7 +214,7 @@ impl Module<Button> for MusicModule {
|
||||||
let button = button.clone();
|
let button = button.clone();
|
||||||
|
|
||||||
let tx = context.tx.clone();
|
let tx = context.tx.clone();
|
||||||
let mut rx = context.subscribe();
|
let rx = context.subscribe();
|
||||||
|
|
||||||
glib_recv!(rx, event => {
|
glib_recv!(rx, event => {
|
||||||
let ControllerEvent::Update(mut event) = event else {
|
let ControllerEvent::Update(mut event) = event else {
|
||||||
|
@ -263,7 +263,7 @@ impl Module<Button> for MusicModule {
|
||||||
fn into_popup(
|
fn into_popup(
|
||||||
self,
|
self,
|
||||||
tx: mpsc::Sender<Self::ReceiveMessage>,
|
tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||||
mut rx: broadcast::Receiver<Self::SendMessage>,
|
rx: broadcast::Receiver<Self::SendMessage>,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
) -> Option<gtk::Box> {
|
) -> Option<gtk::Box> {
|
||||||
let icon_theme = info.icon_theme;
|
let icon_theme = info.icon_theme;
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl Module<gtk::Button> for UpowerModule {
|
||||||
label.set_angle(info.bar_position.get_angle());
|
label.set_angle(info.bar_position.get_angle());
|
||||||
let format = self.format.clone();
|
let format = self.format.clone();
|
||||||
|
|
||||||
let mut rx = context.subscribe();
|
let rx = context.subscribe();
|
||||||
glib_recv!(rx, properties => {
|
glib_recv!(rx, properties => {
|
||||||
let format = format.replace("{percentage}", &properties.percentage.to_string());
|
let format = format.replace("{percentage}", &properties.percentage.to_string());
|
||||||
let icon_name = String::from("icon:") + &properties.icon_name;
|
let icon_name = String::from("icon:") + &properties.icon_name;
|
||||||
|
@ -203,7 +203,7 @@ impl Module<gtk::Button> for UpowerModule {
|
||||||
fn into_popup(
|
fn into_popup(
|
||||||
self,
|
self,
|
||||||
_tx: mpsc::Sender<Self::ReceiveMessage>,
|
_tx: mpsc::Sender<Self::ReceiveMessage>,
|
||||||
mut rx: broadcast::Receiver<Self::SendMessage>,
|
rx: broadcast::Receiver<Self::SendMessage>,
|
||||||
_info: &ModuleInfo,
|
_info: &ModuleInfo,
|
||||||
) -> Option<gtk::Box>
|
) -> Option<gtk::Box>
|
||||||
where
|
where
|
||||||
|
|
|
@ -10,7 +10,7 @@ use serde::Deserialize;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use tokio::sync::mpsc::{Receiver, Sender};
|
use tokio::sync::mpsc::{Receiver, Sender};
|
||||||
use tracing::trace;
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
@ -97,6 +97,10 @@ fn create_button(
|
||||||
style_context.add_class("focused");
|
style_context.add_class("focused");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !visibility.is_visible() {
|
||||||
|
style_context.add_class("inactive")
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
|
@ -158,9 +162,10 @@ impl Module<gtk::Box> for WorkspacesModule {
|
||||||
client.subscribe_workspace_change()
|
client.subscribe_workspace_change()
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("Set up Sway workspace subscription");
|
trace!("Set up workspace subscription");
|
||||||
|
|
||||||
while let Ok(payload) = srx.recv().await {
|
while let Ok(payload) = srx.recv().await {
|
||||||
|
debug!("Received update: {payload:?}");
|
||||||
send_async!(tx, ModuleUpdateEvent::Update(payload));
|
send_async!(tx, ModuleUpdateEvent::Update(payload));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -347,7 +352,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WorkspaceUpdate::Update(_) => {}
|
WorkspaceUpdate::Unknown => warn!("Received unknown type workspace event")
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn load_css(style_path: PathBuf) {
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_USER as u32,
|
GTK_STYLE_PROVIDER_PRIORITY_USER as u32,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::channel(8);
|
let (tx, rx) = mpsc::channel(8);
|
||||||
|
|
||||||
spawn(async move {
|
spawn(async move {
|
||||||
let style_path2 = style_path.clone();
|
let style_path2 = style_path.clone();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue