Skip to content

Commit df74a32

Browse files
committed
mapped: Allow to query in-flight configure for resize throttling
1 parent 6c7ec54 commit df74a32

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/shell/element/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,14 @@ impl CosmicMapped {
489489
}
490490
}
491491

492+
pub fn latest_size_committed(&self) -> bool {
493+
match &self.element {
494+
CosmicMappedInternal::Stack(s) => s.surfaces().any(|s| s.latest_size_committed()),
495+
CosmicMappedInternal::Window(w) => w.surface().latest_size_committed(),
496+
_ => unreachable!(),
497+
}
498+
}
499+
492500
pub fn configure(&self) -> Option<Serial> {
493501
match &self.element {
494502
CosmicMappedInternal::Stack(s) => {

src/shell/element/surface.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use smithay::{
4545
},
4646
xwayland::{xwm::X11Relatable, X11Surface},
4747
};
48+
use tracing::trace;
4849

4950
use crate::{
5051
state::{State, SurfaceDmabufFeedback},
@@ -499,6 +500,60 @@ impl CosmicSurface {
499500
}
500501
}
501502

503+
pub fn serial_past(&self, serial: &Serial) -> bool {
504+
match self.0.underlying_surface() {
505+
WindowSurface::Wayland(toplevel) => with_states(toplevel.wl_surface(), |states| {
506+
let attrs = states
507+
.data_map
508+
.get::<XdgToplevelSurfaceData>()
509+
.unwrap()
510+
.lock()
511+
.unwrap();
512+
attrs
513+
.current_serial
514+
.as_ref()
515+
.map(|s| s >= serial)
516+
.unwrap_or(false)
517+
}),
518+
WindowSurface::X11(_surface) => true,
519+
}
520+
}
521+
522+
pub fn latest_size_committed(&self) -> bool {
523+
match self.0.underlying_surface() {
524+
WindowSurface::Wayland(toplevel) => {
525+
with_states(toplevel.wl_surface(), |states| {
526+
let attributes = states
527+
.data_map
528+
.get::<XdgToplevelSurfaceData>()
529+
.unwrap()
530+
.lock()
531+
.unwrap();
532+
533+
let current_server = attributes.current_server_state();
534+
if attributes.current.size == current_server.size {
535+
// The window had committed for our previous size change, so we can
536+
// change the size again.
537+
trace!(
538+
"current size matches server size: {:?}",
539+
attributes.current.size
540+
);
541+
true
542+
} else {
543+
// The window had not committed for our previous size change yet.
544+
// This throttling is done because some clients do not batch size requests,
545+
// leading to bad behavior with very fast input devices (i.e. a 1000 Hz
546+
// mouse). This throttling also helps interactive resize transactions
547+
// preserve visual consistency.
548+
trace!("throttling resize");
549+
false
550+
}
551+
})
552+
}
553+
WindowSurface::X11(_) => true,
554+
}
555+
}
556+
502557
pub fn force_configure(&self) -> Option<Serial> {
503558
match self.0.underlying_surface() {
504559
WindowSurface::Wayland(toplevel) => Some(toplevel.send_configure()),

0 commit comments

Comments
 (0)