Output: use separate scene trees for layers
This commit is contained in:
parent
b38676f078
commit
f4a8d6dcc9
@ -95,7 +95,7 @@ fn handleUnmap(listener: *wl.Listener(*wlr.LayerSurfaceV1), _: *wlr.LayerSurface
|
||||
|
||||
// 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);
|
||||
self.output.layer_surfaces[@intCast(usize, @enumToInt(self.layer))].remove(self_node);
|
||||
|
||||
// If the unmapped surface is focused, clear focus
|
||||
var it = server.input_manager.seats.first;
|
||||
|
@ -57,7 +57,7 @@ const State = struct {
|
||||
wlr_output: *wlr.Output,
|
||||
|
||||
/// All layer surfaces on the output, indexed by the layer enum.
|
||||
layers: [4]std.TailQueue(LayerSurface) = [1]std.TailQueue(LayerSurface){.{}} ** 4,
|
||||
layer_surfaces: [4]std.TailQueue(LayerSurface) = [1]std.TailQueue(LayerSurface){.{}} ** 4,
|
||||
|
||||
/// The area left for views and other layer surfaces after applying the
|
||||
/// exclusive zones of exclusive layer surfaces.
|
||||
@ -70,6 +70,24 @@ tree: *wlr.SceneTree,
|
||||
normal_content: *wlr.SceneTree,
|
||||
locked_content: *wlr.SceneTree,
|
||||
|
||||
layers: struct {
|
||||
background_color_rect: *wlr.SceneRect,
|
||||
/// Background layer shell layer
|
||||
background: *wlr.SceneTree,
|
||||
/// Bottom layer shell layer
|
||||
bottom: *wlr.SceneTree,
|
||||
/// Tiled and floating views
|
||||
views: *wlr.SceneTree,
|
||||
/// Top layer shell layer
|
||||
top: *wlr.SceneTree,
|
||||
/// Fullscreen views
|
||||
fullscreen: *wlr.SceneTree,
|
||||
/// Overlay layer shell layer
|
||||
overlay: *wlr.SceneTree,
|
||||
/// Xdg popups, Xwayland override redirect windows
|
||||
popups: *wlr.SceneTree,
|
||||
},
|
||||
|
||||
/// The top of the stack is the "most important" view.
|
||||
views: ViewStack(View) = .{},
|
||||
|
||||
@ -146,16 +164,44 @@ pub fn create(wlr_output: *wlr.Output) !void {
|
||||
};
|
||||
}
|
||||
|
||||
var width: c_int = undefined;
|
||||
var height: c_int = undefined;
|
||||
wlr_output.effectiveResolution(&width, &height);
|
||||
|
||||
const tree = try server.root.scene.tree.createSceneTree();
|
||||
const normal_content = try tree.createSceneTree();
|
||||
|
||||
self.* = .{
|
||||
.wlr_output = wlr_output,
|
||||
.tree = tree,
|
||||
.normal_content = try tree.createSceneTree(),
|
||||
.normal_content = normal_content,
|
||||
.locked_content = try tree.createSceneTree(),
|
||||
.usable_box = undefined,
|
||||
.layers = .{
|
||||
.background_color_rect = try normal_content.createSceneRect(
|
||||
width,
|
||||
height,
|
||||
&server.config.background_color,
|
||||
),
|
||||
.background = try normal_content.createSceneTree(),
|
||||
.bottom = try normal_content.createSceneTree(),
|
||||
.views = try normal_content.createSceneTree(),
|
||||
.top = try normal_content.createSceneTree(),
|
||||
.fullscreen = try normal_content.createSceneTree(),
|
||||
.overlay = try normal_content.createSceneTree(),
|
||||
.popups = try normal_content.createSceneTree(),
|
||||
},
|
||||
.usable_box = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = width,
|
||||
.height = height,
|
||||
},
|
||||
};
|
||||
wlr_output.data = @ptrToInt(self);
|
||||
|
||||
_ = try self.layers.fullscreen.createSceneRect(width, height, &[_]f32{ 0, 0, 0, 1.0 });
|
||||
self.layers.fullscreen.node.setEnabled(false);
|
||||
|
||||
wlr_output.events.destroy.add(&self.destroy);
|
||||
wlr_output.events.enable.add(&self.enable);
|
||||
wlr_output.events.mode.add(&self.mode);
|
||||
@ -171,14 +217,6 @@ pub fn create(wlr_output: *wlr.Output) !void {
|
||||
std.log.scoped(.cursor).err("failed to load xcursor theme at scale {}", .{wlr_output.scale});
|
||||
}
|
||||
|
||||
self.usable_box = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = undefined,
|
||||
.height = undefined,
|
||||
};
|
||||
self.wlr_output.effectiveResolution(&self.usable_box.width, &self.usable_box.height);
|
||||
|
||||
self.setTitle();
|
||||
|
||||
const ptr_node = try util.gpa.create(std.TailQueue(*Self).Node);
|
||||
@ -189,7 +227,7 @@ pub fn create(wlr_output: *wlr.Output) !void {
|
||||
}
|
||||
|
||||
pub fn getLayer(self: *Self, layer: zwlr.LayerShellV1.Layer) *std.TailQueue(LayerSurface) {
|
||||
return &self.layers[@intCast(usize, @enumToInt(layer))];
|
||||
return &self.layer_surfaces[@intCast(usize, @enumToInt(layer))];
|
||||
}
|
||||
|
||||
pub fn sendViewTags(self: Self) void {
|
||||
@ -475,7 +513,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||
// Remove the destroyed output from root if it wasn't already removed
|
||||
server.root.removeOutput(self);
|
||||
assert(self.views.first == null and self.views.last == null);
|
||||
for (self.layers) |layer| assert(layer.len == 0);
|
||||
for (self.layer_surfaces) |layer| assert(layer.len == 0);
|
||||
assert(self.layouts.len == 0);
|
||||
|
||||
var it = server.root.all_outputs.first;
|
||||
@ -538,6 +576,18 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||
|
||||
fn handleMode(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
|
||||
const self = @fieldParentPtr(Self, "mode", listener);
|
||||
|
||||
{
|
||||
var width: c_int = undefined;
|
||||
var height: c_int = undefined;
|
||||
self.wlr_output.effectiveResolution(&width, &height);
|
||||
self.layers.background_color_rect.setSize(width, height);
|
||||
|
||||
var it = self.layers.fullscreen.children.iterator(.forward);
|
||||
const background_color_rect = @fieldParentPtr(wlr.SceneRect, "node", it.next().?);
|
||||
background_color_rect.setSize(width, height);
|
||||
}
|
||||
|
||||
self.arrangeLayers(.mapped);
|
||||
self.arrangeViews();
|
||||
server.root.startTransaction();
|
||||
|
@ -93,7 +93,10 @@ pub fn init(self: *Self) !void {
|
||||
const transaction_timer = try event_loop.addTimer(*Self, handleTransactionTimeout, self);
|
||||
errdefer transaction_timer.remove();
|
||||
|
||||
// TODO get rid of this hack somehow
|
||||
const noop_wlr_output = try server.headless_backend.headlessAddOutput(1920, 1080);
|
||||
const noop_tree = try scene.tree.createSceneTree();
|
||||
noop_tree.node.setEnabled(false);
|
||||
self.* = .{
|
||||
.scene = scene,
|
||||
.output_layout = output_layout,
|
||||
@ -102,9 +105,23 @@ pub fn init(self: *Self) !void {
|
||||
.transaction_timer = transaction_timer,
|
||||
.noop_output = .{
|
||||
.wlr_output = noop_wlr_output,
|
||||
.tree = try scene.tree.createSceneTree(),
|
||||
.normal_content = try scene.tree.createSceneTree(),
|
||||
.locked_content = try scene.tree.createSceneTree(),
|
||||
.tree = noop_tree,
|
||||
.normal_content = try noop_tree.createSceneTree(),
|
||||
.locked_content = try noop_tree.createSceneTree(),
|
||||
.layers = .{
|
||||
.background_color_rect = try noop_tree.createSceneRect(
|
||||
0,
|
||||
0,
|
||||
&server.config.background_color,
|
||||
),
|
||||
.background = try noop_tree.createSceneTree(),
|
||||
.bottom = try noop_tree.createSceneTree(),
|
||||
.views = try noop_tree.createSceneTree(),
|
||||
.top = try noop_tree.createSceneTree(),
|
||||
.fullscreen = try noop_tree.createSceneTree(),
|
||||
.overlay = try noop_tree.createSceneTree(),
|
||||
.popups = try noop_tree.createSceneTree(),
|
||||
},
|
||||
.usable_box = .{ .x = 0, .y = 0, .width = 0, .height = 0 },
|
||||
},
|
||||
};
|
||||
@ -218,7 +235,7 @@ pub fn removeOutput(self: *Self, output: *Output) void {
|
||||
}
|
||||
|
||||
// Close all layer surfaces on the removed output
|
||||
for (output.layers) |*layer| {
|
||||
for (output.layer_surfaces) |*layer| {
|
||||
// Destroying the layer surface will cause it to be removed from this list.
|
||||
while (layer.first) |layer_node| layer_node.data.wlr_layer_surface.destroy();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ pub fn create(output: *Output, xdg_toplevel: *wlr.XdgToplevel) error{OutOfMemory
|
||||
errdefer util.gpa.destroy(node);
|
||||
const view = &node.view;
|
||||
|
||||
const tree = try output.normal_content.createSceneXdgSurface(xdg_toplevel.base);
|
||||
const tree = try output.layers.views.createSceneXdgSurface(xdg_toplevel.base);
|
||||
errdefer tree.node.destroy();
|
||||
|
||||
try view.init(output, tree, .{ .xdg_toplevel = .{
|
||||
|
@ -68,7 +68,7 @@ pub fn create(output: *Output, xwayland_surface: *wlr.XwaylandSurface) error{Out
|
||||
const view = &node.view;
|
||||
|
||||
// TODO actually render xwayland windows, not just an empty tree.
|
||||
const tree = try output.tree.createSceneTree();
|
||||
const tree = try output.layers.views.createSceneTree();
|
||||
|
||||
view.init(output, tree, .{ .xwayland_view = .{
|
||||
.view = view,
|
||||
|
@ -46,6 +46,11 @@ pub fn backgroundColor(
|
||||
if (args.len > 2) return Error.TooManyArguments;
|
||||
|
||||
server.config.background_color = try parseRgba(args[1]);
|
||||
var it = server.root.all_outputs.first;
|
||||
while (it) |node| : (it = node.next) {
|
||||
const output = node.data;
|
||||
output.layers.background_color_rect.setColor(&server.config.background_color);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borderColorFocused(
|
||||
|
Loading…
Reference in New Issue
Block a user