aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-05-11 23:43:04 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2020-05-11 23:43:04 +0200
commit5bec8f4fcb361d3c7527d367bc66c0810e3c91d9 (patch)
treed75a4ea10140d854efbd8d2c4d9f7654c9b15c78 /src
parentb2f172e91b2d75b0b2af02621ab302afce3a94d6 (diff)
downloadriver-5bec8f4fcb361d3c7527d367bc66c0810e3c91d9.tar.gz
river-5bec8f4fcb361d3c7527d367bc66c0810e3c91d9.tar.xz
Only store mapped views in the view stack
Diffstat (limited to 'src')
-rw-r--r--src/Output.zig9
-rw-r--r--src/Server.zig11
-rw-r--r--src/View.zig17
-rw-r--r--src/XdgToplevel.zig5
-rw-r--r--src/XwaylandView.zig6
-rw-r--r--src/view_stack.zig28
6 files changed, 32 insertions, 44 deletions
diff --git a/src/Output.zig b/src/Output.zig
index cb5cba4..c2315bc 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -147,15 +147,6 @@ pub fn getRenderer(self: Self) *c.wlr_renderer {
return c.river_wlr_backend_get_renderer(self.wlr_output.backend);
}
-/// Add a new view to the output. arrangeViews() will be called by the view
-/// when it is mapped. The surface argument must be a c.wlr_xdg_surface or
-/// c.wlr_xwayland_surface (if xwayland is enabled)
-pub fn addView(self: *Self, surface: var) !void {
- const node = try self.root.server.allocator.create(ViewStack(View).Node);
- node.view.init(self, self.current_focused_tags, surface);
- self.views.push(node);
-}
-
/// Add a newly created layer surface to the output.
pub fn addLayerSurface(self: *Self, wlr_layer_surface: *c.wlr_layer_surface_v1) !void {
const layer = wlr_layer_surface.client_pending.layer;
diff --git a/src/Server.zig b/src/Server.zig
index 944f297..8639233 100644
--- a/src/Server.zig
+++ b/src/Server.zig
@@ -190,7 +190,10 @@ fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) v
Log.Debug.log("New xdg_toplevel", .{});
- self.input_manager.default_seat.focused_output.addView(wlr_xdg_surface) catch unreachable;
+ // The View will add itself to the output's view stack on map
+ const output = self.input_manager.default_seat.focused_output;
+ const node = self.allocator.create(ViewStack(View).Node) catch unreachable;
+ node.view.init(output, output.current_focused_tags, wlr_xdg_surface);
}
/// This event is raised when the layer_shell recieves a new surface from a client.
@@ -261,5 +264,9 @@ fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(
"New xwayland surface: title '{}', class '{}'",
.{ wlr_xwayland_surface.title, wlr_xwayland_surface.class },
);
- self.input_manager.default_seat.focused_output.addView(wlr_xwayland_surface) catch unreachable;
+
+ // The View will add itself to the output's view stack on map
+ const output = self.input_manager.default_seat.focused_output;
+ const node = self.allocator.create(ViewStack(View).Node) catch unreachable;
+ node.view.init(output, output.current_focused_tags, wlr_xwayland_surface);
}
diff --git a/src/View.zig b/src/View.zig
index 32924b4..8ab32cc 100644
--- a/src/View.zig
+++ b/src/View.zig
@@ -105,7 +105,7 @@ pub fn init(
} else unreachable;
}
-pub fn deinit(self: *Self) void {
+pub fn deinit(self: Self) void {
if (self.stashed_buffer) |buffer| {
c.wlr_buffer_unref(buffer);
}
@@ -227,6 +227,10 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surfa
pub fn map(self: *Self) void {
const root = self.output.root;
+ // Add the view to the stack of its output
+ const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
+ self.output.views.push(node);
+
// Focus the newly mapped view. Note: if a seat is focusing a different output
// it will continue to do so.
var it = root.server.input_manager.seats.first;
@@ -252,5 +256,16 @@ pub fn unmap(self: *Self) void {
seat.handleViewUnmap(self);
}
+ // Remove the view from its output's stack
+ const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
+ self.output.views.remove(node);
+
root.arrange();
}
+
+/// Destory the view and free the ViewStack node holding it.
+pub fn destroy(self: *const Self) void {
+ self.deinit();
+ const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
+ self.output.root.server.allocator.destroy(node);
+}
diff --git a/src/XdgToplevel.zig b/src/XdgToplevel.zig
index a9c2040..95fee3e 100644
--- a/src/XdgToplevel.zig
+++ b/src/XdgToplevel.zig
@@ -110,10 +110,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
c.wl_list_remove(&self.listen_map.link);
c.wl_list_remove(&self.listen_unmap.link);
- // Remove the view from the stack
- const node = @fieldParentPtr(ViewStack(View).Node, "view", self.view);
- output.views.remove(node);
- output.root.server.allocator.destroy(node);
+ self.view.destroy();
}
/// Called when the xdg surface is mapped, or ready to display on-screen.
diff --git a/src/XwaylandView.zig b/src/XwaylandView.zig
index a6bf0e1..dbd35e4 100644
--- a/src/XwaylandView.zig
+++ b/src/XwaylandView.zig
@@ -108,17 +108,13 @@ pub fn surfaceAt(self: Self, ox: f64, oy: f64, sx: *f64, sy: *f64) ?*c.wlr_surfa
/// Called when the xwayland surface is destroyed
fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_destroy", listener.?);
- const output = self.view.output;
// Remove listeners that are active for the entire lifetime of the view
c.wl_list_remove(&self.listen_destroy.link);
c.wl_list_remove(&self.listen_map.link);
c.wl_list_remove(&self.listen_unmap.link);
- // Remove the view from the stack
- const node = @fieldParentPtr(ViewStack(View).Node, "view", self.view);
- output.views.remove(node);
- output.root.server.allocator.destroy(node);
+ self.view.destroy();
}
/// Called when the xwayland surface is mapped, or ready to display on-screen.
diff --git a/src/view_stack.zig b/src/view_stack.zig
index 7e32a91..0543d03 100644
--- a/src/view_stack.zig
+++ b/src/view_stack.zig
@@ -92,7 +92,7 @@ pub fn ViewStack(comptime T: type) type {
/// This function is horribly ugly, but it's well tested below.
pub fn next(self: *Iterator) ?*Node {
while (self.it) |node| : (self.it = if (self.reverse) node.prev else node.next) {
- if (node.view.wlr_surface != null and if (self.pending)
+ if (if (self.pending)
if (node.view.pending_tags) |pending_tags|
self.tags & pending_tags != 0
else
@@ -109,7 +109,6 @@ pub fn ViewStack(comptime T: type) type {
/// Returns an iterator starting at the passed node and filtered by
/// checking the passed tags against the current tags of each view.
- /// Unmapped views are skipped.
pub fn iterator(start: ?*Node, tags: u32) Iterator {
return Iterator{
.it = start,
@@ -121,7 +120,6 @@ pub fn ViewStack(comptime T: type) type {
/// Returns a reverse iterator starting at the passed node and filtered by
/// checking the passed tags against the current tags of each view.
- /// Unmapped views are skipped.
pub fn reverseIterator(start: ?*Node, tags: u32) Iterator {
return Iterator{
.it = start,
@@ -133,8 +131,7 @@ pub fn ViewStack(comptime T: type) type {
/// Returns an iterator starting at the passed node and filtered by
/// checking the passed tags against the pending tags of each view.
- /// If a view has no pending tags, the current tags are used. Unmapped
- /// views are skipped.
+ /// If a view has no pending tags, the current tags are used.
pub fn pendingIterator(start: ?*Node, tags: u32) Iterator {
return Iterator{
.it = start,
@@ -285,51 +282,36 @@ test "iteration (View)" {
var views: ViewStack(View) = undefined;
views.init();
- // Pretty nice hack for testing: we don't actually need a wlr_surface here,
- // but we need the iteration function to thing that the view has a non-null
- // wlr_surface. So, just cast an integer to a pointer to get an arbitrary
- // but non-null value. Use 8 so the alignment checks out.
-
const one_a_pb = try allocator.create(ViewStack(View).Node);
defer allocator.destroy(one_a_pb);
- one_a_pb.view.wlr_surface = @intToPtr(*c.wlr_surface, 8);
one_a_pb.view.current_tags = 1 << 0;
one_a_pb.view.pending_tags = 1 << 1;
const two_a = try allocator.create(ViewStack(View).Node);
defer allocator.destroy(two_a);
- two_a.view.wlr_surface = @intToPtr(*c.wlr_surface, 8);
two_a.view.current_tags = 1 << 0;
two_a.view.pending_tags = null;
const three_b_pa = try allocator.create(ViewStack(View).Node);
defer allocator.destroy(three_b_pa);
- three_b_pa.view.wlr_surface = @intToPtr(*c.wlr_surface, 8);
three_b_pa.view.current_tags = 1 << 1;
three_b_pa.view.pending_tags = 1 << 0;
const four_b = try allocator.create(ViewStack(View).Node);
defer allocator.destroy(four_b);
- four_b.view.wlr_surface = @intToPtr(*c.wlr_surface, 8);
four_b.view.current_tags = 1 << 1;
four_b.view.pending_tags = null;
const five_b = try allocator.create(ViewStack(View).Node);
defer allocator.destroy(five_b);
- five_b.view.wlr_surface = @intToPtr(*c.wlr_surface, 8);
five_b.view.current_tags = 1 << 1;
five_b.view.pending_tags = null;
- const unmapped_1 = try allocator.create(ViewStack(View).Node);
- defer allocator.destroy(unmapped_1);
- unmapped_1.view.wlr_surface = null;
-
views.push(three_b_pa); // {3}
views.push(one_a_pb); // {1, 3}
- views.push(unmapped_1); // {u, 1, 3}
- views.push(four_b); // {4, u, 1, 3}
- views.push(five_b); // {5, 4, u, 1, 3}
- views.push(two_a); // {2, 5, 4, u, 1, 3}
+ views.push(four_b); // {4, 1, 3}
+ views.push(five_b); // {5, 4, 1, 3}
+ views.push(two_a); // {2, 5, 4, 1, 3}
// Iteration over all tags
{