mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
macOS pen pressure: a feed written on the UI thread never waits for a touch
This commit is contained in:
@@ -130,7 +130,8 @@ impl Pen {
|
|||||||
/// refuses the monitor or this isn't the main thread.
|
/// refuses the monitor or this isn't the main thread.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn start() -> Option<StylusFeed> {
|
pub fn start() -> Option<StylusFeed> {
|
||||||
let feed = StylusFeed::default();
|
// The monitor writes on the main thread before winit hands the event on: a press never waits.
|
||||||
|
let feed = StylusFeed::on_ui_thread();
|
||||||
match monitor::install(feed.clone()) {
|
match monitor::install(feed.clone()) {
|
||||||
Ok(()) => Some(feed),
|
Ok(()) => Some(feed),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ struct Shared {
|
|||||||
pen: Mutex<Pen>,
|
pen: Mutex<Pen>,
|
||||||
/// Signaled on every [`StylusFeed::set_sample`] ([`StylusFeed::set`] included).
|
/// Signaled on every [`StylusFeed::set_sample`] ([`StylusFeed::set`] included).
|
||||||
set: Condvar,
|
set: Condvar,
|
||||||
|
/// Written on the UI thread itself ([`StylusFeed::on_ui_thread`]): a press never waits.
|
||||||
|
ui_thread: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The pen pressure and pen end the host last read, written from any thread and read on the UI
|
/// The pen pressure and pen end the host last read, written from any thread and read on the UI
|
||||||
@@ -77,6 +79,12 @@ struct Shared {
|
|||||||
pub struct StylusFeed(Arc<Shared>);
|
pub struct StylusFeed(Arc<Shared>);
|
||||||
|
|
||||||
impl StylusFeed {
|
impl StylusFeed {
|
||||||
|
/// A feed the host writes on the UI thread, before the UI handles the event it read (macOS):
|
||||||
|
/// a press has its touch already, and waiting for one would only stall the thread.
|
||||||
|
pub fn on_ui_thread() -> Self {
|
||||||
|
Self(Arc::new(Shared { ui_thread: true, ..Shared::default() }))
|
||||||
|
}
|
||||||
|
|
||||||
fn lock(&self) -> MutexGuard<'_, Pen> {
|
fn lock(&self) -> MutexGuard<'_, Pen> {
|
||||||
self.0.pen.lock().unwrap_or_else(|e| e.into_inner())
|
self.0.pen.lock().unwrap_or_else(|e| e.into_inner())
|
||||||
}
|
}
|
||||||
@@ -160,7 +168,7 @@ impl StylusFeed {
|
|||||||
|
|
||||||
fn press_within(&self, wait: Duration) -> Option<f32> {
|
fn press_within(&self, wait: Duration) -> Option<f32> {
|
||||||
let mut pen = self.lock();
|
let mut pen = self.lock();
|
||||||
if pen.hovering() {
|
if pen.hovering() && !self.0.ui_thread {
|
||||||
pen = self.wait_for_touch(pen, wait);
|
pen = self.wait_for_touch(pen, wait);
|
||||||
}
|
}
|
||||||
let peak = pen.peak.take();
|
let peak = pen.peak.take();
|
||||||
@@ -385,4 +393,15 @@ mod tests {
|
|||||||
assert_eq!(feed.press_within(Duration::from_secs(10)), None);
|
assert_eq!(feed.press_within(Duration::from_secs(10)), None);
|
||||||
assert!(start.elapsed() < Duration::from_secs(5));
|
assert!(start.elapsed() < Duration::from_secs(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A feed written on the UI thread (macOS) has nothing to wait for: a hovering pen's press
|
||||||
|
/// gets its 0 at once rather than stalling the thread.
|
||||||
|
#[test]
|
||||||
|
fn a_feed_written_on_the_ui_thread_never_waits() {
|
||||||
|
let feed = StylusFeed::on_ui_thread();
|
||||||
|
feed.set(Some(0.0));
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
assert_eq!(feed.press_within(Duration::from_secs(10)), Some(0.0));
|
||||||
|
assert!(start.elapsed() < Duration::from_secs(5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user