View: only send configures through transactions
This reduces the number of separate configure events sent to clients through better batching and is also more correct.
This commit is contained in:
parent
ed0aa73670
commit
83fe764fcd
@ -658,7 +658,7 @@ pub fn enterMode(self: *Self, mode: enum { move, resize }, view: *View) void {
|
||||
.offset_x = cur_box.x + cur_box.width - @floatToInt(i32, self.wlr_cursor.x),
|
||||
.offset_y = cur_box.y + cur_box.height - @floatToInt(i32, self.wlr_cursor.y),
|
||||
} };
|
||||
view.setResizing(true);
|
||||
view.pending.resizing = true;
|
||||
},
|
||||
}
|
||||
|
||||
@ -690,7 +690,7 @@ fn leaveMode(self: *Self, event: *wlr.Pointer.event.Button) void {
|
||||
_ = self.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
||||
},
|
||||
.move => {},
|
||||
.resize => |resize| resize.view.setResizing(false),
|
||||
.resize => |resize| resize.view.pending.resizing = false,
|
||||
}
|
||||
|
||||
self.mode = .passthrough;
|
||||
|
@ -420,8 +420,6 @@ pub fn applyPending(root: *Self) void {
|
||||
}
|
||||
if (output.pending.fullscreen != output.inflight.fullscreen) {
|
||||
if (output.inflight.fullscreen) |view| {
|
||||
view.setFullscreen(false);
|
||||
|
||||
view.pending.box = view.post_fullscreen_box;
|
||||
view.pending.clampToOutput();
|
||||
|
||||
@ -449,7 +447,6 @@ pub fn applyPending(root: *Self) void {
|
||||
const output = &node.data;
|
||||
if (output.pending.fullscreen != output.inflight.fullscreen) {
|
||||
if (output.pending.fullscreen) |view| {
|
||||
view.setFullscreen(true);
|
||||
view.post_fullscreen_box = view.pending.box;
|
||||
view.pending.box = .{
|
||||
.x = 0,
|
||||
|
@ -220,7 +220,6 @@ pub fn setFocusRaw(self: *Self, new_focus: FocusTarget) void {
|
||||
switch (self.focused) {
|
||||
.view => |view| {
|
||||
view.pending.focus -= 1;
|
||||
if (view.pending.focus == 0) view.setActivated(false);
|
||||
view.destroyPopups();
|
||||
},
|
||||
.layer => |layer_surface| {
|
||||
@ -234,7 +233,6 @@ pub fn setFocusRaw(self: *Self, new_focus: FocusTarget) void {
|
||||
.view => |target_view| {
|
||||
assert(server.lock_manager.state != .locked);
|
||||
assert(self.focused_output == target_view.pending.output);
|
||||
if (target_view.pending.focus == 0) target_view.setActivated(true);
|
||||
target_view.pending.focus += 1;
|
||||
target_view.pending.urgent = false;
|
||||
},
|
||||
|
@ -66,6 +66,7 @@ pub const State = struct {
|
||||
fullscreen: bool = false,
|
||||
urgent: bool = false,
|
||||
borders: bool = true,
|
||||
resizing: bool = false,
|
||||
|
||||
/// Modify the x/y of the given state by delta_x/delta_y, clamping to the
|
||||
/// bounds of the output.
|
||||
@ -353,48 +354,6 @@ pub fn destroyPopups(self: Self) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setActivated(self: Self, activated: bool) void {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.setActivated(activated),
|
||||
.xwayland_view => |xwayland_view| xwayland_view.setActivated(activated),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setFullscreen(self: *Self, fullscreen: bool) void {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.setFullscreen(fullscreen),
|
||||
.xwayland_view => |*xwayland_view| {
|
||||
// TODO(zig): remove this uneeded if statement
|
||||
// https://github.com/ziglang/zig/issues/13655
|
||||
if (build_options.xwayland) xwayland_view.setFullscreen(fullscreen);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setResizing(self: Self, resizing: bool) void {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| xdg_toplevel.setResizing(resizing),
|
||||
.xwayland_view => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates over all surfaces, subsurfaces, and popups in the tree
|
||||
pub inline fn forEachSurface(
|
||||
self: Self,
|
||||
comptime T: type,
|
||||
comptime iterator: fn (surface: *wlr.Surface, sx: c_int, sy: c_int, data: T) void,
|
||||
user_data: T,
|
||||
) void {
|
||||
switch (self.impl) {
|
||||
.xdg_toplevel => |xdg_toplevel| {
|
||||
xdg_toplevel.xdg_toplevel.base.forEachSurface(T, iterator, user_data);
|
||||
},
|
||||
.xwayland_view => |xwayland_view| {
|
||||
xwayland_view.xwayland_surface.surface.?.forEachSurface(T, iterator, user_data);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current title of the view if any.
|
||||
pub fn getTitle(self: Self) ?[*:0]const u8 {
|
||||
return switch (self.impl) {
|
||||
|
@ -89,13 +89,33 @@ pub fn needsConfigure(self: Self) bool {
|
||||
// configured by setting the current width/height to the initial width/height
|
||||
// of the view in handleMap().
|
||||
return view.inflight.box.width != view.current.box.width or
|
||||
view.inflight.box.height != view.current.box.height;
|
||||
view.inflight.box.height != view.current.box.height or
|
||||
(view.inflight.focus != 0) != (view.current.focus != 0) or
|
||||
(view.inflight.output != null and view.inflight.output.?.inflight.fullscreen == view) !=
|
||||
(view.current.output != null and view.current.output.?.current.fullscreen == view) or
|
||||
view.inflight.borders != view.current.borders or
|
||||
view.inflight.resizing != view.current.resizing;
|
||||
}
|
||||
|
||||
/// Send a configure event, applying the inflight state of the view.
|
||||
pub fn configure(self: *Self) void {
|
||||
const state = &self.view.inflight;
|
||||
|
||||
self.view.inflight_serial = self.xdg_toplevel.setSize(state.box.width, state.box.height);
|
||||
|
||||
_ = self.xdg_toplevel.setActivated(state.focus != 0);
|
||||
|
||||
const fullscreen = state.output != null and state.output.?.inflight.fullscreen == self.view;
|
||||
_ = self.xdg_toplevel.setFullscreen(fullscreen);
|
||||
|
||||
if (state.borders) {
|
||||
_ = self.xdg_toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
|
||||
} else {
|
||||
_ = self.xdg_toplevel.setTiled(.{ .top = false, .bottom = false, .left = false, .right = false });
|
||||
}
|
||||
|
||||
_ = self.xdg_toplevel.setResizing(state.resizing);
|
||||
|
||||
self.acked_inflight_serial = false;
|
||||
}
|
||||
|
||||
@ -108,18 +128,6 @@ pub fn close(self: Self) void {
|
||||
self.xdg_toplevel.sendClose();
|
||||
}
|
||||
|
||||
pub fn setActivated(self: Self, activated: bool) void {
|
||||
_ = self.xdg_toplevel.setActivated(activated);
|
||||
}
|
||||
|
||||
pub fn setFullscreen(self: Self, fullscreen: bool) void {
|
||||
_ = self.xdg_toplevel.setFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
pub fn setResizing(self: Self, resizing: bool) void {
|
||||
_ = self.xdg_toplevel.setResizing(resizing);
|
||||
}
|
||||
|
||||
/// Return the current title of the toplevel if any.
|
||||
pub fn getTitle(self: Self) ?[*:0]const u8 {
|
||||
return self.xdg_toplevel.title;
|
||||
@ -193,13 +201,7 @@ fn handleMap(listener: *wl.Listener(void)) void {
|
||||
|
||||
self.view.pending.fullscreen = self.xdg_toplevel.requested.fullscreen;
|
||||
|
||||
// If the view has an app_id or title which is not configured to use client
|
||||
// side decorations, inform it that it is tiled.
|
||||
if (server.config.csdAllowed(view)) {
|
||||
view.pending.borders = false;
|
||||
} else {
|
||||
_ = self.xdg_toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
|
||||
}
|
||||
view.pending.borders = !server.config.csdAllowed(view);
|
||||
|
||||
view.map() catch {
|
||||
log.err("out of memory", .{});
|
||||
|
@ -84,11 +84,14 @@ pub fn needsConfigure(self: Self) bool {
|
||||
var output_box: wlr.Box = undefined;
|
||||
server.root.output_layout.getBox(output.wlr_output, &output_box);
|
||||
|
||||
const state = &self.view.inflight;
|
||||
return self.xwayland_surface.x != state.box.x + output_box.x or
|
||||
self.xwayland_surface.y != state.box.y + output_box.y or
|
||||
self.xwayland_surface.width != state.box.width or
|
||||
self.xwayland_surface.height != state.box.height;
|
||||
const view = self.view;
|
||||
return self.xwayland_surface.x != view.inflight.box.x + output_box.x or
|
||||
self.xwayland_surface.y != view.inflight.box.y + output_box.y or
|
||||
self.xwayland_surface.width != view.inflight.box.width or
|
||||
self.xwayland_surface.height != view.inflight.box.height or
|
||||
(view.inflight.focus != 0) != (view.current.focus != 0) or
|
||||
(view.inflight.output != null and view.inflight.output.?.inflight.fullscreen == view) !=
|
||||
(view.current.output != null and view.current.output.?.current.fullscreen == view);
|
||||
}
|
||||
|
||||
pub fn configure(self: Self) void {
|
||||
@ -103,6 +106,11 @@ pub fn configure(self: Self) void {
|
||||
@intCast(u16, state.box.width),
|
||||
@intCast(u16, state.box.height),
|
||||
);
|
||||
|
||||
self.setActivated(state.focus != 0);
|
||||
|
||||
const fullscreen = state.output != null and state.output.?.inflight.fullscreen == self.view;
|
||||
self.xwayland_surface.setFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
pub fn rootSurface(self: Self) *wlr.Surface {
|
||||
@ -115,7 +123,7 @@ pub fn close(self: Self) void {
|
||||
self.xwayland_surface.close();
|
||||
}
|
||||
|
||||
pub fn setActivated(self: Self, activated: bool) void {
|
||||
fn setActivated(self: Self, activated: bool) void {
|
||||
// See comment on handleRequestMinimize() for details
|
||||
if (activated and self.xwayland_surface.minimized) {
|
||||
self.xwayland_surface.setMinimized(false);
|
||||
@ -124,10 +132,6 @@ pub fn setActivated(self: Self, activated: bool) void {
|
||||
self.xwayland_surface.restack(null, .above);
|
||||
}
|
||||
|
||||
pub fn setFullscreen(self: *Self, fullscreen: bool) void {
|
||||
self.xwayland_surface.setFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
/// Get the current title of the xwayland surface if any.
|
||||
pub fn getTitle(self: Self) ?[*:0]const u8 {
|
||||
return self.xwayland_surface.title;
|
||||
|
@ -122,17 +122,14 @@ fn csdFilterUpdateViews(kind: FilterKind, pattern: []const u8, operation: enum {
|
||||
|
||||
const view = @intToPtr(*View, xdg_toplevel_decoration.surface.data);
|
||||
if (viewMatchesPattern(kind, pattern, view)) {
|
||||
const toplevel = view.impl.xdg_toplevel.xdg_toplevel;
|
||||
switch (operation) {
|
||||
.add => {
|
||||
_ = xdg_toplevel_decoration.setMode(.client_side);
|
||||
view.pending.borders = false;
|
||||
_ = toplevel.setTiled(.{ .top = false, .bottom = false, .left = false, .right = false });
|
||||
},
|
||||
.remove => {
|
||||
_ = xdg_toplevel_decoration.setMode(.server_side);
|
||||
view.pending.borders = true;
|
||||
_ = toplevel.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user