Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
river: implement river_window_v1.close
river/Window.zig | 10 +++++++---
rivercompat/Seat.zig | 8 ++++++--
rivercompat/Window.zig | 12 ++++++++++++
rivercompat/WindowManager.zig | 3 +++
4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/river/Window.zig b/river/Window.zig
index 35ddbbe..989f526 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -99,7 +99,7 @@ pub const WmState = struct {
},
maximized: bool = false,
fullscreen: bool = false, // XXX output
- closing: bool = false,
+ close: bool = false,
};
/// The window management protocol object for this window
@@ -394,7 +394,7 @@ fn handleRequest(
// XXX send protocol error
window_v1.destroy();
},
- .close => uncommitted.closing = true,
+ .close => uncommitted.close = true,
.get_node => |args| {
if (window.node.object != null) {
// XXX send protocol error
@@ -453,7 +453,7 @@ pub fn commitWmState(window: *Window) void {
.capabilities = window.uncommitted.capabilities,
.maximized = window.uncommitted.maximized,
.fullscreen = window.uncommitted.fullscreen,
- .closing = window.uncommitted.closing,
+ .close = window.uncommitted.close,
};
window.uncommitted.proposed = null;
}
@@ -617,6 +617,10 @@ pub fn configure(window: *Window) bool {
assert(!window.destroying);
+ if (window.committed.close) {
+ window.close();
+ }
+
const activated = blk: {
var it = server.wm.sent.seats.iterator(.forward);
while (it.next()) |seat| {
diff --git a/rivercompat/Seat.zig b/rivercompat/Seat.zig
index 7b04b7e..bd90e29 100644
--- a/rivercompat/Seat.zig
+++ b/rivercompat/Seat.zig
@@ -35,13 +35,17 @@ const gpa = std.heap.c_allocator;
wm: *WindowManager,
seat_v1: *river.SeatV1,
focused: ?*Window = null,
+link: wl.list.Link,
pub fn create(wm: *WindowManager, seat_v1: *river.SeatV1) void {
const seat = gpa.create(Seat) catch @panic("OOM");
seat.* = .{
.wm = wm,
.seat_v1 = seat_v1,
+ .link = undefined,
};
+ wm.seats.append(seat);
+
seat_v1.setListener(*Seat, handleEvent, seat);
XkbBinding.create(seat, xkb.Keysym.n, .{ .mod4 = true });
@@ -67,8 +71,8 @@ pub fn focusNext(seat: *Seat) void {
if (seat.wm.windows.length() >= 2) {
seat.focus(seat.wm.windows.last().?);
}
- } else if (seat.wm.windows.first()) |top| {
- seat.focus(top);
+ } else {
+ seat.focus(seat.wm.windows.first());
}
}
diff --git a/rivercompat/Window.zig b/rivercompat/Window.zig
index 17b51d6..a5659e3 100644
--- a/rivercompat/Window.zig
+++ b/rivercompat/Window.zig
@@ -49,6 +49,18 @@ fn handleEvent(window_v1: *river.WindowV1, event: river.WindowV1.Event, window:
switch (event) {
.closed => {
window_v1.destroy();
+
+ window.link.remove();
+ {
+ var it = window.wm.seats.iterator(.forward);
+ while (it.next()) |seat| {
+ if (seat.focused == window) {
+ seat.focused = null;
+ seat.focusNext();
+ }
+ }
+ }
+
gpa.destroy(window);
},
.dimensions => {},
diff --git a/rivercompat/WindowManager.zig b/rivercompat/WindowManager.zig
index b0a42c5..056d039 100644
--- a/rivercompat/WindowManager.zig
+++ b/rivercompat/WindowManager.zig
@@ -28,13 +28,16 @@ const Window = @import("Window.zig");
wm_v1: *river.WindowManagerV1,
windows: wl.list.Head(Window, .link),
+seats: wl.list.Head(Seat, .link),
pub fn init(wm: *WindowManager, wm_v1: *river.WindowManagerV1) void {
wm.* = .{
.wm_v1 = wm_v1,
.windows = undefined,
+ .seats = undefined,
};
wm.windows.init();
+ wm.seats.init();
wm_v1.setListener(*WindowManager, handleEvent, wm);
}