View: improve transaction timeout handling
This fixes a possible assertion failure in Cursor.updateState() when trying to start move/resize of a xdg toplevel with the timed_out or timed_out_acked configure_state. This also generally improves the UX of transaction timeouts as all state except for the size change is now applied immediately.
This commit is contained in:
parent
46dbbe9799
commit
b0dc5f7294
@ -285,26 +285,28 @@ pub fn commitTransaction(view: *Self) void {
|
||||
|
||||
view.foreign_toplevel_handle.update();
|
||||
|
||||
// Tag and output changes must be applied immediately even if the configure sequence times out.
|
||||
// This allows Root.commitTransaction() to rely on the fact that all tag and output changes
|
||||
// are applied directly by this function.
|
||||
view.current.tags = view.inflight.tags;
|
||||
view.current.output = view.inflight.output;
|
||||
|
||||
view.dropSavedSurfaceTree();
|
||||
|
||||
switch (view.impl) {
|
||||
.xdg_toplevel => |*xdg_toplevel| {
|
||||
switch (xdg_toplevel.configure_state) {
|
||||
.inflight => |serial| {
|
||||
xdg_toplevel.configure_state = .{ .timed_out = serial };
|
||||
},
|
||||
.acked => {
|
||||
xdg_toplevel.configure_state = .timed_out_acked;
|
||||
.inflight, .acked => {
|
||||
switch (xdg_toplevel.configure_state) {
|
||||
.inflight => |serial| xdg_toplevel.configure_state = .{ .timed_out = serial },
|
||||
.acked => xdg_toplevel.configure_state = .timed_out_acked,
|
||||
else => unreachable,
|
||||
}
|
||||
// The width and height cannot be updated until the client has
|
||||
// committed a new buffer in response to the configure.
|
||||
const old_width = view.current.box.width;
|
||||
const old_height = view.current.box.height;
|
||||
view.current = view.inflight;
|
||||
view.current.box.width = old_width;
|
||||
view.current.box.height = old_height;
|
||||
},
|
||||
.idle, .committed => {
|
||||
xdg_toplevel.configure_state = .idle;
|
||||
view.updateCurrent();
|
||||
view.current = view.inflight;
|
||||
},
|
||||
.timed_out, .timed_out_acked => unreachable,
|
||||
}
|
||||
@ -322,15 +324,15 @@ pub fn commitTransaction(view: *Self) void {
|
||||
view.pending.box.width = xwayland_view.xwayland_surface.width;
|
||||
view.pending.box.height = xwayland_view.xwayland_surface.height;
|
||||
|
||||
view.updateCurrent();
|
||||
view.current = view.inflight;
|
||||
},
|
||||
.none => {},
|
||||
}
|
||||
|
||||
view.updateSceneState();
|
||||
}
|
||||
|
||||
pub fn updateCurrent(view: *Self) void {
|
||||
view.current = view.inflight;
|
||||
|
||||
pub fn updateSceneState(view: *Self) void {
|
||||
const box = &view.current.box;
|
||||
view.tree.node.setPosition(box.x, box.y);
|
||||
view.popup_tree.node.setPosition(box.x, box.y);
|
||||
|
@ -369,7 +369,8 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||
view.inflight.box.height = self.geometry.height;
|
||||
view.pending.box.width = self.geometry.width;
|
||||
view.pending.box.height = self.geometry.height;
|
||||
view.updateCurrent();
|
||||
view.current = view.inflight;
|
||||
view.updateSceneState();
|
||||
}
|
||||
},
|
||||
// If the client has not yet acked our configure, we need to send a
|
||||
@ -377,7 +378,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||
// buffers won't be rendered since we are still rendering our
|
||||
// stashed buffer from when the transaction started.
|
||||
.inflight => view.sendFrameDone(),
|
||||
inline .acked, .timed_out_acked => |_, tag| {
|
||||
.acked, .timed_out_acked => {
|
||||
if (view.inflight.resizing) {
|
||||
view.resizeUpdatePosition(self.geometry.width, self.geometry.height);
|
||||
}
|
||||
@ -387,14 +388,15 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||
view.pending.box.width = self.geometry.width;
|
||||
view.pending.box.height = self.geometry.height;
|
||||
|
||||
switch (tag) {
|
||||
switch (self.configure_state) {
|
||||
.acked => {
|
||||
self.configure_state = .committed;
|
||||
server.root.notifyConfigured();
|
||||
},
|
||||
.timed_out_acked => {
|
||||
self.configure_state = .idle;
|
||||
view.updateCurrent();
|
||||
view.current = view.inflight;
|
||||
view.updateSceneState();
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user