aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--river/Output.zig82
1 files changed, 21 insertions, 61 deletions
diff --git a/river/Output.zig b/river/Output.zig
index 73ddae1..4ca3ead 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -61,8 +61,10 @@ master_count: u32,
/// Percentage of the total screen that the master section takes up.
master_factor: f64,
-/// Current layout of the output.
-layout: Layout,
+/// Current layout of the output. If it is "full", river will use the full
+/// layout. Otherwise river assumes it contains a string which, when executed
+/// with sh, will result in a layout.
+layout: []const u8,
/// List of status tracking objects relaying changes to this output to clients.
status_trackers: std.SinglyLinkedList(OutputStatus),
@@ -72,41 +74,6 @@ listen_destroy: c.wl_listener,
listen_frame: c.wl_listener,
listen_mode: c.wl_listener,
-// All possible layouts.
-pub const Layout = enum {
- TopMaster,
- RightMaster,
- BottomMaster,
- LeftMaster,
- Full,
-};
-
-const LayoutName = struct {
- name: []const u8,
- layout: Layout,
-};
-
-// zig fmt: off
-const layout_names = [_]LayoutName {
- .{ .name = "top-master", .layout = Layout.TopMaster, },
- .{ .name = "right-master", .layout = Layout.RightMaster, },
- .{ .name = "bottom-master", .layout = Layout.BottomMaster, },
- .{ .name = "left-master", .layout = Layout.LeftMaster, },
- .{ .name = "full", .layout = Layout.Full, },
-};
-// zig fmt: on
-
-pub fn getLayoutByName(self: Self, name: []const u8) Layout {
- for (layout_names) |current| {
- if (std.mem.eql(u8, name, current.name)) {
- return current.layout;
- }
- }
- Log.Error.log("Layout '{}' does not exist", .{name});
- // In case of error default to LeftMaster
- return Layout.LeftMaster;
-}
-
pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
// 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,
@@ -142,8 +109,7 @@ pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
self.master_factor = 0.6;
- // LeftMaster is the default layout for all outputs
- self.layout = Layout.LeftMaster;
+ self.layout = try std.fmt.allocPrint(self.root.server.allocator, "full", .{});
self.status_trackers = std.SinglyLinkedList(OutputStatus).init();
@@ -257,10 +223,8 @@ fn layoutFull(self: *Self, visible_count: u32, output_tags: u32) void {
/// and completed.
pub fn arrangeViews(self: *Self) void {
// If the output has a zero dimension, trying to arrange would cause
- // underflow and is pointless anyway
- if (self.usable_box.width == 0 or self.usable_box.height == 0) {
- return;
- }
+ // an underflow and is pointless anyway.
+ if (self.usable_box.width == 0 or self.usable_box.height == 0) return;
const output_tags = if (self.pending_focused_tags) |tags|
tags
@@ -271,30 +235,26 @@ pub fn arrangeViews(self: *Self) void {
var count: u32 = 0;
var it = ViewStack(View).pendingIterator(self.views.first, output_tags);
while (it.next()) |node| {
- if (node.view.floating) {
- continue;
- }
+ if (node.view.floating) continue;
count += 1;
}
break :blk count;
};
- // A single view should always use the maximum available space. This is
- // implemented via the "full" layout to remove the need of every single
- // layout to explicitly handle this edge case or the other edge case of
- // no visible views.
- if (visible_count <= 1) {
- layoutFull(self, visible_count, output_tags);
- return;
- }
+ if (visible_count == 0) return;
- switch (self.layout) {
- .Full => layoutFull(self, visible_count, output_tags),
- .TopMaster => layoutTopMaster(self, visible_count, output_tags),
- .RightMaster => layoutRightMaster(self, visible_count, output_tags),
- .BottomMaster => layoutBottomMaster(self, visible_count, output_tags),
- .LeftMaster => layoutLeftMaster(self, visible_count, output_tags),
- }
+ if (std.mem.eql(u8, self.layout, "full")) return layoutFull(self, visible_count, output_tags);
+
+ layoutExternal(self, visible_count, output_tags) catch |err| {
+ switch (err) {
+ LayoutError.BadExitCode => Log.Error.log("Layout command exited with non-zero return code.", .{}),
+ LayoutError.BadWindowConfiguration => Log.Error.log("Invalid window configuration.", .{}),
+ LayoutError.ConfigurationMismatch => Log.Error.log("Mismatch between amount of window configurations and visible windows.", .{}),
+ else => Log.Error.log("Encountered unexpected error while trying to use external layout.", .{}),
+ }
+ Log.Error.log("Falling back to internal layout", .{});
+ layoutFull(self, visible_count, output_tags);
+ };
}
/// Arrange all layer surfaces of this output and addjust the usable aread