No description
Find a file
GoranKovac 645ca1125b
Detect WM_HINTS popup (yabridge popups fix) (#328)
* Detect WM_HINTS popup (yabridge popups fix)

Many windows popups have:

WM_HINTS(WM_HINTS) Client accepts input or input focus: False

Which is a good indicator window SHOULD be a popup.

This is true for example on yabridge plugins and some other apps.
However toplevel windows have this property True. In order to
differentiate them we check if there are no decorations on the window
(client) and this property is False.
Its applied ONLY to _NET_WM_WINDOW_TYPE_NORMAL windows since its most
generic one that comes up.

This was tested across many apps: Reaper, Ardour, Godot, MaterialMaker,
PixelOver, PixelComposer, Steam, Steam games (both windowed and
fullscreen), Fusion 9, Unity and others I have.

There are no regression seen in any of tested apps and fixes yabridge
popups.
Additionally check if MOTIF has functions that should not be in popup
Combine wmhint popup check with skip_taskbar.
wmhint is only considered to be a popup if application has skip_taskbar
atom.
Fixed edgecases so far:
BattleNet spawning as popupp
PixelComposer spawning as popup
2026-01-18 11:31:17 -05:00
.cargo tests: preset RUST_TEST_THREADS to 1 2025-11-09 23:04:09 -05:00
.github Create FUNDING.yml 2025-08-30 12:08:06 -04:00
macros fix: properly specify subprojects' required features 2025-08-30 12:03:45 -04:00
resources Document systemd support and add example service file 2024-07-07 15:55:24 -04:00
src Detect WM_HINTS popup (yabridge popups fix) (#328) 2026-01-18 11:31:17 -05:00
tests Detect WM_HINTS popup (yabridge popups fix) (#328) 2026-01-18 11:31:17 -05:00
testwl test: while dragging, check set_window_dims calls == 1 2025-12-16 20:31:56 -05:00
wl_drm Set input focus on windows without WM_HINTS input flag 2024-05-20 01:26:06 -04:00
.gitignore Initial commit 2024-04-29 00:30:06 -04:00
ARCHITECTURE.md Add ARCHITECTURE.md 2025-04-16 23:32:18 -04:00
build.rs Add git revision to log 2025-05-28 23:10:53 -04:00
Cargo.lock deps: bump xcb to 1.7.0 2026-01-08 23:29:13 -05:00
Cargo.toml deps: bump xcb to 1.7.0 2026-01-08 23:29:13 -05:00
flake.lock Update flake.lock to nixpkgs 25.11 2025-12-02 19:17:55 -05:00
flake.nix Update nixpkgs from 25.05 to 25.11 2025-12-02 01:11:10 -05:00
LICENSE Initial commit 2024-04-29 00:30:06 -04:00
OpenSans-Regular.ttf Add client side decorations to toplevels 2025-11-06 22:32:10 -05:00
README.md Document _JAVA_AWT_WM_NONREPARENTING 2025-09-02 23:11:56 -04:00

xwayland-satellite

xwayland-satellite grants rootless Xwayland integration to any Wayland compositor implementing xdg_wm_base and viewporter. This is particularly useful for compositors that (understandably) do not want to go through implementing support for rootless Xwayland themselves.

Found a bug? Open a bug report.

Need help troubleshooting, or have some other general question? Ask on GitHub Discussions.

Dependencies

  • Xwayland >=23.1
  • xcb
  • xcb-util-cursor
  • clang (building only)

Usage

Run xwayland-satellite. You can specify an X display to use (i.e. :12). Be sure to set the same DISPLAY environment variable for any X11 clients. Because xwayland-satellite is a Wayland client (in addition to being a Wayland compositor), it will need to launch after your compositor launches, but obviously before any X11 applications.

Java applications

Some (most?) Java applications may present themselves as a blank screen by default with satellite. To fix this, simply set the environment variable _JAVA_AWT_WM_NONREPARENTING=1 before launching it to fix this. Unfortunately there is not a way for satellite to automatically do this.

Building

# dev build
cargo build
# release build
cargo build --release

# run - will also build if not already built
cargo run # --release

Systemd support

xwayland-satellite can be built with systemd support - simply add -F systemd to your build command - i.e. cargo build --release -F systemd.

With systemd support, satellite will send a state change notification when Xwayland has been initialized, allowing for having services dependent on satellite's startup.

An example service file is located in resources/xwayland-satellite.service - be sure to replace the ExecStart line with the proper location before using it. It can be placed in a systemd user unit directory (i.e. $XDG_CONFIG_HOME/systemd/user or /etc/systemd/user), and be launched and enabled with systemctl --user enable --now xwayland-satellite. It will be started when the graphical-session.target is reached, which is likely after your compositor is started if it supports systemd.

Scaling/HiDPI

For most GTK and Qt apps, xwayland-satellite should automatically scale them properly. Note that for mixed DPI monitor setups, satellite will choose the smallest monitor's DPI, meaning apps may have small text on other monitors.

Other miscellaneous apps (such as Wine apps) may have small text on HiDPI displays. It is application dependent on getting apps to scale properly with satellite, so you will have to figure out what app specific config needs to be set. See the Arch Wiki on HiDPI for a good place start.

Satellite acts as an Xsettings manager for setting scaling related settings, but will get out of the way of other Xsettings managers. To manually set these settings, try xsettingsd or another Xsettings manager.

Wayland protocols used

The host compositor must implement the following protocols/interfaces for satellite to function:

  • Core interfaces (wl_output, wl_surface, wl_compositor, etc)
  • xdg_shell (xdg_wm_base, xdg_surface, xdg_popup, xdg_toplevel)
  • wp_viewporter - used for scaling

Additionally, satellite can optionally take advantage of the following protocols:

  • Linux dmabuf
  • XDG activation
  • XDG foreign
  • Pointer constraints
  • Tablet input
  • Fractional scale

Compositor integration

Satellite supports passing through the -listenfd Xwayland argument. What this means is you can integrate satellite (and by extension Xwayland) into your compositor, and do things like on demand activation. Note that you must pass a display number to satellite as the first argument, and then the -listenfd argument.

You can view Niri's implementation of this integration for understanding how it should work.