refactor: allow multiple actions for do_action
This commit is contained in:
parent
5a98a2022c
commit
555ffca915
1 changed files with 98 additions and 97 deletions
|
@ -135,7 +135,7 @@ impl NiriTag {
|
|||
}
|
||||
}
|
||||
|
||||
async fn do_action(&mut self, action: TagAction) -> Result<()> {
|
||||
async fn do_actions(&mut self, actions: &[TagAction]) -> Result<()> {
|
||||
use TagAction::*;
|
||||
let (active, inactive): (HashMap<_, _>, HashMap<_, _>) = self
|
||||
.state
|
||||
|
@ -144,102 +144,103 @@ impl NiriTag {
|
|||
.clone()
|
||||
.into_iter()
|
||||
.partition(|(_, ws)| ws.is_active);
|
||||
match action {
|
||||
Window(wid) => {
|
||||
let current_tag = *self.windows.entry(wid).or_insert(0);
|
||||
let tag_visible = self.tags.entry(current_tag).or_default().enabled;
|
||||
let win = self
|
||||
.state
|
||||
.windows
|
||||
.windows
|
||||
.get(&wid)
|
||||
.ok_or(anyhow!("Failed to retrieve window {} from niri state", wid))?;
|
||||
let wsid: u64 = win
|
||||
.workspace_id
|
||||
.ok_or(anyhow!("Retrieving workspace id of a changed window"))?;
|
||||
let win_visible = active.contains_key(&wsid);
|
||||
match (win_visible, tag_visible) {
|
||||
(true, false) => {
|
||||
let inactive_same_output = self.same_output(wsid, &inactive)?;
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::MoveWindowToWorkspace {
|
||||
window_id: Some(wid),
|
||||
reference: WorkspaceReferenceArg::Id(inactive_same_output.id),
|
||||
focus: false,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
for action in actions {
|
||||
match action {
|
||||
Window(wid) => {
|
||||
let current_tag = *self.windows.entry(*wid).or_insert(0);
|
||||
let tag_visible = self.tags.entry(current_tag).or_default().enabled;
|
||||
let win = self
|
||||
.state
|
||||
.windows
|
||||
.windows
|
||||
.get(wid)
|
||||
.ok_or(anyhow!("Failed to retrieve window {} from niri state", wid))?;
|
||||
let wsid: u64 = win
|
||||
.workspace_id
|
||||
.ok_or(anyhow!("Retrieving workspace id of a changed window"))?;
|
||||
let win_visible = active.contains_key(&wsid);
|
||||
match (win_visible, tag_visible) {
|
||||
(true, false) => {
|
||||
let inactive_same_output = self.same_output(wsid, &inactive)?;
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::MoveWindowToWorkspace {
|
||||
window_id: Some(*wid),
|
||||
reference: WorkspaceReferenceArg::Id(inactive_same_output.id),
|
||||
focus: false,
|
||||
}),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
(false, true) => {
|
||||
let active_same_output = self.same_output(wsid, &active)?;
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::MoveWindowToWorkspace {
|
||||
window_id: Some(*wid),
|
||||
reference: WorkspaceReferenceArg::Id(active_same_output.id),
|
||||
focus: true,
|
||||
}),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
(false, true) => {
|
||||
let active_same_output = self.same_output(wsid, &active)?;
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::MoveWindowToWorkspace {
|
||||
window_id: Some(wid),
|
||||
reference: WorkspaceReferenceArg::Id(active_same_output.id),
|
||||
focus: true,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
Tag(tag) => {
|
||||
tracing::debug!("Changing tag {}", tag);
|
||||
let tag_visible = self.tags.entry(tag).or_default().enabled;
|
||||
let affected_windows: Vec<u64> = self
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|(_, t)| tag == **t)
|
||||
.map(|(wid, _)| *wid)
|
||||
.collect();
|
||||
tracing::debug!(
|
||||
"{} affected windows of tag {}: {:?}",
|
||||
affected_windows.len(),
|
||||
tag,
|
||||
affected_windows
|
||||
);
|
||||
let focus = affected_windows.last().cloned();
|
||||
self.move_windows(
|
||||
if tag_visible { &active } else { &inactive },
|
||||
affected_windows,
|
||||
)
|
||||
.await;
|
||||
if let Some(focus) = focus {
|
||||
if tag_visible {
|
||||
Tag(tag) => {
|
||||
tracing::debug!("Changing tag {}", tag);
|
||||
let tag_visible = self.tags.entry(*tag).or_default().enabled;
|
||||
let affected_windows: Vec<u64> = self
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|(_, t)| *tag == **t)
|
||||
.map(|(wid, _)| *wid)
|
||||
.collect();
|
||||
tracing::debug!(
|
||||
"{} affected windows of tag {}: {:?}",
|
||||
affected_windows.len(),
|
||||
tag,
|
||||
affected_windows
|
||||
);
|
||||
let focus = affected_windows.last().cloned();
|
||||
self.move_windows(
|
||||
if tag_visible { &active } else { &inactive },
|
||||
affected_windows,
|
||||
)
|
||||
.await;
|
||||
if let Some(focus) = focus {
|
||||
if tag_visible {
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::FocusWindow { id: focus }),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
TagExclusive(t) => {
|
||||
tracing::debug!("Changing all tags");
|
||||
let (active_wid, inactive_wid): (HashMap<u64, u8>, HashMap<u64, u8>) = self
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|(_, it)| **it != 0)
|
||||
.partition(|(_, it)| **it == *t);
|
||||
let focus = active_wid.keys().last();
|
||||
self.move_windows(&inactive, inactive_wid.keys().cloned().collect())
|
||||
.await;
|
||||
self.move_windows(&active, active_wid.keys().cloned().collect())
|
||||
.await;
|
||||
if let Some(f) = focus {
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::FocusWindow { id: focus }),
|
||||
Request::Action(Action::FocusWindow { id: *f }),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
TagExclusive(t) => {
|
||||
tracing::debug!("Changing all tags");
|
||||
let (active_wid, inactive_wid): (HashMap<u64, u8>, HashMap<u64, u8>) = self
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|(_, it)| **it != 0)
|
||||
.partition(|(_, it)| **it == t);
|
||||
let focus = active_wid.keys().last();
|
||||
self.move_windows(&inactive, inactive_wid.keys().cloned().collect())
|
||||
.await;
|
||||
self.move_windows(&active, active_wid.keys().cloned().collect())
|
||||
.await;
|
||||
if let Some(f) = focus {
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::FocusWindow { id: *f }),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_focused_window(&mut self) -> Result<Window> {
|
||||
|
@ -275,7 +276,7 @@ impl NiriTag {
|
|||
async fn handle_recvd(&mut self, recvd: Receivable) -> Result<()> {
|
||||
use TagAction::*;
|
||||
// first do any local mutations
|
||||
let action: TagAction = match recvd {
|
||||
let actions: &[TagAction] = match recvd {
|
||||
Receivable::Event(ev) => {
|
||||
let _ = self.state.apply(ev.clone());
|
||||
return self.handle_event(ev).await;
|
||||
|
@ -294,12 +295,12 @@ impl NiriTag {
|
|||
TagCmd::AddTagToWin(t) => {
|
||||
let wid = self.get_focused_window().await?.id;
|
||||
self.change_window_tag(wid, Some(t)).await?;
|
||||
Window(wid)
|
||||
&[Window(wid)]
|
||||
}
|
||||
TagCmd::RemoveTagFromWin(_) => {
|
||||
let wid = self.get_focused_window().await?.id;
|
||||
self.change_window_tag(wid, None).await?;
|
||||
Window(wid)
|
||||
&[Window(wid)]
|
||||
}
|
||||
TagCmd::ToggleTagOnWin(t) => {
|
||||
let wid = self.get_focused_window().await?.id;
|
||||
|
@ -310,7 +311,7 @@ impl NiriTag {
|
|||
};
|
||||
self.change_window_tag(wid, Some(new_tag)).await?;
|
||||
tracing::debug!("toggling {} to tag {}", wid, new_tag);
|
||||
Window(wid)
|
||||
&[Window(wid)]
|
||||
}
|
||||
|
||||
TagCmd::EnableTag(t) => {
|
||||
|
@ -319,7 +320,7 @@ impl NiriTag {
|
|||
.and_modify(|ts| ts.enabled = true)
|
||||
.or_default();
|
||||
self.fire_event(TagEvent::TagEnabled(t)).await;
|
||||
Tag(t)
|
||||
&[Tag(t)]
|
||||
}
|
||||
TagCmd::DisableTag(t) => {
|
||||
self.tags
|
||||
|
@ -327,7 +328,7 @@ impl NiriTag {
|
|||
.and_modify(|ts| ts.enabled = false)
|
||||
.or_default();
|
||||
self.fire_event(TagEvent::TagDisabled(t)).await;
|
||||
Tag(t)
|
||||
&[Tag(t)]
|
||||
}
|
||||
TagCmd::ToggleTag(t) => {
|
||||
let new_state = self
|
||||
|
@ -342,7 +343,7 @@ impl NiriTag {
|
|||
TagEvent::TagDisabled(t)
|
||||
})
|
||||
.await;
|
||||
Tag(t)
|
||||
&[Tag(t)]
|
||||
}
|
||||
TagCmd::ExclusiveTag(t) => {
|
||||
self.tags
|
||||
|
@ -354,12 +355,12 @@ impl NiriTag {
|
|||
.filter(|(it, _)| **it != 0)
|
||||
.for_each(|(it, ts)| ts.enabled = *it == t);
|
||||
self.fire_event(TagEvent::TagExclusive(t)).await;
|
||||
TagExclusive(t)
|
||||
&[TagExclusive(t)]
|
||||
}
|
||||
},
|
||||
};
|
||||
// then arrange corresponding state in the compositor
|
||||
self.do_action(action).await?;
|
||||
self.do_actions(actions).await?;
|
||||
tell(
|
||||
&mut self.socket,
|
||||
Request::Action(Action::CenterVisibleColumns {}),
|
||||
|
@ -431,7 +432,7 @@ impl NiriTag {
|
|||
WindowsChanged { windows } => {
|
||||
for w in windows {
|
||||
self.change_window_tag(w.id, None).await?;
|
||||
let action = self.do_action(TagAction::Window(w.id)).await;
|
||||
let action = self.do_actions(&[TagAction::Window(w.id)]).await;
|
||||
if let Err(e) = action {
|
||||
tracing::warn!("Failed to ChangeWindow on {}: {}", w.id, e);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue