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 cursor_position getter API #2648

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

amrbashir
Copy link
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
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
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
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
Contributor Author

Wayland yes, macOS should be possible, no?

@amrbashir
Copy link
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
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
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
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
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
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
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.

src/event_loop.rs Show resolved Hide resolved
src/window.rs Outdated Show resolved Hide resolved
src/window.rs Outdated Show resolved Hide resolved
src/platform_impl/macos/util/mod.rs Outdated Show resolved Hide resolved
@filnet
Copy link
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
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
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.

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

src/changelog/unreleased.md Outdated Show resolved Hide resolved
@amrbashir
Copy link
Contributor Author

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

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

@@ -490,6 +491,16 @@ impl ActiveEventLoop {
platform: self.p.owned_display_handle(),
}
}

/// Returns the current cursor position in screen coordinates.
Copy link
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
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
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
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).

src/event_loop.rs Show resolved Hide resolved
@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
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 - macos DS - windows DS - x11 S - api Design and usability
Development

Successfully merging this pull request may close these issues.

None yet

6 participants