aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeon Henrik Plickat <leonhenrik.plickat@stud.uni-goettingen.de>2020-08-17 23:13:16 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2020-08-18 11:00:51 +0200
commit59d6432332a8e021e56e69f0f8c1f1c184744c80 (patch)
treed60b4f6cdc75bd2a863a6bbabd5dc55594b728ef
parent340bfbd7f1b4b0e8d9bb9a5c0a14cc0b5da38e70 (diff)
downloadriver-59d6432332a8e021e56e69f0f8c1f1c184744c80.tar.gz
river-59d6432332a8e021e56e69f0f8c1f1c184744c80.tar.xz
Implement "attach-mode"
-rw-r--r--doc/riverctl.1.scd3
-rw-r--r--river/Output.zig5
-rw-r--r--river/View.zig4
-rw-r--r--river/command.zig1
-rw-r--r--river/command/attach_mode.zig41
-rw-r--r--river/view_stack.zig32
6 files changed, 84 insertions, 2 deletions
diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
index 3f32965..3b7da3c 100644
--- a/doc/riverctl.1.scd
+++ b/doc/riverctl.1.scd
@@ -95,6 +95,9 @@ that tag 1 through 9 are visible.
## CONFIGURATION COMMANDS
+*attach-mode* *top*|*bottom*
+ Configure where new views should attach in the view stack for the currently focused output.
+
*background-color* _#RRGGBB_|_#RRGGBBAA_
Set the background color.
diff --git a/river/Output.zig b/river/Output.zig
index a62c724..777d831 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -30,6 +30,7 @@ const LayerSurface = @import("LayerSurface.zig");
const Root = @import("Root.zig");
const View = @import("View.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
+const AttachMode = @import("view_stack.zig").AttachMode;
const OutputStatus = @import("OutputStatus.zig");
const State = struct {
@@ -37,6 +38,8 @@ const State = struct {
tags: u32,
};
+attach_mode: AttachMode,
+
root: *Root,
wlr_output: *c.wlr_output,
@@ -107,6 +110,8 @@ pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
self.layout = try std.mem.dupe(util.gpa, u8, "full");
+ self.attach_mode = .top;
+
self.status_trackers = std.SinglyLinkedList(OutputStatus).init();
// Set up listeners
diff --git a/river/View.zig b/river/View.zig
index d745f6d..2686b2e 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -243,7 +243,7 @@ pub fn sendToOutput(self: *Self, destination_output: *Output) void {
const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
self.output.views.remove(node);
- destination_output.views.push(node);
+ destination_output.views.attach(node, destination_output.attach_mode);
self.output.sendViewTags();
destination_output.sendViewTags();
@@ -340,7 +340,7 @@ pub fn map(self: *Self) void {
// Add the view to the stack of its output
const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
- self.output.views.push(node);
+ self.output.views.attach(node, self.output.attach_mode);
// Focus the new view, assuming the seat is focusing the proper output
// and there isn't something else like a fullscreen view grabbing focus.
diff --git a/river/command.zig b/river/command.zig
index dc6619d..7cb685e 100644
--- a/river/command.zig
+++ b/river/command.zig
@@ -30,6 +30,7 @@ const str_to_impl_fn = [_]struct {
name: []const u8,
impl: fn (*std.mem.Allocator, *Seat, []const []const u8, *?[]const u8) Error!void,
}{
+ .{ .name = "attach-mode", .impl = @import("command/attach_mode.zig").attach_mode },
.{ .name = "background-color", .impl = @import("command/config.zig").backgroundColor },
.{ .name = "border-color-focused", .impl = @import("command/config.zig").borderColorFocused },
.{ .name = "border-color-unfocused", .impl = @import("command/config.zig").borderColorUnfocused },
diff --git a/river/command/attach_mode.zig b/river/command/attach_mode.zig
new file mode 100644
index 0000000..a689893
--- /dev/null
+++ b/river/command/attach_mode.zig
@@ -0,0 +1,41 @@
+// This file is part of river, a dynamic tiling wayland compositor.
+//
+// Copyright 2020 Leon Henrik Plickat
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+const std = @import("std");
+
+const util = @import("../util.zig");
+
+const Error = @import("../command.zig").Error;
+const Seat = @import("../Seat.zig");
+
+pub fn attach_mode(
+ allocator: *std.mem.Allocator,
+ seat: *Seat,
+ args: []const []const u8,
+ out: *?[]const u8,
+) Error!void {
+ if (args.len < 2) return Error.NotEnoughArguments;
+ if (args.len > 2) return Error.TooManyArguments;
+
+ if (std.mem.eql(u8, "top", args[1])) {
+ seat.focused_output.attach_mode = .top;
+ } else if (std.mem.eql(u8, "bottom", args[1])) {
+ seat.focused_output.attach_mode = .bottom;
+ } else {
+ return Error.UnknownOption;
+ }
+}
diff --git a/river/view_stack.zig b/river/view_stack.zig
index ea344d1..eb69ebc 100644
--- a/river/view_stack.zig
+++ b/river/view_stack.zig
@@ -17,6 +17,11 @@
const View = @import("View.zig");
+pub const AttachMode = enum {
+ top,
+ bottom,
+};
+
/// A specialized doubly-linked stack that allows for filtered iteration
/// over the nodes. T must be View or *View.
pub fn ViewStack(comptime T: type) type {
@@ -64,6 +69,33 @@ pub fn ViewStack(comptime T: type) type {
self.first = new_node;
}
+ /// Add a node to the bottom of the stack.
+ pub fn append(self: *Self, new_node: *Node) void {
+ // Set the prev/next pointers of the new node
+ new_node.prev = self.last;
+ new_node.next = null;
+
+ if (self.last) |last| {
+ // If the list is not empty, set the next pointer of the current
+ // first node to the new node.
+ last.next = new_node;
+ } else {
+ // If the list is empty set the first pointer to the new node.
+ self.first = new_node;
+ }
+
+ // Set the last pointer to the new node
+ self.last = new_node;
+ }
+
+ /// Attach a node into the viewstack based on the attach mode
+ pub fn attach(self: *Self, new_node: *Node, mode: AttachMode) void {
+ switch (mode) {
+ .top => self.push(new_node),
+ .bottom => self.append(new_node),
+ }
+ }
+
/// Remove a node from the view stack. This removes it from the stack of
/// all views as well as the stack of visible ones.
pub fn remove(self: *Self, target_node: *Node) void {