Support layer shell exclusive areas again
This re-adds support for layer-shell exclusive areas (initially removed
in commit a9473204)
The Beansprout bar will now render inside the non-exclusive area and the
usable area for calculating the window layouts is based on the non-
exclusive area minus the beansprout bar's area
Implements: #13
This commit is contained in:
parent
f16f07fa26
commit
6024066488
2 changed files with 51 additions and 18 deletions
13
src/Bar.zig
13
src/Bar.zig
|
|
@ -35,6 +35,8 @@ pending_manage: PendingManage = .{},
|
||||||
pending_render: PendingRender = .{},
|
pending_render: PendingRender = .{},
|
||||||
|
|
||||||
const PendingManage = struct {
|
const PendingManage = struct {
|
||||||
|
/// Recalculate bar geometry (size and position) on the next manage cycle
|
||||||
|
/// Set when output dimensions, position, scale, or exclusive zones change
|
||||||
output_geometry: bool = false,
|
output_geometry: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -159,7 +161,10 @@ pub fn manage(bar: *Bar) !void {
|
||||||
|
|
||||||
const logical_font_height = @divFloor(bar.fcft_fonts.height, @as(i32, bar.font_scale));
|
const logical_font_height = @divFloor(bar.fcft_fonts.height, @as(i32, bar.font_scale));
|
||||||
const height: u31 = @intCast(logical_font_height + 2 * options.vertical_padding);
|
const height: u31 = @intCast(logical_font_height + 2 * options.vertical_padding);
|
||||||
const width: u31 = output.geometry.width -| @as(u31, @intCast(options.margins.left + options.margins.right));
|
// Use the non-exclusive area so the bar sits adjacent to any external layer shell
|
||||||
|
// surfaces rather than overlapping them.
|
||||||
|
const base = output.non_exclusive_area;
|
||||||
|
const width: u31 = @as(u31, @intCast(base.width)) -| @as(u31, @intCast(options.margins.left + options.margins.right));
|
||||||
|
|
||||||
if (bar.geometry.width != width or bar.geometry.height != height) {
|
if (bar.geometry.width != width or bar.geometry.height != height) {
|
||||||
bar.geometry.width = width;
|
bar.geometry.width = width;
|
||||||
|
|
@ -171,10 +176,10 @@ pub fn manage(bar: *Bar) !void {
|
||||||
bar.surfaces.wl_surface.setOpaqueRegion(opaque_region);
|
bar.surfaces.wl_surface.setOpaqueRegion(opaque_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
const x = output.geometry.x + options.margins.left;
|
const x = base.x + options.margins.left;
|
||||||
const y = switch (options.position) {
|
const y = switch (options.position) {
|
||||||
.top => output.geometry.y + options.margins.top,
|
.top => base.y + options.margins.top,
|
||||||
.bottom => output.geometry.y + output.geometry.height - bar.geometry.height - options.margins.bottom,
|
.bottom => base.y + base.height - bar.geometry.height - options.margins.bottom,
|
||||||
};
|
};
|
||||||
bar.pending_render.position = .{ .x = x, .y = y };
|
bar.pending_render.position = .{ .x = x, .y = y };
|
||||||
bar.pending_render.draw = true;
|
bar.pending_render.draw = true;
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,15 @@ wl_output: ?*wl.Output = null,
|
||||||
/// Friendly name of this output
|
/// Friendly name of this output
|
||||||
name: ?[]const u8 = null,
|
name: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Output geometry
|
|
||||||
scale: u31 = 1,
|
scale: u31 = 1,
|
||||||
|
/// The rect for the entire output, this includes space that's taken by widgets like bars and not
|
||||||
|
/// made available to windows.
|
||||||
geometry: Rect = .{},
|
geometry: Rect = .{},
|
||||||
|
|
||||||
/// Area available for window layout (output geometry minus bar space)
|
/// Output geometry minus layer shell exclusive zones
|
||||||
/// Maybe I'll re-add support for layer shell exclusive areas later,
|
non_exclusive_area: Rect = .{},
|
||||||
/// but adding that makes it more work for me and I don't personally
|
|
||||||
/// know of anything that makes me want them since external bars won't
|
/// Area available for window layout (non_exclusive_area minus bar space)
|
||||||
/// work with beansprout.
|
|
||||||
usable_geometry: Rect = .{},
|
usable_geometry: Rect = .{},
|
||||||
|
|
||||||
wallpaper: ?Wallpaper = null,
|
wallpaper: ?Wallpaper = null,
|
||||||
|
|
@ -64,6 +64,7 @@ const TagLayoutOverride = struct {
|
||||||
const PendingManage = struct {
|
const PendingManage = struct {
|
||||||
position: ?struct { x: i32, y: i32 } = null,
|
position: ?struct { x: i32, y: i32 } = null,
|
||||||
dimensions: ?struct { width: u31, height: u31 } = null,
|
dimensions: ?struct { width: u31, height: u31 } = null,
|
||||||
|
non_exclusive_area: ?Rect = null,
|
||||||
|
|
||||||
tags: ?u32 = null,
|
tags: ?u32 = null,
|
||||||
primary_ratio: ?f32 = null,
|
primary_ratio: ?f32 = null,
|
||||||
|
|
@ -106,6 +107,7 @@ pub fn create(context: *Context, river_output_v1: *river.OutputV1) !*Output {
|
||||||
output.windows.init();
|
output.windows.init();
|
||||||
|
|
||||||
output.river_output_v1.setListener(*Output, riverOutputListener, output);
|
output.river_output_v1.setListener(*Output, riverOutputListener, output);
|
||||||
|
output.river_layer_shell_output_v1.setListener(*Output, riverLayerShellOutputListener, output);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
@ -200,8 +202,28 @@ pub fn prevWindow(output: *Output, current: *Window) ?*Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for the river_output_v1 interface
|
fn riverLayerShellOutputListener(
|
||||||
fn riverOutputListener(river_output_v1: *river.OutputV1, event: river.OutputV1.Event, output: *Output) void {
|
_: *river.LayerShellOutputV1,
|
||||||
|
event: river.LayerShellOutputV1.Event,
|
||||||
|
output: *Output,
|
||||||
|
) void {
|
||||||
|
switch (event) {
|
||||||
|
.non_exclusive_area => |area| {
|
||||||
|
output.pending_manage.non_exclusive_area = .{
|
||||||
|
.x = area.x,
|
||||||
|
.y = area.y,
|
||||||
|
.width = @intCast(area.width),
|
||||||
|
.height = @intCast(area.height),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn riverOutputListener(
|
||||||
|
river_output_v1: *river.OutputV1,
|
||||||
|
event: river.OutputV1.Event,
|
||||||
|
output: *Output,
|
||||||
|
) void {
|
||||||
assert(output.river_output_v1 == river_output_v1);
|
assert(output.river_output_v1 == river_output_v1);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.removed => {
|
.removed => {
|
||||||
|
|
@ -286,7 +308,14 @@ pub fn manage(output: *Output) void {
|
||||||
output.geometry.height = dimensions.height;
|
output.geometry.height = dimensions.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.pending_manage.position != null or output.pending_manage.dimensions != null) {
|
if (output.pending_manage.non_exclusive_area) |non_exclusive_area| {
|
||||||
|
output.non_exclusive_area = non_exclusive_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.pending_manage.position != null or
|
||||||
|
output.pending_manage.dimensions != null or
|
||||||
|
output.pending_manage.non_exclusive_area != null)
|
||||||
|
{
|
||||||
if (output.wallpaper) |*wallpaper| {
|
if (output.wallpaper) |*wallpaper| {
|
||||||
wallpaper.pending_render.draw = true;
|
wallpaper.pending_render.draw = true;
|
||||||
}
|
}
|
||||||
|
|
@ -391,11 +420,10 @@ pub fn manage(output: *Output) void {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute usable geometry from output geometry minus bar space.
|
// Compute usable geometry starting from the non-exclusive area reported by the layer shell,
|
||||||
// We don't use non_exclusive_area from layer shell since we don't support
|
// then additionally subtract space for beansprout's own bar (which uses river shell, not layer
|
||||||
// other layer shell clients with exclusive zones (layer shell clients that
|
// shell, so it's not included in the exclusive zone calculation).
|
||||||
// don't use exclusive areas are fine).
|
output.usable_geometry = output.non_exclusive_area;
|
||||||
output.usable_geometry = output.geometry;
|
|
||||||
if (output.bar) |bar| {
|
if (output.bar) |bar| {
|
||||||
if (bar.geometry.height > 0) {
|
if (bar.geometry.height > 0) {
|
||||||
const bar_height: i32 = bar.geometry.height;
|
const bar_height: i32 = bar.geometry.height;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue