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

Hiding the cursor on the actual wl-mirror toplevel #23

Open
Kommynct opened this issue May 3, 2023 · 11 comments
Open

Hiding the cursor on the actual wl-mirror toplevel #23

Kommynct opened this issue May 3, 2023 · 11 comments
Labels
enhancement New feature or request

Comments

@Kommynct
Copy link

Kommynct commented May 3, 2023

Right now there's an option to hide the cursor when it's being mirrored onto another display, but i'd like to do the opposite, hide the cursor when it is over the display doing the mirroring, is that possible? I don't see an option.

@Ferdi265
Copy link
Owner

Ferdi265 commented May 3, 2023

It is correct that in Wayland the client is responsible for managing the state of the cursor, and could potentially hide it. That would probably require wl-mirror to interact with a few more Wayland protocols and might be a bit of an undertaking to support properly. I do think this is an interesting feature, since it would allow you to confuse where the cursor actually is much less than currently.

I don't have much time for wl-mirror currently, so I will not be able to implement this right away, but I do think this is a good feature.

@Ferdi265 Ferdi265 added the enhancement New feature or request label May 3, 2023
@aylurus
Copy link

aylurus commented Jan 5, 2024

Instead of making the cursor invisible over wl-mirror, why not prevent it from entering the region altogether? Apparently this is possible in X (example), but I don't know if that is also true for Wayland. I don't know how much it helps, but I read that Wayland windows can be made unfocusable. I found some hints on that in a reddit thread.

If it was somehow possible to prevent an output where wl-mirror is running in fullscreen to get focused (both by keyboard and by mouse), that would prevent confusion during presentations. Furthermore, it would completely solve the lack of screen-mirroring in compositors like sway. By selectively moving workspaces from resp. to the mirroring output before resp. after running wl-mirror, it would be possible to emulate traditional screen-mirroring with little effort.

The whole idea is probably quite ambitious, though.

@Kommynct
Copy link
Author

Kommynct commented Jan 5, 2024

Unfocusable would just make it so that the mouse would be behind the window, I believe

It'd also make it impossible to close the window, unless you had a dedicated command or used pkill, which would be inconvenient.

You'd have to implement mouse warping or it would just be more annoying with no payoff.

@Ferdi265
Copy link
Owner

Ferdi265 commented Jan 5, 2024

From a wayland protocol perspective, the client doesn't have a lot of influence over focus, neither keyboard nor mouse, and the influence that is available is often limited to specific window roles as defined by protocols such as XDG Shell (IIRC there are things similar to pointer and keyboard grabbing, but no client-controlled warping or explicit focus management).

I haven't looked into the whole input subsystem (wl_seat, wl_pointer, wl_keyboard, etc...) almost at all yet, so there may be things that I am overlooking or misinterpreting, but making something unfocusable or preventing the mouse from entering something is very clearly outside of what a client can do, but could be implemented on the compositor side. (you can make unfocusable popup surfaces for things like tooltips, but the toplevel is always focusable IIUC)

A simple hack I found that can be done on sway to prevent accidently moving the mouse to the other screen is making sure the monitors have a gap in the logical coordinate system between them (i.e one monitor is 1920x1080 at 0,0 and the other is 1920x1080 at 2000,0 with an 80 px gap), which prevents the mouse from moving over, but you can still focus the workspaces by keyboard shortcuts.

Making the cursor disappear on the wl-mirror window is definitely doable, you can just bind the wl_seat and use set_cursor with a NULL surface, but I have noticed that on scaled outputs it also somehow disappears on its own sometimes, which I should probably fix at some point.

@aylurus
Copy link

aylurus commented Jan 6, 2024

It'd also make it impossible to close the window, unless you had a dedicated command or used pkill, which would be inconvenient.

@Kommynct: As long as the behavior is optional, I don't see a problem with that. wl-mirror is probably mainly used with tiling WMs, and their users usually configure their own hotkeys. For example, I have bindings in sway for both starting and killing wl-mirror, without the need to focus its window.

@Ferdi265: I understand now that preventing focus in general is probably not feasible. I agree that output focus is something that should be handled at compositor level. But it would still be neat if the window could somehow block the mouse from entering it. However, it seems that mouse warping is not possible in Wayland by design (for security reasons). Thus, without compositor-level support, preventing the mouse from moving into it can probably only be achieved by some hack. For example, I've read that it's possible to create a virtual mouse with uinput. The idea would be for wl-mirror to watch the global mouse position and counter its movement whenever it touches the border. But even if that worked, it would require an extremely precise temporal resolution, be very inefficient and prone to bugs. So I'm just mentioning this to spark creativity. I am not sure if there exists a reasonable solution within the means of wl-mirror.

Btw, I also found a mention of the focus problem in a sway issue.

@Kommynct
Copy link
Author

Kommynct commented Jan 6, 2024

To clarify, my problem is that, this setting, unless mouse-warping also is solved, would serve no purpose, why bother developing no-focus if it doesn't actually solve any problems and does remove one way of closing out of wl-mirror?

With mouse-warping, it's an interesting feature, otherwise, I don't see the advantage. It's definitely not a problem to setup a keybind to kill wl-mirror, in fact, i've done that myself, but what purpose would a no-focus without mouse warping serve?

@Ferdi265
Copy link
Owner

Ferdi265 commented Jan 6, 2024

Yes, not being able to focus the window while still being able to move your mouse there would be confusing.

Regardless, I don't think any of the features described here except hiding the cursor would be implementable as a regular Wayland client, and I'm not comfortable resorting to crazy hacks for things like trying to work against the Wayland design choice of not allowing clients to interfere with the cursor.

To get back to the point: I'm fine with implementing options for hiding the cursor on the wl-mirror window or (even better) setting the cursor to a different one while over the wl-mirror window, like the crosshair cursor. That would be a very quick indication that your cursor is not where you wanted it to be and you can even see where you need to move it to get back. That would even prepare for things like setting regions or other options just via the mouse, making the tool more user-friendly for GUI users.

@aylurus
Copy link

aylurus commented Jan 6, 2024

not being able to focus the window while still being able to move your mouse there would be confusing.

Of course, I did not mean to suggest implementing key-related focus blocking on its own. But anyway, it's off the table.

I'm not comfortable resorting to crazy hacks for things like trying to work against the Wayland design choice of not allowing clients to interfere with the cursor.

That's very reasonable. I do think it's a good design choice from Wayland not to let an application perform arbitrary manipulations of the cursor. In this case, it would be convenient if it at least admitted some limited form of control. But I also see how this might conflict with security interests, and to be fair, this is a very specific use case.

Thanks for sharing the gap trick for sway. I will try that and see if I find a reasonable configuration to work with it.

@Kommynct
Copy link
Author

Kommynct commented Jan 7, 2024

If you do try it please post what worked for you!

@aylurus
Copy link

aylurus commented Jan 12, 2024

I found another potential solution: Sway allows limiting the scope of the cursor to a specific display via input <identifier> map_to_output <identifier>. This way, the cursor can not move past the screen edge. If the focus is changed via keys and the cursor switches to another output, it instantly moves back to its mapped output upon the next mouse movement (ironically, this uses warping). Of course, this can also be prevented by using mouse_warping none. Maybe one could even configure a proper beamer mode where it's not possible to switch focus to the mirroring output at all. That is probably a bit tedious, as it requires tracking workspace movements and then dynamically and selectively enabling/disabling focus switch commands. But if done in a parametrized way, one could then also have a switch where the external output is mirrored to the primary output in the same way, to access workspaces on the other output. After leaving beamer mode, all of the temporary settings would need to be undone.

So far, I only tested limiting the mouse mapping. I'm not sure how much of the rest is doable in practice and I'm sure I've forgotten several edge cases. But I feel like sway does leave some space for improving the workflow with wl-mirror during presentations. However, these solutions remain hacky (and potentially incomplete) and can probably not be configured in a simple way. But I guess that is true in general when one tries to implement code-level features at configuration level.

@Kommynct
Copy link
Author

Kommynct commented Feb 6, 2024

just sharing my config using those principles on 3 monitors, i use my phone to control my TV but only want the mouse to be bound to the screen currently showing on the TV so that I can control my other monitors without being able to see them, and so that the mouse cursor doesn't vanish with me not knowing where to put it, this has been very beneficial for me on sway.

bindsym --no-repeat {
	mod4+v exec "pkill wl-mirror ; makoctl mode -a camera-shy & swaymsg seat '*' cursor set 2580 720 ; swaymsg input "117:256:Paris_Commune_Mouse" map_to_output DP-1 ; wl-mirror DP-1 && makoctl mode -r camera-shy && swaymsg input "117:256:Paris_Commune_Mouse" map_to_output HDMI-A-1"
	mod4+z exec "pkill wl-mirror ; makoctl mode -r camera-shy & swaymsg seat '*' cursor set 4840 540 ; swaymsg input "117:256:Paris_Commune_Mouse" map_to_output DP-2 ; wl-mirror DP-2 && swaymsg input "117:256:Paris_Commune_Mouse" map_to_output HDMI-A-1"
	mod4+backslash exec "makoctl mode -r camera-shy & pkill wl-mirror & swaymsg seat '*' cursor set 640 360 & swaymsg input "117:256:Paris_Commune_Mouse" map_to_output HDMI-A-1"
	mod4+mod1+z exec "makoctl mode -r camera-shy & pkill wl-mirror & swaymsg seat '*' cursor set 640 360 & swaymsg input "117:256:Paris_Commune_Mouse" map_to_output HDMI-A-1"
}

the mako thing makes it so that the notifications never appear on the mirrored display, as I don't want my notifications to be visible to everyone watching the TV, it then moves the cursor to the screen specified by the bind (the software i'm using doesn't support binding to win+backslash so that bind got repeated in mod4+mod1+z i believe)

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

No branches or pull requests

3 participants