diff --git a/src/Command.zig b/src/Command.zig index a7c2e1d..58c58d3 100644 --- a/src/Command.zig +++ b/src/Command.zig @@ -28,6 +28,7 @@ const command = struct { const focusAllTags = @import("command/focus_all_tags.zig").focusAllTags; const focusOutput = @import("command/focus_output.zig").focusOutput; const focusTag = @import("command/focus_tag.zig").focusTag; + const layout = @import("command/layout.zig").layout; const modMasterCount = @import("command/mod_master_count.zig").modMasterCount; const modMasterFactor = @import("command/mod_master_factor.zig").modMasterFactor; const mode = @import("command/mode.zig").mode; @@ -101,6 +102,7 @@ const str_to_read_fn = [_]Definition{ .{ .name = "focus_all_tags", .arg_type = .none, .impl = command.focusAllTags }, .{ .name = "focus_output", .arg_type = .direction, .impl = command.focusOutput }, .{ .name = "focus_tag", .arg_type = .uint, .impl = command.focusTag }, + .{ .name = "layout", .arg_type = .str, .impl = command.layout}, .{ .name = "mod_master_count", .arg_type = .int, .impl = command.modMasterCount }, .{ .name = "mod_master_factor", .arg_type = .float, .impl = command.modMasterFactor }, .{ .name = "mode", .arg_type = .str, .impl = command.mode }, diff --git a/src/Config.zig b/src/Config.zig index a1a8b05..54eb58a 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -211,6 +211,35 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { .command = try Command.init(&[_][]const u8{ "mode", "normal" }, allocator), }); + // Change master orientation with Mod+{Up,Right,Down,Left} + try normal.keybinds.append(.{ + .keysym = c.XKB_KEY_Up, + .modifiers = mod, + .command = try Command.init(&[_][]const u8{ "layout", "TopMaster" }, allocator), + }); + try normal.keybinds.append(.{ + .keysym = c.XKB_KEY_Right, + .modifiers = mod, + .command = try Command.init(&[_][]const u8{ "layout", "RightMaster" }, allocator), + }); + try normal.keybinds.append(.{ + .keysym = c.XKB_KEY_Down, + .modifiers = mod, + .command = try Command.init(&[_][]const u8{ "layout", "BottomMaster" }, allocator), + }); + try normal.keybinds.append(.{ + .keysym = c.XKB_KEY_Left, + .modifiers = mod, + .command = try Command.init(&[_][]const u8{ "layout", "LeftMaster" }, allocator), + }); + + // Mod+f to change to Full layout + try normal.keybinds.append(.{ + .keysym = c.XKB_KEY_f, + .modifiers = mod, + .command = try Command.init(&[_][]const u8{ "layout", "Full" }, allocator), + }); + // Float views with app_id "float" try self.float_filter.append("float"); } diff --git a/src/Output.zig b/src/Output.zig index 11c467e..6dc999d 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -53,7 +53,7 @@ master_count: u32, master_factor: f64, /// Current layout of the output. -layout: Layouts, +layout: Layout, // All listeners for this output, in alphabetical order listen_destroy: c.wl_listener, @@ -61,7 +61,7 @@ listen_frame: c.wl_listener, listen_mode: c.wl_listener, // All possible layouts. -pub const Layouts = enum { +pub const Layout = enum { TopMaster, RightMaster, BottomMaster, @@ -69,6 +69,32 @@ pub const Layouts = enum { Full, }; +const LayoutName = struct { + name: []const u8, + layout: Layout, +}; + +// zig fmt: off +const layout_names = [_]LayoutName { + .{ .name = "TopMaster", .layout = Layout.TopMaster, }, + .{ .name = "RightMaster", .layout = Layout.RightMaster, }, + .{ .name = "BottomMaster", .layout = Layout.BottomMaster, }, + .{ .name = "LeftMaster", .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, diff --git a/src/command/layout.zig b/src/command/layout.zig new file mode 100644 index 0000000..f895330 --- /dev/null +++ b/src/command/layout.zig @@ -0,0 +1,29 @@ +// 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 . + +const c = @import("../c.zig"); + +const Arg = @import("../Command.zig").Arg; +const Seat = @import("../Seat.zig"); + +pub fn layout(seat: *Seat, arg: Arg) void { + const layout_name = arg.str; + const config = seat.input_manager.server.config; + seat.focused_output.layout = seat.focused_output.getLayoutByName(layout_name); + seat.focused_output.arrangeViews(); + seat.input_manager.server.root.startTransaction(); +}