aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2023-03-14 12:30:53 +0100
committerIsaac Freund <mail@isaacfreund.com>2023-03-14 12:30:53 +0100
commit9db41115a8a2f5a8973d52a440562a9cd81ffcba (patch)
tree8843baf9fdb635cc79e87fdf3849d5ed9d61df55
parent90f240355e1f8316167674219cec2326c9934b37 (diff)
downloadriver-9db41115a8a2f5a8973d52a440562a9cd81ffcba.tar.gz
river-9db41115a8a2f5a8973d52a440562a9cd81ffcba.tar.xz
XdgToplevel: ensure view dimensions match geometry
Some clients (e.g. mpv) do not respond to configures by committing buffers of the exact size requested. Instead they may commit a buffer of a smaller size in order to maintain an aspect ratio or not commit a buffer at all.
-rw-r--r--river/View.zig18
-rw-r--r--river/XdgToplevel.zig14
2 files changed, 26 insertions, 6 deletions
diff --git a/river/View.zig b/river/View.zig
index 24934dd..9eec85e 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -247,13 +247,25 @@ pub fn destroy(view: *Self) void {
pub fn updateCurrent(view: *Self) void {
const config = &server.config;
+ if (view.impl == .xdg_toplevel) {
+ switch (view.impl.xdg_toplevel.configure_state) {
+ // If the configure timed out, don't update current to dimensions
+ // that have not been committed by the client.
+ .inflight, .acked => {
+ view.inflight.box.width = view.current.box.width;
+ view.inflight.box.height = view.current.box.height;
+ view.pending.box.width = view.current.box.width;
+ view.pending.box.height = view.current.box.height;
+ },
+ .idle, .committed => {},
+ }
+ view.impl.xdg_toplevel.configure_state = .idle;
+ }
+
view.foreign_toplevel_handle.update();
view.current = view.inflight;
view.dropSavedSurfaceTree();
- if (view.impl == .xdg_toplevel) {
- view.impl.xdg_toplevel.configure_state = .idle;
- }
const color = blk: {
if (view.current.urgent) break :blk &config.border_color_urgent;
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index 188be4b..734e116 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -50,6 +50,8 @@ configure_state: union(enum) {
inflight: u32,
/// A configure was acked but the surface has not yet been committed.
acked,
+ /// A configure was acked and the surface was committed.
+ committed,
} = .idle,
// Listeners that are always active over the view's lifetime
@@ -288,7 +290,7 @@ fn handleAckConfigure(
.inflight => |serial| if (acked_configure.serial == serial) {
self.configure_state = .acked;
},
- .acked, .idle => {},
+ .acked, .idle, .committed => {},
}
}
@@ -310,7 +312,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
self.xdg_toplevel.base.getGeometry(&self.geometry);
switch (self.configure_state) {
- .idle => {
+ .idle, .committed => {
const size_changed = self.geometry.width != old_geometry.width or
self.geometry.height != old_geometry.height;
const no_layout = view.current.output != null and view.current.output.?.layout == null;
@@ -334,7 +336,13 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
// stashed buffer from when the transaction started.
.inflight => view.sendFrameDone(),
.acked => {
- self.configure_state = .idle;
+ self.configure_state = .committed;
+
+ view.inflight.box.width = self.geometry.width;
+ view.inflight.box.height = self.geometry.height;
+ view.pending.box.width = self.geometry.width;
+ view.pending.box.height = self.geometry.height;
+
server.root.notifyConfigured();
},
}