Split river and riverctl directories
This commit is contained in:
37
river/command/close.zig
Normal file
37
river/command/close.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Close the focused view, if any.
|
||||
pub fn close(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!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();
|
||||
}
|
||||
}
|
51
river/command/declare_mode.zig
Normal file
51
river/command/declare_mode.zig
Normal file
@ -0,0 +1,51 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Mapping = @import("../Mapping.zig");
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Declare a new keymap mode
|
||||
pub fn declareMode(
|
||||
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 config = &seat.input_manager.server.config;
|
||||
const new_mode_name = args[1];
|
||||
|
||||
if (config.mode_to_id.get(new_mode_name) != null) {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"mode '{}' already exists and cannot be re-declared",
|
||||
.{new_mode_name},
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
}
|
||||
|
||||
try config.mode_to_id.putNoClobber(new_mode_name, config.modes.items.len);
|
||||
errdefer _ = config.mode_to_id.remove(new_mode_name);
|
||||
try config.modes.append(std.ArrayList(Mapping).init(allocator));
|
||||
}
|
43
river/command/enter_mode.zig
Normal file
43
river/command/enter_mode.zig
Normal file
@ -0,0 +1,43 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Switch to the given mode
|
||||
pub fn enterMode(
|
||||
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 config = seat.input_manager.server.config;
|
||||
const target_mode = args[1];
|
||||
seat.mode_id = config.mode_to_id.getValue(target_mode) orelse {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"cannot enter non-existant mode '{}'",
|
||||
.{target_mode},
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
};
|
||||
}
|
34
river/command/exit.zig
Normal file
34
river/command/exit.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Exit the compositor, terminating the wayland session.
|
||||
pub fn exit(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!void {
|
||||
if (args.len > 1) return Error.TooManyArguments;
|
||||
c.wl_display_terminate(seat.input_manager.server.wl_display);
|
||||
}
|
67
river/command/focus.zig
Normal file
67
river/command/focus.zig
Normal file
@ -0,0 +1,67 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Direction = @import("../command.zig").Direction;
|
||||
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(
|
||||
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 direction = try Direction.parse(args[1]);
|
||||
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);
|
||||
}
|
32
river/command/focus_all_tags.zig
Normal file
32
river/command/focus_all_tags.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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();
|
||||
}
|
54
river/command/focus_output.zig
Normal file
54
river/command/focus_output.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Direction = @import("../command.zig").Direction;
|
||||
const Output = @import("../Output.zig");
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Focus either the next or the previous output, depending on the bool passed.
|
||||
/// Does nothing if there is only one output.
|
||||
pub fn focusOutput(
|
||||
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 direction = try Direction.parse(args[1]);
|
||||
const root = &seat.input_manager.server.root;
|
||||
// If the noop output is focused, there are no other outputs to switch to
|
||||
if (seat.focused_output == &root.noop_output) {
|
||||
std.debug.assert(root.outputs.len == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus the next/prev output in the list if there is one, else wrap
|
||||
const focused_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", seat.focused_output);
|
||||
seat.focused_output = switch (direction) {
|
||||
.Next => if (focused_node.next) |node| &node.data else &root.outputs.first.?.data,
|
||||
.Prev => if (focused_node.prev) |node| &node.data else &root.outputs.last.?.data,
|
||||
};
|
||||
|
||||
seat.focus(null);
|
||||
}
|
37
river/command/focus_tag.zig
Normal file
37
river/command/focus_tag.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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();
|
||||
}
|
37
river/command/layout.zig
Normal file
37
river/command/layout.zig
Normal file
@ -0,0 +1,37 @@
|
||||
// This file is part of river, a dynamic tiling wayland compositor.
|
||||
//
|
||||
// Copyright 2020 Leon Henrik Plickat
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
pub fn layout(
|
||||
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;
|
||||
|
||||
seat.focused_output.layout = seat.focused_output.getLayoutByName(args[1]);
|
||||
seat.focused_output.arrangeViews();
|
||||
seat.input_manager.server.root.startTransaction();
|
||||
}
|
110
river/command/map.zig
Normal file
110
river/command/map.zig
Normal file
@ -0,0 +1,110 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Mapping = @import("../Mapping.zig");
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
const modifier_names = [_]struct {
|
||||
name: []const u8,
|
||||
modifier: u32,
|
||||
}{
|
||||
.{ .name = "Shift", .modifier = c.WLR_MODIFIER_SHIFT },
|
||||
.{ .name = "Lock", .modifier = c.WLR_MODIFIER_CAPS },
|
||||
.{ .name = "Control", .modifier = c.WLR_MODIFIER_CTRL },
|
||||
.{ .name = "Mod1", .modifier = c.WLR_MODIFIER_ALT },
|
||||
.{ .name = "Mod2", .modifier = c.WLR_MODIFIER_MOD2 },
|
||||
.{ .name = "Mod3", .modifier = c.WLR_MODIFIER_MOD3 },
|
||||
.{ .name = "Mod4", .modifier = c.WLR_MODIFIER_LOGO },
|
||||
.{ .name = "Mod5", .modifier = c.WLR_MODIFIER_MOD5 },
|
||||
};
|
||||
|
||||
/// Create a new mapping for a given mode
|
||||
///
|
||||
/// Example:
|
||||
/// map normal Mod4|Shift Return spawn alacritty
|
||||
pub fn map(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!void {
|
||||
if (args.len < 4) return Error.NotEnoughArguments;
|
||||
|
||||
// Parse the mode
|
||||
const config = seat.input_manager.server.config;
|
||||
const target_mode = args[1];
|
||||
const mode_id = config.mode_to_id.getValue(target_mode) orelse {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"cannot add mapping to non-existant mode '{}p'",
|
||||
.{target_mode},
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
};
|
||||
|
||||
// Parse the modifiers
|
||||
var it = std.mem.split(args[2], "|");
|
||||
var modifiers: u32 = 0;
|
||||
while (it.next()) |mod_name| {
|
||||
for (modifier_names) |def| {
|
||||
if (std.mem.eql(u8, def.name, mod_name)) {
|
||||
modifiers |= def.modifier;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"invalid modifier '{}'",
|
||||
.{mod_name},
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the keysym
|
||||
const keysym_name = try std.cstr.addNullByte(allocator, args[3]);
|
||||
defer allocator.free(keysym_name);
|
||||
const keysym = c.xkb_keysym_from_name(keysym_name, .XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
if (keysym == c.XKB_KEY_NoSymbol) {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"invalid keysym '{}'",
|
||||
.{args[3]},
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
}
|
||||
|
||||
// Check if the mapping already exists
|
||||
const mode_mappings = &config.modes.items[mode_id];
|
||||
for (mode_mappings.items) |existant_mapping| {
|
||||
if (existant_mapping.modifiers == modifiers and existant_mapping.keysym == keysym) {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"a mapping for modifiers '{}' and keysym '{}' already exists",
|
||||
.{ args[2], args[3] },
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
}
|
||||
}
|
||||
|
||||
try mode_mappings.append(try Mapping.init(allocator, keysym, modifiers, args[4..]));
|
||||
}
|
42
river/command/mod_master_count.zig
Normal file
42
river/command/mod_master_count.zig
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Modify the number of master views
|
||||
pub fn modMasterCount(
|
||||
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 delta = try std.fmt.parseInt(i32, args[1], 10);
|
||||
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();
|
||||
}
|
45
river/command/mod_master_factor.zig
Normal file
45
river/command/mod_master_factor.zig
Normal file
@ -0,0 +1,45 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Modify the percent of the width of the screen that the master views occupy.
|
||||
pub fn modMasterFactor(
|
||||
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 delta = try std.fmt.parseFloat(f64, args[1]);
|
||||
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();
|
||||
}
|
||||
}
|
62
river/command/send_to_output.zig
Normal file
62
river/command/send_to_output.zig
Normal file
@ -0,0 +1,62 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Direction = @import("../command.zig").Direction;
|
||||
const Output = @import("../Output.zig");
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Send the focused view to the the next or the previous output, depending on
|
||||
/// the bool passed. Does nothing if there is only one output.
|
||||
pub fn sendToOutput(
|
||||
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 direction = try Direction.parse(args[1]);
|
||||
const root = &seat.input_manager.server.root;
|
||||
|
||||
if (seat.focused_view) |view| {
|
||||
// If the noop output is focused, there is nowhere to send the view
|
||||
if (view.output == &root.noop_output) {
|
||||
std.debug.assert(root.outputs.len == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send to the next/preg output in the list if there is one, else wrap
|
||||
const current_node = @fieldParentPtr(std.TailQueue(Output).Node, "data", view.output);
|
||||
const destination_output = switch (direction) {
|
||||
.Next => if (current_node.next) |node| &node.data else &root.outputs.first.?.data,
|
||||
.Prev => if (current_node.prev) |node| &node.data else &root.outputs.last.?.data,
|
||||
};
|
||||
|
||||
// Move the view to the target output
|
||||
view.sendToOutput(destination_output);
|
||||
|
||||
// Handle the change and focus whatever's next in the focus stack
|
||||
root.arrange();
|
||||
seat.focus(null);
|
||||
}
|
||||
}
|
47
river/command/spawn.zig
Normal file
47
river/command/spawn.zig
Normal file
@ -0,0 +1,47 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Spawn a program.
|
||||
pub fn spawn(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!void {
|
||||
if (args.len < 2) return Error.NotEnoughArguments;
|
||||
|
||||
const cmd = try std.mem.join(allocator, " ", args[1..]);
|
||||
defer allocator.free(cmd);
|
||||
|
||||
const child_args = [_][]const u8{ "/bin/sh", "-c", cmd };
|
||||
const child = try std.ChildProcess.init(&child_args, allocator);
|
||||
defer child.deinit();
|
||||
|
||||
std.ChildProcess.spawn(child) catch |err| {
|
||||
failure_message.* = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"failed to spawn {}: {}.",
|
||||
.{ cmd, err },
|
||||
);
|
||||
return Error.CommandFailed;
|
||||
};
|
||||
}
|
43
river/command/tag_view.zig
Normal file
43
river/command/tag_view.zig
Normal file
@ -0,0 +1,43 @@
|
||||
// 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 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();
|
||||
}
|
||||
}
|
||||
}
|
38
river/command/tag_view_all_tags.zig
Normal file
38
river/command/tag_view_all_tags.zig
Normal file
@ -0,0 +1,38 @@
|
||||
// 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 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();
|
||||
}
|
||||
}
|
||||
}
|
38
river/command/toggle_float.zig
Normal file
38
river/command/toggle_float.zig
Normal file
@ -0,0 +1,38 @@
|
||||
// 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 std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
|
||||
/// Make the focused view float or stop floating, depending on its current
|
||||
/// state.
|
||||
pub fn toggleFloat(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!void {
|
||||
if (args.len > 1) return Error.TooManyArguments;
|
||||
if (seat.focused_view) |view| {
|
||||
view.setFloating(!view.floating);
|
||||
view.output.root.arrange();
|
||||
}
|
||||
}
|
43
river/command/toggle_tag_focus.zig
Normal file
43
river/command/toggle_tag_focus.zig
Normal file
@ -0,0 +1,43 @@
|
||||
// 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 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();
|
||||
}
|
||||
}
|
44
river/command/toggle_view_tag.zig
Normal file
44
river/command/toggle_view_tag.zig
Normal file
@ -0,0 +1,44 @@
|
||||
// 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 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();
|
||||
}
|
||||
}
|
||||
}
|
54
river/command/zoom.zig
Normal file
54
river/command/zoom.zig
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const c = @import("../c.zig");
|
||||
|
||||
const Error = @import("../command.zig").Error;
|
||||
const Seat = @import("../Seat.zig");
|
||||
const View = @import("../View.zig");
|
||||
const ViewStack = @import("../view_stack.zig").ViewStack;
|
||||
|
||||
/// Bump the focused view to the top of the stack. If the view on the top of
|
||||
/// the stack is focused, bump the second view to the top.
|
||||
pub fn zoom(
|
||||
allocator: *std.mem.Allocator,
|
||||
seat: *Seat,
|
||||
args: []const []const u8,
|
||||
failure_message: *[]const u8,
|
||||
) Error!void {
|
||||
if (args.len > 1) return Error.TooManyArguments;
|
||||
|
||||
if (seat.focused_view) |current_focus| {
|
||||
const output = seat.focused_output;
|
||||
const focused_node = @fieldParentPtr(ViewStack(View).Node, "view", current_focus);
|
||||
|
||||
var it = ViewStack(View).iterator(output.views.first, output.current_focused_tags);
|
||||
const zoom_node = if (focused_node == it.next())
|
||||
if (it.next()) |second| second else null
|
||||
else
|
||||
focused_node;
|
||||
|
||||
if (zoom_node) |to_bump| {
|
||||
output.views.remove(to_bump);
|
||||
output.views.push(to_bump);
|
||||
seat.input_manager.server.root.arrange();
|
||||
seat.focus(&to_bump.view);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user