Only store mapped layer surfaces in Output.layers

This commit is contained in:
Isaac Freund 2020-05-12 00:11:11 +02:00
parent 5bec8f4fcb
commit 0eb6c7c113
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
4 changed files with 22 additions and 34 deletions

View file

@ -28,9 +28,6 @@ const Output = @import("Output.zig");
output: *Output,
wlr_layer_surface: *c.wlr_layer_surface_v1,
/// True if the layer surface is currently mapped
mapped: bool,
box: Box,
layer: c.zwlr_layer_shell_v1_layer,
@ -47,20 +44,22 @@ pub fn init(
self: *Self,
output: *Output,
wlr_layer_surface: *c.wlr_layer_surface_v1,
layer: c.zwlr_layer_shell_v1_layer,
) void {
self.output = output;
self.wlr_layer_surface = wlr_layer_surface;
wlr_layer_surface.data = self;
self.layer = layer;
self.layer = wlr_layer_surface.client_pending.layer;
// Temporarily set mapped to true and apply the pending state to allow
// Temporarily add to the output's list and apply the pending state to allow
// for inital arrangement which sends the first configure.
self.mapped = true;
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
const list = &output.layers[@intCast(usize, @enumToInt(self.layer))];
const stashed_state = wlr_layer_surface.current;
wlr_layer_surface.current = wlr_layer_surface.client_pending;
list.append(node);
output.arrangeLayers();
list.remove(node);
wlr_layer_surface.current = stashed_state;
// Set up listeners that are active for the entire lifetime of the layer surface
@ -86,10 +85,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
c.wl_list_remove(&self.listen_unmap.link);
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
output.layers[@intCast(usize, @enumToInt(self.layer))].remove(node);
output.root.server.allocator.destroy(node);
self.output.arrangeLayers();
}
fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
@ -98,8 +94,6 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
Log.Debug.log("Layer surface '{}' mapped.", .{wlr_layer_surface.namespace});
self.mapped = true;
// Add listeners that are only active while mapped
self.listen_commit.notify = handleCommit;
c.wl_signal_add(&wlr_layer_surface.surface.*.events.commit, &self.listen_commit);
@ -111,6 +105,9 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
wlr_layer_surface.surface,
wlr_layer_surface.output,
);
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
self.output.layers[@intCast(usize, @enumToInt(self.layer))].append(node);
}
fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
@ -119,9 +116,10 @@ fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
Log.Debug.log("Layer surface '{}' unmapped.", .{self.wlr_layer_surface.namespace});
// This is a bit ugly: we need to use the wlr bool here since surfaces
// may be closed during the inital configure since we set our mapped
// bool to true so that we can avoid making the arrange function even
// more complex.
// may be closed during the inital configure which we preform
// while unmapped. wlroots currently calls unmap unconditionally on close
// even if the surface is not mapped. I sent a patch which was merged, but
// we need to wait for a release to use it.
//
// TODO(wlroots): Remove this check on updating
// https://github.com/swaywm/wlroots/commit/11e94c406bb75c9a8990ce99489798411deb110c
@ -131,7 +129,9 @@ fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
c.wl_list_remove(&self.listen_new_popup.link);
}
self.mapped = false;
// Remove from the output's list of layer surfaces
const self_node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
self.output.layers[@intCast(usize, @enumToInt(self.layer))].remove(self_node);
// If the unmapped surface is focused, clear focus
var it = self.output.root.server.input_manager.seats.first;

View file

@ -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 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;
const node = try self.layers[@intCast(usize, @enumToInt(layer))].allocateNode(self.root.server.allocator);
node.data.init(self, wlr_layer_surface, layer);
self.layers[@intCast(usize, @enumToInt(layer))].append(node);
self.arrangeLayers();
}
/// Arrange all views on the output for the current layout. Modifies only
/// pending state, the changes are not appplied until a transaction is started
/// and completed.
@ -312,10 +303,7 @@ pub fn arrangeLayers(self: *Self) void {
var it = self.layers[layer].last;
while (it) |node| : (it = node.prev) {
const layer_surface = &node.data;
// Only mapped surfaces may gain focus
if (layer_surface.mapped and
layer_surface.wlr_layer_surface.current.keyboard_interactive)
{
if (layer_surface.wlr_layer_surface.current.keyboard_interactive) {
break :outer layer_surface;
}
}
@ -360,7 +348,7 @@ fn arrangeLayer(
// If the value of exclusive_zone is greater than zero, then it exclusivly
// occupies some area of the screen.
if (!layer_surface.mapped or exclusive != (current_state.exclusive_zone > 0)) {
if (exclusive != (current_state.exclusive_zone > 0)) {
continue;
}

View file

@ -25,6 +25,7 @@ const c = @import("c.zig");
const Config = @import("Config.zig");
const DecorationManager = @import("DecorationManager.zig");
const InputManager = @import("InputManager.zig");
const LayerSurface = @import("LayerSurface.zig");
const Log = @import("log.zig").Log;
const Output = @import("Output.zig");
const Root = @import("Root.zig");
@ -240,8 +241,10 @@ fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C)
}
}
// The layer surface will add itself to the proper list of the output on map
const output = @ptrCast(*Output, @alignCast(@alignOf(*Output), wlr_layer_surface.output.*.data));
output.addLayerSurface(wlr_layer_surface) catch unreachable;
const node = self.allocator.create(std.TailQueue(LayerSurface).Node) catch unreachable;
node.data.init(output, wlr_layer_surface);
}
fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {

View file

@ -121,9 +121,6 @@ fn renderLayer(output: Output, layer: std.TailQueue(LayerSurface), now: *c.times
var it = layer.first;
while (it) |node| : (it = node.next) {
const layer_surface = &node.data;
if (!layer_surface.mapped) {
continue;
}
var rdata = SurfaceRenderData{
.output = &output,
.output_x = layer_surface.box.x,