diff options
| -rw-r--r-- | river/Server.zig | 40 | ||||
| -rw-r--r-- | river/View.zig | 24 | ||||
| -rw-r--r-- | river/XdgToplevel.zig | 14 | ||||
| -rw-r--r-- | river/XwaylandUnmanaged.zig | 15 | ||||
| -rw-r--r-- | river/XwaylandView.zig | 22 |
5 files changed, 63 insertions, 52 deletions
diff --git a/river/Server.zig b/river/Server.zig index e730b5e..8609554 100644 --- a/river/Server.zig +++ b/river/Server.zig @@ -33,9 +33,9 @@ const LayoutManager = @import("LayoutManager.zig"); const Output = @import("Output.zig"); const Root = @import("Root.zig"); const StatusManager = @import("StatusManager.zig"); -const View = @import("View.zig"); -const ViewStack = @import("view_stack.zig").ViewStack; +const XdgToplevel = @import("XdgToplevel.zig"); const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig"); +const XwaylandView = @import("XwaylandView.zig"); const IdleInhibitorManager = @import("IdleInhibitorManager.zig"); const log = std.log.scoped(.server); @@ -187,13 +187,12 @@ fn handleNewXdgSurface(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wl log.debug("new xdg_toplevel", .{}); - // The View will add itself to the output's view stack on map const output = self.input_manager.defaultSeat().focused_output; - const node = util.gpa.create(ViewStack(View).Node) catch { + XdgToplevel.create(output, xdg_surface) catch { + log.err("out of memory", .{}); xdg_surface.resource.postNoMemory(); return; }; - node.view.init(output, xdg_surface); } /// This event is raised when the layer_shell recieves a new surface from a client. @@ -239,25 +238,24 @@ fn handleNewLayerSurface(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_ node.data.init(output, wlr_layer_surface); } -fn handleNewXwaylandSurface(listener: *wl.Listener(*wlr.XwaylandSurface), wlr_xwayland_surface: *wlr.XwaylandSurface) void { +fn handleNewXwaylandSurface(listener: *wl.Listener(*wlr.XwaylandSurface), xwayland_surface: *wlr.XwaylandSurface) void { const self = @fieldParentPtr(Self, "new_xwayland_surface", listener); - if (wlr_xwayland_surface.override_redirect) { - log.debug("new unmanaged xwayland surface", .{}); - // The unmanged surface will add itself to the list of unmanaged views - // in Root when it is mapped. - const node = util.gpa.create(std.TailQueue(XwaylandUnmanaged).Node) catch return; - node.data.init(wlr_xwayland_surface); - return; - } - log.debug( - "new xwayland surface: title '{s}', class '{s}'", - .{ wlr_xwayland_surface.title, wlr_xwayland_surface.class }, + "new xwayland surface: title='{s}', class='{s}', override redirect={}", + .{ xwayland_surface.title, xwayland_surface.class, xwayland_surface.override_redirect }, ); - // The View will add itself to the output's view stack on map - const output = self.input_manager.defaultSeat().focused_output; - const node = util.gpa.create(ViewStack(View).Node) catch return; - node.view.init(output, wlr_xwayland_surface); + if (xwayland_surface.override_redirect) { + _ = XwaylandUnmanaged.create(xwayland_surface) catch { + log.err("out of memory", .{}); + return; + }; + } else { + const output = self.input_manager.defaultSeat().focused_output; + _ = XwaylandView.create(output, xwayland_surface) catch { + log.err("out of memory", .{}); + return; + }; + } } diff --git a/river/View.zig b/river/View.zig index 0435e62..16d6036 100644 --- a/river/View.zig +++ b/river/View.zig @@ -74,7 +74,7 @@ const SavedBuffer = struct { }; /// The implementation of this view -impl: Impl = undefined, +impl: Impl, /// The output this view is currently associated with output: *Output, @@ -102,7 +102,7 @@ surface_box: Box = undefined, saved_surface_box: Box = undefined, /// These are what we render while a transaction is in progress -saved_buffers: std.ArrayList(SavedBuffer), +saved_buffers: std.ArrayListUnmanaged(SavedBuffer) = .{}, /// The floating dimensions the view, saved so that they can be restored if the /// view returns to floating mode. @@ -126,26 +126,18 @@ foreign_close: wl.Listener(*wlr.ForeignToplevelHandleV1) = request_activate: wl.Listener(*wlr.XdgActivationV1.event.RequestActivate) = wl.Listener(*wlr.XdgActivationV1.event.RequestActivate).init(handleRequestActivate), -pub fn init(self: *Self, output: *Output, surface: anytype) void { +pub fn init(self: *Self, output: *Output, impl: Impl) void { const initial_tags = blk: { const tags = output.current.tags & output.spawn_tagmask; break :blk if (tags != 0) tags else output.current.tags; }; self.* = .{ + .impl = impl, .output = output, .current = .{ .tags = initial_tags }, .pending = .{ .tags = initial_tags }, - .saved_buffers = std.ArrayList(SavedBuffer).init(util.gpa), }; - - if (@TypeOf(surface) == *wlr.XdgSurface) { - self.impl = .{ .xdg_toplevel = undefined }; - self.impl.xdg_toplevel.init(self, surface); - } else if (build_options.xwayland and @TypeOf(surface) == *wlr.XwaylandSurface) { - self.impl = .{ .xwayland_view = undefined }; - self.impl.xwayland_view.init(self, surface); - } else unreachable; } /// If saved buffers of the view are currently in use by a transaction, @@ -159,7 +151,7 @@ pub fn destroy(self: *Self) void { // around until the current transaction completes. This function will be // called again in Root.commitTransaction() if (self.saved_buffers.items.len == 0) { - self.saved_buffers.deinit(); + self.saved_buffers.deinit(util.gpa); const node = @fieldParentPtr(ViewStack(Self).Node, "view", self); util.gpa.destroy(node); @@ -237,19 +229,19 @@ pub fn dropSavedBuffers(self: *Self) void { pub fn saveBuffers(self: *Self) void { assert(self.saved_buffers.items.len == 0); self.saved_surface_box = self.surface_box; - self.forEachSurface(*std.ArrayList(SavedBuffer), saveBuffersIterator, &self.saved_buffers); + self.forEachSurface(*std.ArrayListUnmanaged(SavedBuffer), saveBuffersIterator, &self.saved_buffers); } fn saveBuffersIterator( surface: *wlr.Surface, surface_x: c_int, surface_y: c_int, - saved_buffers: *std.ArrayList(SavedBuffer), + saved_buffers: *std.ArrayListUnmanaged(SavedBuffer), ) callconv(.C) void { if (surface.buffer) |buffer| { var source_box: wlr.FBox = undefined; surface.getBufferSourceBox(&source_box); - saved_buffers.append(.{ + saved_buffers.append(util.gpa, .{ .client_buffer = buffer, .surface_box = .{ .x = surface_x, diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig index 19cfe9b..9793adb 100644 --- a/river/XdgToplevel.zig +++ b/river/XdgToplevel.zig @@ -25,6 +25,7 @@ const server = &@import("main.zig").server; const util = @import("util.zig"); const Box = @import("Box.zig"); +const Output = @import("Output.zig"); const Seat = @import("Seat.zig"); const Subsurface = @import("Subsurface.zig"); const View = @import("View.zig"); @@ -62,8 +63,17 @@ request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = set_title: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetTitle), set_app_id: wl.Listener(*wlr.XdgSurface) = wl.Listener(*wlr.XdgSurface).init(handleSetAppId), -pub fn init(self: *Self, view: *View, xdg_surface: *wlr.XdgSurface) void { - self.* = .{ .view = view, .xdg_surface = xdg_surface }; +/// The View will add itself to the output's view stack on map +pub fn create(output: *Output, xdg_surface: *wlr.XdgSurface) error{OutOfMemory}!void { + const node = try util.gpa.create(ViewStack(View).Node); + const view = &node.view; + + view.init(output, .{ .xdg_toplevel = .{ + .view = view, + .xdg_surface = xdg_surface, + } }); + + const self = &node.view.impl.xdg_toplevel; xdg_surface.data = @ptrToInt(self); // Add listeners that are active over the view's entire lifetime diff --git a/river/XwaylandUnmanaged.zig b/river/XwaylandUnmanaged.zig index 4eb6a88..f490779 100644 --- a/river/XwaylandUnmanaged.zig +++ b/river/XwaylandUnmanaged.zig @@ -47,7 +47,12 @@ set_override_redirect: wl.Listener(*wlr.XwaylandSurface) = // Listeners that are only active while mapped commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit), -pub fn init(self: *Self, xwayland_surface: *wlr.XwaylandSurface) void { +/// The unmanged surface will add itself to the list of unmanaged views +/// in Root when it is mapped. +pub fn create(xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!*Self { + const node = try util.gpa.create(std.TailQueue(Self).Node); + const self = &node.data; + self.* = .{ .xwayland_surface = xwayland_surface }; // Add listeners that are active over the the entire lifetime @@ -55,6 +60,8 @@ pub fn init(self: *Self, xwayland_surface: *wlr.XwaylandSurface) void { xwayland_surface.events.destroy.add(&self.destroy); xwayland_surface.events.map.add(&self.map); xwayland_surface.events.unmap.add(&self.unmap); + + return self; } fn handleRequestConfigure( @@ -135,15 +142,13 @@ fn handleSetOverrideRedirect( if (xwayland_surface.mapped) handleUnmap(&self.unmap, xwayland_surface); handleDestroy(&self.destroy, xwayland_surface); - // The View will add itself to the output's view stack on map const output = server.input_manager.defaultSeat().focused_output; - const node = util.gpa.create(ViewStack(View).Node) catch { + const xwayland_view = XwaylandView.create(output, xwayland_surface) catch { log.err("out of memory", .{}); return; }; - node.view.init(output, xwayland_surface); if (xwayland_surface.mapped) { - XwaylandView.handleMap(&node.view.impl.xwayland_view.map, xwayland_surface); + XwaylandView.handleMap(&xwayland_view.map, xwayland_surface); } } diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 153ccee..b7434c8 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -27,6 +27,7 @@ const server = &@import("main.zig").server; const util = @import("util.zig"); const Box = @import("Box.zig"); +const Output = @import("Output.zig"); const View = @import("View.zig"); const ViewStack = @import("view_stack.zig").ViewStack; const XdgPopup = @import("XdgPopup.zig"); @@ -63,12 +64,18 @@ request_fullscreen: wl.Listener(*wlr.XwaylandSurface) = request_minimize: wl.Listener(*wlr.XwaylandSurface.event.Minimize) = wl.Listener(*wlr.XwaylandSurface.event.Minimize).init(handleRequestMinimize), -pub fn init(self: *Self, view: *View, xwayland_surface: *wlr.XwaylandSurface) void { - self.* = .{ +/// The View will add itself to the output's view stack on map +pub fn create(output: *Output, xwayland_surface: *wlr.XwaylandSurface) error{OutOfMemory}!*Self { + const node = try util.gpa.create(ViewStack(View).Node); + const view = &node.view; + + view.init(output, .{ .xwayland_view = .{ .view = view, .xwayland_surface = xwayland_surface, .last_set_fullscreen_state = xwayland_surface.fullscreen, - }; + } }); + + const self = &node.view.impl.xwayland_view; xwayland_surface.data = @ptrToInt(self); // Add listeners that are active over the view's entire lifetime @@ -76,6 +83,8 @@ pub fn init(self: *Self, view: *View, xwayland_surface: *wlr.XwaylandSurface) vo xwayland_surface.events.map.add(&self.map); xwayland_surface.events.unmap.add(&self.unmap); xwayland_surface.events.request_configure.add(&self.request_configure); + + return self; } pub fn needsConfigure(self: Self) bool { @@ -283,16 +292,13 @@ fn handleSetOverrideRedirect( if (xwayland_surface.mapped) handleUnmap(&self.unmap, xwayland_surface); handleDestroy(&self.destroy, xwayland_surface); - // The unmanged surface will add itself to the list of unmanaged views - // in Root when it is mapped. - const node = util.gpa.create(std.TailQueue(XwaylandUnmanaged).Node) catch { + const unmanaged = XwaylandUnmanaged.create(xwayland_surface) catch { log.err("out of memory", .{}); return; }; - node.data.init(xwayland_surface); if (xwayland_surface.mapped) { - XwaylandUnmanaged.handleMap(&node.data.map, xwayland_surface); + XwaylandUnmanaged.handleMap(&unmanaged.map, xwayland_surface); } } |
