Skip to content

Add cursor_position getter API#2648

Open
amrbashir wants to merge 22 commits intorust-windowing:masterfrom
amrbashir:feat/cursor-position
Open

Add cursor_position getter API#2648
amrbashir wants to merge 22 commits intorust-windowing:masterfrom
amrbashir:feat/cursor-position

Conversation

@amrbashir
Copy link
Copy Markdown
Contributor

@amrbashir amrbashir commented Jan 24, 2023

  • Tested on all platforms changed
    • Windows
    • macOS
    • X11
  • 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

@filnet
Copy link
Copy Markdown
Contributor

filnet commented Jan 24, 2023

What's the motivation for getting the cursor position with the new function over getting it via an event ?

@amrbashir
Copy link
Copy Markdown
Contributor Author

amrbashir commented Jan 24, 2023

This is useful for positioning the window on a particular monitor when creating the window, for example, when making a spotlight-like app, where you want to show the window on the monitor the has the cursor, then I would need to:

  1. get the cursor location
  2. get the monitor based on the cursor location
  3. center the app on the monitor

This PR is for 1 and I will be opening another PR for 2, later today or tomorrow.

@kchibisov
Copy link
Copy Markdown
Member

get the cursor location
get the monitor based on the cursor location

This won't work on macOS/Wayland for sure?

@amrbashir
Copy link
Copy Markdown
Contributor Author

Wayland yes, macOS should be possible, no?

@amrbashir
Copy link
Copy Markdown
Contributor Author

for macOS there is no direct API to get a monitor based on a point but we can iterate over available monitors and check if the point is contained within one of them

@kchibisov
Copy link
Copy Markdown
Member

Wayland yes, macOS should be possible, no?

On Wayland certainly not. Since you know only about the cursor over your window. You don't even have control were to open a window, so use-case you're describing is very specific and can be achieved on X11 and maybe Windows.

@kchibisov
Copy link
Copy Markdown
Member

And in my experience normal window managers will open a new window where your cursor is if you don't explicitly specify the output you want(like on Wayland it's done by majority).

@amrbashir
Copy link
Copy Markdown
Contributor Author

yeah mostly you don't need to manually position your window but there is use-cases where you want to control which monitor to spawn the window on, for example: spotlight-like apps, widgets, overlays...etc

@kchibisov
Copy link
Copy Markdown
Member

But you already have all in-place for that? You could just report current_monitor on the event_loop or such?

@ids1024
Copy link
Copy Markdown
Member

ids1024 commented Jan 24, 2023

On Wayland certainly not. Since you know only about the cursor over your window. You don't even have control were to open a window, so use-case you're describing is very specific and can be achieved on X11 and maybe Windows.

You should be able to implement a centered "spotlight-like" app like this on Wayland with layer-shell (in compositors that support it), but yeah, you couldn't implement it this way.

Copy link
Copy Markdown
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.

macOS impl approved, unsure about desired API, I'll leave that up for you to decide on.

@filnet
Copy link
Copy Markdown
Contributor

filnet commented Jan 30, 2023

This is useful for positioning the window on a particular monitor when creating the window, for example, when making a spotlight-like app, where you want to show the window on the monitor the has the cursor, then I would need to:

1. get the cursor location

2. get the monitor based on the cursor location

3. center the app on the monitor

This PR is for 1 and I will be opening another PR for 2, later today or tomorrow.

May be you can keep 1 private for 2 ?

@amrbashir
Copy link
Copy Markdown
Contributor Author

amrbashir commented Jan 30, 2023

May be you can keep 1 private for 2 ?

2 has been rejected in #2649 so this API is no longer connected to 2 directly

@ids1024
Copy link
Copy Markdown
Member

ids1024 commented Jan 30, 2023

As I mentioned earlier, the "spotlight-like app" use case on Wayland would be served by layer shell (#2582). I think what would be ideal for that is if either winit or an extension crate could provide an API that can use layer shell, or position things more manually on X/win32/etc. to provide as portable a solution as possible for this particular use case.

I would generally agree with the authors of the base Wayland protocol that applications placing windows at specific spots on screen is generally a bad practice outside of specialized things like this (though Winit already has set_outer_position).

#2160 is relevant, wrt including things in winit vs a separate crate.

@daxpedda daxpedda added DS - win32 Affects the Win32/Windows backend DS - x11 Affects the X11 backend, or generally free Unix platforms labels Feb 27, 2024
Copy link
Copy Markdown
Member

@daxpedda daxpedda left a comment

Choose a reason for hiding this comment

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

We just decided in the meeting that we are happy to move forward with this.
The coordinate system used here should be the same as for all other APIs covering the cursor position.

There was also a concern raised about multiple pointers, which is something that we decided we will handle separately but will most likely include adding a device ID parameter.

@daxpedda daxpedda removed the C - nominated Nominated for discussion in the next meeting label Mar 15, 2024
@amrbashir amrbashir requested a review from daxpedda March 26, 2024 03:33
Copy link
Copy Markdown
Member

@daxpedda daxpedda left a comment

Choose a reason for hiding this comment

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

LGTM.
Can't review the relevant backends though and the CI needs to pass.

@amrbashir
Copy link
Copy Markdown
Contributor Author

Seems like a couple of tests are failing on nightly but should be unrelated to this PR

Copy link
Copy Markdown
Member

@daxpedda daxpedda left a comment

Choose a reason for hiding this comment

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

Thanks!

CI should be fixed after #3604.

}
}

/// Returns the current cursor position in screen coordinates.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Referencing #2648 (review).

I think we thought this was on Window, and hence expected things to be in window coordinates, just like the coordinates for set_cursor_position (such that window.set_cursor_position(window.cursor_position()?)? is (roughly) a no-op). But we decided against Window::cursor_position in https://github.com/rust-windowing/winit/pull/2648/files#r1090072945, this API is ActiveEventLoop::cursor_position.

In that case, I'd expect the coordinates to be the same as those from Window::outer_position, is that correct? If so, could you refer to that for discussion about the coordinate space, just like Window::set_outer_position does?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(If you think that this interpretation is correct, I'll test the macOS implementation myself to ensure that it matches Window::outer_position).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In that case, I'd expect the coordinates to be the same as those from Window::outer_position, is that correct?

Yeah

If so, could you refer to that for discussion about the coordinate space, just like Window::set_outer_position does?

like this amrbashir@1f9a3df ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yup.

And I've tested it now, and pushed a fix to return positions with the correct scaling and such (it's still a little broken, but that's a more general issue, see #3615).

@kchibisov kchibisov added the C - nominated Nominated for discussion in the next meeting label Mar 29, 2024
@kchibisov kchibisov self-requested a review March 29, 2024 15:42
///
/// - **iOS / Android / Wayland / Orbital / Web**: Unsupported.
#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It confused me that the return type of this is not PhysicalPosition<i32> like the return type of Window::outer_position, but I guess it matches the CursorMoved event - apparently cursors can be positioned on a sub-pixel scale, didn't know that!

We needed to flip and scale the coordinates, as is usual for macOS'
screen coordinates.
@daxpedda daxpedda removed the C - nominated Nominated for discussion in the next meeting label Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C - waiting on maintainer A maintainer must review this code DS - appkit Affects the AppKit/macOS backend DS - win32 Affects the Win32/Windows backend DS - x11 Affects the X11 backend, or generally free Unix platforms S - api Design and usability

Development

Successfully merging this pull request may close these issues.

6 participants