srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/wayland/src')
-rw-r--r--crates/wayland/src/udev/render.rs26
-rw-r--r--crates/wayland/src/winit/render.rs7
2 files changed, 30 insertions, 3 deletions
diff --git a/crates/wayland/src/udev/render.rs b/crates/wayland/src/udev/render.rs
index c2899ae..a2cf367 100644
--- a/crates/wayland/src/udev/render.rs
+++ b/crates/wayland/src/udev/render.rs
@@ -315,10 +315,17 @@ impl CompState {
let Some(dwindow) = self.id_to_window.get(&id) else { continue };
let Some(surface) = crate::elements::window_wl_surface(dwindow) else { continue };
let geom = self.window_anims.get(&id).map(crate::state::WindowAnim::current_rect).unwrap_or(w.geometry);
+ // Content is positioned from `frame`, not `geom`, for
+ // the same reason as the Pixman loop's own content
+ // push below: `geom` is the live drag target and
+ // moves a frame ahead of the client, so content drawn
+ // from it slides out from under the decoration drawn
+ // around it.
+ let frame = crate::state::CompState::effective_frame_of(&self.wm, &self.id_to_window, &self.pending_size_configure, id, geom);
let band = if w.decorated { srdwm_core::TITLEBAR_HEIGHT as i32 } else { 0 };
let raw_offset = dwindow.geometry().loc;
let content_offset = Point::<i32, Logical>::from((raw_offset.x.max(0), raw_offset.y.max(0)));
- let pos = (geom.x - origin.x - content_offset.x, geom.y + band - origin.y - content_offset.y);
+ let pos = (frame.x - origin.x - content_offset.x, frame.y + band - origin.y - content_offset.y);
elements.extend(crate::elements::surface_content_elements(&mut gpu.renderer, &surface, pos, w.opacity));
// Border strips (top/bottom) and the titlebar bitmap,
// reusing the exact same cached `MemoryRenderBuffer`s
@@ -1005,7 +1012,22 @@ impl CompState {
// exactly on this same real content top-left --
// the margin has already been compensated for
// once, inside the buffer itself.
- let content_pos = (geom.x - origin.x, geom.y + band - origin.y);
+ // `frame`, not `geom`: `geom` is the live drag
+ // target, which moves with the pointer on the
+ // very frame the pointer moves, while every
+ // decoration around it is drawn from `frame` --
+ // the committed size anchored to the edge the
+ // drag is not holding. Drawing content from one
+ // and its frame from the other is what made a
+ // titlebar look detached from its own window
+ // while resizing, and made dragging a left edge
+ // look like it moved the right one: the stale
+ // buffer slid left with the pointer, carrying
+ // its old width, while the border stayed put.
+ // Outside a resize the two are identical --
+ // `committed_frame` only ever corrects the far
+ // edge - so this changes nothing else.
+ let content_pos = (frame.x - origin.x, frame.y + band - origin.y);
// Only for the *fallback* path below
// (`surface_content_elements`, pushed when
// masking is off or fails): that renders the
diff --git a/crates/wayland/src/winit/render.rs b/crates/wayland/src/winit/render.rs
index d49351f..02ee322 100644
--- a/crates/wayland/src/winit/render.rs
+++ b/crates/wayland/src/winit/render.rs
@@ -489,7 +489,12 @@ impl WaylandPlatform {
// shift content away from the border instead of into it.
let raw_offset = dwindow.geometry().loc;
let content_offset = smithay::utils::Point::<i32, smithay::utils::Logical>::from((raw_offset.x.max(0), raw_offset.y.max(0)));
- let pos = (geom.x - content_offset.x, geom.y + band - content_offset.y);
+ // `frame`, not `geom` - see the matching comment in
+ // `udev/render.rs`'s own content push: content and the
+ // decoration around it have to come from the same rect,
+ // or they visibly disagree for as long as a resize drag
+ // is ahead of the client.
+ let pos = (frame.x - content_offset.x, frame.y + band - content_offset.y);
let rounded = rounded_corners_enabled.then_some(self.state.rounded_corners_program.as_ref()).flatten().and_then(|program| {
let corners = if w.decorated { crate::rounded_corners::RoundedCorners::BOTTOM_ONLY } else { crate::rounded_corners::RoundedCorners::ALL };
crate::rounded_corners::rounded_content_element(renderer, program, &surface, pos, w.opacity, w.corner_radius as f32, corners)