accepts_input_at rejects buffer-less surfaces
This commit is contained in:
parent
bb43c238e3
commit
12adb678bb
1 changed files with 48 additions and 2 deletions
|
|
@ -318,7 +318,7 @@ pub struct WlSurface {
|
||||||
pub content_type: Cell<Option<ContentType>>,
|
pub content_type: Cell<Option<ContentType>>,
|
||||||
pub drm_feedback: CopyHashMap<ZwpLinuxDmabufFeedbackV1Id, Rc<ZwpLinuxDmabufFeedbackV1>>,
|
pub drm_feedback: CopyHashMap<ZwpLinuxDmabufFeedbackV1Id, Rc<ZwpLinuxDmabufFeedbackV1>>,
|
||||||
syncobj_surface: CloneCell<Option<Rc<WpLinuxDrmSyncobjSurfaceV1>>>,
|
syncobj_surface: CloneCell<Option<Rc<WpLinuxDrmSyncobjSurfaceV1>>>,
|
||||||
destroyed: Cell<bool>,
|
pub destroyed: Cell<bool>,
|
||||||
commit_timeline: CommitTimeline,
|
commit_timeline: CommitTimeline,
|
||||||
alpha_modifier: CloneCell<Option<Rc<WpAlphaModifierSurfaceV1>>>,
|
alpha_modifier: CloneCell<Option<Rc<WpAlphaModifierSurfaceV1>>>,
|
||||||
alpha: Cell<Option<f32>>,
|
alpha: Cell<Option<f32>>,
|
||||||
|
|
@ -1019,6 +1019,7 @@ impl WlSurfaceRequestHandler for WlSurface {
|
||||||
self.unset_dnd_icons();
|
self.unset_dnd_icons();
|
||||||
self.unset_cursors();
|
self.unset_cursors();
|
||||||
self.ext.get().on_surface_destroy()?;
|
self.ext.get().on_surface_destroy()?;
|
||||||
|
self.destroyed.set(true);
|
||||||
self.destroy_node();
|
self.destroy_node();
|
||||||
{
|
{
|
||||||
let mut children = self.children.borrow_mut();
|
let mut children = self.children.borrow_mut();
|
||||||
|
|
@ -1029,6 +1030,19 @@ impl WlSurfaceRequestHandler for WlSurface {
|
||||||
}
|
}
|
||||||
*children = None;
|
*children = None;
|
||||||
}
|
}
|
||||||
|
// Capture a close-animation snapshot if the client is destroying the
|
||||||
|
// surface while it still has a buffer (i.e. without a clean null-attach
|
||||||
|
// commit first — typical for crash/disconnect paths).
|
||||||
|
if self.buffer.is_some()
|
||||||
|
&& let Some(tl) = self.toplevel.get()
|
||||||
|
&& let Some(snap) = crate::animation::capture_snapshot(&self.client.state, &tl)
|
||||||
|
{
|
||||||
|
self.client
|
||||||
|
.state
|
||||||
|
.close_snapshots
|
||||||
|
.borrow_mut()
|
||||||
|
.push(Rc::new(snap));
|
||||||
|
}
|
||||||
self.buffer.set(None);
|
self.buffer.set(None);
|
||||||
self.reset_shm_textures();
|
self.reset_shm_textures();
|
||||||
if let Some(xwayland_serial) = self.xwayland_serial.get() {
|
if let Some(xwayland_serial) = self.xwayland_serial.get() {
|
||||||
|
|
@ -1041,7 +1055,6 @@ impl WlSurfaceRequestHandler for WlSurface {
|
||||||
self.client.remove_obj(self)?;
|
self.client.remove_obj(self)?;
|
||||||
self.idle_inhibitors.clear();
|
self.idle_inhibitors.clear();
|
||||||
self.constraints.take();
|
self.constraints.take();
|
||||||
self.destroyed.set(true);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1238,8 +1251,24 @@ impl WlSurface {
|
||||||
let mut buffer_changed = false;
|
let mut buffer_changed = false;
|
||||||
let mut old_raw_size = None;
|
let mut old_raw_size = None;
|
||||||
let (mut dx, mut dy) = mem::take(&mut pending.offset);
|
let (mut dx, mut dy) = mem::take(&mut pending.offset);
|
||||||
|
let mut buffer_presence_changed = false;
|
||||||
if let Some(buffer_change) = pending.buffer.take() {
|
if let Some(buffer_change) = pending.buffer.take() {
|
||||||
buffer_changed = true;
|
buffer_changed = true;
|
||||||
|
buffer_presence_changed = buffer_change.is_some() != self.buffer.is_some();
|
||||||
|
// If the client just attached a null buffer to the main surface of
|
||||||
|
// a mapped toplevel, capture a snapshot before we drop the buffer
|
||||||
|
// so the close animation has something to render after teardown.
|
||||||
|
if buffer_change.is_none()
|
||||||
|
&& self.buffer.is_some()
|
||||||
|
&& let Some(tl) = self.toplevel.get()
|
||||||
|
&& let Some(snap) = crate::animation::capture_snapshot(&self.client.state, &tl)
|
||||||
|
{
|
||||||
|
self.client
|
||||||
|
.state
|
||||||
|
.close_snapshots
|
||||||
|
.borrow_mut()
|
||||||
|
.push(Rc::new(snap));
|
||||||
|
}
|
||||||
if let Some(buffer) = self.buffer.take() {
|
if let Some(buffer) = self.buffer.take() {
|
||||||
old_raw_size = Some(buffer.buffer.buf.rect);
|
old_raw_size = Some(buffer.buffer.buf.rect);
|
||||||
}
|
}
|
||||||
|
|
@ -1408,6 +1437,16 @@ impl WlSurface {
|
||||||
};
|
};
|
||||||
self.is_opaque.set(is_opaque);
|
self.is_opaque.set(is_opaque);
|
||||||
}
|
}
|
||||||
|
if buffer_abs_pos_size_changed || buffer_presence_changed {
|
||||||
|
// Pointer focus depends on whether this surface accepts input.
|
||||||
|
// It just changed (size shrank/grew, or buffer went from null to
|
||||||
|
// non-null or vice versa — the latter happens when a client
|
||||||
|
// dismisses a subsurface by null-attaching while keeping its
|
||||||
|
// wp_viewport destination). Force a re-evaluation so the pointer
|
||||||
|
// stack doesn't keep a now-invisible surface focused until the
|
||||||
|
// next motion event.
|
||||||
|
self.client.state.tree_changed();
|
||||||
|
}
|
||||||
let mut tearing_changed = false;
|
let mut tearing_changed = false;
|
||||||
if let Some(tearing) = pending.tearing.take()
|
if let Some(tearing) = pending.tearing.take()
|
||||||
&& self.tearing.replace(tearing) != tearing
|
&& self.tearing.replace(tearing) != tearing
|
||||||
|
|
@ -1597,6 +1636,13 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts_input_at(&self, mut x: i32, mut y: i32) -> bool {
|
fn accepts_input_at(&self, mut x: i32, mut y: i32) -> bool {
|
||||||
|
// Per the wayland spec, a surface without a buffer is invisible and
|
||||||
|
// cannot receive input. Without this check, a client that null-buffers
|
||||||
|
// but keeps a wp_viewport destination set (as foot does for its
|
||||||
|
// fractional-scaling subsurfaces) would keep an invisible hit-rect.
|
||||||
|
if self.buffer.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let rect = self.buffer_abs_pos.get().at_point(0, 0);
|
let rect = self.buffer_abs_pos.get().at_point(0, 0);
|
||||||
if !rect.contains(x, y) {
|
if !rect.contains(x, y) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue