diff --git a/contrib/config.sh b/contrib/config.sh index 18c6d68..08ca6a2 100755 --- a/contrib/config.sh +++ b/contrib/config.sh @@ -38,24 +38,26 @@ riverctl map normal $mod+Shift H mod-master-count +1 riverctl map normal $mod+Shift L mod-master-count -1 for i in $(seq 1 9); do - # Mod+[1-9] to focus tag [1-9] - riverctl map normal $mod $i focus-tag $i + tagmask=$((1 << ($i - 1))) - # Mod+Shift+[1-9] to tag focused view with tag [1-9] - riverctl map normal $mod+Shift $i tag-view $i + # Mod+[1-9] to focus tag [0-8] + riverctl map normal $mod $i set-focused-tags $tagmask - # Mod+Ctrl+[1-9] to toggle focus of tag [1-9] - riverctl map normal $mod+Control $i toggle-tag-focus $i + # Mod+Shift+[1-9] to tag focused view with tag [0-8] + riverctl map normal $mod+Shift $i set-view-tags $tagmask - # Mod+Shift+Ctrl+[1-9] to toggle tag [1-9] of focused view - riverctl map normal $mod+Shift+Control $i toggle-view-tag $i + # Mod+Ctrl+[1-9] to toggle focus of tag [0-8] + riverctl map normal $mod+Control $i toggle-focused-tags $tagmask + + # Mod+Shift+Ctrl+[1-9] to toggle tag [0-8] of focused view + riverctl map normal $mod+Shift+Control $i toggle-view-tags $tagmask done # Mod+0 to focus all tags -riverctl map normal $mod 0 focus-all-tags - # Mod+Shift+0 to tag focused view with all tags -riverctl map normal $mod+Shift 0 tag-view-all-tags +all_tags_mask=$(((1 << 32) - 1)) +riverctl map normal $mod 0 set-focused-tags $all_tags_mask +riverctl map normal $mod+Shift 0 set-view-tags $all_tags_mask # Mod+Space to toggle float riverctl map normal $mod Space toggle-float diff --git a/river/command.zig b/river/command.zig index fd3cd28..243acfa 100644 --- a/river/command.zig +++ b/river/command.zig @@ -24,21 +24,19 @@ const impl = struct { const declareMode = @import("command/declare_mode.zig").declareMode; const enterMode = @import("command/enter_mode.zig").enterMode; const exit = @import("command/exit.zig").exit; - const focusView = @import("command/focus_view.zig").focusView; - const focusAllTags = @import("command/focus_all_tags.zig").focusAllTags; const focusOutput = @import("command/focus_output.zig").focusOutput; - const map = @import("command/map.zig").map; - const focusTag = @import("command/focus_tag.zig").focusTag; + const focusView = @import("command/focus_view.zig").focusView; const layout = @import("command/layout.zig").layout; + const map = @import("command/map.zig").map; const modMasterCount = @import("command/mod_master_count.zig").modMasterCount; const modMasterFactor = @import("command/mod_master_factor.zig").modMasterFactor; const sendToOutput = @import("command/send_to_output.zig").sendToOutput; + const setFocusedTags = @import("command/tags.zig").setFocusedTags; + const setViewTags = @import("command/tags.zig").setViewTags; 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 toggleFocusedTags = @import("command/tags.zig").toggleFocusedTags; + const toggleViewTags = @import("command/tags.zig").toggleViewTags; const zoom = @import("command/zoom.zig").zoom; }; @@ -56,34 +54,30 @@ pub const Direction = enum { } }; -const Definition = struct { - name: []const u8, - impl: fn (*std.mem.Allocator, *Seat, []const []const u8, *[]const u8) Error!void, -}; - // TODO: this could be replaced with a comptime hashmap // zig fmt: off -const str_to_impl_fn = [_]Definition{ - .{ .name = "close", .impl = impl.close }, - .{ .name = "declare-mode", .impl = impl.declareMode}, - .{ .name = "enter-mode", .impl = impl.enterMode }, - .{ .name = "exit", .impl = impl.exit }, - .{ .name = "focus-view", .impl = impl.focusView }, - .{ .name = "focus-all-tags", .impl = impl.focusAllTags }, - .{ .name = "focus-output", .impl = impl.focusOutput }, - .{ .name = "focus-tag", .impl = impl.focusTag }, - .{ .name = "layout", .impl = impl.layout }, - .{ .name = "mod-master-count", .impl = impl.modMasterCount }, - .{ .name = "mod-master-factor", .impl = impl.modMasterFactor }, - .{ .name = "send-to-output", .impl = impl.sendToOutput }, - .{ .name = "spawn", .impl = impl.spawn }, - .{ .name = "map", .impl = impl.map }, - .{ .name = "tag-view", .impl = impl.tagView }, - .{ .name = "tag-view-all-tags", .impl = impl.tagViewAllTags }, - .{ .name = "toggle-float", .impl = impl.toggleFloat }, - .{ .name = "toggle-tag-focus", .impl = impl.toggleTagFocus }, - .{ .name = "toggle-view-tag", .impl = impl.toggleViewTag }, - .{ .name = "zoom", .impl = impl.zoom }, +const str_to_impl_fn = [_]struct { + name: []const u8, + impl: fn (*std.mem.Allocator, *Seat, []const []const u8, *[]const u8) Error!void, +}{ + .{ .name = "close", .impl = impl.close }, + .{ .name = "declare-mode", .impl = impl.declareMode }, + .{ .name = "enter-mode", .impl = impl.enterMode }, + .{ .name = "exit", .impl = impl.exit }, + .{ .name = "focus-output", .impl = impl.focusOutput }, + .{ .name = "focus-view", .impl = impl.focusView }, + .{ .name = "layout", .impl = impl.layout }, + .{ .name = "map", .impl = impl.map }, + .{ .name = "mod-master-count", .impl = impl.modMasterCount }, + .{ .name = "mod-master-factor", .impl = impl.modMasterFactor }, + .{ .name = "send-to-output", .impl = impl.sendToOutput }, + .{ .name = "set-focused-tags", .impl = impl.setFocusedTags }, + .{ .name = "set-view-tags", .impl = impl.setViewTags }, + .{ .name = "spawn", .impl = impl.spawn }, + .{ .name = "toggle-float", .impl = impl.toggleFloat }, + .{ .name = "toggle-focused-tags", .impl = impl.toggleFocusedTags }, + .{ .name = "toggle-view-tags", .impl = impl.toggleViewTags }, + .{ .name = "zoom", .impl = impl.zoom }, }; // zig fmt: on diff --git a/river/command/focus_all_tags.zig b/river/command/focus_all_tags.zig deleted file mode 100644 index 28e001d..0000000 --- a/river/command/focus_all_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 std = @import("std"); - -const Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Set focus to all tags -pub fn focusAllTags( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - seat.focused_output.pending_focused_tags = 0xFFFFFFFF; - seat.input_manager.server.root.arrange(); -} diff --git a/river/command/focus_tag.zig b/river/command/focus_tag.zig deleted file mode 100644 index 8f69e6e..0000000 --- a/river/command/focus_tag.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 Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Switch focus to the passed tag. -pub fn focusTag( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - if (args.len < 2) return Error.NotEnoughArguments; - if (args.len > 2) return Error.TooManyArguments; - - const tag = try std.fmt.parseInt(u32, args[1], 10); - const tags = @as(u32, 1) << @intCast(u5, tag - 1); - seat.focused_output.pending_focused_tags = tags; - seat.input_manager.server.root.arrange(); -} diff --git a/river/command/tag_view.zig b/river/command/tag_view.zig deleted file mode 100644 index 735481d..0000000 --- a/river/command/tag_view.zig +++ /dev/null @@ -1,43 +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 Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Set the tag of the focused view. -pub fn tagView( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - if (args.len < 2) return Error.NotEnoughArguments; - if (args.len > 2) return Error.TooManyArguments; - - const tag = try std.fmt.parseInt(u32, args[1], 10); - const tags = @as(u32, 1) << @intCast(u5, tag - 1); - if (seat.focused_view) |view| { - if (view.current_tags != tags) { - view.pending_tags = tags; - seat.input_manager.server.root.arrange(); - } - } -} diff --git a/river/command/tag_view_all_tags.zig b/river/command/tag_view_all_tags.zig deleted file mode 100644 index 2d187f3..0000000 --- a/river/command/tag_view_all_tags.zig +++ /dev/null @@ -1,38 +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 Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Tag the focused view with all tags. -pub fn tagViewAllTags( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - if (seat.focused_view) |view| { - if (view.current_tags != 0xFFFFFFFF) { - view.pending_tags = 0xFFFFFFFF; - seat.input_manager.server.root.arrange(); - } - } -} diff --git a/river/command/tags.zig b/river/command/tags.zig new file mode 100644 index 0000000..430b99e --- /dev/null +++ b/river/command/tags.zig @@ -0,0 +1,102 @@ +// 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 Error = @import("../command.zig").Error; +const Seat = @import("../Seat.zig"); + +/// Switch focus to the passed tags. +pub fn setFocusedTags( + allocator: *std.mem.Allocator, + seat: *Seat, + args: []const []const u8, + failure_message: *[]const u8, +) Error!void { + const tags = try parseTags(allocator, args, failure_message); + if (seat.focused_output.current_focused_tags != tags) { + seat.focused_output.pending_focused_tags = tags; + seat.input_manager.server.root.arrange(); + } +} + +/// Set the tags of the focused view. +pub fn setViewTags( + allocator: *std.mem.Allocator, + seat: *Seat, + args: []const []const u8, + failure_message: *[]const u8, +) Error!void { + const tags = try parseTags(allocator, args, failure_message); + if (seat.focused_view) |view| { + if (view.current_tags != tags) { + view.pending_tags = tags; + seat.input_manager.server.root.arrange(); + } + } +} + +/// Toggle focus of the passsed tags. +pub fn toggleFocusedTags( + allocator: *std.mem.Allocator, + seat: *Seat, + args: []const []const u8, + failure_message: *[]const u8, +) Error!void { + const tags = try parseTags(allocator, args, failure_message); + 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(); + } +} + +/// Toggle the passed tags of the focused view +pub fn toggleViewTags( + allocator: *std.mem.Allocator, + seat: *Seat, + args: []const []const u8, + failure_message: *[]const u8, +) Error!void { + const tags = try parseTags(allocator, args, failure_message); + 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(); + } + } +} + +fn parseTags( + allocator: *std.mem.Allocator, + args: []const []const u8, + failure_message: *[]const u8, +) Error!u32 { + if (args.len < 2) return Error.NotEnoughArguments; + if (args.len > 2) return Error.TooManyArguments; + + const tags = try std.fmt.parseInt(u32, args[1], 10); + + if (tags == 0) { + failure_message.* = try std.fmt.allocPrint(allocator, "tagmask may not be 0", .{}); + return Error.CommandFailed; + } + + return tags; +} diff --git a/river/command/toggle_tag_focus.zig b/river/command/toggle_tag_focus.zig deleted file mode 100644 index 09761c7..0000000 --- a/river/command/toggle_tag_focus.zig +++ /dev/null @@ -1,43 +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 Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Toggle focus of the passsed tags. -pub fn toggleTagFocus( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - if (args.len < 2) return Error.NotEnoughArguments; - if (args.len > 2) return Error.TooManyArguments; - - const tag = try std.fmt.parseInt(u32, args[1], 10); - const tags = @as(u32, 1) << @intCast(u5, tag - 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/river/command/toggle_view_tag.zig b/river/command/toggle_view_tag.zig deleted file mode 100644 index 469a750..0000000 --- a/river/command/toggle_view_tag.zig +++ /dev/null @@ -1,44 +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 Error = @import("../command.zig").Error; -const Seat = @import("../Seat.zig"); - -/// Toggle the passed tag of the focused view -pub fn toggleViewTag( - allocator: *std.mem.Allocator, - seat: *Seat, - args: []const []const u8, - failure_message: *[]const u8, -) Error!void { - if (args.len < 2) return Error.NotEnoughArguments; - if (args.len > 2) return Error.TooManyArguments; - - const tag = try std.fmt.parseInt(u32, args[1], 10); - const tags = @as(u32, 1) << @intCast(u5, tag - 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(); - } - } -}