docs: add book
This commit is contained in:
parent
c9d6fb9e40
commit
d14105eb1a
43 changed files with 7254 additions and 1204 deletions
521
docs/config.md
521
docs/config.md
|
|
@ -1,521 +0,0 @@
|
|||
# Configuration
|
||||
|
||||
Jay can be configured via
|
||||
|
||||
- a declarative TOML file or
|
||||
- a shared library that gets injected into the compositor.
|
||||
|
||||
## Shared Library Configuration
|
||||
|
||||
This is described in the [rustdoc](https://docs.rs/jay-config) of the configuration crate.
|
||||
|
||||
## TOML Configuration
|
||||
|
||||
The configuration file is stored under `$HOME/.config/jay/config.toml`.
|
||||
If you don't have such a file, the default configuration will be used.
|
||||
|
||||
The full format of this file is described in the auto-generated file [spec.generated.md](../toml-spec/spec/spec.generated.md).
|
||||
You can also get auto completion with the auto-generated JSON Schema linked from that document.
|
||||
|
||||
The following code block contains the annotated default configuration.
|
||||
Below that we will describe individual usecases.
|
||||
|
||||
```toml
|
||||
# The keymap that is used for shortcuts and also sent to clients.
|
||||
keymap = """
|
||||
xkb_keymap {
|
||||
xkb_keycodes { include "evdev+aliases(qwerty)" };
|
||||
xkb_types { include "complete" };
|
||||
xkb_compat { include "complete" };
|
||||
xkb_symbols { include "pc+us+inet(evdev)" };
|
||||
};
|
||||
"""
|
||||
|
||||
# An action that will be executed when the GPU has been initialized.
|
||||
on-graphics-initialized = [
|
||||
{ type = "exec", exec = "mako" },
|
||||
{ type = "exec", exec = "wl-tray-bridge" },
|
||||
]
|
||||
|
||||
# Shortcuts that are processed by the compositor.
|
||||
# The left hand side should be a key, possibly prefixed with modifiers.
|
||||
# The right hand side should be an action.
|
||||
[shortcuts]
|
||||
# The focus-X actions move the keyboard focus to next window on the X.
|
||||
alt-h = "focus-left"
|
||||
alt-j = "focus-down"
|
||||
alt-k = "focus-up"
|
||||
alt-l = "focus-right"
|
||||
|
||||
# The move-X actions move window that has the keyboard focus to the X.
|
||||
alt-shift-h = "move-left"
|
||||
alt-shift-j = "move-down"
|
||||
alt-shift-k = "move-up"
|
||||
alt-shift-l = "move-right"
|
||||
|
||||
# The split-X action places the currently focused window in a container
|
||||
# and sets the split direction of the container to X.
|
||||
alt-d = "split-horizontal"
|
||||
alt-v = "split-vertical"
|
||||
|
||||
# The toggle-split action changes the split direction of the current
|
||||
# container.
|
||||
alt-t = "toggle-split"
|
||||
# The toggle-mono action changes whether the current container shows
|
||||
# a single window or all windows next to each other.
|
||||
alt-m = "toggle-mono"
|
||||
# The toggle-fullscreen action toggles the current window between
|
||||
# windowed and fullscreen.
|
||||
alt-u = "toggle-fullscreen"
|
||||
|
||||
# The focus-parent action moves the keyboard focus to the parent of
|
||||
# the currently focused window.
|
||||
alt-f = "focus-parent"
|
||||
# The open-control-center action opens the control center.
|
||||
alt-c = "open-control-center"
|
||||
# The close action requests the currently focused window to close.
|
||||
alt-shift-c = "close"
|
||||
# The toggle-floating action changes the currently focused window between
|
||||
# floating and tiled.
|
||||
alt-shift-f = "toggle-floating"
|
||||
|
||||
# All actions above are so-called simple actions that are identified by
|
||||
# a string. More complex actions take parameters and are written as a table.
|
||||
# For example, the exec action spawns an application and has the exec field
|
||||
# that describes how to spawn the application.
|
||||
Super_L = { type = "exec", exec = "alacritty" }
|
||||
alt-p = { type = "exec", exec = "bemenu-run" }
|
||||
|
||||
# The quit action terminates the compositor.
|
||||
alt-q = "quit"
|
||||
# The reload-config-toml action reloads the TOML configuration file.
|
||||
alt-shift-r = "reload-config-toml"
|
||||
|
||||
# The switch-to-vt action switches to a different virtual terminal.
|
||||
ctrl-alt-F1 = { type = "switch-to-vt", num = 1 }
|
||||
ctrl-alt-F2 = { type = "switch-to-vt", num = 2 }
|
||||
ctrl-alt-F3 = { type = "switch-to-vt", num = 3 }
|
||||
ctrl-alt-F4 = { type = "switch-to-vt", num = 4 }
|
||||
ctrl-alt-F5 = { type = "switch-to-vt", num = 5 }
|
||||
ctrl-alt-F6 = { type = "switch-to-vt", num = 6 }
|
||||
ctrl-alt-F7 = { type = "switch-to-vt", num = 7 }
|
||||
ctrl-alt-F8 = { type = "switch-to-vt", num = 8 }
|
||||
ctrl-alt-F9 = { type = "switch-to-vt", num = 9 }
|
||||
ctrl-alt-F10 = { type = "switch-to-vt", num = 10 }
|
||||
ctrl-alt-F11 = { type = "switch-to-vt", num = 11 }
|
||||
ctrl-alt-F12 = { type = "switch-to-vt", num = 12 }
|
||||
|
||||
# The show-workspace action switches to a workspace. If the workspace is not
|
||||
# currently being used, it is created on the output that contains the pointer.
|
||||
alt-F1 = { type = "show-workspace", name = "1" }
|
||||
alt-F2 = { type = "show-workspace", name = "2" }
|
||||
alt-F3 = { type = "show-workspace", name = "3" }
|
||||
alt-F4 = { type = "show-workspace", name = "4" }
|
||||
alt-F5 = { type = "show-workspace", name = "5" }
|
||||
alt-F6 = { type = "show-workspace", name = "6" }
|
||||
alt-F7 = { type = "show-workspace", name = "7" }
|
||||
alt-F8 = { type = "show-workspace", name = "8" }
|
||||
alt-F9 = { type = "show-workspace", name = "9" }
|
||||
alt-F10 = { type = "show-workspace", name = "10" }
|
||||
alt-F11 = { type = "show-workspace", name = "11" }
|
||||
alt-F12 = { type = "show-workspace", name = "12" }
|
||||
|
||||
# The move-to-workspace action moves the currently focused window to a workspace.
|
||||
alt-shift-F1 = { type = "move-to-workspace", name = "1" }
|
||||
alt-shift-F2 = { type = "move-to-workspace", name = "2" }
|
||||
alt-shift-F3 = { type = "move-to-workspace", name = "3" }
|
||||
alt-shift-F4 = { type = "move-to-workspace", name = "4" }
|
||||
alt-shift-F5 = { type = "move-to-workspace", name = "5" }
|
||||
alt-shift-F6 = { type = "move-to-workspace", name = "6" }
|
||||
alt-shift-F7 = { type = "move-to-workspace", name = "7" }
|
||||
alt-shift-F8 = { type = "move-to-workspace", name = "8" }
|
||||
alt-shift-F9 = { type = "move-to-workspace", name = "9" }
|
||||
alt-shift-F10 = { type = "move-to-workspace", name = "10" }
|
||||
alt-shift-F11 = { type = "move-to-workspace", name = "11" }
|
||||
alt-shift-F12 = { type = "move-to-workspace", name = "12" }
|
||||
```
|
||||
|
||||
### Configuring Keymaps and Repeat Rates
|
||||
|
||||
The keymap can be configured via the top-level `keymap` field.
|
||||
|
||||
```toml
|
||||
keymap = """
|
||||
xkb_keymap {
|
||||
xkb_keycodes { include "evdev+aliases(qwerty)" };
|
||||
xkb_types { include "complete" };
|
||||
xkb_compat { include "complete" };
|
||||
xkb_symbols { include "pc+us+inet(evdev)" };
|
||||
};
|
||||
"""
|
||||
```
|
||||
|
||||
The format is described in the ArchWiki: https://wiki.archlinux.org/title/X_keyboard_extension
|
||||
|
||||
If you want to use multiple keymaps, you can assign names to them:
|
||||
|
||||
```toml
|
||||
keymap.name = "laptop"
|
||||
|
||||
[[keymaps]]
|
||||
name = "laptop"
|
||||
path = "./laptop-keymap.xkb"
|
||||
|
||||
[[keymaps]]
|
||||
name = "external"
|
||||
path = "./external-keymap.xkb"
|
||||
```
|
||||
|
||||
Such paths are relative to the configuration file.
|
||||
You can also write the map inline in this format:
|
||||
|
||||
```toml
|
||||
[[keymaps]]
|
||||
name = "external"
|
||||
map = "..."
|
||||
```
|
||||
|
||||
If you want to switch the keymap with a shortcut, use the `set-keymap` action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-j = { type = "set-keymap", keymap.name = "laptop" }
|
||||
alt-k = { type = "set-keymap", keymap.name = "external" }
|
||||
```
|
||||
|
||||
The keyboard repeat rate is configured via the top-level `repeat-rate` field.
|
||||
|
||||
```toml
|
||||
repeat-rate = { rate = 25, delay = 250 }
|
||||
```
|
||||
|
||||
You can change this at runtime with the `set-repeat-rate` action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-x = { type = "set-repeat-rate", rate = { rate = 25, delay = 250 } }
|
||||
```
|
||||
|
||||
Note that you can change all of this from the command line with the `jay input` command.
|
||||
|
||||
### Configuring Shortcuts
|
||||
|
||||
Shortcuts are configured in the top-level `shortcuts` table.
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-h = "focus-left"
|
||||
```
|
||||
|
||||
The left-hand side should be a key that can optionally be prefixed with modifiers.
|
||||
|
||||
The right-hand side should be an action.
|
||||
|
||||
See [spec.generated.md](../toml-spec/spec/spec.generated.md) for a full list of actions.
|
||||
|
||||
### Complex Shortcuts
|
||||
|
||||
If you need more control over shortcut execution, you can use the `complex-shortcuts` table.
|
||||
|
||||
```toml
|
||||
[complex-shortcuts.alt-x]
|
||||
action = { type = "exec", exec = ["pactl", "set-sink-mute", "0", "1"] }
|
||||
latch = { type = "exec", exec = ["pactl", "set-sink-mute", "0", "0"] }
|
||||
```
|
||||
|
||||
This mutes the audio output while the key is pressed and un-mutes once the `x` key is released.
|
||||
The order in which `alt` and `x` are released does not matter for this.
|
||||
|
||||
This can also be used to implement push to talk.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Running Multiple Actions
|
||||
|
||||
In every place that accepts an action, you can also run multiple actions by wrapping them
|
||||
in an array:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-h = ["focus-left", "focus-up"]
|
||||
```
|
||||
|
||||
### Spawning Applications
|
||||
|
||||
You can spawn applications by using the `exec` action:
|
||||
|
||||
```toml
|
||||
Super_L = { type = "exec", exec = "alacritty" }
|
||||
```
|
||||
|
||||
The `exec` field can be either a string, an array of strings, or a table.
|
||||
|
||||
When a string is used, it should be the name of the application.
|
||||
|
||||
When an array is used, it should be the name of the application followed by arguments.
|
||||
|
||||
```toml
|
||||
Super_L = { type = "exec", exec = ["alacritty", "-e", "date"] }
|
||||
```
|
||||
|
||||
When a table is used, you can additionally specify
|
||||
|
||||
- environment variables to pass to the application,
|
||||
- whether the application should have access to privileged protocols.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Running an Action at Startup
|
||||
|
||||
If you want to run an action at startup, you can use the top-level `on-graphics-initialized`
|
||||
field:
|
||||
|
||||
```toml
|
||||
on-graphics-initialized = [
|
||||
{ type = "exec", exec = "mako" },
|
||||
{ type = "exec", exec = "wl-tray-bridge" },
|
||||
]
|
||||
```
|
||||
|
||||
### Setting Environment Variables
|
||||
|
||||
You can set environment variables with the the top level `env` table.
|
||||
|
||||
```toml
|
||||
[env]
|
||||
GTK_THEME = "Adwaita:dark"
|
||||
```
|
||||
|
||||
These environment variables are passed to all applications started afterwards.
|
||||
|
||||
You can also use the `set-env` action to modify these variables:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-l = { type = "set-env", env.GTK_THEME = "Adwaita:dark" }
|
||||
```
|
||||
|
||||
The `unset-env` action is similar.
|
||||
See the specification for more details.
|
||||
|
||||
### Using a Status Program
|
||||
|
||||
You can configure a status program with the top-level `status` table.
|
||||
|
||||
```toml
|
||||
[status]
|
||||
format = "i3bar"
|
||||
exec = "i3status"
|
||||
```
|
||||
|
||||
The `format` field specifies the format used by the status program.
|
||||
Possible values are `plain`, `pango`, and `i3bar`.
|
||||
|
||||
The `exec` field specifies how to start the status program.
|
||||
|
||||
Note that i3status will not automatically use i3bar format when started this way.
|
||||
You have to explicitly opt into i3bar format in your i3status configuration.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Configuring Idle Timeout and Actions
|
||||
|
||||
You can configure the idle timeout with the top-level `idle` table.
|
||||
|
||||
```toml
|
||||
idle.minutes = 10
|
||||
```
|
||||
|
||||
If you want to lock the screen when this timeout happens, you can use the `on-idle` table.
|
||||
|
||||
```toml
|
||||
on-idle = { type = "exec", exec = { prog = "swaylock", privileged = true } }
|
||||
```
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Configuring GPUs
|
||||
|
||||
You can configure GPUs with the top-level `drm-devices` array.
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
name = "dedicated"
|
||||
match = { pci-vendor = 0x1002, pci-model = 0x73ff }
|
||||
|
||||
[[drm-devices]]
|
||||
name = "integrated"
|
||||
match = { pci-vendor = 0x1002, pci-model = 0x164e }
|
||||
gfx-api = "OpenGl"
|
||||
```
|
||||
|
||||
For each device, you can configure the following properties:
|
||||
|
||||
- Whether direct scanout is enabled on monitors connected to this device.
|
||||
- Which API to use for this device (OpenGL or Vulkan).
|
||||
|
||||
You can assign names to these device to refer to them elsewhere.
|
||||
|
||||
The `match` field is used to identify the device.
|
||||
Unless you have two identical graphics cards installed, using the pci-vendor and model
|
||||
fields is usually the best choice.
|
||||
You can get these values by running `jay randr`.
|
||||
|
||||
You can select the device used for rendering the desktop with the top-level `render-device` field.
|
||||
|
||||
```toml
|
||||
render-device.name = "dedicated"
|
||||
```
|
||||
|
||||
You can modify the render device and configure GPUs at runtime with the `set-render-device`
|
||||
and `configure-drm-device` actions.
|
||||
|
||||
You can use the top-level `gfx-api` field to set the default API used (unless overwritten for specific device).
|
||||
|
||||
```toml
|
||||
gfx-api = "Vulkan"
|
||||
```
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Configuring Monitors
|
||||
|
||||
You can configure monitors with the top-level `outputs` field.
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
name = "left"
|
||||
match.serial-number = "33K03894SL0"
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
[[outputs]]
|
||||
name = "right"
|
||||
match.serial-number = "ETW1M02062SL0"
|
||||
x = 1920
|
||||
y = 0
|
||||
```
|
||||
|
||||
For each output, you can configure the following properties:
|
||||
|
||||
- The x, y coordinates in global compositor space.
|
||||
- The scale to use for the monitor.
|
||||
- The transformation to apply to the content (rotation, mirroring).
|
||||
- The mode to use for the monitor.
|
||||
|
||||
You can query the available modes and modify these properties from the command line with
|
||||
the `jay randr` command.
|
||||
|
||||
The `match` field selects the monitors the configuration applies to.
|
||||
The serial number is usually a good unique identifier.
|
||||
|
||||
You can assign a name to monitors to refer to them in other places.
|
||||
|
||||
You can use the `configure-output` action to change this configuration at runtime.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Configuring Connectors
|
||||
|
||||
Connectors are the physical ports at the back of your GPU.
|
||||
You can configure them with the top-level `connectors` array.
|
||||
|
||||
```toml
|
||||
[[connectors]]
|
||||
name = "eDP-1"
|
||||
enabled = false
|
||||
```
|
||||
|
||||
Currently you can only use this to disable or enable connectors.
|
||||
This is useful to disable the internal monitor of a laptop when the laptop is closed.
|
||||
|
||||
You can use the `configure-connector` action to change this configuration at runtime.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Disabling Connectors of Closed Laptops
|
||||
|
||||
If a laptop has a switch that is signaled when the laptop is closed, you can configure
|
||||
the built-in connector to be disabled automatically:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "<switch name>"
|
||||
on-lid-closed = { type = "configure-connector", connector = { match.name = "eDP-1", enabled = false } }
|
||||
on-lid-opened = { type = "configure-connector", connector = { match.name = "eDP-1", enabled = true } }
|
||||
```
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Configuring Input Devices
|
||||
|
||||
You can configure input devices with the top-level `inputs` array.
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
tag = "mice"
|
||||
match.is-pointer = true
|
||||
left-handed = true
|
||||
transform-matrix = [[0.35, 0], [0, 0.35]]
|
||||
tap-enabled = true
|
||||
```
|
||||
|
||||
For each input device you can configure the following properties:
|
||||
|
||||
- The libinput acceleration profile.
|
||||
- The libinput acceleration speed.
|
||||
- The libinput tap setting.
|
||||
- The libinput tap-drag setting.
|
||||
- The libinput tap-drag-lock setting.
|
||||
- The libinput left-handed setting.
|
||||
- The libinput natural-scrolling setting.
|
||||
- The number of pixels to scroll per scroll-wheel dedent.
|
||||
- A transformation matrix to apply to relative movements.
|
||||
|
||||
You can inspect and modify these settings from the command line with the `jay input` command.
|
||||
|
||||
The `match` field selects the input devices to operate on.
|
||||
|
||||
You can assign a `tag` to input devices to refer to them elsewhere.
|
||||
|
||||
You can use the `configure-input` action to change these settings at runtime.
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Mapping Tablets to Outputs
|
||||
|
||||
You can map tablets to outputs using the `output` property:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
name = "left"
|
||||
match.serial-number = "33K03894SL0"
|
||||
|
||||
[[inputs]]
|
||||
match.name = "Wacom Bamboo Comic 2FG Pen"
|
||||
output.name = "left"
|
||||
```
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Theming
|
||||
|
||||
You can configure the colors, sizes, and fonts used by the compositor with the top-level `theme` table.
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
bg-color = "#ff000"
|
||||
```
|
||||
|
||||
See the specification for more details.
|
||||
|
||||
### Tray Icons and Menus
|
||||
|
||||
The default configuration will try to start [wl-tray-bridge] to give you access to tray
|
||||
icons and menus.
|
||||
|
||||
[wl-tray-bridge]: https://github.com/mahkoh/wl-tray-bridge
|
||||
|
||||
### Window and Client Rules
|
||||
|
||||
This is described in [window-and-client-rules.md](window-and-client-rules.md).
|
||||
229
docs/features.md
229
docs/features.md
|
|
@ -1,229 +0,0 @@
|
|||
# Features
|
||||
|
||||
## Configuration
|
||||
|
||||
Jay can be configured via
|
||||
|
||||
- a declarative TOML file or
|
||||
- a shared library that gets injected into the compositor.
|
||||
|
||||
See [config.md](config.md) for more details.
|
||||
|
||||
## i3 Look and Feel
|
||||
|
||||
Jay's appearance is based on the default i3 look and feel.
|
||||
|
||||
Colors, sizes, and fonts can be customized.
|
||||
|
||||
## Stability
|
||||
|
||||
Jay has been stable for a long time.
|
||||
Crashes and incorrect behavior in released versions are very rare.
|
||||
|
||||
Jay also aims to be forward and backward compatible for existing setups, allowing you to
|
||||
upgrade or downgrade the compositor without having to adjust your configuration.
|
||||
|
||||
There is a small but growing integration test suite that is used to ensure this.
|
||||
|
||||
## CLI
|
||||
|
||||
Jay has a CLI that can be used to configure the compositor at runtime.
|
||||
|
||||
```
|
||||
~$ jay
|
||||
A wayland compositor
|
||||
|
||||
Usage: jay [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
run Run the compositor
|
||||
config Create/modify the toml config
|
||||
generate-completion Generate shell completion scripts for jay
|
||||
log Open the log file
|
||||
set-log-level Sets the log level
|
||||
quit Stop the compositor
|
||||
unlock Unlocks the compositor
|
||||
screenshot Take a screenshot
|
||||
idle Inspect/modify the idle (screensaver) settings
|
||||
run-privileged Run a privileged program
|
||||
run-tagged Run a program with a connection tag
|
||||
seat-test Tests the events produced by a seat
|
||||
portal Run the desktop portal
|
||||
randr Inspect/modify graphics card and connector settings
|
||||
input Inspect/modify input settings
|
||||
xwayland Inspect/modify xwayland settings
|
||||
color-management Inspect/modify the color-management settings
|
||||
clients Inspect/manipulate the connected clients
|
||||
tree Inspect the surface tree
|
||||
control-center Opens the control center
|
||||
version Prints the Jay version and exits
|
||||
pid Prints the Jay PID and exits
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
--log-level <LOG_LEVEL> The log level [default: info] [possible values: trace, debug, info, warn, error, off]
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
## Multi-Monitor Support
|
||||
|
||||
Jay can be used with multiple monitors with hot-plug and hot-unplug support.
|
||||
When a monitor is unplugged, all workspaces are automatically moved one of the remaining
|
||||
monitors.
|
||||
When the monitor is plugged in again, these workspaces are restored.
|
||||
|
||||
## Multi-GPU Support
|
||||
|
||||
Jay can be used with multiple GPUs and monitors connected to different GPUs.
|
||||
One GPU is always used for rendering the desktop.
|
||||
You can change this GPU at runtime.
|
||||
|
||||
## Screen Sharing
|
||||
|
||||
Jay supports screen sharing via xdg-desktop-portal.
|
||||
There are three supported modes:
|
||||
|
||||
- Window capture
|
||||
- Output capture
|
||||
- Workspace capture which is like output capture except that only one workspace will be
|
||||
shown.
|
||||
|
||||
## Screen Locking
|
||||
|
||||
Jay can automatically lock your screen and disable outputs after inactivity.
|
||||
|
||||
## Notifications
|
||||
|
||||
Jay supports the zwlr_layer_shell_v1 protocol used by notification daemons.
|
||||
|
||||
## Fractional Scaling
|
||||
|
||||
Jay supports per-monitor fractional scaling.
|
||||
|
||||
## OpenGL and Vulkan
|
||||
|
||||
Jay can use either OpenGL or Vulkan for rendering.
|
||||
Vulkan offers better performance and memory usage but OpenGL is still provided for
|
||||
older hardware.
|
||||
|
||||
You can change the API at runtime without restarting the compositor.
|
||||
|
||||
## Explicit Sync
|
||||
|
||||
Jay supports explicit sync for compatibility with Nvidia hardware.
|
||||
|
||||
## Clipboard Managers
|
||||
|
||||
Jay supports clipboard managers via `zwlr_data_control_manager_v1`.
|
||||
|
||||
## Privilege Separation
|
||||
|
||||
Jay splits protocols into unprivileged and privileged protocols.
|
||||
By default, applications only have access to unprivileged protocols.
|
||||
|
||||
You can explicitly opt into giving applications access to privileged protocols via the Jay CLI or shortcuts.
|
||||
|
||||
## Push to Talk
|
||||
|
||||
Jay's shortcut system allows you to execute an action when a key is pressed and to execute a different action when the key is released.
|
||||
|
||||
## VR
|
||||
|
||||
Jay supports leasing VR headsets to applications.
|
||||
|
||||
## Adaptive Sync
|
||||
|
||||
Jay supports adaptive sync with configurable cursor refresh rates.
|
||||
|
||||
## Tearing
|
||||
|
||||
Jay supports tearing presentation for games.
|
||||
|
||||
## Low Input Latency
|
||||
|
||||
Jay uses frame scheduling to achieve input latency as low as 1.5 ms.
|
||||
|
||||
## Color Management & HDR
|
||||
|
||||
Jay supports the color management protocol and HDR10.
|
||||
|
||||
## Night Light
|
||||
|
||||
Jay supports night-light applications via `zwlr_gamma_control_manager_v1`.
|
||||
|
||||
## Window and Client Rules
|
||||
|
||||
Jay supports powerful window and client rules.
|
||||
|
||||
See [window-and-client-rules.md](window-and-client-rules.md) for more details.
|
||||
|
||||
## Protocol Support
|
||||
|
||||
Jay supports the following wayland protocols:
|
||||
|
||||
| Global | Version | Privileged |
|
||||
|------------------------------------------------------|:----------------|---------------|
|
||||
| ext_data_control_manager_v1 | 1 | Yes |
|
||||
| ext_foreign_toplevel_image_capture_source_manager_v1 | 1 | |
|
||||
| ext_foreign_toplevel_list_v1 | 1 | Yes |
|
||||
| ext_idle_notifier_v1 | 2 | Yes |
|
||||
| ext_image_copy_capture_manager_v1 | 1[^composited] | Yes |
|
||||
| ext_output_image_capture_source_manager_v1 | 1 | |
|
||||
| ext_session_lock_manager_v1 | 1 | Yes |
|
||||
| ext_transient_seat_manager_v1 | 1[^ts_rejected] | Yes |
|
||||
| ext_workspace_manager_v1 | 1 | Yes |
|
||||
| jay_popup_ext_manager_v1 | 1 | |
|
||||
| jay_tray_v1 | 1 | |
|
||||
| org_kde_kwin_server_decoration_manager | 1 | |
|
||||
| wl_compositor | 7 | |
|
||||
| wl_data_device_manager | 4 | |
|
||||
| wl_drm | 2 | |
|
||||
| wl_fixes | 1 | |
|
||||
| wl_output | 4 | |
|
||||
| wl_seat | 10 | |
|
||||
| wl_shm | 2 | |
|
||||
| wl_subcompositor | 1 | |
|
||||
| wp_alpha_modifier_v1 | 1 | |
|
||||
| wp_color_manager_v1 | 2 | |
|
||||
| wp_color_representation_manager_v1 | 1 | |
|
||||
| wp_commit_timing_manager_v1 | 1 | |
|
||||
| wp_content_type_manager_v1 | 1 | |
|
||||
| wp_cursor_shape_manager_v1 | 2 | |
|
||||
| wp_drm_lease_device_v1 | 1 | |
|
||||
| wp_fifo_manager_v1 | 1 | |
|
||||
| wp_fractional_scale_manager_v1 | 1 | |
|
||||
| wp_linux_drm_syncobj_manager_v1 | 1 | |
|
||||
| wp_pointer_warp_v1 | 1 | |
|
||||
| wp_presentation | 2 | |
|
||||
| wp_security_context_manager_v1 | 1 | |
|
||||
| wp_single_pixel_buffer_manager_v1 | 1 | |
|
||||
| wp_tearing_control_manager_v1 | 1 | |
|
||||
| wp_viewporter | 1 | |
|
||||
| xdg_activation_v1 | 1 | |
|
||||
| xdg_toplevel_drag_manager_v1 | 1 | |
|
||||
| xdg_toplevel_tag_manager_v1 | 1 | |
|
||||
| xdg_wm_base | 7 | |
|
||||
| xdg_wm_dialog_v1 | 1 | |
|
||||
| zwlr_data_control_manager_v1 | 2 | Yes |
|
||||
| zwlr_foreign_toplevel_manager_v1 | 3 | Yes |
|
||||
| zwlr_gamma_control_manager_v1 | 1 | Yes |
|
||||
| zwlr_layer_shell_v1 | 5 | No[^lsaccess] |
|
||||
| zwlr_output_manager_v1 | 4 | Yes |
|
||||
| zwlr_screencopy_manager_v1 | 3 | Yes |
|
||||
| zwlr_virtual_pointer_manager_v1 | 2 | Yes |
|
||||
| zwp_idle_inhibit_manager_v1 | 1 | |
|
||||
| zwp_input_method_manager_v2 | 1 | Yes |
|
||||
| zwp_linux_dmabuf_v1 | 5 | |
|
||||
| zwp_pointer_constraints_v1 | 1 | |
|
||||
| zwp_pointer_gestures_v1 | 3 | |
|
||||
| zwp_primary_selection_device_manager_v1 | 1 | |
|
||||
| zwp_relative_pointer_manager_v1 | 1 | |
|
||||
| zwp_tablet_manager_v2 | 2 | |
|
||||
| zwp_text_input_manager_v3 | 1 | |
|
||||
| zwp_virtual_keyboard_manager_v1 | 1 | Yes |
|
||||
| zxdg_decoration_manager_v1 | 2 | |
|
||||
| zxdg_output_manager_v1 | 3 | |
|
||||
|
||||
[^lsaccess]: Sandboxes can restrict access to this protocol.
|
||||
[^ts_rejected]: Seat creation is always rejected.
|
||||
[^composited]: Cursors are always composited.
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
# Mouse Interactions
|
||||
|
||||
Jay supports a number of mouse-based interactions that might be hard to discover. This
|
||||
file documents all of them.
|
||||
|
||||
- Inside a tiled container, the tiles can be resized by dragging the separators.
|
||||
|
||||
- Floating windows can be resized by dragging the borders.
|
||||
|
||||
- Floating windows can be moved by dragging the title.
|
||||
|
||||
- Tiles inside containers can be moved by dragging the title.
|
||||
|
||||
- Dragging them onto an existing workspace moves them to that workspace.
|
||||
|
||||
- Dragging them onto the bar outside an existing workspace creates a new workspace.
|
||||
|
||||
- Workspaces can be moved by dragging their titles with the mouse.
|
||||
|
||||
- In a container in mono layout, scrolling over the title switches between tiles.
|
||||
|
||||
- Scrolling over the bar switches between workspaces.
|
||||
|
||||
- Double clicking on a tile title/floating window title switches between floating and
|
||||
tiling.
|
||||
|
||||
- Right clicking on any title in a container switches the container between mono and tiled
|
||||
layout.
|
||||
|
||||
- Right clicking on the title of a floating window pins/unpins the window. (Pinned windows
|
||||
are visible on all workspaces.)
|
||||
|
||||
- When the pin icon is visible on a floating window, left clicking the icon pins/unpins
|
||||
the window.
|
||||
|
||||
- When selecting a toplevel (noticeable by the purple overlay), right clicking on the
|
||||
title of any tile in a container selects that container.
|
||||
|
||||
- Any long running mouse interaction can be canceled by pressing escape.
|
||||
|
||||
## Window Management Mode
|
||||
|
||||
Window-management mode makes more interactions available. See the configurable
|
||||
`window-management-key`.
|
||||
|
||||
- In window-management mode, floating windows, tiles, and popups can be resized by
|
||||
dragging their contents with the right mouse button.
|
||||
|
||||
- In window-management mode, floating windows, tiles, popups, and fullscreen windows can
|
||||
be moved by dragging their contents with the left mouse button.
|
||||
|
||||
- Entering window-management mode disables all pointer constraints and can therefore be
|
||||
used to move the pointer out of windows that have grabbed the pointer.
|
||||
127
docs/setup.md
127
docs/setup.md
|
|
@ -1,127 +0,0 @@
|
|||
# Building
|
||||
|
||||
## Compile-time Dependencies
|
||||
|
||||
The following libraries must be installed before compiling Jay:
|
||||
|
||||
- libinput.so
|
||||
- libgbm.so
|
||||
- libudev.so
|
||||
- libpangocairo-1.0.so
|
||||
- libfontconfig.so
|
||||
|
||||
You must also have a C compiler (GCC or Clang) and the latest version of rust installed.
|
||||
You can install rust with [rustup](https://rustup.rs/).
|
||||
|
||||
## Runtime Dependencies
|
||||
|
||||
Most of these dependencies are optional and will enable additional features.
|
||||
|
||||
- Linux 6.7: Required for explicit sync.
|
||||
- Xwayland: Required for running X applications.
|
||||
- Pipewire: Required for screen sharing.
|
||||
- logind (part of systemd): Required when running Jay from a virtual terminal.
|
||||
- libEGL.so and libGLESv2.so: Required for the OpenGL renderer.
|
||||
- libvulkan.so: Required for the Vulkan renderer.
|
||||
|
||||
Note that Jay will not work if neither the OpenGL nor the Vulkan renderer are available.
|
||||
|
||||
## Compiling
|
||||
|
||||
To compile the latest stable version of Jay, run
|
||||
|
||||
```
|
||||
cargo install --locked jay-compositor
|
||||
```
|
||||
|
||||
This will install Jay under `$HOME/.cargo/bin/jay`.
|
||||
|
||||
If you want to use the latest version from git, run
|
||||
|
||||
```
|
||||
cargo install --locked --git https://github.com/mahkoh/jay.git jay-compositor
|
||||
```
|
||||
|
||||
If you only want to build Jay without installing it, run the following command from within this repository:
|
||||
|
||||
```
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
The binary is then available under `./target/release/jay`.
|
||||
|
||||
## Running with CAP_SYS_NICE
|
||||
|
||||
Jay supports being started with CAP_SYS_NICE capabilities. For example, such
|
||||
capabilities can be added to the binary via
|
||||
|
||||
```shell
|
||||
~# setcap cap_sys_nice=p jay
|
||||
```
|
||||
|
||||
If CAP_SYS_NICE is available, Jay will, by default, elevate its scheduler to
|
||||
SCHED_RR and create Vulkan queues with the highest available priority. This can
|
||||
improve responsiveness if the CPU or GPU are under high load.
|
||||
|
||||
If Jay is started with the environment variable `JAY_NO_REALTIME=1` or a
|
||||
`config.so` exists, then Jay will not elevate its scheduler but will still
|
||||
create elevated Vulkan queues.
|
||||
|
||||
Jay will drop all capabilities almost immediately after being started. Before
|
||||
that, it will spawn a dedicated thread that retains the CAP_SYS_NICE capability
|
||||
to create elevated Vulkan queues later.
|
||||
|
||||
If Jay has elevated its scheduler to SCHED_RR, then it will refuse to load
|
||||
`config.so` configurations. Otherwise unprivileged applications would be able
|
||||
to run arbitrary code with SCHED_RR by crafting a dedicated `config.so`. This
|
||||
behavior can be overridden by compiling Jay with
|
||||
`JAY_ALLOW_REALTIME_CONFIG_SO=1`.
|
||||
|
||||
# Setup
|
||||
|
||||
## Configuration
|
||||
|
||||
See [config.md](./config.md).
|
||||
|
||||
## Screen Sharing
|
||||
|
||||
This step is only required to enable screen sharing.
|
||||
|
||||
1. Copy `../etc/jay.portal` to `/usr/share/xdg-desktop-portal/portals/jay.portal`.
|
||||
2. Copy `../etc/jay-portals.conf` to `/usr/share/xdg-desktop-portal/jay-portals.conf`.
|
||||
|
||||
Then restart `xdg-deskop-portal`.
|
||||
|
||||
## Recommended Applications
|
||||
|
||||
- [xdg-desktop-portal-gtk4](https://github.com/mahkoh/xdg-desktop-portal-gtk4)
|
||||
|
||||
Provides a file-picker portal that supports thumbnails. It will be used
|
||||
automatically if it is installed.
|
||||
|
||||
- [wl-tray-bridge](https://github.com/mahkoh/wl-tray-bridge)
|
||||
|
||||
Shows applications using the D-Bus StatusNotifierItem protocol as tray icons.
|
||||
|
||||
- [window-to-tray](https://github.com/mahkoh/wl-proxy/tree/master/apps/window-to-tray)
|
||||
|
||||
Allows you to run most wayland applications as tray applications. For example,
|
||||
to get a quick-access volume mixer in the tray:
|
||||
|
||||
```shell
|
||||
~$ window-to-tray pavucontrol-qt
|
||||
```
|
||||
|
||||
# Mouse Interactions
|
||||
|
||||
See [mouse-interactions.md](./mouse-interactions.md).
|
||||
|
||||
# Running
|
||||
|
||||
1. Switch to a virtual terminal by pressing `ctrl-alt-F2` (or F3, F4, ...).
|
||||
2. Run `jay run`.
|
||||
|
||||
If you have not yet changed the default configuration, you can
|
||||
|
||||
- quit Jay by pressing `alt-q`,
|
||||
- start Alacritty by pressing the left Windows key.
|
||||
|
|
@ -1,261 +0,0 @@
|
|||
# Window and Client Rules
|
||||
|
||||
Jay supports powerful window and client rules similar to i3.
|
||||
|
||||
## Example
|
||||
|
||||
```toml
|
||||
# Move spotify to workspace 3 and fullscreen it.
|
||||
[[windows]]
|
||||
match.client.sandbox-app-id = "com.spotify.Client"
|
||||
action = [
|
||||
{ type = "move-to-workspace", name = "3" },
|
||||
"enter-fullscreen",
|
||||
]
|
||||
|
||||
# Spawn the Chromium screen sharing window, the GIMP splash screen, and the
|
||||
# JetBrains splash screen floating and without focus stealing.
|
||||
[[windows]]
|
||||
match.any = [
|
||||
{ title-regex = 'is sharing (your screen|a window)\.$', client.comm = "chromium" },
|
||||
{ title = "GIMP Startup", app-id = "gimp" },
|
||||
{ title = "splash", x-class-regex = "^jetbrains-(clion|rustrover)$" }
|
||||
]
|
||||
initial-tile-state = "floating"
|
||||
auto-focus = false
|
||||
|
||||
# Spawn the JetBrains project selector floating.
|
||||
[[windows]]
|
||||
match.title-regex = "^Welcome to (RustRover|CLion)$"
|
||||
match.x-class-regex = "^jetbrains-(clion|rustrover)$"
|
||||
initial-tile-state = "floating"
|
||||
```
|
||||
|
||||
## General Principles
|
||||
|
||||
Each rule consists of three components:
|
||||
|
||||
1. Criteria that determine which clients/windows the rule applies to.
|
||||
2. An action to execute when a client/window starts matching the rule.
|
||||
3. An action to execute when a client/window stops matching the rule.
|
||||
|
||||
Each rule can be assigned a name which allows other rules to refer to it.
|
||||
|
||||
Additionally, rules have ad-hoc properties for things that are not easily
|
||||
expressed via actions, such as whether a window should be mapped floating or
|
||||
tiled.
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
name = "..." # the rule name
|
||||
match = { } # the rule criteria
|
||||
action = "..." # the action to run on start
|
||||
latch = "..." # the action to run on stop
|
||||
```
|
||||
|
||||
Rules are re-evaluated whenever any of the referenced criteria changes. That is,
|
||||
if you have the following rule
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.title = "VIM"
|
||||
action = "enter-fullscreen"
|
||||
```
|
||||
|
||||
then the window will enter fullscreen whenever title changes from something that
|
||||
is not `VIM` to `VIM`. For window rules, if you only want to match windows that
|
||||
have just been mapped, you can set the `just-mapped` criterion to `true`:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.title = "VIM"
|
||||
match.just-mapped = true
|
||||
action = "enter-fullscreen"
|
||||
```
|
||||
|
||||
This is similar to the `initial-title` criterion found in some other
|
||||
compositors.
|
||||
|
||||
Rules can trigger each other. For example:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.fullscreen = false
|
||||
action = "enter-fullscreen"
|
||||
|
||||
[[windows]]
|
||||
match.fullscreen = true
|
||||
action = "exit-fullscreen"
|
||||
```
|
||||
|
||||
This causes an infinite repetition of switching between windowed and fullscreen.
|
||||
Jay prevents such loops from locking up the compositor by never performing more
|
||||
than 1000 action callbacks before yielding to other work. However, they will
|
||||
still cause the compositor to use 100% CPU and will likely cause affected
|
||||
clients to be killed, since they won't be able to receive wayland messages fast
|
||||
enough.
|
||||
|
||||
## Combining Criteria
|
||||
|
||||
Criteria can be combined with the following operations:
|
||||
|
||||
- `any` - match if any of a number of criteria match
|
||||
- `all` - match if all of a number of criteria match
|
||||
- `not` - match if a criterion does not match
|
||||
- `exactly` - match if an exact number of criteria match
|
||||
- `name` - match if another window rule with that name matches
|
||||
|
||||
```toml
|
||||
# match windows that have the title `chromium` or `spotify`
|
||||
match.any = [
|
||||
{ title = "chromium" },
|
||||
{ title = "spotify" },
|
||||
]
|
||||
|
||||
# match windows whose title match both `chro` and `mium`
|
||||
match.all = [
|
||||
{ title-regex = "chro" },
|
||||
{ title-regex = "mium" },
|
||||
]
|
||||
|
||||
# match windows whose title is not `firefox`
|
||||
match.not.title = "firefox"
|
||||
|
||||
# match windows whose title is `VIM` or whose clients are sandboxed, but not
|
||||
# both
|
||||
match.exactly.num = 1
|
||||
match.exactly.list = [
|
||||
{ title = "VIM" },
|
||||
{ client.sandboxed = true },
|
||||
]
|
||||
|
||||
# match if another rule called `another-rule-name` matches
|
||||
match.name = "another-rule-name"
|
||||
```
|
||||
|
||||
A criterion object has multiple fields, for example
|
||||
|
||||
```toml
|
||||
match.title = "abc"
|
||||
match.app-id = "xyz"
|
||||
```
|
||||
|
||||
These fields are implicitly combined with `all` operator. That is, this behaves
|
||||
just like
|
||||
|
||||
```toml
|
||||
match.all = [
|
||||
{ title = "abc" },
|
||||
{ app-id = "xyz" },
|
||||
]
|
||||
```
|
||||
|
||||
## Finding Criteria Values
|
||||
|
||||
To determine which values to use in criteria, the `jay` executable provides the
|
||||
subcommands `jay clients` and `jay tree` to inspect currently active clients and
|
||||
open windows. For example
|
||||
|
||||
```text
|
||||
~$ jay tree query select-window
|
||||
- xdg-toplevel:
|
||||
id: 258ae697663a1b8abc7e4da9570ad36f
|
||||
pos: 1920x36 + 1920x1044
|
||||
client:
|
||||
id: 15
|
||||
uid: 1000
|
||||
pid: 2159136
|
||||
comm: chromium
|
||||
exe: /usr/lib/chromium/chromium
|
||||
title: YouTube - Chromium
|
||||
app-id: chromium
|
||||
workspace: 2
|
||||
visible
|
||||
```
|
||||
|
||||
In this case, `select-window` allows you to interactively select a window and
|
||||
then prints its properties.
|
||||
|
||||
## Client Rules
|
||||
|
||||
```toml
|
||||
# start executable `b` whenever a client with executable `A` connects
|
||||
[[clients]]
|
||||
match.exe = "A"
|
||||
action = { type = "exec", exec = "b" }
|
||||
```
|
||||
|
||||
All properties that can be referred to in client criteria are currently
|
||||
constant over the lifetime of the client.
|
||||
|
||||
### Client Criteria
|
||||
|
||||
The full specification of client criteria can be found in
|
||||
[spec.generated.md](../toml-spec/spec/spec.generated.md).
|
||||
|
||||
- `sandboxed` - Matches clients that are/aren't sandboxed.
|
||||
- `sandbox-engine`, `sandbox-engine-regex` - Matches the sandbox engine that was
|
||||
used to wrap this client. Usually `org.flatpak`.
|
||||
- `sandbox-app-id`, `sandbox-app-id-regex` - Matches the app-id provided by the
|
||||
sandbox engine
|
||||
- `sandbox-instance-id-id`, `sandbox-instance-id-regex` - Matches the
|
||||
instance-id provided by the sandbox engine
|
||||
- `uid`, `pid` - Matches the UID/PID of the client.
|
||||
- `is-xwayland` - Matches if the client is/isn't Xwayland.
|
||||
- `comm`, `comm-regex` - Matches the `/proc/self/comm` of the client.
|
||||
- `exe`, `exe-regex` - Matches the `/proc/self/exe` of the client.
|
||||
- `tag`, `tag-regex` - Matches the tag of the client.
|
||||
|
||||
## Window Rules
|
||||
|
||||
## Ad-hoc Window Rules
|
||||
|
||||
Rule actions are evaluated asynchronously. For window rules, this means that
|
||||
they are evaluated after the window has been mapped but before it is displayed
|
||||
for the first time. This makes them ill-suited for things that need to be fixed
|
||||
during the mapping process. Ad-hoc window rules can be used to bridge this gap:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.title = "chromium"
|
||||
initial-tile-state = "floating"
|
||||
auto-focus = false
|
||||
```
|
||||
|
||||
The `initial-tile-state` rule can be used to define whether the window is mapped
|
||||
tiled or floating. If no such rule exists, this is determined via heuristics.
|
||||
If multiple such rules exist and match a window, the compositor picks one at
|
||||
random.
|
||||
|
||||
The `auto-focus` rule determines if the window is automatically focused when it
|
||||
is mapped. If no such rule exists, newly mapped windows always get the keyboard
|
||||
focus except in some cases involving Xwayland. If multiple such rules exist and
|
||||
match a window, then the window _does not_ get the focus if _any_ of them is set
|
||||
to `false`.
|
||||
|
||||
## Window Criteria
|
||||
|
||||
The full specification of window criteria can be found in
|
||||
[spec.generated.md](../toml-spec/spec/spec.generated.md).
|
||||
|
||||
- `types` - Matches the type of a window. Currently there are four types:
|
||||
containers, placeholders, xdg toplevels, and X windows. If the rule does not
|
||||
contain such a criterion, the rule will only match windows created by clients,
|
||||
that is, xdg toplevels and X windows.
|
||||
- `client` - This is a client criterion. See above.
|
||||
- `title`, `title-regex` - Matches the title of the window.
|
||||
- `app-id`, `app-id-regex` - Matches the XDG app-id of the window.
|
||||
- `floating` - Matches if the window is/isn't floating.
|
||||
- `visible` - Matches if the window is/isn't visible.
|
||||
- `urgent` - Matches if the window wants/doesn't want attentions.
|
||||
- `focused` - Matches if the window is/isn't focused.
|
||||
- `fullscreen` - Matches if the window is/isn't fullscreen.
|
||||
- `just-mapped` - Matches if the window has/hasn't just been mapped. This is
|
||||
true for a single frame after the window has been mapped.
|
||||
- `tag`, `tag-regex` - Matches the XDG toplevel tag of the window.
|
||||
- `x-class`, `x-class-regex` - Matches the X class of the window.
|
||||
- `x-instance`, `x-instance-regex` - Matches the X instance of the window.
|
||||
- `x-role`, `x-role-regex` - Matches the X role of the window.
|
||||
- `workspace`, `workspace-regex` - Matches the workspace of the window.
|
||||
- `content-types` - Matches the content type of a window. Currently there are
|
||||
three types: photos, videos, and games.
|
||||
Loading…
Add table
Add a link
Reference in a new issue