Skip to content

Commit

Permalink
feat(wm): add monitor reconciliator module
Browse files Browse the repository at this point in the history
This commit adds the monitor_reconciliator module which uses a tightly
bounded channel (cap: 1) to handle monitor connection and disconnection
events, as well as resolution and work area change events.

Before, all this logic lived in a the WindowManager.reconcile_monitors
function, which ran on pretty much every process_event iteration, and
sometimes led to undesirable behaviour, but now the logic is split up to
only run when the appropriate notifications are dispatched from the
hidden window which listens for monitor and display-related events.

The monitor cache has been moved out of WindowManager and into the
monitor_reconciliator module, and in addition to the previous behaviour
of attempting to cache monitors which had been identified as
disconnected, now when the static configuration file is loaded, if the
user has set display_index_preferences, the device IDs will be used to
pre-populate the cache for the event where a known monitor is connected
later in a session.

The monitor cache itself now uses the unique device ID as a key rather
than the hmonitor which is known to be inconsistent.

This commit also delegates all display monitor-related Win32 calls to
the "win32-display-data" crate, which was extracted from the larger
"brightness" crate for its use in komorebi.

As a result of these changes, "device" and "device_id" on Monitor have
been changed from Option<String> to String types, as failures in
retrieving these values with directly attached monitors has not been
possible to reproduce. However, it remains to be seen if this will
adversely impact users who use display docks which may prevent display
monitor device IDs from being read and stored by the operating system.

WindowManagerEvent::DisplayChange has been removed in favour of
the monitor_reconciliator::Notification enum, as these events are no
longer being handled in process_events.

Attempts are now made to eagerly update hmonitors both within the
monitor_reconciliator loop on DisplayConnectionChange notifications and
when failing to find a matching hmonitor in functions like
monitor_idx_from_current_pos and monitor_idx_from_window.
  • Loading branch information
LGUG2Z committed May 19, 2024
1 parent 27cd173 commit a29ab4c
Show file tree
Hide file tree
Showing 16 changed files with 782 additions and 498 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions komorebi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,7 @@ windows-interface = { workspace = true }
winput = "0.2"
winreg = "0.52"

win32-display-data = { git = "https://github.com/LGUG2Z/win32-display-data" }

[features]
deadlock_detection = []
75 changes: 0 additions & 75 deletions komorebi/src/hidden.rs

This file was deleted.

6 changes: 1 addition & 5 deletions komorebi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub mod com;
pub mod ring;
pub mod colour;
pub mod container;
pub mod hidden;
pub mod monitor;
pub mod monitor_reconciliator;
pub mod process_command;
pub mod process_event;
pub mod process_movement;
Expand Down Expand Up @@ -33,13 +33,11 @@ use std::path::PathBuf;
use std::process::Command;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::AtomicI32;
use std::sync::atomic::AtomicIsize;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;
use std::sync::Arc;

pub use colour::*;
pub use hidden::*;
pub use process_command::*;
pub use process_event::*;
pub use stackbar::*;
Expand Down Expand Up @@ -217,8 +215,6 @@ pub static SESSION_ID: AtomicU32 = AtomicU32::new(0);

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

pub static HIDDEN_HWND: AtomicIsize = AtomicIsize::new(0);

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
Expand Down
5 changes: 2 additions & 3 deletions komorebi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::EnvFilter;

use komorebi::border_manager;
use komorebi::hidden::Hidden;
use komorebi::load_configuration;
use komorebi::monitor_reconciliator;
use komorebi::process_command::listen_for_commands;
use komorebi::process_command::listen_for_commands_tcp;
use komorebi::process_event::listen_for_events;
Expand Down Expand Up @@ -188,8 +188,6 @@ fn main() -> Result<()> {
#[cfg(feature = "deadlock_detection")]
detect_deadlocks();

Hidden::create("komorebi-hidden")?;

let static_config = opts.config.map_or_else(
|| {
let komorebi_json = HOME_DIR.join("komorebi.json");
Expand Down Expand Up @@ -257,6 +255,7 @@ fn main() -> Result<()> {

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

let (ctrlc_sender, ctrlc_receiver) = crossbeam_channel::bounded(1);
ctrlc::set_handler(move || {
Expand Down
17 changes: 12 additions & 5 deletions komorebi/src/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub struct Monitor {
#[getset(get = "pub", set = "pub")]
name: String,
#[getset(get = "pub", set = "pub")]
device: Option<String>,
device: String,
#[getset(get = "pub", set = "pub")]
device_id: Option<String>,
device_id: String,
#[getset(get = "pub", set = "pub")]
size: Rect,
#[getset(get = "pub", set = "pub")]
Expand All @@ -50,15 +50,22 @@ pub struct Monitor {

impl_ring_elements!(Monitor, Workspace);

pub fn new(id: isize, size: Rect, work_area_size: Rect, name: String) -> Monitor {
pub fn new(
id: isize,
size: Rect,
work_area_size: Rect,
name: String,
device: String,
device_id: String,
) -> Monitor {
let mut workspaces = Ring::default();
workspaces.elements_mut().push_back(Workspace::default());

Monitor {
id,
name,
device: None,
device_id: None,
device,
device_id,
size,
work_area_size,
work_area_offset: None,
Expand Down
Loading

0 comments on commit a29ab4c

Please sign in to comment.