From cee41e925dc0a9d7460806c9f8386512b207edf3 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 19 May 2020 22:59:50 +0200 Subject: Implement command execution through riverctl --- src/Command.zig | 141 +++++++++++++++++++++++++++++++++++ src/Config.zig | 77 ++++++++----------- src/Keybind.zig | 5 +- src/Mode.zig | 1 + src/Seat.zig | 2 +- src/Server.zig | 1 + src/WindowManagement.zig | 11 ++- src/command.zig | 50 ------------- src/command/close.zig | 30 ++++++++ src/command/close_view.zig | 30 -------- src/command/exit.zig | 26 +++++++ src/command/exit_compositor.zig | 26 ------- src/command/focus.zig | 54 ++++++++++++++ src/command/focus_all_tags.zig | 25 +++++++ src/command/focus_output.zig | 2 +- src/command/focus_tag.zig | 26 +++++++ src/command/focus_tags.zig | 28 ------- src/command/focus_view.zig | 54 -------------- src/command/mod_master_count.zig | 34 +++++++++ src/command/mod_master_factor.zig | 37 +++++++++ src/command/mode.zig | 2 +- src/command/modify_master_count.zig | 34 --------- src/command/modify_master_factor.zig | 37 --------- src/command/send_to_output.zig | 2 +- src/command/set_view_tags.zig | 32 -------- src/command/spawn.zig | 2 +- src/command/tag_view.zig | 32 ++++++++ src/command/tag_view_all_tags.zig | 31 ++++++++ src/command/toggle_float.zig | 2 +- src/command/toggle_tag_focus.zig | 32 ++++++++ src/command/toggle_tags.zig | 32 -------- src/command/toggle_view_tag.zig | 33 ++++++++ src/command/toggle_view_tags.zig | 33 -------- src/command/zoom.zig | 2 +- 34 files changed, 550 insertions(+), 416 deletions(-) create mode 100644 src/Command.zig delete mode 100644 src/command.zig create mode 100644 src/command/close.zig delete mode 100644 src/command/close_view.zig create mode 100644 src/command/exit.zig delete mode 100644 src/command/exit_compositor.zig create mode 100644 src/command/focus.zig create mode 100644 src/command/focus_all_tags.zig create mode 100644 src/command/focus_tag.zig delete mode 100644 src/command/focus_tags.zig delete mode 100644 src/command/focus_view.zig create mode 100644 src/command/mod_master_count.zig create mode 100644 src/command/mod_master_factor.zig delete mode 100644 src/command/modify_master_count.zig delete mode 100644 src/command/modify_master_factor.zig delete mode 100644 src/command/set_view_tags.zig create mode 100644 src/command/tag_view.zig create mode 100644 src/command/tag_view_all_tags.zig create mode 100644 src/command/toggle_tag_focus.zig delete mode 100644 src/command/toggle_tags.zig create mode 100644 src/command/toggle_view_tag.zig delete mode 100644 src/command/toggle_view_tags.zig (limited to 'src') diff --git a/src/Command.zig b/src/Command.zig new file mode 100644 index 0000000..a7c2e1d --- /dev/null +++ b/src/Command.zig @@ -0,0 +1,141 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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 Self = @This(); + +const std = @import("std"); + +const Seat = @import("Seat.zig"); + +const command = struct { + const close = @import("command/close.zig").close; + const exit = @import("command/exit.zig").exit; + const focus = @import("command/focus.zig").focus; + 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 modMasterCount = @import("command/mod_master_count.zig").modMasterCount; + const modMasterFactor = @import("command/mod_master_factor.zig").modMasterFactor; + const mode = @import("command/mode.zig").mode; + const sendToOutput = @import("command/send_to_output.zig").sendToOutput; + const spawn = @import("command/spawn.zig").spawn; + const tagView = @import("command/tag_view.zig").tagView; + const tagViewAllTags = @import("command/tag_view_all_tags.zig").tagViewAllTags; + const toggleFloat = @import("command/toggle_float.zig").toggleFloat; + const toggleTagFocus = @import("command/toggle_tag_focus.zig").toggleTagFocus; + const toggleViewTag = @import("command/toggle_view_tag.zig").toggleViewTag; + const zoom = @import("command/zoom.zig").zoom; +}; + +const Direction = enum { + Next, + Prev, +}; + +pub const Arg = union(enum) { + int: i32, + uint: u32, + float: f64, + str: []const u8, + direction: Direction, + none: void, + + fn parse( + arg_type: @TagType(Arg), + args: []const []const u8, + allocator: *std.mem.Allocator, + ) !Arg { + switch (arg_type) { + .int, .uint, .float, .direction => { + if (args.len == 0) return error.NotEnoughArguments; + if (args.len > 1) return error.TooManyArguments; + return switch (arg_type) { + .int => .{ .int = try std.fmt.parseInt(i32, args[0], 10) }, + .uint => .{ .uint = try std.fmt.parseInt(u32, args[0], 10) }, + .float => .{ .float = try std.fmt.parseFloat(f64, args[0]) }, + .direction => if (std.mem.eql(u8, args[0], "next")) + Arg{ .direction = .Next } + else if (std.mem.eql(u8, args[0], "previous")) + Arg{ .direction = .Prev } + else + error.InvalidDirection, + else => unreachable, + }; + }, + .str => { + if (args.len == 0) return error.NotEnoughArguments; + return Arg{ .str = try std.mem.join(allocator, " ", args) }; + }, + .none => return if (args.len == 0) .{ .none = {} } else error.TooManyArguments, + } + } +}; + +const ImplFn = fn (seat: *Seat, arg: Arg) void; + +const Definition = struct { + name: []const u8, + arg_type: @TagType(Arg), + impl: ImplFn, +}; + +// zig fmt: off +const str_to_read_fn = [_]Definition{ + .{ .name = "close", .arg_type = .none, .impl = command.close }, + .{ .name = "exit", .arg_type = .none, .impl = command.exit }, + .{ .name = "focus", .arg_type = .direction, .impl = command.focus }, + .{ .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 = "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 }, + .{ .name = "send_to_output", .arg_type = .direction, .impl = command.sendToOutput }, + .{ .name = "spawn", .arg_type = .str, .impl = command.spawn }, + .{ .name = "tag_view", .arg_type = .uint, .impl = command.tagView }, + .{ .name = "tag_view_all_tags", .arg_type = .none, .impl = command.tagViewAllTags }, + .{ .name = "toggle_float", .arg_type = .none, .impl = command.toggleFloat }, + .{ .name = "toggle_tag_focus", .arg_type = .uint, .impl = command.toggleTagFocus }, + .{ .name = "toggle_view_tag", .arg_type = .uint, .impl = command.toggleViewTag }, + .{ .name = "zoom", .arg_type = .none, .impl = command.zoom }, +}; +// zig fmt: on + +impl: ImplFn, +arg: Arg, + +pub fn init(args: []const []const u8, allocator: *std.mem.Allocator) !Self { + if (args.len == 0) return error.NoCommand; + const name = args[0]; + + const definition = for (str_to_read_fn) |definition| { + if (std.mem.eql(u8, name, definition.name)) break definition; + } else return error.UnknownCommand; + + return Self{ + .impl = definition.impl, + .arg = try Arg.parse(definition.arg_type, args[1..], allocator), + }; +} + +pub fn deinit(self: Self, allocator: *std.mem.Allocator) void { + if (self.arg == .str) allocator.free(self.arg.str); +} + +pub fn run(self: Self, seat: *Seat) void { + self.impl(seat, self.arg); +} diff --git a/src/Config.zig b/src/Config.zig index 85c9b32..a1a8b05 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -20,8 +20,8 @@ const Self = @This(); const std = @import("std"); const c = @import("c.zig"); -const command = @import("command.zig"); +const Command = @import("Command.zig"); const Log = @import("log.zig").Log; const Mode = @import("Mode.zig"); const Server = @import("Server.zig"); @@ -58,38 +58,33 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try normal.keybinds.append(.{ .keysym = c.XKB_KEY_Return, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.spawn, - .arg = .{ .str = "alacritty" }, + .command = try Command.init(&[_][]const u8{ "spawn", "alacritty" }, allocator), }); // Mod+Q to close the focused view try normal.keybinds.append(.{ .keysym = c.XKB_KEY_q, .modifiers = mod, - .command = command.close_view, - .arg = .{ .none = {} }, + .command = try Command.init(&[_][]const u8{"close"}, allocator), }); // Mod+E to exit river try normal.keybinds.append(.{ .keysym = c.XKB_KEY_e, .modifiers = mod, - .command = command.exitCompositor, - .arg = .{ .none = {} }, + .command = try Command.init(&[_][]const u8{"exit"}, allocator), }); // Mod+J and Mod+K to focus the next/previous view in the layout stack try normal.keybinds.append(.{ .keysym = c.XKB_KEY_j, .modifiers = mod, - .command = command.focusView, - .arg = .{ .direction = .Next }, + .command = try Command.init(&[_][]const u8{ "focus", "next" }, allocator), }); try normal.keybinds.append(.{ .keysym = c.XKB_KEY_k, .modifiers = mod, - .command = command.focusView, - .arg = .{ .direction = .Prev }, + .command = try Command.init(&[_][]const u8{ "focus", "previous" }, allocator), }); // Mod+Return to bump the focused view to the top of the layout stack, @@ -97,22 +92,19 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try normal.keybinds.append(.{ .keysym = c.XKB_KEY_Return, .modifiers = mod, - .command = command.zoom, - .arg = .{ .none = {} }, + .command = try Command.init(&[_][]const u8{"zoom"}, allocator), }); // Mod+H and Mod+L to increase/decrease the width of the master column try normal.keybinds.append(.{ .keysym = c.XKB_KEY_h, .modifiers = mod, - .command = command.modifyMasterFactor, - .arg = .{ .float = 0.05 }, + .command = try Command.init(&[_][]const u8{ "mod_master_factor", "+0.05" }, allocator), }); try normal.keybinds.append(.{ .keysym = c.XKB_KEY_l, .modifiers = mod, - .command = command.modifyMasterFactor, - .arg = .{ .float = -0.05 }, + .command = try Command.init(&[_][]const u8{ "mod_master_factor", "-0.05" }, allocator), }); // Mod+Shift+H and Mod+Shift+L to increment/decrement the number of @@ -120,45 +112,40 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try normal.keybinds.append(.{ .keysym = c.XKB_KEY_h, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.modifyMasterCount, - .arg = .{ .int = 1 }, + .command = try Command.init(&[_][]const u8{ "mod_master_count", "+1" }, allocator), }); try normal.keybinds.append(.{ .keysym = c.XKB_KEY_l, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.modifyMasterCount, - .arg = .{ .int = -1 }, + .command = try Command.init(&[_][]const u8{ "mod_master_count", "+1" }, allocator), }); comptime var i = 0; inline while (i < 9) : (i += 1) { + const str = &[_]u8{i + '0' + 1}; // Mod+[1-9] to focus tag [1-9] try normal.keybinds.append(.{ .keysym = c.XKB_KEY_1 + i, .modifiers = mod, - .command = command.focusTags, - .arg = .{ .uint = 1 << i }, + .command = try Command.init(&[_][]const u8{ "focus_tag", str }, allocator), }); // Mod+Shift+[1-9] to tag focused view with tag [1-9] try normal.keybinds.append(.{ .keysym = c.XKB_KEY_1 + i, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.setViewTags, - .arg = .{ .uint = 1 << i }, + .command = try Command.init(&[_][]const u8{ "tag_view", str }, allocator), }); // Mod+Ctrl+[1-9] to toggle focus of tag [1-9] try normal.keybinds.append(.{ .keysym = c.XKB_KEY_1 + i, .modifiers = mod | c.WLR_MODIFIER_CTRL, - .command = command.toggleTags, - .arg = .{ .uint = 1 << i }, + .command = try Command.init(&[_][]const u8{ "toggle_tag_focus", str }, allocator), }); // Mod+Shift+Ctrl+[1-9] to toggle tag [1-9] of focused view try normal.keybinds.append(.{ .keysym = c.XKB_KEY_1 + i, .modifiers = mod | c.WLR_MODIFIER_CTRL | c.WLR_MODIFIER_SHIFT, - .command = command.toggleViewTags, - .arg = .{ .uint = 1 << i }, + .command = try Command.init(&[_][]const u8{ "toggle_view_tag", str }, allocator), }); } @@ -166,30 +153,26 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try normal.keybinds.append(.{ .keysym = c.XKB_KEY_0, .modifiers = mod, - .command = command.focusTags, - .arg = .{ .uint = 0xFFFFFFFF }, + .command = try Command.init(&[_][]const u8{"focus_all_tags"}, allocator), }); // Mod+Shift+0 to tag focused view with all tags try normal.keybinds.append(.{ .keysym = c.XKB_KEY_0, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.setViewTags, - .arg = .{ .uint = 0xFFFFFFFF }, + .command = try Command.init(&[_][]const u8{"tag_view_all_tags"}, allocator), }); // Mod+Period and Mod+Comma to focus the next/previous output try normal.keybinds.append(.{ .keysym = c.XKB_KEY_period, .modifiers = mod, - .command = command.focusOutput, - .arg = .{ .direction = .Next }, + .command = try Command.init(&[_][]const u8{ "focus_output", "next" }, allocator), }); try normal.keybinds.append(.{ .keysym = c.XKB_KEY_comma, .modifiers = mod, - .command = command.focusOutput, - .arg = .{ .direction = .Prev }, + .command = try Command.init(&[_][]const u8{ "focus_output", "previous" }, allocator), }); // Mod+Shift+Period/Comma to send the focused view to the the @@ -197,30 +180,26 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try normal.keybinds.append(.{ .keysym = c.XKB_KEY_period, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.sendToOutput, - .arg = .{ .direction = .Next }, + .command = try Command.init(&[_][]const u8{ "send_to_output", "next" }, allocator), }); try normal.keybinds.append(.{ .keysym = c.XKB_KEY_comma, .modifiers = mod | c.WLR_MODIFIER_SHIFT, - .command = command.sendToOutput, - .arg = .{ .direction = .Prev }, + .command = try Command.init(&[_][]const u8{ "send_to_output", "previous" }, allocator), }); // Mod+Space to toggle float try normal.keybinds.append(.{ .keysym = c.XKB_KEY_space, .modifiers = mod, - .command = command.toggleFloat, - .arg = .{ .none = {} }, + .command = try Command.init(&[_][]const u8{"toggle_float"}, allocator), }); // Mod+F11 to enter passthrough mode try normal.keybinds.append(.{ .keysym = c.XKB_KEY_F11, .modifiers = mod, - .command = command.mode, - .arg = .{ .str = "passthrough" }, + .command = try Command.init(&[_][]const u8{ "mode", "passthrough" }, allocator), }); try self.modes.append(try Mode.init("passthrough", allocator)); @@ -229,14 +208,18 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { try self.modes.items[1].keybinds.append(.{ .keysym = c.XKB_KEY_F11, .modifiers = mod, - .command = command.mode, - .arg = .{ .str = "normal" }, + .command = try Command.init(&[_][]const u8{ "mode", "normal" }, allocator), }); // Float views with app_id "float" try self.float_filter.append("float"); } +pub fn deinit(self: Self, allocator: *std.mem.Allocator) void { + for (self.modes.items) |*mode| mode.deinit(); + self.modes.deinit(); +} + pub fn getMode(self: Self, name: []const u8) *Mode { for (self.modes.items) |*mode| if (std.mem.eql(u8, mode.name, name)) return mode; diff --git a/src/Keybind.zig b/src/Keybind.zig index 9a156ad..d82be7a 100644 --- a/src/Keybind.zig +++ b/src/Keybind.zig @@ -16,9 +16,8 @@ // along with this program. If not, see . const c = @import("c.zig"); -const command = @import("command.zig"); +const Command = @import("Command.zig"); keysym: c.xkb_keysym_t, modifiers: u32, -command: command.Command, -arg: command.Arg, +command: Command, diff --git a/src/Mode.zig b/src/Mode.zig index 9210db6..dfc4f54 100644 --- a/src/Mode.zig +++ b/src/Mode.zig @@ -38,5 +38,6 @@ pub fn init(name: []const u8, allocator: *std.mem.Allocator) !Self { pub fn deinit(self: Self) void { const allocator = self.keybinds.allocator; allocator.free(self.name); + for (self.keybinds.items) |keybind| keybind.command.deinit(allocator); self.keybinds.deinit(); } diff --git a/src/Seat.zig b/src/Seat.zig index c697010..3ff3667 100644 --- a/src/Seat.zig +++ b/src/Seat.zig @@ -252,7 +252,7 @@ pub fn handleKeybinding(self: *Self, keysym: c.xkb_keysym_t, modifiers: u32) boo for (self.mode.keybinds.items) |keybind| { if (modifiers == keybind.modifiers and keysym == keybind.keysym) { // Execute the bound command - keybind.command(self, keybind.arg); + keybind.command.run(self); return true; } } diff --git a/src/Server.zig b/src/Server.zig index 622b76f..a75ead0 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -143,6 +143,7 @@ pub fn deinit(self: *Self) void { c.wl_display_destroy(self.wl_display); self.input_manager.deinit(); self.root.deinit(); + self.config.deinit(self.allocator); } /// Create the socket, set WAYLAND_DISPLAY, and start the backend diff --git a/src/WindowManagement.zig b/src/WindowManagement.zig index 7c14838..c95aa23 100644 --- a/src/WindowManagement.zig +++ b/src/WindowManagement.zig @@ -21,6 +21,7 @@ const std = @import("std"); const c = @import("c.zig"); +const Command = @import("Command.zig"); const Log = @import("log.zig").Log; const Server = @import("Server.zig"); @@ -73,15 +74,15 @@ fn resourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void { // TODO } -fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ?*c.wl_array) callconv(.C) void { +fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, wl_array: ?*c.wl_array) callconv(.C) void { const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); const allocator = self.server.allocator; var args = std.ArrayList([]const u8).init(allocator); var i: usize = 0; - const data = @ptrCast([*]const u8, command.?.data); - while (i < command.?.size) { + const data = @ptrCast([*]const u8, wl_array.?.data); + while (i < wl_array.?.size) { const slice = std.mem.spanZ(@ptrCast([*:0]const u8, &data[i])); args.append(std.mem.dupe(allocator, u8, slice) catch unreachable) catch unreachable; @@ -91,4 +92,8 @@ fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ? for (args.items) |x| { std.debug.warn("{}\n", .{x}); } + + // TODO: send the error event on failure instead of crashing + const command = Command.init(args.items, allocator) catch unreachable; + command.run(self.server.input_manager.default_seat); } diff --git a/src/command.zig b/src/command.zig deleted file mode 100644 index 95baf20..0000000 --- a/src/command.zig +++ /dev/null @@ -1,50 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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 Seat = @import("Seat.zig"); - -pub const Direction = enum { - Next, - Prev, -}; - -pub const Arg = union { - int: i32, - uint: u32, - float: f64, - str: []const u8, - direction: Direction, - none: void, -}; - -pub const Command = fn (seat: *Seat, arg: Arg) void; - -pub usingnamespace @import("command/close_view.zig"); -pub usingnamespace @import("command/exit_compositor.zig"); -pub usingnamespace @import("command/focus_output.zig"); -pub usingnamespace @import("command/focus_tags.zig"); -pub usingnamespace @import("command/focus_view.zig"); -pub usingnamespace @import("command/mode.zig"); -pub usingnamespace @import("command/modify_master_count.zig"); -pub usingnamespace @import("command/modify_master_factor.zig"); -pub usingnamespace @import("command/send_to_output.zig"); -pub usingnamespace @import("command/set_view_tags.zig"); -pub usingnamespace @import("command/spawn.zig"); -pub usingnamespace @import("command/toggle_float.zig"); -pub usingnamespace @import("command/toggle_tags.zig"); -pub usingnamespace @import("command/toggle_view_tags.zig"); -pub usingnamespace @import("command/zoom.zig"); diff --git a/src/command/close.zig b/src/command/close.zig new file mode 100644 index 0000000..c5be01c --- /dev/null +++ b/src/command/close.zig @@ -0,0 +1,30 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Close the focused view, if any. +pub fn close(seat: *Seat, arg: Arg) void { + if (seat.focused_view) |view| { + // Note: we don't call arrange() here as it will be called + // automatically when the view is unmapped. + view.close(); + } +} diff --git a/src/command/close_view.zig b/src/command/close_view.zig deleted file mode 100644 index 7bee0b6..0000000 --- a/src/command/close_view.zig +++ /dev/null @@ -1,30 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Close the focused view, if any. -pub fn close_view(seat: *Seat, arg: Arg) void { - if (seat.focused_view) |view| { - // Note: we don't call arrange() here as it will be called - // automatically when the view is unmapped. - view.close(); - } -} diff --git a/src/command/exit.zig b/src/command/exit.zig new file mode 100644 index 0000000..799b12c --- /dev/null +++ b/src/command/exit.zig @@ -0,0 +1,26 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Exit the compositor, terminating the wayland session. +pub fn exit(seat: *Seat, arg: Arg) void { + c.wl_display_terminate(seat.input_manager.server.wl_display); +} diff --git a/src/command/exit_compositor.zig b/src/command/exit_compositor.zig deleted file mode 100644 index 7736452..0000000 --- a/src/command/exit_compositor.zig +++ /dev/null @@ -1,26 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Exit the compositor, terminating the wayland session. -pub fn exitCompositor(seat: *Seat, arg: Arg) void { - c.wl_display_terminate(seat.input_manager.server.wl_display); -} diff --git a/src/command/focus.zig b/src/command/focus.zig new file mode 100644 index 0000000..930a36c --- /dev/null +++ b/src/command/focus.zig @@ -0,0 +1,54 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); +const View = @import("../View.zig"); +const ViewStack = @import("../view_stack.zig").ViewStack; + +/// Focus either the next or the previous visible view, depending on the enum +/// passed. Does nothing if there are 1 or 0 views in the stack. +pub fn focus(seat: *Seat, arg: Arg) void { + const direction = arg.direction; + const output = seat.focused_output; + if (seat.focused_view) |current_focus| { + // If there is a currently focused view, focus the next visible view in the stack. + const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus); + var it = switch (direction) { + .Next => ViewStack(View).iterator(focused_node, output.current_focused_tags), + .Prev => ViewStack(View).reverseIterator(focused_node, output.current_focused_tags), + }; + + // Skip past the focused node + _ = it.next(); + // Focus the next visible node if there is one + if (it.next()) |node| { + seat.focus(&node.view); + return; + } + } + + // There is either no currently focused view or the last visible view in the + // stack is focused and we need to wrap. + var it = switch (direction) { + .Next => ViewStack(View).iterator(output.views.first, output.current_focused_tags), + .Prev => ViewStack(View).reverseIterator(output.views.last, output.current_focused_tags), + }; + seat.focus(if (it.next()) |node| &node.view else null); +} diff --git a/src/command/focus_all_tags.zig b/src/command/focus_all_tags.zig new file mode 100644 index 0000000..d2eef88 --- /dev/null +++ b/src/command/focus_all_tags.zig @@ -0,0 +1,25 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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 Arg = @import("../Command.zig").Arg; +const Seat = @import("../Seat.zig"); + +/// Set focus to all tags +pub fn focusAllTags(seat: *Seat, arg: Arg) void { + seat.focused_output.pending_focused_tags = 0xFFFFFFFF; + seat.input_manager.server.root.arrange(); +} diff --git a/src/command/focus_output.zig b/src/command/focus_output.zig index 5140943..02b7999 100644 --- a/src/command/focus_output.zig +++ b/src/command/focus_output.zig @@ -19,7 +19,7 @@ const std = @import("std"); const c = @import("../c.zig"); -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Output = @import("../Output.zig"); const Seat = @import("../Seat.zig"); diff --git a/src/command/focus_tag.zig b/src/command/focus_tag.zig new file mode 100644 index 0000000..edb3292 --- /dev/null +++ b/src/command/focus_tag.zig @@ -0,0 +1,26 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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 Arg = @import("../Command.zig").Arg; +const Seat = @import("../Seat.zig"); + +/// Switch focus to the passed tag. +pub fn focusTag(seat: *Seat, arg: Arg) void { + const tags = @as(u32, 1) << @intCast(u5, arg.uint - 1); + seat.focused_output.pending_focused_tags = tags; + seat.input_manager.server.root.arrange(); +} diff --git a/src/command/focus_tags.zig b/src/command/focus_tags.zig deleted file mode 100644 index aa29b7c..0000000 --- a/src/command/focus_tags.zig +++ /dev/null @@ -1,28 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Switch focus to the passed tags. -pub fn focusTags(seat: *Seat, arg: Arg) void { - const tags = arg.uint; - seat.focused_output.pending_focused_tags = tags; - seat.input_manager.server.root.arrange(); -} diff --git a/src/command/focus_view.zig b/src/command/focus_view.zig deleted file mode 100644 index 225fa5e..0000000 --- a/src/command/focus_view.zig +++ /dev/null @@ -1,54 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); -const View = @import("../View.zig"); -const ViewStack = @import("../view_stack.zig").ViewStack; - -/// Focus either the next or the previous visible view, depending on the enum -/// passed. Does nothing if there are 1 or 0 views in the stack. -pub fn focusView(seat: *Seat, arg: Arg) void { - const direction = arg.direction; - const output = seat.focused_output; - if (seat.focused_view) |current_focus| { - // If there is a currently focused view, focus the next visible view in the stack. - const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus); - var it = switch (direction) { - .Next => ViewStack(View).iterator(focused_node, output.current_focused_tags), - .Prev => ViewStack(View).reverseIterator(focused_node, output.current_focused_tags), - }; - - // Skip past the focused node - _ = it.next(); - // Focus the next visible node if there is one - if (it.next()) |node| { - seat.focus(&node.view); - return; - } - } - - // There is either no currently focused view or the last visible view in the - // stack is focused and we need to wrap. - var it = switch (direction) { - .Next => ViewStack(View).iterator(output.views.first, output.current_focused_tags), - .Prev => ViewStack(View).reverseIterator(output.views.last, output.current_focused_tags), - }; - seat.focus(if (it.next()) |node| &node.view else null); -} diff --git a/src/command/mod_master_count.zig b/src/command/mod_master_count.zig new file mode 100644 index 0000000..bd2fde0 --- /dev/null +++ b/src/command/mod_master_count.zig @@ -0,0 +1,34 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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 std = @import("std"); + +const c = @import("../c.zig"); + +const Arg = @import("../Command.zig").Arg; +const Seat = @import("../Seat.zig"); + +/// Modify the number of master views +pub fn modMasterCount(seat: *Seat, arg: Arg) void { + const delta = arg.int; + const output = seat.focused_output; + output.master_count = @intCast( + u32, + std.math.max(0, @intCast(i32, output.master_count) + delta), + ); + seat.input_manager.server.root.arrange(); +} diff --git a/src/command/mod_master_factor.zig b/src/command/mod_master_factor.zig new file mode 100644 index 0000000..2e2a73c --- /dev/null +++ b/src/command/mod_master_factor.zig @@ -0,0 +1,37 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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 std = @import("std"); + +const c = @import("../c.zig"); + +const Arg = @import("../Command.zig").Arg; +const Seat = @import("../Seat.zig"); + +/// Modify the percent of the width of the screen that the master views occupy. +pub fn modMasterFactor(seat: *Seat, arg: Arg) void { + const delta = arg.float; + const output = seat.focused_output; + const new_master_factor = std.math.min( + std.math.max(output.master_factor + delta, 0.05), + 0.95, + ); + if (new_master_factor != output.master_factor) { + output.master_factor = new_master_factor; + seat.input_manager.server.root.arrange(); + } +} diff --git a/src/command/mode.zig b/src/command/mode.zig index cf0d709..706533c 100644 --- a/src/command/mode.zig +++ b/src/command/mode.zig @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Seat = @import("../Seat.zig"); /// Switch to the given mode diff --git a/src/command/modify_master_count.zig b/src/command/modify_master_count.zig deleted file mode 100644 index c7a5ac1..0000000 --- a/src/command/modify_master_count.zig +++ /dev/null @@ -1,34 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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 std = @import("std"); - -const c = @import("../c.zig"); - -const Arg = @import("../command.zig").Arg; -const Seat = @import("../Seat.zig"); - -/// Modify the number of master views -pub fn modifyMasterCount(seat: *Seat, arg: Arg) void { - const delta = arg.int; - const output = seat.focused_output; - output.master_count = @intCast( - u32, - std.math.max(0, @intCast(i32, output.master_count) + delta), - ); - seat.input_manager.server.root.arrange(); -} diff --git a/src/command/modify_master_factor.zig b/src/command/modify_master_factor.zig deleted file mode 100644 index b2af06f..0000000 --- a/src/command/modify_master_factor.zig +++ /dev/null @@ -1,37 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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 std = @import("std"); - -const c = @import("../c.zig"); - -const Arg = @import("../command.zig").Arg; -const Seat = @import("../Seat.zig"); - -/// Modify the percent of the width of the screen that the master views occupy. -pub fn modifyMasterFactor(seat: *Seat, arg: Arg) void { - const delta = arg.float; - const output = seat.focused_output; - const new_master_factor = std.math.min( - std.math.max(output.master_factor + delta, 0.05), - 0.95, - ); - if (new_master_factor != output.master_factor) { - output.master_factor = new_master_factor; - seat.input_manager.server.root.arrange(); - } -} diff --git a/src/command/send_to_output.zig b/src/command/send_to_output.zig index f0658ca..7e0bbbf 100644 --- a/src/command/send_to_output.zig +++ b/src/command/send_to_output.zig @@ -19,7 +19,7 @@ const std = @import("std"); const c = @import("../c.zig"); -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Output = @import("../Output.zig"); const Seat = @import("../Seat.zig"); diff --git a/src/command/set_view_tags.zig b/src/command/set_view_tags.zig deleted file mode 100644 index 562d311..0000000 --- a/src/command/set_view_tags.zig +++ /dev/null @@ -1,32 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Set the tags of the focused view. -pub fn setViewTags(seat: *Seat, arg: Arg) void { - const tags = arg.uint; - if (seat.focused_view) |view| { - if (view.current_tags != tags) { - view.pending_tags = tags; - seat.input_manager.server.root.arrange(); - } - } -} diff --git a/src/command/spawn.zig b/src/command/spawn.zig index 53566fa..61aedab 100644 --- a/src/command/spawn.zig +++ b/src/command/spawn.zig @@ -19,7 +19,7 @@ const std = @import("std"); const c = @import("../c.zig"); -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Log = @import("../log.zig").Log; const Seat = @import("../Seat.zig"); diff --git a/src/command/tag_view.zig b/src/command/tag_view.zig new file mode 100644 index 0000000..fd74285 --- /dev/null +++ b/src/command/tag_view.zig @@ -0,0 +1,32 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Set the tag of the focused view. +pub fn tagView(seat: *Seat, arg: Arg) void { + const tags = @as(u32, 1) << @intCast(u5, arg.uint - 1); + if (seat.focused_view) |view| { + if (view.current_tags != tags) { + view.pending_tags = tags; + seat.input_manager.server.root.arrange(); + } + } +} diff --git a/src/command/tag_view_all_tags.zig b/src/command/tag_view_all_tags.zig new file mode 100644 index 0000000..1b93233 --- /dev/null +++ b/src/command/tag_view_all_tags.zig @@ -0,0 +1,31 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Tag the focused view with all tags. +pub fn tagViewAllTags(seat: *Seat, arg: Arg) void { + if (seat.focused_view) |view| { + if (view.current_tags != 0xFFFFFFFF) { + view.pending_tags = 0xFFFFFFFF; + seat.input_manager.server.root.arrange(); + } + } +} diff --git a/src/command/toggle_float.zig b/src/command/toggle_float.zig index 27e3186..e890d73 100644 --- a/src/command/toggle_float.zig +++ b/src/command/toggle_float.zig @@ -17,7 +17,7 @@ const c = @import("../c.zig"); -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Seat = @import("../Seat.zig"); /// Make the focused view float or stop floating, depending on its current diff --git a/src/command/toggle_tag_focus.zig b/src/command/toggle_tag_focus.zig new file mode 100644 index 0000000..8a1a707 --- /dev/null +++ b/src/command/toggle_tag_focus.zig @@ -0,0 +1,32 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Toggle focus of the passsed tags. +pub fn toggleTagFocus(seat: *Seat, arg: Arg) void { + const tags = @as(u32, 1) << @intCast(u5, arg.uint - 1); + const output = seat.focused_output; + const new_focused_tags = output.current_focused_tags ^ tags; + if (new_focused_tags != 0) { + output.pending_focused_tags = new_focused_tags; + seat.input_manager.server.root.arrange(); + } +} diff --git a/src/command/toggle_tags.zig b/src/command/toggle_tags.zig deleted file mode 100644 index 2d9f86e..0000000 --- a/src/command/toggle_tags.zig +++ /dev/null @@ -1,32 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Toggle focus of the passsed tags. -pub fn toggleTags(seat: *Seat, arg: Arg) void { - const tags = arg.uint; - const output = seat.focused_output; - const new_focused_tags = output.current_focused_tags ^ tags; - if (new_focused_tags != 0) { - output.pending_focused_tags = new_focused_tags; - seat.input_manager.server.root.arrange(); - } -} diff --git a/src/command/toggle_view_tag.zig b/src/command/toggle_view_tag.zig new file mode 100644 index 0000000..fa869b5 --- /dev/null +++ b/src/command/toggle_view_tag.zig @@ -0,0 +1,33 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 Isaac Freund +// +// 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"); + +/// Toggle the passed tag of the focused view +pub fn toggleViewTag(seat: *Seat, arg: Arg) void { + const tags = @as(u32, 1) << @intCast(u5, arg.uint - 1); + if (seat.focused_view) |view| { + const new_tags = view.current_tags ^ tags; + if (new_tags != 0) { + view.pending_tags = new_tags; + seat.input_manager.server.root.arrange(); + } + } +} diff --git a/src/command/toggle_view_tags.zig b/src/command/toggle_view_tags.zig deleted file mode 100644 index 2f5ba3e..0000000 --- a/src/command/toggle_view_tags.zig +++ /dev/null @@ -1,33 +0,0 @@ -// This file is part of river, a dynamic tiling wayland compositor. -// -// Copyright 2020 Isaac Freund -// -// 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"); - -/// Toggle the passed tags of the focused view -pub fn toggleViewTags(seat: *Seat, arg: Arg) void { - const tags = arg.uint; - if (seat.focused_view) |view| { - const new_tags = view.current_tags ^ tags; - if (new_tags != 0) { - view.pending_tags = new_tags; - seat.input_manager.server.root.arrange(); - } - } -} diff --git a/src/command/zoom.zig b/src/command/zoom.zig index b1f7ba6..b603a69 100644 --- a/src/command/zoom.zig +++ b/src/command/zoom.zig @@ -17,7 +17,7 @@ const c = @import("../c.zig"); -const Arg = @import("../command.zig").Arg; +const Arg = @import("../Command.zig").Arg; const Seat = @import("../Seat.zig"); const View = @import("../View.zig"); const ViewStack = @import("../view_stack.zig").ViewStack; -- cgit v1.2.3