diff --git a/cosmic-comp-config/src/lib.rs b/cosmic-comp-config/src/lib.rs index e5e738830..c1be0c5c5 100644 --- a/cosmic-comp-config/src/lib.rs +++ b/cosmic-comp-config/src/lib.rs @@ -91,6 +91,15 @@ pub struct CosmicCompConfig { pub cursor_follows_focus: bool, /// The delay in milliseconds before focus follows mouse (if enabled) pub focus_follows_cursor_delay: u64, + /// When `focus_follows_cursor` is enabled, controls whether the window + /// that gains keyboard focus from the pointer passing over it is also + /// raised to the front of the stack. + /// + /// `true` = historical behaviour: hovering focuses AND raises. + /// `false` = "sloppy focus": hovering focuses but leaves stacking order + /// alone; a window only rises when explicitly acted upon + /// (clicked, keyboard-focused, or activated by an app). + pub focus_follows_cursor_raise: bool, /// Let X11 applications scale themselves pub descale_xwayland: XwaylandDescaling, /// Let X11 applications snoop on certain key-presses to allow for global shortcuts @@ -133,6 +142,9 @@ impl Default for CosmicCompConfig { focus_follows_cursor: false, cursor_follows_focus: false, focus_follows_cursor_delay: 250, + // Default true preserves the historical focus-follows-cursor + // behaviour (raise on hover) for everyone who has not opted out. + focus_follows_cursor_raise: true, descale_xwayland: XwaylandDescaling::Fractional, xwayland_eavesdropping: XwaylandEavesdropping::default(), edge_snap_threshold: 0, @@ -247,3 +259,19 @@ pub enum XwaylandDescaling { #[default] Fractional, } + +#[cfg(test)] +mod tests { + use super::CosmicCompConfig; + + /// The new "raise on focus-follows-cursor" option must default to `true` + /// so that upgrading users keep the historical behaviour (focus follows + /// the pointer AND raises). Only users who explicitly opt out get the + /// new "sloppy focus" behaviour. + #[test] + fn focus_follows_cursor_raise_defaults_to_true() { + // Build the whole config with its Default impl and check just the one field. + let config = CosmicCompConfig::default(); + assert!(config.focus_follows_cursor_raise); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 1d9b9c921..aff89abe3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -924,6 +924,17 @@ fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut state.common.config.cosmic_conf.focus_follows_cursor_delay = new; } } + // Live-reload the "raise on focus-follows-cursor" toggle. Reading the + // key and comparing before assigning matches the surrounding arms and + // avoids a needless write when the value is unchanged. No further work + // is required on change: the flag is consulted the next time focus + // follows the pointer, so the new setting takes effect immediately. + "focus_follows_cursor_raise" => { + let new = get_config::(&config, "focus_follows_cursor_raise"); + if new != state.common.config.cosmic_conf.focus_follows_cursor_raise { + state.common.config.cosmic_conf.focus_follows_cursor_raise = new; + } + } "edge_snap_threshold" => { let new = get_config::(&config, "edge_snap_threshold"); if new != state.common.config.cosmic_conf.edge_snap_threshold { diff --git a/src/input/actions.rs b/src/input/actions.rs index 3d017697d..f963136c7 100644 --- a/src/input/actions.rs +++ b/src/input/actions.rs @@ -3,7 +3,7 @@ use crate::{ config::{Action, PrivateAction}, shell::{ - FocusResult, InvalidWorkspaceIndex, MoveResult, SeatExt, Trigger, WorkspaceDelta, + FocusResult, InvalidWorkspaceIndex, MoveResult, Raise, SeatExt, Trigger, WorkspaceDelta, focus::{FocusTarget, target::KeyboardFocusTarget}, layout::tiling::SwapWindowGrab, }, @@ -306,6 +306,7 @@ impl State { seat, None, matches!(x, Action::MoveToWorkspace(_)), + Raise::Yes, ); } } @@ -333,6 +334,7 @@ impl State { seat, None, matches!(x, Action::MoveToLastWorkspace), + Raise::Yes, ); } } @@ -381,6 +383,7 @@ impl State { seat, None, matches!(x, Action::MoveToNextWorkspace), + Raise::Yes, ); } Ok(None) => {} @@ -472,6 +475,7 @@ impl State { seat, None, matches!(x, Action::MoveToPreviousWorkspace), + Raise::Yes, ); } Ok(None) => {} @@ -565,7 +569,14 @@ impl State { std::mem::drop(shell); let update_cursor = self.common.config.cosmic_conf.cursor_follows_focus; - Shell::set_focus(self, new_target.as_ref(), seat, None, update_cursor); + Shell::set_focus( + self, + new_target.as_ref(), + seat, + None, + update_cursor, + Raise::Yes, + ); if let Some(ptr) = seat.get_pointer() { // Update cursor position if `set_focus` didn't already @@ -640,7 +651,14 @@ impl State { if let Ok(Some((target, new_pos))) = res { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), seat, None, is_move_action); + Shell::set_focus( + self, + Some(&target), + seat, + None, + is_move_action, + Raise::Yes, + ); if let Some(ptr) = seat.get_pointer() { ptr.motion( self, @@ -787,7 +805,7 @@ impl State { } FocusResult::Handled => {} FocusResult::Some(target) => { - Shell::set_focus(self, Some(&target), seat, None, true); + Shell::set_focus(self, Some(&target), seat, None, true, Raise::Yes); } } } @@ -843,7 +861,7 @@ impl State { ) } MoveResult::ShiftFocus(shift) => { - Shell::set_focus(self, Some(&shift), seat, None, true); + Shell::set_focus(self, Some(&shift), seat, None, true, Raise::Yes); } _ => { let current_output = seat.active_output(); @@ -919,7 +937,14 @@ impl State { &self.common.event_loop_handle, ) { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), seat, Some(serial), true); + Shell::set_focus( + self, + Some(&target), + seat, + Some(serial), + true, + Raise::Yes, + ); } } Some(KeyboardFocusTarget::Fullscreen(surface)) => { @@ -927,7 +952,14 @@ impl State { shell.unfullscreen_request(&surface, &self.common.event_loop_handle) { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), seat, Some(serial), true); + Shell::set_focus( + self, + Some(&target), + seat, + Some(serial), + true, + Raise::Yes, + ); } } _ => {} @@ -964,7 +996,14 @@ impl State { .write() .toggle_stacking_focused(seat, &self.common.event_loop_handle); if let Some(new_focus) = res { - Shell::set_focus(self, Some(&new_focus), seat, Some(serial), false); + Shell::set_focus( + self, + Some(&new_focus), + seat, + Some(serial), + false, + Raise::Yes, + ); } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 1114d50b5..14e4d99c3 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -11,7 +11,7 @@ use crate::{ }, input::gestures::{GestureState, SwipeAction}, shell::{ - LastModifierChange, SeatExt, Trigger, + LastModifierChange, Raise, SeatExt, Trigger, focus::{ Stage, render_input_order, target::{KeyboardFocusTarget, PointerFocusTarget}, @@ -462,12 +462,27 @@ impl State { //takes this function to run state.common.pointer_focus_state = None; + // Focus is following the pointer here. Raise + // only if the user has left raise-on-hover on; + // otherwise pass Raise::No so the window gains + // focus without being lifted (sloppy focus). + let raise = if state + .common + .config + .cosmic_conf + .focus_follows_cursor_raise + { + Raise::Yes + } else { + Raise::No + }; Shell::set_focus( state, target.as_ref(), &seat, Some(SERIAL_COUNTER.next_serial()), false, + raise, ); TimeoutAction::Drop @@ -909,7 +924,14 @@ impl State { } } - Shell::set_focus(self, Some(&target), &seat, Some(serial), false); + Shell::set_focus( + self, + Some(&target), + &seat, + Some(serial), + false, + Raise::Yes, + ); } } } else { @@ -2036,7 +2058,14 @@ impl State { ) { let seat = seat.clone(); self.common.event_loop_handle.insert_idle(move |state| { - Shell::set_focus(state, Some(&focus), &seat, None, true); + Shell::set_focus( + state, + Some(&focus), + &seat, + None, + true, + Raise::Yes, + ); }); } old_workspace.refresh_focus_stack(); @@ -2052,7 +2081,7 @@ impl State { std::mem::drop(spaces); let seat = seat.clone(); self.common.event_loop_handle.insert_idle(move |state| { - Shell::set_focus(state, Some(&focus), &seat, None, true); + Shell::set_focus(state, Some(&focus), &seat, None, true, Raise::Yes); }); } workspace.refresh_focus_stack(); @@ -2088,7 +2117,7 @@ impl State { ) { let seat = seat.clone(); self.common.event_loop_handle.insert_idle(move |state| { - Shell::set_focus(state, Some(&focus), &seat, None, true); + Shell::set_focus(state, Some(&focus), &seat, None, true, Raise::Yes); }); } old_workspace.refresh_focus_stack(); diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index 9374230a4..a6c2edbd9 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -36,6 +36,27 @@ pub enum FocusTarget { Fullscreen(CosmicSurface), } +/// Whether a focus change should also raise the focused window to the top of +/// its layer's stacking order. +/// +/// This exists to keep raising separate from focusing. Historically every +/// focus change raised the window; with focus-follows-cursor that means a +/// window jumps to the front merely because the pointer crossed it. Passing +/// `Raise::No` lets focus move without disturbing stacking order (sloppy +/// focus). A named enum is used instead of a bare `bool` because `set_focus` +/// already takes another boolean (`update_cursor`); two adjacent bools at a +/// call site are easy to transpose, whereas `Raise::Yes`/`Raise::No` is +/// self-documenting. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Raise { + /// Raise the window. Used for explicit focus intent: a click, a keyboard + /// action, or an application activating itself. + Yes, + /// Do not raise. Used when focus arrived passively (the pointer moved onto + /// the window) and the user has opted out of raise-on-hover. + No, +} + impl PartialEq for FocusTarget { fn eq(&self, other: &CosmicMapped) -> bool { matches!(self, FocusTarget::Window(mapped) if mapped == other) @@ -194,6 +215,10 @@ impl Shell { seat: &Seat, serial: Option, update_cursor: bool, + // Whether this focus change should also raise the window. Explicit + // focus passes Raise::Yes; passive focus-follows-cursor passes the + // user's configured choice. + raise: Raise, ) { let focus_target = match target { Some(KeyboardFocusTarget::Element(mapped)) => Some(FocusTarget::Window(mapped.clone())), @@ -209,7 +234,24 @@ impl Shell { update_focus_state(seat, target, state, serial, update_cursor); - state.common.shell.write().update_active(); + // Record or clear the "focused but do not auto-raise" mark under the + // same write lock we use to run update_active(), so the two stay + // consistent. On explicit focus (Raise::Yes) we clear any prior mark + // so the window raises normally. On passive focus with raising off + // (Raise::No) we mark the focused window — but only if it is an actual + // toplevel element; fullscreen and layer-surface targets are never in + // the floating stack, so there is nothing to suppress for them. + { + let mut shell = state.common.shell.write(); + shell.no_raise_window = match raise { + Raise::No => match target { + Some(KeyboardFocusTarget::Element(mapped)) => Some(mapped.clone()), + _ => None, + }, + Raise::Yes => None, + }; + shell.update_active(); + } } pub fn append_focus_stack(&mut self, target: impl Into, seat: &Seat) { @@ -269,9 +311,22 @@ impl Shell { }) .collect::>(); + // Snapshot the no-raise mark before the loops below borrow `self` + // mutably (they call `self.workspaces...get_mut`). Cloning a + // CosmicMapped is cheap (it is reference-counted) and releasing the + // borrow here keeps the borrow checker happy. + let no_raise = self.no_raise_window.clone(); + for output in self.outputs().cloned().collect::>().into_iter() { let set = self.workspaces.sets.get_mut(&output).unwrap(); for focused in focused_windows.iter() { + // Skip raising a window the user is only hovering over (sloppy + // focus): raising it would defeat focus-follows-cursor-without- + // raise. All other (explicit) focus changes cleared the mark, + // so they fall through and raise as before. + if no_raise.as_ref() == Some(focused) { + continue; + } raise_with_children(&mut set.sticky_layer, focused); } for window in set.sticky_layer.mapped() { @@ -302,6 +357,10 @@ impl Shell { fs.surface.send_configure(); } for focused in focused_windows.iter() { + // Same sloppy-focus guard as the sticky layer above. + if no_raise.as_ref() == Some(focused) { + continue; + } raise_with_children(&mut workspace.floating_layer, focused); } for window in workspace.mapped() { diff --git a/src/shell/grabs/menu/default.rs b/src/shell/grabs/menu/default.rs index c7418b6d9..337cb7344 100644 --- a/src/shell/grabs/menu/default.rs +++ b/src/shell/grabs/menu/default.rs @@ -8,7 +8,7 @@ use crate::{ config::Config, fl, shell::{ - CosmicSurface, PointGlobalExt, Shell, + CosmicSurface, PointGlobalExt, Raise, Shell, element::{CosmicMapped, CosmicWindow}, grabs::ReleaseMode, }, @@ -24,7 +24,7 @@ fn toggle_stacking(state: &mut State, mapped: &CosmicMapped) { let seat = shell.seats.last_active().clone(); if let Some(new_focus) = shell.toggle_stacking(&seat, mapped) { std::mem::drop(shell); - Shell::set_focus(state, Some(&new_focus), &seat, None, false); + Shell::set_focus(state, Some(&new_focus), &seat, None, false, Raise::Yes); } } @@ -78,7 +78,7 @@ fn move_fullscreen_prev_workspace(state: &mut State, surface: &CosmicSurface) { ); if let Some((target, _)) = res { std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, true); + Shell::set_focus(state, Some(&target), &seat, None, true, Raise::Yes); } } @@ -104,7 +104,7 @@ fn move_fullscreen_next_workspace(state: &mut State, surface: &CosmicSurface) { ); if let Some((target, _)) = res { std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, true); + Shell::set_focus(state, Some(&target), &seat, None, true, Raise::Yes); } } @@ -130,7 +130,7 @@ fn move_element_prev_workspace(state: &mut State, mapped: &CosmicMapped) { ); if let Some((target, _)) = res { std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, true); + Shell::set_focus(state, Some(&target), &seat, None, true, Raise::Yes); } } @@ -156,7 +156,7 @@ fn move_element_next_workspace(state: &mut State, mapped: &CosmicMapped) { ); if let Some((target, _point)) = res { std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, true) + Shell::set_focus(state, Some(&target), &seat, None, true, Raise::Yes) } } @@ -304,7 +304,7 @@ pub fn window_items( &state.common.event_loop_handle, ) { std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, false); + Shell::set_focus(state, Some(&target), &seat, None, false, Raise::Yes); } }); }) @@ -594,7 +594,7 @@ pub fn fullscreen_items(window: &CosmicSurface, config: &Config) -> impl Iterato { let seat = shell.seats.last_active().clone(); std::mem::drop(shell); - Shell::set_focus(state, Some(&target), &seat, None, true); + Shell::set_focus(state, Some(&target), &seat, None, true, Raise::Yes); } }); }) diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index d87148300..1c5287b31 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -5,7 +5,7 @@ use crate::{ BackdropShader, IndicatorShader, Key, Usage, cursor::CursorState, element::AsGlowRenderer, }, shell::{ - CosmicMapped, CosmicSurface, Direction, ManagedLayer, + CosmicMapped, CosmicSurface, Direction, ManagedLayer, Raise, element::{CosmicMappedRenderElement, stack_hover::StackHover}, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, layout::floating::TiledCorners, @@ -967,6 +967,7 @@ impl Drop for MoveGrab { &seat, Some(serial), false, + Raise::Yes, ) } }); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 8e6289854..2b67a8f22 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -97,6 +97,8 @@ mod seats; mod workspace; pub mod zoom; pub use self::element::{CosmicMapped, CosmicMappedRenderElement, CosmicSurface}; +// Re-export Raise so call sites can `use crate::shell::Raise;` alongside Shell. +pub use self::focus::Raise; pub use self::seats::*; pub use self::workspace::*; use self::zoom::{OutputZoomState, ZoomState}; @@ -297,6 +299,19 @@ pub struct Shell { appearance_conf: AppearanceConfig, tiling_exceptions: TilingExceptions, + /// The single window that currently holds focus but must NOT be + /// auto-raised, because focus arrived from the pointer while + /// raise-on-hover was disabled (`focus_follows_cursor_raise == false`). + /// + /// `update_active()` — and the periodic focus-reconciliation pass that + /// also calls it — skip raising this window, so it stays at its current + /// stacking depth. The mark is set by `set_focus` when passed `Raise::No` + /// and cleared when passed `Raise::Yes` (any explicit focus). Only one + /// window is tracked: focus-follows-cursor is inherently a single-pointer + /// gesture, so a per-seat map would add complexity without user-visible + /// benefit in the common single-seat case. + no_raise_window: Option, + #[cfg(feature = "debug")] pub debug_active: bool, } @@ -1713,6 +1728,8 @@ impl Shell { appearance_conf: config.cosmic_conf.appearance_settings, zoom_state: None, tiling_exceptions, + // No window starts marked as no-raise; the mark is set on demand. + no_raise_window: None, #[cfg(feature = "debug")] debug_active: false, diff --git a/src/wayland/handlers/compositor.rs b/src/wayland/handlers/compositor.rs index 12bc2e565..6d39a4d6b 100644 --- a/src/wayland/handlers/compositor.rs +++ b/src/wayland/handlers/compositor.rs @@ -1,6 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-only -use crate::{shell::grabs::SeatMoveGrabState, state::ClientState, utils::prelude::*}; +use crate::{ + shell::{Raise, grabs::SeatMoveGrabState}, + state::ClientState, + utils::prelude::*, +}; use calloop::Interest; use smithay::{ backend::renderer::{ @@ -406,7 +410,7 @@ impl 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, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); return true; } } @@ -423,7 +427,7 @@ impl State { if let Some(target) = shell.map_layer(&layer_surface) { let seat = shell.seats.last_active().clone(); std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, false); + Shell::set_focus(self, Some(&target), &seat, None, false, Raise::Yes); } layer_surface.layer_surface().send_configure(); return true; diff --git a/src/wayland/handlers/toplevel_management.rs b/src/wayland/handlers/toplevel_management.rs index 3da399529..12889f1a8 100644 --- a/src/wayland/handlers/toplevel_management.rs +++ b/src/wayland/handlers/toplevel_management.rs @@ -10,7 +10,7 @@ use smithay::{ }; use crate::{ - shell::{CosmicSurface, Shell, WorkspaceDelta, focus::target::KeyboardFocusTarget}, + shell::{CosmicSurface, Raise, Shell, WorkspaceDelta, focus::target::KeyboardFocusTarget}, utils::prelude::*, wayland::protocols::{ toplevel_info::ToplevelInfoHandler, @@ -131,7 +131,7 @@ impl ToplevelManagementHandler for State { } } - Shell::set_focus(self, Some(&target), &seat, None, false); + Shell::set_focus(self, Some(&target), &seat, None, false, Raise::Yes); return; } } @@ -168,7 +168,7 @@ impl ToplevelManagementHandler for State { ); if let Some((target, _)) = res { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } } @@ -191,7 +191,7 @@ impl ToplevelManagementHandler for State { shell.fullscreen_request(window, output, &self.common.event_loop_handle) { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } } diff --git a/src/wayland/handlers/xdg_activation.rs b/src/wayland/handlers/xdg_activation.rs index ad8ce0d05..58bbee0da 100644 --- a/src/wayland/handlers/xdg_activation.rs +++ b/src/wayland/handlers/xdg_activation.rs @@ -1,3 +1,4 @@ +use crate::shell::Raise; use crate::shell::WorkspaceDelta; use crate::shell::focus::target::KeyboardFocusTarget; use crate::{shell::ActivationKey, state::ClientState, utils::prelude::*}; @@ -259,6 +260,7 @@ impl State { &seat, None, false, + Raise::Yes, ); } else if let Some((workspace, _)) = shell.workspace_for_surface(surface) { let current_workspace = shell.active_space(¤t_output).unwrap(); @@ -275,7 +277,7 @@ impl State { }; std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, false); + Shell::set_focus(self, Some(&target), &seat, None, false, Raise::Yes); } else { if let Some(surface) = shell .workspaces diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index 98b8acf66..6135ef386 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -1,7 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - shell::{CosmicSurface, PendingWindow, focus::target::KeyboardFocusTarget, grabs::ReleaseMode}, + shell::{ + CosmicSurface, PendingWindow, Raise, focus::target::KeyboardFocusTarget, grabs::ReleaseMode, + }, utils::prelude::*, }; use smithay::desktop::layer_map_for_output; @@ -123,6 +125,7 @@ impl XdgShellHandler for State { &seat, Some(serial), false, + Raise::Yes, ); keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial); } @@ -275,7 +278,7 @@ impl XdgShellHandler for State { match shell.fullscreen_request(&surface, output.clone(), &self.common.event_loop_handle) { Some(target) => { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } None => { if let Some(pending) = shell.pending_windows.iter_mut().find(|pending| { @@ -305,7 +308,7 @@ impl XdgShellHandler for State { if let Some(target) = shell.unfullscreen_request(&surface, &self.common.event_loop_handle) { std::mem::drop(shell); if should_focus { - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } } else if let Some(pending) = shell .pending_windows diff --git a/src/xwayland.rs b/src/xwayland.rs index aba65ef52..05ed178cc 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -9,7 +9,8 @@ use std::{ use crate::{ backend::render::cursor::{Cursor, load_cursor_env, load_cursor_theme}, shell::{ - CosmicSurface, PendingWindow, Shell, focus::target::KeyboardFocusTarget, grabs::ReleaseMode, + CosmicSurface, PendingWindow, Raise, Shell, focus::target::KeyboardFocusTarget, + grabs::ReleaseMode, }, state::State, utils::prelude::*, @@ -850,7 +851,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(self, Some(&target), &seat, None, false, Raise::Yes); } } } @@ -1130,7 +1131,7 @@ impl XwmHandler for State { match shell.fullscreen_request(&window, output.clone(), &self.common.event_loop_handle) { Some(target) => { std::mem::drop(shell); - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } None => { if let Some(pending) = shell @@ -1162,7 +1163,7 @@ impl XwmHandler for State { if let Some(target) = shell.unfullscreen_request(&window, &self.common.event_loop_handle) { std::mem::drop(shell); if should_focus { - Shell::set_focus(self, Some(&target), &seat, None, true); + Shell::set_focus(self, Some(&target), &seat, None, true, Raise::Yes); } } else if let Some(pending) = shell .pending_windows