refactor(wm): remove mutability from window and events

We had a mut requirement on some of the Window functions which may have
been vestigial or in preparation for more state on Window objects, but
presently unused. I removed that, as the Window struct is currently just
carrying an HWND value that's essentially always immutable - there's no
advantage to ever reusing a Window struct vs. making a new one for
another HWND.

In doing so we then no longer needed to be passing in mutable events, so
I applied a little simplification of the event receiver / dispatcher to
process_event. After that it became obvious that we could just pass the
owned event directly into process_event instead, which substantially
simplifies the ownership model and lifetime for those objects.

This is small, and shouldn't create any meaningful behavioral change.
This commit is contained in:
James Tucker
2024-04-13 14:11:30 -07:00
committed by LGUG2Z
parent 5334e1944e
commit f56fc36557
2 changed files with 14 additions and 19 deletions

View File

@@ -4,7 +4,6 @@ use std::sync::Arc;
use color_eyre::eyre::anyhow; use color_eyre::eyre::anyhow;
use color_eyre::Result; use color_eyre::Result;
use crossbeam_channel::select;
use parking_lot::Mutex; use parking_lot::Mutex;
use komorebi_core::OperationDirection; use komorebi_core::OperationDirection;
@@ -42,14 +41,10 @@ pub fn listen_for_events(wm: Arc<Mutex<WindowManager>>) {
std::thread::spawn(move || { std::thread::spawn(move || {
tracing::info!("listening"); tracing::info!("listening");
loop { loop {
select! { if let Ok(event) = receiver.recv() {
recv(receiver) -> mut maybe_event => { match wm.lock().process_event(event) {
if let Ok(event) = maybe_event.as_mut() { Ok(()) => {}
match wm.lock().process_event(event) { Err(error) => tracing::error!("{}", error),
Ok(()) => {},
Err(error) => tracing::error!("{}", error)
}
}
} }
} }
} }
@@ -59,13 +54,13 @@ pub fn listen_for_events(wm: Arc<Mutex<WindowManager>>) {
impl WindowManager { impl WindowManager {
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)] #[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn process_event(&mut self, event: &mut WindowManagerEvent) -> Result<()> { pub fn process_event(&mut self, event: WindowManagerEvent) -> Result<()> {
if self.is_paused { if self.is_paused {
tracing::trace!("ignoring while paused"); tracing::trace!("ignoring while paused");
return Ok(()); return Ok(());
} }
let should_manage = event.window().should_manage(Some(*event))?; let should_manage = event.window().should_manage(Some(event))?;
// Hide or reposition the window based on whether the target is managed. // Hide or reposition the window based on whether the target is managed.
if BORDER_ENABLED.load(Ordering::SeqCst) { if BORDER_ENABLED.load(Ordering::SeqCst) {
@@ -73,7 +68,7 @@ impl WindowManager {
let border_window = Border::from(BORDER_HWND.load(Ordering::SeqCst)); let border_window = Border::from(BORDER_HWND.load(Ordering::SeqCst));
if should_manage { if should_manage {
border_window.set_position(*window, true)?; border_window.set_position(window, true)?;
} else { } else {
let mut stackbar = false; let mut stackbar = false;
if let Ok(class) = window.class() { if let Ok(class) = window.class() {
@@ -122,7 +117,7 @@ impl WindowManager {
| WindowManagerEvent::MoveResizeEnd(_, window) => { | WindowManagerEvent::MoveResizeEnd(_, window) => {
self.reconcile_monitors()?; self.reconcile_monitors()?;
let monitor_idx = self.monitor_idx_from_window(*window) let monitor_idx = self.monitor_idx_from_window(window)
.ok_or_else(|| anyhow!("there is no monitor associated with this window, it may have already been destroyed"))?; .ok_or_else(|| anyhow!("there is no monitor associated with this window, it may have already been destroyed"))?;
// This is a hidden window apparently associated with COM support mechanisms (based // This is a hidden window apparently associated with COM support mechanisms (based
@@ -329,14 +324,14 @@ impl WindowManager {
if !workspace.contains_window(window.hwnd) { if !workspace.contains_window(window.hwnd) {
match behaviour { match behaviour {
WindowContainerBehaviour::Create => { WindowContainerBehaviour::Create => {
workspace.new_container_for_window(*window); workspace.new_container_for_window(window);
self.update_focused_workspace(false)?; self.update_focused_workspace(false)?;
} }
WindowContainerBehaviour::Append => { WindowContainerBehaviour::Append => {
workspace workspace
.focused_container_mut() .focused_container_mut()
.ok_or_else(|| anyhow!("there is no focused container"))? .ok_or_else(|| anyhow!("there is no focused container"))?
.add_window(*window); .add_window(window);
self.update_focused_workspace(true)?; self.update_focused_workspace(true)?;
} }
} }
@@ -607,7 +602,7 @@ impl WindowManager {
.iter() .iter()
.any(|w| w.hwnd == window.hwnd) .any(|w| w.hwnd == window.hwnd)
{ {
target_window = Option::from(*window); target_window = Option::from(window);
WindowsApi::raise_window(border.hwnd())?; WindowsApi::raise_window(border.hwnd())?;
}; };
@@ -700,7 +695,7 @@ impl WindowManager {
serde_json::to_writer_pretty(&file, &known_hwnds)?; serde_json::to_writer_pretty(&file, &known_hwnds)?;
notify_subscribers(&serde_json::to_string(&Notification { notify_subscribers(&serde_json::to_string(&Notification {
event: NotificationEvent::WindowManager(*event), event: NotificationEvent::WindowManager(event),
state: self.as_ref().into(), state: self.as_ref().into(),
})?)?; })?)?;

View File

@@ -125,7 +125,7 @@ impl Window {
HWND(self.hwnd) HWND(self.hwnd)
} }
pub fn center(&mut self, work_area: &Rect) -> Result<()> { pub fn center(&self, work_area: &Rect) -> Result<()> {
let half_width = work_area.right / 2; let half_width = work_area.right / 2;
let half_weight = work_area.bottom / 2; let half_weight = work_area.bottom / 2;
@@ -140,7 +140,7 @@ impl Window {
) )
} }
pub fn set_position(&mut self, layout: &Rect, top: bool) -> Result<()> { pub fn set_position(&self, layout: &Rect, top: bool) -> Result<()> {
let rect = *layout; let rect = *layout;
WindowsApi::position_window(self.hwnd(), &rect, top) WindowsApi::position_window(self.hwnd(), &rect, top)
} }