-
Notifications
You must be signed in to change notification settings - Fork 914
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
Custom cursor images for all desktop platforms #3218
Custom cursor images for all desktop platforms #3218
Conversation
@eero-lehtinen let me know if you need any help for the Web backend! |
Thank you. I will continue working on this today and this week so I'll ask when things come up. |
ded1bdb
to
62adca0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Web looks fine so far.
@eero-lehtinen would appreciate a rebase! |
b0f9f88
to
03707ec
Compare
@daxpedda Rebased |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate your enthusiasm on this issue and thank you for the PR.
However I don't think I'll merge this approach in the current state, especially given how everything is more complex and inconsistent. But it's not like I'll do a release either even if you add those changes (unless someone really asks me to do that).
Like the API should be simple
pub fn set_cursor(Window, icon: CursorIcon { NamedCursorIcon, Custom }
And that's really all it should be, everything else is on the downstream when dealing with that. Yes it can do everything on its own just about fine. No special changes will be required for that on any platform no fighting with Wayland, because it already does that.
I'll also write Wayland part myself, since clearly you never wrote wayland stuff.
Besides, when writing a massive patches, please, do ask in #winit
or on github issue, if we'd like to cope through review now, because otherwise your patch could stall until a good times.
It doesn't mean that the code will be discarded, because internally you're doing pretty much everything what should be done, it'll just be ported to a different API or you can port to the one I've suggested, where you just set cursor and don't do any registration, etc, because just setting it is more than enough (yes, client will just must reset it if they fill so).
The main problem seems to be how to handle multiple cursors without having to re-initialize them every time. Unfortunately to implement some @eero-lehtinen I believe following what @kchibisov has said here, this PR should be refactored into just a simple function on Some thoughts on that future PR: I think probably the best thing we can do here is as we discussed above: creating the cursor would require
After we finish and merge the first PR I will open an issue where we can discuss the details of that and if it's desirable in the first place. |
If you do that it'll work properly on Wayland, since wayland already draws custom cursors, they are just hidden, but it already does everything the same. The same with X11. So everything is properly dropped, etc in the way I said that because it's already how it works. For the future I wouldn't abuse event loop for it, I'd just callback to client to provide a new shape when DPI changes, and clients should cache them somehow. |
Just to make it clear. Caching could be done internally by the backends, you don't need to do any of that. It also doesn't need to be efficient when it comes to dropping. The way to approach this PR would be:
Like doing anything more complex than that doesn't worth it. Also, for wayland stuff, just do regular sw rendering pipeline expected by it. Look at SCTK examples how the draw software buffers and just create a Shm pool. Like this https://github.com/Smithay/client-toolkit/blob/master/examples/simple_window.rs#L139 should be fine, and then share this pool with every window, like it's already done internally with SCTK. You can look at pointer impl in it and on wayland-cursor crate. |
It's true, I don't know much about wayland. I will do the best baseline implementation I can and you guys can edit it to be the way you like.
Sorry. I just wanted a patch for myself and thought to post it here to see what you think. Anyway that didn't even work out because Bevy doesn't use 29 yet. I would have to port it to 28 to benefit from it right now.
I can port it to be that way. So basically always just a single function that always reallocates the cursor. My current solution tries to be more efficient but I guess creating a cursor even every frame won't be that taxing and will be simpler.
Thanks for the pointers. I think I was already looking at that when gobbling my solution together. |
You don't need to change cursor unless you change it every frame to something new, like when you're animating it. Once you set it, it's just being used and set back by winit when needed. |
Some games might want to change it every frame or at least call the function to make sure if there is no way to query what the current cursor is. |
Once you set the cursor it's winit job to keep it the same. Programs doing stupid things should get what they ask for. |
I don't think we disagree. The use case of changing custom cursors often exists and could be optimized for, but not in this pr. Edit: Or it is optimized currently, but I'll remove it as planned. |
I mean, you surely can try to optimize, but you don't need to expose any of that to the user. Like you can't drop cursors easily on all platforms (you can't on Wayland, you either append or purge all of them). |
741ec27
to
ef518c9
Compare
Co-authored-by: daxpedda <[email protected]>
Co-authored-by: daxpedda <[email protected]>
60fae4f
to
b8b1802
Compare
b8b1802
to
d337015
Compare
@eero-lehtinen I've fixed some style issue, but it should be good. |
Co-authored-by: daxpedda <[email protected]>
@eero-lehtinen thank you for your patience in seeing this through! Great work! |
Thanks for the help! |
Issue: #3005
Hello.
There seems to be many PRs relating to this issue, but they don't include all platforms and for some reason lost steam. This PR again tries to make this feature happen, and does it for all desktop platforms (x11, wayland, macos, windows, web).
Use case
I think the best user of this feature and the reason I'm doing this is Bevy and game engines in general. There non laggy hardware cursors with custom images are very important. Game devs also like their PNGs so supporting platform native cursor files is not that important, but I guess could be added too.
UPDATE: API
Instead of the things below, we have chosen to make the simplest possible API, where we have a single function for setting the cursor, and it internally recreates whatever is needed to display the cursor every time.
API 1
At first I tried to make a very simple api (in branch custom-cursors) where the user "registers" cursors by calling a window method with a rgba vector and a u64 key. Then when the user want's to change the cursor, they would just use this key. This was simple and efficient because the window itself would handle making and deleting the cursors and switching between them.
This API didn't seem very rusty. I thought that there was a simpler api hiding in there so I tried to make another one, which is in this PR.
API 2
This PR contains a (simpler?) api that allows users to create their own platform specific cursors that are held by smart pointers and automatically deallocated on drop. This way cursors can be swapped by just setting a single smart pointer with no registration step. Update: I moved this implementation to custom-cursors2-old.
This works wonderfully with windows, macos and web, but linux is really annoying. First of all it seems that all linux cursors would need to support both x11 and wayland, because there is no way to know what kind of event loop they will be inserted into. Secondly there seems to be no way to use smart pointers with wayland, because it needs to have a reference to the wayland connection. So now on wayland we just use an rgba vector so the wayland buffer can be recreated every time the user want's to swap cursors. Linux really was a lot simpler and more efficient with API 1.
API Conclusion for Me
So in the end I think that API 1 was better because it's just more efficient and simpler on linux. We should probably make the CursorImage struct platform dependent so it could be extended by different platforms. Also maybe we could use some kind of better handle compared to just u64?
What do you guys think about these apis?
I chose this branch (API 2) to show my thought process, but we could also continue the other branch.
Scaling
Currently screen scaling isn't handled. Different platforms have different interactions.
So in general we could solve this just by accepting an array of different sized images that could be used for different scales. Dunno what to do about the web and it's automatic scaling though.
Other Issues
wl_buffer.release
event, but I don't know much about that. Also seems to work without issues in practice.Even if this PR doesn't make it, at least here I show how to create cursors for all platforms :).
Checklist
CHANGELOG.md
if knowledge of this change could be valuable to users