From 483a38cff68686a2a72dffe8fffc7607a4ea97ad Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sat, 31 Oct 2026 15:17:43 -0700 Subject: [PATCH] refactor(windows): the title-bar rules are taken once per pass, through begin_pass BEHAVIOUR (Windows runtime): restores the original read of the title-bar tables. WindowsPlatform::begin_pass takes REMOVE_TITLEBARS, NO_TITLEBAR and REGEX_IDENTIFIERS once per placement pass (after the layout is computed, as the old pass loop did) and place_container reads that snapshot from Placement::pass, instead of locking and cloning the two tables for every container, where a configuration reload in the middle of a pass could give two containers two tables. Reviewer finding F3 (Windows review finding 6). Windows e2e scenarios needed: layouts, stackbars and title-bar scenarios (remove-title-bar, toggle-title-bars, no_titlebar rules), config_reload (a reload while windows are being placed). Verified: Windows clippy --locked --all-targets -D warnings: PASS; KDE cargo test -p komorebi-linux (lite env): 664 passed, 0 failed; macOS fake-CC check: PASS; komorebi-core tests: 30 passed. Not run: Windows tests, e2e. --- komorebi/src/workspace.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index fb3e6599..6189503c 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -11,6 +11,13 @@ pub(crate) use komorebi_core::sorted_layout_options_rules; /// platform's methods added by [`WorkspaceExt`] and the scrolling ones of [`WorkspaceScrolling`] pub type Workspace = komorebi_core::Workspace; +/// The title-bar rules of one placement pass, taken once by `begin_pass` +struct TitleBarRules { + should_remove_titlebars: bool, + no_titlebar: Vec, + regex_identifiers: HashMap, +} + /// The Windows daemon as the platform of the shared workspace #[derive(Debug, Clone, PartialEq)] pub struct WindowsPlatform; @@ -159,15 +166,29 @@ impl komorebi_core::WorkspacePlatform for WindowsPlatform { } } + fn begin_pass(_workspace: &Workspace) -> Option> { + // read once for the whole pass: a configuration reload in the middle of it must not give + // two containers two different tables + Some(Box::new(TitleBarRules { + should_remove_titlebars: REMOVE_TITLEBARS.load(Ordering::SeqCst), + no_titlebar: NO_TITLEBAR.lock().clone(), + regex_identifiers: REGEX_IDENTIFIERS.lock().clone(), + })) + } + fn place_container( container: &mut Container, layout: &Rect, hidden: bool, placement: &komorebi_core::Placement, ) -> eyre::Result<()> { - let should_remove_titlebars = REMOVE_TITLEBARS.load(Ordering::SeqCst); - let no_titlebar = NO_TITLEBAR.lock().clone(); - let regex_identifiers = REGEX_IDENTIFIERS.lock().clone(); + let rules = placement + .pass + .and_then(|pass| pass.downcast_ref::()) + .ok_or_eyre("the title-bar rules of this pass were not taken")?; + let should_remove_titlebars = rules.should_remove_titlebars; + let no_titlebar = &rules.no_titlebar; + let regex_identifiers = &rules.regex_identifiers; for window in container.windows() { if container @@ -179,8 +200,8 @@ impl komorebi_core::WorkspacePlatform for WindowsPlatform { &window.exe().unwrap_or_default(), &window.class().unwrap_or_default(), &window.path().unwrap_or_default(), - &no_titlebar, - ®ex_identifiers, + no_titlebar, + regex_identifiers, ) .is_some();