Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions crates/kas-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ dark-light = { version = "2.0", optional = true }
raw-window-handle = "0.6.0"
async-global-executor = { version = "3.1.0", optional = true }
cfg-if = "1.0.0"
smol_str = "0.2.0"
smol_str = "0.3.2"
hash_hasher = "2.0.4"
accesskit = { version = "0.21.0", optional = true }
accesskit_winit = { version = "0.29.0", optional = true }
Expand All @@ -128,9 +128,11 @@ version = "0.5.0" # used in doc links

[dependencies.winit]
# Provides translations for several winit types
version = "0.30.1"
version = "0.30.12"
# path = "../../../../window/winit/winit"
git = "https://github.com/dhardy/winit.git"
branch = "push-vyvulynwwlxu"
default-features = false
features = ["rwh_06"]

[lints.clippy]
module_inception = "allow"
Expand Down
32 changes: 16 additions & 16 deletions crates/kas-core/src/config/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Shortcuts {
/// Load default shortcuts for the current platform
pub fn load_platform_defaults(&mut self) {
#[cfg(target_os = "macos")]
const CMD: ModifiersState = ModifiersState::SUPER;
const CMD: ModifiersState = ModifiersState::META;
#[cfg(not(target_os = "macos"))]
const CMD: ModifiersState = ModifiersState::CONTROL;

Expand Down Expand Up @@ -163,7 +163,7 @@ impl Shortcuts {
// Ctrl + Command (MacOS)
#[cfg(target_os = "macos")]
{
let modifiers = ModifiersState::CONTROL | ModifiersState::SUPER;
let modifiers = ModifiersState::CONTROL | ModifiersState::META;
let map = self.map.entry(modifiers).or_insert_with(Default::default);
map.insert(Key::Character("f".into()), Command::Fullscreen);
}
Expand Down Expand Up @@ -290,25 +290,25 @@ mod common {
const SHIFT: ModifiersState = ModifiersState::SHIFT;
const CONTROL: ModifiersState = ModifiersState::CONTROL;
const ALT: ModifiersState = ModifiersState::ALT;
const SUPER: ModifiersState = ModifiersState::SUPER;
const META: ModifiersState = ModifiersState::META;

let s = match self.0 {
state if state == ModifiersState::empty() => "none",
SUPER => "super",
META => "meta",
ALT => "alt",
state if state == ALT | SUPER => "alt-super",
state if state == ALT | META => "alt-meta",
state if state == CONTROL => "ctrl",
state if state == CONTROL | SUPER => "ctrl-super",
state if state == CONTROL | META => "ctrl-meta",
state if state == CONTROL | ALT => "ctrl-alt",
state if state == CONTROL | ALT | SUPER => "ctrl-alt-super",
state if state == CONTROL | ALT | META => "ctrl-alt-meta",
SHIFT => "shift",
state if state == SHIFT | SUPER => "shift-super",
state if state == SHIFT | META => "shift-meta",
state if state == SHIFT | ALT => "alt-shift",
state if state == SHIFT | ALT | SUPER => "alt-shift-super",
state if state == SHIFT | ALT | META => "alt-shift-meta",
state if state == SHIFT | CONTROL => "ctrl-shift",
state if state == SHIFT | CONTROL | SUPER => "ctrl-shift-super",
state if state == SHIFT | CONTROL | META => "ctrl-shift-meta",
state if state == SHIFT | CONTROL | ALT => "ctrl-alt-shift",
_ => "ctrl-alt-shift-super",
_ => "ctrl-alt-shift-meta",
};

serializer.serialize_str(s)
Expand All @@ -319,7 +319,7 @@ mod common {
type Value = ModifiersStateDeser;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("none or (sub-set of) ctrl-alt-shift-super")
formatter.write_str("none or (sub-set of) ctrl-alt-shift-meta")
}

fn visit_str<E: de::Error>(self, u: &str) -> Result<Self::Value, E> {
Expand Down Expand Up @@ -347,8 +347,8 @@ mod common {
v = &v[v.len().min(5)..];
adv_dash_if_not_empty(&mut v);
}
if v.starts_with("super") {
state |= ModifiersState::SUPER;
if v.starts_with("meta") {
state |= ModifiersState::META;
v = &v[v.len().min(5)..];
}

Expand All @@ -357,7 +357,7 @@ mod common {
} else {
Err(E::invalid_value(
de::Unexpected::Str(u),
&"none or (sub-set of) ctrl-alt-shift-super",
&"none or (sub-set of) ctrl-alt-shift-meta",
))
}
}
Expand Down Expand Up @@ -469,7 +469,7 @@ mod deser {
type Value = OptModifiersStateDeser;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("none or (sub-set of) ctrl-alt-shift-super or other")
formatter.write_str("none or (sub-set of) ctrl-alt-shift-meta or other")
}

fn visit_str<E: de::Error>(self, u: &str) -> Result<Self::Value, E> {
Expand Down
4 changes: 2 additions & 2 deletions crates/kas-core/src/event/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,8 @@ impl TextInput {
Phase::Cursor(_, coord) => Action::CursorEnd { coord },
},
Event::Timer(TIMER_SELECT) => match self.phase {
Phase::PressStart(touch_id, coord) => {
self.phase = Phase::Cursor(touch_id, coord);
Phase::PressStart(source, coord) => {
self.phase = Phase::Cursor(source, coord);
Action::CursorStart {
coord,
clear: !cx.modifiers().shift_key(),
Expand Down
14 changes: 10 additions & 4 deletions crates/kas-core/src/event/cx/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,15 @@ impl<'a> EventCx<'a> {

pub(super) fn ime_event(&mut self, widget: Node<'_>, ime: Ime) {
match ime {
winit::event::Ime::Enabled => {
Ime::Enabled => {
// We expect self.ime.is_some(), but it's possible that the request is outdated
if self.ime.is_some()
&& let Some(id) = self.sel_focus.clone()
{
self.send_event(widget, id, Event::ImeFocus);
}
}
winit::event::Ime::Disabled => {
Ime::Disabled => {
// We can only assume that this is received due to us disabling
// IME if self.old_ime_target is set, and is otherwise due to an
// external cause.
Expand All @@ -380,14 +380,20 @@ impl<'a> EventCx<'a> {
self.send_event(widget, id, Event::LostImeFocus);
}
}
winit::event::Ime::Preedit(text, cursor) => {
Ime::Preedit(text, cursor) => {
if self.ime.is_some()
&& let Some(id) = self.sel_focus.clone()
{
self.send_event(widget, id, Event::ImePreedit(&text, cursor));
}
}
winit::event::Ime::Commit(text) => {
Ime::DeleteSurrounding {
before_bytes,
after_bytes,
} => {
// TODO
}
Ime::Commit(text) => {
if self.ime.is_some()
&& let Some(id) = self.sel_focus.clone()
{
Expand Down
64 changes: 28 additions & 36 deletions crates/kas-core/src/event/cx/press.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ mod mouse;
mod touch;
pub(crate) mod velocity;

use std::mem::transmute;

#[allow(unused)] use super::{Event, EventState}; // for doc-links
use super::{EventCx, IsUsed};
#[allow(unused)] use crate::Events; // for doc-links
use crate::event::{CursorIcon, MouseButton, Unused, Used};
use crate::geom::{Coord, DVec2, Offset, Vec2};
use crate::{Action, Id};
use cast::{CastApprox, Conv};
use cast::{Cast, CastApprox, Conv};
pub(crate) use mouse::Mouse;
pub(crate) use touch::Touch;
use winit::event::FingerId;

/// Controls the types of events delivered by [`PressStart::grab`]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
Expand Down Expand Up @@ -65,9 +64,9 @@ impl GrabMode {

/// Source of a [`Press`] event
///
/// This identifies the source of a click, touch or similar event, including
/// which mouse button is pressed and whether this is a double-click (see
/// [`Self::repetitions`]).
/// This identifies the source of a click, touch or pointer motion. It
/// identifies which mouse button is pressed (if any) and whether this is a
/// double-click (see [`Self::repetitions`]).
///
/// This may be used to track a click/touch, but note that identifiers may be
/// re-used after the event completes, thus an [`Event::PressStart`] with
Expand All @@ -81,15 +80,17 @@ impl PressSource {
const FLAG_TOUCH: u64 = 1 << 63;

/// Construct a mouse source
pub(crate) fn mouse(button: MouseButton, repetitions: u32) -> Self {
pub(crate) fn mouse(button: Option<MouseButton>, repetitions: u32) -> Self {
let r = (repetitions as u64) << 32;
debug_assert!(r & Self::FLAG_TOUCH == 0);
let b: u32 = unsafe { transmute(button) };
// Note: MouseButton::try_from_u8 returns None on u8::MAX
let b = button.map(|b| b as u8).unwrap_or(u8::MAX);
Self(r | b as u64)
}

/// Construct a touch source
pub(crate) fn touch(id: u64) -> Self {
pub(crate) fn touch(finger_id: FingerId) -> Self {
let id = u64::conv(finger_id.into_raw());
// Investigation shows that almost all sources use a 32-bit identifier.
// The only exceptional winit backend is iOS, which uses a pointer.
assert!(id & Self::FLAG_TOUCH == 0);
Expand All @@ -108,23 +109,24 @@ impl PressSource {
self.0 & Self::FLAG_TOUCH != 0
}

/// Returns the touch identifier if this represents a touch event
fn touch_id(self) -> Option<u64> {
/// Returns the finger identifier if this represents a touch event
fn finger_id(self) -> Option<FingerId> {
if self.is_touch() {
Some(self.0 & !Self::FLAG_TOUCH)
let id = self.0 & !Self::FLAG_TOUCH;
Some(FingerId::from_raw(id.cast()))
} else {
None
}
}

/// Identify the mouse button used
///
/// This always returns `Some(_)` for mouse events and `None` for touch
/// events.
/// This returns `Some(button)` for mouse events with a button. It returns
/// `None` for touch events and mouse events without a button (e.g. motion).
pub fn mouse_button(self) -> Option<MouseButton> {
if self.is_mouse() {
let b = self.0 as u32;
Some(unsafe { transmute::<u32, MouseButton>(b) })
let b = self.0 as u8;
MouseButton::try_from_u8(b)
} else {
None
}
Expand All @@ -133,29 +135,19 @@ impl PressSource {
/// Returns true if this represents the left mouse button or a touch event
#[inline]
pub fn is_primary(self) -> bool {
match self.mouse_button() {
None => true,
Some(MouseButton::Left) => true,
Some(_) => false,
}
self.is_touch() || self.mouse_button() == Some(MouseButton::Left)
}

/// Returns true if this represents the right mouse button
#[inline]
pub fn is_secondary(self) -> bool {
match self.mouse_button() {
Some(MouseButton::Right) => true,
None | Some(_) => false,
}
self.mouse_button() == Some(MouseButton::Right)
}

/// Returns true if this represents the middle mouse button
#[inline]
pub fn is_tertiary(self) -> bool {
match self.mouse_button() {
Some(MouseButton::Middle) => true,
None | Some(_) => false,
}
self.mouse_button() == Some(MouseButton::Middle)
}

/// The `repetitions` value
Expand Down Expand Up @@ -321,10 +313,10 @@ impl GrabBuilder {
mode,
cursor.unwrap_or_default(),
)
} else if let Some(touch_id) = source.touch_id() {
cx.touch.start_grab(touch_id, id.clone(), position, mode)
} else if let Some(finger_id) = source.finger_id() {
cx.touch.start_grab(finger_id, id.clone(), position, mode)
} else {
unreachable!()
false
};

if success {
Expand Down Expand Up @@ -413,8 +405,8 @@ impl EventState {
old = grab.depress.take();
grab.depress = target.clone();
}
} else if let Some(id) = source.touch_id() {
if let Some(grab) = self.touch.get_touch(id) {
} else if let Some(finger_id) = source.finger_id() {
if let Some(grab) = self.touch.get_touch(finger_id) {
redraw = grab.depress != target;
old = grab.depress.take();
grab.depress = target.clone();
Expand Down Expand Up @@ -458,8 +450,8 @@ impl EventState {
let evc = self.config().event();
if source.is_mouse() {
Some(self.mouse.samples.velocity(evc.kinetic_timeout()))
} else if let Some(id) = source.touch_id() {
self.touch.velocity(id, evc)
} else if let Some(finger_id) = source.finger_id() {
self.touch.velocity(finger_id, evc)
} else {
unreachable!()
}
Expand Down
Loading
Loading