Skip to content

Commit

Permalink
feat(stackbar): add stackbar manager module
Browse files Browse the repository at this point in the history
This commit removes all stackbar-related code from Container, Workspace,
process_command, process_event etc. and centralizes it in the new
stackbar_manager module.

Instead of trying to figure out where in process_event and
process_command we should make stackbar-related changes, a notification
gets sent to a channel that stackbar_manager listens to whenever an
event or command has finished processing.

The stackbar_manager listener, upon receiving a notification, acquires a
lock on the WindowManager instance and updates stackbars for the focused
workspace on every monitor; this allows us to centralize all edge case
handling within the stackbar_manager listener's loop.

Global state related to stackbars has also been moved into the
stackbar_manager module, which also tracks the state of stackbar objects
(STACKBAR_STATE), mappings between stackbars and containers
(STACKBARS_CONTAINERS) and the mappings between stackbars and monitors
(STACKBARS_MONITORS).

A number of edge cases around stackbar behaviour have been addressed in
this commit (re #832), and stackbars now respect the "border_style"
configuration option.
  • Loading branch information
LGUG2Z committed May 19, 2024
1 parent a29ab4c commit 2a45f98
Show file tree
Hide file tree
Showing 11 changed files with 559 additions and 495 deletions.
71 changes: 0 additions & 71 deletions komorebi/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,13 @@ use serde::Deserialize;
use serde::Serialize;

use crate::ring::Ring;
use crate::stackbar::Stackbar;
use crate::window::Window;
use crate::WindowsApi;
use crate::STACKBAR_MODE;
use komorebi_core::StackbarMode;

#[derive(Debug, Clone, Serialize, Deserialize, Getters, JsonSchema)]
pub struct Container {
#[getset(get = "pub")]
id: String,
windows: Ring<Window>,
#[serde(skip)]
#[getset(get = "pub", get_mut = "pub")]
stackbar: Option<Stackbar>,
}

impl_ring_elements!(Container, Window);
Expand All @@ -30,10 +23,6 @@ impl Default for Container {
Self {
id: nanoid!(),
windows: Ring::default(),
stackbar: match STACKBAR_MODE.load() {
StackbarMode::Always => Stackbar::create().ok(),
StackbarMode::Never | StackbarMode::OnStack => None,
},
}
}
}
Expand All @@ -46,10 +35,6 @@ impl PartialEq for Container {

impl Container {
pub fn hide(&self, omit: Option<isize>) {
if let Some(stackbar) = self.stackbar() {
stackbar.hide();
}

for window in self.windows().iter().rev() {
let mut should_hide = omit.is_none();

Expand All @@ -68,10 +53,6 @@ impl Container {
}

pub fn restore(&self) {
if let Some(stackbar) = self.stackbar() {
stackbar.restore();
}

if let Some(window) = self.focused_window() {
window.restore();
}
Expand Down Expand Up @@ -124,13 +105,6 @@ impl Container {
pub fn remove_window_by_idx(&mut self, idx: usize) -> Option<Window> {
let window = self.windows_mut().remove(idx);

if matches!(STACKBAR_MODE.load(), StackbarMode::OnStack) && self.windows().len() <= 1 {
if let Some(stackbar) = &self.stackbar {
let _ = WindowsApi::close_window(stackbar.hwnd());
self.stackbar = None;
}
}

if idx != 0 {
self.focus_window(idx - 1);
};
Expand All @@ -145,14 +119,6 @@ impl Container {

pub fn add_window(&mut self, window: Window) {
self.windows_mut().push_back(window);

if matches!(STACKBAR_MODE.load(), StackbarMode::OnStack)
&& self.windows().len() > 1
&& self.stackbar.is_none()
{
self.stackbar = Stackbar::create().ok();
}

self.focus_window(self.windows().len() - 1);
}

Expand All @@ -161,41 +127,4 @@ impl Container {
tracing::info!("focusing window");
self.windows.focus(idx);
}

pub fn set_stackbar_mode(&mut self, mode: StackbarMode) {
match mode {
StackbarMode::Always => {
if self.stackbar.is_none() {
self.stackbar = Stackbar::create().ok();
}
}
StackbarMode::Never => {
if let Some(stackbar) = &self.stackbar {
let _ = WindowsApi::close_window(stackbar.hwnd());
}

self.stackbar = None
}
StackbarMode::OnStack => {
if self.windows().len() > 1 && self.stackbar().is_none() {
self.stackbar = Stackbar::create().ok();
}

if let Some(stackbar) = &self.stackbar {
if self.windows().len() == 1 {
let _ = WindowsApi::close_window(stackbar.hwnd());
self.stackbar = None;
}
}
}
}
}

pub fn renew_stackbar(&mut self) {
if let Some(stackbar) = &self.stackbar {
if !WindowsApi::is_window(stackbar.hwnd()) {
self.stackbar = Stackbar::create().ok()
}
}
}
}
14 changes: 1 addition & 13 deletions komorebi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod process_command;
pub mod process_event;
pub mod process_movement;
pub mod set_window_position;
pub mod stackbar;
pub mod stackbar_manager;
pub mod static_config;
pub mod styles;
pub mod window;
Expand Down Expand Up @@ -40,7 +40,6 @@ use std::sync::Arc;
pub use colour::*;
pub use process_command::*;
pub use process_event::*;
pub use stackbar::*;
pub use static_config::*;
pub use window::*;
pub use window_manager::*;
Expand All @@ -49,16 +48,13 @@ pub use windows_api::WindowsApi;
pub use windows_api::*;

use color_eyre::Result;
use crossbeam_utils::atomic::AtomicCell;
use komorebi_core::config_generation::IdWithIdentifier;
use komorebi_core::config_generation::MatchingRule;
use komorebi_core::config_generation::MatchingStrategy;
use komorebi_core::ApplicationIdentifier;
use komorebi_core::HidingBehaviour;
use komorebi_core::Rect;
use komorebi_core::SocketMessage;
use komorebi_core::StackbarLabel;
use komorebi_core::StackbarMode;
use os_info::Version;
use parking_lot::Mutex;
use regex::Regex;
Expand Down Expand Up @@ -215,14 +211,6 @@ pub static SESSION_ID: AtomicU32 = AtomicU32::new(0);

pub static REMOVE_TITLEBARS: AtomicBool = AtomicBool::new(false);

pub static STACKBAR_FOCUSED_TEXT_COLOUR: AtomicU32 = AtomicU32::new(16777215); // white
pub static STACKBAR_UNFOCUSED_TEXT_COLOUR: AtomicU32 = AtomicU32::new(11776947); // gray text
pub static STACKBAR_TAB_BACKGROUND_COLOUR: AtomicU32 = AtomicU32::new(3355443); // gray
pub static STACKBAR_TAB_HEIGHT: AtomicI32 = AtomicI32::new(40);
pub static STACKBAR_TAB_WIDTH: AtomicI32 = AtomicI32::new(200);
pub static STACKBAR_LABEL: AtomicCell<StackbarLabel> = AtomicCell::new(StackbarLabel::Process);
pub static STACKBAR_MODE: AtomicCell<StackbarMode> = AtomicCell::new(StackbarMode::Never);

#[must_use]
pub fn current_virtual_desktop() -> Option<Vec<u8>> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
Expand Down
2 changes: 2 additions & 0 deletions komorebi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use komorebi::process_command::listen_for_commands;
use komorebi::process_command::listen_for_commands_tcp;
use komorebi::process_event::listen_for_events;
use komorebi::process_movement::listen_for_movements;
use komorebi::stackbar_manager;
use komorebi::static_config::StaticConfig;
use komorebi::window_manager::WindowManager;
use komorebi::windows_api::WindowsApi;
Expand Down Expand Up @@ -254,6 +255,7 @@ fn main() -> Result<()> {
}

border_manager::listen_for_notifications(wm.clone());
stackbar_manager::listen_for_notifications(wm.clone());
workspace_reconciliator::listen_for_notifications(wm.clone());
monitor_reconciliator::listen_for_notifications(wm.clone())?;

Expand Down
24 changes: 9 additions & 15 deletions komorebi/src/process_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use crate::border_manager::STYLE;
use crate::colour::Rgb;
use crate::current_virtual_desktop;
use crate::notify_subscribers;
use crate::stackbar_manager;
use crate::static_config::StaticConfig;
use crate::window::RuleDebug;
use crate::window::Window;
Expand All @@ -64,18 +65,18 @@ use crate::MONITOR_INDEX_PREFERENCES;
use crate::NO_TITLEBAR;
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
use crate::REMOVE_TITLEBARS;
use crate::STACKBAR_FOCUSED_TEXT_COLOUR;
use crate::STACKBAR_LABEL;
use crate::STACKBAR_MODE;
use crate::STACKBAR_TAB_BACKGROUND_COLOUR;
use crate::STACKBAR_TAB_HEIGHT;
use crate::STACKBAR_TAB_WIDTH;
use crate::STACKBAR_UNFOCUSED_TEXT_COLOUR;
use crate::SUBSCRIPTION_PIPES;
use crate::SUBSCRIPTION_SOCKETS;
use crate::TCP_CONNECTIONS;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
use crate::WORKSPACE_RULES;
use stackbar_manager::STACKBAR_FOCUSED_TEXT_COLOUR;
use stackbar_manager::STACKBAR_LABEL;
use stackbar_manager::STACKBAR_MODE;
use stackbar_manager::STACKBAR_TAB_BACKGROUND_COLOUR;
use stackbar_manager::STACKBAR_TAB_HEIGHT;
use stackbar_manager::STACKBAR_TAB_WIDTH;
use stackbar_manager::STACKBAR_UNFOCUSED_TEXT_COLOUR;

#[tracing::instrument]
pub fn listen_for_commands(wm: Arc<Mutex<WindowManager>>) {
Expand Down Expand Up @@ -1245,14 +1246,6 @@ impl WindowManager {
}
SocketMessage::StackbarMode(mode) => {
STACKBAR_MODE.store(mode);

for m in self.monitors_mut() {
for w in m.workspaces_mut() {
for c in w.containers_mut() {
c.set_stackbar_mode(mode);
}
}
}
}
SocketMessage::StackbarLabel(label) => {
STACKBAR_LABEL.store(label);
Expand Down Expand Up @@ -1342,6 +1335,7 @@ impl WindowManager {

notify_subscribers(&serde_json::to_string(&notification)?)?;
border_manager::event_tx().send(border_manager::Notification)?;
stackbar_manager::event_tx().send(stackbar_manager::Notification)?;

tracing::info!("processed");
Ok(())
Expand Down
27 changes: 3 additions & 24 deletions komorebi/src/process_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,19 @@ use parking_lot::Mutex;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use komorebi_core::Sizing;
use komorebi_core::StackbarLabel;
use komorebi_core::WindowContainerBehaviour;

use crate::border_manager;
use crate::border_manager::BORDER_OFFSET;
use crate::border_manager::BORDER_WIDTH;
use crate::current_virtual_desktop;
use crate::notify_subscribers;
use crate::stackbar_manager;
use crate::window::should_act;
use crate::window::RuleDebug;
use crate::window_manager::WindowManager;
use crate::window_manager_event::WindowManagerEvent;
use crate::windows_api::WindowsApi;
use crate::winevent::WinEvent;
use crate::workspace_reconciliator;
use crate::workspace_reconciliator::ALT_TAB_HWND;
use crate::workspace_reconciliator::ALT_TAB_HWND_INSTANT;
Expand All @@ -33,7 +32,6 @@ use crate::NotificationEvent;
use crate::DATA_DIR;
use crate::HIDDEN_HWNDS;
use crate::REGEX_IDENTIFIERS;
use crate::STACKBAR_LABEL;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;

#[tracing::instrument]
Expand Down Expand Up @@ -269,23 +267,6 @@ impl WindowManager {
WindowManagerEvent::Show(_, window)
| WindowManagerEvent::Manage(window)
| WindowManagerEvent::Uncloak(_, window) => {
if matches!(
event,
WindowManagerEvent::Show(WinEvent::ObjectNameChange, _)
) {
if matches!(STACKBAR_LABEL.load(), StackbarLabel::Title) {
for m in self.monitors() {
for ws in m.workspaces() {
if let Some(container) = ws.container_for_window(window.hwnd) {
if let Some(stackbar) = container.stackbar() {
stackbar.update(container.windows(), window.hwnd)?;
}
}
}
}
}
}

let focused_monitor_idx = self.focused_monitor_idx();
let focused_workspace_idx =
self.focused_workspace_idx_for_monitor_idx(focused_monitor_idx)?;
Expand Down Expand Up @@ -461,10 +442,7 @@ impl WindowManager {

// If we have moved across the monitors, use that override, otherwise determine
// if a move has taken place by ruling out a resize
let right_bottom_constant = ((BORDER_WIDTH.load(Ordering::SeqCst)
+ BORDER_OFFSET.load(Ordering::SeqCst))
* 2)
.abs();
let right_bottom_constant = 0;

let is_move = moved_across_monitors
|| resize.right.abs() == right_bottom_constant
Expand Down Expand Up @@ -640,6 +618,7 @@ impl WindowManager {

notify_subscribers(&serde_json::to_string(&notification)?)?;
border_manager::event_tx().send(border_manager::Notification)?;
stackbar_manager::event_tx().send(stackbar_manager::Notification)?;

tracing::info!("processed: {}", event.window().to_string());
Ok(())
Expand Down
Loading

0 comments on commit 2a45f98

Please sign in to comment.