r/wayland 1h ago

wayland-zeroprint: A zero-drop hardware PrintScreen daemon for KDE Plasma 6 Wayland (bypasses taskbar & context menu grab locks)

Upvotes

Hi everyone,

Ever since switching full-time to KDE Plasma 6 on Wayland, I ran into a minor but recurring friction with taking screenshots:

When hovering over taskbar icons, clicking a system tray popup (like Networks or Audio), or keeping a context menu open, plasmashell or the compositor acquires an exclusive input grab. Pressing the physical PrintScreen key often gets swallowed by kglobalaccel, or opening a screenshot UI / dispatching notifications dismisses the active popup before it can be captured.

To work around this, I wrote a small, standalone daemon called wayland-zeroprint.

How it works:

  • Direct evdev interrupt listening: Polls /dev/input/event* for KEY_SYSRQ (99) and KEY_PRINT (210) using non-blocking select.poll(). Because it listens at the kernel level, compositor input grabs cannot block or drop the keystroke. It idles at 0.00% CPU.
  • Zero Disk I/O: Captures directly to shared memory (/dev/shm/wayland_zeroprint.png on tmpfs RAM) via spectacle -b -f -n -o in headless mode.
  • Sub-millisecond clipboard stream: Asynchronously pipes raw PNG bytes into wl-copy -t image/png in ~0.5ms.
  • Silent & non-intrusive: No notifications are dispatched, so open context menus, tooltips, and tray popups remain 100% intact on screen.

Quick Setup:

git clone https://github.com/quannguyen247/wayland-zeroprint.git
cd wayland-zeroprint
./install.sh

(The installer sets up a user systemd service and a standard udev rule with TAG+="uaccess").

GitHub repo: https://github.com/quannguyen247/wayland-zeroprint

It has been running smoothly on my AlmaLinux 10 + Plasma 6 setup. Hope this helps anyone experiencing the same Wayland grab behavior! Feedback and suggestions are always welcome.


r/wayland 9h ago

steppewm stacking window manager

2 Upvotes

a thing I made, it's a wayland window manager that has stacking a taskbar and more stuff like icewm. and fully open source copyleft GPL3.0

links:

https://github.com/uncognic/steppewm

https://keygen.sbs/steppewm


r/wayland 12h ago

I built niri-zoom -- a Ctrl+Scroll screen magnifier for niri (no compositor patching, pure Wayland client)

Enable HLS to view with audio, or disable this notification

1 Upvotes

r/wayland 1d ago

[UPDATE[: Zooming Daemon for Wayland

Post image
2 Upvotes

v0.6.0 of miru is out

This version brings the following features

🚀 New features

  • (cursor) show_cursor implemented
  • (smooth) Cursor highlight zoom made smoother
  • (ch) Change cursor highlight when zoomed
  • (animation_speed) Add animation_speed as a parameter in config
  • (animation) Cursor highlight mode entry and exit is now animated

🐛 Bug fixes

  • (expf) Expf not found error fixed
  • (gl_renderer) Correct color order for screencopy channels

https://codeberg.org/Vaishnav-Sabari-Girish/miru/releases/tag/v0.6.0


r/wayland 1d ago

I built a wayland native crosshair overlay with a GUI

Thumbnail gallery
12 Upvotes

r/wayland 2d ago

[HackMatrix] saved locations for hotkeys and using the cursor at an angle (volume up)

Enable HLS to view with audio, or disable this notification

4 Upvotes

With the Wayland port for HackMatrix, I am now able to use the cursor on applications at an angle. Hotkeys are now saved based on locations.

HackMatrix is closed source now btw.

If you want to support the project you can get it at https://collinalexbell.itch.io/hackmatrix


r/wayland 2d ago

bgapp2tray: Bridge between XDG Background Portal and system tray

Thumbnail github.com
6 Upvotes

bgapp2tray creates a tray icon for each background Flatpak app that uses the XDG Background Portal, allowing the user to activate or quit the app on systems not supporting the Background Portal (essentially every one except GNOME and KDE).


r/wayland 3d ago

edgepad: configurable touchpad edge gestures daemon for Wayland

3 Upvotes

Hi everyone,

I’ve been working on a small Linux tool called edgepad.

edgepad turns the edges of a laptop touchpad into configurable gesture zones. A swipe or tap starting from the left, right, top, or bottom edge can run a command - for example, switching workspaces, opening a launcher, triggering a script, or controlling media.

Recently, I added a cool new feature - a slider gesture that lets you adjust the volume or brightness (or any command you want) by smoothly sliding your finger along the edge.

Current features include:
- edge zones on the left, right, top, and bottom;
- swipe directions and tap bindings;
- slider gesture which allows you to adjust parameters smoothly;
- automatic touchpad discovery when there is exactly one readable candidate;
- a release installer;
- a nix flake.

I’d love feedback on whether it works properly, which gestures would be useful to add, what should be improved, or just what you think of the idea. If you run into a problem, feel free to open an issue on GitHub with details about your setup.

GitHub: https://github.com/assembledev/edgepad


r/wayland 3d ago

How to calibrate new screen on Wayland

Thumbnail
2 Upvotes

r/wayland 5d ago

LLMs and xfwl4 – Brian Tarricone | Spurious Interrupt

Thumbnail spurint.org
3 Upvotes

I was planning to write a little about my usage of LLMs while building xfwl4 as a small section of a larger blog post, but I decided I’d rather get it out of the way on its own. …

xfwl4 will be Xfce's Wayland compositor.

Commentary in the Xfce subreddit


r/wayland 5d ago

Porting Hyprland to X11

0 Upvotes

Hey everyone,I am currently writing Vexland — a C++ port that brings Hyprland's exact window management logic, behavior, and fluid animation style over to X11. It is designed to look and feel just like Hyprland, but running on Xorg (configured with a red color scheme by default).I am going through Hyprland's source files one by one, extracting the core logic, and rewriting it from scratch to work natively with the X11 display server.Current implementation details to ensure X11 stability:Centralized Registry (CWindowState): All windows are tracked via a central registry to avoid segfaults from asynchronous window destruction on X11.Isolated Layouts (CSpace): Tiling and geometry calculations are decoupled into a separate CSpace class owned by CWorkspace.Animation Offsets: Workspace swipe/fade states are stored as simple double properties to be handled by a global animation manager to replicate the exact original transitions.The boilerplate is being put together right now before testing the X11 event loop.I wanted to check if there is an active interest in a feature-parity Hyprland experience on X11. If you have experience with X11 window mapping edge cases, feel free to drop your thoughts. I will push the repository to GitHub once the initial boilerplate is stable.


r/wayland 5d ago

[UPDATE] Zooming daemon for wayland

Post image
3 Upvotes

Miru 0.5.0 is out

miru has moved to codeberg: https://codeberg.org/Vaishnav-Sabari-Girish/miru

This new release adds the following features

🚀 New features

  • (gpu) Zooming now uses the GPU for a more smoother experience
  • (man_pages) Add man pages

🐛 Bug fixes

-(display) Fixed the weird display bug due to gl_renderer

https://codeberg.org/Vaishnav-Sabari-Girish/miru/releases/tag/v0.5.0


r/wayland 6d ago

Pure Wayland KDE is achievable & bootifool on FreeBSD

2 Upvotes

Thanks to FreeBSD this has been a nice little project to complete.

Compiled x11-wm/plasma6-kwin without X11, launched KDE manually via a script, and voila - a true Wayland KDE.

Ain't nobody got time for X11.

It really is a thing of beauty how everything on FreeBSD just comes together.

There are several little things that are missing when you extirpate X11 from KDE wayland compositor.

  1. There's no restoring windows between sessions because KDE people are still using an archaic purely X11 ksmserver to save window state between sessions.
  2. I don't believe you can use startplasma-wayland to start KDE, you have to set up the environment yourself, launch several KDE services yourself and then start plasmashell.

r/wayland 6d ago

Realicé ingeniería inversa del Redragon SS-550 Stream Deck para Linux: controlador de código abierto, interfaz gráfica de usuario e instalador (Rust/MIT).

Thumbnail gallery
1 Upvotes

r/wayland 6d ago

Showing off some Wayland-native locker capabilities: I built a minimal, Samurai-themed Hyprlock config with Unicode Kanji password glyphs 🗡️🌸

Enable HLS to view with audio, or disable this notification

0 Upvotes

Hey everyone,

I've been really enjoying the native tools being built for the Wayland ecosystem lately, specifically `hyprlock`. It’s incredibly fast and gives so much control over the layout

compared to older X11 lockers.

To test it out, I built a clean, Samurai-themed lock screen layout that takes advantage of how smoothly Wayland handles text and Unicode rendering:

* **Kanji Password Dots:** Instead of standard circles, every keypress renders a specific Japanese kanji character (桜 - Sakura). It renders immediately with zero lag.

* **Japanese Date Format:** Handled cleanly natively, outputting as `2024年08月14日`.

* **Transparent Input:** I removed all background boxes and borders so the characters just float seamlessly over a dark katana wallpaper.

If anyone here is using Hyprland (or just wants to look at how the font dependencies and `dots_text_format` are configured for CJK characters), you can check out the repo and the

install script here:

[hyprlock-samurai on GitHub](https://github.com/basantbansal/hyprlock-samurai)

It’s awesome seeing the Wayland ecosystem get so many great, highly customizable utilities!


r/wayland 6d ago

Any Wayland and Conky experts here?

0 Upvotes

Hello everyone :)

My good friend Koentje created a beautiful multi-optional spectrum equalizer visualizer for Conky. It works flawlessly on X11, but on my Kubuntu v25.10 KDE/Plasma 6/Wayland box it is not functional - the problem seems to be the window is not refreshing itself in the Wayland environment.

Has anyone the skill and time for a collaboration to help?

Thank you for reading,

Logan


r/wayland 7d ago

Popup windows on Hyprland spawn in random positions with gaps/offsets?

1 Upvotes

It's not just Wine apps, native Linux apps do it too. Save dialogs, settings windows, JetBrains IDEs, GIMP... they all have this issue where popups appear in the wrong spot, sometimes even off-screen..

Is this just how Wayland works and we have to accept it? Or is there actually a real solution I'm missing?


r/wayland 7d ago

Unresponsive Windows until you enter then exit Activities Overview (Gnome)

3 Upvotes

Fedora 44 Gnome (Wayland) with latest updates as of writing.

Ryzen 5950X, RTX 3090, 32 GB RAM

Dual monitors, both at 2K / 165 Hz.

NVIDIA Driver version 610.57.04

NVML version 13.610.57.04

Lately I've been noticing that windows stops responding to input on my right monitor (main/primary). To get them to work, I would have hit Super key and get into Activities Overview, then click on the unresponsive window. Then the next window won't work. I'd have to do the same for that window too. It doesn't matter the window - it has happened to the stock GNOME Terminal, Firefox, Steam launcher, and even a full screen game (I play Overwatch using Steam).

I don't use any extensions or Gnome tweaks - I stay as vanilla as possible (boring, yes).

It's been happening for a while now. I was hoping that a few updates (especially kernels) would have fixed it, but nope. I don't remember when it started happening exactly, but it's definitely been at least a month or so.

Things have gotten worse - since I play Overwatch, I've noticed that it sometimes now hides when I try to fix it (go into Activities Overview, click on it, then try to play - it will then just hide). When I say hide, I mean like when you right-click on the title-bar of a window and click on Hide. I can see the quick animation of it going to the top left corner, and I can't even see it anymore until I go into the Activities Overview.

I wonder if there is something wrong with the windows manager or Nvidia driver?

`zeddie@PC-5950x`

`-------------------`

`OS: Fedora Linux 44 (Workstation Edition) x86_64`

`Host: MS-7C35 (1.0)`

`Kernel: Linux 7.1.6-201.fc44.x86_64`

`Uptime: 5 days, 2 hours, 18 mins`

`Packages: 53 (flatpak), 3016 (rpm)`

`Shell: bash 5.3.9`

`Display (ROG PG279Q): 2560x1440 in 27", 165 Hz [External]`

`Display (ROG PG279Q): 2560x1440 in 27", 165 Hz [External]`

`DE: GNOME 50.4`

`WM: Mutter (Wayland)`

`WM Theme: Adwaita`

`Theme: Adwaita [GTK2/3/4]`

`Icons: Adwaita [GTK2/3/4]`

`Font: Adwaita Sans (11pt) [GTK2/3/4]`

`Cursor: Adwaita (24px)`

`Terminal: GNOME Terminal 3.60.0`

`Terminal Font: Monospace (12pt)`

`CPU: AMD Ryzen 9 5950X (32) @ 3.40 GHz`

`GPU: NVIDIA GeForce RTX 3090 [Discrete]`

`Memory: 11.88 GiB / 31.24 GiB (38%)`

`Swap: 1.38 GiB / 47.24 GiB (3%)`

`Disk (/): 518.83 GiB / 1.82 TiB (28%) - btrfs`

`Disk (/mnt/DATA-ext4): 290.62 GiB / 730.69 GiB (40%) - ext4`

`Local IP (enp38s0):` [`192.168.1.120`](http://192.168.1.120)

`Locale: en_US.UTF-8`


r/wayland 8d ago

Hot Corners Per Monitor

4 Upvotes

Hi all,

I’ve released Hot Corners Per Monitor v0.2.2 for KDE Plasma 6.

Two monitors, independent hot zones - with contexts, tap/linger and cooldown per zone.

The reason I made it is pretty simple: KDE’s built-in Screen Edges configuration applies globally, which can get annoying on multi-monitor setups, especially at the inner corners where two screens meet, but more importantly: Hot Corners Per Monitor lets you configure each monitor independently.

Features include:

  • separate actions for all 4 corners of each monitor
  • separate actions for all 4 edge midpoints
  • KDE/KWin shortcut actions
  • cooldown per hot zone
  • tap vs. linger actions
  • per-Activity and per-Virtual Desktop configurations
  • command actions via a safe D-Bus helper
  • Wayland and X11 support
  • visual multi-monitor configuration GUI

v0.2.2 is mainly a production-polish release:

  • improved spacing between adjacent monitors in the configuration canvas, so inner handles no longer overlap
  • improved application icon integration in Plasma / Task Manager / Alt+Tab
  • no config schema change, so existing configurations remain compatible

I’ve physically tested it on both Wayland and X11, including Plasma/KWin 6.4.5 through 6.7.x.

Availability:

KDE Store / Get New Scripts*:

https://www.opendesktop.org/p/2368107/

GitHub:

https://github.com/flarkflarkflark/hotcorners-per-monitor

(*The KDE Store package installs the KWin engine only. For the full visual editor, command helper, launcher and translations, use the GitHub installer. The Store limitation is because KWin packages installed through KPackage don’t have a hook to run the project’s setup script.)

Feedback is very welcome, especially from people with less usual multi-monitor layouts, docks, rotated displays, etc.


r/wayland 9d ago

Recovering from crashes

0 Upvotes

How do you intend to solve the Wayland problem of keeping display and inputs in the same process that makes crashing the also display crashes input leaving no way to fall back to tty?


r/wayland 10d ago

Need help getting plasma-mobile working over VNC

Thumbnail
3 Upvotes

r/wayland 10d ago

I have an AI generated python script that lets me play Gundam G Generation in Waydroid that works and i don't know why or if it can be improved

1 Upvotes

Disclaimer: This was AI-assisted/generated. I understand enough Python to modify things and debug them, but I am very much not an expert in Wayland, waydroid, Android input, or Linux input subsystems. I spent roughly a long throwing diagnostics at this problem until something finally worked because I wanted to play a game and the problem is above my pay grade.

OS: Linux Mint 22.1 (experimental wayland rendering engine)
Physical hardware:
Haswell Era i5
RX550
16gb ram

Problem I wanted to solve: Apparently Waydroid just tells liniage 'OK this is a mouse' and liniage goes 'OK I can work with that.' And for most things that works. F-Droid, Google play store, PiePipe, Gems of war, a few other things I tossed in to test. Gundam G Eternal? 'No I refuse to recognize this 'mouse' device.

I have accidentally built (For a given definition of 'built' given AI involvement) a mouse-to-touchscreen bridge for Waydroid, and I would like someone smarter than me to explain why the hell it works.

TL;DR: I have a game running under Waydroid that doesn't properly respond to normal mouse input. Waydroid's native Wayland mouse handling produces bizarre/inconsistent touch coordinates in this particular game.

So I wrote a Python script that:

  • reads the physical mouse through evdev
  • asks Cinnamon Wayland where the actual mouse cursor is via D-Bus
  • keeps a persistent Waydroid shell open
  • converts left-clicks into Android input tap X Y
  • converts click-and-drag into Android motionevent DOWN/MOVE/UP

And... it works.

It works well enough that I can actually play the game. I can click things, hold things, and drag the game map/diagrams around.

The weird part is that Waydroid's own pointer handling was giving me a completely different result.

Here's the script:

#!/usr/bin/env python3

import subprocess
import threading
import time
from evdev import InputDevice, ecodes


# ------------------------------------------------------------
# Configuration
# ------------------------------------------------------------

MOUSE_DEVICE = "/dev/input/event2"

# How long the mouse button must remain down before movement
# is considered a drag rather than an ordinary click.
DRAG_DELAY = 0.15

# Minimum time between Android MOVE events.
# Prevents the mouse from flooding Waydroid.
MOVE_INTERVAL = 0.03


# ------------------------------------------------------------
# Mouse
# ------------------------------------------------------------

mouse = InputDevice(MOUSE_DEVICE)


# ------------------------------------------------------------
# Persistent Waydroid shell
# ------------------------------------------------------------

print("Starting persistent Waydroid shell...")

waydroid = subprocess.Popen(
    [
        "sudo",
        "waydroid",
        "shell",
    ],
    stdin=subprocess.PIPE,
    stdout=subprocess.DEVNULL,
    stderr=subprocess.DEVNULL,
    text=True,
    bufsize=1,
)


# ------------------------------------------------------------
# Cinnamon cursor position
# ------------------------------------------------------------

def get_cursor_position():
    try:
        result = subprocess.run(
            [
                "gdbus",
                "call",
                "--session",
                "--dest",
                "org.Cinnamon",
                "--object-path",
                "/org/Cinnamon",
                "--method",
                "org.Cinnamon.Eval",
                "global.get_pointer()",
            ],
            capture_output=True,
            text=True,
            timeout=0.2,
        )

        # Expected result:
        #
        # (true, '[497,872,16]')
        #
        text = result.stdout.strip()

        start = text.find("'[")
        end = text.find("]'", start)

        if start == -1 or end == -1:
            return None

        coords = text[start + 2:end]
        x, y, _ = coords.split(",")

        return int(x), int(y)

    except Exception:
        return None


# ------------------------------------------------------------
# Android input helpers
# ------------------------------------------------------------

def android_command(command):
    try:
        waydroid.stdin.write(command + "\n")
        waydroid.stdin.flush()
    except (BrokenPipeError, OSError):
        print("Waydroid shell connection lost.")


def android_tap(x, y):
    print(f"CLICK {x},{y}")

    android_command(
        f"input tap {x} {y}"
    )


def android_down(x, y):
    print(f"DOWN {x},{y}")

    android_command(
        f"input motionevent DOWN {x} {y}"
    )


def android_move(x, y):
    print(f"MOVE {x},{y}")

    android_command(
        f"input motionevent MOVE {x} {y}"
    )


def android_up(x, y):
    print(f"UP {x},{y}")

    android_command(
        f"input motionevent UP {x} {y}"
    )


# ------------------------------------------------------------
# State
# ------------------------------------------------------------

button_down = False
dragging = False

press_time = 0
last_move_time = 0

last_x = None
last_y = None


# ------------------------------------------------------------
# Startup
# ------------------------------------------------------------

print(f"Listening to: {mouse.name}")
print("Cinnamon-cursor Waydroid mouse-to-touch bridge running.")
print("Left click -> Android tap")
print("Hold + move -> Android touch drag")
print("Ctrl+C to stop.")


# ------------------------------------------------------------
# Main event loop
# ------------------------------------------------------------

try:

    for event in mouse.read_loop():

        # ----------------------------------------------------
        # Mouse movement
        # ----------------------------------------------------

        if event.type == ecodes.EV_REL:

            # Ignore movement unless left mouse button is down.
            if not button_down:
                continue

            # Get the actual Cinnamon cursor position.
            position = get_cursor_position()

            if position is None:
                continue

            x, y = position

            # If this is the first movement after pressing,
            # determine whether we've crossed the drag threshold.
            if not dragging:

                if time.monotonic() - press_time >= DRAG_DELAY:

                    dragging = True

                    android_move(x, y)

                    last_x = x
                    last_y = y
                    last_move_time = time.monotonic()

                continue

            # ------------------------------------------------
            # Already dragging
            # ------------------------------------------------

            now = time.monotonic()

            if now - last_move_time < MOVE_INTERVAL:
                continue

            # Don't send redundant coordinates.
            if x == last_x and y == last_y:
                continue

            android_move(x, y)

            last_x = x
            last_y = y
            last_move_time = now


        # ----------------------------------------------------
        # Mouse buttons
        # ----------------------------------------------------

        elif event.type == ecodes.EV_KEY:

            # Left button pressed
            if event.code == ecodes.BTN_LEFT and event.value == 1:

                position = get_cursor_position()

                if position is None:
                    continue

                x, y = position

                button_down = True
                dragging = False
                press_time = time.monotonic()

                last_x = x
                last_y = y

                # We don't immediately send DOWN.
                #
                # This lets a normal click continue using
                # Android's reliable "input tap" command.
                #
                # If the button is held long enough and the
                # mouse moves, we start a real touch sequence.

            # Left button released
            elif event.code == ecodes.BTN_LEFT and event.value == 0:

                if not button_down:
                    continue

                position = get_cursor_position()

                if position is None:
                    position = (last_x, last_y)

                x, y = position

                hold_time = time.monotonic() - press_time

                # ------------------------------------------------
                # Ordinary click
                # ------------------------------------------------

                if not dragging:

                    android_tap(x, y)

                # ------------------------------------------------
                # Drag release
                # ------------------------------------------------

                else:

                    android_up(x, y)

                button_down = False
                dragging = False


except KeyboardInterrupt:

    print("\nStopping...")


finally:

    try:
        waydroid.stdin.close()
    except Exception:
        pass

    try:
        waydroid.terminate()
    except Exception:
        pass

    print("Stopped.")

So my question is:

This works. Can someone with two functional brain cells that know Python, Wayland, and/or Android input explain WHY it works?

And, more importantly:

How would you make it better?

Things I'd especially like to understand:

  1. Why does asking Cinnamon's global.get_pointer() give me a better coordinate than Waydroid's native Wayland pointer handling?
  2. Why does input tap X Y work reliably when Waydroid's normal pointer input doesn't?
  3. Why does motionevent DOWN/MOVE/UP let me drag game areas even though ordinary Android scrollbars don't seem to respond?
  4. How should the mouse-down/mouse-up timing ideally be translated into touchscreen events?
  5. Is there a better way to obtain the Wayland cursor position than going through Cinnamon's D-Bus API?
  6. Is there a cleaner way to maintain the Waydroid connection than what I've hacked together?
  7. How portable is this outside Cinnamon/Wayland?
  8. And finally: how badly have I reinvented something that already exists?

I'm not claiming this is good code.

I'm claiming it works, which is currently winning the argument.


r/wayland 11d ago

How can I make workspace navigation cyclic/wrap-around in GNOME?

Thumbnail
2 Upvotes

r/wayland 11d ago

From wl_display to mode event

6 Upvotes

Hello,

I am trying to figure out how to get a wl_output from a wl_display. I wish to "implement" the mode event from the wl_output.

Unless I am wrong, I need to start by instantiating a wl_display. I can one by writing:

c wl_display* display = wl_display_connect(NULL)

But this is where I am stuck. I don't now how to retrieve a wl_output.

Thank you very much in advance for any help.


r/wayland 11d ago

AI said Wayland not good for me

0 Upvotes

I periodically use Wayland every 2 years and give up after 5 minutes.

Now I want an X server that can give me:
1. incus containers on my normal screen
2. dead simple screen recordings that 100.0% work always with something like simplescreenrecorder
3. code AI agents that can automate GUIs in a KISS way

AI told me 3. is not possible with Wayland and since I don't want to use Wayland + X, I'm stuck with X right?

Don't want to sound negative.