From fa5a1e5da046014477c09502d83c73ca18876e6e Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 20 Feb 2024 23:01:46 +0100 Subject: [PATCH] XdgToplevel: handle timed out state in configure() If a new transaction is started that calls configure() on an xdg toplevel with a timed_out/timed_out_acked configure_state we currently leave the configure_state untouched if no new configure is needed. This can cause an assertion failure in View.commitTransaction() if the xdg toplevel still hasn't acked/committed by the time the new transaction completes. To fix this, update the configure_state as necessary. --- river/XdgToplevel.zig | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index dbb3340..653b01c 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -118,6 +118,11 @@ pub fn configure(self: *Self) bool { .inflight, .acked, .committed => unreachable, } + defer switch (self.configure_state) { + .idle, .inflight, .acked => {}, + .timed_out, .timed_out_acked, .committed => unreachable, + }; + const inflight = &self.view.inflight; const current = &self.view.current; @@ -135,7 +140,20 @@ pub fn configure(self: *Self) bool { inflight.ssd == current.ssd and inflight.resizing == current.resizing) { - return false; + // If no new configure is required, continue to track a timed out configure + // from the previous transaction if any. + switch (self.configure_state) { + .idle => return false, + .timed_out => |serial| { + self.configure_state = .{ .inflight = serial }; + return true; + }, + .timed_out_acked => { + self.configure_state = .acked; + return true; + }, + .inflight, .acked, .committed => unreachable, + } } _ = self.xdg_toplevel.setActivated(inflight.focus != 0); @@ -160,8 +178,11 @@ pub fn configure(self: *Self) bool { const configure_serial = self.xdg_toplevel.setSize(inflight.box.width, inflight.box.height); // Only track configures with the transaction system if they affect the dimensions of the view. + // If the configure state is not idle this means we are currently tracking a timed out + // configure from a previous transaction and should instead track the newly sent configure. if (inflight.box.width == current.box.width and - inflight.box.height == current.box.height) + inflight.box.height == current.box.height and + self.configure_state == .idle) { return false; }