refactor CompositorInterface.subscribe_event_loop to separate concerns

This commit is contained in:
Florian Finkernagel 2025-04-08 08:59:32 +02:00 committed by Gergő Sályi
parent 4b02797e16
commit dfa2580bdc
3 changed files with 44 additions and 45 deletions

View file

@ -66,11 +66,28 @@ impl Compositor {
// } // }
// } // }
pub trait CompositorInterface: Send + Sync { /// abstract 'sending back workspace change events'
fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible>; pub (self) struct EventSender {
fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>); tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>,
} }
impl EventSender {
fn new(tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) -> Self {
EventSender { tx, waker }
}
fn send(&self, workspace: WorkspaceVisible) {
self.tx.send(workspace).unwrap();
self.waker.wake().unwrap();
}
}
pub (self) trait CompositorInterface: Send + Sync {
fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible>;
fn subscribe_event_loop(self, event_sender: EventSender);
}
pub struct ConnectionTask { pub struct ConnectionTask {
tx: Sender<WorkspaceVisible>, tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>, waker: Arc<Waker>,
@ -96,14 +113,15 @@ impl ConnectionTask {
tx: Sender<WorkspaceVisible>, tx: Sender<WorkspaceVisible>,
waker: Arc<Waker>, waker: Arc<Waker>,
) { ) {
let event_sender = EventSender::new(tx, waker);
spawn(move || match composer { spawn(move || match composer {
Compositor::Sway => { Compositor::Sway => {
let composer_interface = sway::SwayConnectionTask::new(); let composer_interface = sway::SwayConnectionTask::new();
composer_interface.subscribe_event_loop(tx, waker); composer_interface.subscribe_event_loop(event_sender);
} }
Compositor::Niri => { Compositor::Niri => {
let composer_interface = niri::NiriConnectionTask::new(); let composer_interface = niri::NiriConnectionTask::new();
composer_interface.subscribe_event_loop(tx, waker); composer_interface.subscribe_event_loop(event_sender);
} }
}); });
} }
@ -127,12 +145,9 @@ impl ConnectionTask {
} }
pub fn request_visible_workspaces(&mut self) { pub fn request_visible_workspaces(&mut self) {
for workspace in self for workspace in self.interface.request_visible_workspaces().into_iter() {
.interface self.tx
.request_visible_workspaces() .send(WorkspaceVisible {
.into_iter()
{
self.tx.send(WorkspaceVisible {
output: workspace.output, output: workspace.output,
workspace_name: workspace.workspace_name, workspace_name: workspace.workspace_name,
}) })

View file

@ -1,7 +1,5 @@
use std::sync::{mpsc::Sender, Arc};
use super::{CompositorInterface, WorkspaceVisible}; use super::{CompositorInterface, WorkspaceVisible, EventSender};
use mio::Waker;
use niri_ipc::{socket::Socket, Event, Request, Response}; use niri_ipc::{socket::Socket, Event, Request, Response};
pub struct NiriConnectionTask {} pub struct NiriConnectionTask {}
@ -29,7 +27,7 @@ impl NiriConnectionTask {
} }
} }
impl CompositorInterface for NiriConnectionTask { impl CompositorInterface for NiriConnectionTask {
fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible>{ fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible> {
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)
@ -37,20 +35,17 @@ impl CompositorInterface for NiriConnectionTask {
return workspaces return workspaces
.into_iter() .into_iter()
.filter(|w| w.is_active) .filter(|w| w.is_active)
.map(|workspace| { .map(|workspace| WorkspaceVisible {
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),
}
}) })
.collect() .collect();
} else } else {
{
panic!("unable to retrieve niri workspaces") panic!("unable to retrieve niri workspaces")
} }
} }
fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) { fn subscribe_event_loop(self, event_sender: EventSender) {
if let Ok((Ok(Response::Handled), mut callback)) = Socket::connect() if let Ok((Ok(Response::Handled), mut callback)) = Socket::connect()
.expect("failed to connect to niri socket") .expect("failed to connect to niri socket")
.send(Request::EventStream) .send(Request::EventStream)
@ -58,14 +53,10 @@ impl CompositorInterface for NiriConnectionTask {
while let Ok(event) = callback() { while let Ok(event) = callback() {
if let Event::WorkspaceActivated { id, focused: _ } = event { if let Event::WorkspaceActivated { id, focused: _ } = event {
let (workspace_name, output) = self.query_workspace(id); let (workspace_name, output) = self.query_workspace(id);
event_sender.send(WorkspaceVisible {
tx.send(WorkspaceVisible {
output, output,
workspace_name, workspace_name,
}) });
.unwrap();
waker.wake().unwrap();
} }
} }
} else { } else {

View file

@ -1,7 +1,4 @@
use std::sync::{mpsc::Sender, Arc}; use super::{CompositorInterface, WorkspaceVisible, EventSender};
use super::{CompositorInterface, WorkspaceVisible};
use mio::Waker;
use swayipc::{Connection, Event, EventType, WorkspaceChange}; use swayipc::{Connection, Event, EventType, WorkspaceChange};
pub struct SwayConnectionTask { pub struct SwayConnectionTask {
@ -30,7 +27,7 @@ impl CompositorInterface for SwayConnectionTask {
.collect() .collect()
} }
fn subscribe_event_loop(self, tx: Sender<WorkspaceVisible>, waker: Arc<Waker>) { fn subscribe_event_loop(self, event_sender: EventSender) {
let event_stream = self.sway_conn.subscribe([EventType::Workspace]).unwrap(); let event_stream = self.sway_conn.subscribe([EventType::Workspace]).unwrap();
for event_result in event_stream { for event_result in event_stream {
let event = event_result.unwrap(); let event = event_result.unwrap();
@ -39,14 +36,10 @@ 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();
event_sender.send(WorkspaceVisible {
tx.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();
waker.wake().unwrap();
} }
} }
} }