Skip to content

Commit

Permalink
fix: scale cursor_position (#712)
Browse files Browse the repository at this point in the history
* fix: scale cursor_position, closes #708

* adjust for wayland

* Add macOS fix

---------

Co-authored-by: Wu Wayne <[email protected]>
  • Loading branch information
amrbashir and wusyong authored Mar 8, 2023
1 parent ea2e60d commit dc913cd
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changes/cursor-position-scale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": "patch"
---

Fix `Window::cursor_position` and `EventLoopWindowTarget::cursor_position` scale on Linux and macOS.
2 changes: 1 addition & 1 deletion src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl<T> EventLoopWindowTarget<T> {
///
/// ## Platform-specific
///
/// - **iOS / Android**: Unsupported.
/// - **iOS / Android / Linux(Wayland)**: Unsupported, returns `0,0`.
#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
self.p.cursor_position()
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/linux/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl<T> EventLoopWindowTarget<T> {

#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
util::cursor_position()
util::cursor_position(self.is_wayland())
}
}

Expand Down
32 changes: 24 additions & 8 deletions src/platform_impl/linux/util.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
use gdk::Display;

use crate::{dpi::PhysicalPosition, error::ExternalError};
use crate::{
dpi::{LogicalPosition, PhysicalPosition},
error::ExternalError,
};

#[inline]
pub fn cursor_position() -> Result<PhysicalPosition<f64>, ExternalError> {
Display::default()
.and_then(|d| d.default_seat())
.and_then(|s| s.pointer())
.map(|p| p.position_double())
.map(|(_, x, y)| (x, y).into())
.ok_or(ExternalError::Os(os_error!(super::OsError)))
pub fn cursor_position(is_wayland: bool) -> Result<PhysicalPosition<f64>, ExternalError> {
if is_wayland {
Ok((0, 0).into())
} else {
Display::default()
.map(|d| {
(
d.default_seat().and_then(|s| s.pointer()),
d.default_group(),
)
})
.map(|(p, g)| {
p.map(|p| {
let (_, x, y) = p.position_double();
LogicalPosition::new(x, y).to_physical(g.scale_factor() as _)
})
})
.map(|p| p.ok_or(ExternalError::Os(os_error!(super::OsError))))
.ok_or(ExternalError::Os(os_error!(super::OsError)))?
}
}
2 changes: 1 addition & 1 deletion src/platform_impl/linux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ impl Window {

#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
util::cursor_position()
util::cursor_position(self.window.display().backend().is_wayland())
}

pub fn current_monitor(&self) -> Option<RootMonitorHandle> {
Expand Down
7 changes: 6 additions & 1 deletion src/platform_impl/macos/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,12 @@ impl<T: 'static> EventLoopWindowTarget<T> {

#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
util::cursor_position()
let point = util::cursor_position()?;
if let Some(m) = self.monitor_from_point(point.x, point.y) {
Ok(point.to_physical(m.scale_factor()))
} else {
Err(ExternalError::Os(os_error!(super::OsError::CGError(0))))
}
}
}

Expand Down
10 changes: 3 additions & 7 deletions src/platform_impl/macos/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ use core_graphics::{
};
use objc::runtime::{Class, Object, Sel, BOOL, YES};

use crate::{
dpi::{LogicalPosition, PhysicalPosition},
error::ExternalError,
platform_impl::platform::ffi,
};
use crate::{dpi::LogicalPosition, error::ExternalError, platform_impl::platform::ffi};

// Replace with `!` once stable
#[derive(Debug)]
Expand Down Expand Up @@ -129,11 +125,11 @@ pub fn window_position(position: LogicalPosition<f64>) -> NSPoint {
}

// FIXME: This is actually logical position.
pub fn cursor_position() -> Result<PhysicalPosition<f64>, ExternalError> {
pub fn cursor_position() -> Result<LogicalPosition<f64>, ExternalError> {
if let Ok(s) = CGEventSource::new(CGEventSourceStateID::CombinedSessionState) {
if let Ok(e) = CGEvent::new(s) {
let pt = e.location();
let pos = PhysicalPosition::new(pt.x, pt.y);
let pos = LogicalPosition::new(pt.x, pt.y);
return Ok(pos);
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,12 @@ impl UnownedWindow {

#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
util::cursor_position()
let point = util::cursor_position()?;
if let Some(m) = self.monitor_from_point(point.x, point.y) {
Ok(point.to_physical(m.scale_factor()))
} else {
Err(ExternalError::Os(os_error!(OsError::CGError(0))))
}
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ impl Window {
///
/// ## Platform-specific
///
/// - **iOS / Android**: Unsupported, returns `0,0`.
/// - **iOS / Android / Linux(Wayland)**: Unsupported, returns `0,0`.
#[inline]
pub fn cursor_position(&self) -> Result<PhysicalPosition<f64>, ExternalError> {
self.window.cursor_position()
Expand Down

0 comments on commit dc913cd

Please sign in to comment.