Refactor CompositorInterface to expose fewer multibg implementation details

This commit is contained in:
Florian Finkernagel 2025-04-08 08:47:56 +02:00 committed by Gergő Sályi
parent 1fdbd7ffb0
commit 4b02797e16
3 changed files with 60 additions and 97 deletions

View file

@ -1,15 +1,13 @@
mod niri; mod niri;
mod sway; mod sway;
use std::{ use std::{env, os::unix::ffi::OsStrExt};
env,
os::unix::ffi::OsStrExt,
};
use log::{debug, warn}; use log::{debug, warn};
use mio::Waker; use mio::Waker;
use std::{ use std::{
sync::{mpsc::Sender, Arc}, thread::spawn sync::{mpsc::Sender, Arc},
thread::spawn,
}; };
#[derive(Clone, Copy, Debug, clap::ValueEnum)] #[derive(Clone, Copy, Debug, clap::ValueEnum)]
@ -34,8 +32,10 @@ impl Compositor {
debug!("Selecting compositor Niri based on {xdg_desktop_var}"); debug!("Selecting compositor Niri based on {xdg_desktop_var}");
Some(Compositor::Niri) Some(Compositor::Niri)
} else { } else {
warn!("Unrecognized compositor from {xdg_desktop_var} \ warn!(
environment variable: {xdg_desktop:?}"); "Unrecognized compositor from {xdg_desktop_var} \
environment variable: {xdg_desktop:?}"
);
None None
} }
} else { } else {
@ -67,13 +67,7 @@ impl Compositor {
// } // }
pub trait CompositorInterface: Send + Sync { pub trait CompositorInterface: Send + Sync {
fn request_visible_workspace( fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible>;
&mut self,
output: &str,
tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>,
);
fn request_visible_workspaces(&mut self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>);
fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>); fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>);
} }
@ -115,13 +109,37 @@ impl ConnectionTask {
} }
pub fn request_visible_workspace(&mut self, output: &str) { pub fn request_visible_workspace(&mut self, output: &str) {
self.interface if let Some(workspace) = self
.request_visible_workspace(output, self.tx.clone(), self.waker.clone()); .interface
.request_visible_workspaces()
.into_iter()
.find(|w| w.output == output)
{
self.tx
.send(WorkspaceVisible {
output: workspace.output,
workspace_name: workspace.workspace_name,
})
.unwrap();
self.waker.wake().unwrap();
}
} }
pub fn request_visible_workspaces(&mut self) { pub fn request_visible_workspaces(&mut self) {
self.interface for workspace in self
.request_visible_workspaces(self.tx.clone(), self.waker.clone()); .interface
.request_visible_workspaces()
.into_iter()
{
self.tx.send(WorkspaceVisible {
output: workspace.output,
workspace_name: workspace.workspace_name,
})
.unwrap();
self.waker.wake().unwrap();
}
} }
} }

View file

@ -29,46 +29,24 @@ impl NiriConnectionTask {
} }
} }
impl CompositorInterface for NiriConnectionTask { impl CompositorInterface for NiriConnectionTask {
fn request_visible_workspace( fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible>{
&mut self,
output: &str,
tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>,
) {
if let Ok((Ok(Response::Workspaces(workspaces)), _)) = Socket::connect() if let Ok((Ok(Response::Workspaces(workspaces)), _)) = Socket::connect()
.expect("failed to connect to niri socket") .expect("failed to connect to niri socket")
.send(Request::Workspaces) .send(Request::Workspaces)
{ {
if let Some(workspace) = workspaces return workspaces
.into_iter() .into_iter()
.filter(|w| w.is_focused) .filter(|w| w.is_active)
.find(|w| w.output.as_ref().map_or("", |v| v) == output) .map(|workspace| {
{ WorkspaceVisible {
tx.send(WorkspaceVisible { output: workspace.output.unwrap_or_else(String::new),
output: workspace.output.unwrap_or_else(String::new), workspace_name: workspace.name.unwrap_or_else(String::new),
workspace_name: workspace.name.unwrap_or_else(String::new), }
}) })
.unwrap(); .collect()
} else
waker.wake().unwrap();
}
}
}
fn request_visible_workspaces(&mut self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) {
if let Ok((Ok(Response::Workspaces(workspaces)), _)) = Socket::connect()
.expect("failed to connect to niri socket")
.send(Request::Workspaces)
{ {
for workspace in workspaces.into_iter().filter(|w| w.is_active) { panic!("unable to retrieve niri workspaces")
tx.send(WorkspaceVisible {
output: workspace.output.unwrap_or_else(String::new),
workspace_name: workspace.name.unwrap_or_else(String::new),
})
.unwrap();
waker.wake().unwrap();
}
} }
} }

View file

@ -1,6 +1,4 @@
use std::{ use std::sync::{mpsc::Sender, Arc};
sync::{mpsc::Sender, Arc},
};
use super::{CompositorInterface, WorkspaceVisible}; use super::{CompositorInterface, WorkspaceVisible};
use mio::Waker; use mio::Waker;
@ -19,47 +17,17 @@ impl SwayConnectionTask {
} }
impl CompositorInterface for SwayConnectionTask { impl CompositorInterface for SwayConnectionTask {
fn request_visible_workspace( fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible> {
&mut self, self.sway_conn
output: &str,
tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>,
) {
if let Some(workspace) = self
.sway_conn
.get_workspaces() .get_workspaces()
.unwrap() .unwrap()
.into_iter() .into_iter()
.filter(|w| w.visible) .filter(|w| w.visible)
.find(|w| w.output == output) .map(|workspace| WorkspaceVisible {
{ output: workspace.output,
tx workspace_name: workspace.name,
.send(WorkspaceVisible { })
output: workspace.output, .collect()
workspace_name: workspace.name,
})
.unwrap();
waker.wake().unwrap();
}
}
fn request_visible_workspaces(&mut self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) {
for workspace in self
.sway_conn
.get_workspaces()
.unwrap()
.into_iter()
.filter(|w| w.visible)
{
tx
.send(WorkspaceVisible {
output: workspace.output,
workspace_name: workspace.name,
})
.unwrap();
}
waker.wake().unwrap();
} }
fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) { fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) {
@ -72,12 +40,11 @@ impl CompositorInterface for SwayConnectionTask {
if let WorkspaceChange::Focus = workspace_event.change { if let WorkspaceChange::Focus = workspace_event.change {
let current_workspace = workspace_event.current.unwrap(); let current_workspace = workspace_event.current.unwrap();
tx tx.send(WorkspaceVisible {
.send(WorkspaceVisible { output: current_workspace.output.unwrap(),
output: current_workspace.output.unwrap(), workspace_name: current_workspace.name.unwrap(),
workspace_name: current_workspace.name.unwrap(), })
}) .unwrap();
.unwrap();
waker.wake().unwrap(); waker.wake().unwrap();
} }