Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide cursor #299

Open
travisghansen opened this issue Dec 27, 2023 · 25 comments
Open

hide cursor #299

travisghansen opened this issue Dec 27, 2023 · 25 comments

Comments

@travisghansen
Copy link

I have searched and can't seem to find much beyond the 'hidden cursor when touchscreen present' PR. I'm using an rpi3 trying to create a view-only display (launching chromium with debug port allowing for remote control of the browser). In principle everything seems to be working correctly but I cannot figure out how to make the cursor disappear from dead center of the screen. I have no keyboard/mouse connected and would prefer to make the cursor disappear disappear initially and/or after a period of inactivity.

Is this possible currently?

@Winterhuman
Copy link

I have a (admittedly janky) solution to hiding the cursor, which is just removing or hiding /usr/share/icons/*/cursors from cage (e.g. Set InaccesiblePaths=/usr/share/icons/ in the systemd service that executes cage).

Outside of that hack, or this patch, I don't believe cage provides a way to disable the cursor; trying some of the WLR_* env vars from this cursor-related patch didn't seem to work.

@travisghansen
Copy link
Author

Thanks for the tip! I also noticed setting the XCURSOR_THEME seemed to have no effect as well. I wanted to set it to this theme here: https://github.com/johnodon/Transparent_Cursor_Theme

I ultimately ended up replacing all the themes with the above mentioned to get it to work, but I like the inaccessible path approach better frankly. I'll try that and see if it takes effect.

@travisghansen
Copy link
Author

InaccesiblePaths=/usr/share/icons/ didn't work for me :( let me know if you get that working properly and maybe send over an example.

@Winterhuman
Copy link

Winterhuman commented Dec 28, 2023

Hmm, you're right. Ironically, I was assuming a cursor package I installed was what allowed me to see a cursor in cage, so you discovering that has made my life a little simple (thanks for that!), but yeah, I'll need to do some investigating into how I managed to break cursors in the first place.

EDIT: Okay, so cage uses client-side cursors, which usually means that the XCURSOR_* env vars aren't respected in most Wayland clients. But also, the reason my cursor wasn't showing at some point in the past was because I was using a different renderer for cage (a non-pixman renderer), which is what broke them originally

@joggee-fr
Copy link
Collaborator

If I remember correctly, if no pointer input is available no cursor should be displayed by Cage. Could you check the inputs seen by the compositor?

@travisghansen
Copy link
Author

How would I check the inputs? Sorry for the ignorance, don’t really know what I am doing as it relates to the compositor :(

Based on my ignorant reading of the relevant PR my understanding was that if a touch device is found it hides the cursor. Subtly different from no pointer devices found (which should be my case). But even if a pointer device is present I prefer to make it disappear after a certain inactivity timeout. When I was messing with sway it had setting of this nature (which incidentally didn’t work when set in the config file but did work if I sent a swaymsg).

Regarding the cursor env vars, those variables are actually explicitly called out in the docs as supported so we probably want to update the docs if indeed they are ignored.

@Winterhuman
Copy link

From what I understand, they should already be supported, but only if you're using hardware cursors (although I've never figured out how to fix the warn: wayland.c:1512: no server-side cursors available, falling back to client-side cursors message, and WLR_NO_HARDWARE_CURSORS=0 doesn't change this)

@Winterhuman
Copy link

Winterhuman commented Dec 28, 2023

Though to answer your question, run sudo libinput list-devices to check for pointer devices, which would be indicated by the Capabilities: pointer line.

@travisghansen
Copy link
Author

Maybe this is why it still shows up for me even if I don't have a keyboard/mouse plugged in?

libinput list-devices
Device:           vc4-hdmi
Kernel:           /dev/input/event0
Group:            1
Seat:             seat0, default
Capabilities:     keyboard pointer 
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      disabled
Nat.scrolling:    disabled
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   *button
Click methods:    none
Disable-w-typing: n/a
Disable-w-trackpointing: n/a
Accel profiles:   flat *adaptive custom
Rotation:         n/a

Seems odd an hdmi device is a keyboard and a pointer but I suppose it's something to do with cec?

@joggee-fr
Copy link
Collaborator

This pointer device should be exactly why a cursor is displayed: here in the code. HDMI-CEC seems to be a good explanation.
Maybe you can disable it at udev / libinput layer as there is no option (yet?) to disable cursor in Cage.

@travisghansen
Copy link
Author

Thanks for looking that up! I think the transparent cursor is the better option in my case as someone may have a mouse plugged in etc. That should work perfectly well until a proper inactivity or similar solution is available.

I think the current logic (as I understand it) is sound:

  • if any touch devices present hide the cursor
  • If 0 pointer devices present hide the cursor

additionally the 3rd bit would be:

  • if pointer is visible (no touch devices present) then hide after x period of inactivity.

As an interim solution, maybe it would be possible currently to default the position to the upper left corner or something instead of sitting dead center of the content area. Would at least make it a little less noticeable.

@joggee-fr
Copy link
Collaborator

Current logic is quite "simple". If any input device has pointer capability, show the cursor. If not, do not show any cursor. This is how I understand it.
Tranparent cursor or removing images loaded by Xcursor should do the trick for your case.

@travisghansen
Copy link
Author

Yeah, would be good to understand why the env vars don't seem to be working. For example setting the cursor path to /dev/null would be cleaner than replacing all cursors...or even setting the theme properly would be great as well. Perhaps I have something messed up on my end preventing those from working as desired?

@emersion
Copy link
Contributor

emersion commented May 8, 2024

Here are two possible solutions with udev:

@mnschipper
Copy link

Cage handles the cursor differently than Weston. When I start the same electron application with cage as compositor, there is a cursor in the center of the screen (although only a touch screen is connected, no mouse). When I start the application with weston as compositor, the cursor is NOT displayed. So it would be nice if cage could use the same logic for displaying the cursor as weston does.

@jarrodsfarrell
Copy link

Coming from the future, I also want to disable the cursor only when running cage (or at least hide it visually or not have it right in the middle of the screen). I'm doing "things that doesn't make sane sense to do other than it looks neat" and that's running tuigreet with alacritty within cage as part of the whole greeter. It works surprisingly well.

Using the suggestion from @travisghansen for setting a transparent cursor theme didn't work, and the way I did it was modifying the systemd unit for greetd (which will be running cage) with a XCURSOR_PATH pointing to the desired cursor. And being on NixOS, this was generated during nixos-rebuild so there is a little bit of indirection. I can tell cage is reading XCURSOR_PATH because previously I didn't specify the path correctly and resulted in cage failing to start.

Relevant nix:

{ config, pkgs, ... }:

let
  transparent-cursor = pkgs.fetchFromGitHub {
    owner = "johnodon";
    repo = "Transparent_Cursor_Theme";
    rev = "22cf8e6b6ccbd93a7f0ff36d98a5b454f18bed77";
    sha256 = "sha256-wf5wnSiJsDqcHznbg6rRCZEq/pUneRkqFIJ+mNWb4Go=";
  };
  cage = "${pkgs.cage}/bin/cage";
  tuigreet = "${pkgs.greetd.tuigreet}/bin/tuigreet";
  alacritty = "${pkgs.alacritty}/bin/alacritty";
  greeting = "...";
in {
  # ...
  services.greetd = {
    enable = true;
    settings = {
      default_session = {
        command = "${cage} -- ${alacritty} --command ${tuigreet} --time --greeting \"${greeting}\"";
      };
    };
  };

  systemd.services.greetd.serviceConfig = {
    Environment = "XCURSOR_PATH=${transparent-cursor}/Transparent";
  };
}

Resulting greetd.service:

# /etc/systemd/system/greetd.service
[Unit]
After=systemd-user-sessions.service
After[email protected]
After=plymouth-quit-wait.service
Conflicts[email protected]
Wants=systemd-user-sessions.service

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/wkb8skirx4zmrnsw6dcxz07p926kz32p-glibc-locales-2.39-52/lib/locale/locale-archive"
Environment="PATH=[…Lots of nix store paths…]"
Environment="TZDIR=/nix/store/fn1y6zydm7mgxrm7b08h1w1c9qkrzk8r-tzdata-2024a/share/zoneinfo"
X-RestartIfChanged=false
# ! This path is from the `fetchFromGitHub` as seen in the nix expression. 
Environment=XCURSOR_PATH=/nix/store/6q45r4mg9xm1pf7wiiyb3dl0p1a53h5n-source/Transparent
ExecStart=/nix/store/6dr06lxs8x9cgs62h83ms48f1srahxjs-greetd-0.10.3/bin/greetd --config /nix/store/gcr1i2wrr3djlhar7q5jivi8isxm79ji-greetd.toml
IgnoreSIGPIPE=false
KeyringMode=shared
Restart=on-success
SendSIGHUP=true
TimeoutStopSec=30s
Type=idle

[Install]
WantedBy=graphical.target

@senstar-mgroff
Copy link

I'm sharing this in case it helps anyone else who tries to hack the code to get rid of the cursor. I tried commenting out lines in seat.c to make it remove the cursor even if it detects a pointing device. I made this line run:

cage/seat.c

Line 131 in df508d6

wlr_cursor_unset_image(seat->cursor);

The cursor still showed up. I had to comment out this line get rid of it:
https://github.com/cage-kiosk/cage/blob/df508d65e7e7413ba986a0d63a1660deda7bbe4c/seat.c#L486C3-L486C25

Something is setting the cursor and that brings it back even if it was removed. I'm using cage to run Electron.

@traverseda
Copy link

Is there really no way to auto-hide the cursor after it hasn't moved for a while? This seems pretty critical for a kiosk.

@joggee-fr
Copy link
Collaborator

@traverseda
I am not aware of such a feature in Cage.
If you have a hand in the executed application, you may use the idle notifier protocol to change the cursor when needed. I don't really know what it is possible to do but could be a nice test.

@emersion
Copy link
Contributor

Clients cannot change the cursor if they don't have pointer focus. Maybe as a workaround it's possible to create a fullscreen transparent layer-shell surface after the idle timeout expires, and destroy it on activity.

Anyways, patches welcome if you want to implement this in cage.

@joggee-fr
Copy link
Collaborator

Some efforts are currently made by @OctopusET on layer-shell protocol support, see issue #95 and PR #345.
@emersion, any reason the executed application in Cage will not have the pointer focus?

@emersion
Copy link
Contributor

The application executed in cage will have pointer focus. However, I assumed the use-case here is to launch an off-the-shelf application such as a web browser and hide the cursor when inactive. It would be annoying to have a patch and compile Firefox just to be able to hide the cursor :P

@joggee-fr
Copy link
Collaborator

Still thinking of this hide cursor at idle, the transparent application may not have to use layer shell. Just launch this application when receiving idle notification and stop it when receiving resume one. It should do the job.

@emersion
Copy link
Contributor

Regular fullscreen applications can't be fully transparent (because of security concerns).

@traverseda
Copy link

traverseda commented Sep 18, 2024

This really does just need to be a feature of Cage. This is a feature of KDE running under wayland, where it will hide the cursor is you touch the touch screen anywhere. Sure, there might be some way to hack it up, but if Cage's goal is to be good application kiosk software, this feature needs to exist.

Making the cursor invisible is not a good solutions, as a technician might need to hook a mouse up in order to debug problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants