-
Notifications
You must be signed in to change notification settings - Fork 175
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
Change PointerHandle.motion
and friends to take relative coords
#1223
base: master
Are you sure you want to change the base?
Conversation
4236e1e
to
f7fb1c4
Compare
I can't get anvil to run on my machine for (it appears unrelated) reasons, so I haven't tested that part. It occurs to me that this will probably result in confusing behavior for existing compositors who update without knowing. I don't really know how to mitigate that. |
Hm, this is kinda lackluster. Taking another stab at this with a newtype to flush out cases I missed. |
e574574
to
5ceb562
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1223 +/- ##
========================================
Coverage 21.76% 21.76%
========================================
Files 155 156 +1
Lines 24373 24490 +117
========================================
+ Hits 5305 5331 +26
- Misses 19068 19159 +91
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Ok, I think this is much better now. I introduced a type, I find the new API is a bit more intuitive (I got confused that This has the extra benefit that the calculation |
PointerHandle.motion
to take relative coordsPointerHandle.motion
and friends to take relative coords
focus: Some((root.into(), (0, 0).into())), | ||
focus: Some(RelativePoint { | ||
surface: root.into(), | ||
loc: (0f64, 0f64).into(), |
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 wanted to highlight this as something I really wasn't sure about.
0880050
to
c624329
Compare
Before giving this a proper review, note that I would love to have proper API in smithay to support overriding scale factors of windows and/or globally for Xwayland. |
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.
Couple of nitpicks. I like the general approach, this seems more flexible without introducing too much friction in the api.
/// Represents a point on a surface, relative to that surface's origin in | ||
/// global compositor space. | ||
#[derive(Debug, Clone)] | ||
pub struct RelativePoint<S> { |
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 am not a huge fan of this name, as it is used to denote the focus of the pointer and the relative location. I don't think specifying the relative aspect in the name is most important, if surface
and loc
have good documentation.
I am open to some bike shedding over the name, but I am leaning towards something like FocusedPoint
or FocusPoint
?
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.
That's what I originally had, but I realized I had to move it out of the input::pointer
mod because it's used by grab
code. Once I moved it into utils
, it seemed appropriate to give it more of a general name (Focus
being an input-specific concept).
Happy to place/name it whatever you like, just wanted to add that context. My suggestion given your constraints would be SurfaceCoordinate
or SurfacePoint
or similar.
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.
SurfacePoint
That is also a good one, but given a focused element doesn't have to be a surface, RelativePoint
does seem to capture this quite well. 😅
src/input/pointer/mod.rs
Outdated
let event = MotionEvent { | ||
location: event.location - surface_location.to_f64(), | ||
location: focus.loc.to_f64(), |
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.
So we are not using the MotionEvent
location anymore at all? I quite dislike that to be honest, because that means we pass in multiple locations, but ignore some of them. In that case please change the signature of motion
to not take a MotionEvent
, but directly the serial
and time
.
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.
event.location
is still used to set self.location
, which is provided by PointerHandle.current_location
, for example.
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.
event.location is still used to set self.location
Right... Maybe we should then at least rename MotionEvent::location
to global_location
or absolute_location
to further differenciate the two values?
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.
Done in e3a9927.
The existing API was helpful in that it made it harder to mess up the math, but not flexible enough to support having different windows with different scaling factors. That's relevent if, for example, you want to force a scale factor of 1 for Xwayland windows.
c624329
to
180b08e
Compare
Sorry for the delay! Updated to address comments. |
Renaming smithay/src/desktop/wayland/layer.rs Line 729 in 859ed44
But I'm not sure. |
It is correct, the issue is that And I think this the core issue, that makes this api feel so weird. We probably don't want to use the same type here, as this is confusing at best. This fits quite nicely with a discussion we recently had of introducing |
I took a stab at making #[derive(Debug)]
pub struct GlobalOrigin;
#[derive(Debug)]
pub struct SurfaceOrigin;
/// Pointer motion event
#[derive(Debug)]
pub struct MotionEvent<Origin> {
/// Location of the pointer. If `Origin` is `SurfaceOrigin`, the coordinates
/// are relative to the origin of the surface. If `Origin` is `GlobalOrigin`, it is a
/// location in global compositor space.
pub location: Point<f64, Logical>,
/// Serial of the event
pub serial: Serial,
/// Timestamp of the event, with millisecond granularity
pub time: u32,
_origin: std::marker::PhantomData<Origin>,
} The problem is still that lots of functions take an optional /// Notify that the pointer moved
///
/// You provide the new location of the pointer, in the form of:
///
/// - The surface that the cursor is on top of, and
/// - The coordinates of the cursor relative to the origin of that surface
///
/// A value of None indicates that no surface is focused, and the
/// coordinates of the MotionEvent will be ignored.
///
/// This will internally take care of notifying the appropriate client
/// objects of enter/motion/leave events.
#[instrument(level = "trace", parent = &self.span, skip(self, data, focus))]
pub fn motion(&self, data: &mut D, focus: Option<D::PointerFocus>, event: &MotionEvent<SurfaceOrigin>) {
// ...
} Here, if I see two possibilities:
I think I like 2 the best. |
I agree, that 2. sounds like a good solution. |
Naively trying to understand this -- If MotionEvent doesn't have location, how do we gather where the pointer moved in |
The |
I don't think With |
The existing API is helpful in that it makes it harder to mess up the math, but it's not flexible enough to support having different windows with different scaling factors. That's relevant if, for example, you want to force a scale factor of 1 for Xwayland windows.
The existing API takes
Option<(<D as SeatHandler>::PointerFocus, Point<i32, Logical>)>
, with the point being the surface origin, rather than the relative coordinates of the point on that surface. Then, internally, it converts into relative coordinates to generate the wayland event. A user familiar with wayland but not reading the documentation closely might think that the point should be the relative coords, not the surface origin (this happened to me).Additionally, if you have different scale factors for different windows, it's impossible (or very difficult) to get the calculation right, since smithay is assuming that the coordinate space for the surface is the same as the global compositor space.