river: update to wlroots 0.15.0
This commit is contained in:
parent
c3370afa3d
commit
4d19621f1e
@ -41,7 +41,7 @@ distribution.
|
|||||||
- [zig](https://ziglang.org/download/) 0.8
|
- [zig](https://ziglang.org/download/) 0.8
|
||||||
- wayland
|
- wayland
|
||||||
- wayland-protocols
|
- wayland-protocols
|
||||||
- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.14
|
- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.15
|
||||||
- xkbcommon
|
- xkbcommon
|
||||||
- libevdev
|
- libevdev
|
||||||
- pixman
|
- pixman
|
||||||
|
2
deps/zig-wlroots
vendored
2
deps/zig-wlroots
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9bb6b03f0ea04d4ea6a102ed3e45badba9e8e262
|
Subproject commit e2be6fbcc25694e111defdd41de9096802bf049a
|
@ -51,11 +51,7 @@ pub const InputDevice = struct {
|
|||||||
const identifier = try std.fmt.allocPrint(
|
const identifier = try std.fmt.allocPrint(
|
||||||
util.gpa,
|
util.gpa,
|
||||||
"{}:{}:{s}",
|
"{}:{}:{s}",
|
||||||
.{ device.vendor, device.product, mem.trim(
|
.{ device.vendor, device.product, mem.trim(u8, mem.span(device.name), &ascii.spaces) },
|
||||||
u8,
|
|
||||||
mem.sliceTo(device.name, 0),
|
|
||||||
&ascii.spaces,
|
|
||||||
) },
|
|
||||||
);
|
);
|
||||||
for (identifier) |*char| {
|
for (identifier) |*char| {
|
||||||
if (char.* == ' ' or !std.ascii.isPrint(char.*)) {
|
if (char.* == ' ' or !std.ascii.isPrint(char.*)) {
|
||||||
@ -238,7 +234,7 @@ fn handleNewInput(listener: *wl.Listener(*wlr.InputDevice), device: *wlr.InputDe
|
|||||||
|
|
||||||
// Apply matching input device configuration, if exists.
|
// Apply matching input device configuration, if exists.
|
||||||
for (self.input_configs.items) |*input_config| {
|
for (self.input_configs.items) |*input_config| {
|
||||||
if (mem.eql(u8, input_config.identifier, mem.sliceTo(input_device_node.data.identifier, 0))) {
|
if (mem.eql(u8, input_config.identifier, input_device_node.data.identifier)) {
|
||||||
input_config.apply(&input_device_node.data);
|
input_config.apply(&input_device_node.data);
|
||||||
break; // There will only ever be one InputConfig for any unique identifier;
|
break; // There will only ever be one InputConfig for any unique identifier;
|
||||||
}
|
}
|
||||||
|
@ -139,9 +139,6 @@ fn handleUnmap(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_surface: *
|
|||||||
fn handleCommit(listener: *wl.Listener(*wlr.Surface), wlr_surface: *wlr.Surface) void {
|
fn handleCommit(listener: *wl.Listener(*wlr.Surface), wlr_surface: *wlr.Surface) void {
|
||||||
const self = @fieldParentPtr(Self, "commit", listener);
|
const self = @fieldParentPtr(Self, "commit", listener);
|
||||||
|
|
||||||
// Ignore commits if the surface has been closed.
|
|
||||||
if (self.wlr_layer_surface.closed) return;
|
|
||||||
|
|
||||||
assert(self.wlr_layer_surface.output != null);
|
assert(self.wlr_layer_surface.output != null);
|
||||||
|
|
||||||
// If a surface is committed while it is not mapped, we may need to send a configure.
|
// If a surface is committed while it is not mapped, we may need to send a configure.
|
||||||
|
@ -100,7 +100,7 @@ fn handleRequestInert(layout: *river.LayoutV3, request: river.LayoutV3.Request,
|
|||||||
pub fn startLayoutDemand(self: *Self, views: u32) void {
|
pub fn startLayoutDemand(self: *Self, views: u32) void {
|
||||||
log.debug(
|
log.debug(
|
||||||
"starting layout demand '{s}' on output '{s}'",
|
"starting layout demand '{s}' on output '{s}'",
|
||||||
.{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0) },
|
.{ self.namespace, self.output.wlr_output.name },
|
||||||
);
|
);
|
||||||
|
|
||||||
std.debug.assert(self.output.layout_demand == null);
|
std.debug.assert(self.output.layout_demand == null);
|
||||||
@ -129,7 +129,7 @@ fn handleRequest(layout: *river.LayoutV3, request: river.LayoutV3.Request, self:
|
|||||||
.push_view_dimensions => |req| {
|
.push_view_dimensions => |req| {
|
||||||
log.debug(
|
log.debug(
|
||||||
"layout '{s}' on output '{s}' pushed view dimensions: {} {} {} {}",
|
"layout '{s}' on output '{s}' pushed view dimensions: {} {} {} {}",
|
||||||
.{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0), req.x, req.y, req.width, req.height },
|
.{ self.namespace, self.output.wlr_output.name, req.x, req.y, req.width, req.height },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (self.output.layout_demand) |*layout_demand| {
|
if (self.output.layout_demand) |*layout_demand| {
|
||||||
@ -146,7 +146,7 @@ fn handleRequest(layout: *river.LayoutV3, request: river.LayoutV3.Request, self:
|
|||||||
.commit => |req| {
|
.commit => |req| {
|
||||||
log.debug(
|
log.debug(
|
||||||
"layout '{s}' on output '{s}' commited",
|
"layout '{s}' on output '{s}' commited",
|
||||||
.{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0) },
|
.{ self.namespace, self.output.wlr_output.name },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (self.output.layout_demand) |*layout_demand| {
|
if (self.output.layout_demand) |*layout_demand| {
|
||||||
@ -166,7 +166,7 @@ fn handleDestroy(layout: *river.LayoutV3, self: *Self) void {
|
|||||||
pub fn destroy(self: *Self) void {
|
pub fn destroy(self: *Self) void {
|
||||||
log.debug(
|
log.debug(
|
||||||
"destroying layout '{s}' on output '{s}'",
|
"destroying layout '{s}' on output '{s}'",
|
||||||
.{ self.namespace, mem.sliceTo(&self.output.wlr_output.name, 0) },
|
.{ self.namespace, self.output.wlr_output.name },
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove layout from the list
|
// Remove layout from the list
|
||||||
|
@ -72,7 +72,7 @@ pub fn deinit(self: *const Self) void {
|
|||||||
fn handleTimeout(layout: *Layout) callconv(.C) c_int {
|
fn handleTimeout(layout: *Layout) callconv(.C) c_int {
|
||||||
log.notice(
|
log.notice(
|
||||||
"layout demand for layout '{s}' on output '{s}' timed out",
|
"layout demand for layout '{s}' on output '{s}' timed out",
|
||||||
.{ layout.namespace, mem.sliceTo(&layout.output.wlr_output.name, 0) },
|
.{ layout.namespace, layout.output.wlr_output.name },
|
||||||
);
|
);
|
||||||
layout.output.layout_demand.?.deinit();
|
layout.output.layout_demand.?.deinit();
|
||||||
layout.output.layout_demand = null;
|
layout.output.layout_demand = null;
|
||||||
|
@ -67,7 +67,7 @@ fn handleRequest(layout_manager: *river.LayoutManagerV3, request: river.LayoutMa
|
|||||||
const wlr_output = wlr.Output.fromWlOutput(req.output) orelse return;
|
const wlr_output = wlr.Output.fromWlOutput(req.output) orelse return;
|
||||||
const output = @intToPtr(*Output, wlr_output.data);
|
const output = @intToPtr(*Output, wlr_output.data);
|
||||||
|
|
||||||
log.debug("bind layout '{s}' on output '{s}'", .{ req.namespace, mem.sliceTo(&output.wlr_output.name, 0) });
|
log.debug("bind layout '{s}' on output '{s}'", .{ req.namespace, output.wlr_output.name });
|
||||||
|
|
||||||
Layout.create(
|
Layout.create(
|
||||||
layout_manager.getClient(),
|
layout_manager.getClient(),
|
||||||
|
@ -99,7 +99,9 @@ frame: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(hand
|
|||||||
damage_destroy: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleDamageDestroy),
|
damage_destroy: wl.Listener(*wlr.OutputDamage) = wl.Listener(*wlr.OutputDamage).init(handleDamageDestroy),
|
||||||
|
|
||||||
pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
pub fn init(self: *Self, wlr_output: *wlr.Output) !void {
|
||||||
assert(!wlr_output.isNoop());
|
assert(!wlr_output.isHeadless());
|
||||||
|
|
||||||
|
if (!wlr_output.initRender(server.allocator, server.renderer)) return;
|
||||||
|
|
||||||
// Some backends don't have modes. DRM+KMS does, and we need to set a mode
|
// Some backends don't have modes. DRM+KMS does, and we need to set a mode
|
||||||
// before we can use the output. The mode is a tuple of (width, height,
|
// before we can use the output. The mode is a tuple of (width, height,
|
||||||
@ -413,10 +415,10 @@ fn arrangeLayer(
|
|||||||
.mapped => {
|
.mapped => {
|
||||||
assert(layer_surface.wlr_layer_surface.mapped);
|
assert(layer_surface.wlr_layer_surface.mapped);
|
||||||
layer_surface.box = new_box;
|
layer_surface.box = new_box;
|
||||||
layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
|
_ = layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
|
||||||
},
|
},
|
||||||
.unmapped => if (!layer_surface.wlr_layer_surface.mapped) {
|
.unmapped => if (!layer_surface.wlr_layer_surface.mapped) {
|
||||||
layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
|
_ = layer_surface.wlr_layer_surface.configure(new_box.width, new_box.height);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +436,7 @@ fn handleDamageDestroy(listener: *wl.Listener(*wlr.OutputDamage), wlr_output: *w
|
|||||||
fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
fn handleDestroy(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
const self = @fieldParentPtr(Self, "destroy", listener);
|
const self = @fieldParentPtr(Self, "destroy", listener);
|
||||||
|
|
||||||
std.log.scoped(.server).debug("output '{s}' destroyed", .{mem.sliceTo(&self.wlr_output.name, 0)});
|
std.log.scoped(.server).debug("output '{s}' destroyed", .{self.wlr_output.name});
|
||||||
|
|
||||||
// Remove the destroyed output from root if it wasn't already removed
|
// Remove the destroyed output from root if it wasn't already removed
|
||||||
server.root.removeOutput(self);
|
server.root.removeOutput(self);
|
||||||
@ -499,8 +501,8 @@ pub fn getEffectiveResolution(self: *Self) struct { width: u32, height: u32 } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn setTitle(self: Self) void {
|
fn setTitle(self: Self) void {
|
||||||
var buf: ["river - ".len + self.wlr_output.name.len + 1]u8 = undefined;
|
const title = fmt.allocPrintZ(util.gpa, "river - {s}", .{self.wlr_output.name}) catch return;
|
||||||
const title = fmt.bufPrintZ(&buf, "river - {s}", .{mem.sliceTo(&self.wlr_output.name, 0)}) catch unreachable;
|
defer util.gpa.free(title);
|
||||||
if (self.wlr_output.isWl()) {
|
if (self.wlr_output.isWl()) {
|
||||||
self.wlr_output.wlSetTitle(title);
|
self.wlr_output.wlSetTitle(title);
|
||||||
} else if (wlr.config.has_x11_backend and self.wlr_output.isX11()) {
|
} else if (wlr.config.has_x11_backend and self.wlr_output.isX11()) {
|
||||||
|
@ -94,7 +94,7 @@ pub fn init(self: *Self) !void {
|
|||||||
const transaction_timer = try event_loop.addTimer(*Self, handleTransactionTimeout, self);
|
const transaction_timer = try event_loop.addTimer(*Self, handleTransactionTimeout, self);
|
||||||
errdefer transaction_timer.remove();
|
errdefer transaction_timer.remove();
|
||||||
|
|
||||||
const noop_wlr_output = try server.noop_backend.noopAddOutput();
|
const noop_wlr_output = try server.headless_backend.headlessAddOutput();
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.output_layout = output_layout,
|
.output_layout = output_layout,
|
||||||
.output_manager = try wlr.OutputManagerV1.create(server.wl_server),
|
.output_manager = try wlr.OutputManagerV1.create(server.wl_server),
|
||||||
@ -123,7 +123,7 @@ pub fn deinit(self: *Self) void {
|
|||||||
|
|
||||||
fn handleNewOutput(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
fn handleNewOutput(listener: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output) void {
|
||||||
const self = @fieldParentPtr(Self, "new_output", listener);
|
const self = @fieldParentPtr(Self, "new_output", listener);
|
||||||
std.log.scoped(.output_manager).debug("new output {s}", .{mem.sliceTo(&wlr_output.name, 0)});
|
std.log.scoped(.output_manager).debug("new output {s}", .{wlr_output.name});
|
||||||
|
|
||||||
const node = util.gpa.create(std.TailQueue(Output).Node) catch {
|
const node = util.gpa.create(std.TailQueue(Output).Node) catch {
|
||||||
wlr_output.destroy();
|
wlr_output.destroy();
|
||||||
@ -480,7 +480,7 @@ fn applyOutputConfig(self: *Self, config: *wlr.OutputConfigurationV1) bool {
|
|||||||
// Since we have done a successful test commit, this will only fail
|
// Since we have done a successful test commit, this will only fail
|
||||||
// due to error in the output's backend implementation.
|
// due to error in the output's backend implementation.
|
||||||
output.wlr_output.commit() catch
|
output.wlr_output.commit() catch
|
||||||
std.log.scoped(.output_manager).err("output commit failed for {s}", .{mem.sliceTo(&output.wlr_output.name, 0)});
|
std.log.scoped(.output_manager).err("output commit failed for {s}", .{output.wlr_output.name});
|
||||||
|
|
||||||
if (output.wlr_output.enabled) {
|
if (output.wlr_output.enabled) {
|
||||||
// Moves the output if it is already in the layout
|
// Moves the output if it is already in the layout
|
||||||
@ -520,7 +520,7 @@ fn testOutputConfig(config: *wlr.OutputConfigurationV1, rollback: bool) bool {
|
|||||||
if (too_small) {
|
if (too_small) {
|
||||||
std.log.scoped(.output_manager).info(
|
std.log.scoped(.output_manager).info(
|
||||||
"The requested output resolution {}x{} scaled with {} for {s} would be too small.",
|
"The requested output resolution {}x{} scaled with {} for {s} would be too small.",
|
||||||
.{ width, height, scale, mem.sliceTo(&wlr_output.name, 0) },
|
.{ width, height, scale, wlr_output.name },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,11 +592,11 @@ fn handlePowerManagerSetMode(
|
|||||||
const log_text = if (enable) "Enabling" else "Disabling";
|
const log_text = if (enable) "Enabling" else "Disabling";
|
||||||
std.log.scoped(.output_manager).debug(
|
std.log.scoped(.output_manager).debug(
|
||||||
"{s} dpms for output {s}",
|
"{s} dpms for output {s}",
|
||||||
.{ log_text, mem.sliceTo(&event.output.name, 0) },
|
.{ log_text, event.output.name },
|
||||||
);
|
);
|
||||||
|
|
||||||
event.output.enable(enable);
|
event.output.enable(enable);
|
||||||
event.output.commit() catch {
|
event.output.commit() catch {
|
||||||
std.log.scoped(.server).err("output commit failed for {s}", .{mem.sliceTo(&event.output.name, 0)});
|
std.log.scoped(.server).err("output commit failed for {s}", .{event.output.name});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,10 @@ sigint_source: *wl.EventSource,
|
|||||||
sigterm_source: *wl.EventSource,
|
sigterm_source: *wl.EventSource,
|
||||||
|
|
||||||
backend: *wlr.Backend,
|
backend: *wlr.Backend,
|
||||||
noop_backend: *wlr.Backend,
|
headless_backend: *wlr.Backend,
|
||||||
|
|
||||||
|
renderer: *wlr.Renderer,
|
||||||
|
allocator: *wlr.Allocator,
|
||||||
|
|
||||||
xdg_shell: *wlr.XdgShell,
|
xdg_shell: *wlr.XdgShell,
|
||||||
new_xdg_surface: wl.Listener(*wlr.XdgSurface),
|
new_xdg_surface: wl.Listener(*wlr.XdgSurface),
|
||||||
@ -82,27 +85,27 @@ pub fn init(self: *Self) !void {
|
|||||||
// This frees itself when the wl.Server is destroyed
|
// This frees itself when the wl.Server is destroyed
|
||||||
self.backend = try wlr.Backend.autocreate(self.wl_server);
|
self.backend = try wlr.Backend.autocreate(self.wl_server);
|
||||||
|
|
||||||
// This backend is used to create a noop output for use when no actual
|
// This backend is used to create a headless output for use when no actual
|
||||||
// outputs are available. This frees itself when the wl.Server is destroyed.
|
// outputs are available. This frees itself when the wl.Server is destroyed.
|
||||||
self.noop_backend = try wlr.Backend.createNoop(self.wl_server);
|
self.headless_backend = try wlr.Backend.createHeadless(self.wl_server);
|
||||||
|
|
||||||
// This will never be null for the non-custom backends in wlroots
|
self.renderer = try wlr.Renderer.autocreate(self.backend);
|
||||||
const renderer = self.backend.getRenderer().?;
|
errdefer self.renderer.destroy();
|
||||||
try renderer.initServer(self.wl_server);
|
try self.renderer.initServer(self.wl_server);
|
||||||
|
|
||||||
const compositor = try wlr.Compositor.create(self.wl_server, renderer);
|
self.allocator = try wlr.Allocator.autocreate(self.backend, self.renderer);
|
||||||
|
errdefer self.allocator.destroy();
|
||||||
|
|
||||||
|
const compositor = try wlr.Compositor.create(self.wl_server, self.renderer);
|
||||||
|
|
||||||
// Set up xdg shell
|
|
||||||
self.xdg_shell = try wlr.XdgShell.create(self.wl_server);
|
self.xdg_shell = try wlr.XdgShell.create(self.wl_server);
|
||||||
self.new_xdg_surface.setNotify(handleNewXdgSurface);
|
self.new_xdg_surface.setNotify(handleNewXdgSurface);
|
||||||
self.xdg_shell.events.new_surface.add(&self.new_xdg_surface);
|
self.xdg_shell.events.new_surface.add(&self.new_xdg_surface);
|
||||||
|
|
||||||
// Set up layer shell
|
|
||||||
self.layer_shell = try wlr.LayerShellV1.create(self.wl_server);
|
self.layer_shell = try wlr.LayerShellV1.create(self.wl_server);
|
||||||
self.new_layer_surface.setNotify(handleNewLayerSurface);
|
self.new_layer_surface.setNotify(handleNewLayerSurface);
|
||||||
self.layer_shell.events.new_surface.add(&self.new_layer_surface);
|
self.layer_shell.events.new_surface.add(&self.new_layer_surface);
|
||||||
|
|
||||||
// Set up xwayland if built with support
|
|
||||||
if (build_options.xwayland) {
|
if (build_options.xwayland) {
|
||||||
self.xwayland = try wlr.Xwayland.create(self.wl_server, compositor, false);
|
self.xwayland = try wlr.Xwayland.create(self.wl_server, compositor, false);
|
||||||
self.new_xwayland_surface.setNotify(handleNewXwaylandSurface);
|
self.new_xwayland_surface.setNotify(handleNewXwaylandSurface);
|
||||||
@ -142,6 +145,8 @@ pub fn deinit(self: *Self) void {
|
|||||||
self.wl_server.destroyClients();
|
self.wl_server.destroyClients();
|
||||||
|
|
||||||
self.backend.destroy();
|
self.backend.destroy();
|
||||||
|
self.renderer.destroy();
|
||||||
|
self.allocator.destroy();
|
||||||
|
|
||||||
self.root.deinit();
|
self.root.deinit();
|
||||||
self.input_manager.deinit();
|
self.input_manager.deinit();
|
||||||
@ -196,15 +201,15 @@ fn handleNewLayerSurface(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_
|
|||||||
"new layer surface: namespace {s}, layer {s}, anchor {b:0>4}, size {},{}, margin {},{},{},{}, exclusive_zone {}",
|
"new layer surface: namespace {s}, layer {s}, anchor {b:0>4}, size {},{}, margin {},{},{},{}, exclusive_zone {}",
|
||||||
.{
|
.{
|
||||||
wlr_layer_surface.namespace,
|
wlr_layer_surface.namespace,
|
||||||
@tagName(wlr_layer_surface.client_pending.layer),
|
@tagName(wlr_layer_surface.pending.layer),
|
||||||
@bitCast(u32, wlr_layer_surface.client_pending.anchor),
|
@bitCast(u32, wlr_layer_surface.pending.anchor),
|
||||||
wlr_layer_surface.client_pending.desired_width,
|
wlr_layer_surface.pending.desired_width,
|
||||||
wlr_layer_surface.client_pending.desired_height,
|
wlr_layer_surface.pending.desired_height,
|
||||||
wlr_layer_surface.client_pending.margin.top,
|
wlr_layer_surface.pending.margin.top,
|
||||||
wlr_layer_surface.client_pending.margin.right,
|
wlr_layer_surface.pending.margin.right,
|
||||||
wlr_layer_surface.client_pending.margin.bottom,
|
wlr_layer_surface.pending.margin.bottom,
|
||||||
wlr_layer_surface.client_pending.margin.left,
|
wlr_layer_surface.pending.margin.left,
|
||||||
wlr_layer_surface.client_pending.exclusive_zone,
|
wlr_layer_surface.pending.exclusive_zone,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -218,9 +223,7 @@ fn handleNewLayerSurface(listener: *wl.Listener(*wlr.LayerSurfaceV1), wlr_layer_
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("new layer surface had null output, assigning it to output '{s}'", .{
|
log.debug("new layer surface had null output, assigning it to output '{s}'", .{output.wlr_output.name});
|
||||||
mem.sliceTo(&output.wlr_output.name, 0),
|
|
||||||
});
|
|
||||||
wlr_layer_surface.output = output.wlr_output;
|
wlr_layer_surface.output = output.wlr_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,11 +81,17 @@ pub fn create(wlr_subsurface: *wlr.Subsurface, parent: Parent) void {
|
|||||||
/// given surface when river becomes aware of the surface as we won't
|
/// given surface when river becomes aware of the surface as we won't
|
||||||
/// recieve a new_subsurface event for them.
|
/// recieve a new_subsurface event for them.
|
||||||
pub fn handleExisting(surface: *wlr.Surface, parent: Parent) void {
|
pub fn handleExisting(surface: *wlr.Surface, parent: Parent) void {
|
||||||
var below_it = surface.subsurfaces_below.iterator(.forward);
|
var below_it = surface.current.subsurfaces_below.iterator(.forward);
|
||||||
while (below_it.next()) |s| Subsurface.create(s, parent);
|
while (below_it.next()) |parent_state| {
|
||||||
|
const subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
||||||
|
Subsurface.create(subsurface, parent);
|
||||||
|
}
|
||||||
|
|
||||||
var above_it = surface.subsurfaces_above.iterator(.forward);
|
var above_it = surface.current.subsurfaces_above.iterator(.forward);
|
||||||
while (above_it.next()) |s| Subsurface.create(s, parent);
|
while (above_it.next()) |parent_state| {
|
||||||
|
const subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
||||||
|
Subsurface.create(subsurface, parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy this Subsurface and all of its children
|
/// Destroy this Subsurface and all of its children
|
||||||
@ -104,13 +110,15 @@ pub fn destroy(subsurface: *Subsurface) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroySubsurfaces(surface: *wlr.Surface) void {
|
pub fn destroySubsurfaces(surface: *wlr.Surface) void {
|
||||||
var below_it = surface.subsurfaces_below.iterator(.forward);
|
var below_it = surface.current.subsurfaces_below.iterator(.forward);
|
||||||
while (below_it.next()) |wlr_subsurface| {
|
while (below_it.next()) |parent_state| {
|
||||||
|
const wlr_subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
||||||
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
var above_it = surface.subsurfaces_above.iterator(.forward);
|
var above_it = surface.current.subsurfaces_above.iterator(.forward);
|
||||||
while (above_it.next()) |wlr_subsurface| {
|
while (above_it.next()) |parent_state| {
|
||||||
|
const wlr_subsurface = @fieldParentPtr(wlr.Subsurface, "current", parent_state);
|
||||||
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
if (@intToPtr(?*Subsurface, wlr_subsurface.data)) |s| s.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,18 +80,13 @@ pub fn init(self: *Self, view: *View, xdg_surface: *wlr.XdgSurface) void {
|
|||||||
/// Returns true if a configure must be sent to ensure that the pending
|
/// Returns true if a configure must be sent to ensure that the pending
|
||||||
/// dimensions are applied.
|
/// dimensions are applied.
|
||||||
pub fn needsConfigure(self: Self) bool {
|
pub fn needsConfigure(self: Self) bool {
|
||||||
const server_pending = &self.xdg_surface.role_data.toplevel.server_pending;
|
const scheduled = &self.xdg_surface.role_data.toplevel.scheduled;
|
||||||
const state = &self.view.pending;
|
const state = &self.view.pending;
|
||||||
|
|
||||||
// Checking server_pending is sufficient here since it will be either in
|
// We avoid a special case for newly mapped views which we have not yet
|
||||||
// sync with the current dimensions or be the dimensions sent with the
|
// configured by setting scheduled.width/height to the initial width/height
|
||||||
// most recent configure. In both cases server_pending has the values we
|
// of the view in handleMap().
|
||||||
// want to check against.
|
return state.box.width != scheduled.width or state.box.height != scheduled.height;
|
||||||
// Furthermore, we avoid a special case for newly mapped views which we
|
|
||||||
// have not yet configured by setting server_pending.width/height to the
|
|
||||||
// initial width/height of the view in handleMap().
|
|
||||||
return state.box.width != server_pending.width or
|
|
||||||
state.box.height != server_pending.height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a configure event, applying the pending state of the view.
|
/// Send a configure event, applying the pending state of the view.
|
||||||
@ -196,8 +191,8 @@ fn handleMap(listener: *wl.Listener(*wlr.XdgSurface), xdg_surface: *wlr.XdgSurfa
|
|||||||
|
|
||||||
// We initialize these to avoid special-casing newly mapped views in
|
// We initialize these to avoid special-casing newly mapped views in
|
||||||
// the check preformed in needsConfigure().
|
// the check preformed in needsConfigure().
|
||||||
toplevel.server_pending.width = @intCast(u32, initial_box.width);
|
toplevel.scheduled.width = @intCast(u32, initial_box.width);
|
||||||
toplevel.server_pending.height = @intCast(u32, initial_box.height);
|
toplevel.scheduled.height = @intCast(u32, initial_box.height);
|
||||||
|
|
||||||
view.surface = self.xdg_surface.surface;
|
view.surface = self.xdg_surface.surface;
|
||||||
view.surface_box = Box.fromWlrBox(initial_box);
|
view.surface_box = Box.fromWlrBox(initial_box);
|
||||||
|
@ -40,7 +40,7 @@ pub fn listInputs(
|
|||||||
var it = server.input_manager.input_devices.first;
|
var it = server.input_manager.input_devices.first;
|
||||||
while (it) |node| : (it = node.next) {
|
while (it) |node| : (it = node.next) {
|
||||||
const configured = for (server.input_manager.input_configs.items) |*input_config| {
|
const configured = for (server.input_manager.input_configs.items) |*input_config| {
|
||||||
if (mem.eql(u8, input_config.identifier, mem.sliceTo(node.data.identifier, 0))) {
|
if (mem.eql(u8, input_config.identifier, node.data.identifier)) {
|
||||||
break true;
|
break true;
|
||||||
}
|
}
|
||||||
} else false;
|
} else false;
|
||||||
|
@ -47,8 +47,6 @@ const SurfaceRenderData = struct {
|
|||||||
|
|
||||||
/// The rendering order in this function must be kept in sync with Cursor.surfaceAt()
|
/// The rendering order in this function must be kept in sync with Cursor.surfaceAt()
|
||||||
pub fn renderOutput(output: *Output) void {
|
pub fn renderOutput(output: *Output) void {
|
||||||
const renderer = output.wlr_output.backend.getRenderer().?;
|
|
||||||
|
|
||||||
var now: os.timespec = undefined;
|
var now: os.timespec = undefined;
|
||||||
os.clock_gettime(os.CLOCK_MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
|
os.clock_gettime(os.CLOCK_MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
|
||||||
|
|
||||||
@ -66,7 +64,7 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.begin(@intCast(u32, output.wlr_output.width), @intCast(u32, output.wlr_output.height));
|
server.renderer.begin(@intCast(u32, output.wlr_output.width), @intCast(u32, output.wlr_output.height));
|
||||||
|
|
||||||
// Find the first visible fullscreen view in the stack if there is one
|
// Find the first visible fullscreen view in the stack if there is one
|
||||||
var it = ViewStack(View).iter(output.views.first, .forward, output.current.tags, renderFilter);
|
var it = ViewStack(View).iter(output.views.first, .forward, output.current.tags, renderFilter);
|
||||||
@ -77,12 +75,12 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
// If we have a fullscreen view to render, render it.
|
// If we have a fullscreen view to render, render it.
|
||||||
if (fullscreen_view) |view| {
|
if (fullscreen_view) |view| {
|
||||||
// Always clear with solid black for fullscreen
|
// Always clear with solid black for fullscreen
|
||||||
renderer.clear(&[_]f32{ 0, 0, 0, 1 });
|
server.renderer.clear(&[_]f32{ 0, 0, 0, 1 });
|
||||||
renderView(output, view, &now);
|
renderView(output, view, &now);
|
||||||
if (build_options.xwayland) renderXwaylandUnmanaged(output, &now);
|
if (build_options.xwayland) renderXwaylandUnmanaged(output, &now);
|
||||||
} else {
|
} else {
|
||||||
// No fullscreen view, so render normal layers/views
|
// No fullscreen view, so render normal layers/views
|
||||||
renderer.clear(&server.config.background_color);
|
server.renderer.clear(&server.config.background_color);
|
||||||
|
|
||||||
renderLayer(output, output.getLayer(.background).*, &now, .toplevels);
|
renderLayer(output, output.getLayer(.background).*, &now, .toplevels);
|
||||||
renderLayer(output, output.getLayer(.bottom).*, &now, .toplevels);
|
renderLayer(output, output.getLayer(.bottom).*, &now, .toplevels);
|
||||||
@ -146,11 +144,11 @@ pub fn renderOutput(output: *Output) void {
|
|||||||
|
|
||||||
// Conclude rendering and swap the buffers, showing the final frame
|
// Conclude rendering and swap the buffers, showing the final frame
|
||||||
// on-screen.
|
// on-screen.
|
||||||
renderer.end();
|
server.renderer.end();
|
||||||
|
|
||||||
// TODO: handle failure
|
// TODO: handle failure
|
||||||
output.wlr_output.commit() catch
|
output.wlr_output.commit() catch
|
||||||
log.err("output commit failed for {s}", .{mem.sliceTo(&output.wlr_output.name, 0)});
|
log.err("output commit failed for {s}", .{output.wlr_output.name});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderFilter(view: *View, filter_tags: u32) bool {
|
fn renderFilter(view: *View, filter_tags: u32) bool {
|
||||||
@ -315,8 +313,7 @@ fn renderTexture(
|
|||||||
|
|
||||||
// This takes our matrix, the texture, and an alpha, and performs the actual
|
// This takes our matrix, the texture, and an alpha, and performs the actual
|
||||||
// rendering on the GPU.
|
// rendering on the GPU.
|
||||||
const renderer = output.wlr_output.backend.getRenderer().?;
|
server.renderer.renderSubtextureWithMatrix(texture, source_box, &matrix, 1.0) catch return;
|
||||||
renderer.renderSubtextureWithMatrix(texture, source_box, &matrix, 1.0) catch return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renderBorders(output: *const Output, view: *View, now: *os.timespec) void {
|
fn renderBorders(output: *const Output, view: *View, now: *os.timespec) void {
|
||||||
@ -361,11 +358,7 @@ fn renderBorders(output: *const Output, view: *View, now: *os.timespec) void {
|
|||||||
fn renderRect(output: *const Output, box: Box, color: *const [4]f32) void {
|
fn renderRect(output: *const Output, box: Box, color: *const [4]f32) void {
|
||||||
var wlr_box = box.toWlrBox();
|
var wlr_box = box.toWlrBox();
|
||||||
scaleBox(&wlr_box, output.wlr_output.scale);
|
scaleBox(&wlr_box, output.wlr_output.scale);
|
||||||
output.wlr_output.backend.getRenderer().?.renderRect(
|
server.renderer.renderRect(&wlr_box, color, &output.wlr_output.transform_matrix);
|
||||||
&wlr_box,
|
|
||||||
color,
|
|
||||||
&output.wlr_output.transform_matrix,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scale a wlr_box, taking the possibility of fractional scaling into account.
|
/// Scale a wlr_box, taking the possibility of fractional scaling into account.
|
||||||
|
Loading…
Reference in New Issue
Block a user