xdg-shell: set resizing state during interactive resize

This commit is contained in:
Isaac Freund 2021-07-14 15:32:24 +02:00
parent 7b18b4944e
commit d413db9227
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
3 changed files with 36 additions and 13 deletions

View file

@ -19,6 +19,7 @@ const Self = @This();
const build_options = @import("build_options"); const build_options = @import("build_options");
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert;
const math = std.math; const math = std.math;
const wlr = @import("wlroots"); const wlr = @import("wlroots");
const wayland = @import("wayland"); const wayland = @import("wayland");
@ -524,7 +525,7 @@ fn surfaceAtFilter(view: *View, filter_tags: u32) bool {
/// Enter move or resize mode /// Enter move or resize mode
pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void { pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void {
log.debug("enter {s} mode", .{@tagName(mode)}); log.debug("enter {s} cursor mode", .{@tagName(mode)});
self.seat.focus(view); self.seat.focus(view);
@ -535,18 +536,19 @@ pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void {
server.root.startTransaction(); server.root.startTransaction();
}, },
.move, .resize => { .move, .resize => {
const cur_box = &view.current.box; switch (mode) {
self.mode = switch (mode) {
.passthrough, .down => unreachable, .passthrough, .down => unreachable,
.move => .{ .move = view }, .move => self.mode = .{ .move = view },
.resize => .{ .resize => {
.resize = .{ const cur_box = &view.current.box;
self.mode = .{ .resize = .{
.view = view, .view = view,
.offset_x = cur_box.x + @intCast(i32, cur_box.width) - @floatToInt(i32, self.wlr_cursor.x), .offset_x = cur_box.x + @intCast(i32, cur_box.width) - @floatToInt(i32, self.wlr_cursor.x),
.offset_y = cur_box.y + @intCast(i32, cur_box.height) - @floatToInt(i32, self.wlr_cursor.y), .offset_y = cur_box.y + @intCast(i32, cur_box.height) - @floatToInt(i32, self.wlr_cursor.y),
} };
view.setResizing(true);
}, },
}, }
};
// Automatically float all views being moved by the pointer, if // Automatically float all views being moved by the pointer, if
// their dimensions are set by a layout client. If however the views // their dimensions are set by a layout client. If however the views
@ -556,6 +558,10 @@ pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void {
view.pending.float = true; view.pending.float = true;
view.float_box = view.current.box; view.float_box = view.current.box;
view.applyPending(); view.applyPending();
} else {
// The View.applyPending() call in the other branch starts
// the transaction needed after the seat.focus() call above.
server.root.startTransaction();
} }
// Clear cursor focus, so that the surface does not receive events // Clear cursor focus, so that the surface does not receive events
@ -571,13 +577,17 @@ pub fn enterMode(self: *Self, mode: std.meta.Tag((Mode)), view: *View) void {
/// Return from down/move/resize to passthrough /// Return from down/move/resize to passthrough
fn leaveMode(self: *Self, event: *wlr.Pointer.event.Button) void { fn leaveMode(self: *Self, event: *wlr.Pointer.event.Button) void {
std.debug.assert(self.mode != .passthrough);
log.debug("leave {s} mode", .{@tagName(self.mode)}); log.debug("leave {s} mode", .{@tagName(self.mode)});
switch (self.mode) {
.passthrough => unreachable,
.down => {
// If we were in down mode, we need pass along the release event // If we were in down mode, we need pass along the release event
if (self.mode == .down)
_ = self.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state); _ = self.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
},
.move => {},
.resize => |resize| resize.view.setResizing(false),
}
self.mode = .passthrough; self.mode = .passthrough;
self.passthrough(event.time_msec); self.passthrough(event.time_msec);
@ -666,6 +676,8 @@ fn processMotion(self: *Self, device: *wlr.InputDevice, time: u32, delta_x: f64,
/// Pass an event on to the surface under the cursor, if any. /// Pass an event on to the surface under the cursor, if any.
fn passthrough(self: *Self, time: u32) void { fn passthrough(self: *Self, time: u32) void {
assert(self.mode == .passthrough);
var sx: f64 = undefined; var sx: f64 = undefined;
var sy: f64 = undefined; var sy: f64 = undefined;
if (self.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y, &sx, &sy)) |surface| { if (self.surfaceAt(self.wlr_cursor.x, self.wlr_cursor.y, &sx, &sy)) |surface| {

View file

@ -338,6 +338,13 @@ pub fn setFullscreen(self: Self, fullscreen: bool) void {
} }
} }
pub fn setResizing(self: Self, resizing: bool) void {
switch (self.impl) {
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.setResizing(resizing),
.xwayland_view => unreachable,
}
}
pub inline fn forEachPopupSurface( pub inline fn forEachPopupSurface(
self: Self, self: Self,
comptime T: type, comptime T: type,

View file

@ -120,6 +120,10 @@ pub fn setFullscreen(self: Self, fullscreen: bool) void {
_ = self.xdg_surface.role_data.toplevel.setFullscreen(fullscreen); _ = self.xdg_surface.role_data.toplevel.setFullscreen(fullscreen);
} }
pub fn setResizing(self: Self, resizing: bool) void {
_ = self.xdg_surface.role_data.toplevel.setResizing(resizing);
}
pub inline fn forEachPopupSurface( pub inline fn forEachPopupSurface(
self: Self, self: Self,
comptime T: type, comptime T: type,