diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index 2ff1799a..eda6d100 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -7,7 +7,7 @@ use crate::{ use indexmap::IndexSet; use smithay::{ desktop::{layer_map_for_output, PopupUngrabStrategy}, - input::Seat, + input::{pointer::MotionEvent, Seat}, output::Output, reexports::wayland_server::Resource, utils::{IsAlive, Serial, SERIAL_COUNTER}, @@ -261,6 +261,8 @@ impl Common { .cloned() .collect::>(); for seat in &seats { + update_pointer_focus(state, &seat); + let mut shell = state.common.shell.write().unwrap(); let output = seat.active_output(); if !shell.outputs().any(|o| o == &output) { @@ -481,6 +483,30 @@ fn update_focus_target( } } +fn update_pointer_focus(state: &mut State, seat: &Seat) { + if let Some(pointer) = seat.get_pointer() { + let output = seat.active_output(); + let position = pointer.current_location().as_global(); + + let mut shell = state.common.shell.write().unwrap(); + let under = State::surface_under(position, &output, &mut shell) + .map(|(target, pos)| (target, pos.as_logical())); + drop(shell); + + if pointer.current_focus().as_ref() != under.as_ref().map(|(target, _)| target) { + pointer.motion( + state, + under, + &MotionEvent { + location: pointer.current_location(), + serial: SERIAL_COUNTER.next_serial(), + time: 0, + }, + ); + } + } +} + // Get the top-most layer, if any, with at least one surface with exclusive keyboard interactivity. // Only considers surface in `Top` or `Overlay` layer. fn exclusive_layer_surface_layer(shell: &Shell) -> Option {