Implement command execution through riverctl

This commit is contained in:
Isaac Freund 2020-05-19 22:59:50 +02:00
parent 569308d91b
commit cee41e925d
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
25 changed files with 271 additions and 137 deletions

141
src/Command.zig Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
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);
}

View file

@ -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;

View file

@ -16,9 +16,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
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,

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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 <https://www.gnu.org/licenses/>.
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");

View file

@ -17,11 +17,11 @@
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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 {
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 file

@ -17,10 +17,10 @@
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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 {
pub fn exit(seat: *Seat, arg: Arg) void {
c.wl_display_terminate(seat.input_manager.server.wl_display);
}

View file

@ -17,14 +17,14 @@
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;
/// 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 {
pub fn focus(seat: *Seat, arg: Arg) void {
const direction = arg.direction;
const output = seat.focused_output;
if (seat.focused_view) |current_focus| {

View file

@ -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 <https://www.gnu.org/licenses/>.
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();
}

View file

@ -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");

View file

@ -15,14 +15,12 @@
// 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 c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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;
/// 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();
}

View file

@ -19,11 +19,11 @@ const std = @import("std");
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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 {
pub fn modMasterCount(seat: *Seat, arg: Arg) void {
const delta = arg.int;
const output = seat.focused_output;
output.master_count = @intCast(

View file

@ -19,11 +19,11 @@ const std = @import("std");
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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 {
pub fn modMasterFactor(seat: *Seat, arg: Arg) void {
const delta = arg.float;
const output = seat.focused_output;
const new_master_factor = std.math.min(

View file

@ -15,7 +15,7 @@
// 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 Arg = @import("../command.zig").Arg;
const Arg = @import("../Command.zig").Arg;
const Seat = @import("../Seat.zig");
/// Switch to the given mode

View file

@ -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");

View file

@ -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");

View file

@ -17,12 +17,12 @@
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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;
/// 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;

View file

@ -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 <https://www.gnu.org/licenses/>.
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();
}
}
}

View file

@ -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

View file

@ -17,12 +17,12 @@
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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;
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) {

View file

@ -17,12 +17,12 @@
const c = @import("../c.zig");
const Arg = @import("../command.zig").Arg;
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;
/// 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 file

@ -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;