Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
build: delete dead riverctl/rivertile code
PACKAGING.md | 6 -
README.md | 3 -
build.zig | 85 +----
completions/bash/riverctl | 150 ---------
completions/fish/riverctl.fish | 140 --------
completions/zsh/_riverctl | 217 -------------
contrib/layout.c | 488 ----------------------------
contrib/layout.py | 146 ---------
doc/riverctl.1.scd | 562 ---------------------------------
doc/rivertile.1.scd | 88 ------
example/init | 162 ----------
protocol/river-control-unstable-v1.xml | 85 -----
protocol/river-layout-v3.xml | 196 ------------
riverctl/main.zig | 148 ---------
rivertile/main.zig | 419 ------------------------
15 files changed, 2 insertions(+), 2893 deletions(-)
diff --git a/PACKAGING.md b/PACKAGING.md
index 315fe14..0b32c32 100644
--- a/PACKAGING.md
+++ b/PACKAGING.md
@@ -144,12 +144,6 @@ install() {
}
```
-## River specific suggestions
-
-I recommend installing the example init file found at `example/init` to
-`/usr/share/examples/river/init` or similar if your distribution has such
-a convention.
-
## Examples
Build for the host architecture and libc ABI:
diff --git a/README.md b/README.md
index d9f3aa3..3b0bf28 100644
--- a/README.md
+++ b/README.md
@@ -87,9 +87,6 @@ Usually this executable is a shell script invoking *riverctl*(1) to create
mappings, start programs such as a layout generator or status bar, and
perform other configuration.
-An example init script with sane defaults is provided [here](example/init)
-in the example directory.
-
For complete documentation see the `river(1)`, `riverctl(1)`, and
`rivertile(1)` man pages.
diff --git a/build.zig b/build.zig
index 15aa910..a32d3ca 100644
--- a/build.zig
+++ b/build.zig
@@ -31,24 +31,6 @@ pub fn build(b: *Build) !void {
break :scdoc_found true;
};
- const bash_completion = b.option(
- bool,
- "bash-completion",
- "Set to true to install bash completion for riverctl. Defaults to true.",
- ) orelse true;
-
- const zsh_completion = b.option(
- bool,
- "zsh-completion",
- "Set to true to install zsh completion for riverctl. Defaults to true.",
- ) orelse true;
-
- const fish_completion = b.option(
- bool,
- "fish-completion",
- "Set to true to install fish completion for riverctl. Defaults to true.",
- ) orelse true;
-
const xwayland = b.option(
bool,
"xwayland",
@@ -96,8 +78,6 @@ pub fn build(b: *Build) !void {
scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml");
scanner.addCustomProtocol(b.path("protocol/river-window-management-v1.xml"));
- scanner.addCustomProtocol(b.path("protocol/river-control-unstable-v1.xml"));
- scanner.addCustomProtocol(b.path("protocol/river-layout-v3.xml"));
scanner.addCustomProtocol(b.path("protocol/wlr-output-power-management-unstable-v1.xml"));
// Some of these versions may be out of date with what wlroots implements.
@@ -124,9 +104,6 @@ pub fn build(b: *Build) !void {
scanner.generate("river_window_manager_v1", 1);
- scanner.generate("zriver_control_v1", 1);
- scanner.generate("river_layout_manager_v3", 2);
-
scanner.generate("zwlr_output_power_manager_v1", 1);
const wayland = b.createModule(.{ .root_source_file = scanner.result });
@@ -213,52 +190,6 @@ pub fn build(b: *Build) !void {
b.installArtifact(rivercompat);
}
- {
- const riverctl = b.addExecutable(.{
- .name = "riverctl",
- .root_source_file = b.path("riverctl/main.zig"),
- .target = target,
- .optimize = optimize,
- .strip = strip,
- .use_llvm = llvm,
- .use_lld = llvm,
- });
- riverctl.root_module.addOptions("build_options", options);
-
- riverctl.root_module.addImport("flags", flags);
- riverctl.root_module.addImport("wayland", wayland);
- riverctl.linkLibC();
- riverctl.linkSystemLibrary("wayland-client");
-
- riverctl.pie = pie;
- riverctl.root_module.omit_frame_pointer = omit_frame_pointer;
-
- b.installArtifact(riverctl);
- }
-
- {
- const rivertile = b.addExecutable(.{
- .name = "rivertile",
- .root_source_file = b.path("rivertile/main.zig"),
- .target = target,
- .optimize = optimize,
- .strip = strip,
- .use_llvm = llvm,
- .use_lld = llvm,
- });
- rivertile.root_module.addOptions("build_options", options);
-
- rivertile.root_module.addImport("flags", flags);
- rivertile.root_module.addImport("wayland", wayland);
- rivertile.linkLibC();
- rivertile.linkSystemLibrary("wayland-client");
-
- rivertile.pie = pie;
- rivertile.root_module.omit_frame_pointer = omit_frame_pointer;
-
- b.installArtifact(rivertile);
- }
-
{
const wf = Build.Step.WriteFile.create(b);
const pc_file = wf.add("river-protocols.pc", b.fmt(
@@ -272,12 +203,12 @@ pub fn build(b: *Build) !void {
\\Version: {s}
, .{ b.install_prefix, full_version }));
- b.installFile("protocol/river-layout-v3.xml", "share/river-protocols/river-layout-v3.xml");
+ b.installFile("protocol/river-window-management-v1.xml", "share/river-protocols/river-window-management-v1.xml");
b.getInstallStep().dependOn(&b.addInstallFile(pc_file, "share/pkgconfig/river-protocols.pc").step);
}
if (man_pages) {
- inline for (.{ "river", "riverctl", "rivertile" }) |page| {
+ inline for (.{"river"}) |page| {
// Workaround for https://github.com/ziglang/zig/issues/16369
// Even passing a buffer to std.Build.Step.Run appears to be racy and occasionally deadlocks.
const scdoc = b.addSystemCommand(&.{ "/bin/sh", "-c", "scdoc < doc/" ++ page ++ ".1.scd" });
@@ -289,18 +220,6 @@ pub fn build(b: *Build) !void {
}
}
- if (bash_completion) {
- b.installFile("completions/bash/riverctl", "share/bash-completion/completions/riverctl");
- }
-
- if (zsh_completion) {
- b.installFile("completions/zsh/_riverctl", "share/zsh/site-functions/_riverctl");
- }
-
- if (fish_completion) {
- b.installFile("completions/fish/riverctl.fish", "share/fish/vendor_completions.d/riverctl.fish");
- }
-
{
const globber_test = b.addTest(.{
.root_source_file = b.path("common/globber.zig"),
diff --git a/completions/bash/riverctl b/completions/bash/riverctl
deleted file mode 100644
index 68684d5..0000000
--- a/completions/bash/riverctl
+++ /dev/null
@@ -1,150 +0,0 @@
-function __riverctl_completion ()
-{
- local rule_actions="float no-float ssd csd tags output position dimensions fullscreen no-fullscreen"
- if [ "${COMP_CWORD}" -eq 1 ]
- then
- OPTS=" \
- keyboard-group-create \
- keyboard-group-destroy \
- keyboard-group-add \
- keyboard-group-remove \
- keyboard-layout \
- keyboard-layout-file \
- close \
- exit \
- focus-output \
- focus-view \
- input \
- list-inputs \
- list-input-configs \
- move \
- resize \
- rule-add \
- rule-del \
- list-rules \
- snap \
- send-to-output \
- spawn \
- swap \
- toggle-float \
- toggle-fullscreen \
- zoom \
- default-layout \
- output-layout \
- send-layout-cmd \
- set-focused-tags \
- focus-previous-tags \
- send-to-previous-tags \
- set-view-tags \
- toggle-focused-tags \
- toggle-view-tags \
- spawn-tagmask \
- declare-mode \
- enter-mode \
- map \
- map-pointer \
- map-switch \
- unmap \
- unmap-pointer \
- unmap-switch \
- default-attach-mode \
- output-attach-mode \
- background-color \
- border-color-focused \
- border-color-unfocused \
- border-color-urgent \
- border-width \
- focus-follows-cursor \
- hide-cursor \
- set-repeat \
- set-cursor-warp \
- xcursor-theme"
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[1]}"))
- elif [ "${COMP_CWORD}" -eq 2 ]
- then
- case "${COMP_WORDS[1]}" in
- "focus-output"|"send-to-output") OPTS="next previous up right down left" ;;
- "focus-view"|"swap") OPTS="next previous up down left right" ;;
- "input") OPTS="$(riverctl list-inputs | sed '/configured:/d')" ;;
- "move"|"snap") OPTS="up down left right" ;;
- "resize") OPTS="horizontal vertical" ;;
- "rule-add"|"rule-del") OPTS="-app-id -title $rule_actions" ;;
- "list-rules") OPTS="float ssd tags output position dimensions fullscreen" ;;
- "map") OPTS="-release -repeat -layout" ;;
- "unmap") OPTS="-release" ;;
- "default-attach-mode"|"output-attach-mode") OPTS="top bottom above below after" ;;
- "focus-follows-cursor") OPTS="disabled normal always" ;;
- "set-cursor-warp") OPTS="disabled on-output-change on-focus-change" ;;
- "hide-cursor") OPTS="timeout when-typing" ;;
- *) return ;;
- esac
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[2]}"))
- elif [ "${COMP_CWORD}" -eq 3 ]
- then
- if [ "${COMP_WORDS[1]}" == "input" ]
- then
- OPTS="events \
- accel-profile \
- pointer-accel \
- click-method \
- drag \
- drag-lock \
- disable-while-typing \
- disable-while-trackpointing \
- middle-emulation \
- natural-scroll \
- scroll-factor \
- left-handed \
- tap \
- tap-button-map \
- scroll-method \
- scroll-button \
- map-to-output"
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[3]}"))
- elif [ "${COMP_WORDS[1]}" == "hide-cursor" ]
- then
- case "${COMP_WORDS[2]}" in
- "when-typing") OPTS="enabled disabled" ;;
- *) return ;;
- esac
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[3]}"))
- fi
- elif [ "${COMP_CWORD}" -eq 4 ]
- then
- if [ "${COMP_WORDS[1]}" == "input" ]
- then
- case "${COMP_WORDS[3]}" in
- "events") OPTS="enabled disabled disabled-on-external-mouse" ;;
- "accel-profile") OPTS="none flat adaptive" ;;
- "click-method") OPTS="none button-areas clickfinger" ;;
- "drag"|"drag-lock"|"disable-while-typing"|"middle-emulation"|"left-handed"|"tap") OPTS="enabled disabled" ;;
- "tap-button-map") OPTS="left-right-middle left-middle-right" ;;
- "scroll-method") OPTS="none two-finger edge button" ;;
- *) return ;;
- esac
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[4]}"))
- elif [ "${COMP_WORDS[1]:0:5}" == "rule-" ]
- then
- case "${COMP_WORDS[2]}" in
- "-app-id") OPTS="-title $rule_actions" ;;
- "-title") OPTS="-app-id $rule_actions" ;;
- *) return ;;
- esac
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[4]}"))
- fi
- elif [ "${COMP_CWORD}" -eq 6 ]
- then
- if [ "${COMP_WORDS[1]:0:5}" == "rule-" ]
- then
- case "${COMP_WORDS[4]}" in
- "-app-id"|"-title") OPTS="$rule_actions" ;;
- *) return ;;
- esac
- COMPREPLY=($(compgen -W "${OPTS}" -- "${COMP_WORDS[6]}"))
- fi
- else
- return
- fi
-}
-
-complete -F __riverctl_completion riverctl
diff --git a/completions/fish/riverctl.fish b/completions/fish/riverctl.fish
deleted file mode 100644
index 65fad0a..0000000
--- a/completions/fish/riverctl.fish
+++ /dev/null
@@ -1,140 +0,0 @@
-function __riverctl_list_input_devices
- riverctl list-inputs | sed '/configured:/d'
-end
-
-function __fish_riverctl_complete_arg
- set -l cmd (commandline -opc)
- if test (count $cmd) -eq $argv[1]
- return 0
- end
- return 1
-end
-
-# Remove any previous completion, such as options extracted from the manpage
-complete -c riverctl -e
-# Do not suggest files
-complete -c riverctl -f
-# Options
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -o 'h' -d 'Print a help message and exit'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -o 'version' -d 'Print the version number and exit'
-
-# Actions
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'close' -d 'Close the focued view'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'exit' -d 'Exit the compositor, terminating the Wayland session'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'focus-output' -d 'Focus the next or previous output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'focus-view' -d 'Focus the next or previous view in the stack'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'input' -d 'Create a configuration rule for an input device'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'list-inputs' -d 'List all input devices'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'list-input-configs' -d 'List all input configurations'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'move' -d 'Move the focused view in the specified direction'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'resize' -d 'Resize the focused view along the given axis'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'snap' -d 'Snap the focused view to the specified screen edge'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'send-to-output' -d 'Send the focused view to the next/previous output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'spawn' -d 'Run shell_command using /bin/sh -c'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'swap' -d 'Swap the focused view with the next/previous visible non-floating view'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'toggle-float' -d 'Toggle the floating state of the focused view'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'toggle-fullscreen' -d 'Toggle the fullscreen state of the focused view'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'zoom' -d 'Bump the focused view to the top of the layout stack'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'default-layout' -d 'Set the layout namespace to be used by all outputs by default'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'output-layout' -d 'Set the layout namespace of currently focused output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'send-layout-cmd' -d 'Send command to the layout generator on the currently focused output with the given namespace'
-# Tag managements
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'set-focused-tags' -d 'Show views with tags corresponding to the set bits of tags'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'set-view-tags' -d 'Assign the currently focused view the tags corresponding to the set bits of tags'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'toggle-focused-tags' -d 'Toggle visibility of views with tags corresponding to the set bits of tags'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'toggle-view-tags' -d 'Toggle the tags of the currently focused view'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'spawn-tagmask' -d 'Set a tagmask to filter the tags assigned to newly spawned views on the focused output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'focus-previous-tags' -d 'Sets tags to their previous value on the focused output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'send-to-previous-tags' -d 'Assign the currently focused view the previous tags of the focused output'
-# Mappings
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'declare-mode' -d 'Create a new mode'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'enter-mode' -d 'Switch to given mode if it exists'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'map' -d 'Run command when key is pressed while modifiers are held down and in the specified mode'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'map-pointer' -d 'Move or resize views or run command when button and modifers are held down while in the specified mode'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'map-switch ' -d 'Run command when river receives a switch event in the specified mode'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'unmap' -d 'Remove the mapping defined by the arguments'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'unmap-pointer' -d 'Remove the pointer mapping defined by the arguments'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'unmap-switch' -d 'Remove the switch mapping defined by the arguments'
-# Rules
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'rule-add' -d 'Apply an action to matching views'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'rule-del' -d 'Delete a rule added with rule-add'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'list-rules' -d 'Print rules in a given list'
-# Configuration
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'default-attach-mode' -d 'Set the attach mode to be used by all outputs by default'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'output-attach-mode' -d 'Set the attach mode of the currently focused output'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'background-color' -d 'Set the background color'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'border-color-focused' -d 'Set the border color of focused views'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'border-color-unfocused' -d 'Set the border color of unfocused views'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'border-color-urgent' -d 'Set the border color of urgent views'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'border-width' -d 'Set the border width to pixels'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'focus-follows-cursor' -d 'Configure the focus behavior when moving cursor'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'hide-cursor' -d 'Hide cursor when typing or after inactivity'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'set-repeat' -d 'Set the keyboard repeat rate and repeat delay'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'set-cursor-warp' -d 'Set the cursor warp mode'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'xcursor-theme' -d 'Set the xcursor theme'
-# Keyboardgroups
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-group-create' -d 'Create a keyboard group'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-group-destroy' -d 'Destroy a keyboard group'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-group-add' -d 'Add a keyboard to a keyboard group'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-group-remove' -d 'Remove a keyboard from a keyboard group'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-layout' -d 'Set the keyboard layout'
-complete -c riverctl -n '__fish_riverctl_complete_arg 1' -a 'keyboard-layout-file' -d 'Set the keyboard layout from a file.'
-
-# Subcommands
-complete -c riverctl -n '__fish_seen_subcommand_from focus-output send-to-output' -n '__fish_riverctl_complete_arg 2' -a 'next previous up right down left'
-complete -c riverctl -n '__fish_seen_subcommand_from focus-view swap' -n '__fish_riverctl_complete_arg 2' -a 'next previous up down left right'
-complete -c riverctl -n '__fish_seen_subcommand_from move snap' -n '__fish_riverctl_complete_arg 2' -a 'up down left right'
-complete -c riverctl -n '__fish_seen_subcommand_from resize' -n '__fish_riverctl_complete_arg 2' -a 'horizontal vertical'
-complete -c riverctl -n '__fish_seen_subcommand_from map' -o 'release' -o 'repeat' -o 'layout'
-complete -c riverctl -n '__fish_seen_subcommand_from unmap' -n '__fish_riverctl_complete_arg 2' -o 'release'
-complete -c riverctl -n '__fish_seen_subcommand_from default-attach-mode' -n '__fish_riverctl_complete_arg 2' -a 'top bottom above below after'
-complete -c riverctl -n '__fish_seen_subcommand_from output-attach-mode' -n '__fish_riverctl_complete_arg 2' -a 'top bottom above below after'
-complete -c riverctl -n '__fish_seen_subcommand_from focus-follows-cursor' -n '__fish_riverctl_complete_arg 2' -a 'disabled normal always'
-complete -c riverctl -n '__fish_seen_subcommand_from set-cursor-warp' -n '__fish_riverctl_complete_arg 2' -a 'disabled on-output-change on-focus-change'
-complete -c riverctl -n '__fish_seen_subcommand_from list-rules' -n '__fish_riverctl_complete_arg 2' -a 'float ssd tags output position dimensions fullscreen'
-
-# Options and subcommands for 'rule-add' and 'rule-del'
-set -l rule_actions float no-float ssd csd tags output position dimensions fullscreen no-fullscreen
-complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o app-id' -o 'app-id' -r
-complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o title' -o 'title' -r
-complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'test (math (count (commandline -opc)) % 2) -eq 0' -a "$rule_actions"
-set -e rule_actions
-
-# Subcommands for 'input'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 2' -a "(__riverctl_list_input_devices)"
-
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'events' -d 'Configure whether the input device\'s events will be used'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'accel-profile' -d 'Set the pointer acceleration profile'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'pointer-accel' -d 'Set the pointer acceleration factor'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'click-method' -d 'Set the click method'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'drag' -d 'Enable or disable the tap-and-drag functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'drag-lock' -d 'Enable or disable the drag lock functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'disable-while-typing' -d 'Enable or disable the disable-while-typing functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'disable-while-trackpointing' -d 'Enable or disable the disable-while-trackpointing functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'middle-emulation' -d 'Enable or disable the middle-emulation functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'natural-scroll' -d 'Enable or disable the natural-scroll functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'scroll-factor' -d 'Set the scroll factor'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'left-handed' -d 'Enable or disable the left handed mode'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'tap' -d 'Enable or disable the tap functionality'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'tap-button-map' -d 'Configure the button mapping for tapping'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'scroll-method' -d 'Set the scroll method'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'scroll-button' -d 'Set the scroll button'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'map-to-output' -d 'Map to a given output'
-
-# Subcommands for the subcommands of 'input'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from drag drag-lock disable-while-typing disable-while-trackpointing middle-emulation natural-scroll left-handed tap' -a 'enabled disabled'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from events' -a 'enabled disabled disabled-on-external-mouse'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from accel-profile' -a 'none flat adaptive'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from click-method' -a 'none button-areas clickfinger'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from tap-button-map' -a 'left-right-middle left-middle-right'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from scroll-method' -a 'none' -d 'No scrolling'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from scroll-method' -a 'two-finger' -d 'Scroll by swiping with two fingers simultaneously'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from scroll-method' -a 'edge' -d 'Scroll by swiping along the edge'
-complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 4; and __fish_seen_subcommand_from scroll-method' -a 'button' -d 'Scroll with pointer movement while holding down a button'
-
-# Subcommands for 'hide-cursor'
-complete -c riverctl -n '__fish_seen_subcommand_from hide-cursor; and __fish_riverctl_complete_arg 2' -a 'timeout' -d 'Hide cursor if it wasn\'t moved in the last X millisecond, until it is moved again'
-complete -c riverctl -n '__fish_seen_subcommand_from hide-cursor; and __fish_riverctl_complete_arg 2' -a 'when-typing' -d 'Enable or disable whether the cursor should be hidden when pressing any non-modifier key'
-
-# Subcommands for the subcommands of 'hide-cursor'
-complete -c riverctl -n '__fish_seen_subcommand_from hide-cursor; and __fish_riverctl_complete_arg 3; and __fish_seen_subcommand_from when-typing' -a 'enabled disabled'
diff --git a/completions/zsh/_riverctl b/completions/zsh/_riverctl
deleted file mode 100644
index 73df6b1..0000000
--- a/completions/zsh/_riverctl
+++ /dev/null
@@ -1,217 +0,0 @@
-#compdef riverctl
-#
-# Completion script for riverctl, part of river <https://codeberg.org/river/river>
-
-# This is the list of all riverctl first argument, i.e `riverctl <first_arg>`.
-# If a command doesn't need completion for subcommands then you just need
-# to add a line to this list.
-# Format is '<command-name>:<description>'
-_riverctl_commands()
-{
- local -a riverctl_commands
-
- riverctl_commands=(
- # Actions
- 'close:Close the focused view'
- 'exit:Exit the compositor, terminating the Wayland session'
- 'focus-output:Focus the next or previous output'
- 'focus-view:Focus the next or previous view in the stack'
- 'move:Move the focused view in the specified direction'
- 'resize:Resize the focused view along the given axis'
- 'snap:Snap the focused view to the specified screen edge'
- 'send-to-output:Send the focused view to the next or the previous output'
- 'spawn:Run shell_command using /bin/sh -c'
- 'swap:Swap the focused view with the next/previous visible non-floating view'
- 'toggle-float:Toggle the floating state of the focused view'
- 'toggle-fullscreen:Toggle the fullscreen state of the focused view'
- 'zoom:Bump the focused view to the top of the layout stack'
- 'default-layout:Set the layout namespace to be used by all outputs by default.'
- 'output-layout:Set the layout namespace of currently focused output.'
- 'send-layout-cmd:Send command to the layout generator on the currently focused output with matching namespace'
- # Tag management
- 'set-focused-tags:Show views with tags corresponding to the set bits of tags'
- 'set-view-tags:Assign the currently focused view the tags corresponding to the set bits of tags'
- 'toggle-focused-tags:Toggle visibility of views with tags corresponding to the set bits of tags'
- 'toggle-view-tags:Toggle the tags of the currently focused view'
- 'spawn-tagmask:Set a tagmask to filter the tags assigned to newly spawned views on the focused output'
- 'focus-previous-tags:Sets tags to their previous value on the focused output'
- 'send-to-previous-tags:Assign the currently focused view the previous tags of the focused output'
- # Mappings
- 'declare-mode:Create a new mode'
- 'enter-mode:Switch to given mode if it exists'
- 'map:Run command when key is pressed while modifiers are held down and in the specified mode'
- 'map-pointer:Move or resize views or run command when button and modifiers are held down while in the specified mode'
- 'map-switch:Run command when river receives a switch event in the specified mode'
- 'unmap:Remove the mapping defined by the arguments'
- 'unmap-pointer:Remove the pointer mapping defined by the arguments'
- 'unmap-switch:Remove the switch mapping defined by the arguments'
- # Rules
- 'rule-add:Apply an action to matching views'
- 'rule-del:Delete a rule added with rule-add'
- 'list-rules:Print rules in a given list'
- # Configuration
- 'default-attach-mode:Configure where new views should attach to the view stack'
- 'output-attach-mode:Configure where new views should attach to the view stack of the currently focuesed output'
- 'background-color:Set the background color'
- 'border-color-focused:Set the border color of focused views'
- 'border-color-unfocused:Set the border color of unfocused views'
- 'border-color-urgent:Set the border color of urgent views'
- 'border-width:Set the border width to pixels'
- 'focus-follows-cursor:Configure the focus behavior when moving cursor'
- 'hide-cursor:Hide cursor when typing or after inactivity'
- 'set-repeat:Set the keyboard repeat rate and repeat delay'
- 'set-cursor-warp:Set the cursor warp mode.'
- 'xcursor-theme:Set the xcursor theme'
- # Keyboard groups
- 'keyboard-group-create:Create a keyboard group'
- 'keyboard-group-destroy:Destroy a keyboard group'
- 'keyboard-group-add:Add a keyboard to a keyboard group'
- 'keyboard-group-remove:Remove a keyboard from a keyboard group'
- 'keyboard-layout:Set the keyboard layout'
- 'keyboard-layout-file:Set the keyboard layout from a file'
- # Input
- 'input:Configure input devices'
- 'list-inputs:List all input devices'
- 'list-input-configs:List all input configurations'
- )
-
- _describe -t command 'command' riverctl_commands
-}
-
-# This is the function called for the completion. Commands added in the
-# riverctl_commands above are generated in the `commands` case, there is
-# nothing more to do for this. If a command has a subcommand then a new case
-# need to be added in `args`.
-# If this is a simple subcommand with simple multi choice, the easier way to
-# do it is:
-# <command-name>) _alternative 'arguments:args:(<choice1 choice2)' ;;
-# If the subcommand also has subcommands then, good luck...
-# This is really complex, the easiest example to look at is the `hide-cursor` one.
-_riverctl()
-{
- local state line
-
- _arguments -C \
- '1: :->commands' \
- '*:: :->args'
-
- case "$state" in
- commands) _alternative 'common-commands:common:_riverctl_commands' ;;
- args)
- case "$line[1]" in
- focus-output) _alternative 'arguments:args:(next previous up right down left)' ;;
- focus-view) _alternative 'arguments:args:(next previous up down left right)' ;;
- keyboard-layout) _arguments '*::optional:(-rules -model -variant -options)' ;;
- input)
- _arguments '1: :->name' '2: :->commands' ':: :->args'
-
- case "$state" in
- name) _alternative "arguments:args:($(riverctl list-inputs | grep -e '^[^[:space:]]'))" ;;
- commands)
- local -a input_subcommands
- input_subcommands=(
- 'events:Configure whether the input devices events will be used by river'
- 'accel-profile:Set the pointer acceleration profile'
- 'pointer-accel:Set the pointer acceleration factor'
- 'click-method:Set the click method'
- 'drag:Enable or disable the tap-and-drag functionality'
- 'drag-lock:Enable or disable the drag lock functionality'
- 'disable-while-typing:Enable or disable the disable-while-typing functionality'
- 'disable-while-trackpointing:Enable or disable the disable-while-trackpointing functionality'
- 'middle-emulation:Enable or disable the middle click emulation functionality'
- 'natural-scroll:Enable or disable the natural scroll functionality'
- 'scroll-factor:Set the scroll factor'
- 'left-handed:Enable or disable the left handed mode'
- 'tap:Enable or disable the tap functionality'
- 'tap-button-map:Configure the button mapping for tapping'
- 'scroll-method:Set the scroll method'
- 'scroll-button:Set the scroll button'
- 'map-to-output:Map to a given output'
- )
-
- _describe -t command 'command' input_subcommands
- ;;
- args)
- case "$line[2]" in
- events) _alternative 'input-cmds:args:(enabled disabled disabled-on-external-mouse)' ;;
- accel-profile) _alternative 'input-cmds:args:(none flat adaptive)' ;;
- click-method) _alternative 'input-cmds:args:(none button-areas clickfinger)' ;;
- drag) _alternative 'input-cmds:args:(enabled disabled)' ;;
- drag-lock) _alternative 'input-cmds:args:(enabled disabled)' ;;
- disable-while-typing) _alternative 'input-cmds:args:(enabled disabled)' ;;
- disable-while-trackpointing) _alternative 'input-cmds:args:(enabled disabled)' ;;
- middle-emulation) _alternative 'input-cmds:args:(enabled disabled)' ;;
- natural-scroll) _alternative 'input-cmds:args:(enabled disabled)' ;;
- left-handed) _alternative 'input-cmds:args:(enabled disabled)' ;;
- tap) _alternative 'input-cmds:args:(enabled disabled)' ;;
- tap-button-map) _alternative 'input-cmds:args:(left-right-middle left-middle-right)' ;;
- scroll-method) _alternative 'input-cmds:args:(none two-finger edge button)' ;;
- *) return 0 ;;
- esac
- ;;
- esac
- ;;
- move) _alternative 'arguments:args:(up down left right)' ;;
- resize) _alternative 'arguments:args:(horizontal vertical)' ;;
- snap) _alternative 'arguments:args:(up down left right)' ;;
- send-to-output) _arguments \
- '1::optional:(-current-tag)' \
- '::args:(next previous up right down left)'
- ;;
- swap) _alternative 'arguments:args:(next previous up down left right)' ;;
- map) _alternative 'arguments:optional:(-release -repeat -layout)' ;;
- unmap) _alternative 'arguments:optional:(-release)' ;;
- map-switch | unmap-switch)
- _arguments '1: :' '2:args:(lid tablet)' '3:args:->args'
- case "$state" in
- args)
- case "$line[2]" in
- lid) _alternative 'arguments:args:(close open)' ;;
- tablet) _alternative 'arguments:args:(on off)' ;;
- esac
- ;;
- esac
- ;;
- default-attach-mode) _alternative 'arguments:args:(top bottom above below after)' ;;
- output-attach-mode) _alternative 'arguments:args:(top bottom above below after)' ;;
- focus-follows-cursor) _alternative 'arguments:args:(disabled normal always)' ;;
- set-cursor-warp) _alternative 'arguments:args:(disabled on-output-change on-focus-change)' ;;
- hide-cursor)
- _arguments '1: :->commands' ':: :->args'
-
- case "$state" in
- commands)
- local -a hide_cursor_subcommands
- hide_cursor_subcommands=(
- "timeout:Hide cursor if it wasn\'t moved in the last X millisecond, until it is moved again"
- 'when-typing:Enable or disable whether the cursor should be hidden when pressing any non-modifier key'
- )
-
- _describe -t command 'command' hide_cursor_subcommands
- ;;
- args)
- case "$line[1]" in
- when-typing) _alternative 'hide-cursor-cmds:args:(enabled disabled)' ;;
- *) return 0 ;;
- esac
- ;;
- esac
- ;;
- rule-add | rule-del)
- # This is not perfect as it only complete if there is
- # either '-app-id' or '-title'.
- # The empty action(2) mean that we need an argument
- # but we don't generate anything for it.
- # In case of a new rule added in river, we just need
- # to add it to the third option between '()',
- # i.e (float no-float <new-option>)
- _arguments '1: :(-app-id -title)' '2: : ' ':: :(float no-float ssd csd tags output position dimensions fullscreen no-fullscreen)'
- ;;
- list-rules) _alternative 'arguments:args:(float ssd tags output position dimensions fullscreen)' ;;
- *) return 0 ;;
- esac
- ;;
- esac
-}
-
-_riverctl "$@"
diff --git a/contrib/layout.c b/contrib/layout.c
deleted file mode 100644
index 0e1fdfb..0000000
--- a/contrib/layout.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Tiled layout for river, implemented in understandable, simple, commented code.
- * Reading this code should help you get a basic understanding of how to use
- * river-layout to create a basic layout generator.
- *
- * Q: Wow, this is a lot of code just for a layout!
- * A: No, it really is not. Most of the code here is just generic Wayland client
- * boilerplate. The actual layout part is pretty small.
- *
- * Q: Can I use this to port dwm layouts to river?
- * A: Yes you can! You just need to replace the logic in layout_handle_layout_demand().
- * You don't even need to fully understand the protocol if all you want to
- * do is just port some layouts.
- *
- * Q: I have no idea how any of this works.
- * A: If all you want to do is create layouts, you do not need to understand
- * the Wayland parts of the code. If you still want to understand it and are
- * familiar with how Wayland clients work, read the protocol. If you are new
- * to writing Wayland client code, you can read https://wayland-book.com,
- * then read the protocol.
- *
- * Q: How do I build this?
- * A: To build, you need to generate the header and code of the layout protocol
- * extension and link against them. This is achieved with the following
- * commands (You may want to setup a build system).
- *
- * wayland-scanner private-code < river-layout-v3.xml > river-layout-v3.c
- * wayland-scanner client-header < river-layout-v3.xml > river-layout-v3.h
- * gcc -Wall -Wextra -Wpedantic -Wno-unused-parameter -c -o layout.o layout.c
- * gcc -Wall -Wextra -Wpedantic -Wno-unused-parameter -c -o river-layout-v3.o river-layout-v3.c
- * gcc -o layout layout.o river-layout-v3.o -lwayland-client
- */
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <wayland-client.h>
-#include <wayland-client-protocol.h>
-
-#include "river-layout-v3.h"
-
-/* A few macros to indulge the inner glibc user. */
-#define MIN(a, b) ( a < b ? a : b )
-#define MAX(a, b) ( a > b ? a : b )
-#define CLAMP(a, b, c) ( MIN(MAX(b, c), MAX(MIN(b, c), a)) )
-
-struct Output
-{
- struct wl_list link;
-
- struct wl_output *output;
- struct river_layout_v3 *layout;
-
- uint32_t main_count;
- double main_ratio;
- uint32_t view_padding;
- uint32_t outer_padding;
-
- bool configured;
-};
-
-/* In Wayland it's a good idea to have your main data global, since you'll need
- * it everywhere anyway.
- */
-struct wl_display *wl_display;
-struct wl_registry *wl_registry;
-struct wl_callback *sync_callback;
-struct river_layout_manager_v3 *layout_manager;
-struct wl_list outputs;
-bool loop = true;
-int ret = EXIT_FAILURE;
-
-static void layout_handle_layout_demand (void *data, struct river_layout_v3 *river_layout_v3,
- uint32_t view_count, uint32_t width, uint32_t height, uint32_t tags, uint32_t serial)
-{
- struct Output *output = (struct Output *)data;
-
- /* Simple tiled layout with no frills.
- *
- * If you want to create your own layout, just rip the following code
- * out and replace it with your own logic. All dynamic tiling layouts
- * you know, for example from dwm, can be easily ported to river this
- * way. For more creative layouts, you probably also want to add custom
- * values. Happy hacking!
- */
- width -= 2 * output->outer_padding, height -= 2 * output->outer_padding;
- unsigned int main_size, stack_size, view_x, view_y, view_width, view_height;
- if ( output->main_count == 0 )
- {
- main_size = 0;
- stack_size = width;
- }
- else if ( view_count <= output->main_count )
- {
- main_size = width;
- stack_size = 0;
- }
- else
- {
- main_size = width * output->main_ratio;
- stack_size = width - main_size;
- }
- for (unsigned int i = 0; i < view_count; i++)
- {
- if ( i < output->main_count ) /* main area. */
- {
- view_x = 0;
- view_width = main_size;
- view_height = height / MIN(output->main_count, view_count);
- view_y = i * view_height;
- }
- else /* Stack area. */
- {
- view_x = main_size;
- view_width = stack_size;
- view_height = height / ( view_count - output->main_count);
- view_y = (i - output->main_count) * view_height;
- }
-
- river_layout_v3_push_view_dimensions(output->layout,
- view_x + output->view_padding + output->outer_padding,
- view_y + output->view_padding + output->outer_padding,
- view_width - (2 * output->view_padding),
- view_height - (2 * output->view_padding),
- serial);
- }
-
- /* Committing the layout means telling the server that your code is done
- * laying out windows. Make sure you have pushed exactly the right
- * amount of view dimensions, a mismatch is a protocol error.
- *
- * You also have to provide a layout name. This is a user facing string
- * that the server can forward to status bars. You can use it to tell
- * the user which layout is currently in use. You could also add some
- * status information about your layout, but in this example we are
- * boring and just use a static "[]=" like in dwm.
- */
- river_layout_v3_commit(output->layout, "[]=", serial);
-}
-
-static void layout_handle_namespace_in_use (void *data, struct river_layout_v3 *river_layout_v3)
-{
- /* Oh no, the namespace we choose is already used by another client!
- * All we can do now is destroy the river_layout object. Because we are
- * lazy, we just abort and let our cleanup mechanism destroy it. A more
- * sophisticated client could instead destroy only the one single
- * affected river_layout object and recover from this mishap. Writing
- * such a client is left as an exercise for the reader.
- */
- fputs("Namespace already in use.\n", stderr);
- loop = false;
-}
-
-static bool skip_whitespace (char **ptr)
-{
- if ( *ptr == NULL )
- return false;
- while (isspace(**ptr))
- {
- (*ptr)++;
- if ( **ptr == '\0' )
- return false;
- }
- return true;
-}
-
-static bool skip_nonwhitespace (char **ptr)
-{
- if ( *ptr == NULL )
- return false;
- while (! isspace(**ptr))
- {
- (*ptr)++;
- if ( **ptr == '\0' )
- return false;
- }
- return true;
-}
-
-static const char *get_second_word (char **ptr, const char *name)
-{
- /* Skip to the next word. */
- if ( !skip_nonwhitespace(ptr) || !skip_whitespace(ptr) )
- {
- fprintf(stderr, "ERROR: Too few arguments. '%s' needs one argument.\n", name);
- return NULL;
- }
-
- /* Now we know where the second word begins. */
- const char *second_word = *ptr;
-
- /* Check if there is a third word. */
- if ( skip_nonwhitespace(ptr) && skip_whitespace(ptr) )
- {
- fprintf(stderr, "ERROR: Too many arguments. '%s' needs one argument.\n", name);
- return NULL;
- }
-
- return second_word;
-}
-
-static void handle_uint32_command (char **ptr, uint32_t *value, const char *name)
-{
- const char *second_word = get_second_word(ptr, name);
- if ( second_word == NULL )
- return;
- const int32_t arg = atoi(second_word);
- if ( *second_word == '+' || *second_word == '-' )
- *value = (uint32_t)MAX((int32_t)*value + arg, 0);
- else
- *value = (uint32_t)MAX(arg, 0);
-}
-
-static void handle_float_command(char **ptr, double *value, const char *name, double clamp_upper, double clamp_lower)
-{
- const char *second_word = get_second_word(ptr, name);
- if ( second_word == NULL )
- return;
- const double arg = atof(second_word);
- if ( *second_word == '+' || *second_word == '-' )
- *value = CLAMP(*value + arg, clamp_upper, clamp_lower);
- else
- *value = CLAMP(arg, clamp_upper, clamp_lower);
-}
-
-static bool word_comp (const char *word, const char *comp)
-{
- if ( strncmp(word, comp, strlen(comp)) == 0 )
- {
- const char *after_comp = word + strlen(comp);
- if ( isspace(*after_comp) || *after_comp == '\0' )
- return true;
- }
- return false;
-
-}
-
-static void layout_handle_user_command (void *data, struct river_layout_v3 *river_layout_manager_v3,
- const char *_command)
-{
- /* The user_command event will be received whenever the user decided to
- * send us a command. As an example, commands can be used to change the
- * layout values. Parsing the commands is the job of the layout
- * generator, the server just sends us the raw string.
- *
- * After this event is recevied, the views on the output will be
- * re-arranged and so we will also receive a layout_demand event.
- */
-
- struct Output *output = (struct Output *)data;
-
- /* Skip preceding whitespace. */
- char *command = (char *)_command;
- if (! skip_whitespace(&command))
- return;
-
- if (word_comp(command, "main_count"))
- handle_uint32_command(&command, &output->main_count, "main_count");
- else if (word_comp(command, "view_padding"))
- handle_uint32_command(&command, &output->view_padding, "view_padding");
- else if (word_comp(command, "outer_padding"))
- handle_uint32_command(&command, &output->outer_padding, "outer_padding");
- else if (word_comp(command, "main_ratio"))
- handle_float_command(&command, &output->main_ratio, "main_ratio", 0.1, 0.9);
- else if (word_comp(command, "reset"))
- {
- /* This is an example of a command that does something different
- * than just modifying a value. It resets all values to their
- * defaults.
- */
-
- if ( skip_nonwhitespace(&command) && skip_whitespace(&command) )
- {
- fputs("ERROR: Too many arguments. 'reset' has no arguments.\n", stderr);
- return;
- }
-
- output->main_count = 1;
- output->main_ratio = 0.6;
- output->view_padding = 5;
- output->outer_padding = 5;
- }
- else
- fprintf(stderr, "ERROR: Unknown command: %s\n", command);
-}
-
-static const struct river_layout_v3_listener layout_listener = {
- .namespace_in_use = layout_handle_namespace_in_use,
- .layout_demand = layout_handle_layout_demand,
- .user_command = layout_handle_user_command,
-};
-
-static void configure_output (struct Output *output)
-{
- output->configured = true;
-
- /* The namespace of the layout is how the compositor chooses what layout
- * to use. It can be any arbitrary string. It should describe roughly
- * what kind of layout your client will create, so here we use "tile".
- */
- output->layout = river_layout_manager_v3_get_layout(layout_manager,
- output->output, "tile");
- river_layout_v3_add_listener(output->layout, &layout_listener, output);
-}
-
-static bool create_output (struct wl_output *wl_output)
-{
- struct Output *output = calloc(1, sizeof(struct Output));
- if ( output == NULL )
- {
- fputs("Failed to allocate.\n", stderr);
- return false;
- }
-
- output->output = wl_output;
- output->layout = NULL;
- output->configured = false;
-
- /* These are the parameters of our layout. In this case, they are the
- * ones you'd typically expect from a dynamic tiling layout, but if you
- * are creative, you can do more. You can use any arbitrary amount of
- * all kinds of values in your layout. If the user wants to change a
- * value, the server lets us know using user_command event of the
- * river_layout object.
- *
- * A layout generator is responsible for having sane defaults for all
- * layout values. The server only sends user_command events when there
- * actually is a command the user wants to send us.
- */
- output->main_count = 1;
- output->main_ratio = 0.6;
- output->view_padding = 5;
- output->outer_padding = 5;
-
- /* If we already have the river_layout_manager, we can get a
- * river_layout object for this output.
- */
- if ( layout_manager != NULL )
- configure_output(output);
-
- wl_list_insert(&outputs, &output->link);
- return true;
-}
-
-static void destroy_output (struct Output *output)
-{
- if ( output->layout != NULL )
- river_layout_v3_destroy(output->layout);
- wl_output_destroy(output->output);
- wl_list_remove(&output->link);
- free(output);
-}
-
-static void destroy_all_outputs ()
-{
- struct Output *output, *tmp;
- wl_list_for_each_safe(output, tmp, &outputs, link)
- destroy_output(output);
-}
-
-static void registry_handle_global (void *data, struct wl_registry *registry,
- uint32_t name, const char *interface, uint32_t version)
-{
- if ( strcmp(interface, river_layout_manager_v3_interface.name) == 0 )
- layout_manager = wl_registry_bind(registry, name,
- &river_layout_manager_v3_interface, 1);
- else if ( strcmp(interface, wl_output_interface.name) == 0 )
- {
- struct wl_output *wl_output = wl_registry_bind(registry, name,
- &wl_output_interface, version);
- if (! create_output(wl_output))
- {
- loop = false;
- ret = EXIT_FAILURE;
- }
- }
-}
-
-/* A no-op function we plug into listeners when we don't want to handle an event. */
-static void noop () {}
-
-static const struct wl_registry_listener registry_listener = {
- .global = registry_handle_global,
- .global_remove = noop
-};
-
-static void sync_handle_done (void *data, struct wl_callback *wl_callback,
- uint32_t irrelevant)
-{
- wl_callback_destroy(wl_callback);
- sync_callback = NULL;
-
- /* When this function is called, the registry finished advertising all
- * available globals. Let's check if we have everything we need.
- */
- if ( layout_manager == NULL )
- {
- fputs("Wayland compositor does not support river-layout-v3.\n", stderr);
- ret = EXIT_FAILURE;
- loop = false;
- return;
- }
-
- /* If outputs were registered before the river_layout_manager is
- * available, they won't have a river_layout, so we need to create those
- * here.
- */
- struct Output *output;
- wl_list_for_each(output, &outputs, link)
- if (! output->configured)
- configure_output(output);
-}
-
-static const struct wl_callback_listener sync_callback_listener = {
- .done = sync_handle_done,
-};
-
-static bool init_wayland (void)
-{
- /* We query the display name here instead of letting wl_display_connect()
- * figure it out itself, because libwayland (for legacy reasons) falls
- * back to using "wayland-0" when $WAYLAND_DISPLAY is not set, which is
- * generally not desirable.
- */
- const char *display_name = getenv("WAYLAND_DISPLAY");
- if ( display_name == NULL )
- {
- fputs("WAYLAND_DISPLAY is not set.\n", stderr);
- return false;
- }
-
- wl_display = wl_display_connect(display_name);
- if ( wl_display == NULL )
- {
- fputs("Can not connect to Wayland server.\n", stderr);
- return false;
- }
-
- wl_list_init(&outputs);
-
- /* The registry is a global object which is used to advertise all
- * available global objects.
- */
- wl_registry = wl_display_get_registry(wl_display);
- wl_registry_add_listener(wl_registry, ®istry_listener, NULL);
-
- /* The sync callback we attach here will be called when all previous
- * requests have been handled by the server. This allows us to know the
- * end of the startup, at which point all necessary globals should be
- * bound.
- */
- sync_callback = wl_display_sync(wl_display);
- wl_callback_add_listener(sync_callback, &sync_callback_listener, NULL);
-
- return true;
-}
-
-static void finish_wayland (void)
-{
- if ( wl_display == NULL )
- return;
-
- destroy_all_outputs();
-
- if ( sync_callback != NULL )
- wl_callback_destroy(sync_callback);
- if ( layout_manager != NULL )
- river_layout_manager_v3_destroy(layout_manager);
-
- wl_registry_destroy(wl_registry);
- wl_display_disconnect(wl_display);
-}
-
-int main (int argc, char *argv[])
-{
- if (init_wayland())
- {
- ret = EXIT_SUCCESS;
- while ( loop && wl_display_dispatch(wl_display) != -1 );
- }
- finish_wayland();
- return ret;
-}
diff --git a/contrib/layout.py b/contrib/layout.py
deleted file mode 100755
index 5313449..0000000
--- a/contrib/layout.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python3
-#
-# Fibonacci spiral layout for river, implemented in simple python. Reading this
-# code should help you get a basic understanding of how to use river-layout to
-# create a basic layout generator.
-#
-# This depends on pywayland: https://github.com/flacjacket/pywayland/
-#
-# Q: Wow, this looks complicated!
-# A: For simple layouts, you really only need to care about what's in the
-# layout_handle_layout_demand() function. And the rest isn't as complicated
-# as it looks.
-#
-# Q: The script runs but nothing happens! How can I see this layout?
-# A: Once started, to set this layout as default use the command:
-# riverctl default-layout layout.py
-
-import mmap
-import time
-from pywayland.client import Display
-from pywayland.protocol.wayland import WlOutput
-try:
- from pywayland.protocol.river_layout_v3 import RiverLayoutManagerV3
-except:
- river_layout_help = """
- Your pywayland package does not have bindings for river-layout-v3.
- You can generate the bindings with the following command:
- python3 -m pywayland.scanner -i /usr/share/wayland/wayland.xml river-layout-v3.xml
- It is recommended to use a virtual environment to avoid modifying your
- system-wide python installation, See: https://docs.python.org/3/library/venv.html
- """
- print(river_layout_help)
- quit()
-
-layout_manager = None
-outputs = []
-loop = True
-
-def layout_handle_layout_demand(layout, view_count, usable_w, usable_h, tags, serial):
- x = 0
- y = 0
- w = usable_w
- h = usable_h
- for i in range(0, view_count - 1):
- if i % 2 == 0:
- w //= 2
- if i % 4 == 2:
- layout.push_view_dimensions(x + w, y, w, h, serial)
- else:
- layout.push_view_dimensions(x, y, w, h, serial)
- x += w
- else:
- h //= 2
- if i % 4 == 3:
- layout.push_view_dimensions(x, y + h, w, h, serial)
- else:
- layout.push_view_dimensions(x, y, w, h, serial)
- y += h
- layout.push_view_dimensions(x, y, w, h, serial)
-
- # Committing the layout means telling the server that your code is done
- # laying out windows. Make sure you have pushed exactly the right amount of
- # view dimensions, a mismatch is a fatal protocol error.
- #
- # You also have to provide a layout name. This is a user facing string that
- # the server can forward to status bars. You can use it to tell the user
- # which layout is currently in use. You could also add some status
- # information status information about your layout, which is what we do here.
- layout.commit(f"{view_count} windows laid out by python", serial)
-
-def layout_handle_namespace_in_use(layout):
- # Oh no, the namespace we choose is already used by another client! All we
- # can do now is destroy the layout object. Because we are lazy, we just
- # abort and let our cleanup mechanism destroy it. A more sophisticated
- # client could instead destroy only the one single affected layout object
- # and recover from this mishap. Writing such a client is left as an exercise
- # for the reader.
- print("Namespace already in use!")
- global loop
- loop = False
-
-class Output(object):
- def __init__(self):
- self.output = None
- self.layout = None
- self.id = None
-
- def destroy(self):
- if self.layout is not None:
- self.layout.destroy()
- if self.output is not None:
- self.output.destroy()
-
- def configure(self):
- global layout_manager
- if self.layout is None and layout_manager is not None:
- # We need to set a namespace, which is used to identify our layout.
- self.layout = layout_manager.get_layout(self.output, "layout.py")
- self.layout.user_data = self
- self.layout.dispatcher["layout_demand"] = layout_handle_layout_demand
- self.layout.dispatcher["namespace_in_use"] = layout_handle_namespace_in_use
-
-def registry_handle_global(registry, id, interface, version):
- global layout_manager
- global output
- if interface == 'river_layout_manager_v3':
- layout_manager = registry.bind(id, RiverLayoutManagerV3, version)
- elif interface == 'wl_output':
- output = Output()
- output.output = registry.bind(id, WlOutput, version)
- output.id = id
- output.configure()
- outputs.append(output)
-
-def registry_handle_global_remove(registry, id):
- for output in outputs:
- if output.id == id:
- output.destroy()
- outputs.remove(output)
-
-display = Display()
-display.connect()
-
-registry = display.get_registry()
-registry.dispatcher["global"] = registry_handle_global
-registry.dispatcher["global_remove"] = registry_handle_global_remove
-
-display.dispatch(block=True)
-display.roundtrip()
-
-if layout_manager is None:
- print("No layout_manager, aborting")
- quit()
-
-for output in outputs:
- output.configure()
-
-while loop and display.dispatch(block=True) != -1:
- pass
-
-# Destroy outputs
-for output in outputs:
- output.destroy()
- outputs.remove(output)
-
-display.disconnect()
diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
deleted file mode 100644
index 01b05a1..0000000
--- a/doc/riverctl.1.scd
+++ /dev/null
@@ -1,562 +0,0 @@
-RIVERCTL(1)
-
-# NAME
-
-riverctl - command-line interface for controlling river
-
-# SYNOPSIS
-
-*riverctl* [_options_] _command_ [_command specific arguments_]
-
-# DESCRIPTION
-
-*riverctl* is a command-line utility used to control and configure river
-over the Wayland protocol.
-
-# OPTIONS
-
-*-h*
- Print a help message and exit.
-
-*-version*
- Print the version number and exit.
-
-# TERMINOLOGY
-
-This manual uses terms that some may find confusing, coming mostly from their
-usage among other Wayland projects.
-
-The *compositor*, display server, Wayland server etc. are ways to refer to river
-itself.
-
-A *view* (or *toplevel*) is what most call a window.
-
-An *output* is a synonym for a screen or monitor.
-
-*Tags* are river's way of dividing views of an output into groups (not
-necessarily disjunct), an analogy to workspaces.
-
-# COMMANDS
-
-## ACTIONS
-
-*close*
- Close the focused view.
-
-*exit*
- Exit the compositor, terminating the Wayland session.
-
-*focus-output* *next*|*previous*|*up*|*right*|*down*|*left*|_name_
- Focus the next or previous output, the closest output in any direction
- or an output by name.
-
-*focus-view* [*-skip-floating*] *next*|*previous*|*up*|*down*|*left*|*right*
- Focus the next or previous view in the stack or the closest view in
- any direction.
-
- - *-skip-floating*: Skip floating views, only focusing tiled ones.
-
-*move* *up*|*down*|*left*|*right* _delta_
- Move the focused view in the specified direction by _delta_ logical
- pixels. The view will be set to floating.
-
-*resize* *horizontal*|*vertical* _delta_
- Resize the focused view along the given axis by _delta_ logical
- pixels. The view will be set to floating.
-
-*snap* *up*|*down*|*left*|*right*
- Snap the focused view to the specified screen edge. The view will
- be set to floating.
-
-*send-to-output* [*-current-tags*] *next*|*previous*|*up*|*right*|*down*|*left*|_name_
- Send the focused view to the next or previous output, the closest
- output in any direction or to an output by name.
-
- - *-current-tags*: Assign the currently focused tags of the destination
- output to the view.
-
-*spawn* _shell_command_
- Run _shell_command_ using `/bin/sh -c _shell_command_`. Note that
- *spawn* only takes a single argument. To spawn a command taking
- multiple arguments, wrapping the command in quotes is recommended.
-
-*swap* *next*|*previous*|*up*|*down*|*left*|*right*
- Swap the focused view with the next or previous non-floating view in the
- stack or the closest non-floating view in any direction.
-
-*toggle-float*
- Toggle the floating state of the focused view.
-
-*toggle-fullscreen*
- Toggle the fullscreen state of the focused view.
-
-*zoom*
- Bump the focused view to the top of the layout stack. If the top
- view in the stack is already focused, bump the second view.
-
-*default-layout* _namespace_
- Set the layout namespace to be used by all outputs by default.
-
-*output-layout* _namespace_
- Set the layout namespace of currently focused output, overriding
- the value set with *default-layout* if any.
-
-*send-layout-cmd* _namespace_ _command_
- Send _command_ to the layout generator on the currently focused output
- with the given _namespace_, if any. What commands a layout generator
- understands depends on the layout generator. For rivertile, see the
- documentation in the *rivertile*(1) man page.
-
-## TAG MANAGEMENT
-
-Tags are similar to workspaces but more flexible. You can assign views multiple
-tags and focus multiple tags simultaneously. Bitfields are used to describe
-sets of tags when interfacing with river. As such, the following commands
-take a normal base 10 number as their argument but the semantics are best
-understood in binary. The binary number 000000001 represents a set containing
-only tag 1 while 100001101 represents a set containing tags 1, 3, 4, and 9.
-
-When a view spawns it is assigned the currently focused tags of the output.
-
-At least one tag must always be focused and each view must be assigned at
-least one tag. Operations that would violate either of these requirements
-are ignored by river.
-
-*set-focused-tags* _tags_
- Show views with tags corresponding to the set bits of _tags_ on the
- currently focused output.
-
-*set-view-tags* _tags_
- Assign the currently focused view the tags corresponding to the set
- bits of _tags_.
-
-*toggle-focused-tags* _tags_
- Toggle visibility of views with tags corresponding to the set bits
- of _tags_ on the currently focused output.
-
-*toggle-view-tags* _tags_
- Toggle the tags of the currently focused view corresponding to the
- set bits of _tags_.
-
-*spawn-tagmask* _tagmask_
- Set a _tagmask_ to filter the tags assigned to newly spawned views. This mask
- will be applied to the tags of new views with a bitwise and. If, for example,
- the tags 000011111 are focused and the spawn _tagmask_ is 111110001, a
- new view will be assigned the tags 000010001. If no tags would remain after
- filtering, the _tagmask_ is ignored.
-
-*focus-previous-tags*
- Sets tags to their previous value on the currently focused output,
- allowing jumping back and forth between 2 tag setups.
-
-*send-to-previous-tags*
- Assign the currently focused view the previous tags of the currently
- focused output.
-
-## MAPPINGS
-
-Mappings are modal in river. Each mapping is associated with a mode and
-is only active while in that mode. There are two special modes: "normal"
-and "locked". The normal mode is the initial mode on startup. The locked
-mode is automatically entered while the session is locked (e.g. due to
-a screenlocker). It cannot be entered or exited manually.
-
-The following modifiers are available for use in mappings:
-
- - Shift
- - Control
- - Mod1 (Alt)
- - Mod3
- - Mod4 (Super)
- - Mod5
- - None
-
-Alt and Super are aliases for Mod1 and Mod4 respectively. None allows creating
-a mapping without modifiers.
-
-Keys are specified by their XKB keysym name. See
-_/usr/include/xkbcommon/xkbcommon-keysyms.h_ for the complete list.
-
-Mouse buttons are specified by Linux input event code names. The most commonly
-used values are:
-
- - BTN_LEFT - left mouse button
- - BTN_RIGHT - right mouse button
- - BTN_MIDDLE - middle mouse button
-
-A complete list may be found in _/usr/include/linux/input-event-codes.h_
-
-*declare-mode* _name_
- Create a new mode called _name_.
-
-*enter-mode* _name_
- Switch to given mode if it exists.
-
-*map* [*-release*|*-repeat*|*-layout* _index_] _mode_ _modifiers_ _key_ _command_
- Run _command_ when _key_ is pressed while _modifiers_ are held down
- and in the specified _mode_.
-
- - *-release*: if passed activate on key release instead of key press
- - *-repeat*: if passed activate repeatedly until key release; may not
- be used with *-release*
- - *-layout*: if passed, a specific layout is pinned to the mapping.
- When the mapping is checked against a pressed key, this layout is
- used to translate the key independent of the active layout
- - _index_: zero-based index of a layout set with the *keyboard-layout*
- command. If the index is out of range, the *-layout* option will
- have no effect
- - _mode_: name of the mode for which to create the mapping
- - _modifiers_: one or more of the modifiers listed above, separated
- by a plus sign (+).
- - _key_: an XKB keysym name as described above
- - _command_: any command that may be run with riverctl
-
-*map-pointer* _mode_ _modifiers_ _button_ _action_|_command_
- Move or resize views or run _command_ when _button_ and _modifiers_ are held
- down while in the specified _mode_. The view under the cursor will be
- focused.
-
- - _mode_: name of the mode for which to create the mapping
- - _modifiers_: one or more of the modifiers listed above, separated
- by a plus sign (+).
- - _button_: the name of a Linux input event code as described above
- - _action_: one of the following values:
- - move-view
- - resize-view
- - _command_: any command that may be run with riverctl
-
-*map-switch* _mode_ *lid*|*tablet* _state_ _command_
- Run _command_ when river receives a certain switch event.
-
- - _mode_: name of the mode for which to create the mapping
- - _lid_|_tablet_: 'lid switch' and 'tablet mode switch' are supported
- - _state_:
- - possible states for _lid_:
- - close
- - open
- - possible states for _tablet_:
- - on
- - off
- - _command_: any command that may be run with riverctl
-
-*unmap* [*-release*] _mode_ _modifiers_ _key_
- Remove the mapping defined by the arguments:
-
- - *-release*: if passed unmap the key release instead of the key press
- - _mode_: name of the mode for which to remove the mapping
- - _modifiers_: one or more of the modifiers listed above, separated
- by a plus sign (+).
- - _key_: an XKB keysym name as described above
-
-*unmap-pointer* _mode_ _modifiers_ _button_
- Remove the pointer mapping defined by the arguments:
-
- - _mode_: name of the mode for which to remove the mapping
- - _modifiers_: one or more of the modifiers listed above, separated
- by a plus sign (+).
- - _button_: the name of a Linux input event code as described above
-
-*unmap-switch* _mode_ *lid*|*tablet* _state_
- Remove the switch mapping defined by the arguments:
-
- - _mode_: name of the mode for which to remove the mapping
- - _lid_|_tablet_: the switch for which to remove the mapping
- - _state_: a state as listed above
-
-## RULES
-
-Rules match the app-id and title of views against a _glob_ pattern. A _glob_
-is a string that may optionally have an _\*_ at the beginning and/or end. An
-_\*_ in a _glob_ matches zero or more arbitrary characters in the app-id
-or title.
-
-For example, _abc_ is matched by _a\*_, _\*a\*_, _\*b\*_, _\*c_, _abc_, and
-_\*_ but not matched by _\*a_, _b\*_, _\*b_, _c\*_, or _ab_. Note that _\*_
-matches everything while _\*\*_ and the empty string are invalid.
-
-*rule-add* [*-app-id* _glob_|*-title* _glob_] _action_ [_arguments_]
- Add a rule that applies an _action_ to views with *app-id* and *title*
- matched by the respective _glob_. Omitting *-app-id* or *-title*
- is equivalent to passing *-app-id* _\*_ or *-title* _\*_.
- Some actions require one or more _arguments_.
-
- The supported _action_ types are:
-
- - *float*: Make the view floating. Applies only to new views.
- - *no-float*: Don't make the view floating. Applies only to
- new views.
- - *ssd*: Use server-side decorations for the view. Applies to new
- and existing views.
- - *csd*: Use client-side decorations for the view. Applies to new
- and existing views.
- - *tags*: Set the initial tags of the view. Requires the tags as
- an argument. Applies only to new views.
- - *output*: Set the initial output of the view. Requires the output
- as an argument. Applies only to new views. The output can be specified
- either by connector name (such as _HDMI-A-1_, or _DP-2_), or by
- identifier in the form of _MAKE MODEL SERIAL_, for example for an output
- with make: _HP Inc._, model: _HP 22w_, and serial: _CNC93720WF_, the
- identifier would be: _HP Inc. HP 22w CNC93720WF_. If the make, model, or
- serial is unknown, the word "Unknown" is used instead.
- - *position*: Set the initial position of the view, clamping to the
- bounds of the output. Requires x and y coordinates of the view as
- arguments, both of which must be non-negative. Applies only to new views.
- - *dimensions*: Set the initial dimensions of the view, clamping to the
- constraints of the view. Requires width and height of the view as
- arguments, both of which must be non-negative. Applies only to new views.
- - *fullscreen*: Make the view fullscreen. Applies only to new views.
- - *no-fullscreen*: Don't make the view fullscreen. Applies only to
- new views.
-
- Both *float* and *no-float* rules are added to the same list,
- which means that adding a *no-float* rule with the same arguments
- as a *float* rule will overwrite it. The same holds for *ssd* and
- *csd*, *fullscreen* and *no-fullscreen* rules.
-
- If multiple rules in a list match a given view the most specific
- rule will be applied. For example with the following rules
- ```
- app-id title action
- foo bar ssd
- foo * csd
- * bar csd
- * baz ssd
- ```
- a view with app-id 'foo' and title 'bar' would get ssd despite matching
- two csd rules as the first rule is most specific. Furthermore a view
- with app-id 'foo' and title 'baz' would get csd despite matching the
- last rule in the list since app-id specificity takes priority over
- title specificity.
-
- If a view is not matched by any rule, river will respect the csd/ssd
- wishes of the client and may start the view floating based on simple
- heuristics intended to catch popup-like views.
-
- If a view is started fullscreen or is not floating, then *position* and
- *dimensions* rules will have no effect A view must be matched by a *float*
- rule in order for them to take effect.
-
-*rule-del* [*-app-id* _glob_|*-title* _glob_] _action_
- Delete a rule created using *rule-add* with the given arguments.
-
-*list-rules* *float*|*ssd*|*tags*|*position*|*dimensions*|*fullscreen*
- Print the specified rule list. The output is ordered from most specific
- to least specific, the same order in which views are checked against
- when searching for a match. Only the first matching rule in the list
- has an effect on a given view.
-
-## CONFIGURATION
-
-*default-attach-mode* *top*|*bottom*|*above*|*below*|*after <N>*
- Set the attach mode to be used by all outputs by default.
-
- Possible values:
- - top: Prepends the newly spawned view at the top of the stack.
- - bottom: Appends the newly spawned view at the bottom of the stack.
- - above: Inserts the newly spawned view above the currently focused view.
- - below: Inserts the newly spawned view below the currently focused view.
- - after <N>: Inserts the newly spawned view after N views in the stack.
-
- Note that the deprecated *attach-mode* command is aliased to
- *default-attach-mode* for backwards compatibility.
-
-*output-attach-mode* *top*|*bottom*|*above*|*below*|*after <N>*
- Set the attach mode of the currently focused output, overriding the value of
- default-attach-mode if any.
-
-*background-color* _0xRRGGBB_|_0xRRGGBBAA_
- Set the background color.
-
-*border-color-focused* _0xRRGGBB_|_0xRRGGBBAA_
- Set the border color of focused views.
-
-*border-color-unfocused* _0xRRGGBB_|_0xRRGGBBAA_
- Set the border color of unfocused views.
-
-*border-color-urgent* _0xRRGGBB_|_0xRRGGBBAA_
- Set the border color of urgent views.
-
-*border-width* _pixels_
- Set the border width to _pixels_.
-
-*focus-follows-cursor* *disabled*|*normal*|*always*
- There are three available modes:
-
- - _disabled_: Moving the cursor does not affect focus. This is
- the default.
- - _normal_: Moving the cursor over a view will focus that view.
- Moving the cursor within a view will not re-focus that view if
- focus has moved elsewhere.
- - _always_: Moving the cursor will always focus whatever view is
- under the cursor.
-
- If the view to be focused is on an output that does not have focus,
- focus is switched to that output.
-
-*hide-cursor* *timeout* _timeout_
- Hide the cursor if it wasn't moved in the last _timeout_ milliseconds
- until it is moved again. The default value is 0, which disables
- automatically hiding the cursor. Show the cursor again on any movement.
-
-*hide-cursor* *when-typing* *enabled*|*disabled*
- Hide the cursor when pressing any non-modifier key. Show the cursor
- again on any movement.
-
-*set-cursor-warp* *disabled*|*on-output-change*|*on-focus-change*
- Set the cursor warp mode. There are two available modes:
-
- - _disabled_: Cursor will not be warped. This is the default.
- - _on-output-change_: When a different output is focused, the cursor will be
- warped to its center.
- - _on-focus-change_: When a different view/output is focused, the cursor will be
- warped to its center.
-
-*set-repeat* _rate_ _delay_
- Set the keyboard repeat rate to _rate_ key repeats per second and
- repeat delay to _delay_ milliseconds.
-
-*xcursor-theme* _theme_name_ [_size_]
- Set the xcursor theme to _theme_name_ and optionally set the _size_.
- The theme of the default seat determines the default for Xwayland
- and is made available through the _XCURSOR_THEME_ and _XCURSOR_SIZE_
- environment variables.
-
-## INPUT CONFIGURATION
-
-*list-inputs*
- List all input devices.
-
-*list-input-configs*
- List all input configurations.
-
-*keyboard-layout* [-rules _rules_] [-model _model_] [-variant _variant_] \
-[-options _options_] _layout_
- Set the XKB layout for all keyboards. Defaults from libxkbcommon are used for
- everything left unspecified. Note that _layout_ may be a comma separated list
- of layouts (e.g. "us,de") which may be switched between using various key
- combinations configured through the options argument (e.g. -options
- "grp:ctrl_space_toggle"). See *xkeyboard-config*(7) for possible values and
- more information.
-
-*keyboard-layout-file* _path_
- Set the XKB layout for all keyboards from an XKB keymap file at the provided
- path. Documentation for the XKB keymap file format can be found at the
- following URL:
- https://xkbcommon.org/doc/current/keymap-text-format-v1.html
-
-*keyboard-group-create* _group_name_
- Create a keyboard group. A keyboard group collects multiple keyboards in
- a single logical keyboard. This means that all state, like the active
- modifiers, is shared between the keyboards in a group.
-
-*keyboard-group-destroy* _group_name_
- Destroy the keyboard group with the given name. All attached keyboards
- will be released, making them act as separate devices again.
-
-*keyboard-group-add* _group_name_ _input_device_name_
- Add a keyboard to a keyboard group, identified by the keyboard's
- input device name. Any currently connected and future keyboards with
- the given name will be added to the group. Simple globbing patterns are
- supported, see the rules section for further information on globs.
-
-*keyboard-group-remove* _group_name_ _input_device_name_
- Remove a keyboard from a keyboard group, identified by the keyboard's
- input device name.
-
-The _input_ command can be used to create a configuration rule for an input
-device identified by its _name_.
-The _name_ of an input device consists of its type, its numerical vendor id,
-its numerical product id and finally its self-advertised name, separated by -.
-Simple globbing patterns are supported, see the rules section for further
-information on globs.
-
-A list of all device properties that can be configured may be found below.
-However note that not every input device supports every property.
-
-*input* _name_ *events* *enabled*|*disabled*|*disabled-on-external-mouse*
- Configure whether the input devices events will be used by river.
-
-*input* _name_ *accel-profile* *none*|*flat*|*adaptive*
- Set the pointer acceleration profile of the input device.
-
-*input* _name_ *pointer-accel* _factor_
- Set the pointer acceleration factor of the input device. Needs a float
- between -1.0 and 1.0.
-
-*input* _name_ *click-method* *none*|*button-areas*|*clickfinger*
- Set the click method of the input device.
-
-*input* _name_ *drag* *enabled*|*disabled*
- Enable or disable the tap-and-drag functionality of the input device.
-
-*input* _name_ *drag-lock* *enabled*|*disabled*
- Enable or disable the drag lock functionality of the input device.
-
-*input* _name_ *disable-while-typing* *enabled*|*disabled*
- Enable or disable the disable-while-typing functionality of the input device.
-
-*input* _name_ *disable-while-trackpointing* *enabled*|*disabled*
- Enable or disable the disable-while-trackpointing functionality of the input device.
-
-*input* _name_ *middle-emulation* *enabled*|*disabled*
- Enable or disable the middle click emulation functionality of the input device.
-
-*input* _name_ *natural-scroll* *enabled*|*disabled*
- Enable or disable the natural scroll functionality of the input device. If
- active, the scroll direction is inverted.
-
-*input* _name_ *scroll-factor* _factor_
- Set the scroll factor of the input device. Accepts a postive value
- greater than 0. For example, a _factor_ of 0.5 will make scrolling twice
- as slow while a _factor_ of 3 will make scrolling 3 times as fast.
-
-*input* _name_ *left-handed* *enabled*|*disabled*
- Enable or disable the left handed mode of the input device.
-
-*input* _name_ *tap* *enabled*|*disabled*
- Enable or disable the tap functionality of the input device.
-
-*input* _name_ *tap-button-map* *left-right-middle*|*left-middle-right*
- Configure the button mapping for tapping.
-
- - _left-right-middle_: 1 finger tap equals left click, 2 finger tap equals
- right click, 3 finger tap equals middle click.
- - _left-middle-right_: 1 finger tap equals left click, 2 finger tap equals
- middle click, 3 finger tap equals right click.
-
-*input* _name_ *scroll-method* *none*|*two-finger*|*edge*|*button*
- Set the scroll method of the input device.
-
- - _none_: No scrolling
- - _two-finger_: Scroll by swiping with two fingers simultaneously
- - _edge_: Scroll by swiping along the edge
- - _button_: Scroll with pointer movement while holding down a button
-
-*input* _name_ *scroll-button* _button_
- Set the scroll button of an input device. _button_ is the name of a Linux
- input event code.
-
-*input* _name_ *map-to-output* _output_|*disabled*
- Maps the input to a given output. This is valid even if the output isn't
- currently active and will lead to the device being mapped once it is
- connected.
-
-# EXAMPLES
-
-Bind Super+Return in normal mode to spawn a *foot*(1) terminal:
-
- riverctl map normal Mod4 Return spawn 'foot --app-id=foobar'
-
-Bind Super+Shift+J to swap the focused view with the next visible view:
-
- riverctl map normal Mod4+Shift J swap next
-
-# AUTHORS
-
-Maintained by Isaac Freund <[email protected]> who is assisted by open
-source contributors. For more information about river's development, see
-<https://isaacfreund.com/software/river>.
-
-# SEE ALSO
-
-*river*(1), *rivertile*(1)
diff --git a/doc/rivertile.1.scd b/doc/rivertile.1.scd
deleted file mode 100644
index a73ebde..0000000
--- a/doc/rivertile.1.scd
+++ /dev/null
@@ -1,88 +0,0 @@
-RIVERTILE(1)
-
-# NAME
-
-rivertile - tiled layout generator for river
-
-# SYNOPSIS
-
-*rivertile* [_options_]
-
-# DESCRIPTION
-
-*rivertile* is a layout generator for *river*(1). It provides a simple tiled
-layout with split main/secondary stacks. The initial state may be configured
-with various options passed on startup. Some values may additionally be
-modified while rivertile is running with the help of *riverctl*(1).
-
-# OPTIONS
-
-*-h*
- Print a help message and exit.
-
-*-version*
- Print the version number and exit.
-
-*-view-padding* _pixels_
- Set the padding around views in pixels. (Default: 6)
-
-*-outer-padding* _pixels_
- Set the padding around the edge of the layout area in pixels.
- (Default: 6)
-
-*-main-location* [*top*|*bottom*|*left*|*right*]
- Set the initial location of the main area in the layout.
- (Default: *left*)
-
-*-main-count* _count_
- Set the initial number of views in the main area of the
- layout. (Default: 1)
-
-*-main-ratio* _ratio_
- Set the initial ratio of the main area to total layout area. The
- _ratio_ must be between 0.1 and 0.9, inclusive. (Default: 0.6)
-
-# COMMANDS
-
-These commands may be sent to rivertile at runtime with the help of
-*riverctl*(1).
-
-*main-location* [*top*|*bottom*|*left*|*right*]
- Set the location of the main area in the layout.
-
-*main-count* _value_
- Set or modify the number of views in the main area of the layout. If
- _value_ is prefixed by a +/- sign, _value_ is added/subtracted from the
- current count. If there is no sign, the main count is set to _value_.
- Note that the main count cannot be decreased below 1.
-
-*main-ratio* _value_
- Set or modify the ratio of the main area to total layout area. If
- _value_ is prefixed by a +/- sign, _value_ is added/subtracted from
- the current ratio. If there is no sign, the main ratio is set to
- _value_. Note that the ratio will always be clamped to the range
- 0.1 to 0.9.
-
-# EXAMPLES
-
-Start *rivertile* with 4 pixels outer padding and the *top* main location:
-
- rivertile -outer-padding 4 -main-location top
-
-Increase the main ratio by 0.1 at runtime:
-
- riverctl send-layout-cmd rivertile "main-ratio +0.1"
-
-Set the main count to 3 at runtime:
-
- riverctl send-layout-cmd rivertile "main-count 3"
-
-# AUTHORS
-
-Maintained by Isaac Freund <[email protected]> who is assisted by open
-source contributors. For more information about river's development, see
-<https://isaacfreund.com/software/river>.
-
-# SEE ALSO
-
-*river*(1), *riverctl*(1)
diff --git a/example/init b/example/init
deleted file mode 100755
index 06595b5..0000000
--- a/example/init
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/bin/sh
-
-# This is the example configuration file for river.
-#
-# If you wish to edit this, you will probably want to copy it to
-# $XDG_CONFIG_HOME/river/init or $HOME/.config/river/init first.
-#
-# See the river(1), riverctl(1), and rivertile(1) man pages for complete
-# documentation.
-
-# Note: the "Super" modifier is also known as Logo, GUI, Windows, Mod4, etc.
-
-# Super+Shift+Return to start an instance of foot (https://codeberg.org/dnkl/foot)
-riverctl map normal Super+Shift Return spawn foot
-
-# Super+Q to close the focused view
-riverctl map normal Super Q close
-
-# Super+Shift+E to exit river
-riverctl map normal Super+Shift E exit
-
-# Super+J and Super+K to focus the next/previous view in the layout stack
-riverctl map normal Super J focus-view next
-riverctl map normal Super K focus-view previous
-
-# Super+Shift+J and Super+Shift+K to swap the focused view with the next/previous
-# view in the layout stack
-riverctl map normal Super+Shift J swap next
-riverctl map normal Super+Shift K swap previous
-
-# Super+Period and Super+Comma to focus the next/previous output
-riverctl map normal Super Period focus-output next
-riverctl map normal Super Comma focus-output previous
-
-# Super+Shift+{Period,Comma} to send the focused view to the next/previous output
-riverctl map normal Super+Shift Period send-to-output next
-riverctl map normal Super+Shift Comma send-to-output previous
-
-# Super+Return to bump the focused view to the top of the layout stack
-riverctl map normal Super Return zoom
-
-# Super+H and Super+L to decrease/increase the main ratio of rivertile(1)
-riverctl map normal Super H send-layout-cmd rivertile "main-ratio -0.05"
-riverctl map normal Super L send-layout-cmd rivertile "main-ratio +0.05"
-
-# Super+Shift+H and Super+Shift+L to increment/decrement the main count of rivertile(1)
-riverctl map normal Super+Shift H send-layout-cmd rivertile "main-count +1"
-riverctl map normal Super+Shift L send-layout-cmd rivertile "main-count -1"
-
-# Super+Alt+{H,J,K,L} to move views
-riverctl map normal Super+Alt H move left 100
-riverctl map normal Super+Alt J move down 100
-riverctl map normal Super+Alt K move up 100
-riverctl map normal Super+Alt L move right 100
-
-# Super+Alt+Control+{H,J,K,L} to snap views to screen edges
-riverctl map normal Super+Alt+Control H snap left
-riverctl map normal Super+Alt+Control J snap down
-riverctl map normal Super+Alt+Control K snap up
-riverctl map normal Super+Alt+Control L snap right
-
-# Super+Alt+Shift+{H,J,K,L} to resize views
-riverctl map normal Super+Alt+Shift H resize horizontal -100
-riverctl map normal Super+Alt+Shift J resize vertical 100
-riverctl map normal Super+Alt+Shift K resize vertical -100
-riverctl map normal Super+Alt+Shift L resize horizontal 100
-
-# Super + Left Mouse Button to move views
-riverctl map-pointer normal Super BTN_LEFT move-view
-
-# Super + Right Mouse Button to resize views
-riverctl map-pointer normal Super BTN_RIGHT resize-view
-
-# Super + Middle Mouse Button to toggle float
-riverctl map-pointer normal Super BTN_MIDDLE toggle-float
-
-for i in $(seq 1 9)
-do
- tags=$((1 << ($i - 1)))
-
- # Super+[1-9] to focus tag [0-8]
- riverctl map normal Super $i set-focused-tags $tags
-
- # Super+Shift+[1-9] to tag focused view with tag [0-8]
- riverctl map normal Super+Shift $i set-view-tags $tags
-
- # Super+Control+[1-9] to toggle focus of tag [0-8]
- riverctl map normal Super+Control $i toggle-focused-tags $tags
-
- # Super+Shift+Control+[1-9] to toggle tag [0-8] of focused view
- riverctl map normal Super+Shift+Control $i toggle-view-tags $tags
-done
-
-# Super+0 to focus all tags
-# Super+Shift+0 to tag focused view with all tags
-all_tags=$(((1 << 32) - 1))
-riverctl map normal Super 0 set-focused-tags $all_tags
-riverctl map normal Super+Shift 0 set-view-tags $all_tags
-
-# Super+Space to toggle float
-riverctl map normal Super Space toggle-float
-
-# Super+F to toggle fullscreen
-riverctl map normal Super F toggle-fullscreen
-
-# Super+{Up,Right,Down,Left} to change layout orientation
-riverctl map normal Super Up send-layout-cmd rivertile "main-location top"
-riverctl map normal Super Right send-layout-cmd rivertile "main-location right"
-riverctl map normal Super Down send-layout-cmd rivertile "main-location bottom"
-riverctl map normal Super Left send-layout-cmd rivertile "main-location left"
-
-# Declare a passthrough mode. This mode has only a single mapping to return to
-# normal mode. This makes it useful for testing a nested wayland compositor
-riverctl declare-mode passthrough
-
-# Super+F11 to enter passthrough mode
-riverctl map normal Super F11 enter-mode passthrough
-
-# Super+F11 to return to normal mode
-riverctl map passthrough Super F11 enter-mode normal
-
-# Various media key mapping examples for both normal and locked mode which do
-# not have a modifier
-for mode in normal locked
-do
- # Eject the optical drive (well if you still have one that is)
- riverctl map $mode None XF86Eject spawn 'eject -T'
-
- # Control pulse audio volume with pamixer (https://github.com/cdemoulins/pamixer)
- riverctl map $mode None XF86AudioRaiseVolume spawn 'pamixer -i 5'
- riverctl map $mode None XF86AudioLowerVolume spawn 'pamixer -d 5'
- riverctl map $mode None XF86AudioMute spawn 'pamixer --toggle-mute'
-
- # Control MPRIS aware media players with playerctl (https://github.com/altdesktop/playerctl)
- riverctl map $mode None XF86AudioMedia spawn 'playerctl play-pause'
- riverctl map $mode None XF86AudioPlay spawn 'playerctl play-pause'
- riverctl map $mode None XF86AudioPrev spawn 'playerctl previous'
- riverctl map $mode None XF86AudioNext spawn 'playerctl next'
-
- # Control screen backlight brightness with brightnessctl (https://github.com/Hummer12007/brightnessctl)
- riverctl map $mode None XF86MonBrightnessUp spawn 'brightnessctl set +5%'
- riverctl map $mode None XF86MonBrightnessDown spawn 'brightnessctl set 5%-'
-done
-
-# Set background and border color
-riverctl background-color 0x002b36
-riverctl border-color-focused 0x93a1a1
-riverctl border-color-unfocused 0x586e75
-
-# Set keyboard repeat rate
-riverctl set-repeat 50 300
-
-# Make all views with an app-id that starts with "float" and title "foo" start floating.
-riverctl rule-add -app-id 'float*' -title 'foo' float
-
-# Make all views with app-id "bar" and any title use client-side decorations
-riverctl rule-add -app-id "bar" csd
-
-# Set the default layout generator to be rivertile and start it.
-# River will send the process group of the init executable SIGTERM on exit.
-riverctl default-layout rivertile
-rivertile -view-padding 6 -outer-padding 6 &
diff --git a/protocol/river-control-unstable-v1.xml b/protocol/river-control-unstable-v1.xml
deleted file mode 100644
index aa5fc4d..0000000
--- a/protocol/river-control-unstable-v1.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="river_control_unstable_v1">
- <copyright>
- Copyright 2020 The River Developers
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- </copyright>
-
- <interface name="zriver_control_v1" version="1">
- <description summary="run compositor commands">
- This interface allows clients to run compositor commands and receive a
- success/failure response with output or a failure message respectively.
-
- Each command is built up in a series of add_argument requests and
- executed with a run_command request. The first argument is the command
- to be run.
-
- A complete list of commands should be made available in the man page of
- the compositor.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="destroy the river_control object">
- This request indicates that the client will not use the
- river_control object any more. Objects that have been created
- through this instance are not affected.
- </description>
- </request>
-
- <request name="add_argument">
- <description summary="add an argument to the current command">
- Arguments are stored by the server in the order they were sent until
- the run_command request is made.
- </description>
- <arg name="argument" type="string" summary="the argument to add"/>
- </request>
-
- <request name="run_command">
- <description summary="run the current command">
- Execute the command built up using the add_argument request for the
- given seat.
- </description>
- <arg name="seat" type="object" interface="wl_seat"/>
- <arg name="callback" type="new_id" interface="zriver_command_callback_v1"
- summary="callback object"/>
- </request>
- </interface>
-
- <interface name="zriver_command_callback_v1" version="1">
- <description summary="callback object">
- This object is created by the run_command request. Exactly one of the
- success or failure events will be sent. This object will be destroyed
- by the compositor after one of the events is sent.
- </description>
-
- <event name="success" type="destructor">
- <description summary="command successful">
- Sent when the command has been successfully received and executed by
- the compositor. Some commands may produce output, in which case the
- output argument will be a non-empty string.
- </description>
- <arg name="output" type="string" summary="the output of the command"/>
- </event>
-
- <event name="failure" type="destructor">
- <description summary="command failed">
- Sent when the command could not be carried out. This could be due to
- sending a non-existent command, no command, not enough arguments, too
- many arguments, invalid arguments, etc.
- </description>
- <arg name="failure_message" type="string"
- summary="a message explaining why failure occurred"/>
- </event>
- </interface>
-</protocol>
diff --git a/protocol/river-layout-v3.xml b/protocol/river-layout-v3.xml
deleted file mode 100644
index 8a1bdce..0000000
--- a/protocol/river-layout-v3.xml
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="river_layout_v3">
- <copyright>
- Copyright 2020-2021 The River Developers
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- </copyright>
-
- <description summary="let clients propose view positions and dimensions">
- This protocol specifies a way for clients to propose arbitrary positions
- and dimensions for a set of views on a specific output of a compositor
- through the river_layout_v3 object.
-
- Layouts are a strictly linear list of views, the position and dimensions
- of which are supplied by the client. Any complex underlying data structure
- a client may use when generating the layout is lost in transmission. This
- is an intentional limitation.
-
- Additionally, this protocol allows the compositor to deliver arbitrary
- user-provided commands associated with a layout to clients. A client
- may use these commands to implement runtime configuration/control, or
- may ignore them entirely. How the user provides these commands to the
- compositor is not specified by this protocol and left to compositor policy.
-
- Warning! The protocol described in this file is currently in the
- testing phase. Backward compatible changes may be added together with
- the corresponding interface version bump. Backward incompatible changes
- can only be done by creating a new major version of the extension.
- </description>
-
- <interface name="river_layout_manager_v3" version="2">
- <description summary="manage river layout objects">
- A global factory for river_layout_v3 objects.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="destroy the river_layout_manager object">
- This request indicates that the client will not use the
- river_layout_manager object any more. Objects that have been created
- through this instance are not affected.
- </description>
- </request>
-
- <request name="get_layout">
- <description summary="create a river_layout_v3 object">
- This creates a new river_layout_v3 object for the given wl_output.
-
- All layout related communication is done through this interface.
-
- The namespace is used by the compositor to decide which river_layout_v3
- object will receive layout demands for the output.
-
- The namespace is required to be be unique per-output. Furthermore,
- two separate clients may not share a namespace on separate outputs. If
- these conditions are not upheld, the the namespace_in_use event will
- be sent directly after creation of the river_layout_v3 object.
- </description>
- <arg name="id" type="new_id" interface="river_layout_v3"/>
- <arg name="output" type="object" interface="wl_output"/>
- <arg name="namespace" type="string" summary="namespace of the layout object"/>
- </request>
- </interface>
-
- <interface name="river_layout_v3" version="2">
- <description summary="receive and respond to layout demands">
- This interface allows clients to receive layout demands from the
- compositor for a specific output and subsequently propose positions and
- dimensions of individual views.
- </description>
-
- <enum name="error">
- <entry name="count_mismatch" value="0" summary="number of
- proposed dimensions does not match number of views in layout"/>
- <entry name="already_committed" value="1" summary="the layout demand with
- the provided serial was already committed"/>
- </enum>
-
- <request name="destroy" type="destructor">
- <description summary="destroy the river_layout_v3 object">
- This request indicates that the client will not use the river_layout_v3
- object any more.
- </description>
- </request>
-
- <event name="namespace_in_use">
- <description summary="the requested namespace is already in use">
- After this event is sent, all requests aside from the destroy event
- will be ignored by the server. If the client wishes to try again with
- a different namespace they must create a new river_layout_v3 object.
- </description>
- </event>
-
- <event name="layout_demand">
- <description summary="the compositor requires a layout">
- The compositor sends this event to inform the client that it requires a
- layout for a set of views.
-
- The usable width and height indicate the space in which the client
- can safely position views without interfering with desktop widgets
- such as panels.
-
- The serial of this event is used to identify subsequent requests as
- belonging to this layout demand. Beware that the client might need
- to handle multiple layout demands at the same time.
-
- The server will ignore responses to all but the most recent layout
- demand. Thus, clients are only required to respond to the most recent
- layout_demand received. If a newer layout_demand is received before
- the client has finished responding to an old demand, the client should
- abort work on the old demand as any further work would be wasted.
- </description>
- <arg name="view_count" type="uint" summary="number of views in the layout"/>
- <arg name="usable_width" type="uint" summary="width of the usable area"/>
- <arg name="usable_height" type="uint" summary="height of the usable area"/>
- <arg name="tags" type="uint" summary="tags of the output, 32-bit bitfield"/>
- <arg name="serial" type="uint" summary="serial of the layout demand"/>
- </event>
-
- <request name="push_view_dimensions">
- <description summary="propose dimensions of the next view">
- This request proposes a size and position for a view in the layout demand
- with matching serial.
-
- A client must send this request for every view that is part of the
- layout demand. The number of views in the layout is given by the
- view_count argument of the layout_demand event. Pushing too many or
- too few view dimensions is a protocol error.
-
- The x and y coordinates are relative to the usable area of the output,
- with (0,0) as the top left corner.
- </description>
- <arg name="x" type="int" summary="x coordinate of view"/>
- <arg name="y" type="int" summary="y coordinate of view"/>
- <arg name="width" type="uint" summary="width of view"/>
- <arg name="height" type="uint" summary="height of view"/>
- <arg name="serial" type="uint" summary="serial of layout demand"/>
- </request>
-
- <request name="commit">
- <description summary="commit a layout">
- This request indicates that the client is done pushing dimensions
- and the compositor may apply the layout. This completes the layout
- demand with matching serial, any other requests sent with the serial
- are a protocol error.
-
- The layout_name argument is a user-facing name or short description
- of the layout that is being committed. The compositor may for example
- display this on a status bar, though what exactly is done with it is
- left to the compositor's discretion.
-
- The compositor is free to use this proposed layout however it chooses,
- including ignoring it.
- </description>
- <arg name="layout_name" type="string" summary="name of committed layout"/>
- <arg name="serial" type="uint" summary="serial of layout demand"/>
- </request>
-
- <event name="user_command">
- <description summary="a command sent by the user">
- This event informs the client of a command sent to it by the user.
-
- The semantic meaning of the command is left for the client to
- decide. It is also free to ignore it entirely if it so chooses.
-
- A layout_demand will be sent after this event if the compositor is
- currently using this layout object to arrange the output.
-
- If version 2 or higher of the river_layout_v3 object is bound, the
- user_command_tags event is guaranteed to be sent directly before the
- user_command event.
- </description>
- <arg name="command" type="string"/>
- </event>
-
- <event name="user_command_tags" since="2">
- <description summary="a command sent by the user">
- If version 2 or higher of the river_layout_v3 object is bound, this
- event will be sent directly before every user_command event. This allows
- layout generators to be aware of the active tags when a user command is
- sent. This is necessary for generators wanting to keep settings on a
- per-tag basis.
- </description>
- <arg name="tags" type="uint" summary="tags of the output, 32-bit bitfield"/>
- </event>
- </interface>
-</protocol>
diff --git a/riverctl/main.zig b/riverctl/main.zig
deleted file mode 100644
index 06d083b..0000000
--- a/riverctl/main.zig
+++ /dev/null
@@ -1,148 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020-2021 The River Developers
-//
-// 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, version 3.
-//
-// 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 mem = std.mem;
-const io = std.io;
-const posix = std.posix;
-const assert = std.debug.assert;
-const builtin = @import("builtin");
-
-const wayland = @import("wayland");
-const wl = wayland.client.wl;
-const zriver = wayland.client.zriver;
-
-const flags = @import("flags");
-
-const usage =
- \\usage: riverctl [options] <command>
- \\
- \\ -h Print this help message and exit.
- \\ -version Print the version number and exit.
- \\
- \\Complete documentation of the recognized commands may be found in
- \\the riverctl(1) man page.
- \\
-;
-
-const gpa = std.heap.c_allocator;
-
-pub const Globals = struct {
- control: ?*zriver.ControlV1 = null,
- seat: ?*wl.Seat = null,
-};
-
-pub fn main() !void {
- _main() catch |err| {
- switch (err) {
- error.RiverControlNotAdvertised => fatal(
- \\The Wayland server does not support river-control-unstable-v1.
- \\Do your versions of river and riverctl match?
- , .{}),
- error.SeatNotAdverstised => fatal(
- \\The Wayland server did not advertise any seat.
- , .{}),
- error.ConnectFailed => {
- std.log.err("Unable to connect to the Wayland server.", .{});
- if (posix.getenvZ("WAYLAND_DISPLAY") == null) {
- fatal("WAYLAND_DISPLAY is not set.", .{});
- } else {
- fatal("Does WAYLAND_DISPLAY contain the socket name of a running server?", .{});
- }
- },
- else => return err,
- }
- };
-}
-
-fn _main() !void {
- const result = flags.parser([*:0]const u8, &.{
- .{ .name = "h", .kind = .boolean },
- .{ .name = "version", .kind = .boolean },
- }).parse(std.os.argv[1..]) catch {
- try io.getStdErr().writeAll(usage);
- posix.exit(1);
- };
- if (result.flags.h) {
- try io.getStdOut().writeAll(usage);
- posix.exit(0);
- }
- if (result.flags.version) {
- try io.getStdOut().writeAll(@import("build_options").version ++ "\n");
- posix.exit(0);
- }
-
- const display = try wl.Display.connect(null);
- const registry = try display.getRegistry();
-
- var globals = Globals{};
-
- registry.setListener(*Globals, registryListener, &globals);
- if (display.roundtrip() != .SUCCESS) fatal("initial roundtrip failed", .{});
-
- const control = globals.control orelse return error.RiverControlNotAdvertised;
- const seat = globals.seat orelse return error.SeatNotAdverstised;
-
- for (result.args) |arg| control.addArgument(arg);
-
- const callback = try control.runCommand(seat);
- callback.setListener(?*anyopaque, callbackListener, null);
-
- // Loop until our callback is called and we exit.
- while (true) {
- if (display.dispatch() != .SUCCESS) fatal("failed to dispatch wayland events", .{});
- }
-}
-
-fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *Globals) void {
- switch (event) {
- .global => |global| {
- if (mem.orderZ(u8, global.interface, wl.Seat.interface.name) == .eq) {
- assert(globals.seat == null); // TODO: support multiple seats
- globals.seat = registry.bind(global.name, wl.Seat, 1) catch @panic("out of memory");
- } else if (mem.orderZ(u8, global.interface, zriver.ControlV1.interface.name) == .eq) {
- globals.control = registry.bind(global.name, zriver.ControlV1, 1) catch @panic("out of memory");
- }
- },
- .global_remove => {},
- }
-}
-
-fn callbackListener(_: *zriver.CommandCallbackV1, event: zriver.CommandCallbackV1.Event, _: ?*anyopaque) void {
- switch (event) {
- .success => |success| {
- if (mem.len(success.output) > 0) {
- const stdout = io.getStdOut().writer();
- stdout.print("{s}\n", .{success.output}) catch @panic("failed to write to stdout");
- }
- posix.exit(0);
- },
- .failure => |failure| {
- // A small hack to provide usage text when river reports an unknown command.
- if (mem.orderZ(u8, failure.failure_message, "unknown command") == .eq) {
- std.log.err("unknown command", .{});
- io.getStdErr().writeAll(usage) catch {};
- posix.exit(1);
- }
- fatal("{s}", .{failure.failure_message});
- },
- }
-}
-
-fn fatal(comptime format: []const u8, args: anytype) noreturn {
- std.log.err(format, args);
- posix.exit(1);
-}
diff --git a/rivertile/main.zig b/rivertile/main.zig
deleted file mode 100644
index ad76ed9..0000000
--- a/rivertile/main.zig
+++ /dev/null
@@ -1,419 +0,0 @@
-// This file is part of river, a dynamic tiling wayland compositor.
-//
-// Copyright 2020-2021 The River Developers
-//
-// 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, version 3.
-//
-// 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/>.
-
-// This is an implementation of the default "tiled" layout of dwm and the
-// 3 other orientations thereof. This code is written for the main stack
-// to the left and then the input/output values are adjusted to apply
-// the necessary transformations to derive the other orientations.
-//
-// With 4 views and one main on the left, the layout looks something like this:
-//
-// +-----------------------+------------+
-// | | |
-// | | |
-// | | |
-// | +------------+
-// | | |
-// | | |
-// | | |
-// | +------------+
-// | | |
-// | | |
-// | | |
-// +-----------------------+------------+
-
-const std = @import("std");
-const fmt = std.fmt;
-const mem = std.mem;
-const math = std.math;
-const posix = std.posix;
-const assert = std.debug.assert;
-
-const wayland = @import("wayland");
-const wl = wayland.client.wl;
-const river = wayland.client.river;
-
-const flags = @import("flags");
-
-const usage =
- \\usage: rivertile [options]
- \\
- \\ -h Print this help message and exit.
- \\ -version Print the version number and exit.
- \\ -view-padding Set the padding around views in pixels. (Default 6)
- \\ -outer-padding Set the padding around the edge of the layout area in
- \\ pixels. (Default 6)
- \\ -main-location Set the initial location of the main area in the
- \\ layout. (Default left)
- \\ -main-count Set the initial number of views in the main area of the
- \\ layout. (Default 1)
- \\ -main-ratio Set the initial ratio of main area to total layout
- \\ area. (Default: 0.6)
- \\
-;
-
-const Command = enum {
- @"main-location",
- @"main-count",
- @"main-ratio",
-};
-
-const Location = enum {
- top,
- right,
- bottom,
- left,
-};
-
-// Configured through command line options
-var view_padding: u31 = 6;
-var outer_padding: u31 = 6;
-var default_main_location: Location = .left;
-var default_main_count: u31 = 1;
-var default_main_ratio: f64 = 0.6;
-
-/// We don't free resources on exit, only when output globals are removed.
-const gpa = std.heap.c_allocator;
-
-const Context = struct {
- initialized: bool = false,
- layout_manager: ?*river.LayoutManagerV3 = null,
- outputs: std.DoublyLinkedList(Output) = .{},
-
- fn addOutput(context: *Context, registry: *wl.Registry, name: u32) !void {
- const wl_output = try registry.bind(name, wl.Output, 3);
- errdefer wl_output.release();
- const node = try gpa.create(std.DoublyLinkedList(Output).Node);
- errdefer gpa.destroy(node);
- try node.data.init(context, wl_output, name);
- context.outputs.append(node);
- }
-};
-
-const Output = struct {
- wl_output: *wl.Output,
- name: u32,
-
- main_location: Location,
- main_count: u31,
- main_ratio: f64,
-
- layout: *river.LayoutV3 = undefined,
-
- fn init(output: *Output, context: *Context, wl_output: *wl.Output, name: u32) !void {
- output.* = .{
- .wl_output = wl_output,
- .name = name,
- .main_location = default_main_location,
- .main_count = default_main_count,
- .main_ratio = default_main_ratio,
- };
- if (context.initialized) try output.getLayout(context);
- }
-
- fn getLayout(output: *Output, context: *Context) !void {
- assert(context.initialized);
- output.layout = try context.layout_manager.?.getLayout(output.wl_output, "rivertile");
- output.layout.setListener(*Output, layoutListener, output);
- }
-
- fn deinit(output: *Output) void {
- output.wl_output.release();
- output.layout.destroy();
- }
-
- fn layoutListener(layout: *river.LayoutV3, event: river.LayoutV3.Event, output: *Output) void {
- switch (event) {
- .namespace_in_use => fatal("namespace 'rivertile' already in use.", .{}),
-
- .user_command => |ev| {
- var it = mem.tokenizeSequence(u8, mem.span(ev.command), " ");
- const raw_cmd = it.next() orelse {
- std.log.err("not enough arguments", .{});
- return;
- };
- const raw_arg = it.next() orelse {
- std.log.err("not enough arguments", .{});
- return;
- };
- if (it.next() != null) {
- std.log.err("too many arguments", .{});
- return;
- }
- const cmd = std.meta.stringToEnum(Command, raw_cmd) orelse {
- std.log.err("unknown command: {s}", .{raw_cmd});
- return;
- };
- switch (cmd) {
- .@"main-location" => {
- output.main_location = std.meta.stringToEnum(Location, raw_arg) orelse {
- std.log.err("unknown location: {s}", .{raw_arg});
- return;
- };
- },
- .@"main-count" => {
- const arg = fmt.parseInt(i32, raw_arg, 10) catch |err| {
- std.log.err("failed to parse argument: {}", .{err});
- return;
- };
- switch (raw_arg[0]) {
- '+' => output.main_count +|= @intCast(arg),
- '-' => {
- const result = output.main_count +| arg;
- if (result >= 1) output.main_count = @intCast(result);
- },
- else => {
- if (arg >= 1) output.main_count = @intCast(arg);
- },
- }
- },
- .@"main-ratio" => {
- const arg = fmt.parseFloat(f64, raw_arg) catch |err| {
- std.log.err("failed to parse argument: {}", .{err});
- return;
- };
- switch (raw_arg[0]) {
- '+', '-' => {
- output.main_ratio = math.clamp(output.main_ratio + arg, 0.1, 0.9);
- },
- else => output.main_ratio = math.clamp(arg, 0.1, 0.9),
- }
- },
- }
- },
-
- .layout_demand => |ev| {
- assert(ev.view_count > 0);
-
- const main_count = @min(output.main_count, ev.view_count);
- const secondary_count = saturatingCast(u31, ev.view_count) -| main_count;
-
- const usable_width = switch (output.main_location) {
- .left, .right => saturatingCast(u31, ev.usable_width) -| (2 *| outer_padding),
- .top, .bottom => saturatingCast(u31, ev.usable_height) -| (2 *| outer_padding),
- };
- const usable_height = switch (output.main_location) {
- .left, .right => saturatingCast(u31, ev.usable_height) -| (2 *| outer_padding),
- .top, .bottom => saturatingCast(u31, ev.usable_width) -| (2 *| outer_padding),
- };
-
- // to make things pixel-perfect, we make the first main and first secondary
- // view slightly larger if the height is not evenly divisible
- var main_width: u31 = undefined;
- var main_height: u31 = undefined;
- var main_height_rem: u31 = undefined;
-
- var secondary_width: u31 = undefined;
- var secondary_height: u31 = undefined;
- var secondary_height_rem: u31 = undefined;
-
- if (secondary_count > 0) {
- main_width = @intFromFloat(output.main_ratio * @as(f64, @floatFromInt(usable_width)));
- main_height = usable_height / main_count;
- main_height_rem = usable_height % main_count;
-
- secondary_width = usable_width - main_width;
- secondary_height = usable_height / secondary_count;
- secondary_height_rem = usable_height % secondary_count;
- } else {
- main_width = usable_width;
- main_height = usable_height / main_count;
- main_height_rem = usable_height % main_count;
- }
-
- var i: u31 = 0;
- while (i < ev.view_count) : (i += 1) {
- var x: i32 = undefined;
- var y: i32 = undefined;
- var width: u31 = undefined;
- var height: u31 = undefined;
-
- if (i < main_count) {
- x = 0;
- y = (i * main_height) + if (i > 0) main_height_rem else 0;
- width = main_width;
- height = main_height + if (i == 0) main_height_rem else 0;
- } else {
- x = main_width;
- y = (i - main_count) * secondary_height + if (i > main_count) secondary_height_rem else 0;
- width = secondary_width;
- height = secondary_height + if (i == main_count) secondary_height_rem else 0;
- }
-
- x +|= view_padding;
- y +|= view_padding;
- width -|= 2 *| view_padding;
- height -|= 2 *| view_padding;
-
- switch (output.main_location) {
- .left => layout.pushViewDimensions(
- x +| outer_padding,
- y +| outer_padding,
- width,
- height,
- ev.serial,
- ),
- .right => layout.pushViewDimensions(
- usable_width - width - x +| outer_padding,
- y +| outer_padding,
- width,
- height,
- ev.serial,
- ),
- .top => layout.pushViewDimensions(
- y +| outer_padding,
- x +| outer_padding,
- height,
- width,
- ev.serial,
- ),
- .bottom => layout.pushViewDimensions(
- y +| outer_padding,
- usable_width - width - x +| outer_padding,
- height,
- width,
- ev.serial,
- ),
- }
- }
-
- switch (output.main_location) {
- .left => layout.commit("rivertile - left", ev.serial),
- .right => layout.commit("rivertile - right", ev.serial),
- .top => layout.commit("rivertile - top", ev.serial),
- .bottom => layout.commit("rivertile - bottom", ev.serial),
- }
- },
- .user_command_tags => {},
- }
- }
-};
-
-pub fn main() !void {
- const result = flags.parser([*:0]const u8, &[_]flags.Flag{
- .{ .name = "h", .kind = .boolean },
- .{ .name = "version", .kind = .boolean },
- .{ .name = "view-padding", .kind = .arg },
- .{ .name = "outer-padding", .kind = .arg },
- .{ .name = "main-location", .kind = .arg },
- .{ .name = "main-count", .kind = .arg },
- .{ .name = "main-ratio", .kind = .arg },
- }).parse(std.os.argv[1..]) catch {
- try std.io.getStdErr().writeAll(usage);
- posix.exit(1);
- };
- if (result.flags.h) {
- try std.io.getStdOut().writeAll(usage);
- posix.exit(0);
- }
- if (result.args.len != 0) fatalPrintUsage("unknown option '{s}'", .{result.args[0]});
-
- if (result.flags.version) {
- try std.io.getStdOut().writeAll(@import("build_options").version ++ "\n");
- posix.exit(0);
- }
- if (result.flags.@"view-padding") |raw| {
- view_padding = fmt.parseUnsigned(u31, raw, 10) catch
- fatalPrintUsage("invalid value '{s}' provided to -view-padding", .{raw});
- }
- if (result.flags.@"outer-padding") |raw| {
- outer_padding = fmt.parseUnsigned(u31, raw, 10) catch
- fatalPrintUsage("invalid value '{s}' provided to -outer-padding", .{raw});
- }
- if (result.flags.@"main-location") |raw| {
- default_main_location = std.meta.stringToEnum(Location, raw) orelse
- fatalPrintUsage("invalid value '{s}' provided to -main-location", .{raw});
- }
- if (result.flags.@"main-count") |raw| {
- default_main_count = fmt.parseUnsigned(u31, raw, 10) catch
- fatalPrintUsage("invalid value '{s}' provided to -main-count", .{raw});
- }
- if (result.flags.@"main-ratio") |raw| {
- default_main_ratio = fmt.parseFloat(f64, raw) catch {
- fatalPrintUsage("invalid value '{s}' provided to -main-ratio", .{raw});
- };
- if (default_main_ratio < 0.1 or default_main_ratio > 0.9) {
- fatalPrintUsage("invalid value '{s}' provided to -main-ratio", .{raw});
- }
- }
-
- const display = wl.Display.connect(null) catch {
- std.debug.print("Unable to connect to Wayland server.\n", .{});
- posix.exit(1);
- };
- defer display.disconnect();
-
- var context: Context = .{};
-
- const registry = try display.getRegistry();
- registry.setListener(*Context, registryListener, &context);
- if (display.roundtrip() != .SUCCESS) fatal("initial roundtrip failed", .{});
-
- if (context.layout_manager == null) {
- fatal("wayland compositor does not support river-layout-v3.\n", .{});
- }
-
- context.initialized = true;
-
- var it = context.outputs.first;
- while (it) |node| : (it = node.next) {
- const output = &node.data;
- try output.getLayout(&context);
- }
-
- while (true) {
- if (display.dispatch() != .SUCCESS) fatal("failed to dispatch wayland events", .{});
- }
-}
-
-fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, context: *Context) void {
- switch (event) {
- .global => |global| {
- if (mem.orderZ(u8, global.interface, river.LayoutManagerV3.interface.name) == .eq) {
- context.layout_manager = registry.bind(global.name, river.LayoutManagerV3, 1) catch return;
- } else if (mem.orderZ(u8, global.interface, wl.Output.interface.name) == .eq) {
- context.addOutput(registry, global.name) catch |err| fatal("failed to bind output: {}", .{err});
- }
- },
- .global_remove => |ev| {
- var it = context.outputs.first;
- while (it) |node| : (it = node.next) {
- const output = &node.data;
- if (output.name == ev.name) {
- context.outputs.remove(node);
- output.deinit();
- gpa.destroy(node);
- break;
- }
- }
- },
- }
-}
-
-fn fatal(comptime format: []const u8, args: anytype) noreturn {
- std.log.err(format, args);
- posix.exit(1);
-}
-
-fn fatalPrintUsage(comptime format: []const u8, args: anytype) noreturn {
- std.log.err(format, args);
- std.io.getStdErr().writeAll(usage) catch {};
- posix.exit(1);
-}
-
-fn saturatingCast(comptime T: type, x: anytype) T {
- return @max(math.minInt(T), @min(math.maxInt(T), x));
-}