diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index 4e88c499..cab37a85 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -212,6 +212,29 @@ impl Shell { state.common.shell.write().update_active(); } + // We suppress Element(X) to Fullscreen(X) transition to avoid + // loss of focus by the X window when having a transition to fullscreen + // but in the case of X11 unmap/map the leave/enter needs to happen for the X11 + // internal state to be focused on the window + pub fn set_focus_on_x11_map( + state: &mut State, + target: &KeyboardFocusTarget, + seat: &Seat, + update_cursor: bool, + ) { + let need_reset = seat + .get_keyboard() + .and_then(|keyboard| keyboard.current_focus()) + .and_then(|current| current.x11_surface()) + .is_some_and(|current| Some(current) == target.x11_surface()); + + if need_reset { + update_focus_state(seat, None, state, None, false); + } + + Shell::set_focus(state, Some(target), seat, None, update_cursor); + } + pub fn append_focus_stack(&mut self, target: impl Into, seat: &Seat) { let target = target.into(); if target.is_minimized() { diff --git a/src/shell/focus/target.rs b/src/shell/focus/target.rs index 929cd92e..80b1a34f 100644 --- a/src/shell/focus/target.rs +++ b/src/shell/focus/target.rs @@ -326,7 +326,7 @@ impl KeyboardFocusTarget { } } - fn x11_surface(&self) -> Option { + pub fn x11_surface(&self) -> Option { match self { KeyboardFocusTarget::Element(mapped) => mapped.active_window().x11_surface().cloned(), KeyboardFocusTarget::Fullscreen(surface) => surface.x11_surface().cloned(), diff --git a/src/xwayland.rs b/src/xwayland.rs index 25b8b0e0..83978b6e 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -858,7 +858,7 @@ impl XwmHandler for State { if let Some(target) = res { let seat = shell.seats.last_active().clone(); std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, false); + Shell::set_focus_on_x11_map(self, &target, &seat, false); } } }