aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Server.zig40
-rw-r--r--river/View.zig24
-rw-r--r--river/XdgToplevel.zig14
-rw-r--r--river/XwaylandUnmanaged.zig15
-rw-r--r--river/XwaylandView.zig22
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);
}
}