Change niri event subscription loop to cache the state of current workspaces
This commit is contained in:
parent
e64359806c
commit
bcb60ea839
1 changed files with 57 additions and 49 deletions
|
@ -1,6 +1,6 @@
|
|||
|
||||
use std::io;
|
||||
use super::{CompositorInterface, WorkspaceVisible, EventSender};
|
||||
use niri_ipc::{socket::Socket, Event, Request, Response};
|
||||
use niri_ipc::{socket::Socket, Event, Request, Response, Workspace};
|
||||
|
||||
pub struct NiriConnectionTask {}
|
||||
|
||||
|
@ -8,60 +8,68 @@ impl NiriConnectionTask {
|
|||
pub fn new() -> Self {
|
||||
NiriConnectionTask {}
|
||||
}
|
||||
|
||||
fn query_workspace(&self, id: u64) -> (String, String) {
|
||||
if let Ok((Ok(Response::Workspaces(workspaces)), _)) = Socket::connect()
|
||||
.expect("failed to connect to niri socket")
|
||||
.send(Request::Workspaces)
|
||||
{
|
||||
if let Some(workspace) = workspaces.into_iter().find(|w| w.id == id) {
|
||||
return (
|
||||
workspace.name.unwrap_or_else(|| format!("{}", workspace.idx)),
|
||||
workspace.output.unwrap_or_else(String::new),
|
||||
);
|
||||
}
|
||||
panic!("unknown workspace id");
|
||||
} else {
|
||||
panic!("niri workspace query failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CompositorInterface for NiriConnectionTask {
|
||||
fn request_visible_workspaces(&mut self) -> Vec<WorkspaceVisible> {
|
||||
if let Ok((Ok(Response::Workspaces(workspaces)), _)) = Socket::connect()
|
||||
.expect("failed to connect to niri socket")
|
||||
.send(Request::Workspaces)
|
||||
{
|
||||
workspaces
|
||||
.into_iter()
|
||||
.filter(|w| w.is_active)
|
||||
.map(|workspace| WorkspaceVisible {
|
||||
output: workspace.output.unwrap_or_default(),
|
||||
workspace_name: workspace.name
|
||||
.unwrap_or_else(|| format!("{}", workspace.idx)),
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
panic!("unable to retrieve niri workspaces")
|
||||
}
|
||||
request_workspaces().into_iter()
|
||||
.filter(|w| w.is_active)
|
||||
.map(|workspace| WorkspaceVisible {
|
||||
output: workspace.output.unwrap_or_default(),
|
||||
workspace_name: workspace.name
|
||||
.unwrap_or_else(|| format!("{}", workspace.idx)),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn subscribe_event_loop(self, event_sender: EventSender) {
|
||||
if let Ok((Ok(Response::Handled), mut callback)) = Socket::connect()
|
||||
.expect("failed to connect to niri socket")
|
||||
.send(Request::EventStream)
|
||||
{
|
||||
while let Ok(event) = callback() {
|
||||
if let Event::WorkspaceActivated { id, focused: _ } = event {
|
||||
let (workspace_name, output) = self.query_workspace(id);
|
||||
event_sender.send(WorkspaceVisible {
|
||||
output,
|
||||
workspace_name,
|
||||
});
|
||||
}
|
||||
let mut workspaces_state = request_workspaces();
|
||||
let mut callback = request_event_stream();
|
||||
while let Ok(event) = callback() {
|
||||
match event {
|
||||
Event::WorkspaceActivated { id, focused: _ } => {
|
||||
let visible_workspace =
|
||||
find_workspace(&workspaces_state, id);
|
||||
event_sender.send(visible_workspace);
|
||||
},
|
||||
Event::WorkspacesChanged { workspaces } => {
|
||||
workspaces_state = workspaces
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
} else {
|
||||
panic!("failed to subscribe to event stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_workspace(workspaces: &[Workspace], id: u64) -> WorkspaceVisible {
|
||||
let workspace = workspaces.iter()
|
||||
.find(|workspace| workspace.id == id)
|
||||
.expect("Unknown niri workspace id {id}");
|
||||
let workspace_name = workspace.name.clone()
|
||||
.unwrap_or_else(|| format!("{}", workspace.idx));
|
||||
let output = workspace.output.clone().unwrap_or_default();
|
||||
WorkspaceVisible { output, workspace_name }
|
||||
}
|
||||
|
||||
fn request_event_stream() -> impl FnMut() -> Result<Event, io::Error> {
|
||||
let Ok((Ok(Response::Handled), callback)) = Socket::connect()
|
||||
.expect("failed to connect to niri socket")
|
||||
.send(Request::EventStream)
|
||||
else {
|
||||
panic!("failed to subscribe to event stream");
|
||||
};
|
||||
callback
|
||||
}
|
||||
|
||||
fn request_workspaces() -> Vec<Workspace> {
|
||||
let response = Socket::connect()
|
||||
.expect("failed to connect to niri socket")
|
||||
.send(Request::Workspaces)
|
||||
.expect("failed to send niri ipc request")
|
||||
.0
|
||||
.expect("niri workspace query failed");
|
||||
let Response::Workspaces(workspaces) = response else {
|
||||
panic!("unexpected response from niri");
|
||||
};
|
||||
workspaces
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue