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 indexmap::IndexSet;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::{layer_map_for_output, PopupUngrabStrategy},
|
desktop::{layer_map_for_output, PopupUngrabStrategy},
|
||||||
input::Seat,
|
input::{pointer::MotionEvent, Seat},
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::Resource,
|
reexports::wayland_server::Resource,
|
||||||
utils::{IsAlive, Serial, SERIAL_COUNTER},
|
utils::{IsAlive, Serial, SERIAL_COUNTER},
|
||||||
|
|
@ -261,6 +261,8 @@ impl Common {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
for seat in &seats {
|
for seat in &seats {
|
||||||
|
update_pointer_focus(state, &seat);
|
||||||
|
|
||||||
let mut shell = state.common.shell.write().unwrap();
|
let mut shell = state.common.shell.write().unwrap();
|
||||||
let output = seat.active_output();
|
let output = seat.active_output();
|
||||||
if !shell.outputs().any(|o| o == &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.
|
// Get the top-most layer, if any, with at least one surface with exclusive keyboard interactivity.
|
||||||
// Only considers surface in `Top` or `Overlay` layer.
|
// Only considers surface in `Top` or `Overlay` layer.
|
||||||
fn exclusive_layer_surface_layer(shell: &Shell) -> Option<Layer> {
|
fn exclusive_layer_surface_layer(shell: &Shell) -> Option<Layer> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue