feat: change socket nomenclature + implement events provider
This commit is contained in:
parent
389c4b3ee6
commit
05e12ea2f2
5 changed files with 212 additions and 65 deletions
|
@ -4,9 +4,9 @@ use niri_ipc::{
|
|||
Action, Event, Reply, Request, Response, Window, Workspace, WorkspaceReferenceArg,
|
||||
state::{EventStreamState, EventStreamStatePart},
|
||||
};
|
||||
use niri_tag::TagCmd;
|
||||
use niri_tag::{TagCmd, TagEvent};
|
||||
use smol::{
|
||||
channel::{self},
|
||||
channel::{self, Sender},
|
||||
future,
|
||||
io::BufReader,
|
||||
net::unix::UnixStream,
|
||||
|
@ -18,6 +18,7 @@ pub struct NiriTag {
|
|||
windows: HashMap<u64, u8>,
|
||||
state: EventStreamState,
|
||||
socket: BufReader<UnixStream>,
|
||||
ev_tx: channel::Sender<TagEvent>,
|
||||
}
|
||||
|
||||
enum TagAction {
|
||||
|
@ -26,12 +27,13 @@ enum TagAction {
|
|||
}
|
||||
|
||||
impl NiriTag {
|
||||
pub async fn new() -> Result<Self> {
|
||||
pub async fn new(ev_tx: channel::Sender<TagEvent>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
tags: HashMap::new(),
|
||||
windows: HashMap::new(),
|
||||
state: EventStreamState::default(),
|
||||
socket: create_niri_socket().await?,
|
||||
ev_tx,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -196,6 +198,36 @@ impl NiriTag {
|
|||
|
||||
async fn handle_recvd(&mut self, recvd: Receivable) -> Result<()> {
|
||||
use TagAction::*;
|
||||
let send_event = async |tx: Sender<TagEvent>, ev| {
|
||||
smol::spawn(async move {
|
||||
tx.send(ev)
|
||||
.await
|
||||
.inspect_err(|e| tracing::error!("Failed to send event: {}", e))
|
||||
})
|
||||
.detach();
|
||||
};
|
||||
let add_tag = async |tx: Sender<TagEvent>, windows: &HashMap<u64, u8>, t| {
|
||||
if windows
|
||||
.iter()
|
||||
.filter(|(_, tag)| **tag == t)
|
||||
.collect::<HashMap<_, _>>()
|
||||
.is_empty()
|
||||
{
|
||||
send_event(tx, TagEvent::TagOccupied(t)).await;
|
||||
}
|
||||
};
|
||||
let rm_tag = async |tx: Sender<TagEvent>, windows: &HashMap<u64, u8>, wid, old_tag| {
|
||||
if old_tag != 0
|
||||
&& windows
|
||||
.iter()
|
||||
.filter(|(w, tag)| **tag == old_tag && **w != wid)
|
||||
.collect::<Vec<(_, _)>>()
|
||||
.is_empty()
|
||||
{
|
||||
send_event(tx, TagEvent::TagEmpty(old_tag)).await;
|
||||
}
|
||||
};
|
||||
|
||||
// first do any local mutations
|
||||
let action: TagAction = match recvd {
|
||||
Receivable::Event(ev) => {
|
||||
|
@ -208,13 +240,17 @@ impl NiriTag {
|
|||
let wid = win.id;
|
||||
self.windows.insert(wid, t);
|
||||
tracing::debug!("adding tag {} to {}", t, wid);
|
||||
let tx = self.ev_tx.clone();
|
||||
add_tag(tx, &self.windows, t).await;
|
||||
ChangeWindow(wid)
|
||||
}
|
||||
TagCmd::RemoveTagFromWin(_) => {
|
||||
let win = self.get_focused_window().await?;
|
||||
let wid = win.id;
|
||||
self.windows.insert(wid, 0);
|
||||
let old_tag = self.windows.insert(wid, 0).unwrap_or(0);
|
||||
tracing::debug!("resetting tag on {}", wid);
|
||||
let tx = self.ev_tx.clone();
|
||||
rm_tag(tx, &self.windows, wid, old_tag).await;
|
||||
ChangeWindow(wid)
|
||||
}
|
||||
TagCmd::ToggleTagOnWin(t) => {
|
||||
|
@ -223,6 +259,12 @@ impl NiriTag {
|
|||
tracing::debug!("{} has tag {:?}", wid, self.windows.get(&wid));
|
||||
let this_tag = *self.windows.entry(wid).or_insert(0);
|
||||
let toggle = if this_tag == t { 0 } else { t };
|
||||
let tx = self.ev_tx.clone();
|
||||
if toggle == 0 {
|
||||
rm_tag(tx, &self.windows, wid, this_tag).await;
|
||||
} else {
|
||||
add_tag(tx, &self.windows, t).await;
|
||||
}
|
||||
tracing::debug!("toggling {} to tag {}", wid, toggle);
|
||||
self.windows.insert(wid, toggle);
|
||||
ChangeWindow(wid)
|
||||
|
@ -230,14 +272,21 @@ impl NiriTag {
|
|||
|
||||
TagCmd::EnableTag(t) => {
|
||||
self.tags.insert(t, true);
|
||||
send_event(self.ev_tx.clone(), TagEvent::TagEnabled(t)).await;
|
||||
ChangeTag(t)
|
||||
}
|
||||
TagCmd::DisableTag(t) => {
|
||||
self.tags.insert(t, false);
|
||||
send_event(self.ev_tx.clone(), TagEvent::TagDisabled(t)).await;
|
||||
ChangeTag(t)
|
||||
}
|
||||
TagCmd::ToggleTag(t) => {
|
||||
let visible = *self.tags.entry(t).or_insert(false);
|
||||
if visible {
|
||||
send_event(self.ev_tx.clone(), TagEvent::TagEnabled(t)).await;
|
||||
} else {
|
||||
send_event(self.ev_tx.clone(), TagEvent::TagDisabled(t)).await;
|
||||
}
|
||||
tracing::debug!("toggling tag {} to {}", t, !visible);
|
||||
self.tags.insert(t, !visible);
|
||||
ChangeTag(t)
|
||||
|
@ -283,7 +332,7 @@ impl NiriTag {
|
|||
tag_rx.recv().await.map(Receivable::TagCmd)
|
||||
})
|
||||
.await?;
|
||||
tracing::debug!("received {:?}", recvd);
|
||||
tracing::debug!("manager received {:?}", recvd);
|
||||
|
||||
let res = self.handle_recvd(recvd).await;
|
||||
match res {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue