docs: add book
This commit is contained in:
parent
c9d6fb9e40
commit
d14105eb1a
43 changed files with 7254 additions and 1204 deletions
1
book/.gitignore
vendored
Normal file
1
book/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/book
|
||||
293
book/AGENTS.md
Normal file
293
book/AGENTS.md
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
# Jay Book -- Agent Instructions
|
||||
|
||||
This file provides context for AI agents working on the Jay user documentation
|
||||
book (mdbook). Read this before making changes.
|
||||
|
||||
## What is this?
|
||||
|
||||
An [mdbook](https://rust-lang.github.io/mdBook/) providing comprehensive
|
||||
user-facing documentation for the [Jay Wayland compositor](https://github.com/mahkoh/jay).
|
||||
The target audience is end users, not developers. The goal is feature
|
||||
discoverability: every capability Jay offers should be documented here in a
|
||||
way that users can find and understand.
|
||||
|
||||
## Current status
|
||||
|
||||
The book is feature-complete. All 29 chapters cover every known Jay feature:
|
||||
a features overview, installation (including AUR packages), running, the
|
||||
control center, all configuration sections, tiling, workspaces, floating
|
||||
windows, mouse interactions, input modes, window/client rules, screen sharing,
|
||||
HDR & color management, the full CLI reference, and troubleshooting.
|
||||
|
||||
Three rounds of source-code verification have been completed and all
|
||||
identified issues have been fixed. The book should be accurate against the
|
||||
codebase as of the latest review.
|
||||
|
||||
A subsequent style and formatting pass has been completed:
|
||||
|
||||
- Converted ~45 two-column tables to mdbook definition lists across 16 files.
|
||||
- Lowercased all keyboard shortcut modifiers to match TOML parser expectations.
|
||||
- Reformatted long inline TOML tables into multiline format with trailing
|
||||
commas and 4-space indentation.
|
||||
- Created a dedicated Features chapter (`features.md`) consolidating content
|
||||
from the old `docs/features.md` and the introduction; removed the duplicated
|
||||
feature list from `introduction.md`.
|
||||
- Added a comprehensive "Granting Privileges" section to `window-rules.md` and
|
||||
privilege troubleshooting to `troubleshooting.md`.
|
||||
- Clarified `jay unlock` usage in `configuration/idle.md` and `cli.md`.
|
||||
- Added AUR package (`jay`, `jay-git`) mentions to `installation.md`.
|
||||
- Added a dedicated HDR & Color Management chapter (`hdr.md`) with
|
||||
end-to-end walkthrough, cross-referenced from `features.md`, `outputs.md`,
|
||||
and `misc.md`.
|
||||
- Integrated remaining information from `docs/` and `README.md` that was
|
||||
missing from the book: `JAY_NO_REALTIME` env var and `config.so`/SCHED_RR
|
||||
interaction in `installation.md`, rule loop client-kill consequences and
|
||||
Xwayland override-redirect auto-focus exception in `window-rules.md`,
|
||||
license (GPLv3) and community Discord link in `introduction.md`, ArchWiki
|
||||
XKB link in `keymaps.md`.
|
||||
|
||||
A third review pass fixed:
|
||||
|
||||
- `window-rules.md`: exec action example used a plain string with spaces
|
||||
(`exec = "notify-send 'Firefox connected'"`) which would be treated as a
|
||||
single program name; changed to array form
|
||||
(`exec = ["notify-send", "Firefox connected"]`).
|
||||
- `window-rules.md`: default capabilities paragraph incorrectly said rule
|
||||
capabilities are "added on top" of defaults; corrected to say they
|
||||
**replace** defaults entirely.
|
||||
- `troubleshooting.md`: said Jay "requires at least one working renderer to
|
||||
start"; corrected to say that without one, no GPU can be initialized and
|
||||
nothing will be displayed (Jay itself still starts).
|
||||
- `outputs.md`: VRR variant3 description said "describes its content as"
|
||||
instead of the correct protocol term "describes its content type as".
|
||||
|
||||
**Future work might include:**
|
||||
|
||||
- Keeping the book in sync as Jay adds new features or changes behavior.
|
||||
- Adding screenshots or diagrams (especially for the control center and tiling).
|
||||
- Reviewing after spec.yaml changes (the spec is the canonical source for
|
||||
config options).
|
||||
|
||||
## Directory layout
|
||||
|
||||
```
|
||||
book/
|
||||
AGENTS.md -- this file
|
||||
book.toml -- mdbook configuration
|
||||
src/
|
||||
SUMMARY.md -- table of contents (defines chapter ordering)
|
||||
introduction.md
|
||||
features.md -- feature overview, protocol table, CLI help output
|
||||
installation.md -- deps, AUR, crates.io, git builds, CAP_SYS_NICE
|
||||
running.md -- includes control center intro and default keybindings
|
||||
control-center.md -- detailed tour of all 11 panes
|
||||
configuration/
|
||||
index.md -- config overview, jay config init, file semantics, auto-reload
|
||||
keymaps.md
|
||||
shortcuts.md
|
||||
outputs.md
|
||||
inputs.md
|
||||
gpu.md
|
||||
idle.md
|
||||
theme.md
|
||||
environment.md
|
||||
status-bar.md
|
||||
startup.md
|
||||
xwayland.md
|
||||
misc.md -- color management, libei, floating, ui-drag, etc.
|
||||
tiling.md
|
||||
workspaces.md
|
||||
floating.md
|
||||
mouse.md
|
||||
input-modes.md
|
||||
window-rules.md -- includes "Granting Privileges" section
|
||||
cli.md
|
||||
screen-sharing.md
|
||||
hdr.md -- HDR & color management walkthrough
|
||||
troubleshooting.md -- includes privilege troubleshooting
|
||||
```
|
||||
|
||||
## Source of truth
|
||||
|
||||
The authoritative source for what Jay supports is the source code itself. Key
|
||||
reference files:
|
||||
|
||||
- `toml-spec/spec/spec.yaml` -- Full TOML config specification. Every config
|
||||
key, action, match criterion, and type is defined here. The auto-generated
|
||||
`toml-spec/spec/spec.generated.md` is derived from this file.
|
||||
- `toml-config/src/default-config.toml` -- The built-in default configuration.
|
||||
Contains default keybindings, startup actions (mako, wl-tray-bridge), etc.
|
||||
- `src/cli/*.rs` -- CLI subcommands and their arguments (clap definitions).
|
||||
Jay has 24 CLI subcommands with nesting up to 4 levels deep.
|
||||
- `src/control_center/*.rs` -- Control center pane implementations. Each pane
|
||||
has its own file (cc_outputs.rs, cc_gpus.rs, cc_input.rs, cc_clients.rs,
|
||||
cc_window.rs, cc_idle.rs, cc_compositor.rs, cc_look_and_feel.rs,
|
||||
cc_xwayland.rs, cc_color_management.rs, cc_virtual_outputs.rs). When
|
||||
documenting control center fields, always verify against these source files
|
||||
for correct ordering, labels, and conditional visibility.
|
||||
- `toml-config/src/config/parsers/color.rs` -- Color parser. Accepts 3, 4, 6,
|
||||
or 8 hex digits (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`). Note: spec.yaml
|
||||
says `#rrggbba` (7 digits) which is a typo -- the actual format is 8 digits.
|
||||
- `toml-config/src/config/parsers/exec.rs` -- Exec parser. Accepts string,
|
||||
array, or table. Understanding these three forms is important for writing
|
||||
correct TOML examples.
|
||||
- `src/config/handler.rs` -- Contains `update_capabilities`, which shows that
|
||||
client rule capabilities **replace** defaults (accumulator starts from zero).
|
||||
- The `docs/` directory has been removed. All of its content has been
|
||||
integrated into the book. The README now points to the hosted book at
|
||||
`https://mahkoh.github.io/jay/book`.
|
||||
|
||||
### Known spec.yaml bugs
|
||||
|
||||
- `px-per-wheel-scroll` is listed as `kind: boolean` but the parser
|
||||
(`toml-config/src/config/parsers/input.rs`) uses `fltorint` (a number).
|
||||
The documentation correctly describes it as a numeric value.
|
||||
|
||||
## Critical facts to get right
|
||||
|
||||
1. **Config replacement semantics.** Once `~/.config/jay/config.toml` exists,
|
||||
the entire built-in default configuration is replaced -- not merged. Even an
|
||||
empty config file means no shortcuts, no startup actions, nothing. Users must
|
||||
run `jay config init` to get a config pre-populated with the defaults.
|
||||
|
||||
2. **Config reload.** By default, Jay does not automatically reload
|
||||
config.toml. Reload must be triggered manually via the `alt-shift-r`
|
||||
shortcut (default) or the `reload-config-toml` action. However, setting
|
||||
`auto-reload = true` in config.toml enables inotify-based file watching
|
||||
with a 400 ms debounce (parsed in
|
||||
`toml-config/src/config/parsers/config.rs:209`, acted on in
|
||||
`toml-config/src/lib.rs:1348-1358`).
|
||||
|
||||
3. **Renderer requirement.** Jay requires at least one working renderer
|
||||
(OpenGL via libEGL+libGLESv2, or Vulkan via libvulkan + a GPU driver).
|
||||
Without one, no GPU can be initialized and nothing will be displayed. (Jay
|
||||
itself still starts -- the metal backend initializes logind, udev, and
|
||||
libinput successfully -- but no DRM devices can be set up, so the user sees
|
||||
a black screen.) These libraries are loaded at runtime, not linked at build
|
||||
time. Vulkan is the recommended renderer; OpenGL is legacy and receives no
|
||||
new features.
|
||||
|
||||
4. **Actions are composable.** Anywhere an action is accepted, an array of
|
||||
actions can be used instead. Named actions (`$name`) add another layer of
|
||||
reuse.
|
||||
|
||||
5. **Match systems.** Outputs, connectors, DRM devices, inputs, clients, and
|
||||
windows each have their own match system. All support the same logical
|
||||
combinators: AND (multiple fields in one table), OR (array of matchers),
|
||||
`not`, `all`, `any`, `exactly`.
|
||||
|
||||
6. **Input modes.** Jay supports an input mode stack (`push-mode`,
|
||||
`latch-mode`, `pop-mode`, `clear-modes`). Each mode can define its own
|
||||
shortcuts and inherit from a parent mode. This is how vim-style modal
|
||||
keybindings are implemented. Note: there are NO `resize-left/right/up/down`
|
||||
actions -- resizing is mouse-only. Use `move-*` actions in examples.
|
||||
|
||||
7. **Window/client rules are reactive.** Rules are re-evaluated whenever the
|
||||
matching criteria change (e.g. a window's title changes). The `latch` action
|
||||
fires when a previously-matching rule stops matching.
|
||||
|
||||
8. **Control center.** Opened with `alt-c` (default) or `jay control-center`.
|
||||
It is an egui-based GUI with 11 panes: Clients, Color Management,
|
||||
Compositor, GPUs, Idle, Input, Look and Feel, Outputs (with visual
|
||||
arrangement editor), Virtual Outputs, Window Search, and Xwayland.
|
||||
|
||||
9. **VRR and tearing.** Both have per-output overrides and multiple mode
|
||||
variants (never, always, variant1/2/3). Important distinction: VRR
|
||||
variant1/2 use "fullscreen" as the criterion. Tearing variant3 says "a
|
||||
single application is displayed" (not necessarily fullscreen) -- check the
|
||||
spec.yaml wording carefully.
|
||||
|
||||
10. **Input device type flags.** The full list is: `is-keyboard`, `is-pointer`,
|
||||
`is-touch`, `is-tablet-tool`, `is-tablet-pad`, `is-gesture`, `is-switch`.
|
||||
Note that `is-switch` exists in the parser but is missing from spec.yaml.
|
||||
|
||||
11. **Features chapter is the single source for the feature list.** The
|
||||
introduction links to `features.md` but does not duplicate any feature
|
||||
bullets. All feature descriptions, the protocol support table, and CLI help
|
||||
output live in `features.md` only.
|
||||
|
||||
12. **Privilege separation.** Jay supports granting elevated Wayland protocol
|
||||
access via three methods: `privileged = true` in window rules with
|
||||
`jay run-privileged`, connection tags with client rules, and client match
|
||||
rules by PID/sandboxing. This is documented in the "Granting Privileges"
|
||||
section of `window-rules.md`. **Important:** when any client rule matches,
|
||||
its capabilities **replace** the defaults entirely (they are not added on
|
||||
top). Multiple matching rules are unioned together, but the defaults
|
||||
(`layer-shell | drm-lease` for unsandboxed, `drm-lease` for sandboxed)
|
||||
are only used when no rule matches at all.
|
||||
|
||||
13. **Exec action formats.** The `exec` field in exec actions accepts three
|
||||
forms: a plain string (program name only, no arguments), an array of
|
||||
strings (first element is the program, rest are arguments), or a table
|
||||
with `prog`/`shell`, `args`, `env`, `privileged`, and `tag` fields. A
|
||||
common mistake is using a plain string with spaces like
|
||||
`exec = "notify-send 'hello'"` -- this treats the entire string as the
|
||||
program name. Use the array form instead:
|
||||
`exec = ["notify-send", "hello"]`.
|
||||
|
||||
## Style guidelines
|
||||
|
||||
- Write for users, not developers. Explain what things do, not how they are
|
||||
implemented.
|
||||
- Use ` ```shell ` for shell commands, prefixed with `~$` and `sudo` where
|
||||
appropriate.
|
||||
- Use ` ```toml ` for TOML configuration examples.
|
||||
- Use **mdbook admonitions** (`> [!NOTE]`, `> [!TIP]`, `> [!WARNING]`,
|
||||
`> [!IMPORTANT]`) instead of `> **Note:**` blockquote patterns. mdbook
|
||||
0.5.2+ is installed and supports this syntax.
|
||||
- **Keyboard shortcuts** must be enclosed in backticks and use **lowercase
|
||||
modifiers** -- this matches the format the TOML parser expects. Keysym names
|
||||
retain their original case. Examples: `alt-shift-c`, `ctrl-alt-F2`,
|
||||
`alt-Return`. Never write `Alt-Shift-c` or `Alt+C`.
|
||||
- **Tables vs definition lists.** Use mdbook definition lists (`Term\n:
|
||||
Description`) for two-column term-to-description mappings. Keep true
|
||||
grid-like tables only when they have 3+ meaningful data columns (e.g.,
|
||||
package names per distro, the protocol support table with version numbers).
|
||||
- **TOML formatting.** Break long inline TOML tables over multiple lines with
|
||||
trailing commas (TOML 1.1 syntax). Use 4-space indentation inside TOML code
|
||||
blocks, never 2-space.
|
||||
- Keep examples practical -- show real use cases, not abstract syntax.
|
||||
- Link to the auto-generated spec (`spec.generated.md`) for exhaustive field
|
||||
listings. The book should teach concepts and workflows; the spec is the
|
||||
complete reference.
|
||||
- Each chapter should be self-contained enough to be useful on its own, but
|
||||
cross-reference related chapters where helpful.
|
||||
- Avoid duplicating large tables of every possible value. Summarize, give
|
||||
examples, and link to the spec for the full list.
|
||||
- When documenting the control center, always verify field names, ordering,
|
||||
and conditional visibility against the `src/control_center/cc_*.rs` source
|
||||
files. UI labels must match exactly (case-sensitive).
|
||||
|
||||
## Verification methodology
|
||||
|
||||
When making changes, verify against source code. The most error-prone areas
|
||||
are:
|
||||
|
||||
1. **Control center pane documentation** -- Field names, ordering, and
|
||||
conditional visibility must match the `show_*` functions in the cc_*.rs
|
||||
files. Fields are often conditional (only shown for certain device types or
|
||||
when certain values are set).
|
||||
|
||||
2. **VRR/tearing mode descriptions** -- The exact semantics differ subtly
|
||||
between modes and between VRR vs tearing. Always check spec.yaml wording.
|
||||
|
||||
3. **Exec action examples** -- A plain string is the program name only (no
|
||||
argument splitting). Use arrays or tables when arguments are needed.
|
||||
|
||||
4. **Capability/privilege semantics** -- Capabilities from matching rules
|
||||
replace defaults; they do not add to them. Verify against
|
||||
`src/config/handler.rs:update_capabilities` if in doubt.
|
||||
|
||||
## Building the book
|
||||
|
||||
```shell
|
||||
~$ cd book
|
||||
~$ mdbook build # outputs to book/book/
|
||||
~$ mdbook serve # local preview at http://localhost:3000
|
||||
```
|
||||
|
||||
Requires [mdbook](https://github.com/rust-lang/mdBook) to be installed:
|
||||
|
||||
```shell
|
||||
~$ cargo install mdbook
|
||||
```
|
||||
7
book/book.toml
Normal file
7
book/book.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[book]
|
||||
title = "The Jay Book"
|
||||
language = "en"
|
||||
src = "src"
|
||||
|
||||
[output.html]
|
||||
git-repository-url = "https://github.com/mahkoh/jay"
|
||||
45
book/src/SUMMARY.md
Normal file
45
book/src/SUMMARY.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Summary
|
||||
|
||||
[Introduction](introduction.md)
|
||||
|
||||
# Overview
|
||||
|
||||
- [Features](features.md)
|
||||
|
||||
# Getting Started
|
||||
|
||||
- [Installation](installation.md)
|
||||
- [Running Jay](running.md)
|
||||
- [Control Center](control-center.md)
|
||||
|
||||
# Configuration
|
||||
|
||||
- [Configuration Overview](configuration/index.md)
|
||||
- [Keymaps & Repeat Rate](configuration/keymaps.md)
|
||||
- [Shortcuts](configuration/shortcuts.md)
|
||||
- [Startup Actions](configuration/startup.md)
|
||||
- [Environment Variables](configuration/environment.md)
|
||||
- [Outputs (Monitors)](configuration/outputs.md)
|
||||
- [Input Devices](configuration/inputs.md)
|
||||
- [GPUs](configuration/gpu.md)
|
||||
- [Idle & Screen Locking](configuration/idle.md)
|
||||
- [Theme & Appearance](configuration/theme.md)
|
||||
- [Status Bar](configuration/status-bar.md)
|
||||
- [Xwayland](configuration/xwayland.md)
|
||||
- [Miscellaneous](configuration/misc.md)
|
||||
|
||||
# Using Jay
|
||||
|
||||
- [Tiling](tiling.md)
|
||||
- [Workspaces](workspaces.md)
|
||||
- [Floating Windows](floating.md)
|
||||
- [Mouse Interactions](mouse.md)
|
||||
- [Input Modes](input-modes.md)
|
||||
- [Window & Client Rules](window-rules.md)
|
||||
- [Screen Sharing](screen-sharing.md)
|
||||
- [HDR & Color Management](hdr.md)
|
||||
|
||||
# Reference
|
||||
|
||||
- [Command-Line Interface](cli.md)
|
||||
- [Troubleshooting](troubleshooting.md)
|
||||
663
book/src/cli.md
Normal file
663
book/src/cli.md
Normal file
|
|
@ -0,0 +1,663 @@
|
|||
# Command-Line Interface
|
||||
|
||||
Jay provides a comprehensive CLI for controlling the compositor, managing
|
||||
displays, input devices, clients, and more. All subcommands communicate with
|
||||
the running compositor over the Wayland protocol unless otherwise noted.
|
||||
|
||||
> [!TIP]
|
||||
> Generate shell completions for tab-completion support:
|
||||
>
|
||||
> ```shell
|
||||
> ~$ jay generate-completion bash > ~/.local/share/bash-completion/completions/jay
|
||||
> ~$ jay generate-completion zsh > ~/.zfunc/_jay
|
||||
> ~$ jay generate-completion fish > ~/.config/fish/completions/jay.fish
|
||||
> ~$ jay generate-completion elvish # pipe to appropriate location
|
||||
> ~$ jay generate-completion powershell # pipe to appropriate location
|
||||
> ```
|
||||
|
||||
Every subcommand accepts a global `--log-level` option (`trace`, `debug`,
|
||||
`info`, `warn`, `error`, `off`) that controls the verbosity of the CLI tool itself.
|
||||
|
||||
---
|
||||
|
||||
## Running
|
||||
|
||||
### `jay run`
|
||||
|
||||
Start the compositor.
|
||||
|
||||
```shell
|
||||
~$ jay run
|
||||
```
|
||||
|
||||
Optionally specify which backends to try (comma-separated, tried in order):
|
||||
|
||||
```shell
|
||||
~$ jay run --backends x11,metal,headless
|
||||
```
|
||||
|
||||
The default order is `x11,metal`. The first backend that can be started is
|
||||
used. `metal` is the native DRM/KMS backend for bare-metal sessions.
|
||||
|
||||
### `jay quit`
|
||||
|
||||
Stop the running compositor.
|
||||
|
||||
```shell
|
||||
~$ jay quit
|
||||
```
|
||||
|
||||
### `jay pid`
|
||||
|
||||
Print the PID of the running compositor.
|
||||
|
||||
```shell
|
||||
~$ jay pid
|
||||
```
|
||||
|
||||
### `jay version`
|
||||
|
||||
Print the Jay version.
|
||||
|
||||
```shell
|
||||
~$ jay version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### `jay config init`
|
||||
|
||||
Generate a configuration file pre-populated with all defaults.
|
||||
|
||||
```shell
|
||||
~$ jay config init
|
||||
```
|
||||
|
||||
If a config already exists, pass `--overwrite` to replace it (the old file is
|
||||
backed up):
|
||||
|
||||
```shell
|
||||
~$ jay config init --overwrite
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Once a config file exists, the entire built-in default configuration is
|
||||
> replaced -- not merged. An empty config file means no shortcuts, no startup
|
||||
> actions, nothing. Always use `jay config init` to start with a working
|
||||
> configuration.
|
||||
|
||||
### `jay config path`
|
||||
|
||||
Print the path to the config file.
|
||||
|
||||
```shell
|
||||
~$ jay config path
|
||||
```
|
||||
|
||||
### `jay config open-dir`
|
||||
|
||||
Open the configuration directory with `xdg-open`.
|
||||
|
||||
```shell
|
||||
~$ jay config open-dir
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Display & Graphics
|
||||
|
||||
All display and GPU commands live under `jay randr`.
|
||||
|
||||
### Showing Current Settings
|
||||
|
||||
```shell
|
||||
~$ jay randr
|
||||
~$ jay randr show
|
||||
~$ jay randr show --modes # include all available modes
|
||||
~$ jay randr show --formats # include all available framebuffer formats
|
||||
```
|
||||
|
||||
### GPU / Card Commands
|
||||
|
||||
Set the primary (render) GPU:
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 primary
|
||||
```
|
||||
|
||||
Set the graphics API:
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 api vulkan
|
||||
~$ jay randr card card0 api opengl
|
||||
```
|
||||
|
||||
Toggle direct scanout:
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 direct-scanout enable
|
||||
~$ jay randr card card0 direct-scanout disable
|
||||
```
|
||||
|
||||
Adjust the page-flip margin (in milliseconds, default 1.5):
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 timing set-flip-margin 1.5
|
||||
```
|
||||
|
||||
### Output Commands
|
||||
|
||||
Enable or disable an output:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 enable
|
||||
~$ jay randr output DP-1 disable
|
||||
```
|
||||
|
||||
Set the position:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 position 1920 0
|
||||
```
|
||||
|
||||
Set the scale (fractional scaling supported):
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 scale 1.5
|
||||
~$ jay randr output DP-1 scale --round-to-float 1.333
|
||||
```
|
||||
|
||||
Set the mode (width, height, refresh rate in Hz):
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 mode 2560 1440 144.0
|
||||
```
|
||||
|
||||
Set the transform:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 transform rotate-90
|
||||
~$ jay randr output DP-1 transform none
|
||||
```
|
||||
|
||||
Available transforms: `none`, `rotate-90`, `rotate-180`, `rotate-270`, `flip`,
|
||||
`flip-rotate-90`, `flip-rotate-180`, `flip-rotate-270`.
|
||||
|
||||
Override the non-desktop setting:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 non-desktop true
|
||||
~$ jay randr output DP-1 non-desktop default
|
||||
```
|
||||
|
||||
Configure VRR (variable refresh rate):
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 vrr set-mode always
|
||||
~$ jay randr output DP-1 vrr set-mode variant3
|
||||
~$ jay randr output DP-1 vrr set-cursor-hz 240
|
||||
~$ jay randr output DP-1 vrr set-cursor-hz none
|
||||
```
|
||||
|
||||
VRR modes: `never`, `always`, `variant1` (one or more fullscreen apps),
|
||||
`variant2` (single fullscreen app), `variant3` (single fullscreen app with
|
||||
game/video content type). Pass `none` to `set-cursor-hz` to remove the cursor
|
||||
Hz cap.
|
||||
|
||||
Configure tearing:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 tearing set-mode variant3
|
||||
```
|
||||
|
||||
Tearing modes: `never`, `always`, `variant1` (one or more applications
|
||||
displayed fullscreen), `variant2` (single application displayed fullscreen),
|
||||
`variant3` (default -- single displayed application that requested tearing).
|
||||
|
||||
Set the framebuffer format:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 format set xrgb8888
|
||||
```
|
||||
|
||||
Set the output color space and EOTF (for HDR):
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 colors set bt2020 pq
|
||||
~$ jay randr output DP-1 colors set default default
|
||||
```
|
||||
|
||||
Set the brightness (in cd/m^2, or `default`):
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 brightness 203
|
||||
~$ jay randr output DP-1 brightness default
|
||||
```
|
||||
|
||||
Set the blend space:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 blend-space linear
|
||||
~$ jay randr output DP-1 blend-space srgb
|
||||
```
|
||||
|
||||
Enable or disable native gamut usage:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 use-native-gamut true
|
||||
~$ jay randr output DP-1 use-native-gamut false
|
||||
```
|
||||
|
||||
### Virtual Outputs
|
||||
|
||||
```shell
|
||||
~$ jay randr virtual-output create my-virtual-display
|
||||
~$ jay randr virtual-output remove my-virtual-display
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Input
|
||||
|
||||
All input commands live under `jay input`.
|
||||
|
||||
### Showing Input Devices
|
||||
|
||||
```shell
|
||||
~$ jay input
|
||||
~$ jay input show
|
||||
~$ jay input show -v # verbose output with device details
|
||||
```
|
||||
|
||||
### Seat Commands
|
||||
|
||||
Show seat information:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default show
|
||||
~$ jay input seat default show -v
|
||||
```
|
||||
|
||||
Set keyboard repeat rate (repeats per second, initial delay in ms):
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-repeat-rate 25 600
|
||||
```
|
||||
|
||||
Set the keymap from RMLVO names:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-keymap-from-names -l de
|
||||
~$ jay input seat default set-keymap-from-names -l us -v intl -o compose:ralt
|
||||
```
|
||||
|
||||
Set the keymap from a file (or stdin):
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-keymap /path/to/keymap.xkb
|
||||
```
|
||||
|
||||
Retrieve the current keymap:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default keymap > current.xkb
|
||||
```
|
||||
|
||||
Toggle hardware cursor:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default use-hardware-cursor true
|
||||
~$ jay input seat default use-hardware-cursor false
|
||||
```
|
||||
|
||||
Set cursor size:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-cursor-size 24
|
||||
```
|
||||
|
||||
Configure the simple (XCompose-based) input method:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default simple-im enable
|
||||
~$ jay input seat default simple-im disable
|
||||
~$ jay input seat default simple-im reload
|
||||
```
|
||||
|
||||
### Device Commands
|
||||
|
||||
Show device information:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 show
|
||||
```
|
||||
|
||||
Set acceleration profile and speed:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-accel-profile flat
|
||||
~$ jay input device 42 set-accel-profile adaptive
|
||||
~$ jay input device 42 set-accel-speed -0.5
|
||||
```
|
||||
|
||||
Configure tap behavior:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-tap-enabled true
|
||||
~$ jay input device 42 set-tap-drag-enabled true
|
||||
~$ jay input device 42 set-tap-drag-lock-enabled false
|
||||
```
|
||||
|
||||
Set left-handed mode:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-left-handed true
|
||||
```
|
||||
|
||||
Set natural scrolling:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-natural-scrolling true
|
||||
```
|
||||
|
||||
Set pixels per scroll-wheel step:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-px-per-wheel-scroll 30.0
|
||||
```
|
||||
|
||||
Set the transform matrix (2x2):
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-transform-matrix 1.0 0.0 0.0 1.0
|
||||
```
|
||||
|
||||
Set the calibration matrix (2x3, for touchscreens):
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-calibration-matrix 1.0 0.0 0.0 0.0 1.0 0.0
|
||||
```
|
||||
|
||||
Set the click method:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-click-method clickfinger
|
||||
~$ jay input device 42 set-click-method button-areas
|
||||
~$ jay input device 42 set-click-method none
|
||||
```
|
||||
|
||||
Toggle middle button emulation:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-middle-button-emulation true
|
||||
```
|
||||
|
||||
Set a per-device keymap:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 set-keymap /path/to/keymap.xkb
|
||||
~$ jay input device 42 set-keymap-from-names -l de
|
||||
~$ jay input device 42 keymap > device.xkb
|
||||
```
|
||||
|
||||
Attach / detach a device from a seat:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 attach default
|
||||
~$ jay input device 42 detach
|
||||
```
|
||||
|
||||
Map a device to a specific output:
|
||||
|
||||
```shell
|
||||
~$ jay input device 42 map-to-output DP-1
|
||||
~$ jay input device 42 remove-mapping
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Idle & Locking
|
||||
|
||||
### `jay idle`
|
||||
|
||||
Show idle status, including the current interval, grace period, and active
|
||||
inhibitors:
|
||||
|
||||
```shell
|
||||
~$ jay idle
|
||||
~$ jay idle status
|
||||
```
|
||||
|
||||
### `jay idle set`
|
||||
|
||||
Set the idle interval. Durations can be specified in flexible formats:
|
||||
|
||||
```shell
|
||||
~$ jay idle set 10m
|
||||
~$ jay idle set 1m 30s
|
||||
~$ jay idle set disabled
|
||||
```
|
||||
|
||||
### `jay idle set-grace-period`
|
||||
|
||||
Set the grace period (screens go black but are not locked/disabled):
|
||||
|
||||
```shell
|
||||
~$ jay idle set-grace-period 30s
|
||||
~$ jay idle set-grace-period disabled
|
||||
```
|
||||
|
||||
### `jay unlock`
|
||||
|
||||
Unlock the compositor. This is useful when the screen locker crashes and the
|
||||
session remains locked. Run it from another TTY or via SSH. You must set
|
||||
`WAYLAND_DISPLAY` to the socket of the Jay compositor:
|
||||
|
||||
```shell
|
||||
~$ WAYLAND_DISPLAY=wayland-1 jay unlock
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Logging
|
||||
|
||||
### `jay log`
|
||||
|
||||
Open the log file in `less`:
|
||||
|
||||
```shell
|
||||
~$ jay log
|
||||
~$ jay log -f # follow mode (like tail -f)
|
||||
~$ jay log -e # jump to end of log
|
||||
~$ jay log --path # print the log file path instead
|
||||
```
|
||||
|
||||
### `jay set-log-level`
|
||||
|
||||
Change the log level at runtime:
|
||||
|
||||
```shell
|
||||
~$ jay set-log-level debug
|
||||
~$ jay set-log-level info
|
||||
```
|
||||
|
||||
Available levels: `trace`, `debug`, `info`, `warn`, `error`, `off`.
|
||||
|
||||
---
|
||||
|
||||
## Screenshots
|
||||
|
||||
### `jay screenshot`
|
||||
|
||||
Take a screenshot of the entire display:
|
||||
|
||||
```shell
|
||||
~$ jay screenshot
|
||||
~$ jay screenshot --format png
|
||||
~$ jay screenshot --format qoi
|
||||
~$ jay screenshot my-screenshot.png
|
||||
```
|
||||
|
||||
If no filename is given, the screenshot is saved as
|
||||
`%Y-%m-%d-%H%M%S_jay.<ext>` in the current directory. The filename supports
|
||||
strftime format specifiers.
|
||||
|
||||
---
|
||||
|
||||
## Clients & Windows
|
||||
|
||||
### `jay clients`
|
||||
|
||||
List all connected clients:
|
||||
|
||||
```shell
|
||||
~$ jay clients
|
||||
~$ jay clients show all
|
||||
```
|
||||
|
||||
Show a specific client by ID:
|
||||
|
||||
```shell
|
||||
~$ jay clients show id 42
|
||||
```
|
||||
|
||||
Interactively select a window and show its client:
|
||||
|
||||
```shell
|
||||
~$ jay clients show select-window
|
||||
```
|
||||
|
||||
Kill a client by ID:
|
||||
|
||||
```shell
|
||||
~$ jay clients kill id 42
|
||||
```
|
||||
|
||||
Interactively select a window and kill its client:
|
||||
|
||||
```shell
|
||||
~$ jay clients kill select-window
|
||||
```
|
||||
|
||||
### `jay tree query`
|
||||
|
||||
Inspect the compositor's surface tree:
|
||||
|
||||
```shell
|
||||
~$ jay tree query root
|
||||
~$ jay tree query -r root # recursive
|
||||
~$ jay tree query -r --all-clients root # show client details for every node
|
||||
~$ jay tree query workspace-name main
|
||||
~$ jay tree query select-workspace
|
||||
~$ jay tree query select-window
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Xwayland
|
||||
|
||||
### `jay xwayland`
|
||||
|
||||
Show Xwayland status (scaling mode, implied scale):
|
||||
|
||||
```shell
|
||||
~$ jay xwayland
|
||||
~$ jay xwayland status
|
||||
```
|
||||
|
||||
### `jay xwayland set-scaling-mode`
|
||||
|
||||
```shell
|
||||
~$ jay xwayland set-scaling-mode default
|
||||
~$ jay xwayland set-scaling-mode downscaled
|
||||
```
|
||||
|
||||
In `downscaled` mode, X11 windows are rendered at the highest integer scale and
|
||||
then downscaled, which can improve sharpness on HiDPI displays.
|
||||
|
||||
---
|
||||
|
||||
## Color Management
|
||||
|
||||
### `jay color-management`
|
||||
|
||||
Show color management status:
|
||||
|
||||
```shell
|
||||
~$ jay color-management
|
||||
~$ jay color-management status
|
||||
```
|
||||
|
||||
### `jay color-management enable / disable`
|
||||
|
||||
```shell
|
||||
~$ jay color-management enable
|
||||
~$ jay color-management disable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Other Commands
|
||||
|
||||
### `jay control-center`
|
||||
|
||||
Open the [Control Center](control-center.md) GUI:
|
||||
|
||||
```shell
|
||||
~$ jay control-center
|
||||
```
|
||||
|
||||
### `jay portal`
|
||||
|
||||
Run the Jay desktop portal (provides screen sharing and other XDG desktop
|
||||
portal interfaces):
|
||||
|
||||
```shell
|
||||
~$ jay portal
|
||||
```
|
||||
|
||||
Normally the portal is started automatically. This command is for running it
|
||||
manually or debugging.
|
||||
|
||||
### `jay seat-test`
|
||||
|
||||
Test input events from a seat. Prints all keyboard, pointer, touch, gesture,
|
||||
tablet, and switch events to stdout:
|
||||
|
||||
```shell
|
||||
~$ jay seat-test
|
||||
~$ jay seat-test default
|
||||
~$ jay seat-test -a # test all seats simultaneously
|
||||
```
|
||||
|
||||
### `jay run-privileged`
|
||||
|
||||
Run a program with access to a privileged Wayland socket:
|
||||
|
||||
```shell
|
||||
~$ jay run-privileged my-program --arg1
|
||||
```
|
||||
|
||||
### `jay run-tagged`
|
||||
|
||||
Run a program with a tagged Wayland connection. All Wayland connections from the
|
||||
spawned process tree will carry the specified tag, which can be matched in
|
||||
[client rules](window-rules.md):
|
||||
|
||||
```shell
|
||||
~$ jay run-tagged my-tag firefox
|
||||
```
|
||||
|
||||
### `jay generate-completion`
|
||||
|
||||
Generate shell completion scripts:
|
||||
|
||||
```shell
|
||||
~$ jay generate-completion bash
|
||||
~$ jay generate-completion zsh
|
||||
~$ jay generate-completion fish
|
||||
~$ jay generate-completion elvish
|
||||
~$ jay generate-completion powershell
|
||||
```
|
||||
76
book/src/configuration/environment.md
Normal file
76
book/src/configuration/environment.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Environment Variables
|
||||
|
||||
Jay can set environment variables that are inherited by all programs it spawns.
|
||||
|
||||
## Setting environment variables at startup
|
||||
|
||||
Use the `[env]` table in your config to define variables that apply to every
|
||||
application launched by the compositor:
|
||||
|
||||
```toml
|
||||
[env]
|
||||
GTK_THEME = "Adwaita:dark"
|
||||
QT_QPA_PLATFORM = "wayland"
|
||||
MOZ_ENABLE_WAYLAND = "1"
|
||||
```
|
||||
|
||||
These variables are set when the config is loaded. Programs started after that
|
||||
point will inherit them.
|
||||
|
||||
## Changing variables at runtime
|
||||
|
||||
### set-env
|
||||
|
||||
Use the `set-env` action to add or update environment variables while the
|
||||
compositor is running. This affects all programs started **after** the action
|
||||
runs:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F11 = {
|
||||
type = "set-env",
|
||||
env = { GTK_THEME = "Adwaita:dark" },
|
||||
}
|
||||
alt-F12 = {
|
||||
type = "set-env",
|
||||
env = { GTK_THEME = "Adwaita" },
|
||||
}
|
||||
```
|
||||
|
||||
### unset-env
|
||||
|
||||
Use the `unset-env` action to remove environment variables:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F10 = { type = "unset-env", env = ["GTK_THEME"] }
|
||||
```
|
||||
|
||||
You can unset multiple variables at once with an array:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F10 = {
|
||||
type = "unset-env",
|
||||
env = ["GTK_THEME", "QT_QPA_PLATFORM"],
|
||||
}
|
||||
```
|
||||
|
||||
## Per-process environment variables
|
||||
|
||||
When using the table form of the `exec` action, you can set environment
|
||||
variables that apply only to that specific process:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-Return = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "alacritty",
|
||||
env = { TERM = "xterm-256color" },
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
These per-process variables are merged with (and override) the global
|
||||
environment for that single execution.
|
||||
293
book/src/configuration/gpu.md
Normal file
293
book/src/configuration/gpu.md
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
# GPUs
|
||||
|
||||
Jay configures graphics cards (DRM devices) through the `[[drm-devices]]`
|
||||
array. This is primarily useful on multi-GPU systems for selecting the render
|
||||
device, choosing a graphics API, and tuning per-device settings.
|
||||
|
||||
> [!NOTE]
|
||||
> DRM device configuration in `config.toml` is only applied when a device is
|
||||
> first discovered after the configuration is loaded. To change settings at
|
||||
> runtime, use `jay randr` or the `configure-drm-device` action.
|
||||
|
||||
## Matching GPUs
|
||||
|
||||
Every `[[drm-devices]]` entry requires a `match` field. When `match` is a
|
||||
**table**, all specified fields must match (AND). When `match` is an **array**,
|
||||
any entry matching is sufficient (OR).
|
||||
|
||||
### By PCI vendor and model (recommended)
|
||||
|
||||
PCI IDs are stable, unique identifiers. Use `jay randr` to find them:
|
||||
|
||||
```shell
|
||||
~$ jay randr
|
||||
```
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
gfx-api = "Vulkan"
|
||||
```
|
||||
|
||||
### By vendor or model name
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match.vendor = "Advanced Micro Devices, Inc. [AMD/ATI]"
|
||||
```
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match.model = "Raphael"
|
||||
```
|
||||
|
||||
### By syspath or devnode
|
||||
|
||||
The `syspath` is usually stable across reboots:
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match.syspath = "/sys/devices/pci0000:00/0000:00:08.1/0000:14:00.0"
|
||||
```
|
||||
|
||||
The `devnode` (e.g. `/dev/dri/card0`) is typically not stable.
|
||||
|
||||
## Naming GPUs
|
||||
|
||||
Assign a `name` to reference a device from other parts of the config:
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
name = "dedicated"
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
|
||||
[[drm-devices]]
|
||||
name = "integrated"
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x164e,
|
||||
}
|
||||
```
|
||||
|
||||
Names can then be used in `render-device`, shortcuts, and actions:
|
||||
|
||||
```toml
|
||||
render-device.name = "dedicated"
|
||||
```
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-v = {
|
||||
type = "configure-drm-device",
|
||||
dev = {
|
||||
match.name = "dedicated",
|
||||
gfx-api = "Vulkan",
|
||||
},
|
||||
}
|
||||
alt-o = {
|
||||
type = "configure-drm-device",
|
||||
dev = {
|
||||
match.name = "dedicated",
|
||||
gfx-api = "OpenGl",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Graphics API
|
||||
|
||||
Jay supports two rendering backends per device:
|
||||
|
||||
`Vulkan`
|
||||
: Uses libvulkan. The primary renderer -- use this unless you have a specific
|
||||
reason not to. Required for HDR. All devices in the system must support DRM
|
||||
format modifiers (most do, except AMD GPUs older than RX 5000).
|
||||
|
||||
`OpenGl`
|
||||
: Uses libEGL + libGLESv2. Maintained for backwards compatibility only. No new
|
||||
features will be added to this renderer.
|
||||
|
||||
### Per-device API
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
gfx-api = "Vulkan"
|
||||
```
|
||||
|
||||
### Default API for all devices
|
||||
|
||||
Set the top-level `gfx-api` to apply to any device without a per-device
|
||||
override:
|
||||
|
||||
```toml
|
||||
gfx-api = "Vulkan"
|
||||
```
|
||||
|
||||
This only takes effect for devices discovered after the config is loaded.
|
||||
|
||||
## Direct scanout
|
||||
|
||||
Direct scanout lets the compositor hand a client's buffer directly to the
|
||||
display hardware, bypassing composition. This can reduce latency and power
|
||||
usage, but may cause visual glitches with some hardware or applications.
|
||||
|
||||
### Per-device
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
direct-scanout = false
|
||||
```
|
||||
|
||||
### Global toggle
|
||||
|
||||
```toml
|
||||
direct-scanout = false
|
||||
```
|
||||
|
||||
## Flip margin
|
||||
|
||||
The flip margin is the time (in milliseconds) between the compositor
|
||||
initiating a page flip and the output's vertical blank event. It determines
|
||||
the minimum achievable input latency. The default is 1.5 ms.
|
||||
|
||||
```toml
|
||||
[[drm-devices]]
|
||||
match = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
flip-margin-ms = 2.0
|
||||
```
|
||||
|
||||
If the margin is set too small, the compositor will dynamically increase it to
|
||||
avoid missed frames.
|
||||
|
||||
## Explicit sync
|
||||
|
||||
Explicit sync coordinates buffer access between the compositor and GPU drivers.
|
||||
It is enabled by default and generally should not be disabled:
|
||||
|
||||
```toml
|
||||
explicit-sync = true
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> This setting cannot be changed after the compositor has started. It can only
|
||||
> be set in `config.toml` before launching Jay.
|
||||
|
||||
## Render device
|
||||
|
||||
On multi-GPU systems, select which GPU performs compositing with the
|
||||
`render-device` field. The first matching device is used:
|
||||
|
||||
```toml
|
||||
render-device.name = "dedicated"
|
||||
|
||||
[[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"
|
||||
```
|
||||
|
||||
You can also match directly without naming:
|
||||
|
||||
```toml
|
||||
render-device = {
|
||||
pci-vendor = 0x1002,
|
||||
pci-model = 0x73ff,
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Changing the render device at runtime (via the `set-render-device` action)
|
||||
> may cause windows to become invisible until they are resized or otherwise
|
||||
> redrawn.
|
||||
|
||||
## Runtime changes
|
||||
|
||||
### Listing GPUs
|
||||
|
||||
```shell
|
||||
~$ jay randr
|
||||
```
|
||||
|
||||
This shows all DRM devices with their PCI IDs, vendor/model names, current
|
||||
API, and other settings.
|
||||
|
||||
### Changing settings at runtime
|
||||
|
||||
Use `jay randr` subcommands:
|
||||
|
||||
```shell
|
||||
~$ jay randr card <card> api vulkan
|
||||
~$ jay randr card <card> direct-scanout enable
|
||||
~$ jay randr card <card> primary
|
||||
```
|
||||
|
||||
### Using shortcuts
|
||||
|
||||
The `configure-drm-device` action applies settings from a keybinding:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F5 = {
|
||||
type = "configure-drm-device",
|
||||
dev = {
|
||||
match.name = "dedicated",
|
||||
gfx-api = "Vulkan",
|
||||
},
|
||||
}
|
||||
alt-F6 = {
|
||||
type = "configure-drm-device",
|
||||
dev = {
|
||||
match.name = "dedicated",
|
||||
gfx-api = "OpenGl",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The `set-render-device` action switches the compositing GPU:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F7 = { type = "set-render-device", dev.name = "dedicated" }
|
||||
alt-F8 = { type = "set-render-device", dev.name = "integrated" }
|
||||
```
|
||||
|
||||
## Hardware cursor
|
||||
|
||||
The `use-hardware-cursor` top-level setting controls whether the hardware cursor
|
||||
plane is used. Disabling this forces software cursor rendering, which can be
|
||||
useful for debugging.
|
||||
|
||||
```toml
|
||||
use-hardware-cursor = true # default
|
||||
```
|
||||
|
||||
## Full reference
|
||||
|
||||
For the exhaustive list of all DRM device fields, match criteria, and related
|
||||
types, see the [auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md).
|
||||
186
book/src/configuration/idle.md
Normal file
186
book/src/configuration/idle.md
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
# Idle & Screen Locking
|
||||
|
||||
Jay can detect when the system is idle and automatically run an action -- most
|
||||
commonly launching a screen locker. The idle timeout, grace period, and
|
||||
on-idle action are all configurable.
|
||||
|
||||
## Idle timeout
|
||||
|
||||
Set how long the system must be idle before the on-idle action fires. Specify
|
||||
`minutes` and/or `seconds`:
|
||||
|
||||
```toml
|
||||
idle.minutes = 10
|
||||
```
|
||||
|
||||
```toml
|
||||
idle = { minutes = 5, seconds = 30 }
|
||||
```
|
||||
|
||||
If all values are explicitly set to 0, the idle timeout is disabled entirely:
|
||||
|
||||
```toml
|
||||
idle = { minutes = 0 }
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The idle timeout defined in `config.toml` cannot be changed by reloading the
|
||||
> configuration. Use `jay idle` or the `configure-idle` action to change it at
|
||||
> runtime.
|
||||
|
||||
## Grace period
|
||||
|
||||
The grace period is a warning phase between the timeout expiring and the actual
|
||||
idle event. During the grace period, the screen goes black but outputs are not
|
||||
yet disabled and the `on-idle` action has not yet fired. Any input during this
|
||||
period cancels the idle transition.
|
||||
|
||||
The default grace period is 5 seconds. Configure it with:
|
||||
|
||||
```toml
|
||||
idle.grace-period.seconds = 3
|
||||
```
|
||||
|
||||
```toml
|
||||
idle.grace-period = { minutes = 0, seconds = 10 }
|
||||
```
|
||||
|
||||
Set both values to 0 to disable the grace period (immediately fire the on-idle
|
||||
action when the timeout expires):
|
||||
|
||||
```toml
|
||||
idle.grace-period = { seconds = 0 }
|
||||
```
|
||||
|
||||
## On-idle action
|
||||
|
||||
The `on-idle` field defines what happens when the idle timeout (plus grace
|
||||
period) elapses. The most common use is launching a screen locker:
|
||||
|
||||
```toml
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Screen lockers that use the Wayland session lock protocol (like swaylock)
|
||||
> need `privileged = true` in the exec configuration. This grants the process
|
||||
> the necessary permissions to lock the session.
|
||||
|
||||
You can also combine multiple actions:
|
||||
|
||||
```toml
|
||||
on-idle = [
|
||||
{
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
},
|
||||
{ type = "exec", exec = ["notify-send", "System locked"] },
|
||||
]
|
||||
```
|
||||
|
||||
## Complete example
|
||||
|
||||
A typical idle and screen-locking setup:
|
||||
|
||||
```toml
|
||||
idle = {
|
||||
minutes = 10,
|
||||
grace-period = { seconds = 5 },
|
||||
}
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
This means:
|
||||
1. After 10 minutes of inactivity, the screen goes black (grace period begins).
|
||||
2. If no input occurs within 5 seconds, swaylock is launched and outputs are
|
||||
disabled.
|
||||
3. Any input during the grace period cancels the transition and restores the
|
||||
display.
|
||||
|
||||
## Runtime changes
|
||||
|
||||
### Checking idle status
|
||||
|
||||
```shell
|
||||
~$ jay idle status
|
||||
```
|
||||
|
||||
### Changing the idle timeout
|
||||
|
||||
```shell
|
||||
~$ jay idle set 5m
|
||||
~$ jay idle set 1m30s
|
||||
~$ jay idle set disabled
|
||||
```
|
||||
|
||||
### Changing the grace period
|
||||
|
||||
```shell
|
||||
~$ jay idle set-grace-period 10s
|
||||
~$ jay idle set-grace-period 0s
|
||||
```
|
||||
|
||||
### Duration format
|
||||
|
||||
The CLI accepts durations in a flexible format:
|
||||
|
||||
| Example | Meaning |
|
||||
|----------------------|------------------------|
|
||||
| `1m` | 1 minute |
|
||||
| `1m5s` | 1 minute 5 seconds |
|
||||
| `1min 5sec` | 1 minute 5 seconds |
|
||||
| `90s` | 90 seconds |
|
||||
| `disabled` | Disable the timeout |
|
||||
|
||||
### Unlocking
|
||||
|
||||
If the compositor is locked (e.g. the screen locker crashed), you can unlock
|
||||
it from another TTY or by SSH-ing into the machine. You must set
|
||||
`WAYLAND_DISPLAY` to the socket of the Jay compositor, since you are running
|
||||
the command outside the compositor session:
|
||||
|
||||
```shell
|
||||
~$ WAYLAND_DISPLAY=wayland-1 jay unlock
|
||||
```
|
||||
|
||||
Use `jay pid` with the same `WAYLAND_DISPLAY` value to verify you are
|
||||
targeting the correct compositor instance.
|
||||
|
||||
### Using shortcuts
|
||||
|
||||
The `configure-idle` action lets you change idle settings from a keybinding:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F9 = {
|
||||
type = "configure-idle",
|
||||
idle = {
|
||||
minutes = 5,
|
||||
grace-period = { seconds = 3 },
|
||||
},
|
||||
}
|
||||
alt-F10 = {
|
||||
type = "configure-idle",
|
||||
idle = { minutes = 0 },
|
||||
}
|
||||
```
|
||||
|
||||
## Full reference
|
||||
|
||||
For the exhaustive list of all idle-related fields and types, see the
|
||||
[auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md).
|
||||
130
book/src/configuration/index.md
Normal file
130
book/src/configuration/index.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# Configuration Overview
|
||||
|
||||
Jay is configured through a single TOML file located at:
|
||||
|
||||
```
|
||||
~/.config/jay/config.toml
|
||||
```
|
||||
|
||||
If this file does not exist, Jay uses built-in defaults that provide a
|
||||
reasonable starting configuration with common shortcuts, a US QWERTY keymap,
|
||||
and other sensible settings.
|
||||
|
||||
> [!WARNING]
|
||||
> Once `config.toml` exists, the **entire** built-in default configuration is
|
||||
> replaced -- not merged. Even a completely empty file means no shortcuts, no
|
||||
> startup actions, nothing. Always start from a full config rather than writing
|
||||
> one from scratch.
|
||||
|
||||
## Initializing the config
|
||||
|
||||
The easiest way to get started is to let Jay write the defaults for you:
|
||||
|
||||
```shell
|
||||
~$ jay config init
|
||||
```
|
||||
|
||||
This creates `~/.config/jay/config.toml` pre-populated with the full default
|
||||
configuration. You can then edit it to suit your needs.
|
||||
|
||||
If you already have a config file and want to reset it:
|
||||
|
||||
```shell
|
||||
~$ jay config init --overwrite
|
||||
```
|
||||
|
||||
The old file will be backed up to `config.toml.1` (or `.2`, `.3`, etc.) before
|
||||
being replaced.
|
||||
|
||||
## Other config subcommands
|
||||
|
||||
Print the path to the config file:
|
||||
|
||||
```shell
|
||||
~$ jay config path
|
||||
```
|
||||
|
||||
Open the config directory in your file manager:
|
||||
|
||||
```shell
|
||||
~$ jay config open-dir
|
||||
```
|
||||
|
||||
## Reloading the configuration
|
||||
|
||||
By default, Jay does not automatically reload `config.toml` when it changes on
|
||||
disk. To apply changes, trigger a reload manually:
|
||||
|
||||
- Press `alt-shift-r` (the default shortcut), or
|
||||
- Use the `reload-config-toml` action in any other action context (e.g. a named
|
||||
action or a window rule).
|
||||
|
||||
Most settings take effect immediately on reload. A few exceptions (like
|
||||
`log-level`, `explicit-sync`, and initial `drm-devices` settings) only apply
|
||||
at compositor startup.
|
||||
|
||||
### Automatic reloading
|
||||
|
||||
To have Jay watch `config.toml` for changes and reload automatically, add:
|
||||
|
||||
```toml
|
||||
auto-reload = true
|
||||
```
|
||||
|
||||
When enabled, Jay uses inotify to monitor the config file and its parent
|
||||
directories. Changes are debounced — the config is reloaded 400 ms after the
|
||||
last write, so rapid successive saves don't cause multiple reloads. If the file
|
||||
contents haven't actually changed, the reload is skipped.
|
||||
|
||||
Setting `auto-reload = false` will stop the watcher. Removing the key entirely
|
||||
leaves the watcher state unchanged (if it was running, it keeps running until
|
||||
the compositor restarts).
|
||||
|
||||
## Named actions
|
||||
|
||||
You can define reusable actions in the `[actions]` table and reference them
|
||||
anywhere an action is accepted by prefixing the name with `$`:
|
||||
|
||||
```toml
|
||||
[actions]
|
||||
launch-terminal = { type = "exec", exec = "alacritty" }
|
||||
launch-browser = { type = "exec", exec = "firefox" }
|
||||
|
||||
[shortcuts]
|
||||
alt-Return = "$launch-terminal"
|
||||
alt-b = "$launch-browser"
|
||||
```
|
||||
|
||||
Named actions can reference other named actions. The `max-action-depth` setting
|
||||
controls the maximum recursion depth to prevent infinite loops (default: 16):
|
||||
|
||||
```toml
|
||||
max-action-depth = 32
|
||||
```
|
||||
|
||||
## Composable actions
|
||||
|
||||
Anywhere an action is accepted, you can use an **array of actions** instead.
|
||||
This applies to shortcuts, startup hooks, named actions, and any other action
|
||||
field:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-q = [
|
||||
{ type = "exec", exec = ["notify-send", "Goodbye!"] },
|
||||
"quit",
|
||||
]
|
||||
```
|
||||
|
||||
## Advanced: shared library configuration
|
||||
|
||||
For users who need programmatic configuration beyond what TOML offers, Jay also
|
||||
supports configuration via a compiled Rust shared library using the
|
||||
[jay-config](https://docs.rs/jay-config) crate. This is an advanced option --
|
||||
the TOML config is sufficient for the vast majority of use cases.
|
||||
|
||||
## Full specification
|
||||
|
||||
This book covers the most common configuration options with explanations and
|
||||
examples. For an exhaustive listing of every field, type, and action, see the
|
||||
[auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md).
|
||||
336
book/src/configuration/inputs.md
Normal file
336
book/src/configuration/inputs.md
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
# Input Devices
|
||||
|
||||
Jay configures input devices through the `[[inputs]]` array. Each entry matches
|
||||
one or more devices and applies settings such as acceleration, tap behavior,
|
||||
and device-to-output mapping.
|
||||
|
||||
> [!NOTE]
|
||||
> Input configuration defined in `config.toml` is only applied to devices
|
||||
> connected after the configuration is loaded. To change settings for
|
||||
> already-connected devices, use `jay input` or the `configure-input` action.
|
||||
|
||||
## Matching input devices
|
||||
|
||||
Every `[[inputs]]` entry requires a `match` field. When `match` is a
|
||||
**table**, all specified fields must match (AND logic). When `match` is an
|
||||
**array**, any entry matching is sufficient (OR logic).
|
||||
|
||||
### By device name
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "Logitech G300s Optical Gaming Mouse"
|
||||
left-handed = true
|
||||
```
|
||||
|
||||
Run `jay input` to see the names of all connected input devices.
|
||||
|
||||
### By device type
|
||||
|
||||
Match all devices of a given type using boolean flags:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
natural-scrolling = true
|
||||
```
|
||||
|
||||
Available type flags: `is-keyboard`, `is-pointer`, `is-touch`,
|
||||
`is-tablet-tool`, `is-tablet-pad`, `is-gesture`, `is-switch`.
|
||||
|
||||
### By syspath or devnode
|
||||
|
||||
The `syspath` is usually stable across reboots and useful when you have
|
||||
multiple identical devices:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.syspath = "/sys/devices/pci0000:00/0000:00:08.1/0000:14:00.4/usb5/5-1/5-1.1/5-1.1.2/5-1.1.2:1.0"
|
||||
left-handed = true
|
||||
```
|
||||
|
||||
The `devnode` (e.g. `/dev/input/event4`) is typically not stable across
|
||||
reboots.
|
||||
|
||||
### Combining criteria
|
||||
|
||||
AND -- all fields in a single table must match:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match = { name = "SynPS/2 Synaptics TouchPad", is-pointer = true }
|
||||
tap-enabled = true
|
||||
```
|
||||
|
||||
OR -- any entry in an array may match:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match = [
|
||||
{ name = "Logitech G300s Optical Gaming Mouse" },
|
||||
{ name = "Razer DeathAdder V2" },
|
||||
]
|
||||
left-handed = true
|
||||
```
|
||||
|
||||
## Tagging devices
|
||||
|
||||
Assign a `tag` to reference a device from shortcuts or actions:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
tag = "mouse"
|
||||
match.is-pointer = true
|
||||
|
||||
[shortcuts]
|
||||
alt-l = {
|
||||
type = "configure-input",
|
||||
input = {
|
||||
match.tag = "mouse",
|
||||
left-handed = true,
|
||||
},
|
||||
}
|
||||
alt-r = {
|
||||
type = "configure-input",
|
||||
input = {
|
||||
match.tag = "mouse",
|
||||
left-handed = false,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Tags work similarly to output names -- they let you refer to matched devices
|
||||
elsewhere in the configuration.
|
||||
|
||||
## Libinput settings
|
||||
|
||||
These settings map directly to libinput device options. See the
|
||||
[libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/)
|
||||
for detailed explanations of each.
|
||||
|
||||
### Acceleration
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
accel-profile = "Flat"
|
||||
accel-speed = 0.0
|
||||
```
|
||||
|
||||
| Field | Values | Description |
|
||||
|----------------|----------------------------|----------------------------------------|
|
||||
| `accel-profile`| `Flat` or `Adaptive` | Pointer acceleration curve |
|
||||
| `accel-speed` | `-1.0` to `1.0` | Speed within the selected profile |
|
||||
|
||||
### Tap and click
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
tap-enabled = true
|
||||
tap-drag-enabled = true
|
||||
tap-drag-lock-enabled = false
|
||||
click-method = "clickfinger"
|
||||
```
|
||||
|
||||
| Field | Values | Description |
|
||||
|-------------------------|--------------------------------------------|-------------------------------------------|
|
||||
| `tap-enabled` | `true` / `false` | Tap-to-click on touchpads |
|
||||
| `tap-drag-enabled` | `true` / `false` | Tap-and-drag on touchpads |
|
||||
| `tap-drag-lock-enabled` | `true` / `false` | Keep drag active after lifting finger |
|
||||
| `click-method` | `none`, `button-areas`, `clickfinger` | How physical clicks are interpreted |
|
||||
|
||||
### Other libinput options
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
left-handed = true
|
||||
natural-scrolling = true
|
||||
middle-button-emulation = true
|
||||
```
|
||||
|
||||
`left-handed`
|
||||
: Swap left and right buttons
|
||||
|
||||
`natural-scrolling`
|
||||
: Reverse scroll direction ("macOS-style")
|
||||
|
||||
`middle-button-emulation`
|
||||
: Simultaneous left+right click produces a middle click
|
||||
|
||||
## Scroll speed
|
||||
|
||||
Control how many pixels each scroll wheel detent produces:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
px-per-wheel-scroll = 30
|
||||
```
|
||||
|
||||
This setting maps to the legacy `wl_pointer.axis` event that is mostly unused
|
||||
nowadays. It has no effect on applications that don't use this event.
|
||||
|
||||
## Transform matrix
|
||||
|
||||
Apply a 2x2 matrix to relative motion events. This is useful for adjusting
|
||||
pointer speed independently of libinput acceleration:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-pointer = true
|
||||
transform-matrix = [[0.35, 0], [0, 0.35]]
|
||||
```
|
||||
|
||||
The example above reduces pointer speed to 35% of normal. The identity matrix
|
||||
is `[[1, 0], [0, 1]]`.
|
||||
|
||||
## Calibration matrix
|
||||
|
||||
A 2x3 matrix for absolute input devices (touchscreens). This is passed
|
||||
directly to libinput:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.is-touch = true
|
||||
calibration-matrix = [[0, 1, 0], [-1, 0, 1]]
|
||||
```
|
||||
|
||||
The example above rotates touch input by 90 degrees.
|
||||
|
||||
## Per-device keymap
|
||||
|
||||
Override the global keymap for a specific keyboard:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "ZSA Technology Labs Inc ErgoDox EZ"
|
||||
keymap.rmlvo = {
|
||||
layout = "us",
|
||||
options = "compose:ralt",
|
||||
}
|
||||
```
|
||||
|
||||
The override becomes active when a key is pressed on that device. See the
|
||||
[Keymaps & Repeat Rate](keymaps.md) chapter for the full range of keymap
|
||||
options.
|
||||
|
||||
## Mapping to outputs
|
||||
|
||||
Map tablets and touchscreens to a specific output so that the input area
|
||||
corresponds to the correct display:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
name = "left"
|
||||
match.serial-number = "33K03894SL0"
|
||||
|
||||
[[inputs]]
|
||||
match.name = "Wacom Bamboo Comic 2FG Pen"
|
||||
output.name = "left"
|
||||
```
|
||||
|
||||
You can also map by connector:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "Wacom Bamboo Comic 2FG Pen"
|
||||
output.connector = "DP-1"
|
||||
```
|
||||
|
||||
To remove a mapping at runtime, use the `remove-mapping` field in a
|
||||
`configure-input` action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-x = {
|
||||
type = "configure-input",
|
||||
input = {
|
||||
match.tag = "wacom",
|
||||
remove-mapping = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Lid switch events
|
||||
|
||||
Lid switch devices report when a laptop lid is opened or closed. Use the
|
||||
`on-lid-closed` and `on-lid-opened` fields to trigger actions. These fields
|
||||
only work in the top-level `[[inputs]]` array:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "<lid 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,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Run `jay input` to find the name of your lid switch device.
|
||||
|
||||
## Convertible (2-in-1) events
|
||||
|
||||
For convertible laptops that switch between laptop and tablet form factors:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "<switch name>"
|
||||
on-converted-to-laptop = "$enable-keyboard"
|
||||
on-converted-to-tablet = "$disable-keyboard"
|
||||
```
|
||||
|
||||
These fields only work in the top-level `[[inputs]]` array.
|
||||
|
||||
## Runtime changes
|
||||
|
||||
### Listing devices
|
||||
|
||||
```shell
|
||||
~$ jay input
|
||||
```
|
||||
|
||||
This shows all connected input devices with their names, syspaths, devnodes,
|
||||
type flags, and current settings.
|
||||
|
||||
### Changing settings at runtime
|
||||
|
||||
```shell
|
||||
~$ jay input device <id> set-accel-profile flat
|
||||
~$ jay input device <id> set-accel-speed 0.5
|
||||
~$ jay input device <id> set-tap-enabled true
|
||||
~$ jay input device <id> set-left-handed true
|
||||
~$ jay input device <id> set-natural-scrolling true
|
||||
~$ jay input device <id> set-transform-matrix 0.35 0 0 0.35
|
||||
```
|
||||
|
||||
### Using shortcuts
|
||||
|
||||
The `configure-input` action applies settings from a keybinding:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-n = {
|
||||
type = "configure-input",
|
||||
input = {
|
||||
match.tag = "touchpad",
|
||||
natural-scrolling = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Full reference
|
||||
|
||||
For the exhaustive list of all input fields, match criteria, and related types,
|
||||
see the [auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md).
|
||||
144
book/src/configuration/keymaps.md
Normal file
144
book/src/configuration/keymaps.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# Keymaps & Repeat Rate
|
||||
|
||||
Jay uses XKB keymaps for keyboard layout configuration. The default keymap is
|
||||
US QWERTY.
|
||||
|
||||
## Setting the keymap
|
||||
|
||||
There are several ways to define a keymap.
|
||||
|
||||
### Using RMLVO names (recommended)
|
||||
|
||||
The simplest approach is to specify the layout using RMLVO (Rules, Model,
|
||||
Layout, Variants, Options) names:
|
||||
|
||||
```toml
|
||||
keymap.rmlvo = { layout = "de" }
|
||||
```
|
||||
|
||||
You can specify any combination of RMLVO fields:
|
||||
|
||||
```toml
|
||||
keymap.rmlvo = {
|
||||
layout = "us,de",
|
||||
variants = "dvorak,",
|
||||
options = "grp:ctrl_space_toggle",
|
||||
}
|
||||
```
|
||||
|
||||
All fields are optional. When a field is omitted, Jay checks the corresponding
|
||||
environment variable, then falls back to a default:
|
||||
|
||||
| Field | Environment Variable | Default |
|
||||
|------------|--------------------------|----------|
|
||||
| `rules` | `XKB_DEFAULT_RULES` | `evdev` |
|
||||
| `model` | `XKB_DEFAULT_MODEL` | `pc105` |
|
||||
| `layout` | `XKB_DEFAULT_LAYOUT` | `us` |
|
||||
| `variants` | `XKB_DEFAULT_VARIANTS` | *(none)* |
|
||||
| `options` | `XKB_DEFAULT_OPTIONS` | *(none)* |
|
||||
|
||||
### Using a raw XKB string
|
||||
|
||||
You can provide a complete XKB keymap as a multi-line string. See the
|
||||
[ArchWiki XKB guide](https://wiki.archlinux.org/title/X_keyboard_extension)
|
||||
for background on the format.
|
||||
|
||||
```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)" };
|
||||
};
|
||||
"""
|
||||
```
|
||||
|
||||
### Loading from a file
|
||||
|
||||
Point to an XKB file. Relative paths are resolved from the config directory
|
||||
(`~/.config/jay/`):
|
||||
|
||||
```toml
|
||||
keymap.path = "./my-keymap.xkb"
|
||||
```
|
||||
|
||||
## Named keymaps
|
||||
|
||||
You can define multiple named keymaps and switch between them at runtime.
|
||||
Define them with the `[[keymaps]]` array, then select the default with
|
||||
`keymap.name`:
|
||||
|
||||
```toml
|
||||
keymap.name = "laptop"
|
||||
|
||||
[[keymaps]]
|
||||
name = "laptop"
|
||||
rmlvo = { layout = "us" }
|
||||
|
||||
[[keymaps]]
|
||||
name = "external"
|
||||
rmlvo = { layout = "de", options = "compose:ralt" }
|
||||
```
|
||||
|
||||
Each entry in `[[keymaps]]` must have a `name` and exactly one of `map`,
|
||||
`path`, or `rmlvo`.
|
||||
|
||||
### Switching keymaps at runtime
|
||||
|
||||
Use the `set-keymap` action to switch between named keymaps:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F9 = { type = "set-keymap", keymap.name = "laptop" }
|
||||
alt-F10 = { type = "set-keymap", keymap.name = "external" }
|
||||
```
|
||||
|
||||
You can also switch keymaps from the command line:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-keymap-from-names --layout de
|
||||
```
|
||||
|
||||
## Repeat rate
|
||||
|
||||
The repeat rate controls how keys behave when held down. It has two parameters:
|
||||
|
||||
- `rate` -- number of key repeats per second
|
||||
- `delay` -- milliseconds to wait before repeating begins
|
||||
|
||||
```toml
|
||||
repeat-rate = { rate = 25, delay = 250 }
|
||||
```
|
||||
|
||||
### Changing repeat rate at runtime
|
||||
|
||||
Use the `set-repeat-rate` action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F11 = {
|
||||
type = "set-repeat-rate",
|
||||
rate = { rate = 40, delay = 200 },
|
||||
}
|
||||
```
|
||||
|
||||
Or from the command line:
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-repeat-rate 40 200
|
||||
```
|
||||
|
||||
## Per-device keymaps
|
||||
|
||||
You can override the keymap for specific input devices using the `[[inputs]]`
|
||||
array. For example, to use a different layout for an external keyboard:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "My External Keyboard"
|
||||
keymap.rmlvo = { layout = "de" }
|
||||
```
|
||||
|
||||
See the [Input Devices](inputs.md) chapter for more on matching and configuring
|
||||
individual devices.
|
||||
207
book/src/configuration/misc.md
Normal file
207
book/src/configuration/misc.md
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
# Miscellaneous
|
||||
|
||||
This chapter covers smaller configuration options that don't warrant their own
|
||||
chapter.
|
||||
|
||||
## Color Management
|
||||
|
||||
The Wayland color management protocol lets applications communicate color space
|
||||
information to the compositor. It is disabled by default.
|
||||
|
||||
```toml
|
||||
[color-management]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Changing this setting has no effect on applications that are already running.
|
||||
|
||||
The CLI and control center (**Color Management** pane) can also toggle it:
|
||||
|
||||
```shell
|
||||
~$ jay color-management enable
|
||||
~$ jay color-management disable
|
||||
~$ jay color-management status
|
||||
```
|
||||
|
||||
See [HDR & Color Management](../hdr.md) for a complete guide to HDR output and
|
||||
the color management protocol.
|
||||
|
||||
## Libei
|
||||
|
||||
[libei](https://gitlab.freedesktop.org/libinput/libei) allows applications to
|
||||
emulate input events. By default, applications can only access libei through
|
||||
the portal (which prompts the user for permission). Setting `enable-socket`
|
||||
exposes an unauthenticated socket that any application can use without a prompt.
|
||||
|
||||
```toml
|
||||
libei.enable-socket = false # default
|
||||
```
|
||||
|
||||
## UI Drag
|
||||
|
||||
Controls whether workspaces and tiles can be dragged with the mouse, and how
|
||||
far the pointer must move before a drag begins.
|
||||
|
||||
```toml
|
||||
ui-drag = { enabled = true, threshold = 10 } # defaults
|
||||
```
|
||||
|
||||
Set `enabled = false` to disable drag-and-drop rearrangement entirely. Increase
|
||||
`threshold` if you find yourself accidentally starting drags.
|
||||
|
||||
## Floating Window Pin Icon
|
||||
|
||||
Floating windows can show a small pin icon. This is hidden by default.
|
||||
|
||||
```toml
|
||||
[float]
|
||||
show-pin-icon = true
|
||||
```
|
||||
|
||||
## Workspace Capture
|
||||
|
||||
Controls whether newly created workspaces can be captured (e.g. for screen
|
||||
sharing). The default is `true`.
|
||||
|
||||
```toml
|
||||
workspace-capture = false
|
||||
```
|
||||
|
||||
## Simple Input Method
|
||||
|
||||
Jay includes a built-in XCompose-based input method. It is enabled by default
|
||||
but only activates when no external input method is running.
|
||||
|
||||
```toml
|
||||
[simple-im]
|
||||
enabled = true # default
|
||||
```
|
||||
|
||||
Related actions for use in shortcuts:
|
||||
|
||||
`enable-simple-im`
|
||||
: Enable the built-in input method
|
||||
|
||||
`disable-simple-im`
|
||||
: Disable the built-in input method
|
||||
|
||||
`toggle-simple-im-enabled`
|
||||
: Toggle the built-in input method
|
||||
|
||||
`reload-simple-im`
|
||||
: Reload XCompose files without restarting
|
||||
|
||||
`enable-unicode-input`
|
||||
: Start Unicode codepoint input (requires active IM)
|
||||
|
||||
## Log Level
|
||||
|
||||
Sets the compositor's log verbosity. Valid values: `trace`, `debug`, `info`,
|
||||
`warn`, `error`.
|
||||
|
||||
```toml
|
||||
log-level = "info"
|
||||
```
|
||||
|
||||
This setting **cannot** be changed by reloading the configuration. Use the CLI
|
||||
instead:
|
||||
|
||||
```shell
|
||||
~$ jay set-log-level debug
|
||||
```
|
||||
|
||||
## Focus Follows Mouse
|
||||
|
||||
When enabled, moving the pointer over a window automatically gives it keyboard
|
||||
focus.
|
||||
|
||||
```toml
|
||||
focus-follows-mouse = true # default
|
||||
```
|
||||
|
||||
## Window Management Key
|
||||
|
||||
Designates a key that, while held, enables window management mode. In this
|
||||
mode, the left mouse button moves floating windows and the right mouse button
|
||||
resizes any window.
|
||||
|
||||
```toml
|
||||
window-management-key = "Alt_L"
|
||||
```
|
||||
|
||||
The value should be a keysym name (see the
|
||||
[xkbcommon keysym list](https://github.com/xkbcommon/libxkbcommon/blob/master/include/xkbcommon/xkbcommon-keysyms.h)
|
||||
with the `XKB_KEY_` prefix removed).
|
||||
|
||||
## Middle-Click Paste
|
||||
|
||||
Controls whether middle-clicking pastes the primary selection. Changing this
|
||||
has no effect on running applications.
|
||||
|
||||
```toml
|
||||
middle-click-paste = true # default
|
||||
```
|
||||
|
||||
## Pointer Revert Key
|
||||
|
||||
Pressing this key cancels any active grabs, drags, or selections, returning the
|
||||
pointer to its default state. The default is `Escape`.
|
||||
|
||||
```toml
|
||||
pointer-revert-key = "Escape" # default
|
||||
```
|
||||
|
||||
Set it to `NoSymbol` to disable this functionality entirely:
|
||||
|
||||
```toml
|
||||
pointer-revert-key = "NoSymbol"
|
||||
```
|
||||
|
||||
## Fallback Output Mode
|
||||
|
||||
Determines which output is used when no particular output is specified -- for
|
||||
example, when placing a newly opened window or choosing which workspace to move
|
||||
with `move-to-output`.
|
||||
|
||||
`cursor`
|
||||
: Use the output the cursor is on (default)
|
||||
|
||||
`focus`
|
||||
: Use the output the focused window is on
|
||||
|
||||
```toml
|
||||
fallback-output-mode = "cursor" # default
|
||||
```
|
||||
|
||||
## Focus History
|
||||
|
||||
Configures the behavior of the `focus-prev` and `focus-next` actions.
|
||||
|
||||
`only-visible`
|
||||
: Only cycle to windows that are already visible. Default: `false`.
|
||||
|
||||
`same-workspace`
|
||||
: Only cycle to windows on the current workspace. Default: `false`.
|
||||
|
||||
If `only-visible` is `false`, switching to a non-visible window will make it
|
||||
visible first.
|
||||
|
||||
```toml
|
||||
[focus-history]
|
||||
only-visible = true
|
||||
same-workspace = true
|
||||
```
|
||||
|
||||
## Control Center Fonts
|
||||
|
||||
The `[egui]` table configures fonts used by the control center (an egui-based
|
||||
GUI).
|
||||
|
||||
```toml
|
||||
[egui]
|
||||
proportional-fonts = ["sans-serif", "Noto Sans", "Noto Color Emoji"] # default
|
||||
monospace-fonts = ["monospace", "Noto Sans Mono", "Noto Color Emoji"] # default
|
||||
```
|
||||
|
||||
Override these lists to use your preferred fonts in the control center UI.
|
||||
472
book/src/configuration/outputs.md
Normal file
472
book/src/configuration/outputs.md
Normal file
|
|
@ -0,0 +1,472 @@
|
|||
# Outputs (Monitors)
|
||||
|
||||
Jay configures monitors through the `[[outputs]]` array. Each entry matches
|
||||
one or more connected displays and applies settings such as position, scale,
|
||||
mode, and color management.
|
||||
|
||||
> [!NOTE]
|
||||
> Output configuration defined in `config.toml` is only applied the first time
|
||||
> a matching output is connected after the compositor starts. To change
|
||||
> settings at runtime, use `jay randr` or the `configure-output` action.
|
||||
|
||||
## Matching outputs
|
||||
|
||||
Every `[[outputs]]` entry requires a `match` field that selects which monitors
|
||||
the settings apply to. You can match by serial number, connector name,
|
||||
manufacturer, or model.
|
||||
|
||||
When `match` is a **table**, all specified fields must match (AND logic). When
|
||||
`match` is an **array**, any entry matching is sufficient (OR logic).
|
||||
|
||||
### By serial number (recommended)
|
||||
|
||||
The serial number is a unique identifier that stays the same regardless of
|
||||
which port the monitor is plugged into:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
scale = 1.5
|
||||
```
|
||||
|
||||
Run `jay randr` to find the serial number of your connected displays.
|
||||
|
||||
### By connector name
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.connector = "DP-1"
|
||||
scale = 1.25
|
||||
```
|
||||
|
||||
Connector names (like `DP-1`, `HDMI-A-1`, `eDP-1`) can change if you move
|
||||
cables between ports.
|
||||
|
||||
### By manufacturer and model
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match = { manufacturer = "BNQ", model = "BenQ GW2480" }
|
||||
scale = 1.25
|
||||
```
|
||||
|
||||
When multiple fields appear in a single table, all must match.
|
||||
|
||||
### Combining criteria (OR)
|
||||
|
||||
Use an array to match any of several outputs with the same settings:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match = [
|
||||
{ serial-number = "33K03894SL0" },
|
||||
{ serial-number = "ETW1M02062SL0" },
|
||||
]
|
||||
scale = 2.0
|
||||
```
|
||||
|
||||
## Naming outputs
|
||||
|
||||
Assign a `name` to reference an output from other parts of the config -- for
|
||||
example, when mapping a tablet to a specific monitor or using shortcuts to
|
||||
reconfigure outputs at runtime:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
name = "left"
|
||||
match.serial-number = "33K03894SL0"
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
[[outputs]]
|
||||
name = "right"
|
||||
match.serial-number = "ETW1M02062SL0"
|
||||
x = 1920
|
||||
y = 0
|
||||
```
|
||||
|
||||
Other rules can then reference these names:
|
||||
|
||||
```toml
|
||||
# Map a drawing tablet to the left monitor
|
||||
[[inputs]]
|
||||
match.name = "Wacom Intuos Pro M Pen"
|
||||
output.name = "left"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Rotate a named output with a shortcut
|
||||
[shortcuts]
|
||||
alt-r = {
|
||||
type = "configure-output",
|
||||
output = {
|
||||
match.name = "right",
|
||||
transform = "rotate-90",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Position
|
||||
|
||||
The `x` and `y` fields place outputs in compositor space. Coordinates are
|
||||
integers >= 0 and represent the top-left corner of the output:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
x = 0
|
||||
y = 0
|
||||
|
||||
[[outputs]]
|
||||
match.serial-number = "ETW1M02062SL0"
|
||||
x = 2560
|
||||
y = 0
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> The control center (`alt-c` by default) includes a visual output arrangement
|
||||
> editor where you can drag monitors into position.
|
||||
|
||||
## Scale
|
||||
|
||||
Set fractional scaling with a number greater than 0:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
scale = 1.5
|
||||
```
|
||||
|
||||
Common values: `1.0` (no scaling), `1.25`, `1.5`, `2.0`.
|
||||
|
||||
## Transform
|
||||
|
||||
Rotate or flip the output. The available values are:
|
||||
|
||||
`none`
|
||||
: No transformation
|
||||
|
||||
`rotate-90`
|
||||
: Rotate 90 degrees counter-clockwise
|
||||
|
||||
`rotate-180`
|
||||
: Rotate 180 degrees
|
||||
|
||||
`rotate-270`
|
||||
: Rotate 270 degrees counter-clockwise
|
||||
|
||||
`flip`
|
||||
: Flip around the vertical axis
|
||||
|
||||
`flip-rotate-90`
|
||||
: Flip vertically, then rotate 90 degrees counter-clockwise
|
||||
|
||||
`flip-rotate-180`
|
||||
: Flip vertically, then rotate 180 degrees
|
||||
|
||||
`flip-rotate-270`
|
||||
: Flip vertically, then rotate 270 degrees counter-clockwise
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
transform = "rotate-90"
|
||||
```
|
||||
|
||||
## Mode
|
||||
|
||||
Set the resolution and refresh rate with the `mode` field. If `refresh-rate` is
|
||||
omitted, the first available mode with the specified resolution is used:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
mode = {
|
||||
width = 2560,
|
||||
height = 1440,
|
||||
refresh-rate = 144.0,
|
||||
}
|
||||
```
|
||||
|
||||
Use `jay randr` to see all available modes for each output:
|
||||
|
||||
```shell
|
||||
~$ jay randr show --modes
|
||||
```
|
||||
|
||||
## Variable Refresh Rate (VRR)
|
||||
|
||||
VRR (also known as FreeSync or Adaptive Sync) allows the display to vary its
|
||||
refresh rate to match the content being rendered, reducing stuttering and
|
||||
tearing.
|
||||
|
||||
Configure VRR with the `vrr` field:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
vrr = { mode = "variant1", cursor-hz = 90 }
|
||||
```
|
||||
|
||||
### VRR modes
|
||||
|
||||
`never`
|
||||
: VRR is always off (default)
|
||||
|
||||
`always`
|
||||
: VRR is always on
|
||||
|
||||
`variant1`
|
||||
: VRR is on when one or more applications are displayed fullscreen
|
||||
|
||||
`variant2`
|
||||
: VRR is on when exactly one application is displayed fullscreen
|
||||
|
||||
`variant3`
|
||||
: VRR is on when a single application is displayed fullscreen and describes its
|
||||
content type as video or game via the `wp_content_type_v1` protocol
|
||||
|
||||
### Cursor refresh rate
|
||||
|
||||
When VRR is active, cursor movement can cause the screen to spike to maximum
|
||||
refresh rate. The `cursor-hz` field limits cursor-triggered updates:
|
||||
|
||||
```toml
|
||||
vrr = { mode = "always", cursor-hz = 90 }
|
||||
```
|
||||
|
||||
Set `cursor-hz = "none"` for unbounded cursor updates (the default). A numeric
|
||||
value means the cursor is updated at that rate in Hz, or faster if the
|
||||
application is already driving updates above that rate.
|
||||
|
||||
You can also set default VRR settings for all outputs at the top level:
|
||||
|
||||
```toml
|
||||
vrr = { mode = "variant1", cursor-hz = 90 }
|
||||
```
|
||||
|
||||
Per-output settings override the top-level default.
|
||||
|
||||
## Tearing
|
||||
|
||||
Tearing allows frames to be presented immediately instead of waiting for
|
||||
vertical blank, reducing input latency at the cost of visible tearing
|
||||
artifacts.
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
tearing.mode = "variant3"
|
||||
```
|
||||
|
||||
### Tearing modes
|
||||
|
||||
`never`
|
||||
: Tearing is never enabled
|
||||
|
||||
`always`
|
||||
: Tearing is always enabled
|
||||
|
||||
`variant1`
|
||||
: Tearing is enabled when one or more applications are displayed fullscreen
|
||||
|
||||
`variant2`
|
||||
: Tearing is enabled when a single application is displayed fullscreen
|
||||
|
||||
`variant3`
|
||||
: Tearing is enabled when a single application is displayed and has requested tearing (default)
|
||||
|
||||
The default tearing mode is `variant3`. Like VRR, per-output settings override
|
||||
top-level defaults:
|
||||
|
||||
```toml
|
||||
tearing.mode = "never"
|
||||
```
|
||||
|
||||
## Framebuffer format
|
||||
|
||||
The default framebuffer format is `xrgb8888`. You can change it to any DRM
|
||||
fourcc format:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
format = "rgb565"
|
||||
```
|
||||
|
||||
Common formats include `xrgb8888`, `argb8888`, `xbgr8888`, `abgr8888`,
|
||||
`rgb565`, and many others. See the
|
||||
[auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md) for the full list.
|
||||
|
||||
## HDR and color management
|
||||
|
||||
Jay supports HDR output through color space, transfer function, and brightness
|
||||
settings. These require the Vulkan renderer. For a conceptual overview and
|
||||
step-by-step guide, see [HDR & Color Management](../hdr.md).
|
||||
|
||||
### Color space
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
color-space = "bt2020"
|
||||
```
|
||||
|
||||
Values: `default` (usually sRGB) or `bt2020`.
|
||||
|
||||
### Transfer function (EOTF)
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
transfer-function = "pq"
|
||||
```
|
||||
|
||||
Values: `default` (usually gamma 2.2) or `pq` (Perceptual Quantizer, used for
|
||||
HDR10).
|
||||
|
||||
### Brightness
|
||||
|
||||
Set SDR content brightness in cd/m^2 or use `"default"`:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
brightness = 80
|
||||
```
|
||||
|
||||
The default depends on the transfer function:
|
||||
- With `default` EOTF: the maximum brightness of the display, anchored at
|
||||
80 cd/m^2. Setting a value below 80 creates HDR headroom.
|
||||
- With `pq`: 203 cd/m^2.
|
||||
|
||||
This setting has no effect unless the Vulkan renderer is in use.
|
||||
|
||||
## Blend space
|
||||
|
||||
Controls how colors are blended when compositing overlapping surfaces:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
blend-space = "linear"
|
||||
```
|
||||
|
||||
`srgb`
|
||||
: Classic desktop blending in sRGB space (default)
|
||||
|
||||
`linear`
|
||||
: Physically correct blending in linear light -- produces brighter results
|
||||
|
||||
## Native gamut
|
||||
|
||||
By default, Jay assumes displays use sRGB primaries (matching the behavior of
|
||||
most other compositors). In reality, many displays have a wider gamut.
|
||||
|
||||
Setting `use-native-gamut = true` tells Jay to use the primaries advertised in
|
||||
the display's EDID. This can produce more accurate colors and allows
|
||||
color-managed applications to use the full gamut:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
use-native-gamut = true
|
||||
```
|
||||
|
||||
This has no effect when the display is explicitly operating in a wide color
|
||||
space (e.g. BT.2020).
|
||||
|
||||
## Connector configuration
|
||||
|
||||
The `[[connectors]]` array lets you enable or disable physical display
|
||||
connectors. This is useful for permanently disabling a port:
|
||||
|
||||
```toml
|
||||
[[connectors]]
|
||||
match.name = "eDP-1"
|
||||
enabled = false
|
||||
```
|
||||
|
||||
Connector configuration is applied when the connector is first discovered by
|
||||
the compositor, which typically happens only at startup.
|
||||
|
||||
## Lid switch (auto-disable laptop screen)
|
||||
|
||||
On laptops, you can automatically disable the built-in display when the lid is
|
||||
closed using the `[[inputs]]` array. The lid switch is an input device:
|
||||
|
||||
```toml
|
||||
[[inputs]]
|
||||
match.name = "<lid 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,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Run `jay input` to find the name of your lid switch device. See the
|
||||
[Input Devices](inputs.md) chapter for more details.
|
||||
|
||||
## Runtime changes
|
||||
|
||||
Output settings in `config.toml` are only applied when a display is first
|
||||
connected after compositor startup. For runtime changes, use the `jay randr`
|
||||
CLI or the `configure-output` action.
|
||||
|
||||
### Listing outputs
|
||||
|
||||
```shell
|
||||
~$ jay randr
|
||||
```
|
||||
|
||||
This shows all connected outputs with their connector names, serial numbers,
|
||||
current modes, scales, transforms, and available modes.
|
||||
|
||||
### Changing settings at runtime
|
||||
|
||||
```shell
|
||||
~$ jay randr output <name-or-connector> scale 1.5
|
||||
~$ jay randr output <name-or-connector> mode 2560 1440 144.0
|
||||
~$ jay randr output <name-or-connector> position 1920 0
|
||||
~$ jay randr output <name-or-connector> transform rotate-90
|
||||
~$ jay randr output <name-or-connector> enable
|
||||
~$ jay randr output <name-or-connector> disable
|
||||
```
|
||||
|
||||
### Using shortcuts
|
||||
|
||||
The `configure-output` action lets you change output settings from a
|
||||
keybinding:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F7 = {
|
||||
type = "configure-output",
|
||||
output = {
|
||||
match.name = "right",
|
||||
transform = "none",
|
||||
},
|
||||
}
|
||||
alt-F8 = {
|
||||
type = "configure-output",
|
||||
output = {
|
||||
match.name = "right",
|
||||
transform = "rotate-90",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Full reference
|
||||
|
||||
For the exhaustive list of all output fields, match criteria, and related
|
||||
types, see the [auto-generated specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md).
|
||||
505
book/src/configuration/shortcuts.md
Normal file
505
book/src/configuration/shortcuts.md
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
# Shortcuts
|
||||
|
||||
Shortcuts bind key combinations to actions. They are the primary way to
|
||||
interact with Jay.
|
||||
|
||||
## Basic syntax
|
||||
|
||||
Shortcuts are defined in the `[shortcuts]` table. The left side is a key
|
||||
combination; the right side is an action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-q = "quit"
|
||||
alt-Return = { type = "exec", exec = "alacritty" }
|
||||
alt-shift-c = "close"
|
||||
```
|
||||
|
||||
### Key format
|
||||
|
||||
Key combinations follow the pattern `MODIFIER-MODIFIER-KEYSYM`:
|
||||
|
||||
```
|
||||
(MOD-)*KEYSYM
|
||||
```
|
||||
|
||||
**Keysym names** are unmodified XKB keysym names from [xkbcommon-keysyms.h](https://github.com/xkbcommon/libxkbcommon/blob/master/include/xkbcommon/xkbcommon-keysyms.h)
|
||||
with the `XKB_KEY_` prefix removed. Use the unmodified keysym -- write
|
||||
`shift-q`, not `shift-Q`.
|
||||
|
||||
### Modifiers
|
||||
|
||||
The available modifiers are:
|
||||
|
||||
`shift`
|
||||
: Shift key
|
||||
|
||||
`ctrl`
|
||||
: Control key
|
||||
|
||||
`alt`
|
||||
: Alt key
|
||||
|
||||
`logo`
|
||||
: Super/Meta/Windows key
|
||||
|
||||
`lock`
|
||||
: Lock modifier
|
||||
|
||||
`caps`
|
||||
: Caps Lock
|
||||
|
||||
`num`
|
||||
: Num Lock
|
||||
|
||||
`mod1`
|
||||
: Mod1 (typically Alt)
|
||||
|
||||
`mod2`
|
||||
: Mod2 (typically Num Lock)
|
||||
|
||||
`mod3`
|
||||
: Mod3
|
||||
|
||||
`mod4`
|
||||
: Mod4 (typically Super)
|
||||
|
||||
`mod5`
|
||||
: Mod5
|
||||
|
||||
`release`
|
||||
: Fire on key **release** instead of press
|
||||
|
||||
The `release` modifier is special: it causes the action to trigger when the key
|
||||
is released rather than when it is pressed.
|
||||
|
||||
## Simple actions
|
||||
|
||||
Simple actions are written as plain strings. Here are the most commonly used
|
||||
ones:
|
||||
|
||||
**Focus and movement:**
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-h = "focus-left"
|
||||
alt-j = "focus-down"
|
||||
alt-k = "focus-up"
|
||||
alt-l = "focus-right"
|
||||
|
||||
alt-shift-h = "move-left"
|
||||
alt-shift-j = "move-down"
|
||||
alt-shift-k = "move-up"
|
||||
alt-shift-l = "move-right"
|
||||
```
|
||||
|
||||
**Layout:**
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-d = "split-horizontal"
|
||||
alt-v = "split-vertical"
|
||||
alt-t = "toggle-split"
|
||||
alt-m = "toggle-mono"
|
||||
alt-f = "focus-parent"
|
||||
```
|
||||
|
||||
**Window management:**
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-u = "toggle-fullscreen"
|
||||
alt-shift-f = "toggle-floating"
|
||||
alt-shift-c = "close"
|
||||
```
|
||||
|
||||
**Compositor control:**
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-q = "quit"
|
||||
alt-shift-r = "reload-config-toml"
|
||||
```
|
||||
|
||||
**Other useful simple actions:**
|
||||
|
||||
- `consume` -- consume the key event (prevent it from reaching applications).
|
||||
Key-press events that trigger shortcuts are consumed by default; key-release
|
||||
events are forwarded by default. Consuming key-release events can cause keys
|
||||
to get stuck in the focused application.
|
||||
- `forward` -- forward the key event to the focused application (the inverse
|
||||
of `consume`)
|
||||
- `none` -- unbind this key combination (useful for overriding defaults or
|
||||
inherited mode bindings)
|
||||
- `disable-pointer-constraint` -- release a pointer lock/confinement
|
||||
- `focus-parent` -- move focus to the parent container
|
||||
- `toggle-bar`, `show-bar`, `hide-bar` -- control the status bar
|
||||
- `open-control-center` -- open the Jay control center GUI
|
||||
- `warp-mouse-to-focus` -- warp the cursor to the center of the focused window
|
||||
- `kill-client` -- forcefully disconnect a client (in a window rule, kills the
|
||||
window's client; in a client rule, kills the matched client; has no effect
|
||||
in plain shortcuts)
|
||||
- `focus-below`, `focus-above` -- move focus to the layer below or above the
|
||||
current layer
|
||||
- `focus-tiles` -- focus the tile layer
|
||||
- `create-mark`, `jump-to-mark` -- interactively create or jump to a mark
|
||||
(the next pressed key identifies the mark). See [Marks](#marks) below.
|
||||
- `enable-window-management`, `disable-window-management` -- programmatically
|
||||
enable or disable [window management mode](../floating.md#window-management-mode)
|
||||
- `reload-config-so` -- reload the shared-library configuration (`config.so`)
|
||||
|
||||
See the [specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md) for the full list of simple
|
||||
actions.
|
||||
|
||||
## Parameterized actions
|
||||
|
||||
Actions that need arguments are written as tables with a `type` field:
|
||||
|
||||
### Launching programs
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-Return = { type = "exec", exec = "alacritty" }
|
||||
alt-p = { type = "exec", exec = "bemenu-run" }
|
||||
```
|
||||
|
||||
### Switching virtual terminals
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
ctrl-alt-F1 = { type = "switch-to-vt", num = 1 }
|
||||
ctrl-alt-F2 = { type = "switch-to-vt", num = 2 }
|
||||
```
|
||||
|
||||
### Workspaces
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F1 = { type = "show-workspace", name = "1" }
|
||||
alt-F2 = { type = "show-workspace", name = "2" }
|
||||
|
||||
alt-shift-F1 = { type = "move-to-workspace", name = "1" }
|
||||
alt-shift-F2 = { type = "move-to-workspace", name = "2" }
|
||||
```
|
||||
|
||||
### Moving workspaces to outputs
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
logo-ctrl-shift-Right = {
|
||||
type = "move-to-output",
|
||||
direction = "right",
|
||||
}
|
||||
logo-ctrl-shift-Left = {
|
||||
type = "move-to-output",
|
||||
direction = "left",
|
||||
}
|
||||
```
|
||||
|
||||
### Other parameterized actions
|
||||
|
||||
- `set-keymap` -- change the active keymap
|
||||
- `set-repeat-rate` -- change the keyboard repeat rate
|
||||
- `set-env` -- set environment variables for future spawned programs
|
||||
- `unset-env` -- remove environment variables
|
||||
- `configure-connector` -- enable/disable a monitor
|
||||
- `configure-input` -- change input device settings
|
||||
- `configure-output` -- change output settings
|
||||
- `configure-idle` -- change the idle timeout
|
||||
- `configure-direct-scanout` -- enable or disable direct scanout
|
||||
- `configure-drm-device` -- apply settings to a DRM device
|
||||
- `set-theme` -- change theme settings
|
||||
- `set-log-level` -- change the compositor log level
|
||||
- `set-gfx-api` -- set the graphics API for new DRM devices (usually only
|
||||
effective at startup)
|
||||
- `set-render-device` -- set the render device for compositing
|
||||
- `define-action` -- define or redefine a named action at runtime
|
||||
- `undefine-action` -- remove a named action
|
||||
- `create-mark` -- create a mark with an explicit ID (see [Marks](#marks))
|
||||
- `jump-to-mark` -- jump to a mark with an explicit ID
|
||||
- `copy-mark` -- copy a mark from one ID to another
|
||||
- `create-virtual-output` -- create a virtual output
|
||||
- `remove-virtual-output` -- remove a virtual output
|
||||
|
||||
See the [specification](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md) for the complete list.
|
||||
|
||||
## Running multiple actions
|
||||
|
||||
Use an array to run several actions from a single shortcut:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-q = [
|
||||
{ type = "exec", exec = ["notify-send", "Goodbye!"] },
|
||||
"quit",
|
||||
]
|
||||
```
|
||||
|
||||
## The exec action in detail
|
||||
|
||||
The `exec` field accepts three forms:
|
||||
|
||||
**A simple string** -- the program name with no arguments:
|
||||
|
||||
```toml
|
||||
alt-Return = { type = "exec", exec = "alacritty" }
|
||||
```
|
||||
|
||||
**An array of strings** -- the program name followed by arguments:
|
||||
|
||||
```toml
|
||||
alt-n = { type = "exec", exec = ["notify-send", "Hello", "World"] }
|
||||
```
|
||||
|
||||
**A table** -- full control over execution. Exactly one of `prog` or `shell`
|
||||
must be specified:
|
||||
|
||||
```toml
|
||||
# Using prog + args
|
||||
alt-n = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "notify-send",
|
||||
args = ["Hello"],
|
||||
env = { LANG = "en_US.UTF-8" },
|
||||
},
|
||||
}
|
||||
|
||||
# Using shell (runs as: $SHELL -c "command")
|
||||
alt-s = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
shell = "grim - | wl-copy",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Table fields:
|
||||
|
||||
`prog`
|
||||
: Program to execute (mutually exclusive with `shell`)
|
||||
|
||||
`shell`
|
||||
: Shell command to run via `$SHELL -c` (mutually exclusive with `prog`)
|
||||
|
||||
`args`
|
||||
: Arguments array (only with `prog`)
|
||||
|
||||
`env`
|
||||
: Per-process environment variables
|
||||
|
||||
`privileged`
|
||||
: If `true`, grants access to privileged Wayland protocols (default: `false`)
|
||||
|
||||
`tag`
|
||||
: Tag to apply to all Wayland connections spawned by this process
|
||||
|
||||
### Practical examples
|
||||
|
||||
Volume control with `pactl`:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
XF86AudioRaiseVolume = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-volume", "0", "+5%"],
|
||||
}
|
||||
XF86AudioLowerVolume = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-volume", "0", "-5%"],
|
||||
}
|
||||
XF86AudioMute = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-mute", "0", "toggle"],
|
||||
}
|
||||
```
|
||||
|
||||
Taking a screenshot and copying to clipboard:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
Print = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
shell = "grim - | wl-copy",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Complex shortcuts
|
||||
|
||||
Complex shortcuts provide additional control via the `[complex-shortcuts]`
|
||||
table. They support:
|
||||
|
||||
- **`mod-mask`** -- controls which modifiers are considered when matching.
|
||||
Set to `""` to ignore all modifiers.
|
||||
- **`action`** -- the action to run on key press (defaults to `"none"`).
|
||||
- **`latch`** -- an action to run when the key is **released**.
|
||||
|
||||
### Volume keys regardless of modifiers
|
||||
|
||||
The volume keys should work whether or not Alt, Shift, etc. are held:
|
||||
|
||||
```toml
|
||||
[complex-shortcuts.XF86AudioRaiseVolume]
|
||||
mod-mask = ""
|
||||
action = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-volume", "0", "+5%"],
|
||||
}
|
||||
|
||||
[complex-shortcuts.XF86AudioLowerVolume]
|
||||
mod-mask = ""
|
||||
action = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-volume", "0", "-5%"],
|
||||
}
|
||||
```
|
||||
|
||||
### Push-to-talk
|
||||
|
||||
Unmute audio while a key is held, mute on release:
|
||||
|
||||
```toml
|
||||
[complex-shortcuts.alt-x]
|
||||
action = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-mute", "0", "0"],
|
||||
}
|
||||
latch = {
|
||||
type = "exec",
|
||||
exec = ["pactl", "set-sink-mute", "0", "1"],
|
||||
}
|
||||
```
|
||||
|
||||
The `latch` action fires when the triggering key (`x` in this case) is
|
||||
released, regardless of any other keys pressed at that time.
|
||||
|
||||
## Marks
|
||||
|
||||
Marks let you tag a window and quickly jump back to it later, similar to marks
|
||||
in Vim.
|
||||
|
||||
### Interactive marks
|
||||
|
||||
The simplest way to use marks is interactively. Bind `create-mark` and
|
||||
`jump-to-mark` as simple string actions:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-m = "create-mark"
|
||||
alt-apostrophe = "jump-to-mark"
|
||||
```
|
||||
|
||||
When you press `alt-m`, Jay waits for the next key press (e.g. `a`) and
|
||||
assigns the mark to the currently focused window. When you press
|
||||
`alt-apostrophe` followed by `a`, Jay focuses the marked window.
|
||||
|
||||
### Hard-coded marks
|
||||
|
||||
You can skip the interactive step by specifying a mark ID directly:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-1 = { type = "create-mark", id.key = "1" }
|
||||
alt-1 = { type = "jump-to-mark", id.key = "1" }
|
||||
```
|
||||
|
||||
Mark IDs can be identified by a key name (`id.key`) or by an arbitrary string
|
||||
(`id.name`):
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-b = { type = "create-mark", id.name = "browser" }
|
||||
alt-b = { type = "jump-to-mark", id.name = "browser" }
|
||||
```
|
||||
|
||||
Key names use Linux input event code names with the `KEY_` prefix removed, all
|
||||
lowercase (see the [Linux input event codes](https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h)).
|
||||
|
||||
### Copying marks
|
||||
|
||||
The `copy-mark` action copies a mark from one ID to another:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-c = { type = "copy-mark", src.key = "a", dst.name = "backup" }
|
||||
```
|
||||
|
||||
## Named actions
|
||||
|
||||
Named actions provide another layer of reuse. Define them in the `[actions]`
|
||||
table and reference them with `$name`:
|
||||
|
||||
```toml
|
||||
[actions]
|
||||
my-layout = [
|
||||
"split-horizontal",
|
||||
{ type = "exec", exec = "alacritty" },
|
||||
]
|
||||
|
||||
[shortcuts]
|
||||
alt-l = "$my-layout"
|
||||
```
|
||||
|
||||
You can redefine named actions at runtime using the `define-action` and
|
||||
`undefine-action` parameterized actions:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-q = {
|
||||
type = "define-action",
|
||||
name = "my-layout",
|
||||
action = "quit",
|
||||
}
|
||||
```
|
||||
|
||||
## Virtual outputs
|
||||
|
||||
Virtual outputs can be created and removed via actions. A virtual output has
|
||||
the connector name `VO-{name}` and the serial number `{name}`. A newly created
|
||||
virtual output is initially disabled.
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-v = {
|
||||
type = "create-virtual-output",
|
||||
name = "screen-share",
|
||||
}
|
||||
alt-shift-x = {
|
||||
type = "remove-virtual-output",
|
||||
name = "screen-share",
|
||||
}
|
||||
```
|
||||
|
||||
You can pre-configure the virtual output using connector and output match
|
||||
rules:
|
||||
|
||||
```toml
|
||||
[[connectors]]
|
||||
match.name = "VO-screen-share"
|
||||
enabled = true
|
||||
|
||||
[[outputs]]
|
||||
match.connector = "VO-screen-share"
|
||||
mode = {
|
||||
width = 1920,
|
||||
height = 1080,
|
||||
refresh-rate = 120.0,
|
||||
}
|
||||
```
|
||||
|
||||
## Actions in window rules
|
||||
|
||||
When certain simple actions are used inside a [window rule](../window-rules.md),
|
||||
they apply to the **matched window** instead of the focused window. The
|
||||
affected actions are: `move-left`, `move-down`, `move-up`, `move-right`,
|
||||
`split-horizontal`, `split-vertical`, `toggle-split`, `tile-horizontal`,
|
||||
`tile-vertical`, `show-single`, `show-all`, `toggle-fullscreen`,
|
||||
`enter-fullscreen`, `exit-fullscreen`, `close`, `toggle-floating`, `float`,
|
||||
`tile`, `toggle-float-pinned`, `pin-float`, and `unpin-float`.
|
||||
|
||||
Similarly, `kill-client` applies to the matched window's client in a window
|
||||
rule, or to the matched client in a client rule.
|
||||
104
book/src/configuration/startup.md
Normal file
104
book/src/configuration/startup.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Startup Actions
|
||||
|
||||
Jay provides hooks that run actions at specific points during compositor
|
||||
startup and during idle transitions.
|
||||
|
||||
## on-graphics-initialized
|
||||
|
||||
This hook runs after the GPU has been initialized and the compositor is ready
|
||||
to display graphical content. It is the right place to start **graphical
|
||||
applications** such as notification daemons, system tray bridges, status bars,
|
||||
and similar programs.
|
||||
|
||||
```toml
|
||||
on-graphics-initialized = { type = "exec", exec = "mako" }
|
||||
```
|
||||
|
||||
To start multiple programs, use an array of actions:
|
||||
|
||||
```toml
|
||||
on-graphics-initialized = [
|
||||
{ type = "exec", exec = "mako" },
|
||||
{ type = "exec", exec = "wl-tray-bridge" },
|
||||
]
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The built-in default configuration starts [mako](https://github.com/emersion/mako)
|
||||
> (notification daemon) and [wl-tray-bridge](https://github.com/mahkoh/wl-tray-bridge)
|
||||
> (system tray bridge) in `on-graphics-initialized`. Once you create a config
|
||||
> file, these defaults are replaced -- include them in your config if you want
|
||||
> to keep them.
|
||||
|
||||
This hook runs when the config is first loaded after compositor startup. It
|
||||
does **not** re-run on config reload.
|
||||
|
||||
## on-startup
|
||||
|
||||
This hook runs as early as possible when the compositor starts -- **before**
|
||||
graphics are initialized. Do not start graphical applications here; they will
|
||||
likely fail to connect to the display.
|
||||
|
||||
Use `on-startup` for tasks like setting environment variables or other
|
||||
non-graphical initialization:
|
||||
|
||||
```toml
|
||||
on-startup = {
|
||||
type = "set-env",
|
||||
env = { XDG_CURRENT_DESKTOP = "jay" },
|
||||
}
|
||||
```
|
||||
|
||||
This hook has **no effect on config reload** -- it only runs once when the
|
||||
compositor first starts.
|
||||
|
||||
## on-idle
|
||||
|
||||
This hook runs when the compositor transitions to the idle state (i.e., after
|
||||
the configured idle timeout expires with no user input). The most common use
|
||||
case is starting a screen locker.
|
||||
|
||||
```toml
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Screen lockers need `privileged = true` to access the privileged Wayland
|
||||
> protocols required for locking the session.
|
||||
|
||||
You can combine idle with a grace period. The idle timeout and grace period are
|
||||
configured separately in the `[idle]` section (see [Idle & Screen
|
||||
Locking](idle.md)):
|
||||
|
||||
```toml
|
||||
idle = { minutes = 10 }
|
||||
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Like the other hooks, `on-idle` accepts arrays of actions:
|
||||
|
||||
```toml
|
||||
on-idle = [
|
||||
{ type = "exec", exec = ["notify-send", "Going idle..."] },
|
||||
{
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
97
book/src/configuration/status-bar.md
Normal file
97
book/src/configuration/status-bar.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# Status Bar
|
||||
|
||||
Jay includes a built-in bar that displays workspace tabs, status text, tray
|
||||
icons (via [wl-tray-bridge](https://github.com/mahkoh/wl-tray-bridge)), and a
|
||||
clock. The status text is provided by an external program that you configure
|
||||
in the `[status]` table.
|
||||
|
||||
## Configuring a Status Program
|
||||
|
||||
The `[status]` table has three fields:
|
||||
|
||||
`format`
|
||||
: Message format: `plain`, `pango`, or `i3bar`. Optional.
|
||||
|
||||
`exec`
|
||||
: How to start the program (string, array, or table). Required.
|
||||
|
||||
`i3bar-separator`
|
||||
: Separator between i3bar components (default `" | "`). Optional.
|
||||
|
||||
### Format
|
||||
|
||||
`plain`
|
||||
: Plain text output
|
||||
|
||||
`pango`
|
||||
: Output containing Pango markup
|
||||
|
||||
`i3bar`
|
||||
: JSON output in i3bar protocol format
|
||||
|
||||
### Exec
|
||||
|
||||
The `exec` field accepts the same forms used elsewhere in the configuration:
|
||||
|
||||
- **String** -- the program name: `exec = "i3status"`
|
||||
- **Array** -- program and arguments: `exec = ["i3status", "-c", "~/.config/i3status/config"]`
|
||||
- **Table** -- full control over program, arguments, and environment (see the
|
||||
spec for details)
|
||||
|
||||
## Example: i3status
|
||||
|
||||
[i3status](https://i3wm.org/i3status/) is a popular status line generator.
|
||||
|
||||
```toml
|
||||
[status]
|
||||
format = "i3bar"
|
||||
exec = "i3status"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> i3status defaults to plain-text output. You must explicitly configure it to
|
||||
> use i3bar format by adding `output_format = "i3bar"` to your
|
||||
> `~/.config/i3status/config`:
|
||||
>
|
||||
> ```
|
||||
> general {
|
||||
> output_format = "i3bar"
|
||||
> }
|
||||
> ```
|
||||
|
||||
## Example: Custom Script
|
||||
|
||||
A simple shell script that prints the date every second:
|
||||
|
||||
```toml
|
||||
[status]
|
||||
format = "plain"
|
||||
exec = { shell = "while true; do date '+%Y-%m-%d %H:%M:%S'; sleep 1; done" }
|
||||
```
|
||||
|
||||
## Changing the Status Program at Runtime
|
||||
|
||||
The `set-status` action lets you switch the status program from a shortcut.
|
||||
Omit the `status` field to reset the status text to empty.
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
# Switch to i3status
|
||||
alt-F10 = {
|
||||
type = "set-status",
|
||||
status = {
|
||||
format = "i3bar",
|
||||
exec = "i3status",
|
||||
},
|
||||
}
|
||||
|
||||
# Clear the status text
|
||||
alt-F11 = { type = "set-status" }
|
||||
```
|
||||
|
||||
## Bar Appearance
|
||||
|
||||
The bar's visual appearance (height, background color, text color, position, and
|
||||
font) is configured in the `[theme]` table. See the
|
||||
[Theme & Appearance](theme.md) chapter for details. The bar can be shown or
|
||||
hidden with the `show-bar` top-level setting or the `toggle-bar` action.
|
||||
205
book/src/configuration/theme.md
Normal file
205
book/src/configuration/theme.md
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
# Theme & Appearance
|
||||
|
||||
Jay's visual appearance -- colors, fonts, sizes, and layout -- is controlled by
|
||||
the `[theme]` table and a handful of top-level toggles. Every setting described
|
||||
here can also be adjusted at runtime from the control center's **Look and Feel**
|
||||
pane, which provides color pickers and live preview.
|
||||
|
||||
## Colors
|
||||
|
||||
Colors are specified as hex strings in one of four formats:
|
||||
|
||||
`#rgb` (e.g. `#f00`)
|
||||
: Short RGB
|
||||
|
||||
`#rrggbb` (e.g. `#ff0000`)
|
||||
: Full RGB
|
||||
|
||||
`#rgba` (e.g. `#f008`)
|
||||
: Short RGB + alpha
|
||||
|
||||
`#rrggbbaa` (e.g. `#ff000080`)
|
||||
: Full RGB + alpha
|
||||
|
||||
The available color keys in the `[theme]` table are:
|
||||
|
||||
`bg-color`
|
||||
: Desktop background
|
||||
|
||||
`bar-bg-color`
|
||||
: Bar background
|
||||
|
||||
`bar-status-text-color`
|
||||
: Status text in the bar
|
||||
|
||||
`border-color`
|
||||
: Borders between tiled windows
|
||||
|
||||
`focused-title-bg-color`
|
||||
: Background of the focused window's title
|
||||
|
||||
`focused-title-text-color`
|
||||
: Text color of the focused window's title
|
||||
|
||||
`unfocused-title-bg-color`
|
||||
: Background of unfocused window titles
|
||||
|
||||
`unfocused-title-text-color`
|
||||
: Text color of unfocused window titles
|
||||
|
||||
`focused-inactive-title-bg-color`
|
||||
: Background of focused-but-inactive titles
|
||||
|
||||
`focused-inactive-title-text-color`
|
||||
: Text color of focused-but-inactive titles
|
||||
|
||||
`attention-requested-bg-color`
|
||||
: Background of titles that have requested attention
|
||||
|
||||
`captured-focused-title-bg-color`
|
||||
: Background of focused titles that are being recorded
|
||||
|
||||
`captured-unfocused-title-bg-color`
|
||||
: Background of unfocused titles that are being recorded
|
||||
|
||||
`separator-color`
|
||||
: Separator between title bars and window content
|
||||
|
||||
`highlight-color`
|
||||
: Accent color used to highlight parts of the UI
|
||||
|
||||
"Focused-inactive" refers to a window that was most recently focused in its
|
||||
container but whose container is not the active one. The "captured" colors apply
|
||||
when a window is being recorded (e.g. via screen sharing).
|
||||
|
||||
### Example
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
bg-color = "#1e1e2e"
|
||||
bar-bg-color = "#181825"
|
||||
bar-status-text-color = "#cdd6f4"
|
||||
border-color = "#313244"
|
||||
focused-title-bg-color = "#89b4fa"
|
||||
focused-title-text-color = "#1e1e2e"
|
||||
unfocused-title-bg-color = "#313244"
|
||||
unfocused-title-text-color = "#cdd6f4"
|
||||
attention-requested-bg-color = "#f38ba8"
|
||||
highlight-color = "#f5c2e7"
|
||||
```
|
||||
|
||||
## Sizes
|
||||
|
||||
`border-width`
|
||||
: Width of borders between windows (px)
|
||||
|
||||
`title-height`
|
||||
: Height of window title tabs (px)
|
||||
|
||||
`bar-height`
|
||||
: Height of the bar (px). Defaults to the same as `title-height`.
|
||||
|
||||
`bar-separator-width`
|
||||
: Width of the bar's bottom separator (px). Default: `1`.
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
border-width = 2
|
||||
title-height = 24
|
||||
bar-height = 28
|
||||
```
|
||||
|
||||
## Fonts
|
||||
|
||||
`font`
|
||||
: General font for the compositor
|
||||
|
||||
`title-font`
|
||||
: Font used in window title bars. Defaults to the same as `font`.
|
||||
|
||||
`bar-font`
|
||||
: Font used in the status bar. Defaults to the same as `font`.
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
font = "JetBrains Mono 10"
|
||||
title-font = "Inter 10"
|
||||
bar-font = "Inter 10"
|
||||
```
|
||||
|
||||
## Bar Position
|
||||
|
||||
The `bar-position` field controls whether the bar appears at the top or bottom
|
||||
of each output. The default is `top`.
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
bar-position = "bottom"
|
||||
```
|
||||
|
||||
## Changing the Theme at Runtime
|
||||
|
||||
Use the `set-theme` action in a shortcut to change theme properties on the fly:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F9 = { type = "set-theme", theme.bg-color = "#000000" }
|
||||
```
|
||||
|
||||
Only the fields you include are changed; everything else stays the same.
|
||||
|
||||
## Showing and Hiding UI Elements
|
||||
|
||||
These top-level settings control whether the bar and title bars are visible:
|
||||
|
||||
`show-bar`
|
||||
: Show the built-in status bar. Default: `true`.
|
||||
|
||||
`show-titles`
|
||||
: Show window title bars. Default: `true`.
|
||||
|
||||
```toml
|
||||
show-bar = false
|
||||
show-titles = false
|
||||
```
|
||||
|
||||
Corresponding actions let you toggle these at runtime:
|
||||
|
||||
`show-bar`
|
||||
: Shows the bar
|
||||
|
||||
`hide-bar`
|
||||
: Hides the bar
|
||||
|
||||
`toggle-bar`
|
||||
: Toggles bar visibility
|
||||
|
||||
`show-titles`
|
||||
: Shows title bars
|
||||
|
||||
`hide-titles`
|
||||
: Hides title bars
|
||||
|
||||
`toggle-titles`
|
||||
: Toggles title bars
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-b = "toggle-bar"
|
||||
alt-t = "toggle-titles"
|
||||
```
|
||||
|
||||
## Workspace Display Order
|
||||
|
||||
The `workspace-display-order` top-level setting controls how workspace tabs
|
||||
appear in the bar:
|
||||
|
||||
`manual`
|
||||
: Workspaces can be reordered by dragging (default)
|
||||
|
||||
`sorted`
|
||||
: Workspaces are displayed in alphabetical order
|
||||
|
||||
```toml
|
||||
workspace-display-order = "sorted"
|
||||
```
|
||||
91
book/src/configuration/xwayland.md
Normal file
91
book/src/configuration/xwayland.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# Xwayland
|
||||
|
||||
Xwayland provides compatibility with legacy X11 applications inside a Wayland
|
||||
session. Jay starts Xwayland automatically by default.
|
||||
|
||||
## Configuration
|
||||
|
||||
The `[xwayland]` table controls Xwayland behavior:
|
||||
|
||||
`enabled`
|
||||
: Whether Xwayland is started. Default: `true`.
|
||||
|
||||
`scaling-mode`
|
||||
: How X11 windows are scaled on HiDPI outputs. Default: `default`.
|
||||
|
||||
```toml
|
||||
[xwayland]
|
||||
enabled = true
|
||||
scaling-mode = "default"
|
||||
```
|
||||
|
||||
### Scaling Modes
|
||||
|
||||
`default`
|
||||
: Render at the lowest scale, then upscale to other outputs
|
||||
|
||||
`downscaled`
|
||||
: Render at the highest integer scale, then downscale to match each output
|
||||
|
||||
The `downscaled` mode produces sharper text and UI on HiDPI monitors but has a
|
||||
significant performance cost. For example, on a 3840x2160 output at 1.5x scale,
|
||||
a fullscreen X11 window would be rendered at 5120x2880 (integer scale 2) and
|
||||
then downscaled -- roughly doubling the pixel count. This mode also requires
|
||||
X11 applications to handle scaling themselves (e.g. `GDK_SCALE=2`).
|
||||
|
||||
## CLI
|
||||
|
||||
You can inspect and change Xwayland settings from the command line:
|
||||
|
||||
```shell
|
||||
~$ jay xwayland status
|
||||
~$ jay xwayland set-scaling-mode default
|
||||
~$ jay xwayland set-scaling-mode downscaled
|
||||
```
|
||||
|
||||
Xwayland settings are also available in the control center's **Xwayland** pane.
|
||||
|
||||
## Disabling Xwayland
|
||||
|
||||
If you don't need X11 compatibility, disabling Xwayland avoids starting the
|
||||
X server entirely:
|
||||
|
||||
```toml
|
||||
[xwayland]
|
||||
enabled = false
|
||||
```
|
||||
|
||||
## Matching X11 Windows in Rules
|
||||
|
||||
Window rules can target X11 windows using properties that only exist on X
|
||||
clients. These fields are available in the `match` table of `[[windows]]`
|
||||
rules:
|
||||
|
||||
`x-class` / `x-class-regex`
|
||||
: Match the X11 WM_CLASS class (verbatim or regex)
|
||||
|
||||
`x-instance` / `x-instance-regex`
|
||||
: Match the X11 WM_CLASS instance (verbatim or regex)
|
||||
|
||||
`x-role` / `x-role-regex`
|
||||
: Match the X11 WM_WINDOW_ROLE (verbatim or regex)
|
||||
|
||||
For example, to float all GIMP tool windows:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.x-class = "Gimp"
|
||||
match.x-role-regex = "gimp-(toolbox|dock)"
|
||||
initial-tile-state = "floating"
|
||||
```
|
||||
|
||||
### Matching at the Client Level
|
||||
|
||||
Client rules support the `is-xwayland` field to match (or exclude) the
|
||||
Xwayland client itself:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.is-xwayland = true
|
||||
# ... grant capabilities, etc.
|
||||
```
|
||||
608
book/src/control-center.md
Normal file
608
book/src/control-center.md
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
# Control Center
|
||||
|
||||
The control center is Jay's built-in graphical interface for inspecting and
|
||||
modifying compositor settings. It provides a convenient alternative to editing
|
||||
configuration files or running CLI commands -- most settings that can be changed
|
||||
in `config.toml` or via the CLI can also be changed here.
|
||||
|
||||
> [!NOTE]
|
||||
> Changes made in the control center are not persisted across compositor
|
||||
> restarts. To make settings permanent, add them to your `config.toml`.
|
||||
|
||||
> [!TIP]
|
||||
> The control center consumes GPU and CPU resources while open. Close it when
|
||||
> not in use to avoid reducing compositor performance.
|
||||
|
||||
## Opening the Control Center
|
||||
|
||||
- Press `alt-c` (the default shortcut for the `open-control-center` action).
|
||||
- Run the CLI command:
|
||||
|
||||
```shell
|
||||
~$ jay control-center
|
||||
```
|
||||
|
||||
## Interface Overview
|
||||
|
||||
The control center window has a sidebar on the left listing all available panes
|
||||
and a central panel area on the right.
|
||||
|
||||
- **Click** a pane name in the sidebar to open it.
|
||||
- **Multiple panes** can be open at the same time -- they appear as tabs in the
|
||||
panel area.
|
||||
- **Drag** pane tabs to rearrange them or to split the panel area into
|
||||
side-by-side or stacked layouts.
|
||||
- **Close** a pane by clicking its X button or middle-clicking its tab.
|
||||
|
||||
## Panes
|
||||
|
||||
### Compositor
|
||||
|
||||
General information and top-level controls for the running compositor.
|
||||
|
||||
Repository
|
||||
: Link to the Jay GitHub repository
|
||||
|
||||
Version
|
||||
: The running Jay version
|
||||
|
||||
PID
|
||||
: The compositor process ID
|
||||
|
||||
WAYLAND_DISPLAY
|
||||
: The Wayland socket name (shown when available)
|
||||
|
||||
Config DIR
|
||||
: Path to the active configuration directory (shown when available)
|
||||
|
||||
Libei Socket
|
||||
: Toggle the libei input emulation socket
|
||||
|
||||
LIBEI_SOCKET
|
||||
: The socket name (shown when the Libei Socket toggle is enabled)
|
||||
|
||||
Workspace Display Order
|
||||
: Dropdown to select how workspaces are ordered in the bar
|
||||
|
||||
Log Level
|
||||
: Dropdown to change the active log level at runtime (shown when the logger is available)
|
||||
|
||||
Log File
|
||||
: Click to copy the log file path to the clipboard (shown when the logger is available)
|
||||
|
||||
Buttons at the bottom:
|
||||
|
||||
- **Quit** -- stop the compositor.
|
||||
- **Reload Config** -- reload the configuration file.
|
||||
- **Switch to VT** -- switch to another virtual terminal (with a numeric input
|
||||
to select which one).
|
||||
|
||||
### Outputs
|
||||
|
||||
The Outputs pane is the largest and most interactive pane. It has two sub-views:
|
||||
a visual **arrangement editor** and per-connector **settings**.
|
||||
|
||||
#### Arrangement editor
|
||||
|
||||
A 2D preview of your monitor layout. Monitors are drawn as labeled rectangles
|
||||
at their configured positions and sizes.
|
||||
|
||||
- **Click** a monitor to select it (highlighted with a shadow).
|
||||
- **Drag** a selected monitor to reposition it.
|
||||
- **Scroll** to zoom in and out.
|
||||
- **Middle-click drag** or **right-click drag** to pan the viewport.
|
||||
- **Arrow keys** nudge the selected monitor by 1 pixel.
|
||||
- **Snap to neighbor** -- when enabled, dragged monitors snap to the edges of
|
||||
neighboring monitors within a 10-pixel threshold. Hold **Shift** to
|
||||
temporarily invert the snapping behavior.
|
||||
- **Guide lines** -- optional horizontal and vertical lines at the edges of all
|
||||
monitors, helping you align them precisely.
|
||||
|
||||
A **Zoom To Fit** checkbox in the top bar auto-scales the view to fit all
|
||||
monitors. It is disabled when you manually pan or zoom.
|
||||
|
||||
Arrangement settings (accessible via the Settings button):
|
||||
|
||||
Show guide lines
|
||||
: Draw alignment guide lines
|
||||
|
||||
Snap to neighbor
|
||||
: Snap edges when dragging (hold Shift to invert)
|
||||
|
||||
Show arrangement area
|
||||
: Toggle the visual arrangement sub-pane
|
||||
|
||||
Layout
|
||||
: How the arrangement and settings are split: Auto, Vertical, or Horizontal
|
||||
|
||||
Show disconnected heads
|
||||
: Include outputs that are no longer connected
|
||||
|
||||
Show disabled heads
|
||||
: Include outputs that are disabled
|
||||
|
||||
#### Staged changes
|
||||
|
||||
Changes made in the Outputs pane are **staged** -- they are not applied
|
||||
immediately. Three buttons in the top bar control the workflow:
|
||||
|
||||
- **Test** -- validates the staged changes against the display backend without
|
||||
applying them. Errors are shown in the pane.
|
||||
- **Commit** -- applies all staged changes. The pane title shows `Outputs (*)`
|
||||
when there are uncommitted changes.
|
||||
- **Reset** -- discards all staged changes and reverts to the live state.
|
||||
This is displayed as a checkbox; checking it resets the staged changes.
|
||||
|
||||
When a staged value differs from the live value, the current (live) value is
|
||||
shown alongside with a `^ current` annotation.
|
||||
|
||||
#### Per-connector settings
|
||||
|
||||
Each connected display appears as a collapsible section with the connector name,
|
||||
manufacturer, and model. Inside:
|
||||
|
||||
Serial Number
|
||||
: Read-only identifier
|
||||
|
||||
Enabled
|
||||
: Toggle the connector on or off
|
||||
|
||||
Position
|
||||
: X and Y coordinates in compositor space
|
||||
|
||||
Scale
|
||||
: Fractional scaling factor, with +/- buttons for fine adjustment
|
||||
|
||||
Mode
|
||||
: Resolution and refresh rate (dropdown when multiple modes are available)
|
||||
|
||||
Physical Size (mm)
|
||||
: Read-only physical dimensions in millimeters
|
||||
|
||||
Size
|
||||
: Read-only computed pixel dimensions of the output
|
||||
|
||||
Transform
|
||||
: Rotation and mirroring (none, rotate-90, rotate-180, rotate-270, flip, and flipped rotations)
|
||||
|
||||
Custom Brightness
|
||||
: Toggle whether to use a custom SDR content brightness
|
||||
|
||||
Brightness
|
||||
: Brightness value in cd/m^2 (shown when Custom Brightness is enabled)
|
||||
|
||||
Colorimetry
|
||||
: Color space (depends on monitor capabilities)
|
||||
|
||||
EOTF
|
||||
: Transfer function (depends on monitor capabilities)
|
||||
|
||||
Format
|
||||
: Framebuffer pixel format
|
||||
|
||||
Tearing
|
||||
: Tearing mode. When set to a "Fullscreen" mode, a **Limit Windows** checkbox appears; inside that, a **Requests Tearing** checkbox filters by whether the window has requested tearing.
|
||||
|
||||
VRR Active
|
||||
: Read-only indicator of whether VRR is currently active (only shown when the monitor supports VRR)
|
||||
|
||||
VRR
|
||||
: Variable refresh rate mode (only shown when the monitor supports VRR). When set to a "Fullscreen" mode, a **Limit Windows** checkbox appears; inside that, a **Limit Content Types** checkbox enables filtering by content type (**Photos**, **Videos**, **Games** checkboxes).
|
||||
|
||||
Non-desktop
|
||||
: Read-only indicator (Yes/No) of whether the connector is inherently non-desktop
|
||||
|
||||
Override
|
||||
: Force the connector to be treated as desktop or non-desktop
|
||||
|
||||
Blend Space
|
||||
: How colors are blended during compositing (sRGB or linear)
|
||||
|
||||
Use Native Gamut
|
||||
: Use the display's advertised color primaries instead of assuming sRGB
|
||||
|
||||
Native Gamut
|
||||
: Read-only CIE xy primaries for red, green, blue, and white point
|
||||
|
||||
Limit Cursor HZ
|
||||
: Toggle to limit cursor-triggered refresh rate when VRR is active
|
||||
|
||||
Cursor HZ
|
||||
: Cursor refresh rate value (shown when Limit Cursor HZ is enabled)
|
||||
|
||||
Flip Margin (ms)
|
||||
: Read-only page-flip margin for this connector
|
||||
|
||||
### Virtual Outputs
|
||||
|
||||
Manage headless virtual outputs. These are useful for screen sharing, testing,
|
||||
or running applications on a display without a physical monitor.
|
||||
|
||||
- View the list of existing virtual outputs.
|
||||
- **Add** a new virtual output by entering a name and clicking Add.
|
||||
- **Remove** an existing virtual output by clicking its X button.
|
||||
|
||||
### GPUs
|
||||
|
||||
Inspect and configure graphics cards (DRM devices). Each GPU appears as a
|
||||
collapsible section showing its device path and model name.
|
||||
|
||||
Vendor
|
||||
: Read-only GPU vendor name
|
||||
|
||||
Model
|
||||
: Read-only GPU model name
|
||||
|
||||
Devnode
|
||||
: Read-only device path
|
||||
|
||||
Syspath
|
||||
: Read-only sysfs path
|
||||
|
||||
PCI ID
|
||||
: Read-only vendor:model in hex
|
||||
|
||||
Dev
|
||||
: Read-only major:minor device numbers
|
||||
|
||||
API
|
||||
: Dropdown to select the graphics API -- Vulkan (recommended) or the legacy OpenGL renderer
|
||||
|
||||
Primary Device
|
||||
: Checkbox to make this GPU the render device
|
||||
|
||||
Direct Scanout
|
||||
: Toggle direct scanout (bypasses composition for lower latency)
|
||||
|
||||
Flip Margin
|
||||
: Adjust the page-flip margin in milliseconds, with +/- buttons for 0.1 ms steps
|
||||
|
||||
Connectors
|
||||
: List of display connectors attached to this GPU
|
||||
|
||||
### Input
|
||||
|
||||
The Input pane is divided into per-seat and per-device sections.
|
||||
|
||||
#### Per-seat settings
|
||||
|
||||
Each seat (typically just `default`) appears as a collapsible section:
|
||||
|
||||
Repeat Rate
|
||||
: Key repeat speed, with +/- 20 buttons
|
||||
|
||||
Repeat Delay
|
||||
: Initial delay before key repeat begins, with +/- 20 buttons
|
||||
|
||||
Cursor Size
|
||||
: Size of the seat cursor in pixels
|
||||
|
||||
Simple IM
|
||||
: Toggle the built-in XCompose-based input method
|
||||
|
||||
Hardware Cursor
|
||||
: Toggle hardware cursor rendering
|
||||
|
||||
Pointer Revert Key
|
||||
: Text field for the keysym name of the cancel key
|
||||
|
||||
Focus Follows Mouse
|
||||
: Toggle whether moving the pointer over a window gives it focus
|
||||
|
||||
Fallback Output Mode
|
||||
: Dropdown to choose between cursor-based and focus-based output selection
|
||||
|
||||
Below the settings grid:
|
||||
|
||||
- **Focus History** -- checkboxes for "Only Visible" and "Same Workspace".
|
||||
- **Reload Simple IM** -- button to reload XCompose files without restarting.
|
||||
|
||||
##### Keymap management
|
||||
|
||||
Each seat has a full keymap management section:
|
||||
|
||||
- **Copy Keymap** -- copies the current keymap text to the clipboard.
|
||||
- **Load Default Keymap** -- restores the compositor's default keymap.
|
||||
- **Backup / Restore Keymap** -- save and restore a keymap backup.
|
||||
- **Load Keymap from Clipboard** -- paste a keymap from the clipboard.
|
||||
- **Create Keymap from Names** -- build a keymap from RMLVO (Rules, Model,
|
||||
Layout, Variant, Options) fields. Rules and Model have a text input and a
|
||||
"Default" checkbox; Layouts, Variants, and Options have text inputs only.
|
||||
Click **Load** to apply.
|
||||
|
||||
#### Per-device settings
|
||||
|
||||
Each input device appears as a collapsible section. The available settings
|
||||
depend on the device's capabilities:
|
||||
|
||||
Seat
|
||||
: Dropdown to assign the device to a seat, with a Detach button. Shown for all devices.
|
||||
|
||||
Syspath / Devnode
|
||||
: Read-only device paths. Shown for all devices.
|
||||
|
||||
Capabilities
|
||||
: Read-only list (e.g. Keyboard, Pointer, Touch). Shown for all devices.
|
||||
|
||||
Natural Scrolling
|
||||
: Toggle scroll direction. Shown for devices that support it.
|
||||
|
||||
Scroll Distance (px)
|
||||
: Pixels per legacy scroll event. Shown for pointer devices.
|
||||
|
||||
Accel Profile
|
||||
: Dropdown: Flat or Adaptive. Shown for devices with acceleration.
|
||||
|
||||
Accel Speed
|
||||
: Numeric input (0.0 to 1.0). Shown for devices with acceleration.
|
||||
|
||||
Click Method
|
||||
: Dropdown: none, button-areas, clickfinger. Shown for devices that support it.
|
||||
|
||||
Tap Enabled
|
||||
: Toggle tap-to-click. Shown for touchpads.
|
||||
|
||||
Tap Drag Enabled
|
||||
: Toggle tap-and-drag. Shown for touchpads.
|
||||
|
||||
Tap Drag Lock Enabled
|
||||
: Toggle tap-drag lock. Shown for touchpads.
|
||||
|
||||
Left Handed
|
||||
: Swap primary and secondary buttons. Shown for devices that support it.
|
||||
|
||||
Middle Button Emulation
|
||||
: Simultaneous left+right produces middle click. Shown for devices that support it.
|
||||
|
||||
Output
|
||||
: Dropdown to map the device to a specific output (only has effect for touch and tablet devices), with a Detach button. Shown for all devices.
|
||||
|
||||
Transform Matrix
|
||||
: 2x2 matrix applied to relative motion. Shown for pointer devices.
|
||||
|
||||
Calibration Matrix
|
||||
: 2x3 matrix for absolute input calibration. Shown for devices that support it.
|
||||
|
||||
Device Keymap
|
||||
: Override the seat keymap for this device, with full keymap management UI and a "Use Seat Keymap" button to revert. Shown for keyboards.
|
||||
|
||||
### Idle
|
||||
|
||||
Configure the screensaver and idle behavior:
|
||||
|
||||
Interval
|
||||
: Minutes and seconds of inactivity before the on-idle action fires
|
||||
|
||||
Grace period
|
||||
: Minutes and seconds of the warning phase (screen goes black but is not yet locked)
|
||||
|
||||
Inhibitors
|
||||
: Collapsible list showing which applications are currently preventing idle (e.g. video players), with a count in the header
|
||||
|
||||
### Look and Feel
|
||||
|
||||
Visual customization with live preview. Changes take effect immediately.
|
||||
|
||||
Show Bar
|
||||
: Toggle the status bar
|
||||
|
||||
Bar Position
|
||||
: Dropdown to select the bar position
|
||||
|
||||
Show Titles
|
||||
: Toggle window title bars
|
||||
|
||||
Primary Selection
|
||||
: Toggle middle-click paste (requires application restart to take effect)
|
||||
|
||||
UI Drag
|
||||
: Toggle whether workspaces and tiles can be dragged
|
||||
|
||||
UI Drag Threshold (px)
|
||||
: Minimum distance in pixels before a drag begins
|
||||
|
||||
Float Pin Icon
|
||||
: Show the pin icon on floating windows even when not pinned
|
||||
|
||||
Float Above Fullscreen
|
||||
: Show floating windows above fullscreen windows
|
||||
|
||||
Font
|
||||
: Text field for the main compositor font family
|
||||
|
||||
Title Font
|
||||
: Override font for window title bars (empty = use main font)
|
||||
|
||||
Bar Font
|
||||
: Override font for the status bar (empty = use main font)
|
||||
|
||||
Three reset buttons at the bottom: **Reset Sizes**, **Reset Colors**, and
|
||||
**Reset Fonts**.
|
||||
|
||||
#### Sizes
|
||||
|
||||
A collapsible section with numeric inputs for every theme size: border widths,
|
||||
title heights, bar height, gaps, and other spacing values.
|
||||
|
||||
#### Colors
|
||||
|
||||
A collapsible section with **color pickers** for every theme color. Click a
|
||||
color swatch to open a full RGBA color picker with sliders and hex input.
|
||||
This includes colors for backgrounds, borders, text, the status bar, focused
|
||||
and unfocused windows, attention indicators, and more.
|
||||
|
||||
### Clients
|
||||
|
||||
Inspect and manage connected Wayland clients.
|
||||
|
||||
A **Filter** toggle at the top enables the composable filter builder (see
|
||||
[Filtering](#filtering) below). When filtering is off, all clients are shown.
|
||||
|
||||
Each client appears as a collapsible section showing its ID and process name.
|
||||
Expand it to see:
|
||||
|
||||
ID
|
||||
: Client identifier
|
||||
|
||||
PID
|
||||
: Process ID
|
||||
|
||||
UID
|
||||
: User ID
|
||||
|
||||
comm
|
||||
: Process name
|
||||
|
||||
exe
|
||||
: Executable path
|
||||
|
||||
Sandboxed
|
||||
: Whether the client is sandboxed (only shown for sandboxed clients)
|
||||
|
||||
Secure
|
||||
: Whether the client uses the privileged socket (only shown for secure clients)
|
||||
|
||||
Xwayland
|
||||
: Shown only for X11 clients
|
||||
|
||||
Sandbox Engine
|
||||
: Sandbox engine name (shown when sandboxed)
|
||||
|
||||
App ID
|
||||
: Sandbox application ID (shown when sandboxed)
|
||||
|
||||
Instance ID
|
||||
: Sandbox instance ID (shown when sandboxed)
|
||||
|
||||
Tag
|
||||
: The connection tag, if any
|
||||
|
||||
Kill
|
||||
: Button to forcefully disconnect the client
|
||||
|
||||
Capabilities
|
||||
: Collapsible list of effective Wayland capabilities
|
||||
|
||||
Windows
|
||||
: Collapsible list of all windows owned by this client
|
||||
|
||||
Click the **open in new pane** icon on any client to open a dedicated pane for
|
||||
that client, allowing you to keep it visible while browsing other panes.
|
||||
|
||||
### Window Search
|
||||
|
||||
Search and filter windows across the compositor using the composable filter
|
||||
builder (see [Filtering](#filtering) below).
|
||||
|
||||
Each matching window appears as a collapsible section showing its title. Expand
|
||||
it to see:
|
||||
|
||||
ID
|
||||
: Window identifier
|
||||
|
||||
Title
|
||||
: Window title
|
||||
|
||||
Workspace
|
||||
: Which workspace the window is on
|
||||
|
||||
Type
|
||||
: Container, xdg_toplevel, X Window, or Placeholder
|
||||
|
||||
Tag
|
||||
: Toplevel tag (set via window rules); only shown for xdg_toplevel windows
|
||||
|
||||
X11 properties
|
||||
: Class, Instance, and Role (only shown for Xwayland windows)
|
||||
|
||||
App ID
|
||||
: Application identifier
|
||||
|
||||
Floating
|
||||
: Whether the window is floating
|
||||
|
||||
Visible
|
||||
: Whether the window is visible
|
||||
|
||||
Urgent
|
||||
: Whether the window has the urgency flag
|
||||
|
||||
Fullscreen
|
||||
: Whether the window is fullscreen
|
||||
|
||||
Content Type
|
||||
: The content type hint (photo, video, game), if set
|
||||
|
||||
Client
|
||||
: Full client details (same as the Clients pane)
|
||||
|
||||
Click the **open in new pane** icon on any window to open a dedicated pane for
|
||||
that window.
|
||||
|
||||
### Xwayland
|
||||
|
||||
Manage the Xwayland compatibility layer for running X11 applications:
|
||||
|
||||
Enabled
|
||||
: Toggle Xwayland on or off
|
||||
|
||||
Scaling Mode
|
||||
: Dropdown: `default` or `downscaled` (renders at highest integer scale then downscales for sharper text on HiDPI)
|
||||
|
||||
DISPLAY
|
||||
: Read-only X11 display number (only shown when Xwayland is running)
|
||||
|
||||
Running
|
||||
: Whether Xwayland is currently running
|
||||
|
||||
PID
|
||||
: Xwayland process ID (only shown when Xwayland is running)
|
||||
|
||||
Kill
|
||||
: Button to forcefully terminate Xwayland (only shown when Xwayland is running)
|
||||
|
||||
Client
|
||||
: Collapsible section with full client details for the Xwayland process (only shown when Xwayland is running)
|
||||
|
||||
### Color Management
|
||||
|
||||
Configure the Wayland color management protocol:
|
||||
|
||||
Enabled
|
||||
: Toggle the color management protocol for clients
|
||||
|
||||
Available
|
||||
: Read-only indicator of whether color management is available with the current renderer and hardware
|
||||
|
||||
## Filtering
|
||||
|
||||
The **Clients** and **Window Search** panes share a composable filter system
|
||||
for narrowing down results. The filter builder works as follows:
|
||||
|
||||
At the top level, select a combinator or a leaf criterion from the dropdown:
|
||||
|
||||
- **Not** -- inverts a single child criterion.
|
||||
- **All** -- all child criteria must match (AND).
|
||||
- **Any** -- at least one child criterion must match (OR).
|
||||
- **Exactly(n)** -- exactly *n* child criteria must match (with a numeric input
|
||||
for *n*).
|
||||
|
||||
Compound criteria contain a list of children. Click **Add** to append a new
|
||||
criterion; click the X button on any child to remove it. Criteria can be nested
|
||||
to arbitrary depth.
|
||||
|
||||
Leaf criteria vary by context:
|
||||
|
||||
**Client criteria:** Comm, Exe, Tag, Sandbox Engine, Sandbox App ID, Sandbox
|
||||
Instance ID (all regex-matched text fields with a "Regex" checkbox), Sandboxed,
|
||||
Is Xwayland (boolean), UID, PID (numeric inputs).
|
||||
|
||||
**Window criteria:** Title, App ID, Tag, Workspace, X Class, X Instance, X Role
|
||||
(all regex-matched text fields), Floating, Visible, Urgent, Fullscreen
|
||||
(boolean), Content Types (checkboxes for Photo, Video, Game), and **Client**
|
||||
(a nested client criterion builder for filtering by the owning client's
|
||||
properties).
|
||||
|
||||
Text-matching criteria have a **Regex** checkbox. When unchecked, the input is
|
||||
matched as a literal string. When checked, it is treated as a regular
|
||||
expression. Invalid regex patterns show an error message.
|
||||
290
book/src/features.md
Normal file
290
book/src/features.md
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
# Features
|
||||
|
||||
This chapter provides a high-level overview of what Jay can do. Each feature
|
||||
links to the chapter where it is covered in detail.
|
||||
|
||||
## Configuration
|
||||
|
||||
Jay can be configured via:
|
||||
|
||||
- a **declarative TOML file**, or
|
||||
- a **shared library** that gets injected into the compositor for programmatic
|
||||
control.
|
||||
|
||||
Most users will use the TOML file. The configuration supports composable
|
||||
actions, [input modes](input-modes.md) for vim-style modal keybindings, and
|
||||
powerful [match rules](window-rules.md). See
|
||||
[Configuration Overview](configuration/index.md) for details on getting started
|
||||
and how the config file works.
|
||||
|
||||
## i3 Look and Feel
|
||||
|
||||
Jay provides an i3-inspired tiling layout with manual tiling,
|
||||
horizontal/vertical splits, fullscreen, and floating windows. Its appearance is
|
||||
based on the default i3 look and feel.
|
||||
|
||||
Colors, sizes, and fonts can all be customized. See
|
||||
[Theme & Appearance](configuration/theme.md) for details, and
|
||||
[Tiling](tiling.md) and [Floating Windows](floating.md) for how window
|
||||
management works.
|
||||
|
||||
## Stability
|
||||
|
||||
Jay has been stable for a long time. Crashes and incorrect behavior in released
|
||||
versions are 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.
|
||||
|
||||
## Command-Line Interface
|
||||
|
||||
Jay has a comprehensive CLI that can be used to inspect and 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
|
||||
```
|
||||
|
||||
See the full [Command-Line Interface](cli.md) reference for details.
|
||||
|
||||
## Control Center
|
||||
|
||||
Jay includes a built-in GUI control center (opened with `alt-c`) for managing
|
||||
outputs, input devices, GPUs, idle settings, color management, and more --
|
||||
without editing the config file. See [Control Center](control-center.md).
|
||||
|
||||
## Multi-Monitor Support
|
||||
|
||||
Jay can be used with multiple monitors with hot-plug and hot-unplug support.
|
||||
When a monitor is unplugged, all of its workspaces are automatically moved to
|
||||
one of the remaining monitors. When the monitor is plugged in again, these
|
||||
workspaces are restored.
|
||||
|
||||
See [Outputs (Monitors)](configuration/outputs.md) for configuration options.
|
||||
|
||||
## 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.
|
||||
|
||||
See [GPUs](configuration/gpu.md) for details.
|
||||
|
||||
## Screen Sharing
|
||||
|
||||
Jay supports screen sharing via xdg-desktop-portal. Three capture modes are
|
||||
available:
|
||||
|
||||
- **Window capture** -- share a single window.
|
||||
- **Output capture** -- share an entire monitor.
|
||||
- **Workspace capture** -- like output capture, but only one workspace is shown.
|
||||
|
||||
See [Screen Sharing](screen-sharing.md) for setup instructions.
|
||||
|
||||
## Screen Locking
|
||||
|
||||
Jay can automatically lock your screen and disable outputs after inactivity.
|
||||
See [Idle & Screen Locking](configuration/idle.md) for configuration options.
|
||||
|
||||
## Notifications
|
||||
|
||||
Jay supports the `zwlr_layer_shell_v1` protocol used by notification daemons
|
||||
such as [mako](https://github.com/emersion/mako), which is launched
|
||||
automatically by the default configuration.
|
||||
|
||||
## Fractional Scaling
|
||||
|
||||
Jay supports per-monitor fractional scaling. Scale factors can be set per
|
||||
output in the config file or at runtime via the control center and CLI.
|
||||
|
||||
See [Outputs (Monitors)](configuration/outputs.md) for details.
|
||||
|
||||
## 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 rendering API at runtime without restarting the compositor.
|
||||
|
||||
See [GPUs](configuration/gpu.md) for details.
|
||||
|
||||
## Explicit Sync
|
||||
|
||||
Jay supports explicit sync for compatibility with Nvidia hardware. This
|
||||
requires Linux 6.7 or later.
|
||||
|
||||
## Xwayland
|
||||
|
||||
Jay supports running X11 applications seamlessly through Xwayland. See
|
||||
[Xwayland](configuration/xwayland.md) for configuration options.
|
||||
|
||||
## Clipboard Managers
|
||||
|
||||
Jay supports clipboard managers via the `zwlr_data_control_manager_v1` and
|
||||
`ext_data_control_manager_v1` protocols.
|
||||
|
||||
## Privilege Separation
|
||||
|
||||
Jay splits protocols into unprivileged and privileged protocols. By default,
|
||||
applications only have access to unprivileged protocols. This means that tools
|
||||
like screen lockers, status bars, and clipboard managers need to be explicitly
|
||||
granted access.
|
||||
|
||||
Jay provides several ways to grant privileges, from giving a program full
|
||||
access to all privileged protocols down to granting individual capabilities to
|
||||
specific tagged processes. See
|
||||
[Granting Privileges](window-rules.md#granting-privileges) for a detailed
|
||||
guide and the [Protocol Support](#protocol-support) section below for the full
|
||||
list of protocols and their privilege requirements.
|
||||
|
||||
## Push to Talk
|
||||
|
||||
Jay's shortcut system allows you to execute an action when a key is pressed and
|
||||
a different action when the key is released, enabling push-to-talk
|
||||
functionality. See [Shortcuts](configuration/shortcuts.md) for details.
|
||||
|
||||
## VR
|
||||
|
||||
Jay supports leasing VR headsets to applications via the
|
||||
`wp_drm_lease_device_v1` protocol.
|
||||
|
||||
## Adaptive Sync
|
||||
|
||||
Jay supports adaptive sync (VRR) with configurable cursor refresh rates.
|
||||
See [Outputs (Monitors)](configuration/outputs.md) for per-output VRR settings.
|
||||
|
||||
## Tearing
|
||||
|
||||
Jay supports tearing presentation for games. See
|
||||
[Outputs (Monitors)](configuration/outputs.md) for per-output tearing settings.
|
||||
|
||||
## Low Input Latency
|
||||
|
||||
Jay uses frame scheduling to achieve input latency as low as 1.5 ms.
|
||||
|
||||
## Color Management & HDR
|
||||
|
||||
Jay supports the Wayland color management protocol and HDR10 output with
|
||||
per-monitor color space, transfer function, brightness, and blend space
|
||||
controls. See [HDR & Color Management](hdr.md) for a full walkthrough.
|
||||
|
||||
## Night Light
|
||||
|
||||
Jay supports night-light applications via the
|
||||
`zwlr_gamma_control_manager_v1` protocol.
|
||||
|
||||
## Window and Client Rules
|
||||
|
||||
Jay supports powerful, reactive window and client rules. Rules are
|
||||
re-evaluated whenever matching criteria change (e.g. a window's title changes).
|
||||
|
||||
See [Window & Client Rules](window-rules.md) for details.
|
||||
|
||||
## Protocol Support
|
||||
|
||||
Jay supports a large number of Wayland protocols. Protocols marked as
|
||||
**Privileged** are only accessible to applications that have been explicitly
|
||||
granted access. See
|
||||
[Granting Privileges](window-rules.md#granting-privileges) for how to do this.
|
||||
|
||||
| Protocol | 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[^2] | Yes |
|
||||
| ext_output_image_capture_source_manager_v1 | 1 | |
|
||||
| ext_session_lock_manager_v1 | 1 | Yes |
|
||||
| ext_transient_seat_manager_v1 | 1[^3] | 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[^1] |
|
||||
| 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 | |
|
||||
|
||||
[^1]: Sandboxes can restrict access to this protocol.
|
||||
[^2]: Cursors are always composited.
|
||||
[^3]: Seat creation is always rejected.
|
||||
139
book/src/floating.md
Normal file
139
book/src/floating.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# Floating Windows
|
||||
|
||||
Floating windows are not part of the tiling layout. They hover above tiled
|
||||
windows and can be freely moved and resized. Any tiled window can be made
|
||||
floating, and any floating window can be returned to the tiling layout.
|
||||
|
||||
## Toggling Between Tiled and Floating
|
||||
|
||||
`alt-shift-f` -- `toggle-floating`
|
||||
: Toggle the focused window between tiled and floating
|
||||
|
||||
You can also double-click a window's title bar to toggle between the two states.
|
||||
|
||||
For explicit control without toggling:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-t = "tile" # Make the focused window tiled
|
||||
alt-shift-g = "float" # Make the focused window floating
|
||||
```
|
||||
|
||||
## Moving Floating Windows
|
||||
|
||||
Drag a floating window's title bar to move it. The window follows the cursor
|
||||
until you release the mouse button.
|
||||
|
||||
In [window management mode](#window-management-mode), you can left-drag
|
||||
anywhere on a floating window to move it -- you do not need to target the
|
||||
title bar.
|
||||
|
||||
## Resizing Floating Windows
|
||||
|
||||
Drag a floating window's border to resize it. The cursor changes to a resize
|
||||
indicator when hovering over the border.
|
||||
|
||||
In [window management mode](#window-management-mode), you can right-drag
|
||||
anywhere on a floating window to resize it.
|
||||
|
||||
## Pinning
|
||||
|
||||
A pinned floating window stays visible across workspace switches. This is
|
||||
useful for things like a sticky terminal, a video player, or a chat window that
|
||||
you want on screen at all times.
|
||||
|
||||
`pin-float`
|
||||
: Pin the focused floating window
|
||||
|
||||
`unpin-float`
|
||||
: Unpin the focused floating window
|
||||
|
||||
`toggle-float-pinned`
|
||||
: Toggle pinning on the focused floating window
|
||||
|
||||
Example shortcut configuration:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-p = "toggle-float-pinned"
|
||||
```
|
||||
|
||||
You can also right-click a floating window's title bar to pin or unpin it.
|
||||
|
||||
### Pin Icon
|
||||
|
||||
By default, the pin icon is hidden. Enable it to get a clickable pin indicator
|
||||
on floating windows:
|
||||
|
||||
```toml
|
||||
[float]
|
||||
show-pin-icon = true
|
||||
```
|
||||
|
||||
When the pin icon is visible, click it to pin or unpin the window.
|
||||
|
||||
## Float Above Fullscreen
|
||||
|
||||
By default, floating windows are hidden below fullscreen windows. You can
|
||||
change this so floating windows render above fullscreen windows:
|
||||
|
||||
`enable-float-above-fullscreen`
|
||||
: Floating windows render above fullscreen windows
|
||||
|
||||
`disable-float-above-fullscreen`
|
||||
: Floating windows are hidden below fullscreen windows
|
||||
|
||||
`toggle-float-above-fullscreen`
|
||||
: Toggle the behavior
|
||||
|
||||
Example:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-a = "toggle-float-above-fullscreen"
|
||||
```
|
||||
|
||||
This is a global setting -- it affects all floating windows, not just the
|
||||
focused one.
|
||||
|
||||
## Window Rules: Initial Tile State
|
||||
|
||||
You can force specific windows to start as floating (or tiled) using the
|
||||
`initial-tile-state` field in a [window rule](window-rules.md):
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.app-id = "pavucontrol"
|
||||
initial-tile-state = "floating"
|
||||
|
||||
[[windows]]
|
||||
match.app-id = "mpv"
|
||||
initial-tile-state = "floating"
|
||||
```
|
||||
|
||||
Valid values are `"floating"` and `"tiled"`.
|
||||
|
||||
## Window Management Mode
|
||||
|
||||
Window management mode makes it easier to move and resize windows without
|
||||
needing to target specific UI elements like title bars or borders. Set the
|
||||
`window-management-key` to a keysym -- holding that key activates the mode:
|
||||
|
||||
```toml
|
||||
window-management-key = "Alt_L"
|
||||
```
|
||||
|
||||
While the key is held:
|
||||
|
||||
- **Left-drag** anywhere on a floating window to move it.
|
||||
- **Right-drag** anywhere on a floating window to resize it.
|
||||
|
||||
This mode also works with tiled windows and popups. See
|
||||
[Mouse Interactions](mouse.md#window-management-mode) for the full list of
|
||||
interactions available in this mode.
|
||||
|
||||
> [!NOTE]
|
||||
> Entering window management mode disables all pointer constraints. This can be
|
||||
> used to break out of games or other applications that grab the pointer, but
|
||||
> it also means pointer-dependent applications will behave differently while
|
||||
> the key is held.
|
||||
315
book/src/hdr.md
Normal file
315
book/src/hdr.md
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
# HDR & Color Management
|
||||
|
||||
Jay supports HDR (High Dynamic Range) output and the Wayland color management
|
||||
protocol. This chapter explains how HDR works in Jay and walks through
|
||||
enabling it.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
HDR in Jay requires:
|
||||
|
||||
- The **Vulkan renderer**. The OpenGL renderer does not support color
|
||||
management or HDR. Vulkan is the default when available; you can verify
|
||||
with `jay randr show` (look for the "Api" field under your GPU) or switch
|
||||
to it in the [control center](control-center.md) GPUs pane.
|
||||
- A **monitor that supports HDR**. The display must advertise PQ (Perceptual
|
||||
Quantizer) support and BT.2020 colorimetry through its EDID. Run
|
||||
`jay randr show` to see which color spaces and EOTFs your display supports.
|
||||
|
||||
## Quick start
|
||||
|
||||
Enable HDR10 on a specific output using the CLI:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 colors set bt2020 pq
|
||||
```
|
||||
|
||||
Or in your configuration file:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
color-space = "bt2020"
|
||||
transfer-function = "pq"
|
||||
```
|
||||
|
||||
Enable the color management protocol so that applications can communicate
|
||||
their color spaces to the compositor:
|
||||
|
||||
```shell
|
||||
~$ jay color-management enable
|
||||
```
|
||||
|
||||
Or in your configuration file:
|
||||
|
||||
```toml
|
||||
[color-management]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
To return to SDR:
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 colors set default default
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Run `jay randr` to find connector names and serial numbers for your
|
||||
> displays.
|
||||
|
||||
## Concepts
|
||||
|
||||
### Color space
|
||||
|
||||
The color space determines the range of colors (gamut) the output uses.
|
||||
|
||||
`default`
|
||||
: sRGB gamut. This is the standard gamut for desktop displays.
|
||||
|
||||
`bt2020`
|
||||
: BT.2020 gamut. A much wider gamut used by HDR10 and modern cinema standards.
|
||||
|
||||
### Transfer function (EOTF)
|
||||
|
||||
The transfer function (technically the Electro-Optical Transfer Function)
|
||||
controls how encoded pixel values are mapped to display luminance.
|
||||
|
||||
`default`
|
||||
: Gamma 2.2. The traditional SDR transfer function.
|
||||
|
||||
`pq`
|
||||
: Perceptual Quantizer (SMPTE ST 2084). The HDR10 transfer function, designed
|
||||
to cover luminance levels from 0 to 10,000 cd/m^2.
|
||||
|
||||
Setting `color-space = "bt2020"` and `transfer-function = "pq"` together
|
||||
activates HDR10 mode. Jay sends the appropriate HDR metadata infoframe to the
|
||||
display, including the display's mastering luminance and primaries from its
|
||||
EDID.
|
||||
|
||||
### Brightness
|
||||
|
||||
The brightness setting controls SDR content luminance in cd/m^2. This
|
||||
determines how bright non-HDR content appears on an HDR display.
|
||||
|
||||
With the `default` (gamma 2.2) transfer function, the default brightness is
|
||||
the maximum the display supports, anchored at 80 cd/m^2. Setting brightness
|
||||
below 80 makes SDR content dimmer while creating HDR headroom above it.
|
||||
|
||||
With the `pq` transfer function, the default brightness is 203 cd/m^2 (the
|
||||
ITU reference level for SDR content in an HDR signal).
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
color-space = "bt2020"
|
||||
transfer-function = "pq"
|
||||
brightness = 250
|
||||
```
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 brightness 250
|
||||
~$ jay randr output DP-1 brightness default
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Brightness has no effect unless the Vulkan renderer is in use.
|
||||
|
||||
### Blend space
|
||||
|
||||
When Jay composites overlapping translucent surfaces, the blend space
|
||||
determines in which color space the alpha blending is performed.
|
||||
|
||||
`srgb`
|
||||
: Classic desktop blending in sRGB space. This is the default and matches the
|
||||
behavior of most other compositors.
|
||||
|
||||
`linear`
|
||||
: Blending in linear light. This is physically correct but can make
|
||||
semi-transparent elements appear brighter than expected.
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
blend-space = "linear"
|
||||
```
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 blend-space linear
|
||||
```
|
||||
|
||||
### Native gamut
|
||||
|
||||
By default, Jay assumes all displays use sRGB primaries. This matches the
|
||||
behavior of most other compositors, but most modern displays actually have a
|
||||
wider gamut (e.g. 95% DCI-P3 coverage). Because the display interprets
|
||||
sRGB-intended color values in its wider native gamut, colors appear more
|
||||
saturated than they should.
|
||||
|
||||
Setting `use-native-gamut = true` tells Jay the display's actual primaries
|
||||
from its EDID, allowing the compositor to map colors correctly. This produces
|
||||
less saturated but more accurate colors, and allows color-managed applications
|
||||
to address the full display gamut.
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
use-native-gamut = true
|
||||
```
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 use-native-gamut true
|
||||
```
|
||||
|
||||
This setting has no effect when the display is already operating in a wide
|
||||
color space like BT.2020.
|
||||
|
||||
### Framebuffer format
|
||||
|
||||
The default framebuffer format (`xrgb8888`) uses 8 bits per channel, which
|
||||
can cause banding in HDR content. For HDR, consider a higher-precision format:
|
||||
|
||||
- `xrgb2101010` or `argb2101010` -- 10 bits per channel. Good balance between
|
||||
precision and performance.
|
||||
- `xbgr16161616f` or `abgr16161616f` -- 16-bit floating point per channel.
|
||||
Maximum precision.
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
color-space = "bt2020"
|
||||
transfer-function = "pq"
|
||||
format = "xrgb2101010"
|
||||
```
|
||||
|
||||
```shell
|
||||
~$ jay randr output DP-1 format set xrgb2101010
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> Run `jay randr show --formats` to see which formats your display supports.
|
||||
|
||||
## Color management protocol
|
||||
|
||||
The Wayland color management protocol (`wp_color_manager_v1`) lets
|
||||
applications communicate their color space to the compositor. This enables
|
||||
color-aware applications to render correctly regardless of the output's color
|
||||
settings -- for example, an image viewer can tag its surfaces as sRGB and Jay
|
||||
will map the colors to the output's actual gamut and transfer function.
|
||||
|
||||
The protocol is **disabled by default** and must be enabled explicitly:
|
||||
|
||||
```toml
|
||||
[color-management]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
Or at runtime:
|
||||
|
||||
```shell
|
||||
~$ jay color-management enable
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Changing this setting has no effect on applications that are already running.
|
||||
> They must be restarted to discover the protocol.
|
||||
|
||||
Color management availability requires both the protocol to be enabled **and**
|
||||
the Vulkan renderer to be active. Check with:
|
||||
|
||||
```shell
|
||||
~$ jay color-management status
|
||||
```
|
||||
|
||||
This prints one of:
|
||||
|
||||
`Enabled`
|
||||
: The protocol is enabled and available to clients.
|
||||
|
||||
`Enabled (Unavailable)`
|
||||
: The protocol is enabled but unavailable -- usually because the OpenGL
|
||||
renderer is in use.
|
||||
|
||||
`Disabled`
|
||||
: The protocol is disabled.
|
||||
|
||||
The [control center](control-center.md) **Color Management** pane shows the
|
||||
same information as a toggle and a read-only availability indicator.
|
||||
|
||||
### Supported capabilities
|
||||
|
||||
Jay's color management implementation supports:
|
||||
|
||||
- **Parametric image descriptions** with custom primaries, luminances, and
|
||||
transfer functions (including power curves).
|
||||
- **Named primaries**: sRGB, BT.2020, DCI-P3, Display P3, Adobe RGB, and
|
||||
others.
|
||||
- **Named transfer functions**: sRGB, PQ (ST 2084), gamma 2.2, gamma 2.4,
|
||||
BT.1886, linear, and others.
|
||||
- **Mastering display metadata** for HDR content.
|
||||
- **Windows scRGB** compatibility.
|
||||
|
||||
ICC profile creation is not supported.
|
||||
|
||||
## Checking display capabilities
|
||||
|
||||
Use `jay randr show` to inspect what your display supports:
|
||||
|
||||
```shell
|
||||
~$ jay randr show
|
||||
```
|
||||
|
||||
The output for each connector includes:
|
||||
|
||||
- **Color spaces** -- which color spaces the display supports (e.g. `default`,
|
||||
`bt2020`), with the current setting marked.
|
||||
- **EOTFs** -- which transfer functions the display supports (e.g. `default`,
|
||||
`pq`), with the current setting marked.
|
||||
- **Brightness range** -- minimum and maximum luminance from the EDID, in
|
||||
cd/m^2.
|
||||
- **Current brightness** -- displayed if a custom value is set.
|
||||
- **Blend space** -- current blend space setting.
|
||||
- **Native gamut** -- the display's CIE xy primaries for red, green, blue, and
|
||||
white point.
|
||||
|
||||
## Complete example
|
||||
|
||||
A typical HDR configuration for a monitor that supports HDR10:
|
||||
|
||||
```toml
|
||||
[[outputs]]
|
||||
match.serial-number = "33K03894SL0"
|
||||
color-space = "bt2020"
|
||||
transfer-function = "pq"
|
||||
brightness = 203
|
||||
format = "xrgb2101010"
|
||||
blend-space = "linear"
|
||||
|
||||
[color-management]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
This sets the output to HDR10 with 10-bit color, physically correct blending,
|
||||
and enables the color management protocol so applications can communicate
|
||||
their color spaces.
|
||||
|
||||
## Control center
|
||||
|
||||
The Outputs pane in the [control center](control-center.md) (`alt-c` by
|
||||
default) provides GUI controls for all HDR-related settings per output:
|
||||
Colorimetry, EOTF, Custom Brightness, Format, Blend Space, Use Native Gamut,
|
||||
and a read-only Native Gamut display. See
|
||||
[Outputs (Monitors)](configuration/outputs.md) for details on each field.
|
||||
|
||||
The Color Management pane has a toggle to enable/disable the protocol and a
|
||||
read-only indicator showing whether color management is currently available.
|
||||
|
||||
## See also
|
||||
|
||||
- [Outputs (Monitors)](configuration/outputs.md) -- per-output configuration
|
||||
reference including all color and HDR fields
|
||||
- [Miscellaneous](configuration/misc.md) -- the `[color-management]` config
|
||||
table
|
||||
- [Command-Line Interface](cli.md) -- `jay randr output` color commands and
|
||||
`jay color-management`
|
||||
- [GPUs](configuration/gpu.md) -- renderer selection (Vulkan is required for
|
||||
HDR)
|
||||
177
book/src/input-modes.md
Normal file
177
book/src/input-modes.md
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
# Input Modes
|
||||
|
||||
Jay supports an **input mode stack** that enables vim-style modal keybindings.
|
||||
When a mode is active, its shortcuts take effect instead of (or in addition to)
|
||||
the top-level shortcuts. Multiple modes can be stacked, and the topmost mode
|
||||
always wins.
|
||||
|
||||
## Defining Modes
|
||||
|
||||
Modes are defined in the `[modes]` table. Each mode is a named sub-table that
|
||||
can contain its own `shortcuts` and `complex-shortcuts`:
|
||||
|
||||
```toml
|
||||
[modes."move".shortcuts]
|
||||
h = "move-left"
|
||||
j = "move-down"
|
||||
k = "move-up"
|
||||
l = "move-right"
|
||||
Escape = "pop-mode"
|
||||
```
|
||||
|
||||
## Inheritance
|
||||
|
||||
By default, a mode inherits all shortcuts from the top-level `[shortcuts]`
|
||||
table. Any key not explicitly defined in the mode falls through to the
|
||||
inherited shortcuts.
|
||||
|
||||
To inherit from a different mode instead, set the `parent` field:
|
||||
|
||||
```toml
|
||||
[modes."navigation"]
|
||||
parent = "base"
|
||||
|
||||
[modes."navigation".shortcuts]
|
||||
w = "focus-up"
|
||||
a = "focus-left"
|
||||
s = "focus-down"
|
||||
d = "focus-right"
|
||||
```
|
||||
|
||||
Here, `navigation` inherits from the mode called `base` rather than from the
|
||||
top-level shortcuts.
|
||||
|
||||
### Unbinding Inherited Shortcuts
|
||||
|
||||
Use `"none"` as the action value to unbind a shortcut that would otherwise be
|
||||
inherited:
|
||||
|
||||
```toml
|
||||
[modes."locked".shortcuts]
|
||||
# Disable alt-q (quit) while in this mode
|
||||
alt-q = "none"
|
||||
```
|
||||
|
||||
## Activating and Deactivating Modes
|
||||
|
||||
Jay provides four actions for managing the mode stack:
|
||||
|
||||
`push-mode`
|
||||
: Push a named mode onto the stack. It stays active until explicitly removed.
|
||||
|
||||
`latch-mode`
|
||||
: Temporarily push a mode. It auto-pops after the next shortcut fires.
|
||||
|
||||
`pop-mode`
|
||||
: Remove the topmost mode from the stack.
|
||||
|
||||
`clear-modes`
|
||||
: Clear the entire mode stack, returning to top-level shortcuts.
|
||||
|
||||
### push-mode
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-r = { type = "push-mode", name = "resize" }
|
||||
```
|
||||
|
||||
After pressing `alt-r`, the `resize` mode's shortcuts take effect. It remains
|
||||
active until something pops it.
|
||||
|
||||
### latch-mode
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-x = { type = "latch-mode", name = "navigation" }
|
||||
```
|
||||
|
||||
After pressing `alt-x`, the `navigation` mode is pushed. The very next shortcut
|
||||
that fires will use the mode's bindings, and then the mode is automatically
|
||||
popped. This is ideal for **leader key** patterns.
|
||||
|
||||
### pop-mode
|
||||
|
||||
```toml
|
||||
[modes."resize".shortcuts]
|
||||
Escape = "pop-mode"
|
||||
```
|
||||
|
||||
Pressing `Escape` while in `resize` mode removes it from the stack.
|
||||
|
||||
### clear-modes
|
||||
|
||||
```toml
|
||||
[modes."resize".shortcuts]
|
||||
ctrl-c = "clear-modes"
|
||||
```
|
||||
|
||||
This removes all modes from the stack at once, returning to the top-level
|
||||
shortcuts regardless of how many modes have been stacked.
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### Move Mode
|
||||
|
||||
A dedicated mode for moving windows with `h`/`j`/`k`/`l`, activated by
|
||||
`alt-r` and exited with `Escape`:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-r = { type = "push-mode", name = "move" }
|
||||
|
||||
[modes."move".shortcuts]
|
||||
h = "move-left"
|
||||
j = "move-down"
|
||||
k = "move-up"
|
||||
l = "move-right"
|
||||
Escape = "pop-mode"
|
||||
```
|
||||
|
||||
While in move mode, pressing `h` moves the focused window left, `l` moves it
|
||||
right, and so on -- without needing a modifier key. All other inherited
|
||||
shortcuts (like `alt-q` to quit) remain available. Press `Escape` to return
|
||||
to normal.
|
||||
|
||||
### Leader Key
|
||||
|
||||
A leader key pattern where pressing `alt-x` followed by one key triggers a
|
||||
mode shortcut, then immediately returns to normal:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-x = { type = "latch-mode", name = "leader" }
|
||||
|
||||
[modes."leader".shortcuts]
|
||||
t = { type = "exec", exec = "alacritty" }
|
||||
b = { type = "exec", exec = "firefox" }
|
||||
f = { type = "exec", exec = "thunar" }
|
||||
q = "quit"
|
||||
```
|
||||
|
||||
Press `alt-x` then `t` to launch a terminal. Because `latch-mode` auto-pops
|
||||
after one shortcut, you are immediately back to normal shortcuts.
|
||||
|
||||
### Nested Modes
|
||||
|
||||
Modes can push other modes, creating layers of context:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-n = { type = "push-mode", name = "navigate" }
|
||||
|
||||
[modes."navigate".shortcuts]
|
||||
m = { type = "push-mode", name = "move" }
|
||||
Escape = "pop-mode"
|
||||
|
||||
[modes."move".shortcuts]
|
||||
h = "move-left"
|
||||
l = "move-right"
|
||||
Escape = "pop-mode"
|
||||
```
|
||||
|
||||
`alt-n` enters navigation mode. From there, pressing `m` enters move mode
|
||||
on top of it. `Escape` pops the current mode one level at a time. Use
|
||||
`clear-modes` if you want a shortcut that returns directly to the top level.
|
||||
|
||||
See [spec.generated.md](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md) for the full
|
||||
specification of `InputMode`, `push-mode`, `latch-mode`, and related actions.
|
||||
162
book/src/installation.md
Normal file
162
book/src/installation.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# Installation
|
||||
|
||||
## Compile-Time Dependencies
|
||||
|
||||
The following libraries must be installed before building Jay. They are linked
|
||||
at build time.
|
||||
|
||||
| Library | Arch Linux | Fedora | Debian / Ubuntu |
|
||||
|---------------|----------------|----------------------|----------------------|
|
||||
| libinput | `libinput` | `libinput-devel` | `libinput-dev` |
|
||||
| libgbm | `mesa` | `mesa-libgbm-devel` | `libgbm-dev` |
|
||||
| libudev | `systemd-libs` | `systemd-devel` | `libudev-dev` |
|
||||
| libpangocairo | `pango` | `pango-devel` | `libpango1.0-dev` |
|
||||
| libfontconfig | `fontconfig` | `fontconfig-devel` | `libfontconfig-dev` |
|
||||
|
||||
**One-liner install commands:**
|
||||
|
||||
Arch Linux:
|
||||
|
||||
```shell
|
||||
~$ sudo pacman -S libinput mesa systemd-libs pango fontconfig
|
||||
```
|
||||
|
||||
Fedora:
|
||||
|
||||
```shell
|
||||
~$ sudo dnf install libinput-devel mesa-libgbm-devel systemd-devel pango-devel fontconfig-devel
|
||||
```
|
||||
|
||||
Debian / Ubuntu:
|
||||
|
||||
```shell
|
||||
~$ sudo apt install libinput-dev libgbm-dev libudev-dev libpango1.0-dev libfontconfig-dev
|
||||
```
|
||||
|
||||
You also need a C compiler (GCC or Clang) and the latest stable version of
|
||||
Rust. Install Rust with [rustup](https://rustup.rs/):
|
||||
|
||||
```shell
|
||||
~$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
## Runtime Dependencies
|
||||
|
||||
These libraries are loaded dynamically at runtime. Jay requires **at least one**
|
||||
working renderer -- without one, no GPU can be initialized and nothing will be
|
||||
displayed.
|
||||
|
||||
| Library | Purpose | Arch Linux | Fedora | Debian / Ubuntu |
|
||||
|--------------------|-------------------------------|----------------------|---------------------------------|------------------------|
|
||||
| libEGL + libGLESv2 | OpenGL renderer (legacy) | `mesa` or `libglvnd` | `mesa-libEGL` + `mesa-libGLES` | `libegl1` + `libgles2` |
|
||||
| libvulkan | Vulkan renderer (recommended) | `vulkan-icd-loader` | `vulkan-loader` | `libvulkan1` |
|
||||
|
||||
For Vulkan, you also need the driver for your GPU:
|
||||
|
||||
| GPU | Arch Linux | Fedora | Debian / Ubuntu |
|
||||
|--------|-----------------|-----------------------|-----------------------|
|
||||
| AMD | `vulkan-radeon` | `mesa-vulkan-drivers` | `mesa-vulkan-drivers` |
|
||||
| Intel | `vulkan-intel` | `mesa-vulkan-drivers` | `mesa-vulkan-drivers` |
|
||||
| Nvidia | `nvidia-utils` | `xorg-x11-drv-nvidia` | `nvidia-vulkan-icd` |
|
||||
|
||||
### Optional Runtime Dependencies
|
||||
|
||||
- **Linux 6.7 or later** -- required for explicit sync (needed for Nvidia GPUs).
|
||||
- **Xwayland** -- required for running X11 applications.
|
||||
- **PipeWire** -- required for screen sharing.
|
||||
- **logind** (part of systemd) -- required when running Jay from a virtual terminal or display manager.
|
||||
|
||||
## Building
|
||||
|
||||
### AUR (Arch Linux)
|
||||
|
||||
Arch Linux users can install Jay from the AUR. Two packages are available:
|
||||
|
||||
- **[jay](https://aur.archlinux.org/packages/jay)** -- builds the latest
|
||||
released version.
|
||||
- **[jay-git](https://aur.archlinux.org/packages/jay-git)** -- builds from the
|
||||
latest commit on the master branch.
|
||||
|
||||
Install with your preferred AUR helper, for example:
|
||||
|
||||
```shell
|
||||
~$ yay -S jay
|
||||
```
|
||||
|
||||
The AUR packages handle all compile-time dependencies automatically.
|
||||
|
||||
### From crates.io (recommended)
|
||||
|
||||
```shell
|
||||
~$ cargo install --locked jay-compositor
|
||||
```
|
||||
|
||||
This installs the `jay` binary to `~/.cargo/bin/jay`.
|
||||
|
||||
### From git (latest development version)
|
||||
|
||||
```shell
|
||||
~$ cargo install --locked --git https://github.com/mahkoh/jay.git jay-compositor
|
||||
```
|
||||
|
||||
### From a local clone
|
||||
|
||||
```shell
|
||||
~$ git clone https://github.com/mahkoh/jay.git
|
||||
~$ cd jay
|
||||
~$ cargo build --release
|
||||
```
|
||||
|
||||
The binary is then available at `./target/release/jay`.
|
||||
|
||||
## CAP_SYS_NICE (Optional)
|
||||
|
||||
Granting `CAP_SYS_NICE` to the Jay binary can improve responsiveness when the
|
||||
CPU or GPU are under heavy load:
|
||||
|
||||
```shell
|
||||
~$ sudo setcap cap_sys_nice=p $(which jay)
|
||||
```
|
||||
|
||||
When this capability is available, Jay will elevate its scheduler to `SCHED_RR`
|
||||
(real-time round-robin) and create Vulkan queues with the highest available
|
||||
priority. Both of these help Jay maintain smooth frame delivery under
|
||||
contention.
|
||||
|
||||
Jay drops all capabilities almost immediately after startup. A dedicated thread
|
||||
retains `CAP_SYS_NICE` solely for creating elevated Vulkan queues later.
|
||||
|
||||
> [!NOTE]
|
||||
> You need to re-run the `setcap` command each time you update the Jay binary.
|
||||
|
||||
### SCHED_RR and config.so
|
||||
|
||||
`SCHED_RR` and `config.so` are mutually exclusive: running untrusted code at
|
||||
real-time priority would be a security risk. Jay enforces this as follows:
|
||||
|
||||
- If `config.so` exists in the config directory, Jay skips the `SCHED_RR`
|
||||
elevation (elevated Vulkan queues are still created).
|
||||
- If Jay has already elevated to `SCHED_RR`, it refuses to load `config.so`.
|
||||
|
||||
You can also skip `SCHED_RR` explicitly by setting `JAY_NO_REALTIME=1`:
|
||||
|
||||
```shell
|
||||
~$ JAY_NO_REALTIME=1 jay run
|
||||
```
|
||||
|
||||
This still allows elevated Vulkan queues and does not affect `config.so`
|
||||
loading.
|
||||
|
||||
The mutual exclusion can be overridden at compile time by building Jay with
|
||||
`JAY_ALLOW_REALTIME_CONFIG_SO=1`.
|
||||
|
||||
## Recommended Applications
|
||||
|
||||
The following applications work well with Jay:
|
||||
|
||||
- **[Alacritty](https://alacritty.org/)** -- the default terminal emulator in the built-in configuration.
|
||||
- **[bemenu](https://github.com/Cloudef/bemenu)** -- the default application launcher in the built-in configuration.
|
||||
- **[xdg-desktop-portal-gtk4](https://github.com/mahkoh/xdg-desktop-portal-gtk4)** -- a file-picker portal with thumbnail support. Used automatically when installed.
|
||||
- **[wl-tray-bridge](https://github.com/mahkoh/wl-tray-bridge)** -- shows D-Bus StatusNotifierItem applications as tray icons.
|
||||
- **[mako](https://github.com/emersion/mako)** -- a notification daemon. Launched automatically by the default configuration.
|
||||
- **[window-to-tray](https://github.com/mahkoh/wl-proxy/tree/master/apps/window-to-tray)** -- run most Wayland applications as tray applications (e.g. `window-to-tray pavucontrol-qt`).
|
||||
46
book/src/introduction.md
Normal file
46
book/src/introduction.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Introduction
|
||||
|
||||
> [!NOTE]
|
||||
> This book was written entirely by Claude Opus 4.6 and will likely also be
|
||||
> maintained in the future with the help of AI to ensure a consistent tone of
|
||||
> voice, style, and quality.
|
||||
>
|
||||
> All contents have been reviewed by humans but there might still be some
|
||||
> mistakes left. That would put it in good company since the artisanal,
|
||||
> hand-crafted spec.yaml, that contains the TOML config specification, contains
|
||||
> plenty of mistakes as well.
|
||||
>
|
||||
> The writing is of high quality in my estimation, certainly better than what I
|
||||
> would have produced in any reasonable amount of time. There are few obvious
|
||||
> _slop_ indicators. The AI sometimes uses superlatives ("ideal", "best") that I
|
||||
> would not use myself, but I've seen this style in other pieces of
|
||||
> documentation, so maybe it is just a style that aims to be approachable or to
|
||||
> guide users towards good solutions.
|
||||
>
|
||||
> If you find something objectionable in this book, do not hesitate to open an
|
||||
> issue.
|
||||
|
||||
Jay is a Wayland compositor for Linux with an i3-inspired tiling layout. It
|
||||
supports Vulkan and OpenGL rendering, multi-GPU setups, fractional scaling,
|
||||
variable refresh rate (VRR), tearing presentation, HDR, and screen sharing via
|
||||
xdg-desktop-portal. X11 applications are supported through Xwayland.
|
||||
|
||||
Jay is configured through a declarative TOML file, with an optional advanced
|
||||
mode that uses a shared library for programmatic control. A built-in
|
||||
[control center](control-center.md) (opened with `alt-c`) provides a full GUI
|
||||
for inspecting and changing compositor settings at runtime -- including output
|
||||
arrangement, input devices, color management, GPU selection, and more. A
|
||||
comprehensive command-line interface makes scripting and automation
|
||||
straightforward.
|
||||
|
||||
See the [Features](features.md) chapter for a comprehensive overview of what
|
||||
Jay can do, or jump straight to [Installation](installation.md) to get started.
|
||||
|
||||
## License
|
||||
|
||||
Jay is free software licensed under the
|
||||
[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
|
||||
## Community
|
||||
|
||||
[Discord server (unofficial)](https://discord.gg/Hby736z28G)
|
||||
103
book/src/mouse.md
Normal file
103
book/src/mouse.md
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# Mouse Interactions
|
||||
|
||||
Jay supports a range of mouse-driven interactions for managing windows,
|
||||
workspaces, and layout. This page is a comprehensive reference for all of them.
|
||||
|
||||
## Tiling
|
||||
|
||||
**Resizing tiles.** Drag the separator between two tiles to resize them. The
|
||||
cursor changes to a resize indicator when hovering over a separator.
|
||||
|
||||
**Moving tiles.** Drag a tile's title bar to move it within or between
|
||||
containers. While dragging:
|
||||
|
||||
- Drop it onto another position in a container to rearrange tiles.
|
||||
- Drop it onto a workspace tab in the bar to move it to that workspace.
|
||||
- Drop it onto the bar outside any workspace tab to create a new workspace
|
||||
for it.
|
||||
|
||||
**Double-click a tile's title** to toggle it between tiled and floating. See
|
||||
[Floating Windows](floating.md) for details.
|
||||
|
||||
**Right-click any title** in a container to toggle mono mode (showing one window
|
||||
at a time vs. all side by side). See [Tiling -- Mono Mode](tiling.md#mono-mode).
|
||||
|
||||
**Scroll over a title** in mono mode to cycle between the tiles in that
|
||||
container.
|
||||
|
||||
## Floating Windows
|
||||
|
||||
**Drag a floating window's title** to move it.
|
||||
|
||||
**Drag a floating window's border** to resize it.
|
||||
|
||||
**Double-click a floating window's title** to toggle it back to tiled.
|
||||
|
||||
**Right-click a floating window's title** to pin or unpin it. Pinned floating
|
||||
windows stay visible across workspace switches.
|
||||
|
||||
**Click the pin icon** (if visible) to pin or unpin the window. The pin icon
|
||||
can be enabled with:
|
||||
|
||||
```toml
|
||||
[float]
|
||||
show-pin-icon = true
|
||||
```
|
||||
|
||||
## Workspaces
|
||||
|
||||
**Scroll over the bar** to switch between workspaces on that output.
|
||||
|
||||
**Drag workspace titles** in the bar to reorder them. This only works in manual
|
||||
display order mode (the default). See
|
||||
[Workspaces -- Display Order](workspaces.md#workspace-display-order).
|
||||
|
||||
## Window Management Mode
|
||||
|
||||
Window management mode enables additional mouse interactions that do not require
|
||||
targeting specific UI elements. Configure it by setting `window-management-key`
|
||||
to a keysym:
|
||||
|
||||
```toml
|
||||
window-management-key = "Alt_L"
|
||||
```
|
||||
|
||||
**Hold the configured key** to enter window management mode. While held:
|
||||
|
||||
- **Left-drag** anywhere on a floating window, tile, popup, or fullscreen window
|
||||
to **move** it.
|
||||
- **Right-drag** anywhere on a floating window, tile, or popup to **resize** it.
|
||||
|
||||
This is especially useful for:
|
||||
|
||||
- Moving or resizing floating windows without needing to precisely target the
|
||||
title bar or border.
|
||||
- Moving tiled windows without targeting the title bar.
|
||||
- Moving fullscreen windows (not possible without this mode).
|
||||
- Resizing tiles without targeting the separator.
|
||||
|
||||
> [!NOTE]
|
||||
> Entering window management mode disables all pointer constraints. This means
|
||||
> you can use it to move the pointer out of applications that have grabbed it
|
||||
> (such as games in fullscreen), but pointer-dependent applications will behave
|
||||
> differently while the key is held.
|
||||
|
||||
## Other
|
||||
|
||||
**Toplevel selection.** Some actions (like screen sharing) ask you to select a
|
||||
window, indicated by a purple overlay. During this selection, right-click a
|
||||
tile's title to select the entire container instead of an individual tile.
|
||||
|
||||
**Canceling interactions.** Press `Escape` to cancel any in-progress mouse
|
||||
interaction (dragging, resizing, selection, etc.). The cancel key can be changed
|
||||
with the `pointer-revert-key` configuration:
|
||||
|
||||
```toml
|
||||
# Use a different key to cancel mouse interactions
|
||||
pointer-revert-key = "grave"
|
||||
|
||||
# Disable the cancel key entirely
|
||||
pointer-revert-key = "NoSymbol"
|
||||
```
|
||||
|
||||
The default is `Escape`.
|
||||
127
book/src/running.md
Normal file
127
book/src/running.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# Running Jay
|
||||
|
||||
## From a Virtual Terminal
|
||||
|
||||
Switch to a virtual terminal (e.g. `ctrl-alt-F2`), log in, and run:
|
||||
|
||||
```shell
|
||||
~$ jay run
|
||||
```
|
||||
|
||||
## From a Display Manager
|
||||
|
||||
To make Jay appear as a session option in your display manager (GDM, SDDM,
|
||||
etc.), install the session file.
|
||||
|
||||
If you have the repository checked out:
|
||||
|
||||
```shell
|
||||
~$ sudo cp etc/jay.desktop /usr/share/wayland-sessions/jay.desktop
|
||||
```
|
||||
|
||||
Otherwise, create it manually:
|
||||
|
||||
```shell
|
||||
~$ sudo tee /usr/share/wayland-sessions/jay.desktop > /dev/null << 'EOF'
|
||||
[Desktop Entry]
|
||||
Name=Jay
|
||||
Comment=A Wayland Compositor
|
||||
Exec=jay run
|
||||
Type=Application
|
||||
DesktopNames=jay
|
||||
EOF
|
||||
```
|
||||
|
||||
Then log out and select **Jay** from the session list.
|
||||
|
||||
> [!NOTE]
|
||||
> If you installed Jay via `cargo install`, the `jay` binary lives in
|
||||
> `~/.cargo/bin/`. Your display manager may not include this directory in its
|
||||
> `PATH`. Either add `~/.cargo/bin` to the system `PATH`, or copy/symlink the
|
||||
> binary to `/usr/local/bin`:
|
||||
>
|
||||
> ```shell
|
||||
> ~$ sudo ln -s ~/.cargo/bin/jay /usr/local/bin/jay
|
||||
> ```
|
||||
|
||||
## The Control Center
|
||||
|
||||
Once Jay is running, press `alt-c` to open the
|
||||
[control center](control-center.md) -- a built-in GUI that lets you inspect and
|
||||
modify most compositor settings without editing config files or running CLI
|
||||
commands. From the control center you can:
|
||||
|
||||
- Rearrange monitors with a visual drag-and-drop editor.
|
||||
- Configure input devices -- acceleration, tap behavior, keymaps, and more.
|
||||
- Switch GPUs and graphics APIs.
|
||||
- Adjust theme colors, fonts, borders, and gaps with live color pickers.
|
||||
- Manage idle timeouts and screen locking.
|
||||
- Search and filter windows and clients.
|
||||
- Toggle Xwayland and color management.
|
||||
|
||||
You can also open it from the command line with `jay control-center`. See the
|
||||
[Control Center](control-center.md) chapter for a full tour of every pane.
|
||||
|
||||
## Default Keybindings
|
||||
|
||||
Jay ships with a built-in default configuration. The most important default
|
||||
keybindings are listed below.
|
||||
|
||||
> [!NOTE]
|
||||
> [Alacritty](https://alacritty.org/) and
|
||||
> [bemenu](https://github.com/Cloudef/bemenu) must be installed for the default
|
||||
> terminal and launcher bindings to work.
|
||||
|
||||
`Super_L` (left Windows key)
|
||||
: Open Alacritty terminal
|
||||
|
||||
`alt-p`
|
||||
: Open bemenu application launcher
|
||||
|
||||
`alt-q`
|
||||
: Quit Jay
|
||||
|
||||
`alt-h` / `j` / `k` / `l`
|
||||
: Move focus (left/down/up/right)
|
||||
|
||||
`alt-shift-h` / `j` / `k` / `l`
|
||||
: Move focused window
|
||||
|
||||
`alt-d`
|
||||
: Split horizontally
|
||||
|
||||
`alt-v`
|
||||
: Split vertically
|
||||
|
||||
`alt-u`
|
||||
: Toggle fullscreen
|
||||
|
||||
`alt-shift-f`
|
||||
: Toggle floating
|
||||
|
||||
`alt-c`
|
||||
: Open the control center
|
||||
|
||||
`alt-shift-c`
|
||||
: Close focused window
|
||||
|
||||
`alt-t`
|
||||
: Toggle split direction
|
||||
|
||||
`alt-m`
|
||||
: Toggle mono (stacking) layout
|
||||
|
||||
`alt-f`
|
||||
: Focus parent container
|
||||
|
||||
`alt-shift-r`
|
||||
: Reload configuration
|
||||
|
||||
The defaults also include `ctrl-alt-F1` through `F12` for switching virtual
|
||||
terminals, `alt-F1` through `F12` for switching workspaces, and
|
||||
`alt-shift-F1` through `F12` for moving windows to workspaces.
|
||||
|
||||
Once you create a configuration file, the built-in defaults are entirely
|
||||
replaced -- even an empty config file means no shortcuts. Run `jay config init`
|
||||
to generate a config pre-populated with all the defaults. See the
|
||||
[Configuration Overview](configuration/index.md) chapter for details.
|
||||
111
book/src/screen-sharing.md
Normal file
111
book/src/screen-sharing.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Screen Sharing
|
||||
|
||||
Jay supports screen sharing via
|
||||
[xdg-desktop-portal](https://github.com/flatpak/xdg-desktop-portal). Three
|
||||
capture types are available:
|
||||
|
||||
- **Window capture** -- share a single window.
|
||||
- **Output capture** -- share an entire monitor.
|
||||
- **Workspace capture** -- like output capture, but only a single workspace is
|
||||
shown.
|
||||
|
||||
## Requirements
|
||||
|
||||
[PipeWire](https://pipewire.org/) must be installed and running. Verify with:
|
||||
|
||||
```shell
|
||||
~$ systemctl --user status pipewire
|
||||
```
|
||||
|
||||
## Portal Setup
|
||||
|
||||
Jay implements its own portal backend for the `ScreenCast` and `RemoteDesktop`
|
||||
interfaces. Two configuration files must be installed so that
|
||||
`xdg-desktop-portal` knows to use Jay's backend.
|
||||
|
||||
### If the Repository is Checked Out
|
||||
|
||||
```shell
|
||||
~$ sudo cp etc/jay.portal /usr/share/xdg-desktop-portal/portals/jay.portal
|
||||
~$ sudo cp etc/jay-portals.conf /usr/share/xdg-desktop-portal/jay-portals.conf
|
||||
```
|
||||
|
||||
### If Installed via cargo install
|
||||
|
||||
Create the files manually:
|
||||
|
||||
```shell
|
||||
~$ sudo tee /usr/share/xdg-desktop-portal/portals/jay.portal > /dev/null << 'EOF'
|
||||
[portal]
|
||||
DBusName=org.freedesktop.impl.portal.desktop.jay
|
||||
Interfaces=org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.RemoteDesktop;
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
~$ sudo tee /usr/share/xdg-desktop-portal/jay-portals.conf > /dev/null << 'EOF'
|
||||
[preferred]
|
||||
default=gtk
|
||||
org.freedesktop.impl.portal.ScreenCast=jay
|
||||
org.freedesktop.impl.portal.RemoteDesktop=jay
|
||||
org.freedesktop.impl.portal.Inhibit=none
|
||||
org.freedesktop.impl.portal.FileChooser=gtk4
|
||||
EOF
|
||||
```
|
||||
|
||||
### Restart the Portal
|
||||
|
||||
After installing the files, restart the portal service:
|
||||
|
||||
```shell
|
||||
~$ systemctl --user restart xdg-desktop-portal
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### workspace-capture
|
||||
|
||||
The top-level `workspace-capture` setting controls whether newly created
|
||||
workspaces can be captured via workspace capture. The default is `true`:
|
||||
|
||||
```toml
|
||||
workspace-capture = false
|
||||
```
|
||||
|
||||
Set this to `false` if you want to prevent workspace-level capture by default.
|
||||
|
||||
### Capture Indicator Colors
|
||||
|
||||
When a window is being recorded, its title bar color changes to make the
|
||||
capture visually obvious. You can customize these colors in the `[theme]`
|
||||
table:
|
||||
|
||||
```toml
|
||||
[theme]
|
||||
captured-focused-title-bg-color = "#900000"
|
||||
captured-unfocused-title-bg-color = "#5f0000"
|
||||
```
|
||||
|
||||
- `captured-focused-title-bg-color` -- background color of focused title bars
|
||||
that are being recorded.
|
||||
- `captured-unfocused-title-bg-color` -- background color of unfocused title
|
||||
bars that are being recorded.
|
||||
|
||||
## The jay portal Command
|
||||
|
||||
Jay's portal backend is normally started automatically when a screen-sharing
|
||||
request comes in via D-Bus activation. If you need to start it manually for
|
||||
debugging purposes:
|
||||
|
||||
```shell
|
||||
~$ jay portal
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If screen sharing does not work:
|
||||
|
||||
1. Verify PipeWire is running: `systemctl --user status pipewire`
|
||||
2. Verify the portal files are installed in `/usr/share/xdg-desktop-portal/`.
|
||||
3. Restart the portal: `systemctl --user restart xdg-desktop-portal`
|
||||
4. Check the Jay log for errors: `jay log`
|
||||
186
book/src/tiling.md
Normal file
186
book/src/tiling.md
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
# Tiling
|
||||
|
||||
Jay uses an i3-like tiling layout. Windows are arranged automatically in
|
||||
containers that can be split horizontally or vertically. Containers can be nested
|
||||
to create complex layouts.
|
||||
|
||||
## Splitting Containers
|
||||
|
||||
When you split a window, Jay wraps it in a new container with the specified
|
||||
direction. Subsequent windows opened in that container are placed side by side
|
||||
(horizontal split) or stacked top to bottom (vertical split).
|
||||
|
||||
`alt-d` -- `split-horizontal`
|
||||
: Split the focused window horizontally
|
||||
|
||||
`alt-v` -- `split-vertical`
|
||||
: Split the focused window vertically
|
||||
|
||||
`alt-t` -- `toggle-split`
|
||||
: Toggle the container's split direction
|
||||
|
||||
You can also set the direction explicitly without toggling:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-d = "tile-horizontal"
|
||||
alt-shift-v = "tile-vertical"
|
||||
```
|
||||
|
||||
The `tile-horizontal` action sets the container to horizontal, and
|
||||
`tile-vertical` sets it to vertical -- unlike `split-horizontal`/`split-vertical`
|
||||
which wrap the window in a new container first.
|
||||
|
||||
## Moving Focus
|
||||
|
||||
Move keyboard focus between windows with the directional focus actions:
|
||||
|
||||
`alt-h` -- `focus-left`
|
||||
: Move focus left
|
||||
|
||||
`alt-j` -- `focus-down`
|
||||
: Move focus down
|
||||
|
||||
`alt-k` -- `focus-up`
|
||||
: Move focus up
|
||||
|
||||
`alt-l` -- `focus-right`
|
||||
: Move focus right
|
||||
|
||||
Focus crosses container boundaries, so you can navigate across your entire
|
||||
layout with these four keys.
|
||||
|
||||
## Moving Windows
|
||||
|
||||
Move the focused window within or between containers:
|
||||
|
||||
`alt-shift-h` -- `move-left`
|
||||
: Move window left
|
||||
|
||||
`alt-shift-j` -- `move-down`
|
||||
: Move window down
|
||||
|
||||
`alt-shift-k` -- `move-up`
|
||||
: Move window up
|
||||
|
||||
`alt-shift-l` -- `move-right`
|
||||
: Move window right
|
||||
|
||||
When a window reaches the edge of its container, the move action pushes it into
|
||||
the adjacent container.
|
||||
|
||||
## Focus Parent
|
||||
|
||||
Press `alt-f` (`focus-parent`) to move focus from a window to its parent
|
||||
container. This is useful when you want to operate on an entire group of
|
||||
windows at once. For example, focusing a parent container and then using
|
||||
`move-left` moves the whole group rather than a single window.
|
||||
|
||||
## Mono Mode
|
||||
|
||||
By default, a container shows all its children side by side. Mono mode changes
|
||||
this so only one child is visible at a time, similar to a tabbed view.
|
||||
|
||||
`alt-m` -- `toggle-mono`
|
||||
: Toggle between mono and side-by-side
|
||||
|
||||
You can also right-click any title in a container to toggle mono mode.
|
||||
|
||||
In mono mode, scroll over the title bar to cycle between windows in the
|
||||
container.
|
||||
|
||||
For explicit control without toggling:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-s = "show-single" # Enter mono mode
|
||||
alt-a = "show-all" # Exit mono mode
|
||||
```
|
||||
|
||||
## Fullscreen
|
||||
|
||||
Press `alt-u` (`toggle-fullscreen`) to make the focused window fill the entire
|
||||
output, hiding the bar and other windows. Press it again to return to the tiled
|
||||
layout.
|
||||
|
||||
For explicit control:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-u = "enter-fullscreen"
|
||||
alt-ctrl-u = "exit-fullscreen"
|
||||
```
|
||||
|
||||
## Resizing Tiles
|
||||
|
||||
Drag the separators between tiles with the mouse to resize them. The separator
|
||||
changes the cursor to a resize indicator when hovered.
|
||||
|
||||
In [window management mode](mouse.md#window-management-mode), you can also
|
||||
right-drag anywhere on a tile to resize it without needing to target the
|
||||
separator.
|
||||
|
||||
## Closing Windows
|
||||
|
||||
Press `alt-shift-c` (`close`) to request the focused window to close. This
|
||||
sends a polite close request to the application -- it is not a forceful kill.
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-shift-c = "close"
|
||||
```
|
||||
|
||||
## Toggling Floating
|
||||
|
||||
Double-click a tile's title bar to toggle it between tiled and floating. See
|
||||
[Floating Windows](floating.md) for more details.
|
||||
|
||||
## Summary of Tiling Actions
|
||||
|
||||
`split-horizontal`
|
||||
: Wrap focused window in a horizontal container
|
||||
|
||||
`split-vertical`
|
||||
: Wrap focused window in a vertical container
|
||||
|
||||
`toggle-split`
|
||||
: Toggle container split direction
|
||||
|
||||
`tile-horizontal`
|
||||
: Set container direction to horizontal
|
||||
|
||||
`tile-vertical`
|
||||
: Set container direction to vertical
|
||||
|
||||
`focus-left/right/up/down`
|
||||
: Move keyboard focus
|
||||
|
||||
`move-left/right/up/down`
|
||||
: Move focused window
|
||||
|
||||
`focus-parent`
|
||||
: Focus the parent container
|
||||
|
||||
`toggle-mono`
|
||||
: Toggle mono mode
|
||||
|
||||
`show-single`
|
||||
: Enter mono mode
|
||||
|
||||
`show-all`
|
||||
: Exit mono mode
|
||||
|
||||
`toggle-fullscreen`
|
||||
: Toggle fullscreen
|
||||
|
||||
`enter-fullscreen`
|
||||
: Enter fullscreen
|
||||
|
||||
`exit-fullscreen`
|
||||
: Exit fullscreen
|
||||
|
||||
`close`
|
||||
: Request focused window to close
|
||||
|
||||
`toggle-floating`
|
||||
: Toggle between tiled and floating
|
||||
315
book/src/troubleshooting.md
Normal file
315
book/src/troubleshooting.md
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
# Troubleshooting
|
||||
|
||||
## Jay doesn't start / black screen
|
||||
|
||||
Jay requires **at least one working renderer** -- without one, no GPU can be
|
||||
initialized and nothing will be displayed. It supports Vulkan (via libvulkan
|
||||
plus a GPU-specific driver) and OpenGL (via libEGL and libGLESv2). These
|
||||
libraries are loaded at runtime, not linked at build time. Vulkan is the
|
||||
primary renderer and should be used whenever possible; the OpenGL renderer is
|
||||
maintained only for backwards compatibility.
|
||||
|
||||
Check that the required libraries are installed:
|
||||
|
||||
```shell
|
||||
~$ ls /usr/lib/libEGL.so* /usr/lib/libGLESv2.so* /usr/lib/libvulkan.so* 2>/dev/null
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> On some distributions (e.g. Fedora, Debian), 64-bit libraries live in
|
||||
> `/usr/lib64/` or `/usr/lib/x86_64-linux-gnu/` instead.
|
||||
|
||||
If nothing is listed, install the appropriate packages. See the
|
||||
[Installation](installation.md) chapter for package names by distribution.
|
||||
|
||||
**Nvidia users:**
|
||||
|
||||
- You need **Linux 6.7 or later** for explicit sync support, which is required
|
||||
for Nvidia GPUs.
|
||||
- Make sure the Nvidia Vulkan ICD (Installable Client Driver) is installed.
|
||||
Jay's Vulkan renderer is the recommended option on Nvidia hardware.
|
||||
|
||||
## No applications open
|
||||
|
||||
The built-in default configuration binds:
|
||||
|
||||
- `Super_L` (left Windows key) -- open [Alacritty](https://alacritty.org/).
|
||||
- `alt-p` -- open [bemenu](https://github.com/Cloudef/bemenu) as an
|
||||
application launcher.
|
||||
|
||||
If neither application is installed, nothing will happen when you press these
|
||||
keys. Either install them or create a custom configuration with your preferred
|
||||
applications:
|
||||
|
||||
```shell
|
||||
~$ jay config init
|
||||
```
|
||||
|
||||
Then edit `~/.config/jay/config.toml` to change the terminal and launcher
|
||||
bindings.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> If you created a config file manually (e.g. by touching an empty file), it
|
||||
> will have **no shortcuts at all**. Jay replaces the entire built-in default
|
||||
> when any config file exists. Always use `jay config init` to start with a
|
||||
> working configuration.
|
||||
|
||||
## Application doesn't have access to a protocol
|
||||
|
||||
Jay splits Wayland protocols into unprivileged and privileged. By default,
|
||||
applications only have access to unprivileged protocols. If a program like a
|
||||
screen locker, status bar, clipboard manager, or screen-capture tool is not
|
||||
working, it likely needs access to one or more privileged protocols.
|
||||
|
||||
Common symptoms include:
|
||||
|
||||
- **swaylock** does nothing or fails to lock the screen (needs `session-lock`).
|
||||
- **waybar** or **i3bar** shows no workspace information (needs
|
||||
`foreign-toplevel-list`).
|
||||
- **wl-copy** / **cliphist** cannot access the clipboard (needs
|
||||
`data-control`).
|
||||
- **grim** or **slurp** cannot capture the screen (needs `screencopy`).
|
||||
|
||||
**Quick fix -- grant all privileges:**
|
||||
|
||||
The simplest approach is to launch the program with full access to all
|
||||
privileged protocols. In your config, set `privileged = true` in the exec
|
||||
action:
|
||||
|
||||
```toml
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Or from the command line:
|
||||
|
||||
```shell
|
||||
~$ jay run-privileged waybar
|
||||
```
|
||||
|
||||
**Better fix -- grant only the capabilities needed:**
|
||||
|
||||
Use a client rule to grant specific capabilities:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.comm = "waybar"
|
||||
capabilities = ["layer-shell", "foreign-toplevel-list"]
|
||||
```
|
||||
|
||||
See [Granting Privileges](window-rules.md#granting-privileges) for the full
|
||||
list of capabilities and more advanced approaches using connection tags.
|
||||
|
||||
## Wrong keyboard layout
|
||||
|
||||
The default keyboard layout is US QWERTY. To change it:
|
||||
|
||||
**Option 1 -- edit the config:**
|
||||
|
||||
```shell
|
||||
~$ jay config init
|
||||
```
|
||||
|
||||
Then edit the `keymap.rmlvo` section in `~/.config/jay/config.toml`:
|
||||
|
||||
```toml
|
||||
[keymap.rmlvo]
|
||||
layout = "de"
|
||||
```
|
||||
|
||||
**Option 2 -- change it at runtime:**
|
||||
|
||||
```shell
|
||||
~$ jay input seat default set-keymap-from-names -l de
|
||||
~$ jay input seat default set-keymap-from-names -l us -v intl
|
||||
```
|
||||
|
||||
This takes effect immediately but does not persist across restarts unless
|
||||
configured in the config file.
|
||||
|
||||
## Screen sharing doesn't work
|
||||
|
||||
Screen sharing requires PipeWire and the Jay desktop portal.
|
||||
|
||||
**1. Check that PipeWire is running:**
|
||||
|
||||
```shell
|
||||
~$ systemctl --user status pipewire
|
||||
```
|
||||
|
||||
If it is not running, start it:
|
||||
|
||||
```shell
|
||||
~$ systemctl --user start pipewire
|
||||
```
|
||||
|
||||
**2. Check that the portal files are installed:**
|
||||
|
||||
Jay needs two files to be found by the XDG desktop portal framework:
|
||||
|
||||
- A portal definition file (e.g. `/usr/share/xdg-desktop-portal/portals/jay.portal`).
|
||||
- A portal configuration file (e.g. `/usr/share/xdg-desktop-portal/jay-portals.conf`).
|
||||
|
||||
These files are included in the Jay repository under `etc/`. If you built Jay
|
||||
from source and did not install them, copy them manually:
|
||||
|
||||
```shell
|
||||
~$ sudo cp etc/jay.portal /usr/share/xdg-desktop-portal/portals/
|
||||
~$ sudo cp etc/jay-portals.conf /usr/share/xdg-desktop-portal/
|
||||
```
|
||||
|
||||
**3. Restart the portal:**
|
||||
|
||||
```shell
|
||||
~$ systemctl --user restart xdg-desktop-portal
|
||||
```
|
||||
|
||||
See the [Screen Sharing](screen-sharing.md) chapter for more details.
|
||||
|
||||
## X11 applications don't work
|
||||
|
||||
Jay uses Xwayland to run X11 applications.
|
||||
|
||||
**1. Install Xwayland:**
|
||||
|
||||
- Arch Linux: `sudo pacman -S xorg-xwayland`
|
||||
- Fedora: `sudo dnf install xorg-x11-server-Xwayland`
|
||||
- Debian/Ubuntu: `sudo apt install xwayland`
|
||||
|
||||
**2. Check your configuration:**
|
||||
|
||||
If you have a config file, make sure Xwayland is not explicitly disabled:
|
||||
|
||||
```toml
|
||||
[xwayland]
|
||||
# Make sure this is not set to false:
|
||||
# enabled = false
|
||||
```
|
||||
|
||||
Xwayland is enabled by default. You can also check its status at runtime:
|
||||
|
||||
```shell
|
||||
~$ jay xwayland status
|
||||
```
|
||||
|
||||
## Display manager doesn't show Jay
|
||||
|
||||
**1. Check that the session file exists:**
|
||||
|
||||
```shell
|
||||
~$ ls /usr/share/wayland-sessions/jay.desktop
|
||||
```
|
||||
|
||||
If it does not exist, create it:
|
||||
|
||||
```shell
|
||||
~$ sudo tee /usr/share/wayland-sessions/jay.desktop > /dev/null << 'EOF'
|
||||
[Desktop Entry]
|
||||
Name=Jay
|
||||
Comment=A Wayland Compositor
|
||||
Exec=jay run
|
||||
Type=Application
|
||||
DesktopNames=jay
|
||||
EOF
|
||||
```
|
||||
|
||||
**2. Check that `jay` is in the system PATH:**
|
||||
|
||||
If you installed Jay via `cargo install`, the binary is at `~/.cargo/bin/jay`.
|
||||
Display managers typically do not include `~/.cargo/bin` in their PATH. Either:
|
||||
|
||||
- Add `~/.cargo/bin` to the system PATH, or
|
||||
- Create a symlink:
|
||||
|
||||
```shell
|
||||
~$ sudo ln -s ~/.cargo/bin/jay /usr/local/bin/jay
|
||||
```
|
||||
|
||||
## How to check logs
|
||||
|
||||
Open the log file in a pager:
|
||||
|
||||
```shell
|
||||
~$ jay log
|
||||
```
|
||||
|
||||
Follow the log in real time (like `tail -f`):
|
||||
|
||||
```shell
|
||||
~$ jay log -f
|
||||
```
|
||||
|
||||
Print just the log file path:
|
||||
|
||||
```shell
|
||||
~$ jay log --path
|
||||
```
|
||||
|
||||
Increase log verbosity at runtime:
|
||||
|
||||
```shell
|
||||
~$ jay set-log-level debug
|
||||
```
|
||||
|
||||
To set the log level at startup, add it to your config:
|
||||
|
||||
```toml
|
||||
log-level = "debug"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The `log-level` config setting is read at startup and cannot be changed by
|
||||
> reloading the configuration. Use `jay set-log-level` for runtime changes.
|
||||
|
||||
## Performance issues
|
||||
|
||||
If you experience dropped frames, stuttering, or high latency, try the
|
||||
following:
|
||||
|
||||
**1. Use the Vulkan renderer:**
|
||||
|
||||
The Vulkan renderer is generally faster and supports more features (e.g. HDR,
|
||||
direct scanout). Check your current API and switch if needed:
|
||||
|
||||
```shell
|
||||
~$ jay randr show
|
||||
~$ jay randr card card0 api vulkan
|
||||
```
|
||||
|
||||
**2. Set `CAP_SYS_NICE`:**
|
||||
|
||||
Granting `CAP_SYS_NICE` allows Jay to use real-time scheduling and high-priority
|
||||
Vulkan queues, which improves responsiveness under load:
|
||||
|
||||
```shell
|
||||
~$ sudo setcap cap_sys_nice=p $(which jay)
|
||||
```
|
||||
|
||||
> You need to re-run this command each time you update the Jay binary.
|
||||
|
||||
**3. Adjust the flip margin:**
|
||||
|
||||
The flip margin controls the time between initiating a page flip and the
|
||||
display's vblank. A smaller margin reduces input latency but risks missed
|
||||
frames. The default is 1.5 ms:
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 timing set-flip-margin 1.5
|
||||
```
|
||||
|
||||
If you see missed frames, try increasing it. If you want lower latency, try
|
||||
decreasing it -- Jay will dynamically increase it if the margin is too small.
|
||||
|
||||
**4. Enable direct scanout:**
|
||||
|
||||
Direct scanout allows fullscreen applications to bypass the compositor's
|
||||
rendering pipeline entirely, reducing both latency and GPU usage:
|
||||
|
||||
```shell
|
||||
~$ jay randr card card0 direct-scanout enable
|
||||
```
|
||||
529
book/src/window-rules.md
Normal file
529
book/src/window-rules.md
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
# Window & Client Rules
|
||||
|
||||
Jay supports powerful, reactive rules for controlling how clients connect and
|
||||
how windows behave. Rules are defined in the `[[clients]]` and `[[windows]]`
|
||||
arrays in your configuration file.
|
||||
|
||||
## Client Rules
|
||||
|
||||
Client rules operate on Wayland clients (processes). They are defined with
|
||||
`[[clients]]` entries:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.exe = "/usr/bin/firefox"
|
||||
action = { type = "exec", exec = ["notify-send", "Firefox connected"] }
|
||||
```
|
||||
|
||||
### Structure
|
||||
|
||||
Each client rule can have the following fields:
|
||||
|
||||
`name`
|
||||
: A name for cross-referencing this rule from other rules.
|
||||
|
||||
`match`
|
||||
: A `ClientMatch` specifying which clients this rule applies to.
|
||||
|
||||
`action`
|
||||
: An action to run when a client starts matching.
|
||||
|
||||
`latch`
|
||||
: An action to run when a client stops matching.
|
||||
|
||||
`capabilities`
|
||||
: Wayland protocol access granted to matching clients.
|
||||
|
||||
`sandbox-bounding-capabilities`
|
||||
: Upper bounds for protocols available to child sandboxes.
|
||||
|
||||
### Client Match Criteria
|
||||
|
||||
All client match criteria are constant over the lifetime of a client. If no
|
||||
fields are set, all clients are matched. If multiple fields are set, they are
|
||||
implicitly AND-combined.
|
||||
|
||||
`sandboxed`
|
||||
: Whether the client is sandboxed (`true`/`false`).
|
||||
|
||||
`sandbox-engine` / `sandbox-engine-regex`
|
||||
: The sandbox engine (e.g. `org.flatpak`).
|
||||
|
||||
`sandbox-app-id` / `sandbox-app-id-regex`
|
||||
: The app ID provided by the sandbox.
|
||||
|
||||
`sandbox-instance-id` / `sandbox-instance-id-regex`
|
||||
: The instance ID from the sandbox.
|
||||
|
||||
`uid`
|
||||
: The user ID of the client.
|
||||
|
||||
`pid`
|
||||
: The process ID of the client.
|
||||
|
||||
`is-xwayland`
|
||||
: Whether the client is Xwayland (`true`/`false`).
|
||||
|
||||
`comm` / `comm-regex`
|
||||
: The client's `/proc/pid/comm` value.
|
||||
|
||||
`exe` / `exe-regex`
|
||||
: The client's `/proc/pid/exe` path.
|
||||
|
||||
`tag` / `tag-regex`
|
||||
: The connection tag of the client.
|
||||
|
||||
### Granting Privileges
|
||||
|
||||
Jay splits Wayland protocols into unprivileged and privileged. By default,
|
||||
applications only have access to unprivileged protocols. This means that tools
|
||||
like screen lockers, status bars, screen-capture utilities, and clipboard
|
||||
managers will not work unless you explicitly grant them the necessary
|
||||
privileges.
|
||||
|
||||
See the [Protocol Support](features.md#protocol-support) table in the Features
|
||||
chapter for the full list of protocols and whether they are privileged.
|
||||
|
||||
There are three ways to grant privileges, from simplest to most fine-grained.
|
||||
|
||||
#### 1. Grant all privileges via `privileged = true` (exec) or `jay run-privileged`
|
||||
|
||||
The simplest approach gives a program access to **all** privileged protocols.
|
||||
This is appropriate for trusted tools like screen lockers where you don't want
|
||||
to think about which specific protocols they need.
|
||||
|
||||
In the config, set `privileged = true` in the exec table:
|
||||
|
||||
```toml
|
||||
on-idle = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "swaylock",
|
||||
privileged = true,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
From the command line, use `jay run-privileged`:
|
||||
|
||||
```shell
|
||||
~$ jay run-privileged waybar
|
||||
```
|
||||
|
||||
Both methods connect the program to a privileged Wayland socket that grants
|
||||
access to all privileged protocols.
|
||||
|
||||
#### 2. Grant capabilities via connection tags
|
||||
|
||||
Connection tags let you combine the CLI with client rules for precise control.
|
||||
You tag a program at launch time, then write a client rule that matches
|
||||
the tag and grants specific capabilities.
|
||||
|
||||
First, launch the program with a tag -- either from the command line:
|
||||
|
||||
```shell
|
||||
~$ jay run-tagged bar waybar
|
||||
```
|
||||
|
||||
Or from the config using the `tag` field in an exec action:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-w = {
|
||||
type = "exec",
|
||||
exec = {
|
||||
prog = "waybar",
|
||||
tag = "bar",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Then write a client rule that matches the tag and grants capabilities:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.tag = "bar"
|
||||
capabilities = ["layer-shell", "foreign-toplevel-list"]
|
||||
```
|
||||
|
||||
This way, only the specific instance you launched with the tag receives the
|
||||
privileges -- other programs with the same binary name do not.
|
||||
|
||||
Available capability values: `none`, `all`, `data-control`,
|
||||
`virtual-keyboard`, `foreign-toplevel-list`, `idle-notifier`, `session-lock`,
|
||||
`layer-shell`, `screencopy`, `seat-manager`, `drm-lease`, `input-method`,
|
||||
`workspace-manager`, `foreign-toplevel-manager`, `head-manager`,
|
||||
`gamma-control-manager`, `virtual-pointer`.
|
||||
|
||||
**Default capabilities:** unsandboxed clients receive `layer-shell` and
|
||||
`drm-lease`. Sandboxed clients receive only `drm-lease`. If any client rule
|
||||
matches, its capabilities **replace** the defaults entirely. If multiple rules
|
||||
match, their capabilities are unioned together, but the defaults are not
|
||||
included unless a matching rule also grants them.
|
||||
|
||||
#### 3. Grant capabilities via client match rules
|
||||
|
||||
Client rules can also match programs by properties like their executable name
|
||||
instead of a tag. This is convenient when you always want a given program to
|
||||
have certain capabilities, regardless of how it was launched:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.comm = "waybar"
|
||||
capabilities = ["layer-shell", "foreign-toplevel-list"]
|
||||
|
||||
# Vim 9.2 uses the data-control protocol for seamless wayland integration.
|
||||
[[clients]]
|
||||
match.comm = "vim"
|
||||
match.sandboxed = false
|
||||
capabilities = "data-control"
|
||||
|
||||
# Older versions use wl-copy and wl-paste.
|
||||
[[clients]]
|
||||
match.any = [
|
||||
{ comm = "wl-copy" },
|
||||
{ comm = "wl-paste" },
|
||||
]
|
||||
match.sandboxed = false
|
||||
capabilities = "data-control"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Client match criteria like `comm`, `exe`, and `pid` are checked when a
|
||||
> client connects. Any process with a matching name receives the specified
|
||||
> capabilities. If you need to restrict privileges to programs you launch
|
||||
> yourself, use connection tags (method 2) instead.
|
||||
|
||||
#### Bounding capabilities (sandboxes)
|
||||
|
||||
Capabilities can never exceed the client's **bounding capabilities**. Use
|
||||
`sandbox-bounding-capabilities` on a client rule to set the upper bound for
|
||||
protocols available to sandboxes created by that client:
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.comm = "flatpak-portal"
|
||||
sandbox-bounding-capabilities = ["drm-lease", "layer-shell"]
|
||||
```
|
||||
|
||||
## Window Rules
|
||||
|
||||
Window rules operate on individual windows. They are defined with `[[windows]]`
|
||||
entries:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.app-id = "org.gnome.Nautilus"
|
||||
initial-tile-state = "floating"
|
||||
```
|
||||
|
||||
### Structure
|
||||
|
||||
Each window rule can have the following fields:
|
||||
|
||||
`name`
|
||||
: A name for cross-referencing this rule from other rules.
|
||||
|
||||
`match`
|
||||
: A `WindowMatch` specifying which windows this rule applies to.
|
||||
|
||||
`action`
|
||||
: An action to run when a window starts matching.
|
||||
|
||||
`latch`
|
||||
: An action to run when a window stops matching.
|
||||
|
||||
`initial-tile-state`
|
||||
: `"floating"` or `"tiled"` -- force the initial tile state.
|
||||
|
||||
`auto-focus`
|
||||
: `true`/`false` -- whether the window gets focus on map. Without a matching
|
||||
rule, newly mapped windows always receive focus (except for Xwayland
|
||||
override-redirect windows such as menus and tooltips, which bypass the
|
||||
normal mapping path).
|
||||
|
||||
The `initial-tile-state` and `auto-focus` fields are **ad-hoc properties**.
|
||||
They are evaluated synchronously during the mapping process (before the window
|
||||
is first displayed), unlike `action` which runs asynchronously after mapping.
|
||||
If multiple rules match and any sets `auto-focus` to `false`, the window will
|
||||
not be focused.
|
||||
|
||||
### Window Match Criteria
|
||||
|
||||
If no fields are set, all windows are matched. If multiple fields are set, they
|
||||
are implicitly AND-combined. Without a `types` criterion, rules only match
|
||||
client-created windows (XDG toplevels and X windows).
|
||||
|
||||
`types`
|
||||
: Window type mask: `none`, `any`, `container`, `xdg-toplevel`, `x-window`, `client-window`.
|
||||
|
||||
`client`
|
||||
: A nested `ClientMatch` -- matches the window's owning client.
|
||||
|
||||
`title` / `title-regex`
|
||||
: The window title.
|
||||
|
||||
`app-id` / `app-id-regex`
|
||||
: The XDG app ID.
|
||||
|
||||
`floating`
|
||||
: Whether the window is floating.
|
||||
|
||||
`visible`
|
||||
: Whether the window is visible.
|
||||
|
||||
`urgent`
|
||||
: Whether the window has the urgency flag.
|
||||
|
||||
`focused`
|
||||
: Whether the window has keyboard focus.
|
||||
|
||||
`fullscreen`
|
||||
: Whether the window is fullscreen.
|
||||
|
||||
`just-mapped`
|
||||
: `true` for one compositor iteration after the window maps.
|
||||
|
||||
`tag` / `tag-regex`
|
||||
: The XDG toplevel tag.
|
||||
|
||||
`x-class` / `x-class-regex`
|
||||
: The X11 class (X windows only).
|
||||
|
||||
`x-instance` / `x-instance-regex`
|
||||
: The X11 instance (X windows only).
|
||||
|
||||
`x-role` / `x-role-regex`
|
||||
: The X11 role (X windows only).
|
||||
|
||||
`workspace` / `workspace-regex`
|
||||
: The workspace the window is on.
|
||||
|
||||
`content-types`
|
||||
: Content type mask: `none`, `any`, `photo`, `video`, `game`.
|
||||
|
||||
## Combining Criteria
|
||||
|
||||
All match objects (both `ClientMatch` and `WindowMatch`) support the same
|
||||
logical combinators.
|
||||
|
||||
### AND (Multiple Fields)
|
||||
|
||||
Multiple fields in one match table are implicitly AND-combined:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.title = "VIM"
|
||||
match.app-id = "Alacritty"
|
||||
```
|
||||
|
||||
This matches only windows whose title is `VIM` **and** whose app ID is
|
||||
`Alacritty`.
|
||||
|
||||
### OR (Array of Matchers)
|
||||
|
||||
An array of match objects matches if **any** element matches:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.any = [
|
||||
{ title = "chromium" },
|
||||
{ title = "spotify" },
|
||||
]
|
||||
```
|
||||
|
||||
### NOT (Negation)
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.not.title = "firefox"
|
||||
```
|
||||
|
||||
### ALL (Explicit AND)
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.all = [
|
||||
{ title-regex = "chro" },
|
||||
{ title-regex = "mium" },
|
||||
]
|
||||
```
|
||||
|
||||
### EXACTLY (N of M)
|
||||
|
||||
Match if exactly N of the listed criteria match:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.exactly.num = 1
|
||||
match.exactly.list = [
|
||||
{ title = "VIM" },
|
||||
{ client.sandboxed = true },
|
||||
]
|
||||
```
|
||||
|
||||
### Cross-referencing Rules by Name
|
||||
|
||||
Rules can reference other rules by name:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
name = "spotify-windows"
|
||||
match.client.sandbox-app-id = "com.spotify.Client"
|
||||
|
||||
[[windows]]
|
||||
match.name = "spotify-windows"
|
||||
action = "enter-fullscreen"
|
||||
```
|
||||
|
||||
## Reactive Behavior
|
||||
|
||||
Rules are **re-evaluated dynamically** whenever any referenced criterion
|
||||
changes. For example, if a rule matches on `title`, it is re-checked every time
|
||||
the window title changes.
|
||||
|
||||
- **`action`** fires each time a window transitions from not-matching to
|
||||
matching.
|
||||
- **`latch`** fires each time a window transitions from matching to
|
||||
not-matching.
|
||||
|
||||
### just-mapped
|
||||
|
||||
If you only want a rule to fire once when a window first appears, add
|
||||
`just-mapped = true` to the match:
|
||||
|
||||
```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.
|
||||
|
||||
### Loop Protection
|
||||
|
||||
Rules can trigger each other. For example, one rule could fullscreen a window
|
||||
while another exits fullscreen on the same condition, creating a loop. Jay
|
||||
prevents such loops from locking up the compositor by capping action callbacks
|
||||
at 1000 iterations before yielding to other work. However, such loops will
|
||||
still cause 100% CPU usage and will likely cause affected clients to be killed,
|
||||
since they won't be able to receive Wayland messages fast enough.
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### Force an App to Start Floating
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.app-id = "pavucontrol"
|
||||
initial-tile-state = "floating"
|
||||
```
|
||||
|
||||
### Move a Specific App to a Workspace
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.client.sandbox-app-id = "com.spotify.Client"
|
||||
action = { type = "move-to-workspace", name = "3" }
|
||||
```
|
||||
|
||||
### Float Splash Screens Without Stealing Focus
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.any = [
|
||||
{ title = "GIMP Startup", app-id = "gimp" },
|
||||
{
|
||||
title = "splash",
|
||||
x-class-regex = "^jetbrains-(clion|rustrover)$",
|
||||
},
|
||||
]
|
||||
initial-tile-state = "floating"
|
||||
auto-focus = false
|
||||
```
|
||||
|
||||
### Run a Command When a Window Appears
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.app-id = "firefox"
|
||||
match.just-mapped = true
|
||||
action = {
|
||||
type = "exec",
|
||||
exec = ["notify-send", "Firefox window opened"],
|
||||
}
|
||||
```
|
||||
|
||||
### Grant Protocol Access to a Trusted App
|
||||
|
||||
```toml
|
||||
[[clients]]
|
||||
match.comm = "swaylock"
|
||||
capabilities = ["session-lock", "layer-shell"]
|
||||
|
||||
[[clients]]
|
||||
match.comm = "waybar"
|
||||
capabilities = ["layer-shell", "foreign-toplevel-list"]
|
||||
```
|
||||
|
||||
### Suppress Focus Stealing for Chromium Screen-Share Windows
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.title-regex = 'is sharing (your screen|a window)\.$'
|
||||
match.client.comm = "chromium"
|
||||
initial-tile-state = "floating"
|
||||
auto-focus = false
|
||||
```
|
||||
|
||||
## Introspection
|
||||
|
||||
Jay provides several ways to discover the property values you need for writing
|
||||
rules.
|
||||
|
||||
### jay tree
|
||||
|
||||
Interactively select a window and print its properties:
|
||||
|
||||
```shell
|
||||
~$ jay tree query select-window
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```text
|
||||
- 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
|
||||
```
|
||||
|
||||
### jay clients
|
||||
|
||||
Inspect the client owning a window:
|
||||
|
||||
```shell
|
||||
~$ jay clients show select-window
|
||||
```
|
||||
|
||||
### Control Center Window Search
|
||||
|
||||
The control center (opened with `alt-c` by default, or `jay control-center`)
|
||||
includes a **Window Search** pane where you can search and filter windows using
|
||||
composable criteria -- helpful for experimenting with match expressions before
|
||||
putting them in your config.
|
||||
|
||||
See [spec.generated.md](https://github.com/mahkoh/jay/blob/master/toml-spec/spec/spec.generated.md) for the full
|
||||
specification of `WindowRule`, `WindowMatch`, `ClientRule`, `ClientMatch`, and
|
||||
all available actions.
|
||||
157
book/src/workspaces.md
Normal file
157
book/src/workspaces.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# Workspaces
|
||||
|
||||
Workspaces are virtual desktops that group windows together. Each workspace
|
||||
lives on an output (monitor) and contains its own tiling layout. Jay creates
|
||||
workspaces on demand and automatically manages them when monitors are connected
|
||||
or disconnected.
|
||||
|
||||
## Switching Workspaces
|
||||
|
||||
Use the `show-workspace` action to switch to a workspace. In the default
|
||||
configuration, `alt-F1` through `alt-F12` switch to workspaces named "1"
|
||||
through "12":
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F1 = { type = "show-workspace", name = "1" }
|
||||
alt-F2 = { type = "show-workspace", name = "2" }
|
||||
alt-F3 = { type = "show-workspace", name = "3" }
|
||||
# ... and so on through alt-F12
|
||||
```
|
||||
|
||||
If the workspace does not yet exist, it is created on the output that currently
|
||||
contains the cursor. You can override this by specifying an output:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-F1 = {
|
||||
type = "show-workspace",
|
||||
name = "1",
|
||||
output.name = "left",
|
||||
}
|
||||
```
|
||||
|
||||
You can also scroll over the bar to cycle through workspaces on that output.
|
||||
|
||||
## Moving Windows to Workspaces
|
||||
|
||||
Use the `move-to-workspace` action to send the focused window to a different
|
||||
workspace. The default bindings are `alt-shift-F1` through `alt-shift-F12`:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
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" }
|
||||
# ... and so on through alt-shift-F12
|
||||
```
|
||||
|
||||
You can also drag a tile's title onto a workspace tab in the bar to move it to
|
||||
that workspace. Dragging a tile onto the bar outside any workspace tab creates a
|
||||
new workspace for it.
|
||||
|
||||
## Moving Workspaces Between Outputs
|
||||
|
||||
The `move-to-output` action moves a workspace to a different output. You can
|
||||
target the output by name or by direction:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
# Move the current workspace to a named output
|
||||
alt-o = { type = "move-to-output", output.name = "right" }
|
||||
|
||||
# Move the current workspace in a direction
|
||||
logo-ctrl-shift-Right = {
|
||||
type = "move-to-output",
|
||||
direction = "right",
|
||||
}
|
||||
logo-ctrl-shift-Left = {
|
||||
type = "move-to-output",
|
||||
direction = "left",
|
||||
}
|
||||
logo-ctrl-shift-Up = {
|
||||
type = "move-to-output",
|
||||
direction = "up",
|
||||
}
|
||||
logo-ctrl-shift-Down = {
|
||||
type = "move-to-output",
|
||||
direction = "down",
|
||||
}
|
||||
```
|
||||
|
||||
You can also move a specific workspace by name:
|
||||
|
||||
```toml
|
||||
[shortcuts]
|
||||
alt-o = {
|
||||
type = "move-to-output",
|
||||
workspace = "1",
|
||||
output.name = "right",
|
||||
}
|
||||
```
|
||||
|
||||
If `workspace` is omitted, the currently active workspace is moved.
|
||||
|
||||
## Workspace Display Order
|
||||
|
||||
Workspaces appear as tabs in the bar. Their order can be configured in two
|
||||
modes:
|
||||
|
||||
- **manual** (default) -- workspaces appear in the order they were created and
|
||||
can be reordered by dragging their titles in the bar.
|
||||
- **sorted** -- workspaces are sorted alphabetically. Dragging to reorder is
|
||||
disabled.
|
||||
|
||||
Set the order in your configuration:
|
||||
|
||||
```toml
|
||||
workspace-display-order = "sorted"
|
||||
```
|
||||
|
||||
You can also change this at runtime in the control center.
|
||||
|
||||
## Hot-Plug and Hot-Unplug
|
||||
|
||||
Jay handles monitor connections gracefully:
|
||||
|
||||
- When a monitor is **unplugged**, its workspaces are automatically migrated to
|
||||
one of the remaining monitors.
|
||||
- When the monitor is **plugged back in**, those workspaces are restored to it.
|
||||
|
||||
This means you never lose your workspace layout when docking or undocking a
|
||||
laptop.
|
||||
|
||||
## Workspace Capture
|
||||
|
||||
By default, newly created workspaces can be captured for screen sharing. You
|
||||
can disable this globally:
|
||||
|
||||
```toml
|
||||
workspace-capture = false
|
||||
```
|
||||
|
||||
When workspace capture is enabled, screen-sharing applications can share
|
||||
individual workspaces (in addition to full outputs and individual windows). See
|
||||
[Screen Sharing](screen-sharing.md) for more details.
|
||||
|
||||
## Matching Windows by Workspace
|
||||
|
||||
In [window rules](window-rules.md), you can match windows based on the
|
||||
workspace they are on:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.workspace = "music"
|
||||
action = "enter-fullscreen"
|
||||
```
|
||||
|
||||
The `workspace-regex` field is also available for pattern matching:
|
||||
|
||||
```toml
|
||||
[[windows]]
|
||||
match.workspace-regex = "^(music|video)$"
|
||||
action = "enter-fullscreen"
|
||||
```
|
||||
|
||||
Since window rules are reactive, these rules are re-evaluated whenever a window
|
||||
moves to a different workspace.
|
||||
Loading…
Add table
Add a link
Reference in a new issue