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

pointer moving, clicking doesn't work on headless backend #305

Open
cmitsakis opened this issue Jan 17, 2024 · 2 comments
Open

pointer moving, clicking doesn't work on headless backend #305

cmitsakis opened this issue Jan 17, 2024 · 2 comments

Comments

@cmitsakis
Copy link

cmitsakis commented Jan 17, 2024

When using the headless backend, pointer moving and/or clicking with wlrctl doesn't work.

I encountered this issue on cage 0.1.5 and master on Arch Linux. I even tried the cage PR that adds support for wlroots 0.17 and still had the same issue.

I think it's a wlroots issue because it happens on sway too, but I decided to submit it here first (as advised by the wlroots issue tracker instructions). It might be a wlrctl issue too (if there is a wlrctl alternative, let me know and I will test it).

You can test it with this script. It tries to click the "new tab" button on Chrome and takes a screenshot. For me the coordinates of the button are 270 16 but if it doesn't work, check the coordinates of the button on the screenshot.

unset WAYLAND_DISPLAY
export WLR_BACKENDS=headless
export WLR_LIBINPUT_NO_DEVICES=1
cage -- bash -c "
	set -eux
	trap \"exit\" INT TERM
	trap 'kill \$(jobs -p) 2>/dev/null || :' EXIT
	chromium --ozone-platform=wayland --user-data-dir=\"/tmp/temp_chrome_profile\" &
	sleep 1
	wlrctl pointer move -2000 -2000
	sleep 1
	# move pointer to 'New tab' button
	wlrctl pointer move 270 16
	sleep 1
	wlrctl pointer click
	sleep 1
	grim screenshot.png
"
@cmitsakis
Copy link
Author

cmitsakis commented Jan 18, 2024

I added -c to the grim command to show the mouse pointer. There is no pointer.

I noticed wlrctl creates a virtual pointer and then destroys it. I modified wlrctl and added some sleep time before it destroys the pointer, and took a screenshot while wlrctl was running and discovered that there is pointer.

Is there a way to keep the pointer after wlrctl exits?

@joggee-fr
Copy link
Collaborator

I have tested it using weston-clickdot with WAYLAND_DEBUG=1 environment variable to try to understand what's happening.
Without any modification on wlrctl, I can observe wl_pointer.button event is not sent by the compositor (Cage) to the client (clickdot). If I add a call to wl_display_dispatch() or wl_display_roundtrip() (or just a simple sleep) after zwlr_virtual_pointer_manager_v1_create_virtual_pointer() in wlrctl, the event is well distributed.

I am clearly not a Wayland nor wlroots expert at all, but as I understand it in headless case, no pointer device exists before wlrctl creates a virtual one. Once created, the client (clickdot) get a notification of capabilities update for wl_seat and retrieves a pointer object using wl_seat.get_pointer. It seems that wlroots send pointer events only to client which has requested a pointer object yet. That's where the quick and dirty sleep patch I have tested in wlrctl can make a difference, allowing the client (clickdot) to have time to request a pointer object.

I can't see a reliable way to determine if client is ready to receive pointer events to propose a patch for wlrctl but it is quite interesting.

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

No branches or pull requests

2 participants