aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-11-17 18:30:24 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-11-17 18:30:24 +0400
commit19cafffe0f3f1eefc6984dc446134b0fd93d1e28 (patch)
treeac7a4e261f5c17fb4418a9738553109ac1f2d058 /src
parent136f2726891a5622ff83501a53b23a16a1761560 (diff)
downloadniri-19cafffe0f3f1eefc6984dc446134b0fd93d1e28.tar.gz
niri-19cafffe0f3f1eefc6984dc446134b0fd93d1e28.tar.bz2
niri-19cafffe0f3f1eefc6984dc446134b0fd93d1e28.zip
Fix top layer-shell surfaces keeping keyboard focus during fullscreen
Diffstat (limited to 'src')
-rw-r--r--src/niri.rs42
1 files changed, 27 insertions, 15 deletions
diff --git a/src/niri.rs b/src/niri.rs
index 570c199b..cabca83f 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -28,7 +28,9 @@ use smithay::desktop::utils::{
surface_primary_scanout_output, take_presentation_feedback_surface_tree,
under_from_surface_tree, update_surface_primary_scanout_output, OutputPresentationFeedback,
};
-use smithay::desktop::{layer_map_for_output, PopupManager, Space, Window, WindowSurfaceType};
+use smithay::desktop::{
+ layer_map_for_output, LayerSurface, PopupManager, Space, Window, WindowSurfaceType,
+};
use smithay::input::keyboard::{Layout as KeyboardLayout, XkbConfig, XkbContextHandler};
use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus, MotionEvent};
use smithay::input::{Seat, SeatState};
@@ -370,13 +372,34 @@ impl State {
self.niri.lock_surface_focus()
} else if self.niri.screenshot_ui.is_open() {
None
- } else {
- self.niri.layer_surface_focus().or_else(|| {
+ } else if let Some(output) = self.niri.layout.active_output() {
+ let mon = self.niri.layout.monitor_for_output(output).unwrap();
+ let layers = layer_map_for_output(output);
+
+ let layout_focus = || {
self.niri
.layout
.focus()
.map(|win| win.toplevel().wl_surface().clone())
- })
+ };
+ let layer_focus = |surface: &LayerSurface| {
+ surface
+ .can_receive_keyboard_focus()
+ .then(|| surface.wl_surface().clone())
+ };
+
+ let mut surface = layers.layers_on(Layer::Overlay).find_map(layer_focus);
+ if mon.render_above_top_layer() {
+ surface = surface.or_else(layout_focus);
+ surface = surface.or_else(|| layers.layers_on(Layer::Top).find_map(layer_focus));
+ } else {
+ surface = surface.or_else(|| layers.layers_on(Layer::Top).find_map(layer_focus));
+ surface = surface.or_else(layout_focus);
+ }
+
+ surface
+ } else {
+ None
};
let keyboard = self.niri.seat.get_keyboard().unwrap();
@@ -1145,17 +1168,6 @@ impl Niri {
state.lock_surface.as_ref().map(|s| s.wl_surface()).cloned()
}
- fn layer_surface_focus(&self) -> Option<WlSurface> {
- let output = self.layout.active_output()?;
- let layers = layer_map_for_output(output);
- let surface = layers
- .layers_on(Layer::Overlay)
- .chain(layers.layers_on(Layer::Top))
- .find(|surface| surface.can_receive_keyboard_focus())?;
-
- Some(surface.wl_surface().clone())
- }
-
/// Schedules an immediate redraw on all outputs if one is not already scheduled.
pub fn queue_redraw_all(&mut self) {
let outputs: Vec<_> = self.output_state.keys().cloned().collect();