Cursor: use inflight_mode as needed in updateState()

This fixes possible assertion failures when quickly cancelling and
starting a new move/resize. The following steps, take from the bug
report, can currently reproduce the race:

1. Start with a window in tiled mode.
2. Begin resizing the window with your cursor.
3. Send the window back to tiled mode (with a keybind) and quickly begin
resizing it again with your cursor.
This commit is contained in:
Isaac Freund 2023-11-03 17:06:05 +01:00
parent ddc7997d2f
commit 59c9842c8f
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11

View File

@ -996,6 +996,23 @@ pub fn updateState(self: *Self) void {
},
// TODO: Leave down mode if the target surface is no longer visible.
.down => assert(!self.hidden),
.move, .resize => {
// Moving and resizing of views is handled through the transaction system. Therefore,
// we must inspect the inflight_mode instead if a move or a resize is in progress.
//
// The cases when a move/resize is being started or ended and e.g. mode is resize
// while inflight_mode is passthrough or mode is passthrough while inflight_mode
// is resize shouldn't need any special handling.
//
// In the first case, a move/resize has been started along with a transaction but the
// transaction hasn't been committed yet so there is nothing to do.
//
// In the second case, a move/resize has been terminated by the user but the
// transaction carrying out the final size/position change is still inflight.
// Therefore, the user already expects the cursor to be free from the view and
// we should not warp it back to the fixed offset of the move/resize.
switch (self.inflight_mode) {
.passthrough, .down => {},
inline .move, .resize => |data, mode| {
assert(!self.hidden);
@ -1028,6 +1045,8 @@ pub fn updateState(self: *Self) void {
self.wlr_cursor.warpClosest(null, new_x, new_y);
},
}
},
}
}
/// Pass an event on to the surface under the cursor, if any.