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

Add support of using custom image as cursor icon on windows #2833

Closed

Conversation

Icemic
Copy link

@Icemic Icemic commented Jun 1, 2023

  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

Adds a Window::set_cursor_custom_icon method, which we can pass an Icon to. And this icon is sightly different from a icon created by Icon::from_rgba, because it lacks of hotspot infomation (default to the center of image in fact), so I add an Icon::from_rgba_cursor which has extra hotspot parameters.

A custom cursor icon has higher priority than system cursor once it is set (when processing WM_SETCURSOR). And custom cursor icon will be dropped if Window::set_cursor_icon is called again.

This feature is only added to Windows platform for now, and .cur or .ani format is also not supported for potential cross-platform requirements.

Maybe a common Cursor struct should be added instead of reusing Icon, but on Windows an icon or cursor is not strictly differentiated and I haven't delved into the api of other platforms yet. So I just make minimal changes.

Copy link
Member

@msiglreith msiglreith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I would prefer a dedicated cusor type, where to user can create cursor with a standard icon or with a custom one. At least on X11 IIRC the cursor and icons are different types and mixing them will lead to issues. This would also help to keep a single entry point for the setting the cursor.

Copy link
Member

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a dedicated cusor type, where to user can create cursor with a standard icon or with a custom one. At least on X11 IIRC the cursor and icons are different types and mixing them will lead to issues. This would also help to keep a single entry point for the setting the cursor.

Fully agree, custom cursors are also supportable on macOS and web, both of which define PlatformIcon as NoIcon.

We should also consider how this will interact with the cursor-icon crate.

@kchibisov
Copy link
Member

Yeah, we might add a variant to cursor-icon crate with the custom cursor image. I'd assume some ARGB variant should be fine.

@madsmtm
Copy link
Member

madsmtm commented Jun 5, 2023

cursor_icon::CursorIcon is Copy, so that may be difficult, and perhaps not desired either? There is value in keeping that crate clean of cludges / additions like this.

Instead, we could do something like this (in winit):

// Bikeshed names
pub struct CustomCursorRGBA { ... }
pub struct CustomCursorURL { ... }

trait CursorIconTrait: Sealed { ... }

impl CursorIconTrait for cursor_icon::CursorIcon { ... }
impl CursorIconTrait for CustomCursorRGBA { ... }
impl CursorIconTrait for CustomCursorURL { ... }

impl Window {
    fn set_cursor_icon(&self, icon: impl CursorIconTrait) { ... }
}

//
// Or alternatively:
//

// Bikeshed name
#[non_exhaustive]
pub enum CursorIconEnum {
    Standard(cursor_icon::CursorIcon),
    CustomRGBA(...),
    // E.g. for web
    CustomURL(Url),
}

impl From<cursor_icon::CursorIcon> for CursorIconEnum { ... }
impl From<...> for CursorIconEnum { ... }
impl From<Url> for CursorIconEnum { ... }

impl Window {
    fn set_cursor_icon(&self, icon: impl Into<CursorIconEnum>) { ... }
}

@Icemic
Copy link
Author

Icemic commented Jun 5, 2023

Thank you for reviews!

My intention was to implement this feature quickly so that it would be available as soon as possible, but this did really lack design as well.
I agree with everyone if we want to design it perfectly.

In addition, I suggest we collect the features of the custom mouse pointer under each platform, including the types supported (built-in, general image, proprietary format, url, animated cursor, etc.).

I am more familiar with windows and web:

On Windows, it supports both general images like png and its proprietary format (.cur & .ani), but with different winapi, which means if a Vec is provided it is hard to determind which kind of winapi should be used. For general images, hotspot should be provided or it will use the center of image.

On Web, it supports built-ins, url and binary(Data URI). And for the latter two cases, general images like png, a Windows proprietary format .cur (.ani is not supported) and even SVG is supported. In addition, for general images or SVG, hotspot should be provided or it will a default value.

So, it may not be enough to just divide them to standard, RGBA and URL. For all cases on all the platforms, a sheet shall be made to help tidy it up.

@kchibisov
Copy link
Member

I could add that on Wayland you simply provide and RGBA buffer because you draw the cursor. The animation is also done by you or by compositor, when using named cursors.

@daxpedda
Copy link
Member

@Icemic we currently have a fully working implementation in #3218 for all backends which went through quite a bit of design work already.

Feel free to drop a review for the Windows backend :)

@madsmtm
Copy link
Member

madsmtm commented Dec 17, 2023

Superseded by #3218

@madsmtm madsmtm closed this Dec 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants