1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-01 10:41:03 +02:00

refactor: tidy and format

This commit is contained in:
Jake Stanger 2022-10-10 21:59:44 +01:00
parent b1c66b9117
commit 5ce50b0987
No known key found for this signature in database
GPG key ID: C51FC8F9CB0BEA61
10 changed files with 73 additions and 126 deletions

View file

@ -72,7 +72,7 @@ async fn main() -> Result<()> {
}; };
debug!("Loaded config file"); debug!("Loaded config file");
if let Err(err) = await_sync(create_bars(app, &display, wayland_client, &config)) { if let Err(err) = create_bars(app, &display, wayland_client, &config) {
error!("{:?}", err); error!("{:?}", err);
exit(2); exit(2);
} }
@ -102,7 +102,12 @@ async fn main() -> Result<()> {
} }
/// Creates each of the bars across each of the (configured) outputs. /// Creates each of the bars across each of the (configured) outputs.
async fn create_bars(app: &Application, display: &Display, wl: &WaylandClient, config: &Config) -> Result<()> { fn create_bars(
app: &Application,
display: &Display,
wl: &WaylandClient,
config: &Config,
) -> Result<()> {
let outputs = wl.outputs.as_slice(); let outputs = wl.outputs.as_slice();
debug!("Received {} outputs from Wayland", outputs.len()); debug!("Received {} outputs from Wayland", outputs.len());

View file

@ -1,5 +1,5 @@
use crate::modules::{Module, ModuleInfo, ModuleUpdateEvent, ModuleWidget, WidgetContext}; use crate::modules::{Module, ModuleInfo, ModuleUpdateEvent, ModuleWidget, WidgetContext};
use crate::wayland::{ToplevelChange}; use crate::wayland::ToplevelChange;
use crate::{await_sync, icon, wayland}; use crate::{await_sync, icon, wayland};
use color_eyre::Result; use color_eyre::Result;
use glib::Continue; use glib::Continue;
@ -51,10 +51,7 @@ impl Module<gtk::Box> for FocusedModule {
}); });
if let Some((top, _)) = focused { if let Some((top, _)) = focused {
tx.try_send(ModuleUpdateEvent::Update(( tx.try_send(ModuleUpdateEvent::Update((top.title.clone(), top.app_id)))?;
top.title.clone(),
top.app_id
)))?;
} }
spawn(async move { spawn(async move {
@ -67,7 +64,7 @@ impl Module<gtk::Box> for FocusedModule {
let update = match event.change { let update = match event.change {
ToplevelChange::Focus(focus) => focus, ToplevelChange::Focus(focus) => focus,
ToplevelChange::Title(_) => event.toplevel.active, ToplevelChange::Title(_) => event.toplevel.active,
_ => false _ => false,
}; };
if update { if update {

View file

@ -4,12 +4,12 @@ use crate::icon::get_icon;
use crate::modules::launcher::{ItemEvent, LauncherUpdate}; use crate::modules::launcher::{ItemEvent, LauncherUpdate};
use crate::modules::ModuleUpdateEvent; use crate::modules::ModuleUpdateEvent;
use crate::popup::Popup; use crate::popup::Popup;
use crate::wayland::ToplevelInfo;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{Button, IconTheme, Image}; use gtk::{Button, IconTheme, Image};
use std::rc::Rc; use std::rc::Rc;
use std::sync::RwLock; use std::sync::RwLock;
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
use crate::wayland::ToplevelInfo;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Item { pub struct Item {

View file

@ -108,7 +108,7 @@ impl Module<gtk::Box> for LauncherModule {
let mut items = items.lock().expect("Failed to get lock on items"); let mut items = items.lock().expect("Failed to get lock on items");
for (window, _) in open_windows.clone().into_iter() { for (window, _) in open_windows.clone() {
let item = items.get_mut(&window.app_id); let item = items.get_mut(&window.app_id);
match item { match item {
Some(item) => { Some(item) => {
@ -154,7 +154,8 @@ impl Module<gtk::Box> for LauncherModule {
ToplevelChange::New => { ToplevelChange::New => {
let new_item = { let new_item = {
let mut items = items(); let mut items = items();
match items.get_mut(&app_id) { let item = items.get_mut(&app_id);
match item {
None => { None => {
let item: Item = window.into(); let item: Item = window.into();
items.insert(app_id.clone(), item.clone()); items.insert(app_id.clone(), item.clone());
@ -180,7 +181,8 @@ impl Module<gtk::Box> for LauncherModule {
ToplevelChange::Close => { ToplevelChange::Close => {
let remove_item = { let remove_item = {
let mut items = items(); let mut items = items();
match items.get_mut(&app_id) { let item = items.get_mut(&app_id);
match item {
Some(item) => { Some(item) => {
item.unmerge_toplevel(&window); item.unmerge_toplevel(&window);
@ -239,7 +241,7 @@ impl Module<gtk::Box> for LauncherModule {
send_update(LauncherUpdate::Title(app_id, window.id, title)).await?; send_update(LauncherUpdate::Title(app_id, window.id, title)).await?;
} }
_ => {} ToplevelChange::Fullscreen(_) => {}
} }
} }
@ -290,7 +292,7 @@ impl Module<gtk::Box> for LauncherModule {
.toplevels .toplevels
.read() .read()
.expect("Failed to get read lock on toplevels"); .expect("Failed to get read lock on toplevels");
let seat = wl.seats.first().unwrap(); let seat = wl.seats.first().expect("Failed to get Wayland seat");
if let Some((_top, handle)) = toplevels.get(&id) { if let Some((_top, handle)) = toplevels.get(&id) {
handle.activate(seat); handle.activate(seat);
}; };

View file

@ -3,50 +3,37 @@ use color_eyre::Report;
use futures_util::StreamExt; use futures_util::StreamExt;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::sync::Arc; use std::sync::Arc;
use swayipc_async::{Connection, Event, EventType, WindowEvent, WorkspaceEvent}; use swayipc_async::{Connection, Event, EventType, WorkspaceEvent};
use tokio::spawn; use tokio::spawn;
use tokio::sync::broadcast::{channel, Receiver, Sender}; use tokio::sync::broadcast::{channel, Receiver, Sender};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tracing::{info, trace}; use tracing::{info, trace};
pub mod node;
pub struct SwayEventClient { pub struct SwayEventClient {
workspace_tx: Sender<Box<WorkspaceEvent>>, workspace_tx: Sender<Box<WorkspaceEvent>>,
_workspace_rx: Receiver<Box<WorkspaceEvent>>, _workspace_rx: Receiver<Box<WorkspaceEvent>>,
window_tx: Sender<Box<WindowEvent>>,
_window_rx: Receiver<Box<WindowEvent>>,
} }
impl SwayEventClient { impl SwayEventClient {
fn new() -> Self { fn new() -> Self {
let (workspace_tx, workspace_rx) = channel(16); let (workspace_tx, workspace_rx) = channel(16);
let (window_tx, window_rx) = channel(16);
let workspace_tx2 = workspace_tx.clone(); let workspace_tx2 = workspace_tx.clone();
let window_tx2 = window_tx.clone();
spawn(async move { spawn(async move {
let workspace_tx = workspace_tx2; let workspace_tx = workspace_tx2;
let window_tx = window_tx2;
let client = Connection::new().await?; let client = Connection::new().await?;
info!("Sway IPC subscription client connected"); info!("Sway IPC subscription client connected");
let event_types = [EventType::Window, EventType::Workspace]; let event_types = [EventType::Workspace];
let mut events = client.subscribe(event_types).await?; let mut events = client.subscribe(event_types).await?;
while let Some(event) = events.next().await { while let Some(event) = events.next().await {
trace!("event: {:?}", event); trace!("event: {:?}", event);
match event? { if let Event::Workspace(ev) = event? {
Event::Workspace(ev) => { workspace_tx.send(ev)?;
workspace_tx.send(ev)?;
}
Event::Window(ev) => {
window_tx.send(ev)?;
}
_ => {}
}; };
} }
@ -56,8 +43,6 @@ impl SwayEventClient {
Self { Self {
workspace_tx, workspace_tx,
_workspace_rx: workspace_rx, _workspace_rx: workspace_rx,
window_tx,
_window_rx: window_rx,
} }
} }
@ -65,11 +50,6 @@ impl SwayEventClient {
pub fn subscribe_workspace(&self) -> Receiver<Box<WorkspaceEvent>> { pub fn subscribe_workspace(&self) -> Receiver<Box<WorkspaceEvent>> {
self.workspace_tx.subscribe() self.workspace_tx.subscribe()
} }
/// Gets an event receiver for window events
pub fn subscribe_window(&self) -> Receiver<Box<WindowEvent>> {
self.window_tx.subscribe()
}
} }
lazy_static! { lazy_static! {

View file

@ -1,50 +0,0 @@
use color_eyre::Result;
use swayipc_async::{Connection, Node, NodeType, ShellType};
pub fn get_node_id(node: &Node) -> &str {
node.app_id.as_ref().map_or_else(
|| {
node.window_properties
.as_ref()
.expect("Cannot find node window properties")
.class
.as_ref()
.expect("Cannot find node name")
},
|app_id| app_id,
)
}
/// Checks whether this application
/// is running under xwayland.
pub fn is_node_xwayland(node: &Node) -> bool {
node.shell == Some(ShellType::Xwayland)
}
/// Recursively checks the provided node for any child application nodes.
/// Returns a list of any found application nodes.
fn check_node(node: Node, window_nodes: &mut Vec<Node>) {
if node.name.is_some()
&& (node.node_type == NodeType::Con || node.node_type == NodeType::FloatingCon)
{
window_nodes.push(node);
} else {
node.nodes.into_iter().for_each(|node| {
check_node(node, window_nodes);
});
node.floating_nodes.into_iter().for_each(|node| {
check_node(node, window_nodes);
});
}
}
/// Gets a flat vector of all currently open windows.
pub async fn get_open_windows(client: &mut Connection) -> Result<Vec<Node>> {
let root_node = client.get_tree().await?;
let mut window_nodes = vec![];
check_node(root_node, &mut window_nodes);
Ok(window_nodes)
}

View file

@ -12,11 +12,11 @@ use std::time::Duration;
use tokio::sync::{broadcast, oneshot}; use tokio::sync::{broadcast, oneshot};
use tokio::task::spawn_blocking; use tokio::task::spawn_blocking;
use tracing::trace; use tracing::trace;
use wayland_client::protocol::wl_seat::WlSeat;
use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::{ use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::{
zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1, zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1,
zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1, zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1,
}; };
use wayland_client::protocol::wl_seat::WlSeat;
pub struct WaylandClient { pub struct WaylandClient {
pub outputs: Vec<OutputInfo>, pub outputs: Vec<OutputInfo>,
@ -30,6 +30,7 @@ impl WaylandClient {
pub(super) async fn new() -> Self { pub(super) async fn new() -> Self {
let (output_tx, output_rx) = oneshot::channel(); let (output_tx, output_rx) = oneshot::channel();
let (seat_tx, seat_rx) = oneshot::channel(); let (seat_tx, seat_rx) = oneshot::channel();
let (toplevel_tx, toplevel_rx) = broadcast::channel(32); let (toplevel_tx, toplevel_rx) = broadcast::channel(32);
let toplevel_tx2 = toplevel_tx.clone(); let toplevel_tx2 = toplevel_tx.clone();
@ -49,23 +50,30 @@ impl WaylandClient {
.expect("Failed to send outputs out of task"); .expect("Failed to send outputs out of task");
let seats = env.get_all_seats(); let seats = env.get_all_seats();
seat_tx.send(seats.into_iter().map(|seat| seat.detach()).collect::<Vec<WlSeat>>()).expect("Failed to send seats out of task"); seat_tx
.send(
seats
.into_iter()
.map(|seat| seat.detach())
.collect::<Vec<WlSeat>>(),
)
.expect("Failed to send seats out of task");
let _toplevel_manager = env.require_global::<ZwlrForeignToplevelManagerV1>(); let _toplevel_manager = env.require_global::<ZwlrForeignToplevelManagerV1>();
let _listener = listen_for_toplevels(env, move |handle, event, _ddata| { let _listener = listen_for_toplevels(env, move |handle, event, _ddata| {
trace!("Received toplevel event: {:?}", event); trace!("Received toplevel event: {:?}", event);
if event.change != ToplevelChange::Close { if event.change == ToplevelChange::Close {
toplevels2
.write()
.expect("Failed to get write lock on toplevels")
.insert(event.toplevel.id, (event.toplevel.clone(), handle));
} else {
toplevels2 toplevels2
.write() .write()
.expect("Failed to get write lock on toplevels") .expect("Failed to get write lock on toplevels")
.remove(&event.toplevel.id); .remove(&event.toplevel.id);
} else {
toplevels2
.write()
.expect("Failed to get write lock on toplevels")
.insert(event.toplevel.id, (event.toplevel.clone(), handle));
} }
toplevel_tx2 toplevel_tx2
@ -73,15 +81,17 @@ impl WaylandClient {
.expect("Failed to send toplevel event"); .expect("Failed to send toplevel event");
}); });
let mut event_loop = calloop::EventLoop::<()>::try_new().unwrap(); let mut event_loop =
calloop::EventLoop::<()>::try_new().expect("Failed to create new event loop");
WaylandSource::new(queue) WaylandSource::new(queue)
.quick_insert(event_loop.handle()) .quick_insert(event_loop.handle())
.unwrap(); .expect("Failed to insert event loop into wayland event queue");
loop { loop {
// TODO: Avoid need for duration here - can we force some event when sending requests? // TODO: Avoid need for duration here - can we force some event when sending requests?
event_loop.dispatch(Duration::from_millis(50), &mut ()).unwrap(); event_loop
event_loop. .dispatch(Duration::from_millis(50), &mut ())
.expect("Failed to dispatch pending wayland events");
} }
}); });
@ -109,7 +119,7 @@ impl WaylandClient {
outputs outputs
.iter() .iter()
.filter_map(|output| with_output_info(output, |info| info.clone())) .filter_map(|output| with_output_info(output, Clone::clone))
.collect() .collect()
} }
} }

View file

@ -18,7 +18,7 @@ use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::{
pub use client::WaylandClient; pub use client::WaylandClient;
/// A utility for lazy-loading globals. /// A utility for lazy-loading globals.
/// Taken from smithay_client_toolkit where it's not exposed /// Taken from `smithay_client_toolkit` where it's not exposed
#[derive(Debug)] #[derive(Debug)]
enum LazyGlobal<I: Interface> { enum LazyGlobal<I: Interface> {
Unknown, Unknown,

View file

@ -8,7 +8,9 @@ const STATE_ACTIVE: u32 = 2;
const STATE_FULLSCREEN: u32 = 3; const STATE_FULLSCREEN: u32 = 3;
static COUNTER: AtomicUsize = AtomicUsize::new(1); static COUNTER: AtomicUsize = AtomicUsize::new(1);
fn get_id() -> usize { COUNTER.fetch_add(1, Ordering::Relaxed) } fn get_id() -> usize {
COUNTER.fetch_add(1, Ordering::Relaxed)
}
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct ToplevelInfo { pub struct ToplevelInfo {
@ -24,7 +26,10 @@ pub struct ToplevelInfo {
impl ToplevelInfo { impl ToplevelInfo {
fn new() -> Self { fn new() -> Self {
let id = get_id(); let id = get_id();
Self { id, ..Default::default() } Self {
id,
..Default::default()
}
} }
} }
@ -99,11 +104,11 @@ where
Event::Parent { parent: _ } => None, Event::Parent { parent: _ } => None,
Event::Done => { Event::Done => {
assert_ne!(info.app_id, ""); assert_ne!(info.app_id, "");
if !info.ready { if info.ready {
None
} else {
info.ready = true; info.ready = true;
Some(ToplevelChange::New) Some(ToplevelChange::New)
} else {
None
} }
} }
_ => unreachable!(), _ => unreachable!(),
@ -120,7 +125,7 @@ where
} }
impl Toplevel { impl Toplevel {
pub fn init<F>(handle: Main<ZwlrForeignToplevelHandleV1>, mut callback: F) -> Self pub fn init<F>(handle: &Main<ZwlrForeignToplevelHandleV1>, mut callback: F) -> Self
where where
F: FnMut(ToplevelEvent, DispatchData) + 'static, F: FnMut(ToplevelEvent, DispatchData) + 'static,
{ {
@ -130,7 +135,7 @@ impl Toplevel {
let mut inner = inner let mut inner = inner
.write() .write()
.expect("Failed to get write lock on toplevel inner state"); .expect("Failed to get write lock on toplevel inner state");
toplevel_implem(event, &mut *inner, &mut callback, ddata); toplevel_implem(event, &mut inner, &mut callback, ddata);
}); });
Self Self

View file

@ -12,7 +12,6 @@ use wayland_protocols::wlr::unstable::foreign_toplevel::v1::client::{
zwlr_foreign_toplevel_manager_v1::{self, ZwlrForeignToplevelManagerV1}, zwlr_foreign_toplevel_manager_v1::{self, ZwlrForeignToplevelManagerV1},
}; };
struct ToplevelHandlerInner { struct ToplevelHandlerInner {
manager: LazyGlobal<ZwlrForeignToplevelManagerV1>, manager: LazyGlobal<ZwlrForeignToplevelManagerV1>,
registry: Option<Attached<WlRegistry>>, registry: Option<Attached<WlRegistry>>,
@ -20,7 +19,7 @@ struct ToplevelHandlerInner {
} }
impl ToplevelHandlerInner { impl ToplevelHandlerInner {
fn new() -> Self { const fn new() -> Self {
let toplevels = vec![]; let toplevels = vec![];
Self { Self {
@ -64,7 +63,7 @@ impl GlobalHandler<ZwlrForeignToplevelManagerV1> for ToplevelHandler {
} else { } else {
warn!( warn!(
"Compositor advertised zwlr_foreign_toplevel_manager_v1 multiple times, ignoring." "Compositor advertised zwlr_foreign_toplevel_manager_v1 multiple times, ignoring."
) );
} }
} }
@ -92,14 +91,15 @@ impl GlobalHandler<ZwlrForeignToplevelManagerV1> for ToplevelHandler {
zwlr_foreign_toplevel_manager_v1::Event::Toplevel { zwlr_foreign_toplevel_manager_v1::Event::Toplevel {
toplevel: handle, toplevel: handle,
} => { } => {
let toplevel = Toplevel::init(handle.clone(), move |event, ddata| { let toplevel =
notify_status_listeners( Toplevel::init(&handle.clone(), move |event, ddata| {
&handle, notify_status_listeners(
event, &handle,
ddata, &event,
&status_listeners, ddata,
); &status_listeners,
}); );
});
inner.toplevels.push(toplevel); inner.toplevels.push(toplevel);
} }
@ -122,18 +122,16 @@ type ToplevelStatusCallback =
/// Notifies the callbacks of an event on the toplevel /// Notifies the callbacks of an event on the toplevel
fn notify_status_listeners( fn notify_status_listeners(
toplevel: &ZwlrForeignToplevelHandleV1, toplevel: &ZwlrForeignToplevelHandleV1,
event: ToplevelEvent, event: &ToplevelEvent,
mut ddata: DispatchData, mut ddata: DispatchData,
listeners: &RefCell<Vec<rc::Weak<RefCell<ToplevelStatusCallback>>>>, listeners: &RefCell<Vec<rc::Weak<RefCell<ToplevelStatusCallback>>>>,
) { ) {
listeners.borrow_mut().retain(|lst| { listeners.borrow_mut().retain(|lst| {
if let Some(cb) = rc::Weak::upgrade(lst) { rc::Weak::upgrade(lst).map_or(false, |cb| {
(cb.borrow_mut())(toplevel.clone(), event.clone(), ddata.reborrow()); (cb.borrow_mut())(toplevel.clone(), event.clone(), ddata.reborrow());
true true
} else { })
false });
}
})
} }
pub struct ToplevelStatusListener { pub struct ToplevelStatusListener {