transactions: handle preemption properly
when a transaction interrupts an ongoing transaction, we must be careful to handle the configures properly. This commit adds a new member to view so that we can store the dimensions sent with the last configure in order to determine if the preempting transaction should override the ongoing configure or not. Additionally, some views do not ack a configure if they already have the requested dimensions. This can happen if a pending configure setting alternative dimensions is overridden, so in this case we do not wait for an ack before committing the transaction.
This commit is contained in:
@ -55,8 +55,13 @@ focused: bool,
|
||||
|
||||
/// The current output-relative coordinates and dimensions of the view
|
||||
current_box: Box,
|
||||
|
||||
/// The dimensions sent with the most recent configure
|
||||
pending_box: ?Box,
|
||||
|
||||
/// The dimensions to be used for the next configure
|
||||
next_box: ?Box,
|
||||
|
||||
/// The dimensions the view would have taken if we didn't force it to tile
|
||||
natural_width: u32,
|
||||
natural_height: u32,
|
||||
@ -111,23 +116,40 @@ pub fn deinit(self: Self) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn needsConfigure(self: Self) bool {
|
||||
if (self.pending_box) |pending_box| {
|
||||
return pending_box.width != self.current_box.width or
|
||||
pending_box.height != self.current_box.height;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
/// Returns true if a configure needs to be sent to ensure the next_box is
|
||||
/// applied correctly.
|
||||
pub fn configureAction(self: Self) enum { override, new_configure, old_configure, noop } {
|
||||
// If we have a pending box, check if the next box is different from the
|
||||
// pending box. If we do not have a pending box, check if the next box is
|
||||
// different from the current box.
|
||||
if (self.pending_box) |pending_box|
|
||||
if (self.next_box) |next_box| {
|
||||
if (next_box.width != pending_box.width or next_box.height != pending_box.height) {
|
||||
return .override;
|
||||
} else {
|
||||
return .old_configure;
|
||||
}
|
||||
};
|
||||
|
||||
if (self.next_box) |next_box|
|
||||
if (next_box.width != self.current_box.width or next_box.height != self.current_box.height)
|
||||
return .new_configure;
|
||||
|
||||
return .noop;
|
||||
}
|
||||
|
||||
pub fn configure(self: Self) void {
|
||||
if (self.pending_box) |pending_box| {
|
||||
/// Tell the client to assume the size of next_box. Set pending_box to
|
||||
/// next_box and next_box to null.
|
||||
pub fn configure(self: *Self) void {
|
||||
if (self.next_box) |next_box| {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.configure(pending_box),
|
||||
.xwayland_view => |xwayland_view| xwayland_view.configure(pending_box),
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.configure(next_box),
|
||||
.xwayland_view => |xwayland_view| xwayland_view.configure(next_box),
|
||||
}
|
||||
self.pending_box = next_box;
|
||||
self.next_box = null;
|
||||
} else {
|
||||
Log.Error.log("Configure called on a View with no pending box", .{});
|
||||
Log.Error.log("configure called on View with null next_box", .{});
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user