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 super::{CompositorInterface, WorkspaceVisible, EventSender};
|
||||||
use niri_ipc::{socket::Socket, Event, Request, Response};
|
use niri_ipc::{socket::Socket, Event, Request, Response, Workspace};
|
||||||
|
|
||||||
pub struct NiriConnectionTask {}
|
pub struct NiriConnectionTask {}
|
||||||
|
|
||||||
|
@ -8,32 +8,11 @@ impl NiriConnectionTask {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
NiriConnectionTask {}
|
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 {
|
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()
|
request_workspaces().into_iter()
|
||||||
.expect("failed to connect to niri socket")
|
|
||||||
.send(Request::Workspaces)
|
|
||||||
{
|
|
||||||
workspaces
|
|
||||||
.into_iter()
|
|
||||||
.filter(|w| w.is_active)
|
.filter(|w| w.is_active)
|
||||||
.map(|workspace| WorkspaceVisible {
|
.map(|workspace| WorkspaceVisible {
|
||||||
output: workspace.output.unwrap_or_default(),
|
output: workspace.output.unwrap_or_default(),
|
||||||
|
@ -41,27 +20,56 @@ impl CompositorInterface for NiriConnectionTask {
|
||||||
.unwrap_or_else(|| format!("{}", workspace.idx)),
|
.unwrap_or_else(|| format!("{}", workspace.idx)),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
|
||||||
panic!("unable to retrieve niri workspaces")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscribe_event_loop(self, event_sender: EventSender) {
|
fn subscribe_event_loop(self, event_sender: EventSender) {
|
||||||
if let Ok((Ok(Response::Handled), mut callback)) = Socket::connect()
|
let mut workspaces_state = request_workspaces();
|
||||||
.expect("failed to connect to niri socket")
|
let mut callback = request_event_stream();
|
||||||
.send(Request::EventStream)
|
|
||||||
{
|
|
||||||
while let Ok(event) = callback() {
|
while let Ok(event) = callback() {
|
||||||
if let Event::WorkspaceActivated { id, focused: _ } = event {
|
match event {
|
||||||
let (workspace_name, output) = self.query_workspace(id);
|
Event::WorkspaceActivated { id, focused: _ } => {
|
||||||
event_sender.send(WorkspaceVisible {
|
let visible_workspace =
|
||||||
output,
|
find_workspace(&workspaces_state, id);
|
||||||
workspace_name,
|
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