From 61d01bb79c6882c950f45a1176ba1f30fbbd4824 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Sat, 9 Aug 2025 00:57:00 +0200 Subject: Fix interactive-resize border/shadow lag without the OOB risk that sank the first attempt effective_frame_of now returns the live drag target while a window is being interactively resized (same change as the reverted first attempt), but two things make it safe this time instead of reintroducing the out-of-bounds texture sample that reversion was for: - Every src crop rect built from a window's frame width in udev/render.rs and winit/render.rs (titlebar, top border strip, bottom border strip) is now clamped against DecorationSignature's own recorded width/ border_width - the bitmap's actual last-built size - before reaching MemoryRenderBufferRenderElement::from_buffer, which does not itself validate src against the real texture size. This is a structural floor independent of timing, not a repeat of the previous unsafe approach. - handle_pointer_position now calls redraw_decoration_buffer once per resize motion event (throttled to 60Hz via a new CompState::resize_redraw_at), closing the lag at its source instead of only catching up on the next real client commit. This also fixes the shadow bitmap's identical commit-vs-live-position gap for free, since redraw_decoration_buffer rebuilds all three bitmaps together. Updates the TODO.md entry for this bug with the full before/after. --- crates/wayland/src/input/pointer.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'crates/wayland/src/input/pointer.rs') diff --git a/crates/wayland/src/input/pointer.rs b/crates/wayland/src/input/pointer.rs index 7b3bbce..d4c5678 100644 --- a/crates/wayland/src/input/pointer.rs +++ b/crates/wayland/src/input/pointer.rs @@ -16,6 +16,13 @@ use super::keyboard::core_modifiers_from_xkb; use super::layers::{background_layer_surface_under, layer_surface_under}; use super::{notify_idle_activity, DRAG_MODIFIER}; +/// Minimum gap between `redraw_decoration_buffer` calls fired from an +/// active resize drag's own pointer-motion events - see `CompState:: +/// resize_redraw_at`'s doc comment. 60Hz: fast enough that the border +/// visibly tracks the drag, far below the per-motion-event rate a real +/// mouse or touchpad can produce. +pub(crate) const RESIZE_REDRAW_INTERVAL: std::time::Duration = std::time::Duration::from_millis(1000 / 60); + /// `WindowManager::hit_test`, but substituting each window's currently /// *animated* rect (if it has one active in `state.window_anims`) for its /// final `geometry` - see `hit_test_with`'s own doc comment in @@ -300,6 +307,11 @@ pub(crate) fn handle_pointer_position(state: &mut CompState, pos: Point= RESIZE_REDRAW_INTERVAL); + if due { + state.redraw_decoration_buffer(id); + state.resize_redraw_at = Some(now); + } + } else { + state.resize_redraw_at = None; + } } /// Sets the pointer to a resize-direction shape while hovering (or -- cgit v1.2.3