shell: Don't unconditionally focus on unfullscreen

This commit is contained in:
Victoria Brekenfeld 2025-07-17 18:29:57 +02:00 committed by Victoria Brekenfeld
parent a74c90f14f
commit 0ef372f797
3 changed files with 35 additions and 10 deletions

View file

@ -181,11 +181,9 @@ impl ToplevelManagementHandler for State {
window: &<Self as ToplevelInfoHandler>::Window, window: &<Self as ToplevelInfoHandler>::Window,
) { ) {
let mut shell = self.common.shell.write(); let mut shell = self.common.shell.write();
if let Some(target) = shell.unfullscreen_request(window, &self.common.event_loop_handle) { let _ = shell.unfullscreen_request(window, &self.common.event_loop_handle);
let seat = shell.seats.last_active().clone(); // don't switch focus because of a programmatic action.
std::mem::drop(shell); // If the toplevel-management client intends to focus the now unfullscreened toplevel, it can send an `activate`-request.
Shell::set_focus(self, Some(&target), &seat, None, true);
}
} }
fn maximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) { fn maximize(&mut self, _dh: &DisplayHandle, window: &<Self as ToplevelInfoHandler>::Window) {

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::{ use crate::{
shell::{grabs::ReleaseMode, CosmicSurface, PendingWindow}, shell::{focus::target::KeyboardFocusTarget, grabs::ReleaseMode, CosmicSurface, PendingWindow},
utils::prelude::*, utils::prelude::*,
}; };
use smithay::{ use smithay::{
@ -260,11 +260,24 @@ impl XdgShellHandler for State {
fn unfullscreen_request(&mut self, surface: ToplevelSurface) { fn unfullscreen_request(&mut self, surface: ToplevelSurface) {
let mut shell = self.common.shell.write(); let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
let should_focus = seat
.get_keyboard()
.unwrap()
.current_focus()
.is_some_and(|target| {
if let KeyboardFocusTarget::Fullscreen(s) = target {
s == surface
} else {
false
}
});
if let Some(target) = shell.unfullscreen_request(&surface, &self.common.event_loop_handle) { if let Some(target) = shell.unfullscreen_request(&surface, &self.common.event_loop_handle) {
let seat = shell.seats.last_active().clone();
std::mem::drop(shell); std::mem::drop(shell);
Shell::set_focus(self, Some(&target), &seat, None, true); if should_focus {
Shell::set_focus(self, Some(&target), &seat, None, true);
}
} else { } else {
if let Some(pending) = shell.pending_windows.iter_mut().find(|pending| { if let Some(pending) = shell.pending_windows.iter_mut().find(|pending| {
pending.surface.wl_surface().as_deref() == Some(surface.wl_surface()) pending.surface.wl_surface().as_deref() == Some(surface.wl_surface())

View file

@ -1082,10 +1082,24 @@ impl XwmHandler for State {
fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
let mut shell = self.common.shell.write(); let mut shell = self.common.shell.write();
let seat = shell.seats.last_active().clone();
let should_focus = seat
.get_keyboard()
.unwrap()
.current_focus()
.is_some_and(|target| {
if let KeyboardFocusTarget::Fullscreen(s) = target {
s == window
} else {
false
}
});
if let Some(target) = shell.unfullscreen_request(&window, &self.common.event_loop_handle) { if let Some(target) = shell.unfullscreen_request(&window, &self.common.event_loop_handle) {
let seat = shell.seats.last_active().clone();
std::mem::drop(shell); std::mem::drop(shell);
Shell::set_focus(self, Some(&target), &seat, None, true); if should_focus {
Shell::set_focus(self, Some(&target), &seat, None, true);
}
} else { } else {
if let Some(pending) = shell if let Some(pending) = shell
.pending_windows .pending_windows