1
0
Fork 0
forked from wry/wry

all: split reusable components into workspace crates

This commit is contained in:
kossLAN 2026-05-29 09:14:53 -04:00
parent 2a079ed800
commit 657e7ce2f7
No known key found for this signature in database
225 changed files with 7422 additions and 17602 deletions

View file

@ -35,7 +35,6 @@
- [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

View file

@ -674,18 +674,6 @@ Show color management status:
## Other Commands
### `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,
@ -697,24 +685,6 @@ tablet, and switch events to stdout:
~$ 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:

View file

@ -62,16 +62,10 @@ 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
@ -80,7 +74,6 @@ on-idle = [
type = "exec",
exec = {
prog = "swaylock",
privileged = true,
},
},
{ type = "exec", exec = ["notify-send", "System locked"] },
@ -100,7 +93,6 @@ on-idle = {
type = "exec",
exec = {
prog = "swaylock",
privileged = true,
},
}
```

View file

@ -30,9 +30,8 @@ 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.
emulate input events. Setting `enable-socket` exposes an unauthenticated socket
that any application can use.
```toml
libei.enable-socket = false # default

View file

@ -145,7 +145,6 @@ alt-shift-r = "reload-config-toml"
(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.
@ -309,7 +308,6 @@ alt-s = {
type = "exec",
exec = {
shell = "grim - | wl-copy",
privileged = true,
},
}
```
@ -328,12 +326,6 @@ Table fields:
`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`:
@ -362,7 +354,6 @@ Print = {
type = "exec",
exec = {
shell = "grim - | wl-copy",
privileged = true,
},
}
```

View file

@ -63,15 +63,10 @@ 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)):
@ -83,7 +78,6 @@ on-idle = {
type = "exec",
exec = {
prog = "swaylock",
privileged = true,
},
}
```
@ -97,7 +91,6 @@ on-idle = [
type = "exec",
exec = {
prog = "swaylock",
privileged = true,
},
},
]

View file

@ -73,7 +73,7 @@ The available color keys in the `[theme]` table are:
"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).
when a window is being captured.
### Example

View file

@ -87,5 +87,5 @@ Xwayland client itself:
```toml
[[clients]]
match.is-xwayland = true
# ... grant capabilities, etc.
# ... configure client-specific behavior
```

View file

@ -61,10 +61,7 @@ Commands:
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
@ -101,17 +98,6 @@ 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.
@ -154,20 +140,6 @@ Jay supports running X11 applications seamlessly through Xwayland. See
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

View file

@ -63,7 +63,6 @@ For Vulkan, you also need the driver for your GPU:
- **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
@ -129,14 +128,7 @@ 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`.
### SCHED_RR
You can also skip `SCHED_RR` explicitly by setting `JAY_NO_REALTIME=1`:
@ -144,11 +136,7 @@ You can also skip `SCHED_RR` explicitly by setting `JAY_NO_REALTIME=1`:
~$ 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`.
This still allows elevated Vulkan queues.
## Recommended Applications
@ -156,7 +144,6 @@ 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`).

View file

@ -22,12 +22,11 @@
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.
variable refresh rate (VRR), tearing presentation, and HDR. 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 comprehensive
command-line interface makes scripting and automation straightforward.
Jay is configured through a declarative TOML file. 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.

View file

@ -84,8 +84,8 @@ This is especially useful for:
## 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
**Toplevel selection.** Some actions 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

View file

@ -1,111 +0,0 @@
# 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`

View file

@ -54,57 +54,6 @@ bindings.
> 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:
@ -132,45 +81,6 @@ layout = "de"
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.

View file

@ -31,12 +31,6 @@ Each client rule can have the following fields:
`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
@ -70,142 +64,6 @@ implicitly AND-combined.
`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]]`
@ -456,18 +314,6 @@ action = {
}
```
### 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

View file

@ -123,16 +123,15 @@ laptop.
## Workspace Capture
By default, newly created workspaces can be captured for screen sharing. You
can disable this globally:
By default, newly created workspaces can be captured by capture clients. 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.
When workspace capture is enabled, compositor-native capture clients may capture
individual workspaces instead of whole outputs.
## Matching Windows by Workspace