Skip to content

Commit

Permalink
skip keyboard focus for layer shell surfaces not...
Browse files Browse the repository at this point in the history
...requesting keyboard interactivity
  • Loading branch information
cmeissl committed Nov 24, 2024
1 parent e036fcb commit 08255b2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
23 changes: 20 additions & 3 deletions src/handlers/xdg_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,17 @@ impl XdgShellHandler for State {
let keyboard = seat.get_keyboard().unwrap();
let pointer = seat.get_pointer().unwrap();

let can_receive_keyboard_focus = self
.niri
.layout
.active_output()
.and_then(|output| {
layer_map_for_output(output)
.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)
.map(|layer_surface| layer_surface.can_receive_keyboard_focus())
})
.unwrap_or(true);

let keyboard_grab_mismatches = keyboard.is_grabbed()
&& !(keyboard.has_grab(serial)
|| grab
Expand All @@ -360,15 +371,21 @@ impl XdgShellHandler for State {
let pointer_grab_mismatches = pointer.is_grabbed()
&& !(pointer.has_grab(serial)
|| grab.previous_serial().map_or(true, |s| pointer.has_grab(s)));
if keyboard_grab_mismatches || pointer_grab_mismatches {
if (can_receive_keyboard_focus && keyboard_grab_mismatches) || pointer_grab_mismatches {
grab.ungrab(PopupUngrabStrategy::All);
return;
}

trace!("new grab for root {:?}", root);
keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial);
if can_receive_keyboard_focus {
keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial);
}
pointer.set_grab(self, PopupPointerGrab::new(&grab), serial, Focus::Keep);
self.niri.popup_grab = Some(PopupGrabState { root, grab });
self.niri.popup_grab = Some(PopupGrabState {
root,
grab,
has_keyboard_grab: can_receive_keyboard_focus,
});
}

fn maximize_request(&mut self, surface: ToplevelSurface) {
Expand Down
5 changes: 3 additions & 2 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ pub enum RedrawState {
pub struct PopupGrabState {
pub root: WlSurface,
pub grab: PopupGrab<State>,
pub has_keyboard_grab: bool,
}

// The surfaces here are always toplevel surfaces focused as far as niri's logic is concerned, even
Expand Down Expand Up @@ -837,7 +838,7 @@ impl State {
let layer_grab = self.niri.popup_grab.as_ref().and_then(|g| {
layers
.layer_for_surface(&g.root, WindowSurfaceType::TOPLEVEL)
.map(|l| (&g.root, l.layer()))
.and_then(|l| l.can_receive_keyboard_focus().then(|| (&g.root, l.layer())))
});
let grab_on_layer = |layer: Layer| {
layer_grab
Expand Down Expand Up @@ -956,7 +957,7 @@ impl State {
}

if let Some(grab) = self.niri.popup_grab.as_mut() {
if Some(&grab.root) != focus.surface() {
if grab.has_keyboard_grab && Some(&grab.root) != focus.surface() {
trace!(
"grab root {:?} is not the new focus {:?}, ungrabbing",
grab.root,
Expand Down

0 comments on commit 08255b2

Please sign in to comment.