Update pointer focus before motion occurs
If the surface under the pointer has changed, we should send an `enter` event immediately, instead of waiting for the next motion event. This seems to fix that, without producing unnecessary events. Instead of `time: 0`, this and other synthesized events should probably use `CLOCK_MONOTONIC`. It seems libinput does document that it uses that.
This commit is contained in:
parent
889499b64d
commit
ca6f05c585
1 changed files with 27 additions and 1 deletions
|
|
@ -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::<Vec<_>>();
|
||||
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<State>) {
|
||||
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<Layer> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue