Skip to content

Commit

Permalink
fix: add is_focus_synced for ignoring mouse events
Browse files Browse the repository at this point in the history
  • Loading branch information
jackssrt committed Feb 9, 2025
1 parent 4f3f9ee commit 80b01dc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
7 changes: 6 additions & 1 deletion packages/wm/src/events/handle_mouse_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ pub fn handle_mouse_move(
) -> anyhow::Result<()> {
// Ignore event if left/right-click is down. Otherwise, this causes focus
// to jitter when a window is being resized by its drag handles.
if event.is_mouse_down || !config.value.general.focus_follows_cursor {
// Also ignore if the OS focused window isn't the same as the WM's
// focused window.
if event.is_mouse_down
|| !state.is_focus_synced
|| !config.value.general.focus_follows_cursor
{
return Ok(());
}

Expand Down
25 changes: 12 additions & 13 deletions packages/wm/src/events/handle_window_focused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
container::set_focused_descendant, window::run_window_rules,
workspace::focus_workspace,
},
models::{Container, WorkspaceTarget},
models::WorkspaceTarget,
traits::{CommonGetters, WindowGetters},
user_config::UserConfig,
wm_state::WmState,
Expand All @@ -23,13 +23,20 @@ pub fn handle_window_focused(
let focused_container =
state.focused_container().context("No focused container.")?;

// Update the focus sync state. If the OS focused window is not same as
// the WM's focused container, then the focus is not synced.
state.is_focus_synced = match focused_container.as_window_container() {
Ok(window) => *window.native() == *native_window,
_ => Platform::desktop_window() == *native_window,
};

// Handle overriding focus on close/minimize. After a window is closed
// or minimized, the OS or the closed application might automatically
// switch focus to a different window. To force focus to go to the WM's
// target focus container, we reassign any focus events 100ms after
// close/minimize. This will cause focus to briefly flicker to the OS
// focus target and then to the WM's focus target.
if should_override_focus(&focused_container, native_window, state) {
if should_override_focus(state) {
state.pending_sync.queue_focus_change();
return Ok(());
}
Expand All @@ -54,6 +61,7 @@ pub fn handle_window_focused(

// Native focus has been synced to the WM's focused container.
if focused_container == window.clone().into() {
state.is_focus_synced = true;
state.pending_sync.queue_workspace_to_reorder(workspace);
return Ok(());
}
Expand Down Expand Up @@ -86,19 +94,10 @@ pub fn handle_window_focused(
}

/// Returns true if focus should be reassigned to the WM's focus container.
fn should_override_focus(
focused_container: &Container,
native_window: &NativeWindow,
state: &WmState,
) -> bool {
fn should_override_focus(state: &WmState) -> bool {
let has_recent_unmanage = state
.unmanaged_or_minimized_timestamp
.is_some_and(|time| time.elapsed().as_millis() < 100);

let has_correct_focus = match focused_container.as_window_container() {
Ok(window) => *window.native() == *native_window,
_ => Platform::desktop_window() == *native_window,
};

has_recent_unmanage && !has_correct_focus
has_recent_unmanage && !state.is_focus_synced
}
5 changes: 5 additions & 0 deletions packages/wm/src/wm_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub struct WmState {
/// Whether the WM is paused.
pub is_paused: bool,

/// Whether the OS focused window is the same as the WM focused window.
pub is_focus_synced: bool,

/// Whether the initial state has been populated.
has_initialized: bool,

Expand All @@ -82,6 +85,7 @@ impl WmState {
binding_modes: Vec::new(),
ignored_windows: Vec::new(),
is_paused: false,
is_focus_synced: false,
has_initialized: false,
event_tx,
exit_tx,
Expand Down Expand Up @@ -129,6 +133,7 @@ impl WmState {
.context("Failed to get container to focus.")?;

set_focused_descendant(&container_to_focus, None);
self.is_focus_synced = true;

self
.pending_sync
Expand Down

0 comments on commit 80b01dc

Please sign in to comment.