summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.github/workflows/audit.yml2
-rw-r--r--.github/workflows/document.yml2
-rw-r--r--Cargo.toml5
-rw-r--r--core/Cargo.toml10
-rw-r--r--core/src/keyboard.rs7
-rw-r--r--core/src/keyboard/event.rs29
-rw-r--r--core/src/keyboard/key.rs744
-rw-r--r--core/src/keyboard/key_code.rs203
-rw-r--r--core/src/keyboard/location.rs12
-rw-r--r--core/src/lib.rs2
-rw-r--r--core/src/mouse/button.rs6
-rw-r--r--core/src/time.rs13
-rw-r--r--examples/editor/src/main.rs4
-rw-r--r--examples/integration/src/main.rs124
-rw-r--r--examples/layout/src/main.rs10
-rw-r--r--examples/loading_spinners/src/circular.rs6
-rw-r--r--examples/loading_spinners/src/linear.rs6
-rw-r--r--examples/modal/src/main.rs6
-rw-r--r--examples/pane_grid/src/main.rs31
-rw-r--r--examples/screenshot/src/main.rs33
-rw-r--r--examples/stopwatch/src/main.rs12
-rw-r--r--examples/toast/src/main.rs6
-rw-r--r--examples/todos/src/main.rs16
-rw-r--r--futures/src/keyboard.rs16
-rw-r--r--src/lib.rs3
-rw-r--r--widget/src/canvas/event.rs2
-rw-r--r--widget/src/combo_box.rs14
-rw-r--r--widget/src/shader/event.rs2
-rw-r--r--widget/src/text_editor.rs79
-rw-r--r--widget/src/text_input.rs104
-rw-r--r--winit/src/application.rs389
-rw-r--r--winit/src/application/state.rs24
-rw-r--r--winit/src/conversion.rs583
-rw-r--r--winit/src/multi_window.rs580
-rw-r--r--winit/src/multi_window/state.rs24
35 files changed, 1875 insertions, 1234 deletions
diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml
index 80bbcacd..57169796 100644
--- a/.github/workflows/audit.yml
+++ b/.github/workflows/audit.yml
@@ -27,4 +27,4 @@ jobs:
- name: Delete `web-sys` dependency from `integration` example
run: sed -i '$d' examples/integration/Cargo.toml
- name: Find outdated dependencies
- run: cargo outdated --workspace --exit-code 1
+ run: cargo outdated --workspace --exit-code 1 --ignore raw-window-handle
diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml
index 62e28ca3..35bf10f4 100644
--- a/.github/workflows/document.yml
+++ b/.github/workflows/document.yml
@@ -8,7 +8,7 @@ jobs:
steps:
- uses: hecrj/setup-rust-action@v1
with:
- rust-version: nightly
+ rust-version: nightly-2023-12-11
- uses: actions/checkout@v2
- name: Generate documentation
run: |
diff --git a/Cargo.toml b/Cargo.toml
index bdb6022a..ac72f212 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -130,7 +130,6 @@ glyphon = "0.4"
guillotiere = "0.6"
half = "2.2"
image = "0.24"
-instant = "0.1"
kamadak-exif = "0.5"
kurbo = "0.9"
log = "0.4"
@@ -145,6 +144,7 @@ raw-window-handle = "0.5"
resvg = "0.36"
rustc-hash = "1.0"
smol = "1.0"
+smol_str = "0.2"
softbuffer = "0.2"
syntect = "5.1"
sysinfo = "0.28"
@@ -157,7 +157,8 @@ unicode-segmentation = "1.0"
wasm-bindgen-futures = "0.4"
wasm-timer = "0.2"
web-sys = "0.3"
+web-time = "0.2"
wgpu = "0.18"
winapi = "0.3"
window_clipboard = "0.3"
-winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false }
+winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5", features = ["rwh_05"] }
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 4672c754..be92a572 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -13,18 +13,18 @@ keywords.workspace = true
[dependencies]
bitflags.workspace = true
log.workspace = true
+num-traits.workspace = true
+smol_str.workspace = true
thiserror.workspace = true
+web-time.workspace = true
xxhash-rust.workspace = true
-num-traits.workspace = true
palette.workspace = true
palette.optional = true
-[target.'cfg(target_arch = "wasm32")'.dependencies]
-instant.workspace = true
-
[target.'cfg(windows)'.dependencies]
-raw-window-handle.workspace = true
+# TODO: Use `workspace` dependency once `wgpu` upgrades `raw-window-handle`
+raw-window-handle = "0.6"
[dev-dependencies]
approx = "0.5"
diff --git a/core/src/keyboard.rs b/core/src/keyboard.rs
index 4c6ca08d..b810ccb0 100644
--- a/core/src/keyboard.rs
+++ b/core/src/keyboard.rs
@@ -1,8 +1,11 @@
//! Listen to keyboard events.
+pub mod key;
+
mod event;
-mod key_code;
+mod location;
mod modifiers;
pub use event::Event;
-pub use key_code::KeyCode;
+pub use key::Key;
+pub use location::Location;
pub use modifiers::Modifiers;
diff --git a/core/src/keyboard/event.rs b/core/src/keyboard/event.rs
index 016761af..1eb42334 100644
--- a/core/src/keyboard/event.rs
+++ b/core/src/keyboard/event.rs
@@ -1,4 +1,5 @@
-use super::{KeyCode, Modifiers};
+use crate::keyboard::{Key, Location, Modifiers};
+use crate::SmolStr;
/// A keyboard event.
///
@@ -6,29 +7,35 @@ use super::{KeyCode, Modifiers};
/// additional events, feel free to [open an issue] and share your use case!_
///
/// [open an issue]: https://github.com/iced-rs/iced/issues
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
/// A keyboard key was pressed.
KeyPressed {
- /// The key identifier
- key_code: KeyCode,
+ /// The key pressed.
+ key: Key,
- /// The state of the modifier keys
+ /// The location of the key.
+ location: Location,
+
+ /// The state of the modifier keys.
modifiers: Modifiers,
+
+ /// The text produced by the key press, if any.
+ text: Option<SmolStr>,
},
/// A keyboard key was released.
KeyReleased {
- /// The key identifier
- key_code: KeyCode,
+ /// The key released.
+ key: Key,
- /// The state of the modifier keys
+ /// The location of the key.
+ location: Location,
+
+ /// The state of the modifier keys.
modifiers: Modifiers,
},
- /// A unicode character was received.
- CharacterReceived(char),
-
/// The keyboard modifiers have changed.
ModifiersChanged(Modifiers),
}
diff --git a/core/src/keyboard/key.rs b/core/src/keyboard/key.rs
new file mode 100644
index 00000000..dbde5196
--- /dev/null
+++ b/core/src/keyboard/key.rs
@@ -0,0 +1,744 @@
+//! Identify keyboard keys.
+use crate::SmolStr;
+
+/// A key on the keyboard.
+///
+/// This is mostly the `Key` type found in [`winit`].
+///
+/// [`winit`]: https://docs.rs/winit/0.29.10/winit/keyboard/enum.Key.html
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub enum Key<C = SmolStr> {
+ /// A key with an established name.
+ Named(Named),
+
+ /// A key string that corresponds to the character typed by the user, taking into account the
+ /// user’s current locale setting, and any system-level keyboard mapping overrides that are in
+ /// effect.
+ Character(C),
+
+ /// An unidentified key.
+ Unidentified,
+}
+
+impl Key {
+ /// Convert `Key::Character(SmolStr)` to `Key::Character(&str)` so you can more easily match on
+ /// `Key`. All other variants remain unchanged.
+ pub fn as_ref(&self) -> Key<&str> {
+ match self {
+ Self::Named(named) => Key::Named(*named),
+ Self::Character(c) => Key::Character(c.as_ref()),
+ Self::Unidentified => Key::Unidentified,
+ }
+ }
+}
+
+/// A named key.
+///
+/// This is mostly the `NamedKey` type found in [`winit`].
+///
+/// [`winit`]: https://docs.rs/winit/0.29.10/winit/keyboard/enum.Key.html
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[allow(missing_docs)]
+pub enum Named {
+ /// The `Alt` (Alternative) key.
+ ///
+ /// This key enables the alternate modifier function for interpreting concurrent or subsequent
+ /// keyboard input. This key value is also used for the Apple <kbd>Option</kbd> key.
+ Alt,
+ /// The Alternate Graphics (<kbd>AltGr</kbd> or <kbd>AltGraph</kbd>) key.
+ ///
+ /// This key is used enable the ISO Level 3 shift modifier (the standard `Shift` key is the
+ /// level 2 modifier).
+ AltGraph,
+ /// The `Caps Lock` (Capital) key.
+ ///
+ /// Toggle capital character lock function for interpreting subsequent keyboard input event.
+ CapsLock,
+ /// The `Control` or `Ctrl` key.
+ ///
+ /// Used to enable control modifier function for interpreting concurrent or subsequent keyboard
+ /// input.
+ Control,
+ /// The Function switch `Fn` key. Activating this key simultaneously with another key changes
+ /// that key’s value to an alternate character or function. This key is often handled directly
+ /// in the keyboard hardware and does not usually generate key events.
+ Fn,
+ /// The Function-Lock (`FnLock` or `F-Lock`) key. Activating this key switches the mode of the
+ /// keyboard to changes some keys' values to an alternate character or function. This key is
+ /// often handled directly in the keyboard hardware and does not usually generate key events.
+ FnLock,
+ /// The `NumLock` or Number Lock key. Used to toggle numpad mode function for interpreting
+ /// subsequent keyboard input.
+ NumLock,
+ /// Toggle between scrolling and cursor movement modes.
+ ScrollLock,
+ /// Used to enable shift modifier function for interpreting concurrent or subsequent keyboard
+ /// input.
+ Shift,
+ /// The Symbol modifier key (used on some virtual keyboards).
+ Symbol,
+ SymbolLock,
+ // Legacy modifier key. Also called "Super" in certain places.
+ Meta,
+ // Legacy modifier key.
+ Hyper,
+ /// Used to enable "super" modifier function for interpreting concurrent or subsequent keyboard
+ /// input. This key value is used for the "Windows Logo" key and the Apple `Command` or `⌘` key.
+ ///
+ /// Note: In some contexts (e.g. the Web) this is referred to as the "Meta" key.
+ Super,
+ /// The `Enter` or `↵` key. Used to activate current selection or accept current input. This key
+ /// value is also used for the `Return` (Macintosh numpad) key. This key value is also used for
+ /// the Android `KEYCODE_DPAD_CENTER`.
+ Enter,
+ /// The Horizontal Tabulation `Tab` key.
+ Tab,
+ /// Used in text to insert a space between words. Usually located below the character keys.
+ Space,
+ /// Navigate or traverse downward. (`KEYCODE_DPAD_DOWN`)
+ ArrowDown,
+ /// Navigate or traverse leftward. (`KEYCODE_DPAD_LEFT`)
+ ArrowLeft,
+ /// Navigate or traverse rightward. (`KEYCODE_DPAD_RIGHT`)
+ ArrowRight,
+ /// Navigate or traverse upward. (`KEYCODE_DPAD_UP`)
+ ArrowUp,
+ /// The End key, used with keyboard entry to go to the end of content (`KEYCODE_MOVE_END`).
+ End,
+ /// The Home key, used with keyboard entry, to go to start of content (`KEYCODE_MOVE_HOME`).
+ /// For the mobile phone `Home` key (which goes to the phone’s main screen), use [`GoHome`].
+ ///
+ /// [`GoHome`]: Self::GoHome
+ Home,
+ /// Scroll down or display next page of content.
+ PageDown,
+ /// Scroll up or display previous page of content.
+ PageUp,
+ /// Used to remove the character to the left of the cursor. This key value is also used for
+ /// the key labeled `Delete` on MacOS keyboards.
+ Backspace,
+ /// Remove the currently selected input.
+ Clear,
+ /// Copy the current selection. (`APPCOMMAND_COPY`)
+ Copy,
+ /// The Cursor Select key.
+ CrSel,
+ /// Cut the current selection. (`APPCOMMAND_CUT`)
+ Cut,
+ /// Used to delete the character to the right of the cursor. This key value is also used for the
+ /// key labeled `Delete` on MacOS keyboards when `Fn` is active.
+ Delete,
+ /// The Erase to End of Field key. This key deletes all characters from the current cursor
+ /// position to the end of the current field.
+ EraseEof,
+ /// The Extend Selection (Exsel) key.
+ ExSel,
+ /// Toggle between text modes for insertion or overtyping.
+ /// (`KEYCODE_INSERT`)
+ Insert,
+ /// The Paste key. (`APPCOMMAND_PASTE`)
+ Paste,
+ /// Redo the last action. (`APPCOMMAND_REDO`)
+ Redo,
+ /// Undo the last action. (`APPCOMMAND_UNDO`)
+ Undo,
+ /// The Accept (Commit, OK) key. Accept current option or input method sequence conversion.
+ Accept,
+ /// Redo or repeat an action.
+ Again,
+ /// The Attention (Attn) key.
+ Attn,
+ Cancel,
+ /// Show the application’s context menu.
+ /// This key is commonly found between the right `Super` key and the right `Control` key.
+ ContextMenu,
+ /// The `Esc` key. This key was originally used to initiate an escape sequence, but is
+ /// now more generally used to exit or "escape" the current context, such as closing a dialog
+ /// or exiting full screen mode.
+ Escape,
+ Execute,
+ /// Open the Find dialog. (`APPCOMMAND_FIND`)
+ Find,
+ /// Open a help dialog or toggle display of help information. (`APPCOMMAND_HELP`,
+ /// `KEYCODE_HELP`)
+ Help,
+ /// Pause the current state or application (as appropriate).
+ ///
+ /// Note: Do not use this value for the `Pause` button on media controllers. Use `"MediaPause"`
+ /// instead.
+ Pause,
+ /// Play or resume the current state or application (as appropriate).
+ ///
+ /// Note: Do not use this value for the `Play` button on media controllers. Use `"MediaPlay"`
+ /// instead.
+ Play,
+ /// The properties (Props) key.
+ Props,
+ Select,
+ /// The ZoomIn key. (`KEYCODE_ZOOM_IN`)
+ ZoomIn,
+ /// The ZoomOut key. (`KEYCODE_ZOOM_OUT`)
+ ZoomOut,
+ /// The Brightness Down key. Typically controls the display brightness.
+ /// (`KEYCODE_BRIGHTNESS_DOWN`)
+ BrightnessDown,
+ /// The Brightness Up key. Typically controls the display brightness. (`KEYCODE_BRIGHTNESS_UP`)
+ BrightnessUp,
+ /// Toggle removable media to eject (open) and insert (close) state. (`KEYCODE_MEDIA_EJECT`)
+ Eject,
+ LogOff,
+ /// Toggle power state. (`KEYCODE_POWER`)
+ /// Note: Note: Some devices might not expose this key to the operating environment.
+ Power,
+ /// The `PowerOff` key. Sometime called `PowerDown`.
+ PowerOff,
+ /// Initiate print-screen function.
+ PrintScreen,
+ /// The Hibernate key. This key saves the current state of the computer to disk so that it can
+ /// be restored. The computer will then shutdown.
+ Hibernate,
+ /// The Standby key. This key turns off the display and places the computer into a low-power
+ /// mode without completely shutting down. It is sometimes labelled `Suspend` or `Sleep` key.
+ /// (`KEYCODE_SLEEP`)
+ Standby,
+ /// The WakeUp key. (`KEYCODE_WAKEUP`)
+ WakeUp,
+ /// Initate the multi-candidate mode.
+ AllCandidates,
+ Alphanumeric,
+ /// Initiate the Code Input mode to allow characters to be entered by
+ /// their code points.
+ CodeInput,
+ /// The Compose key, also known as "Multi_key" on the X Window System. This key acts in a
+ /// manner similar to a dead key, triggering a mode where subsequent key presses are combined to
+ /// produce a different character.
+ Compose,
+ /// Convert the current input method sequence.
+ Convert,
+ /// The Final Mode `Final` key used on some Asian keyboards, to enable the final mode for IMEs.
+ FinalMode,
+ /// Switch to the first character group. (ISO/IEC 9995)
+ GroupFirst,
+ /// Switch to the last character group. (ISO/IEC 9995)
+ GroupLast,
+ /// Switch to the next character group. (ISO/IEC 9995)
+ GroupNext,
+ /// Switch to the previous character group. (ISO/IEC 9995)
+ GroupPrevious,
+ /// Toggle between or cycle through input modes of IMEs.
+ ModeChange,
+ NextCandidate,
+ /// Accept current input method sequence without
+ /// conversion in IMEs.
+ NonConvert,
+ PreviousCandidate,
+ Process,
+ SingleCandidate,
+ /// Toggle between Hangul and English modes.
+ HangulMode,
+ HanjaMode,
+ JunjaMode,
+ /// The Eisu key. This key may close the IME, but its purpose is defined by the current IME.
+ /// (`KEYCODE_EISU`)
+ Eisu,
+ /// The (Half-Width) Characters key.
+ Hankaku,
+ /// The Hiragana (Japanese Kana characters) key.
+ Hiragana,
+ /// The Hiragana/Katakana toggle key. (`KEYCODE_KATAKANA_HIRAGANA`)
+ HiraganaKatakana,
+ /// The Kana Mode (Kana Lock) key. This key is used to enter hiragana mode (typically from
+ /// romaji mode).
+ KanaMode,
+ /// The Kanji (Japanese name for ideographic characters of Chinese origin) Mode key. This key is
+ /// typically used to switch to a hiragana keyboard for the purpose of converting input into
+ /// kanji. (`KEYCODE_KANA`)
+ KanjiMode,
+ /// The Katakana (Japanese Kana characters) key.
+ Katakana,
+ /// The Roman characters function key.
+ Romaji,
+ /// The Zenkaku (Full-Width) Characters key.
+ Zenkaku,
+ /// The Zenkaku/Hankaku (full-width/half-width) toggle key. (`KEYCODE_ZENKAKU_HANKAKU`)
+ ZenkakuHankaku,
+ /// General purpose virtual function key, as index 1.
+ Soft1,
+ /// General purpose virtual function key, as index 2.
+ Soft2,
+ /// General purpose virtual function key, as index 3.
+ Soft3,
+ /// General purpose virtual function key, as index 4.
+ Soft4,
+ /// Select next (numerically or logically) lower channel. (`APPCOMMAND_MEDIA_CHANNEL_DOWN`,
+ /// `KEYCODE_CHANNEL_DOWN`)
+ ChannelDown,
+ /// Select next (numerically or logically) higher channel. (`APPCOMMAND_MEDIA_CHANNEL_UP`,
+ /// `KEYCODE_CHANNEL_UP`)
+ ChannelUp,
+ /// Close the current document or message (Note: This doesn’t close the application).
+ /// (`APPCOMMAND_CLOSE`)
+ Close,
+ /// Open an editor to forward the current message. (`APPCOMMAND_FORWARD_MAIL`)
+ MailForward,
+ /// Open an editor to reply to the current message. (`APPCOMMAND_REPLY_TO_MAIL`)
+ MailReply,
+ /// Send the current message. (`APPCOMMAND_SEND_MAIL`)
+ MailSend,
+ /// Close the current media, for example to close a CD or DVD tray. (`KEYCODE_MEDIA_CLOSE`)
+ MediaClose,
+ /// Initiate or continue forward playback at faster than normal speed, or increase speed if
+ /// already fast forwarding. (`APPCOMMAND_MEDIA_FAST_FORWARD`, `KEYCODE_MEDIA_FAST_FORWARD`)
+ MediaFastForward,
+ /// Pause the currently playing media. (`APPCOMMAND_MEDIA_PAUSE`, `KEYCODE_MEDIA_PAUSE`)
+ ///
+ /// Note: Media controller devices should use this value rather than `"Pause"` for their pause
+ /// keys.
+ MediaPause,
+ /// Initiate or continue media playback at normal speed, if not currently playing at normal
+ /// speed. (`APPCOMMAND_MEDIA_PLAY`, `KEYCODE_MEDIA_PLAY`)
+ MediaPlay,
+ /// Toggle media between play and pause states. (`APPCOMMAND_MEDIA_PLAY_PAUSE`,
+ /// `KEYCODE_MEDIA_PLAY_PAUSE`)
+ MediaPlayPause,
+ /// Initiate or resume recording of currently selected media. (`APPCOMMAND_MEDIA_RECORD`,
+ /// `KEYCODE_MEDIA_RECORD`)
+ MediaRecord,
+ /// Initiate or continue reverse playback at faster than normal speed, or increase speed if
+ /// already rewinding. (`APPCOMMAND_MEDIA_REWIND`, `KEYCODE_MEDIA_REWIND`)
+ MediaRewind,
+ /// Stop media playing, pausing, forwarding, rewinding, or recording, if not already stopped.
+ /// (`APPCOMMAND_MEDIA_STOP`, `KEYCODE_MEDIA_STOP`)
+ MediaStop,
+ /// Seek to next media or program track. (`APPCOMMAND_MEDIA_NEXTTRACK`, `KEYCODE_MEDIA_NEXT`)
+ MediaTrackNext,
+ /// Seek to previous media or program track. (`APPCOMMAND_MEDIA_PREVIOUSTRACK`,
+ /// `KEYCODE_MEDIA_PREVIOUS`)
+ MediaTrackPrevious,
+ /// Open a new document or message. (`APPCOMMAND_NEW`)
+ New,
+ /// Open an existing document or message. (`APPCOMMAND_OPEN`)
+ Open,
+ /// Print the current document or message. (`APPCOMMAND_PRINT`)
+ Print,
+ /// Save the current document or message. (`APPCOMMAND_SAVE`)
+ Save,
+ /// Spellcheck the current document or selection. (`APPCOMMAND_SPELL_CHECK`)
+ SpellCheck,
+ /// The `11` key found on media numpads that
+ /// have buttons from `1` ... `12`.
+ Key11,
+ /// The `12` key found on media numpads that
+ /// have buttons from `1` ... `12`.
+ Key12,
+ /// Adjust audio balance leftward. (`VK_AUDIO_BALANCE_LEFT`)
+ AudioBalanceLeft,
+ /// Adjust audio balance rightward. (`VK_AUDIO_BALANCE_RIGHT`)
+ AudioBalanceRight,
+ /// Decrease audio bass boost or cycle down through bass boost states. (`APPCOMMAND_BASS_DOWN`,
+ /// `VK_BASS_BOOST_DOWN`)
+ AudioBassBoostDown,
+ /// Toggle bass boost on/off. (`APPCOMMAND_BASS_BOOST`)
+ AudioBassBoostToggle,
+ /// Increase audio bass boost or cycle up through bass boost states. (`APPCOMMAND_BASS_UP`,
+ /// `VK_BASS_BOOST_UP`)
+ AudioBassBoostUp,
+ /// Adjust audio fader towards front. (`VK_FADER_FRONT`)
+ AudioFaderFront,
+ /// Adjust audio fader towards rear. (`VK_FADER_REAR`)
+ AudioFaderRear,
+ /// Advance surround audio mode to next available mode. (`VK_SURROUND_MODE_NEXT`)
+ AudioSurroundModeNext,
+ /// Decrease treble. (`APPCOMMAND_TREBLE_DOWN`)
+ AudioTrebleDown,
+ /// Increase treble. (`APPCOMMAND_TREBLE_UP`)
+ AudioTrebleUp,
+ /// Decrease audio volume. (`APPCOMMAND_VOLUME_DOWN`, `KEYCODE_VOLUME_DOWN`)
+ AudioVolumeDown,
+ /// Increase audio volume. (`APPCOMMAND_VOLUME_UP`, `KEYCODE_VOLUME_UP`)
+ AudioVolumeUp,
+ /// Toggle between muted state and prior volume level. (`APPCOMMAND_VOLUME_MUTE`,
+ /// `KEYCODE_VOLUME_MUTE`)
+ AudioVolumeMute,
+ /// Toggle the microphone on/off. (`APPCOMMAND_MIC_ON_OFF_TOGGLE`)
+ MicrophoneToggle,
+ /// Decrease microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_DOWN`)
+ MicrophoneVolumeDown,
+ /// Increase microphone volume. (`APPCOMMAND_MICROPHONE_VOLUME_UP`)
+ MicrophoneVolumeUp,
+ /// Mute the microphone. (`APPCOMMAND_MICROPHONE_VOLUME_MUTE`, `KEYCODE_MUTE`)
+ MicrophoneVolumeMute,
+ /// Show correction list when a word is incorrectly identified. (`APPCOMMAND_CORRECTION_LIST`)
+ SpeechCorrectionList,
+ /// Toggle between dictation mode and command/control mode.
+ /// (`APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE`)
+ SpeechInputToggle,
+ /// The first generic "LaunchApplication" key. This is commonly associated with launching "My
+ /// Computer", and may have a computer symbol on the key. (`APPCOMMAND_LAUNCH_APP1`)
+ LaunchApplication1,
+ /// The second generic "LaunchApplication" key. This is commonly associated with launching
+ /// "Calculator", and may have a calculator symbol on the key. (`APPCOMMAND_LAUNCH_APP2`,
+ /// `KEYCODE_CALCULATOR`)
+ LaunchApplication2,
+ /// The "Calendar" key. (`KEYCODE_CALENDAR`)
+ LaunchCalendar,
+ /// The "Contacts" key. (`KEYCODE_CONTACTS`)
+ LaunchContacts,
+ /// The "Mail" key. (`APPCOMMAND_LAUNCH_MAIL`)
+ LaunchMail,
+ /// The "Media Player" key. (`APPCOMMAND_LAUNCH_MEDIA_SELECT`)
+ LaunchMediaPlayer,
+ LaunchMusicPlayer,
+ LaunchPhone,
+ LaunchScreenSaver,
+ LaunchSpreadsheet,
+ LaunchWebBrowser,
+ LaunchWebCam,
+ LaunchWordProcessor,
+ /// Navigate to previous content or page in current history. (`APPCOMMAND_BROWSER_BACKWARD`)
+ BrowserBack,
+ /// Open the list of browser favorites. (`APPCOMMAND_BROWSER_FAVORITES`)
+ BrowserFavorites,
+ /// Navigate to next content or page in current history. (`APPCOMMAND_BROWSER_FORWARD`)
+ BrowserForward,
+ /// Go to the user’s preferred home page. (`APPCOMMAND_BROWSER_HOME`)
+ BrowserHome,
+ /// Refresh the current page or content. (`APPCOMMAND_BROWSER_REFRESH`)
+ BrowserRefresh,
+ /// Call up the user’s preferred search page. (`APPCOMMAND_BROWSER_SEARCH`)
+ BrowserSearch,
+ /// Stop loading the current page or content. (`APPCOMMAND_BROWSER_STOP`)
+ BrowserStop,
+ /// The Application switch key, which provides a list of recent apps to switch between.
+ /// (`KEYCODE_APP_SWITCH`)
+ AppSwitch,
+ /// The Call key. (`KEYCODE_CALL`)
+ Call,
+ /// The Camera key. (`KEYCODE_CAMERA`)
+ Camera,
+ /// The Camera focus key. (`KEYCODE_FOCUS`)
+ CameraFocus,
+ /// The End Call key. (`KEYCODE_ENDCALL`)
+ EndCall,
+ /// The Back key. (`KEYCODE_BACK`)
+ GoBack,
+ /// The Home key, which goes to the phone’s main screen. (`KEYCODE_HOME`)
+ GoHome,
+ /// The Headset Hook key. (`KEYCODE_HEADSETHOOK`)
+ HeadsetHook,
+ LastNumberRedial,
+ /// The Notification key. (`KEYCODE_NOTIFICATION`)
+ Notification,
+ /// Toggle between manner mode state: silent, vibrate, ring, ... (`KEYCODE_MANNER_MODE`)
+ MannerMode,
+ VoiceDial,
+ /// Switch to viewing TV. (`KEYCODE_TV`)
+ TV,
+ /// TV 3D Mode. (`KEYCODE_3D_MODE`)
+ TV3DMode,
+ /// Toggle between antenna and cable input. (`KEYCODE_TV_ANTENNA_CABLE`)
+ TVAntennaCable,
+ /// Audio description. (`KEYCODE_TV_AUDIO_DESCRIPTION`)
+ TVAudioDescription,
+ /// Audio description mixing volume down. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN`)
+ TVAudioDescriptionMixDown,
+ /// Audio description mixing volume up. (`KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP`)
+ TVAudioDescriptionMixUp,
+ /// Contents menu. (`KEYCODE_TV_CONTENTS_MENU`)
+ TVContentsMenu,
+ /// Contents menu. (`KEYCODE_TV_DATA_SERVICE`)
+ TVDataService,
+ /// Switch the input mode on an external TV. (`KEYCODE_TV_INPUT`)
+ TVInput,
+ /// Switch to component input #1. (`KEYCODE_TV_INPUT_COMPONENT_1`)
+ TVInputComponent1,
+ /// Switch to component input #2. (`KEYCODE_TV_INPUT_COMPONENT_2`)
+ TVInputComponent2,
+ /// Switch to composite input #1. (`KEYCODE_TV_INPUT_COMPOSITE_1`)
+ TVInputComposite1,
+ /// Switch to composite input #2. (`KEYCODE_TV_INPUT_COMPOSITE_2`)
+ TVInputComposite2,
+ /// Switch to HDMI input #1. (`KEYCODE_TV_INPUT_HDMI_1`)
+ TVInputHDMI1,
+ /// Switch to HDMI input #2. (`KEYCODE_TV_INPUT_HDMI_2`)
+ TVInputHDMI2,
+ /// Switch to HDMI input #3. (`KEYCODE_TV_INPUT_HDMI_3`)
+ TVInputHDMI3,
+ /// Switch to HDMI input #4. (`KEYCODE_TV_INPUT_HDMI_4`)
+ TVInputHDMI4,
+ /// Switch to VGA input #1. (`KEYCODE_TV_INPUT_VGA_1`)
+ TVInputVGA1,
+ /// Media context menu. (`KEYCODE_TV_MEDIA_CONTEXT_MENU`)
+ TVMediaContext,
+ /// Toggle network. (`KEYCODE_TV_NETWORK`)
+ TVNetwork,
+ /// Number entry. (`KEYCODE_TV_NUMBER_ENTRY`)
+ TVNumberEntry,
+ /// Toggle the power on an external TV. (`KEYCODE_TV_POWER`)
+ TVPower,
+ /// Radio. (`KEYCODE_TV_RADIO_SERVICE`)
+ TVRadioService,
+ /// Satellite. (`KEYCODE_TV_SATELLITE`)
+ TVSatellite,
+ /// Broadcast Satellite. (`KEYCODE_TV_SATELLITE_BS`)
+ TVSatelliteBS,
+ /// Communication Satellite. (`KEYCODE_TV_SATELLITE_CS`)
+ TVSatelliteCS,
+ /// Toggle between available satellites. (`KEYCODE_TV_SATELLITE_SERVICE`)
+ TVSatelliteToggle,
+ /// Analog Terrestrial. (`KEYCODE_TV_TERRESTRIAL_ANALOG`)
+ TVTerrestrialAnalog,
+ /// Digital Terrestrial. (`KEYCODE_TV_TERRESTRIAL_DIGITAL`)
+ TVTerrestrialDigital,
+ /// Timer programming. (`KEYCODE_TV_TIMER_PROGRAMMING`)
+ TVTimer,
+ /// Switch the input mode on an external AVR (audio/video receiver). (`KEYCODE_AVR_INPUT`)
+ AVRInput,
+ /// Toggle the power on an external AVR (audio/video receiver). (`KEYCODE_AVR_POWER`)
+ AVRPower,
+ /// General purpose color-coded media function key, as index 0 (red). (`VK_COLORED_KEY_0`,
+ /// `KEYCODE_PROG_RED`)
+ ColorF0Red,
+ /// General purpose color-coded media function key, as index 1 (green). (`VK_COLORED_KEY_1`,
+ /// `KEYCODE_PROG_GREEN`)
+ ColorF1Green,
+ /// General purpose color-coded media function key, as index 2 (yellow). (`VK_COLORED_KEY_2`,
+ /// `KEYCODE_PROG_YELLOW`)
+ ColorF2Yellow,
+ /// General purpose color-coded media function key, as index 3 (blue). (`VK_COLORED_KEY_3`,
+ /// `KEYCODE_PROG_BLUE`)
+ ColorF3Blue,
+ /// General purpose color-coded media function key, as index 4 (grey). (`VK_COLORED_KEY_4`)
+ ColorF4Grey,
+ /// General purpose color-coded media function key, as index 5 (brown). (`VK_COLORED_KEY_5`)
+ ColorF5Brown,
+ /// Toggle the display of Closed Captions. (`VK_CC`, `KEYCODE_CAPTIONS`)
+ ClosedCaptionToggle,
+ /// Adjust brightness of device, by toggling between or cycling through states. (`VK_DIMMER`)
+ Dimmer,
+ /// Swap video sources. (`VK_DISPLAY_SWAP`)
+ DisplaySwap,
+ /// Select Digital Video Rrecorder. (`KEYCODE_DVR`)
+ DVR,
+ /// Exit the current application. (`VK_EXIT`)
+ Exit,
+ /// Clear program or content stored as favorite 0. (`VK_CLEAR_FAVORITE_0`)
+ FavoriteClear0,
+ /// Clear program or content stored as favorite 1. (`VK_CLEAR_FAVORITE_1`)
+ FavoriteClear1,
+ /// Clear program or content stored as favorite 2. (`VK_CLEAR_FAVORITE_2`)
+ FavoriteClear2,
+ /// Clear program or content stored as favorite 3. (`VK_CLEAR_FAVORITE_3`)
+ FavoriteClear3,
+ /// Select (recall) program or content stored as favorite 0. (`VK_RECALL_FAVORITE_0`)
+ FavoriteRecall0,
+ /// Select (recall) program or content stored as favorite 1. (`VK_RECALL_FAVORITE_1`)
+ FavoriteRecall1,
+ /// Select (recall) program or content stored as favorite 2. (`VK_RECALL_FAVORITE_2`)
+ FavoriteRecall2,
+ /// Select (recall) program or content stored as favorite 3. (`VK_RECALL_FAVORITE_3`)
+ FavoriteRecall3,
+ /// Store current program or content as favorite 0. (`VK_STORE_FAVORITE_0`)
+ FavoriteStore0,
+ /// Store current program or content as favorite 1. (`VK_STORE_FAVORITE_1`)
+ FavoriteStore1,
+ /// Store current program or content as favorite 2. (`VK_STORE_FAVORITE_2`)
+ FavoriteStore2,
+ /// Store current program or content as favorite 3. (`VK_STORE_FAVORITE_3`)
+ FavoriteStore3,
+ /// Toggle display of program or content guide. (`VK_GUIDE`, `KEYCODE_GUIDE`)
+ Guide,
+ /// If guide is active and displayed, then display next day’s content. (`VK_NEXT_DAY`)
+ GuideNextDay,
+ /// If guide is active and displayed, then display previous day’s content. (`VK_PREV_DAY`)
+ GuidePreviousDay,
+ /// Toggle display of information about currently selected context or media. (`VK_INFO`,
+ /// `KEYCODE_INFO`)
+ Info,
+ /// Toggle instant replay. (`VK_INSTANT_REPLAY`)
+ InstantReplay,
+ /// Launch linked content, if available and appropriate. (`VK_LINK`)
+ Link,
+ /// List the current program. (`VK_LIST`)
+ ListProgram,
+ /// Toggle display listing of currently available live content or programs. (`VK_LIVE`)
+ LiveContent,
+ /// Lock or unlock current content or program. (`VK_LOCK`)
+ Lock,
+ /// Show a list of media applications: audio/video players and image viewers. (`VK_APPS`)
+ ///
+ /// Note: Do not confuse this key value with the Windows' `VK_APPS` / `VK_CONTEXT_MENU` key,
+ /// which is encoded as `"ContextMenu"`.
+ MediaApps,
+ /// Audio track key. (`KEYCODE_MEDIA_AUDIO_TRACK`)
+ MediaAudioTrack,
+ /// Select previously selected channel or media. (`VK_LAST`, `KEYCODE_LAST_CHANNEL`)
+ MediaLast,
+ /// Skip backward to next content or program. (`KEYCODE_MEDIA_SKIP_BACKWARD`)
+ MediaSkipBackward,
+ /// Skip forward to next content or program. (`VK_SKIP`, `KEYCODE_MEDIA_SKIP_FORWARD`)
+ MediaSkipForward,
+ /// Step backward to next content or program. (`KEYCODE_MEDIA_STEP_BACKWARD`)
+ MediaStepBackward,
+ /// Step forward to next content or program. (`KEYCODE_MEDIA_STEP_FORWARD`)
+ MediaStepForward,
+ /// Media top menu. (`KEYCODE_MEDIA_TOP_MENU`)
+ MediaTopMenu,
+ /// Navigate in. (`KEYCODE_NAVIGATE_IN`)
+ NavigateIn,
+ /// Navigate to next key. (`KEYCODE_NAVIGATE_NEXT`)
+ NavigateNext,
+ /// Navigate out. (`KEYCODE_NAVIGATE_OUT`)
+ NavigateOut,
+ /// Navigate to previous key. (`KEYCODE_NAVIGATE_PREVIOUS`)
+ NavigatePrevious,
+ /// Cycle to next favorite channel (in favorites list). (`VK_NEXT_FAVORITE_CHANNEL`)
+ NextFavoriteChannel,
+ /// Cycle to next user profile (if there are multiple user profiles). (`VK_USER`)
+ NextUserProfile,
+ /// Access on-demand content or programs. (`VK_ON_DEMAND`)
+ OnDemand,
+ /// Pairing key to pair devices. (`KEYCODE_PAIRING`)
+ Pairing,
+ /// Move picture-in-picture window down. (`VK_PINP_DOWN`)
+ PinPDown,
+ /// Move picture-in-picture window. (`VK_PINP_MOVE`)
+ PinPMove,
+ /// Toggle display of picture-in-picture window. (`VK_PINP_TOGGLE`)
+ PinPToggle,
+ /// Move picture-in-picture window up. (`VK_PINP_UP`)
+ PinPUp,
+ /// Decrease media playback speed. (`VK_PLAY_SPEED_DOWN`)
+ PlaySpeedDown,
+ /// Reset playback to normal speed. (`VK_PLAY_SPEED_RESET`)
+ PlaySpeedReset,
+ /// Increase media playback speed. (`VK_PLAY_SPEED_UP`)
+ PlaySpeedUp,
+ /// Toggle random media or content shuffle mode. (`VK_RANDOM_TOGGLE`)
+ RandomToggle,
+ /// Not a physical key, but this key code is sent when the remote control battery is low.
+ /// (`VK_RC_LOW_BATTERY`)
+ RcLowBattery,
+ /// Toggle or cycle between media recording speeds. (`VK_RECORD_SPEED_NEXT`)
+ RecordSpeedNext,
+ /// Toggle RF (radio frequency) input bypass mode (pass RF input directly to the RF output).
+ /// (`VK_RF_BYPASS`)
+ RfBypass,
+ /// Toggle scan channels mode. (`VK_SCAN_CHANNELS_TOGGLE`)
+ ScanChannelsToggle,
+ /// Advance display screen mode to next available mode. (`VK_SCREEN_MODE_NEXT`)
+ ScreenModeNext,
+ /// Toggle display of device settings screen. (`VK_SETTINGS`, `KEYCODE_SETTINGS`)
+ Settings,
+ /// Toggle split screen mode. (`VK_SPLIT_SCREEN_TOGGLE`)
+ SplitScreenToggle,
+ /// Switch the input mode on an external STB (set top box). (`KEYCODE_STB_INPUT`)
+ STBInput,
+ /// Toggle the power on an external STB (set top box). (`KEYCODE_STB_POWER`)
+ STBPower,
+ /// Toggle display of subtitles, if available. (`VK_SUBTITLE`)
+ Subtitle,
+ /// Toggle display of teletext, if available (`VK_TELETEXT`, `KEYCODE_TV_TELETEXT`).
+ Teletext,
+ /// Advance video mode to next available mode. (`VK_VIDEO_MODE_NEXT`)
+ VideoModeNext,
+ /// Cause device to identify itself in some manner, e.g., audibly or visibly. (`VK_WINK`)
+ Wink,
+ /// Toggle between full-screen and scaled content, or alter magnification level. (`VK_ZOOM`,
+ /// `KEYCODE_TV_ZOOM_MODE`)
+ ZoomToggle,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F1,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F2,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F3,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F4,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F5,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F6,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F7,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F8,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F9,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F10,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F11,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F12,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F13,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F14,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F15,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F16,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F17,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F18,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F19,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F20,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F21,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F22,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F23,
+ /// General-purpose function key.
+ /// Usually found at the top of the keyboard.
+ F24,
+ /// General-purpose function key.
+ F25,
+ /// General-purpose function key.
+ F26,
+ /// General-purpose function key.
+ F27,
+ /// General-purpose function key.
+ F28,
+ /// General-purpose function key.
+ F29,
+ /// General-purpose function key.
+ F30,
+ /// General-purpose function key.
+ F31,
+ /// General-purpose function key.
+ F32,
+ /// General-purpose function key.
+ F33,
+ /// General-purpose function key.
+ F34,
+ /// General-purpose function key.
+ F35,
+}
diff --git a/core/src/keyboard/key_code.rs b/core/src/keyboard/key_code.rs
deleted file mode 100644
index 74ead170..00000000
--- a/core/src/keyboard/key_code.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-/// The symbolic name of a keyboard key.
-///
-/// This is mostly the `KeyCode` type found in [`winit`].
-///
-/// [`winit`]: https://docs.rs/winit/0.20.0-alpha3/winit/
-#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
-#[repr(u32)]
-#[allow(missing_docs)]
-pub enum KeyCode {
- /// The '1' key over the letters.
- Key1,
- /// The '2' key over the letters.
- Key2,
- /// The '3' key over the letters.
- Key3,
- /// The '4' key over the letters.
- Key4,
- /// The '5' key over the letters.
- Key5,
- /// The '6' key over the letters.
- Key6,
- /// The '7' key over the letters.
- Key7,
- /// The '8' key over the letters.
- Key8,
- /// The '9' key over the letters.
- Key9,
- /// The '0' key over the 'O' and 'P' keys.
- Key0,
-
- A,
- B,
- C,
- D,
- E,
- F,
- G,
- H,
- I,
- J,
- K,
- L,
- M,
- N,
- O,
- P,
- Q,
- R,
- S,
- T,
- U,
- V,
- W,
- X,
- Y,
- Z,
-
- /// The Escape key, next to F1.
- Escape,
-
- F1,
- F2,
- F3,
- F4,
- F5,
- F6,
- F7,
- F8,
- F9,
- F10,
- F11,
- F12,
- F13,
- F14,
- F15,
- F16,
- F17,
- F18,
- F19,
- F20,
- F21,
- F22,
- F23,
- F24,
-
- /// Print Screen/SysRq.
- Snapshot,
- /// Scroll Lock.
- Scroll,
- /// Pause/Break key, next to Scroll lock.
- Pause,
-
- /// `Insert`, next to Backspace.
- Insert,
- Home,
- Delete,
- End,
- PageDown,
- PageUp,
-
- Left,
- Up,
- Right,
- Down,
-
- /// The Backspace key, right over Enter.
- Backspace,
- /// The Enter key.
- Enter,
- /// The space bar.
- Space,
-
- /// The "Compose" key on Linux.
- Compose,
-
- Caret,
-
- Numlock,
- Numpad0,
- Numpad1,
- Numpad2,
- Numpad3,
- Numpad4,
- Numpad5,
- Numpad6,
- Numpad7,
- Numpad8,
- Numpad9,
- NumpadAdd,
- NumpadDivide,
- NumpadDecimal,
- NumpadComma,
- NumpadEnter,
- NumpadEquals,
- NumpadMultiply,
- NumpadSubtract,
-
- AbntC1,
- AbntC2,
- Apostrophe,
- Apps,
- Asterisk,
- At,
- Ax,
- Backslash,
- Calculator,
- Capital,
- Colon,
- Comma,
- Convert,
- Equals,
- Grave,
- Kana,
- Kanji,
- LAlt,
- LBracket,
- LControl,
- LShift,
- LWin,
- Mail,
- MediaSelect,
- MediaStop,
- Minus,
- Mute,
- MyComputer,
- NavigateForward, // also called "Next"
- NavigateBackward, // also called "Prior"
- NextTrack,
- NoConvert,
- OEM102,
- Period,
- PlayPause,
- Plus,
- Power,
- PrevTrack,
- RAlt,
- RBracket,
- RControl,
- RShift,
- RWin,
- Semicolon,
- Slash,
- Sleep,
- Stop,
- Sysrq,
- Tab,
- Underline,
- Unlabeled,
- VolumeDown,
- VolumeUp,
- Wake,
- WebBack,
- WebFavorites,
- WebForward,
- WebHome,
- WebRefresh,
- WebSearch,
- WebStop,
- Yen,
- Copy,
- Paste,
- Cut,
-}
diff --git a/core/src/keyboard/location.rs b/core/src/keyboard/location.rs
new file mode 100644
index 00000000..feff0820
--- /dev/null
+++ b/core/src/keyboard/location.rs
@@ -0,0 +1,12 @@
+/// The location of a key on the keyboard.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Location {
+ /// The standard group of keys on the keyboard.
+ Standard,
+ /// The left side of the keyboard.
+ Left,
+ /// The right side of the keyboard.
+ Right,
+ /// The numpad of the keyboard.
+ Numpad,
+}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 54ea5839..864df6e6 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -75,3 +75,5 @@ pub use size::Size;
pub use text::Text;
pub use vector::Vector;
pub use widget::Widget;
+
+pub use smol_str::SmolStr;
diff --git a/core/src/mouse/button.rs b/core/src/mouse/button.rs
index 3eec7f42..a8f90329 100644
--- a/core/src/mouse/button.rs
+++ b/core/src/mouse/button.rs
@@ -10,6 +10,12 @@ pub enum Button {
/// The middle (wheel) button.
Middle,
+ /// The back mouse button.
+ Back,
+
+ /// The forward mouse button.
+ Forward,
+
/// Some other button.
Other(u16),
}
diff --git a/core/src/time.rs b/core/src/time.rs
index 9355ae6d..dcfe4e41 100644
--- a/core/src/time.rs
+++ b/core/src/time.rs
@@ -1,13 +1,4 @@
//! Keep track of time, both in native and web platforms!
-#[cfg(target_arch = "wasm32")]
-pub use instant::Instant;
-
-#[cfg(target_arch = "wasm32")]
-pub use instant::Duration;
-
-#[cfg(not(target_arch = "wasm32"))]
-pub use std::time::Instant;
-
-#[cfg(not(target_arch = "wasm32"))]
-pub use std::time::Duration;
+pub use web_time::Duration;
+pub use web_time::Instant;
diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs
index 03d1e283..bf2aaaa3 100644
--- a/examples/editor/src/main.rs
+++ b/examples/editor/src/main.rs
@@ -134,8 +134,8 @@ impl Application for Editor {
}
fn subscription(&self) -> Subscription<Message> {
- keyboard::on_key_press(|key_code, modifiers| match key_code {
- keyboard::KeyCode::S if modifiers.command() => {
+ keyboard::on_key_press(|key, modifiers| match key.as_ref() {
+ keyboard::Key::Character("s") if modifiers.command() => {
Some(Message::SaveFile)
}
_ => None,
diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs
index 276794c8..b0939d68 100644
--- a/examples/integration/src/main.rs
+++ b/examples/integration/src/main.rs
@@ -19,8 +19,9 @@ use iced_winit::winit;
use iced_winit::Clipboard;
use winit::{
- event::{Event, ModifiersState, WindowEvent},
+ event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
+ keyboard::ModifiersState,
};
#[cfg(target_arch = "wasm32")]
@@ -48,7 +49,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
// Initialize winit
- let event_loop = EventLoop::new();
+ let event_loop = EventLoop::new()?;
#[cfg(target_arch = "wasm32")]
let window = winit::window::WindowBuilder::new()
@@ -160,67 +161,15 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
);
// Run event loop
- event_loop.run(move |event, _, control_flow| {
+ event_loop.run(move |event, window_target| {
// You should change this if you want to render continuosly
- *control_flow = ControlFlow::Wait;
+ window_target.set_control_flow(ControlFlow::Wait);
match event {
- Event::WindowEvent { event, .. } => {
- match event {
- WindowEvent::CursorMoved { position, .. } => {
- cursor_position = Some(position);
- }
- WindowEvent::ModifiersChanged(new_modifiers) => {
- modifiers = new_modifiers;
- }
- WindowEvent::Resized(_) => {
- resized = true;
- }
- WindowEvent::CloseRequested => {
- *control_flow = ControlFlow::Exit;
- }
- _ => {}
- }
-
- // Map window event to iced event
- if let Some(event) = iced_winit::conversion::window_event(
- window::Id::MAIN,
- &event,
- window.scale_factor(),
- modifiers,
- ) {
- state.queue_event(event);
- }
- }
- Event::MainEventsCleared => {
- // If there are events pending
- if !state.is_queue_empty() {
- // We update iced
- let _ = state.update(
- viewport.logical_size(),
- cursor_position
- .map(|p| {
- conversion::cursor_position(
- p,
- viewport.scale_factor(),
- )
- })
- .map(mouse::Cursor::Available)
- .unwrap_or(mouse::Cursor::Unavailable),
- &mut renderer,
- &Theme::Dark,
- &renderer::Style {
- text_color: Color::WHITE,
- },
- &mut clipboard,
- &mut debug,
- );
-
- // and request a redraw
- window.request_redraw();
- }
- }
- Event::RedrawRequested(_) => {
+ Event::WindowEvent {
+ event: WindowEvent::RedrawRequested,
+ ..
+ } => {
if resized {
let size = window.inner_size();
@@ -309,7 +258,60 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
},
}
}
+ Event::WindowEvent { event, .. } => {
+ match event {
+ WindowEvent::CursorMoved { position, .. } => {
+ cursor_position = Some(position);
+ }
+ WindowEvent::ModifiersChanged(new_modifiers) => {
+ modifiers = new_modifiers.state();
+ }
+ WindowEvent::Resized(_) => {
+ resized = true;
+ }
+ WindowEvent::CloseRequested => {
+ window_target.exit();
+ }
+ _ => {}
+ }
+
+ // Map window event to iced event
+ if let Some(event) = iced_winit::conversion::window_event(
+ window::Id::MAIN,
+ event,
+ window.scale_factor(),
+ modifiers,
+ ) {
+ state.queue_event(event);
+ }
+ }
_ => {}
}
- })
+
+ // If there are events pending
+ if !state.is_queue_empty() {
+ // We update iced
+ let _ = state.update(
+ viewport.logical_size(),
+ cursor_position
+ .map(|p| {
+ conversion::cursor_position(p, viewport.scale_factor())
+ })
+ .map(mouse::Cursor::Available)
+ .unwrap_or(mouse::Cursor::Unavailable),
+ &mut renderer,
+ &Theme::Dark,
+ &renderer::Style {
+ text_color: Color::WHITE,
+ },
+ &mut clipboard,
+ &mut debug,
+ );
+
+ // and request a redraw
+ window.request_redraw();
+ }
+ })?;
+
+ Ok(())
}
diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs
index 60dabe54..6cf0e570 100644
--- a/examples/layout/src/main.rs
+++ b/examples/layout/src/main.rs
@@ -71,9 +71,13 @@ impl Application for Layout {
}
fn subscription(&self) -> Subscription<Message> {
- keyboard::on_key_release(|key_code, _modifiers| match key_code {
- keyboard::KeyCode::Left => Some(Message::Previous),
- keyboard::KeyCode::Right => Some(Message::Next),
+ use keyboard::key;
+
+ keyboard::on_key_release(|key, _modifiers| match key {
+ keyboard::Key::Named(key::Named::ArrowLeft) => {
+ Some(Message::Previous)
+ }
+ keyboard::Key::Named(key::Named::ArrowRight) => Some(Message::Next),
_ => None,
})
}
diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs
index 1b163585..2e119979 100644
--- a/examples/loading_spinners/src/circular.rs
+++ b/examples/loading_spinners/src/circular.rs
@@ -271,8 +271,6 @@ where
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
) -> event::Status {
- const FRAME_RATE: u64 = 60;
-
let state = tree.state.downcast_mut::<State>();
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
@@ -283,9 +281,7 @@ where
);
state.cache.clear();
- shell.request_redraw(RedrawRequest::At(
- now + Duration::from_millis(1000 / FRAME_RATE),
- ));
+ shell.request_redraw(RedrawRequest::NextFrame);
}
event::Status::Ignored
diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs
index d245575c..497e0834 100644
--- a/examples/loading_spinners/src/linear.rs
+++ b/examples/loading_spinners/src/linear.rs
@@ -192,16 +192,12 @@ where
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
) -> event::Status {
- const FRAME_RATE: u64 = 60;
-
let state = tree.state.downcast_mut::<State>();
if let Event::Window(_, window::Event::RedrawRequested(now)) = event {
*state = state.timed_transition(self.cycle_duration, now);
- shell.request_redraw(RedrawRequest::At(
- now + Duration::from_millis(1000 / FRAME_RATE),
- ));
+ shell.request_redraw(RedrawRequest::NextFrame);
}
event::Status::Ignored
diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs
index 631efe6e..963c839e 100644
--- a/examples/modal/src/main.rs
+++ b/examples/modal/src/main.rs
@@ -1,6 +1,7 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
+use iced::keyboard::key;
use iced::theme;
use iced::widget::{
self, button, column, container, horizontal_space, pick_list, row, text,
@@ -85,8 +86,9 @@ impl Application for App {
}
Message::Event(event) => match event {
Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: keyboard::KeyCode::Tab,
+ key: keyboard::Key::Named(key::Named::Tab),
modifiers,
+ ..
}) => {
if modifiers.shift() {
widget::focus_previous()
@@ -95,7 +97,7 @@ impl Application for App {
}
}
Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: keyboard::KeyCode::Escape,
+ key: keyboard::Key::Named(key::Named::Escape),
..
}) => {
self.hide_modal();
diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs
index 96bb8e4e..d5e5bcbe 100644
--- a/examples/pane_grid/src/main.rs
+++ b/examples/pane_grid/src/main.rs
@@ -220,23 +220,26 @@ const PANE_ID_COLOR_FOCUSED: Color = Color::from_rgb(
0x47 as f32 / 255.0,
);
-fn handle_hotkey(key_code: keyboard::KeyCode) -> Option<Message> {
- use keyboard::KeyCode;
+fn handle_hotkey(key: keyboard::Key) -> Option<Message> {
+ use keyboard::key::{self, Key};
use pane_grid::{Axis, Direction};
- let direction = match key_code {
- KeyCode::Up => Some(Direction::Up),
- KeyCode::Down => Some(Direction::Down),
- KeyCode::Left => Some(Direction::Left),
- KeyCode::Right => Some(Direction::Right),
- _ => None,
- };
+ match key.as_ref() {
+ Key::Character("v") => Some(Message::SplitFocused(Axis::Vertical)),
+ Key::Character("h") => Some(Message::SplitFocused(Axis::Horizontal)),
+ Key::Character("w") => Some(Message::CloseFocused),
+ Key::Named(key) => {
+ let direction = match key {
+ key::Named::ArrowUp => Some(Direction::Up),
+ key::Named::ArrowDown => Some(Direction::Down),
+ key::Named::ArrowLeft => Some(Direction::Left),
+ key::Named::ArrowRight => Some(Direction::Right),
+ _ => None,
+ };
- match key_code {
- KeyCode::V => Some(Message::SplitFocused(Axis::Vertical)),
- KeyCode::H => Some(Message::SplitFocused(Axis::Horizontal)),
- KeyCode::W => Some(Message::CloseFocused),
- _ => direction.map(Message::FocusAdjacent),
+ direction.map(Message::FocusAdjacent)
+ }
+ _ => None,
}
}
diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs
index 20d34be6..6955551e 100644
--- a/examples/screenshot/src/main.rs
+++ b/examples/screenshot/src/main.rs
@@ -1,11 +1,13 @@
-use iced::keyboard::KeyCode;
-use iced::theme::{Button, Container};
+use iced::alignment;
+use iced::executor;
+use iced::keyboard;
+use iced::theme;
use iced::widget::{button, column, container, image, row, text, text_input};
+use iced::window;
use iced::window::screenshot::{self, Screenshot};
-use iced::{alignment, window};
use iced::{
- event, executor, keyboard, Alignment, Application, Command, ContentFit,
- Element, Event, Length, Rectangle, Renderer, Subscription, Theme,
+ Alignment, Application, Command, ContentFit, Element, Length, Rectangle,
+ Renderer, Subscription, Theme,
};
use ::image as img;
@@ -147,7 +149,7 @@ impl Application for Example {
let image = container(image)
.padding(10)
- .style(Container::Box)
+ .style(theme::Container::Box)
.width(Length::FillPortion(2))
.height(Length::Fill)
.center_x()
@@ -202,9 +204,10 @@ impl Application for Example {
self.screenshot.is_some().then(|| Message::Png),
)
} else {
- button(centered_text("Saving...")).style(Button::Secondary)
+ button(centered_text("Saving..."))
+ .style(theme::Button::Secondary)
}
- .style(Button::Secondary)
+ .style(theme::Button::Secondary)
.padding([10, 20, 10, 20])
.width(Length::Fill)
]
@@ -213,7 +216,7 @@ impl Application for Example {
crop_controls,
button(centered_text("Crop"))
.on_press(Message::Crop)
- .style(Button::Destructive)
+ .style(theme::Button::Destructive)
.padding([10, 20, 10, 20])
.width(Length::Fill),
]
@@ -256,16 +259,10 @@ impl Application for Example {
}
fn subscription(&self) -> Subscription<Self::Message> {
- event::listen_with(|event, status| {
- if let event::Status::Captured = status {
- return None;
- }
+ use keyboard::key;
- if let Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: KeyCode::F5,
- ..
- }) = event
- {
+ keyboard::on_key_press(|key, _modifiers| {
+ if let keyboard::Key::Named(key::Named::F5) = key {
Some(Message::Screenshot)
} else {
None
diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs
index 0b0f0607..8a0674c1 100644
--- a/examples/stopwatch/src/main.rs
+++ b/examples/stopwatch/src/main.rs
@@ -86,12 +86,16 @@ impl Application for Stopwatch {
};
fn handle_hotkey(
- key_code: keyboard::KeyCode,
+ key: keyboard::Key,
_modifiers: keyboard::Modifiers,
) -> Option<Message> {
- match key_code {
- keyboard::KeyCode::Space => Some(Message::Toggle),
- keyboard::KeyCode::R => Some(Message::Reset),
+ use keyboard::key;
+
+ match key.as_ref() {
+ keyboard::Key::Named(key::Named::Space) => {
+ Some(Message::Toggle)
+ }
+ keyboard::Key::Character("r") => Some(Message::Reset),
_ => None,
}
}
diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs
index 300343b9..2e837fa3 100644
--- a/examples/toast/src/main.rs
+++ b/examples/toast/src/main.rs
@@ -1,6 +1,7 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
+use iced::keyboard::key;
use iced::widget::{
self, button, column, container, pick_list, row, slider, text, text_input,
};
@@ -93,11 +94,12 @@ impl Application for App {
Command::none()
}
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: keyboard::KeyCode::Tab,
+ key: keyboard::Key::Named(key::Named::Tab),
modifiers,
+ ..
})) if modifiers.shift() => widget::focus_previous(),
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
- key_code: keyboard::KeyCode::Tab,
+ key: keyboard::Key::Named(key::Named::Tab),
..
})) => widget::focus_next(),
Message::Event(_) => Command::none(),
diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs
index aad47c20..3d79f087 100644
--- a/examples/todos/src/main.rs
+++ b/examples/todos/src/main.rs
@@ -260,15 +260,21 @@ impl Application for Todos {
}
fn subscription(&self) -> Subscription<Message> {
- keyboard::on_key_press(|key_code, modifiers| {
- match (key_code, modifiers) {
- (keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
+ use keyboard::key;
+
+ keyboard::on_key_press(|key, modifiers| {
+ let keyboard::Key::Named(key) = key else {
+ return None;
+ };
+
+ match (key, modifiers) {
+ (key::Named::Tab, _) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
- (keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
+ (key::Named::ArrowUp, keyboard::Modifiers::SHIFT) => {
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
}
- (keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
+ (key::Named::ArrowDown, keyboard::Modifiers::SHIFT) => {
Some(Message::ToggleFullscreen(window::Mode::Windowed))
}
_ => None,
diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs
index af68e1f2..8e7da38f 100644
--- a/futures/src/keyboard.rs
+++ b/futures/src/keyboard.rs
@@ -1,6 +1,6 @@
//! Listen to keyboard events.
use crate::core;
-use crate::core::keyboard::{Event, KeyCode, Modifiers};
+use crate::core::keyboard::{Event, Key, Modifiers};
use crate::subscription::{self, Subscription};
use crate::MaybeSend;
@@ -10,7 +10,7 @@ use crate::MaybeSend;
/// If the function returns `None`, the key press will be simply
/// ignored.
pub fn on_key_press<Message>(
- f: fn(KeyCode, Modifiers) -> Option<Message>,
+ f: fn(Key, Modifiers) -> Option<Message>,
) -> Subscription<Message>
where
Message: MaybeSend + 'static,
@@ -22,11 +22,10 @@ where
match (event, status) {
(
core::Event::Keyboard(Event::KeyPressed {
- key_code,
- modifiers,
+ key, modifiers, ..
}),
core::event::Status::Ignored,
- ) => f(key_code, modifiers),
+ ) => f(key, modifiers),
_ => None,
}
})
@@ -38,7 +37,7 @@ where
/// If the function returns `None`, the key release will be simply
/// ignored.
pub fn on_key_release<Message>(
- f: fn(KeyCode, Modifiers) -> Option<Message>,
+ f: fn(Key, Modifiers) -> Option<Message>,
) -> Subscription<Message>
where
Message: MaybeSend + 'static,
@@ -50,11 +49,12 @@ where
match (event, status) {
(
core::Event::Keyboard(Event::KeyReleased {
- key_code,
+ key,
modifiers,
+ ..
}),
core::event::Status::Ignored,
- ) => f(key_code, modifiers),
+ ) => f(key, modifiers),
_ => None,
}
})
diff --git a/src/lib.rs b/src/lib.rs
index 002d2a79..446590ec 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -230,7 +230,8 @@ pub mod event {
pub mod keyboard {
//! Listen and react to keyboard events.
- pub use crate::core::keyboard::{Event, KeyCode, Modifiers};
+ pub use crate::core::keyboard::key;
+ pub use crate::core::keyboard::{Event, Key, Location, Modifiers};
pub use iced_futures::keyboard::{on_key_press, on_key_release};
}
diff --git a/widget/src/canvas/event.rs b/widget/src/canvas/event.rs
index 1288365f..a8eb47f7 100644
--- a/widget/src/canvas/event.rs
+++ b/widget/src/canvas/event.rs
@@ -8,7 +8,7 @@ pub use crate::core::event::Status;
/// A [`Canvas`] event.
///
/// [`Canvas`]: crate::Canvas
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, PartialEq)]
pub enum Event {
/// A mouse event.
Mouse(mouse::Event),
diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs
index 1b2fa947..73beeac3 100644
--- a/widget/src/combo_box.rs
+++ b/widget/src/combo_box.rs
@@ -1,6 +1,7 @@
//! Display a dropdown list of searchable and selectable options.
use crate::core::event::{self, Event};
use crate::core::keyboard;
+use crate::core::keyboard::key;
use crate::core::layout::{self, Layout};
use crate::core::mouse;
use crate::core::overlay;
@@ -436,14 +437,14 @@ where
}
if let Event::Keyboard(keyboard::Event::KeyPressed {
- key_code,
+ key: keyboard::Key::Named(named_key),
modifiers,
..
}) = event
{
let shift_modifer = modifiers.shift();
- match (key_code, shift_modifer) {
- (keyboard::KeyCode::Enter, _) => {
+ match (named_key, shift_modifer) {
+ (key::Named::Enter, _) => {
if let Some(index) = &menu.hovered_option {
if let Some(option) =
state.filtered_options.options.get(*index)
@@ -455,8 +456,7 @@ where
event_status = event::Status::Captured;
}
- (keyboard::KeyCode::Up, _)
- | (keyboard::KeyCode::Tab, true) => {
+ (key::Named::ArrowUp, _) | (key::Named::Tab, true) => {
if let Some(index) = &mut menu.hovered_option {
if *index == 0 {
*index = state
@@ -492,8 +492,8 @@ where
event_status = event::Status::Captured;
}
- (keyboard::KeyCode::Down, _)
- | (keyboard::KeyCode::Tab, false)
+ (key::Named::ArrowDown, _)
+ | (key::Named::Tab, false)
if !modifiers.shift() =>
{
if let Some(index) = &mut menu.hovered_option {
diff --git a/widget/src/shader/event.rs b/widget/src/shader/event.rs
index 1cc484fb..005c8725 100644
--- a/widget/src/shader/event.rs
+++ b/widget/src/shader/event.rs
@@ -9,7 +9,7 @@ pub use crate::core::event::Status;
/// A [`Shader`] event.
///
/// [`Shader`]: crate::Shader
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, PartialEq)]
pub enum Event {
/// A mouse event.
Mouse(mouse::Event),
diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs
index 9118d124..09a0cac0 100644
--- a/widget/src/text_editor.rs
+++ b/widget/src/text_editor.rs
@@ -1,6 +1,7 @@
//! Display a multi-line text input for text editing.
use crate::core::event::{self, Event};
use crate::core::keyboard;
+use crate::core::keyboard::key;
use crate::core::layout::{self, Layout};
use crate::core::mouse;
use crate::core::renderer;
@@ -646,43 +647,61 @@ impl Update {
},
Event::Keyboard(event) => match event {
keyboard::Event::KeyPressed {
- key_code,
+ key,
modifiers,
+ text,
+ ..
} if state.is_focused => {
- if let Some(motion) = motion(key_code) {
- let motion =
- if platform::is_jump_modifier_pressed(modifiers) {
+ if let keyboard::Key::Named(named_key) = key.as_ref() {
+ if let Some(motion) = motion(named_key) {
+ let motion = if platform::is_jump_modifier_pressed(
+ modifiers,
+ ) {
motion.widen()
} else {
motion
};
- return action(if modifiers.shift() {
- Action::Select(motion)
- } else {
- Action::Move(motion)
- });
+ return action(if modifiers.shift() {
+ Action::Select(motion)
+ } else {
+ Action::Move(motion)
+ });
+ }
}
- match key_code {
- keyboard::KeyCode::Enter => edit(Edit::Enter),
- keyboard::KeyCode::Backspace => edit(Edit::Backspace),
- keyboard::KeyCode::Delete => edit(Edit::Delete),
- keyboard::KeyCode::Escape => Some(Self::Unfocus),
- keyboard::KeyCode::C if modifiers.command() => {
+ match key.as_ref() {
+ keyboard::Key::Named(key::Named::Enter) => {
+ edit(Edit::Enter)
+ }
+ keyboard::Key::Named(key::Named::Backspace) => {
+ edit(Edit::Backspace)
+ }
+ keyboard::Key::Named(key::Named::Delete) => {
+ edit(Edit::Delete)
+ }
+ keyboard::Key::Named(key::Named::Escape) => {
+ Some(Self::Unfocus)
+ }
+ keyboard::Key::Character("c")
+ if modifiers.command() =>
+ {
Some(Self::Copy)
}
- keyboard::KeyCode::V
+ keyboard::Key::Character("v")
if modifiers.command() && !modifiers.alt() =>
{
Some(Self::Paste)
}
- _ => None,
+ _ => {
+ let text = text?;
+
+ edit(Edit::Insert(
+ text.chars().next().unwrap_or_default(),
+ ))
+ }
}
}
- keyboard::Event::CharacterReceived(c) if state.is_focused => {
- edit(Edit::Insert(c))
- }
_ => None,
},
_ => None,
@@ -690,16 +709,16 @@ impl Update {
}
}
-fn motion(key_code: keyboard::KeyCode) -> Option<Motion> {
- match key_code {
- keyboard::KeyCode::Left => Some(Motion::Left),
- keyboard::KeyCode::Right => Some(Motion::Right),
- keyboard::KeyCode::Up => Some(Motion::Up),
- keyboard::KeyCode::Down => Some(Motion::Down),
- keyboard::KeyCode::Home => Some(Motion::Home),
- keyboard::KeyCode::End => Some(Motion::End),
- keyboard::KeyCode::PageUp => Some(Motion::PageUp),
- keyboard::KeyCode::PageDown => Some(Motion::PageDown),
+fn motion(key: key::Named) -> Option<Motion> {
+ match key {
+ key::Named::ArrowLeft => Some(Motion::Left),
+ key::Named::ArrowRight => Some(Motion::Right),
+ key::Named::ArrowUp => Some(Motion::Up),
+ key::Named::ArrowDown => Some(Motion::Down),
+ key::Named::Home => Some(Motion::Home),
+ key::Named::End => Some(Motion::End),
+ key::Named::PageUp => Some(Motion::PageUp),
+ key::Named::PageDown => Some(Motion::PageDown),
_ => None,
}
}
diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs
index 3be9b8e6..c3dce8be 100644
--- a/widget/src/text_input.rs
+++ b/widget/src/text_input.rs
@@ -14,6 +14,7 @@ use editor::Editor;
use crate::core::alignment;
use crate::core::event::{self, Event};
use crate::core::keyboard;
+use crate::core::keyboard::key;
use crate::core::layout;
use crate::core::mouse::{self, click};
use crate::core::renderer;
@@ -748,34 +749,7 @@ where
return event::Status::Captured;
}
}
- Event::Keyboard(keyboard::Event::CharacterReceived(c)) => {
- let state = state();
-
- if let Some(focus) = &mut state.is_focused {
- let Some(on_input) = on_input else {
- return event::Status::Ignored;
- };
-
- if state.is_pasting.is_none()
- && !state.keyboard_modifiers.command()
- && !c.is_control()
- {
- let mut editor = Editor::new(value, &mut state.cursor);
-
- editor.insert(c);
-
- let message = (on_input)(editor.contents());
- shell.publish(message);
-
- focus.updated_at = Instant::now();
-
- update_cache(state, value);
-
- return event::Status::Captured;
- }
- }
- }
- Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. }) => {
+ Event::Keyboard(keyboard::Event::KeyPressed { key, text, .. }) => {
let state = state();
if let Some(focus) = &mut state.is_focused {
@@ -786,14 +760,13 @@ where
let modifiers = state.keyboard_modifiers;
focus.updated_at = Instant::now();
- match key_code {
- keyboard::KeyCode::Enter
- | keyboard::KeyCode::NumpadEnter => {
+ match key.as_ref() {
+ keyboard::Key::Named(key::Named::Enter) => {
if let Some(on_submit) = on_submit.clone() {
shell.publish(on_submit);
}
}
- keyboard::KeyCode::Backspace => {
+ keyboard::Key::Named(key::Named::Backspace) => {
if platform::is_jump_modifier_pressed(modifiers)
&& state.cursor.selection(value).is_none()
{
@@ -813,7 +786,7 @@ where
update_cache(state, value);
}
- keyboard::KeyCode::Delete => {
+ keyboard::Key::Named(key::Named::Delete) => {
if platform::is_jump_modifier_pressed(modifiers)
&& state.cursor.selection(value).is_none()
{
@@ -835,7 +808,7 @@ where
update_cache(state, value);
}
- keyboard::KeyCode::Left => {
+ keyboard::Key::Named(key::Named::ArrowLeft) => {
if platform::is_jump_modifier_pressed(modifiers)
&& !is_secure
{
@@ -850,7 +823,7 @@ where
state.cursor.move_left(value);
}
}
- keyboard::KeyCode::Right => {
+ keyboard::Key::Named(key::Named::ArrowRight) => {
if platform::is_jump_modifier_pressed(modifiers)
&& !is_secure
{
@@ -865,7 +838,7 @@ where
state.cursor.move_right(value);
}
}
- keyboard::KeyCode::Home => {
+ keyboard::Key::Named(key::Named::Home) => {
if modifiers.shift() {
state
.cursor
@@ -874,7 +847,7 @@ where
state.cursor.move_to(0);
}
}
- keyboard::KeyCode::End => {
+ keyboard::Key::Named(key::Named::End) => {
if modifiers.shift() {
state.cursor.select_range(
state.cursor.start(value),
@@ -884,7 +857,7 @@ where
state.cursor.move_to(value.len());
}
}
- keyboard::KeyCode::C
+ keyboard::Key::Character("c")
if state.keyboard_modifiers.command() =>
{
if let Some((start, end)) =
@@ -894,7 +867,7 @@ where
.write(value.select(start, end).to_string());
}
}
- keyboard::KeyCode::X
+ keyboard::Key::Character("x")
if state.keyboard_modifiers.command() =>
{
if let Some((start, end)) =
@@ -912,7 +885,7 @@ where
update_cache(state, value);
}
- keyboard::KeyCode::V => {
+ keyboard::Key::Character("v") => {
if state.keyboard_modifiers.command()
&& !state.keyboard_modifiers.alt()
{
@@ -949,12 +922,12 @@ where
state.is_pasting = None;
}
}
- keyboard::KeyCode::A
+ keyboard::Key::Character("a")
if state.keyboard_modifiers.command() =>
{
state.cursor.select_all(value);
}
- keyboard::KeyCode::Escape => {
+ keyboard::Key::Named(key::Named::Escape) => {
state.is_focused = None;
state.is_dragging = false;
state.is_pasting = None;
@@ -962,28 +935,55 @@ where
state.keyboard_modifiers =
keyboard::Modifiers::default();
}
- keyboard::KeyCode::Tab
- | keyboard::KeyCode::Up
- | keyboard::KeyCode::Down => {
+ keyboard::Key::Named(
+ key::Named::Tab
+ | key::Named::ArrowUp
+ | key::Named::ArrowDown,
+ ) => {
return event::Status::Ignored;
}
- _ => {}
+ _ => {
+ if let Some(text) = text {
+ let c = text.chars().next().unwrap_or_default();
+
+ if state.is_pasting.is_none()
+ && !state.keyboard_modifiers.command()
+ && !c.is_control()
+ {
+ let mut editor =
+ Editor::new(value, &mut state.cursor);
+
+ editor.insert(c);
+
+ let message = (on_input)(editor.contents());
+ shell.publish(message);
+
+ focus.updated_at = Instant::now();
+
+ update_cache(state, value);
+
+ return event::Status::Captured;
+ }
+ }
+ }
}
return event::Status::Captured;
}
}
- Event::Keyboard(keyboard::Event::KeyReleased { key_code, .. }) => {
+ Event::Keyboard(keyboard::Event::KeyReleased { key, .. }) => {
let state = state();
if state.is_focused.is_some() {
- match key_code {
- keyboard::KeyCode::V => {
+ match key.as_ref() {
+ keyboard::Key::Character("v") => {
state.is_pasting = None;
}
- keyboard::KeyCode::Tab
- | keyboard::KeyCode::Up
- | keyboard::KeyCode::Down => {
+ keyboard::Key::Named(
+ key::Named::Tab
+ | key::Named::ArrowUp
+ | key::Named::ArrowDown,
+ ) => {
return event::Status::Ignored;
}
_ => {}
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 35a35872..bf48538d 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -115,7 +115,9 @@ where
let mut debug = Debug::new();
debug.startup_started();
- let event_loop = EventLoopBuilder::with_user_event().build();
+ let event_loop = EventLoopBuilder::with_user_event()
+ .build()
+ .expect("Create event loop");
let proxy = event_loop.create_proxy();
let runtime = {
@@ -155,7 +157,7 @@ where
{
use winit::platform::web::WindowExtWebSys;
- let canvas = window.canvas();
+ let canvas = window.canvas().expect("Get window canvas");
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
@@ -210,45 +212,28 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref());
- platform::run(event_loop, move |event, _, control_flow| {
- use winit::event_loop::ControlFlow;
-
- if let ControlFlow::ExitWithCode(_) = control_flow {
+ let _ = event_loop.run(move |event, event_loop| {
+ if event_loop.exiting() {
return;
}
- let event = match event {
- winit::event::Event::WindowEvent {
- event:
- winit::event::WindowEvent::ScaleFactorChanged {
- new_inner_size,
- ..
- },
- window_id,
- } => Some(winit::event::Event::WindowEvent {
- event: winit::event::WindowEvent::Resized(*new_inner_size),
- window_id,
- }),
- _ => event.to_static(),
- };
-
- if let Some(event) = event {
- event_sender.start_send(event).expect("Send event");
+ event_sender.start_send(event).expect("Send event");
- let poll = instance.as_mut().poll(&mut context);
+ let poll = instance.as_mut().poll(&mut context);
- match poll {
- task::Poll::Pending => {
- if let Ok(Some(flow)) = control_receiver.try_next() {
- *control_flow = flow;
- }
- }
- task::Poll::Ready(_) => {
- *control_flow = ControlFlow::Exit;
+ match poll {
+ task::Poll::Pending => {
+ if let Ok(Some(flow)) = control_receiver.try_next() {
+ event_loop.set_control_flow(flow);
}
- };
- }
- })
+ }
+ task::Poll::Ready(_) => {
+ event_loop.exit();
+ }
+ };
+ });
+
+ Ok(())
}
async fn run_instance<A, E, C>(
@@ -259,7 +244,7 @@ async fn run_instance<A, E, C>(
mut proxy: winit::event_loop::EventLoopProxy<A::Message>,
mut debug: Debug,
mut event_receiver: mpsc::UnboundedReceiver<
- winit::event::Event<'_, A::Message>,
+ winit::event::Event<A::Message>,
>,
mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>,
init_command: Command<A::Message>,
@@ -327,77 +312,56 @@ async fn run_instance<A, E, C>(
while let Some(event) = event_receiver.next().await {
match event {
- event::Event::NewEvents(start_cause) => {
- redraw_pending = matches!(
- start_cause,
- event::StartCause::Init
- | event::StartCause::Poll
- | event::StartCause::ResumeTimeReached { .. }
- );
+ event::Event::NewEvents(
+ event::StartCause::Init
+ | event::StartCause::ResumeTimeReached { .. },
+ ) if !redraw_pending => {
+ window.request_redraw();
+ redraw_pending = true;
}
- event::Event::MainEventsCleared => {
- if !redraw_pending && events.is_empty() && messages.is_empty() {
- continue;
- }
+ event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
+ event::MacOS::ReceivedUrl(url),
+ )) => {
+ use crate::core::event;
- debug.event_processing_started();
+ events.push(Event::PlatformSpecific(
+ event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
+ url,
+ )),
+ ));
+ }
+ event::Event::UserEvent(message) => {
+ messages.push(message);
+ }
+ event::Event::WindowEvent {
+ event: event::WindowEvent::RedrawRequested { .. },
+ ..
+ } => {
+ let physical_size = state.physical_size();
- let (interface_state, statuses) = user_interface.update(
- &events,
- state.cursor(),
- &mut renderer,
- &mut clipboard,
- &mut messages,
- );
+ if physical_size.width == 0 || physical_size.height == 0 {
+ continue;
+ }
- debug.event_processing_finished();
+ let current_viewport_version = state.viewport_version();
- for (event, status) in
- events.drain(..).zip(statuses.into_iter())
- {
- runtime.broadcast(event, status);
- }
+ if viewport_version != current_viewport_version {
+ let logical_size = state.logical_size();
- if !messages.is_empty()
- || matches!(
- interface_state,
- user_interface::State::Outdated
- )
- {
- let mut cache =
- ManuallyDrop::into_inner(user_interface).into_cache();
+ debug.layout_started();
+ user_interface = ManuallyDrop::new(
+ ManuallyDrop::into_inner(user_interface)
+ .relayout(logical_size, &mut renderer),
+ );
+ debug.layout_finished();
- // Update application
- update(
- &mut application,
- &mut compositor,
+ compositor.configure_surface(
&mut surface,
- &mut cache,
- &state,
- &mut renderer,
- &mut runtime,
- &mut clipboard,
- &mut should_exit,
- &mut proxy,
- &mut debug,
- &mut messages,
- &window,
+ physical_size.width,
+ physical_size.height,
);
- // Update window
- state.synchronize(&application, &window);
-
- user_interface = ManuallyDrop::new(build_user_interface(
- &application,
- cache,
- &mut renderer,
- state.logical_size(),
- &mut debug,
- ));
-
- if should_exit {
- break;
- }
+ viewport_version = current_viewport_version;
}
// TODO: Avoid redrawing all the time by forcing widgets to
@@ -418,6 +382,24 @@ async fn run_instance<A, E, C>(
&mut messages,
);
+ let _ = control_sender.start_send(match interface_state {
+ user_interface::State::Updated {
+ redraw_request: Some(redraw_request),
+ } => match redraw_request {
+ window::RedrawRequest::NextFrame => {
+ window.request_redraw();
+
+ ControlFlow::Wait
+ }
+ window::RedrawRequest::At(at) => {
+ ControlFlow::WaitUntil(at)
+ }
+ },
+ _ => ControlFlow::Wait,
+ });
+
+ runtime.broadcast(redraw_event, core::event::Status::Ignored);
+
debug.draw_started();
let new_mouse_interaction = user_interface.draw(
&mut renderer,
@@ -427,6 +409,7 @@ async fn run_instance<A, E, C>(
},
state.cursor(),
);
+ redraw_pending = false;
debug.draw_finished();
if new_mouse_interaction != mouse_interaction {
@@ -437,85 +420,7 @@ async fn run_instance<A, E, C>(
mouse_interaction = new_mouse_interaction;
}
- window.request_redraw();
- runtime.broadcast(redraw_event, core::event::Status::Ignored);
-
- let _ = control_sender.start_send(match interface_state {
- user_interface::State::Updated {
- redraw_request: Some(redraw_request),
- } => match redraw_request {
- window::RedrawRequest::NextFrame => ControlFlow::Poll,
- window::RedrawRequest::At(at) => {
- ControlFlow::WaitUntil(at)
- }
- },
- _ => ControlFlow::Wait,
- });
-
- redraw_pending = false;
- }
- event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
- event::MacOS::ReceivedUrl(url),
- )) => {
- use crate::core::event;
-
- events.push(Event::PlatformSpecific(
- event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
- url,
- )),
- ));
- }
- event::Event::UserEvent(message) => {
- messages.push(message);
- }
- event::Event::RedrawRequested(_) => {
- let physical_size = state.physical_size();
-
- if physical_size.width == 0 || physical_size.height == 0 {
- continue;
- }
-
debug.render_started();
- let current_viewport_version = state.viewport_version();
-
- if viewport_version != current_viewport_version {
- let logical_size = state.logical_size();
-
- debug.layout_started();
- user_interface = ManuallyDrop::new(
- ManuallyDrop::into_inner(user_interface)
- .relayout(logical_size, &mut renderer),
- );
- debug.layout_finished();
-
- debug.draw_started();
- let new_mouse_interaction = user_interface.draw(
- &mut renderer,
- state.theme(),
- &renderer::Style {
- text_color: state.text_color(),
- },
- state.cursor(),
- );
-
- if new_mouse_interaction != mouse_interaction {
- window.set_cursor_icon(conversion::mouse_interaction(
- new_mouse_interaction,
- ));
-
- mouse_interaction = new_mouse_interaction;
- }
- debug.draw_finished();
-
- compositor.configure_surface(
- &mut surface,
- physical_size.width,
- physical_size.height,
- );
-
- viewport_version = current_viewport_version;
- }
-
match compositor.present(
&mut renderer,
&mut surface,
@@ -557,13 +462,80 @@ async fn run_instance<A, E, C>(
if let Some(event) = conversion::window_event(
window::Id::MAIN,
- &window_event,
+ window_event,
state.scale_factor(),
state.modifiers(),
) {
events.push(event);
}
}
+ event::Event::AboutToWait => {
+ if events.is_empty() && messages.is_empty() {
+ continue;
+ }
+
+ debug.event_processing_started();
+
+ let (interface_state, statuses) = user_interface.update(
+ &events,
+ state.cursor(),
+ &mut renderer,
+ &mut clipboard,
+ &mut messages,
+ );
+
+ debug.event_processing_finished();
+
+ for (event, status) in
+ events.drain(..).zip(statuses.into_iter())
+ {
+ runtime.broadcast(event, status);
+ }
+
+ if !messages.is_empty()
+ || matches!(
+ interface_state,
+ user_interface::State::Outdated
+ )
+ {
+ let mut cache =
+ ManuallyDrop::into_inner(user_interface).into_cache();
+
+ // Update application
+ update(
+ &mut application,
+ &mut compositor,
+ &mut surface,
+ &mut cache,
+ &mut state,
+ &mut renderer,
+ &mut runtime,
+ &mut clipboard,
+ &mut should_exit,
+ &mut proxy,
+ &mut debug,
+ &mut messages,
+ &window,
+ );
+
+ user_interface = ManuallyDrop::new(build_user_interface(
+ &application,
+ cache,
+ &mut renderer,
+ state.logical_size(),
+ &mut debug,
+ ));
+
+ if should_exit {
+ break;
+ }
+ }
+
+ if !redraw_pending {
+ window.request_redraw();
+ redraw_pending = true;
+ }
+ }
_ => {}
}
}
@@ -575,8 +547,8 @@ async fn run_instance<A, E, C>(
/// Returns true if the provided event should cause an [`Application`] to
/// exit.
pub fn requests_exit(
- event: &winit::event::WindowEvent<'_>,
- _modifiers: winit::event::ModifiersState,
+ event: &winit::event::WindowEvent,
+ _modifiers: winit::keyboard::ModifiersState,
) -> bool {
use winit::event::WindowEvent;
@@ -584,14 +556,14 @@ pub fn requests_exit(
WindowEvent::CloseRequested => true,
#[cfg(target_os = "macos")]
WindowEvent::KeyboardInput {
- input:
- winit::event::KeyboardInput {
- virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
+ event:
+ winit::event::KeyEvent {
+ logical_key: winit::keyboard::Key::Character(c),
state: winit::event::ElementState::Pressed,
..
},
..
- } if _modifiers.logo() => true,
+ } if c == "q" && _modifiers.super_key() => true,
_ => false,
}
}
@@ -626,7 +598,7 @@ pub fn update<A: Application, C, E: Executor>(
compositor: &mut C,
surface: &mut C::Surface,
cache: &mut user_interface::Cache,
- state: &State<A>,
+ state: &mut State<A>,
renderer: &mut A::Renderer,
runtime: &mut Runtime<E, Proxy<A::Message>, A::Message>,
clipboard: &mut Clipboard,
@@ -663,6 +635,8 @@ pub fn update<A: Application, C, E: Executor>(
);
}
+ state.synchronize(application, window);
+
let subscription = application.subscription();
runtime.track(subscription.into_recipes());
}
@@ -726,10 +700,11 @@ pub fn run_command<A, C, E>(
);
}
window::Action::Resize(_id, size) => {
- window.set_inner_size(winit::dpi::LogicalSize {
- width: size.width,
- height: size.height,
- });
+ let _ =
+ window.request_inner_size(winit::dpi::LogicalSize {
+ width: size.width,
+ height: size.height,
+ });
}
window::Action::FetchSize(_id, callback) => {
let size =
@@ -888,43 +863,3 @@ pub fn run_command<A, C, E>(
}
}
}
-
-#[cfg(not(target_arch = "wasm32"))]
-mod platform {
- pub fn run<T, F>(
- mut event_loop: winit::event_loop::EventLoop<T>,
- event_handler: F,
- ) -> Result<(), super::Error>
- where
- F: 'static
- + FnMut(
- winit::event::Event<'_, T>,
- &winit::event_loop::EventLoopWindowTarget<T>,
- &mut winit::event_loop::ControlFlow,
- ),
- {
- use winit::platform::run_return::EventLoopExtRunReturn;
-
- let _ = event_loop.run_return(event_handler);
-
- Ok(())
- }
-}
-
-#[cfg(target_arch = "wasm32")]
-mod platform {
- pub fn run<T, F>(
- event_loop: winit::event_loop::EventLoop<T>,
- event_handler: F,
- ) -> !
- where
- F: 'static
- + FnMut(
- winit::event::Event<'_, T>,
- &winit::event_loop::EventLoopWindowTarget<T>,
- &mut winit::event_loop::ControlFlow,
- ),
- {
- event_loop.run(event_handler)
- }
-}
diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs
index e655529a..8c9b20e0 100644
--- a/winit/src/application/state.rs
+++ b/winit/src/application/state.rs
@@ -22,7 +22,7 @@ where
viewport: Viewport,
viewport_version: usize,
cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
- modifiers: winit::event::ModifiersState,
+ modifiers: winit::keyboard::ModifiersState,
theme: <A::Renderer as core::Renderer>::Theme,
appearance: application::Appearance,
application: PhantomData<A>,
@@ -54,7 +54,7 @@ where
viewport,
viewport_version: 0,
cursor_position: None,
- modifiers: winit::event::ModifiersState::default(),
+ modifiers: winit::keyboard::ModifiersState::default(),
theme,
appearance,
application: PhantomData,
@@ -102,7 +102,7 @@ where
}
/// Returns the current keyboard modifiers of the [`State`].
- pub fn modifiers(&self) -> winit::event::ModifiersState {
+ pub fn modifiers(&self) -> winit::keyboard::ModifiersState {
self.modifiers
}
@@ -126,7 +126,7 @@ where
pub fn update(
&mut self,
window: &Window,
- event: &WindowEvent<'_>,
+ event: &WindowEvent,
_debug: &mut Debug,
) {
match event {
@@ -142,10 +142,9 @@ where
}
WindowEvent::ScaleFactorChanged {
scale_factor: new_scale_factor,
- new_inner_size,
+ ..
} => {
- let size =
- Size::new(new_inner_size.width, new_inner_size.height);
+ let size = self.viewport.physical_size();
self.viewport = Viewport::with_physical_size(
size,
@@ -164,13 +163,16 @@ where
self.cursor_position = None;
}
WindowEvent::ModifiersChanged(new_modifiers) => {
- self.modifiers = *new_modifiers;
+ self.modifiers = new_modifiers.state();
}
#[cfg(feature = "debug")]
WindowEvent::KeyboardInput {
- input:
- winit::event::KeyboardInput {
- virtual_keycode: Some(winit::event::VirtualKeyCode::F12),
+ event:
+ winit::event::KeyEvent {
+ logical_key:
+ winit::keyboard::Key::Named(
+ winit::keyboard::NamedKey::F12,
+ ),
state: winit::event::ElementState::Pressed,
..
},
diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs
index 7e51a2d4..90a5d27f 100644
--- a/winit/src/conversion.rs
+++ b/winit/src/conversion.rs
@@ -128,9 +128,9 @@ pub fn window_settings(
/// Converts a winit window event into an iced event.
pub fn window_event(
id: window::Id,
- event: &winit::event::WindowEvent<'_>,
+ event: winit::event::WindowEvent,
scale_factor: f64,
- modifiers: winit::event::ModifiersState,
+ modifiers: winit::keyboard::ModifiersState,
) -> Option<Event> {
use winit::event::WindowEvent;
@@ -146,17 +146,6 @@ pub fn window_event(
},
))
}
- WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
- let logical_size = new_inner_size.to_logical(scale_factor);
-
- Some(Event::Window(
- id,
- window::Event::Resized {
- width: logical_size.width,
- height: logical_size.height,
- },
- ))
- }
WindowEvent::CloseRequested => {
Some(Event::Window(id, window::Event::CloseRequested))
}
@@ -174,7 +163,7 @@ pub fn window_event(
Some(Event::Mouse(mouse::Event::CursorLeft))
}
WindowEvent::MouseInput { button, state, .. } => {
- let button = mouse_button(*button);
+ let button = mouse_button(button);
Some(Event::Mouse(match state {
winit::event::ElementState::Pressed => {
@@ -189,8 +178,8 @@ pub fn window_event(
winit::event::MouseScrollDelta::LineDelta(delta_x, delta_y) => {
Some(Event::Mouse(mouse::Event::WheelScrolled {
delta: mouse::ScrollDelta::Lines {
- x: *delta_x,
- y: *delta_y,
+ x: delta_x,
+ y: delta_y,
},
}))
}
@@ -203,42 +192,59 @@ pub fn window_event(
}))
}
},
- WindowEvent::ReceivedCharacter(c) if !is_private_use_character(*c) => {
- Some(Event::Keyboard(keyboard::Event::CharacterReceived(*c)))
- }
WindowEvent::KeyboardInput {
- input:
- winit::event::KeyboardInput {
- virtual_keycode: Some(virtual_keycode),
+ event:
+ winit::event::KeyEvent {
+ logical_key,
state,
+ text,
+ location,
..
},
..
} => Some(Event::Keyboard({
- let key_code = key_code(*virtual_keycode);
+ let key = key(logical_key);
let modifiers = self::modifiers(modifiers);
+ let location = match location {
+ winit::keyboard::KeyLocation::Standard => {
+ keyboard::Location::Standard
+ }
+ winit::keyboard::KeyLocation::Left => keyboard::Location::Left,
+ winit::keyboard::KeyLocation::Right => {
+ keyboard::Location::Right
+ }
+ winit::keyboard::KeyLocation::Numpad => {
+ keyboard::Location::Numpad
+ }
+ };
+
match state {
winit::event::ElementState::Pressed => {
keyboard::Event::KeyPressed {
- key_code,
+ key,
modifiers,
+ location,
+ text,
}
}
winit::event::ElementState::Released => {
keyboard::Event::KeyReleased {
- key_code,
+ key,
modifiers,
+ location,
}
}
}
})),
- WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard(
- keyboard::Event::ModifiersChanged(self::modifiers(*new_modifiers)),
- )),
+ WindowEvent::ModifiersChanged(new_modifiers) => {
+ Some(Event::Keyboard(keyboard::Event::ModifiersChanged(
+ self::modifiers(new_modifiers.state()),
+ )))
+ }
WindowEvent::Focused(focused) => Some(Event::Window(
id,
- if *focused {
+ if focused {
window::Event::Focused
} else {
window::Event::Unfocused
@@ -254,7 +260,7 @@ pub fn window_event(
Some(Event::Window(id, window::Event::FilesHoveredLeft))
}
WindowEvent::Touch(touch) => {
- Some(Event::Touch(touch_event(*touch, scale_factor)))
+ Some(Event::Touch(touch_event(touch, scale_factor)))
}
WindowEvent::Moved(position) => {
let winit::dpi::LogicalPosition { x, y } =
@@ -365,7 +371,7 @@ pub fn mouse_interaction(
match interaction {
Interaction::Idle => winit::window::CursorIcon::Default,
- Interaction::Pointer => winit::window::CursorIcon::Hand,
+ Interaction::Pointer => winit::window::CursorIcon::Pointer,
Interaction::Working => winit::window::CursorIcon::Progress,
Interaction::Grab => winit::window::CursorIcon::Grab,
Interaction::Grabbing => winit::window::CursorIcon::Grabbing,
@@ -388,6 +394,8 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
winit::event::MouseButton::Left => mouse::Button::Left,
winit::event::MouseButton::Right => mouse::Button::Right,
winit::event::MouseButton::Middle => mouse::Button::Middle,
+ winit::event::MouseButton::Back => mouse::Button::Back,
+ winit::event::MouseButton::Forward => mouse::Button::Forward,
winit::event::MouseButton::Other(other) => mouse::Button::Other(other),
}
}
@@ -398,14 +406,14 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
/// [`winit`]: https://github.com/rust-windowing/winit
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10
pub fn modifiers(
- modifiers: winit::event::ModifiersState,
+ modifiers: winit::keyboard::ModifiersState,
) -> keyboard::Modifiers {
let mut result = keyboard::Modifiers::empty();
- result.set(keyboard::Modifiers::SHIFT, modifiers.shift());
- result.set(keyboard::Modifiers::CTRL, modifiers.ctrl());
- result.set(keyboard::Modifiers::ALT, modifiers.alt());
- result.set(keyboard::Modifiers::LOGO, modifiers.logo());
+ result.set(keyboard::Modifiers::SHIFT, modifiers.shift_key());
+ result.set(keyboard::Modifiers::CTRL, modifiers.control_key());
+ result.set(keyboard::Modifiers::ALT, modifiers.alt_key());
+ result.set(keyboard::Modifiers::LOGO, modifiers.super_key());
result
}
@@ -455,179 +463,328 @@ pub fn touch_event(
///
/// [`winit`]: https://github.com/rust-windowing/winit
/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10
-pub fn key_code(
- virtual_keycode: winit::event::VirtualKeyCode,
-) -> keyboard::KeyCode {
- use keyboard::KeyCode;
-
- match virtual_keycode {
- winit::event::VirtualKeyCode::Key1 => KeyCode::Key1,
- winit::event::VirtualKeyCode::Key2 => KeyCode::Key2,
- winit::event::VirtualKeyCode::Key3 => KeyCode::Key3,
- winit::event::VirtualKeyCode::Key4 => KeyCode::Key4,
- winit::event::VirtualKeyCode::Key5 => KeyCode::Key5,
- winit::event::VirtualKeyCode::Key6 => KeyCode::Key6,
- winit::event::VirtualKeyCode::Key7 => KeyCode::Key7,
- winit::event::VirtualKeyCode::Key8 => KeyCode::Key8,
- winit::event::VirtualKeyCode::Key9 => KeyCode::Key9,
- winit::event::VirtualKeyCode::Key0 => KeyCode::Key0,
- winit::event::VirtualKeyCode::A => KeyCode::A,
- winit::event::VirtualKeyCode::B => KeyCode::B,
- winit::event::VirtualKeyCode::C => KeyCode::C,
- winit::event::VirtualKeyCode::D => KeyCode::D,
- winit::event::VirtualKeyCode::E => KeyCode::E,
- winit::event::VirtualKeyCode::F => KeyCode::F,
- winit::event::VirtualKeyCode::G => KeyCode::G,
- winit::event::VirtualKeyCode::H => KeyCode::H,
- winit::event::VirtualKeyCode::I => KeyCode::I,
- winit::event::VirtualKeyCode::J => KeyCode::J,
- winit::event::VirtualKeyCode::K => KeyCode::K,
- winit::event::VirtualKeyCode::L => KeyCode::L,
- winit::event::VirtualKeyCode::M => KeyCode::M,
- winit::event::VirtualKeyCode::N => KeyCode::N,
- winit::event::VirtualKeyCode::O => KeyCode::O,
- winit::event::VirtualKeyCode::P => KeyCode::P,
- winit::event::VirtualKeyCode::Q => KeyCode::Q,
- winit::event::VirtualKeyCode::R => KeyCode::R,
- winit::event::VirtualKeyCode::S => KeyCode::S,
- winit::event::VirtualKeyCode::T => KeyCode::T,
- winit::event::VirtualKeyCode::U => KeyCode::U,
- winit::event::VirtualKeyCode::V => KeyCode::V,
- winit::event::VirtualKeyCode::W => KeyCode::W,
- winit::event::VirtualKeyCode::X => KeyCode::X,
- winit::event::VirtualKeyCode::Y => KeyCode::Y,
- winit::event::VirtualKeyCode::Z => KeyCode::Z,
- winit::event::VirtualKeyCode::Escape => KeyCode::Escape,
- winit::event::VirtualKeyCode::F1 => KeyCode::F1,
- winit::event::VirtualKeyCode::F2 => KeyCode::F2,
- winit::event::VirtualKeyCode::F3 => KeyCode::F3,
- winit::event::VirtualKeyCode::F4 => KeyCode::F4,
- winit::event::VirtualKeyCode::F5 => KeyCode::F5,
- winit::event::VirtualKeyCode::F6 => KeyCode::F6,
- winit::event::VirtualKeyCode::F7 => KeyCode::F7,
- winit::event::VirtualKeyCode::F8 => KeyCode::F8,
- winit::event::VirtualKeyCode::F9 => KeyCode::F9,
- winit::event::VirtualKeyCode::F10 => KeyCode::F10,
- winit::event::VirtualKeyCode::F11 => KeyCode::F11,
- winit::event::VirtualKeyCode::F12 => KeyCode::F12,
- winit::event::VirtualKeyCode::F13 => KeyCode::F13,
- winit::event::VirtualKeyCode::F14 => KeyCode::F14,
- winit::event::VirtualKeyCode::F15 => KeyCode::F15,
- winit::event::VirtualKeyCode::F16 => KeyCode::F16,
- winit::event::VirtualKeyCode::F17 => KeyCode::F17,
- winit::event::VirtualKeyCode::F18 => KeyCode::F18,
- winit::event::VirtualKeyCode::F19 => KeyCode::F19,
- winit::event::VirtualKeyCode::F20 => KeyCode::F20,
- winit::event::VirtualKeyCode::F21 => KeyCode::F21,
- winit::event::VirtualKeyCode::F22 => KeyCode::F22,
- winit::event::VirtualKeyCode::F23 => KeyCode::F23,
- winit::event::VirtualKeyCode::F24 => KeyCode::F24,
- winit::event::VirtualKeyCode::Snapshot => KeyCode::Snapshot,
- winit::event::VirtualKeyCode::Scroll => KeyCode::Scroll,
- winit::event::VirtualKeyCode::Pause => KeyCode::Pause,
- winit::event::VirtualKeyCode::Insert => KeyCode::Insert,
- winit::event::VirtualKeyCode::Home => KeyCode::Home,
- winit::event::VirtualKeyCode::Delete => KeyCode::Delete,
- winit::event::VirtualKeyCode::End => KeyCode::End,
- winit::event::VirtualKeyCode::PageDown => KeyCode::PageDown,
- winit::event::VirtualKeyCode::PageUp => KeyCode::PageUp,
- winit::event::VirtualKeyCode::Left => KeyCode::Left,
- winit::event::VirtualKeyCode::Up => KeyCode::Up,
- winit::event::VirtualKeyCode::Right => KeyCode::Right,
- winit::event::VirtualKeyCode::Down => KeyCode::Down,
- winit::event::VirtualKeyCode::Back => KeyCode::Backspace,
- winit::event::VirtualKeyCode::Return => KeyCode::Enter,
- winit::event::VirtualKeyCode::Space => KeyCode::Space,
- winit::event::VirtualKeyCode::Compose => KeyCode::Compose,
- winit::event::VirtualKeyCode::Caret => KeyCode::Caret,
- winit::event::VirtualKeyCode::Numlock => KeyCode::Numlock,
- winit::event::VirtualKeyCode::Numpad0 => KeyCode::Numpad0,
- winit::event::VirtualKeyCode::Numpad1 => KeyCode::Numpad1,
- winit::event::VirtualKeyCode::Numpad2 => KeyCode::Numpad2,
- winit::event::VirtualKeyCode::Numpad3 => KeyCode::Numpad3,
- winit::event::VirtualKeyCode::Numpad4 => KeyCode::Numpad4,
- winit::event::VirtualKeyCode::Numpad5 => KeyCode::Numpad5,
- winit::event::VirtualKeyCode::Numpad6 => KeyCode::Numpad6,
- winit::event::VirtualKeyCode::Numpad7 => KeyCode::Numpad7,
- winit::event::VirtualKeyCode::Numpad8 => KeyCode::Numpad8,
- winit::event::VirtualKeyCode::Numpad9 => KeyCode::Numpad9,
- winit::event::VirtualKeyCode::AbntC1 => KeyCode::AbntC1,
- winit::event::VirtualKeyCode::AbntC2 => KeyCode::AbntC2,
- winit::event::VirtualKeyCode::NumpadAdd => KeyCode::NumpadAdd,
- winit::event::VirtualKeyCode::Plus => KeyCode::Plus,
- winit::event::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe,
- winit::event::VirtualKeyCode::Apps => KeyCode::Apps,
- winit::event::VirtualKeyCode::At => KeyCode::At,
- winit::event::VirtualKeyCode::Ax => KeyCode::Ax,
- winit::event::VirtualKeyCode::Backslash => KeyCode::Backslash,
- winit::event::VirtualKeyCode::Calculator => KeyCode::Calculator,
- winit::event::VirtualKeyCode::Capital => KeyCode::Capital,
- winit::event::VirtualKeyCode::Colon => KeyCode::Colon,
- winit::event::VirtualKeyCode::Comma => KeyCode::Comma,
- winit::event::VirtualKeyCode::Convert => KeyCode::Convert,
- winit::event::VirtualKeyCode::NumpadDecimal => KeyCode::NumpadDecimal,
- winit::event::VirtualKeyCode::NumpadDivide => KeyCode::NumpadDivide,
- winit::event::VirtualKeyCode::Equals => KeyCode::Equals,
- winit::event::VirtualKeyCode::Grave => KeyCode::Grave,
- winit::event::VirtualKeyCode::Kana => KeyCode::Kana,
- winit::event::VirtualKeyCode::Kanji => KeyCode::Kanji,
- winit::event::VirtualKeyCode::LAlt => KeyCode::LAlt,
- winit::event::VirtualKeyCode::LBracket => KeyCode::LBracket,
- winit::event::VirtualKeyCode::LControl => KeyCode::LControl,
- winit::event::VirtualKeyCode::LShift => KeyCode::LShift,
- winit::event::VirtualKeyCode::LWin => KeyCode::LWin,
- winit::event::VirtualKeyCode::Mail => KeyCode::Mail,
- winit::event::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect,
- winit::event::VirtualKeyCode::MediaStop => KeyCode::MediaStop,
- winit::event::VirtualKeyCode::Minus => KeyCode::Minus,
- winit::event::VirtualKeyCode::NumpadMultiply => KeyCode::NumpadMultiply,
- winit::event::VirtualKeyCode::Mute => KeyCode::Mute,
- winit::event::VirtualKeyCode::MyComputer => KeyCode::MyComputer,
- winit::event::VirtualKeyCode::NavigateForward => {
- KeyCode::NavigateForward
- }
- winit::event::VirtualKeyCode::NavigateBackward => {
- KeyCode::NavigateBackward
+pub fn key(key: winit::keyboard::Key) -> keyboard::Key {
+ use keyboard::key::Named;
+ use winit::keyboard::NamedKey;
+
+ match key {
+ winit::keyboard::Key::Character(c) => keyboard::Key::Character(c),
+ winit::keyboard::Key::Named(named_key) => {
+ keyboard::Key::Named(match named_key {
+ NamedKey::Alt => Named::Alt,
+ NamedKey::AltGraph => Named::AltGraph,
+ NamedKey::CapsLock => Named::CapsLock,
+ NamedKey::Control => Named::Control,
+ NamedKey::Fn => Named::Fn,
+ NamedKey::FnLock => Named::FnLock,
+ NamedKey::NumLock => Named::NumLock,
+ NamedKey::ScrollLock => Named::ScrollLock,
+ NamedKey::Shift => Named::Shift,
+ NamedKey::Symbol => Named::Symbol,
+ NamedKey::SymbolLock => Named::SymbolLock,
+ NamedKey::Meta => Named::Meta,
+ NamedKey::Hyper => Named::Hyper,
+ NamedKey::Super => Named::Super,
+ NamedKey::Enter => Named::Enter,
+ NamedKey::Tab => Named::Tab,
+ NamedKey::Space => Named::Space,
+ NamedKey::ArrowDown => Named::ArrowDown,
+ NamedKey::ArrowLeft => Named::ArrowLeft,
+ NamedKey::ArrowRight => Named::ArrowRight,
+ NamedKey::ArrowUp => Named::ArrowUp,
+ NamedKey::End => Named::End,
+ NamedKey::Home => Named::Home,
+ NamedKey::PageDown => Named::PageDown,
+ NamedKey::PageUp => Named::PageUp,
+ NamedKey::Backspace => Named::Backspace,
+ NamedKey::Clear => Named::Clear,
+ NamedKey::Copy => Named::Copy,
+ NamedKey::CrSel => Named::CrSel,
+ NamedKey::Cut => Named::Cut,
+ NamedKey::Delete => Named::Delete,
+ NamedKey::EraseEof => Named::EraseEof,
+ NamedKey::ExSel => Named::ExSel,
+ NamedKey::Insert => Named::Insert,
+ NamedKey::Paste => Named::Paste,
+ NamedKey::Redo => Named::Redo,
+ NamedKey::Undo => Named::Undo,
+ NamedKey::Accept => Named::Accept,
+ NamedKey::Again => Named::Again,
+ NamedKey::Attn => Named::Attn,
+ NamedKey::Cancel => Named::Cancel,
+ NamedKey::ContextMenu => Named::ContextMenu,
+ NamedKey::Escape => Named::Escape,
+ NamedKey::Execute => Named::Execute,
+ NamedKey::Find => Named::Find,
+ NamedKey::Help => Named::Help,
+ NamedKey::Pause => Named::Pause,
+ NamedKey::Play => Named::Play,
+ NamedKey::Props => Named::Props,
+ NamedKey::Select => Named::Select,
+ NamedKey::ZoomIn => Named::ZoomIn,
+ NamedKey::ZoomOut => Named::ZoomOut,
+ NamedKey::BrightnessDown => Named::BrightnessDown,
+ NamedKey::BrightnessUp => Named::BrightnessUp,
+ NamedKey::Eject => Named::Eject,
+ NamedKey::LogOff => Named::LogOff,
+ NamedKey::Power => Named::Power,
+ NamedKey::PowerOff => Named::PowerOff,
+ NamedKey::PrintScreen => Named::PrintScreen,
+ NamedKey::Hibernate => Named::Hibernate,
+ NamedKey::Standby => Named::Standby,
+ NamedKey::WakeUp => Named::WakeUp,
+ NamedKey::AllCandidates => Named::AllCandidates,
+ NamedKey::Alphanumeric => Named::Alphanumeric,
+ NamedKey::CodeInput => Named::CodeInput,
+ NamedKey::Compose => Named::Compose,
+ NamedKey::Convert => Named::Convert,
+ NamedKey::FinalMode => Named::FinalMode,
+ NamedKey::GroupFirst => Named::GroupFirst,
+ NamedKey::GroupLast => Named::GroupLast,
+ NamedKey::GroupNext => Named::GroupNext,
+ NamedKey::GroupPrevious => Named::GroupPrevious,
+ NamedKey::ModeChange => Named::ModeChange,
+ NamedKey::NextCandidate => Named::NextCandidate,
+ NamedKey::NonConvert => Named::NonConvert,
+ NamedKey::PreviousCandidate => Named::PreviousCandidate,
+ NamedKey::Process => Named::Process,
+ NamedKey::SingleCandidate => Named::SingleCandidate,
+ NamedKey::HangulMode => Named::HangulMode,
+ NamedKey::HanjaMode => Named::HanjaMode,
+ NamedKey::JunjaMode => Named::JunjaMode,
+ NamedKey::Eisu => Named::Eisu,
+ NamedKey::Hankaku => Named::Hankaku,
+ NamedKey::Hiragana => Named::Hiragana,
+ NamedKey::HiraganaKatakana => Named::HiraganaKatakana,
+ NamedKey::KanaMode => Named::KanaMode,
+ NamedKey::KanjiMode => Named::KanjiMode,
+ NamedKey::Katakana => Named::Katakana,
+ NamedKey::Romaji => Named::Romaji,
+ NamedKey::Zenkaku => Named::Zenkaku,
+ NamedKey::ZenkakuHankaku => Named::ZenkakuHankaku,
+ NamedKey::Soft1 => Named::Soft1,
+ NamedKey::Soft2 => Named::Soft2,
+ NamedKey::Soft3 => Named::Soft3,
+ NamedKey::Soft4 => Named::Soft4,
+ NamedKey::ChannelDown => Named::ChannelDown,
+ NamedKey::ChannelUp => Named::ChannelUp,
+ NamedKey::Close => Named::Close,
+ NamedKey::MailForward => Named::MailForward,
+ NamedKey::MailReply => Named::MailReply,
+ NamedKey::MailSend => Named::MailSend,
+ NamedKey::MediaClose => Named::MediaClose,
+ NamedKey::MediaFastForward => Named::MediaFastForward,
+ NamedKey::MediaPause => Named::MediaPause,
+ NamedKey::MediaPlay => Named::MediaPlay,
+ NamedKey::MediaPlayPause => Named::MediaPlayPause,
+ NamedKey::MediaRecord => Named::MediaRecord,
+ NamedKey::MediaRewind => Named::MediaRewind,
+ NamedKey::MediaStop => Named::MediaStop,
+ NamedKey::MediaTrackNext => Named::MediaTrackNext,
+ NamedKey::MediaTrackPrevious => Named::MediaTrackPrevious,
+ NamedKey::New => Named::New,
+ NamedKey::Open => Named::Open,
+ NamedKey::Print => Named::Print,
+ NamedKey::Save => Named::Save,
+ NamedKey::SpellCheck => Named::SpellCheck,
+ NamedKey::Key11 => Named::Key11,
+ NamedKey::Key12 => Named::Key12,
+ NamedKey::AudioBalanceLeft => Named::AudioBalanceLeft,
+ NamedKey::AudioBalanceRight => Named::AudioBalanceRight,
+ NamedKey::AudioBassBoostDown => Named::AudioBassBoostDown,
+ NamedKey::AudioBassBoostToggle => Named::AudioBassBoostToggle,
+ NamedKey::AudioBassBoostUp => Named::AudioBassBoostUp,
+ NamedKey::AudioFaderFront => Named::AudioFaderFront,
+ NamedKey::AudioFaderRear => Named::AudioFaderRear,
+ NamedKey::AudioSurroundModeNext => Named::AudioSurroundModeNext,
+ NamedKey::AudioTrebleDown => Named::AudioTrebleDown,
+ NamedKey::AudioTrebleUp => Named::AudioTrebleUp,
+ NamedKey::AudioVolumeDown => Named::AudioVolumeDown,
+ NamedKey::AudioVolumeUp => Named::AudioVolumeUp,
+ NamedKey::AudioVolumeMute => Named::AudioVolumeMute,
+ NamedKey::MicrophoneToggle => Named::MicrophoneToggle,
+ NamedKey::MicrophoneVolumeDown => Named::MicrophoneVolumeDown,
+ NamedKey::MicrophoneVolumeUp => Named::MicrophoneVolumeUp,
+ NamedKey::MicrophoneVolumeMute => Named::MicrophoneVolumeMute,
+ NamedKey::SpeechCorrectionList => Named::SpeechCorrectionList,
+ NamedKey::SpeechInputToggle => Named::SpeechInputToggle,
+ NamedKey::LaunchApplication1 => Named::LaunchApplication1,
+ NamedKey::LaunchApplication2 => Named::LaunchApplication2,
+ NamedKey::LaunchCalendar => Named::LaunchCalendar,
+ NamedKey::LaunchContacts => Named::LaunchContacts,
+ NamedKey::LaunchMail => Named::LaunchMail,
+ NamedKey::LaunchMediaPlayer => Named::LaunchMediaPlayer,
+ NamedKey::LaunchMusicPlayer => Named::LaunchMusicPlayer,
+ NamedKey::LaunchPhone => Named::LaunchPhone,
+ NamedKey::LaunchScreenSaver => Named::LaunchScreenSaver,
+ NamedKey::LaunchSpreadsheet => Named::LaunchSpreadsheet,
+ NamedKey::LaunchWebBrowser => Named::LaunchWebBrowser,
+ NamedKey::LaunchWebCam => Named::LaunchWebCam,
+ NamedKey::LaunchWordProcessor => Named::LaunchWordProcessor,
+ NamedKey::BrowserBack => Named::BrowserBack,
+ NamedKey::BrowserFavorites => Named::BrowserFavorites,
+ NamedKey::BrowserForward => Named::BrowserForward,
+ NamedKey::BrowserHome => Named::BrowserHome,
+ NamedKey::BrowserRefresh => Named::BrowserRefresh,
+ NamedKey::BrowserSearch => Named::BrowserSearch,
+ NamedKey::BrowserStop => Named::BrowserStop,
+ NamedKey::AppSwitch => Named::AppSwitch,
+ NamedKey::Call => Named::Call,
+ NamedKey::Camera => Named::Camera,
+ NamedKey::CameraFocus => Named::CameraFocus,
+ NamedKey::EndCall => Named::EndCall,
+ NamedKey::GoBack => Named::GoBack,
+ NamedKey::GoHome => Named::GoHome,
+ NamedKey::HeadsetHook => Named::HeadsetHook,
+ NamedKey::LastNumberRedial => Named::LastNumberRedial,
+ NamedKey::Notification => Named::Notification,
+ NamedKey::MannerMode => Named::MannerMode,
+ NamedKey::VoiceDial => Named::VoiceDial,
+ NamedKey::TV => Named::TV,
+ NamedKey::TV3DMode => Named::TV3DMode,
+ NamedKey::TVAntennaCable => Named::TVAntennaCable,
+ NamedKey::TVAudioDescription => Named::TVAudioDescription,
+ NamedKey::TVAudioDescriptionMixDown => {
+ Named::TVAudioDescriptionMixDown
+ }
+ NamedKey::TVAudioDescriptionMixUp => {
+ Named::TVAudioDescriptionMixUp
+ }
+ NamedKey::TVContentsMenu => Named::TVContentsMenu,
+ NamedKey::TVDataService => Named::TVDataService,
+ NamedKey::TVInput => Named::TVInput,
+ NamedKey::TVInputComponent1 => Named::TVInputComponent1,
+ NamedKey::TVInputComponent2 => Named::TVInputComponent2,
+ NamedKey::TVInputComposite1 => Named::TVInputComposite1,
+ NamedKey::TVInputComposite2 => Named::TVInputComposite2,
+ NamedKey::TVInputHDMI1 => Named::TVInputHDMI1,
+ NamedKey::TVInputHDMI2 => Named::TVInputHDMI2,
+ NamedKey::TVInputHDMI3 => Named::TVInputHDMI3,
+ NamedKey::TVInputHDMI4 => Named::TVInputHDMI4,
+ NamedKey::TVInputVGA1 => Named::TVInputVGA1,
+ NamedKey::TVMediaContext => Named::TVMediaContext,
+ NamedKey::TVNetwork => Named::TVNetwork,
+ NamedKey::TVNumberEntry => Named::TVNumberEntry,
+ NamedKey::TVPower => Named::TVPower,
+ NamedKey::TVRadioService => Named::TVRadioService,
+ NamedKey::TVSatellite => Named::TVSatellite,
+ NamedKey::TVSatelliteBS => Named::TVSatelliteBS,
+ NamedKey::TVSatelliteCS => Named::TVSatelliteCS,
+ NamedKey::TVSatelliteToggle => Named::TVSatelliteToggle,
+ NamedKey::TVTerrestrialAnalog => Named::TVTerrestrialAnalog,
+ NamedKey::TVTerrestrialDigital => Named::TVTerrestrialDigital,
+ NamedKey::TVTimer => Named::TVTimer,
+ NamedKey::AVRInput => Named::AVRInput,
+ NamedKey::AVRPower => Named::AVRPower,
+ NamedKey::ColorF0Red => Named::ColorF0Red,
+ NamedKey::ColorF1Green => Named::ColorF1Green,
+ NamedKey::ColorF2Yellow => Named::ColorF2Yellow,
+ NamedKey::ColorF3Blue => Named::ColorF3Blue,
+ NamedKey::ColorF4Grey => Named::ColorF4Grey,
+ NamedKey::ColorF5Brown => Named::ColorF5Brown,
+ NamedKey::ClosedCaptionToggle => Named::ClosedCaptionToggle,
+ NamedKey::Dimmer => Named::Dimmer,
+ NamedKey::DisplaySwap => Named::DisplaySwap,
+ NamedKey::DVR => Named::DVR,
+ NamedKey::Exit => Named::Exit,
+ NamedKey::FavoriteClear0 => Named::FavoriteClear0,
+ NamedKey::FavoriteClear1 => Named::FavoriteClear1,
+ NamedKey::FavoriteClear2 => Named::FavoriteClear2,
+ NamedKey::FavoriteClear3 => Named::FavoriteClear3,
+ NamedKey::FavoriteRecall0 => Named::FavoriteRecall0,
+ NamedKey::FavoriteRecall1 => Named::FavoriteRecall1,
+ NamedKey::FavoriteRecall2 => Named::FavoriteRecall2,
+ NamedKey::FavoriteRecall3 => Named::FavoriteRecall3,
+ NamedKey::FavoriteStore0 => Named::FavoriteStore0,
+ NamedKey::FavoriteStore1 => Named::FavoriteStore1,
+ NamedKey::FavoriteStore2 => Named::FavoriteStore2,
+ NamedKey::FavoriteStore3 => Named::FavoriteStore3,
+ NamedKey::Guide => Named::Guide,
+ NamedKey::GuideNextDay => Named::GuideNextDay,
+ NamedKey::GuidePreviousDay => Named::GuidePreviousDay,
+ NamedKey::Info => Named::Info,
+ NamedKey::InstantReplay => Named::InstantReplay,
+ NamedKey::Link => Named::Link,
+ NamedKey::ListProgram => Named::ListProgram,
+ NamedKey::LiveContent => Named::LiveContent,
+ NamedKey::Lock => Named::Lock,
+ NamedKey::MediaApps => Named::MediaApps,
+ NamedKey::MediaAudioTrack => Named::MediaAudioTrack,
+ NamedKey::MediaLast => Named::MediaLast,
+ NamedKey::MediaSkipBackward => Named::MediaSkipBackward,
+ NamedKey::MediaSkipForward => Named::MediaSkipForward,
+ NamedKey::MediaStepBackward => Named::MediaStepBackward,
+ NamedKey::MediaStepForward => Named::MediaStepForward,
+ NamedKey::MediaTopMenu => Named::MediaTopMenu,
+ NamedKey::NavigateIn => Named::NavigateIn,
+ NamedKey::NavigateNext => Named::NavigateNext,
+ NamedKey::NavigateOut => Named::NavigateOut,
+ NamedKey::NavigatePrevious => Named::NavigatePrevious,
+ NamedKey::NextFavoriteChannel => Named::NextFavoriteChannel,
+ NamedKey::NextUserProfile => Named::NextUserProfile,
+ NamedKey::OnDemand => Named::OnDemand,
+ NamedKey::Pairing => Named::Pairing,
+ NamedKey::PinPDown => Named::PinPDown,
+ NamedKey::PinPMove => Named::PinPMove,
+ NamedKey::PinPToggle => Named::PinPToggle,
+ NamedKey::PinPUp => Named::PinPUp,
+ NamedKey::PlaySpeedDown => Named::PlaySpeedDown,
+ NamedKey::PlaySpeedReset => Named::PlaySpeedReset,
+ NamedKey::PlaySpeedUp => Named::PlaySpeedUp,
+ NamedKey::RandomToggle => Named::RandomToggle,
+ NamedKey::RcLowBattery => Named::RcLowBattery,
+ NamedKey::RecordSpeedNext => Named::RecordSpeedNext,
+ NamedKey::RfBypass => Named::RfBypass,
+ NamedKey::ScanChannelsToggle => Named::ScanChannelsToggle,
+ NamedKey::ScreenModeNext => Named::ScreenModeNext,
+ NamedKey::Settings => Named::Settings,
+ NamedKey::SplitScreenToggle => Named::SplitScreenToggle,
+ NamedKey::STBInput => Named::STBInput,
+ NamedKey::STBPower => Named::STBPower,
+ NamedKey::Subtitle => Named::Subtitle,
+ NamedKey::Teletext => Named::Teletext,
+ NamedKey::VideoModeNext => Named::VideoModeNext,
+ NamedKey::Wink => Named::Wink,
+ NamedKey::ZoomToggle => Named::ZoomToggle,
+ NamedKey::F1 => Named::F1,
+ NamedKey::F2 => Named::F2,
+ NamedKey::F3 => Named::F3,
+ NamedKey::F4 => Named::F4,
+ NamedKey::F5 => Named::F5,
+ NamedKey::F6 => Named::F6,
+ NamedKey::F7 => Named::F7,
+ NamedKey::F8 => Named::F8,
+ NamedKey::F9 => Named::F9,
+ NamedKey::F10 => Named::F10,
+ NamedKey::F11 => Named::F11,
+ NamedKey::F12 => Named::F12,
+ NamedKey::F13 => Named::F13,
+ NamedKey::F14 => Named::F14,
+ NamedKey::F15 => Named::F15,
+ NamedKey::F16 => Named::F16,
+ NamedKey::F17 => Named::F17,
+ NamedKey::F18 => Named::F18,
+ NamedKey::F19 => Named::F19,
+ NamedKey::F20 => Named::F20,
+ NamedKey::F21 => Named::F21,
+ NamedKey::F22 => Named::F22,
+ NamedKey::F23 => Named::F23,
+ NamedKey::F24 => Named::F24,
+ NamedKey::F25 => Named::F25,
+ NamedKey::F26 => Named::F26,
+ NamedKey::F27 => Named::F27,
+ NamedKey::F28 => Named::F28,
+ NamedKey::F29 => Named::F29,
+ NamedKey::F30 => Named::F30,
+ NamedKey::F31 => Named::F31,
+ NamedKey::F32 => Named::F32,
+ NamedKey::F33 => Named::F33,
+ NamedKey::F34 => Named::F34,
+ NamedKey::F35 => Named::F35,
+ _ => return keyboard::Key::Unidentified,
+ })
}
- winit::event::VirtualKeyCode::NextTrack => KeyCode::NextTrack,
- winit::event::VirtualKeyCode::NoConvert => KeyCode::NoConvert,
- winit::event::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma,
- winit::event::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter,
- winit::event::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals,
- winit::event::VirtualKeyCode::OEM102 => KeyCode::OEM102,
- winit::event::VirtualKeyCode::Period => KeyCode::Period,
- winit::event::VirtualKeyCode::PlayPause => KeyCode::PlayPause,
- winit::event::VirtualKeyCode::Power => KeyCode::Power,
- winit::event::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack,
- winit::event::VirtualKeyCode::RAlt => KeyCode::RAlt,
- winit::event::VirtualKeyCode::RBracket => KeyCode::RBracket,
- winit::event::VirtualKeyCode::RControl => KeyCode::RControl,
- winit::event::VirtualKeyCode::RShift => KeyCode::RShift,
- winit::event::VirtualKeyCode::RWin => KeyCode::RWin,
- winit::event::VirtualKeyCode::Semicolon => KeyCode::Semicolon,
- winit::event::VirtualKeyCode::Slash => KeyCode::Slash,
- winit::event::VirtualKeyCode::Sleep => KeyCode::Sleep,
- winit::event::VirtualKeyCode::Stop => KeyCode::Stop,
- winit::event::VirtualKeyCode::NumpadSubtract => KeyCode::NumpadSubtract,
- winit::event::VirtualKeyCode::Sysrq => KeyCode::Sysrq,
- winit::event::VirtualKeyCode::Tab => KeyCode::Tab,
- winit::event::VirtualKeyCode::Underline => KeyCode::Underline,
- winit::event::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled,
- winit::event::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown,
- winit::event::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp,
- winit::event::VirtualKeyCode::Wake => KeyCode::Wake,
- winit::event::VirtualKeyCode::WebBack => KeyCode::WebBack,
- winit::event::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites,
- winit::event::VirtualKeyCode::WebForward => KeyCode::WebForward,
- winit::event::VirtualKeyCode::WebHome => KeyCode::WebHome,
- winit::event::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh,
- winit::event::VirtualKeyCode::WebSearch => KeyCode::WebSearch,
- winit::event::VirtualKeyCode::WebStop => KeyCode::WebStop,
- winit::event::VirtualKeyCode::Yen => KeyCode::Yen,
- winit::event::VirtualKeyCode::Copy => KeyCode::Copy,
- winit::event::VirtualKeyCode::Paste => KeyCode::Paste,
- winit::event::VirtualKeyCode::Cut => KeyCode::Cut,
- winit::event::VirtualKeyCode::Asterisk => KeyCode::Asterisk,
+ _ => keyboard::Key::Unidentified,
}
}
@@ -655,13 +812,3 @@ pub fn icon(icon: window::Icon) -> Option<winit::window::Icon> {
winit::window::Icon::from_rgba(pixels, size.width, size.height).ok()
}
-
-// As defined in: http://www.unicode.org/faq/private_use.html
-pub(crate) fn is_private_use_character(c: char) -> bool {
- matches!(
- c,
- '\u{E000}'..='\u{F8FF}'
- | '\u{F0000}'..='\u{FFFFD}'
- | '\u{100000}'..='\u{10FFFD}'
- )
-}
diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs
index 1550b94b..84c81bea 100644
--- a/winit/src/multi_window.rs
+++ b/winit/src/multi_window.rs
@@ -118,7 +118,10 @@ where
let mut debug = Debug::new();
debug.startup_started();
- let event_loop = EventLoopBuilder::with_user_event().build();
+ let event_loop = EventLoopBuilder::with_user_event()
+ .build()
+ .expect("Create event loop");
+
let proxy = event_loop.create_proxy();
let runtime = {
@@ -210,78 +213,78 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref());
- platform::run(event_loop, move |event, window_target, control_flow| {
- use winit::event_loop::ControlFlow;
-
- if let ControlFlow::ExitWithCode(_) = control_flow {
+ let _ = event_loop.run(move |event, event_loop| {
+ if event_loop.exiting() {
return;
}
- let event = match event {
- winit::event::Event::WindowEvent {
- event:
- winit::event::WindowEvent::ScaleFactorChanged {
- new_inner_size,
- ..
- },
- window_id,
- } => Some(winit::event::Event::WindowEvent {
- event: winit::event::WindowEvent::Resized(*new_inner_size),
- window_id,
- }),
- _ => event.to_static(),
- };
-
- if let Some(event) = event {
- event_sender
- .start_send(Event::EventLoopAwakened(event))
- .expect("Send event");
-
- loop {
- let poll = instance.as_mut().poll(&mut context);
-
- match poll {
- task::Poll::Pending => match control_receiver.try_next() {
- Ok(Some(control)) => match control {
- Control::ChangeFlow(flow) => {
- *control_flow = flow;
- }
- Control::CreateWindow {
- id,
- settings,
- title,
- monitor,
- } => {
- let exit_on_close_request =
- settings.exit_on_close_request;
-
- let window = conversion::window_settings(
- settings, &title, monitor, None,
- )
- .build(window_target)
- .expect("Failed to build window");
-
- event_sender
- .start_send(Event::WindowCreated {
- id,
- window,
- exit_on_close_request,
- })
- .expect("Send event");
+ event_sender
+ .start_send(Event::EventLoopAwakened(event))
+ .expect("Send event");
+
+ loop {
+ let poll = instance.as_mut().poll(&mut context);
+
+ match poll {
+ task::Poll::Pending => match control_receiver.try_next() {
+ Ok(Some(control)) => match control {
+ Control::ChangeFlow(flow) => {
+ use winit::event_loop::ControlFlow;
+
+ match (event_loop.control_flow(), flow) {
+ (
+ ControlFlow::WaitUntil(current),
+ ControlFlow::WaitUntil(new),
+ ) if new < current => {}
+ (
+ ControlFlow::WaitUntil(target),
+ ControlFlow::Wait,
+ ) if target > Instant::now() => {}
+ _ => {
+ event_loop.set_control_flow(flow);
+ }
}
- },
- _ => {
- break;
+ }
+ Control::CreateWindow {
+ id,
+ settings,
+ title,
+ monitor,
+ } => {
+ let exit_on_close_request =
+ settings.exit_on_close_request;
+
+ let window = conversion::window_settings(
+ settings, &title, monitor, None,
+ )
+ .build(event_loop)
+ .expect("Failed to build window");
+
+ event_sender
+ .start_send(Event::WindowCreated {
+ id,
+ window,
+ exit_on_close_request,
+ })
+ .expect("Send event");
+ }
+ Control::Exit => {
+ event_loop.exit();
}
},
- task::Poll::Ready(_) => {
- *control_flow = ControlFlow::Exit;
+ _ => {
break;
}
- };
- }
+ },
+ task::Poll::Ready(_) => {
+ event_loop.exit();
+ break;
+ }
+ };
}
- })
+ });
+
+ Ok(())
}
enum Event<Message: 'static> {
@@ -290,11 +293,12 @@ enum Event<Message: 'static> {
window: winit::window::Window,
exit_on_close_request: bool,
},
- EventLoopAwakened(winit::event::Event<'static, Message>),
+ EventLoopAwakened(winit::event::Event<Message>),
}
enum Control {
ChangeFlow(winit::event_loop::ControlFlow),
+ Exit,
CreateWindow {
id: window::Id,
settings: window::Settings,
@@ -372,7 +376,6 @@ async fn run_instance<A, E, C>(
runtime.track(application.subscription().into_recipes());
let mut messages = Vec::new();
- let mut redraw_pending = false;
debug.startup_finished();
@@ -419,191 +422,15 @@ async fn run_instance<A, E, C>(
}
Event::EventLoopAwakened(event) => {
match event {
- event::Event::NewEvents(start_cause) => {
- redraw_pending = matches!(
- start_cause,
- event::StartCause::Init
- | event::StartCause::Poll
- | event::StartCause::ResumeTimeReached { .. }
- );
- }
- event::Event::MainEventsCleared => {
- debug.event_processing_started();
- let mut uis_stale = false;
-
- for (id, window) in window_manager.iter_mut() {
- let mut window_events = vec![];
-
- events.retain(|(window_id, event)| {
- if *window_id == Some(id) || window_id.is_none()
- {
- window_events.push(event.clone());
- false
- } else {
- true
- }
- });
-
- if !redraw_pending
- && window_events.is_empty()
- && messages.is_empty()
- {
- continue;
- }
-
- let (ui_state, statuses) = user_interfaces
- .get_mut(&id)
- .expect("Get user interface")
- .update(
- &window_events,
- window.state.cursor(),
- &mut window.renderer,
- &mut clipboard,
- &mut messages,
- );
-
- if !uis_stale {
- uis_stale = matches!(
- ui_state,
- user_interface::State::Outdated
- );
- }
-
- for (event, status) in window_events
- .into_iter()
- .zip(statuses.into_iter())
- {
- runtime.broadcast(event, status);
- }
- }
-
- debug.event_processing_finished();
-
- // TODO mw application update returns which window IDs to update
- if !messages.is_empty() || uis_stale {
- let mut cached_interfaces: HashMap<
- window::Id,
- user_interface::Cache,
- > = ManuallyDrop::into_inner(user_interfaces)
- .drain()
- .map(|(id, ui)| (id, ui.into_cache()))
- .collect();
-
- // Update application
- update(
- &mut application,
- &mut compositor,
- &mut runtime,
- &mut clipboard,
- &mut control_sender,
- &mut proxy,
- &mut debug,
- &mut messages,
- &mut window_manager,
- &mut cached_interfaces,
- );
-
- // we must synchronize all window states with application state after an
- // application update since we don't know what changed
- for (id, window) in window_manager.iter_mut() {
- window.state.synchronize(
- &application,
- id,
- &window.raw,
- );
- }
-
- // rebuild UIs with the synchronized states
- user_interfaces =
- ManuallyDrop::new(build_user_interfaces(
- &application,
- &mut debug,
- &mut window_manager,
- cached_interfaces,
- ));
- }
-
- debug.draw_started();
-
- for (id, window) in window_manager.iter_mut() {
- // TODO: Avoid redrawing all the time by forcing widgets to
- // request redraws on state changes
- //
- // Then, we can use the `interface_state` here to decide if a redraw
- // is needed right away, or simply wait until a specific time.
- let redraw_event = core::Event::Window(
- id,
- window::Event::RedrawRequested(Instant::now()),
- );
-
- let cursor = window.state.cursor();
-
- let ui = user_interfaces
- .get_mut(&id)
- .expect("Get user interface");
-
- let (ui_state, _) = ui.update(
- &[redraw_event.clone()],
- cursor,
- &mut window.renderer,
- &mut clipboard,
- &mut messages,
- );
-
- let new_mouse_interaction = {
- let state = &window.state;
-
- ui.draw(
- &mut window.renderer,
- state.theme(),
- &renderer::Style {
- text_color: state.text_color(),
- },
- cursor,
- )
- };
-
- if new_mouse_interaction != window.mouse_interaction
- {
- window.raw.set_cursor_icon(
- conversion::mouse_interaction(
- new_mouse_interaction,
- ),
- );
-
- window.mouse_interaction =
- new_mouse_interaction;
- }
-
+ event::Event::NewEvents(
+ event::StartCause::Init
+ | event::StartCause::ResumeTimeReached { .. },
+ ) => {
+ for (_id, window) in window_manager.iter_mut() {
// TODO once widgets can request to be redrawn, we can avoid always requesting a
// redraw
window.raw.request_redraw();
-
- runtime.broadcast(
- redraw_event.clone(),
- core::event::Status::Ignored,
- );
-
- let _ = control_sender.start_send(
- Control::ChangeFlow(match ui_state {
- user_interface::State::Updated {
- redraw_request: Some(redraw_request),
- } => match redraw_request {
- window::RedrawRequest::NextFrame => {
- ControlFlow::Poll
- }
- window::RedrawRequest::At(at) => {
- ControlFlow::WaitUntil(at)
- }
- },
- _ => ControlFlow::Wait,
- }),
- );
}
-
- redraw_pending = false;
-
- debug.draw_finished();
}
event::Event::PlatformSpecific(
event::PlatformSpecific::MacOS(
@@ -624,13 +451,85 @@ async fn run_instance<A, E, C>(
event::Event::UserEvent(message) => {
messages.push(message);
}
- event::Event::RedrawRequested(id) => {
+ event::Event::WindowEvent {
+ window_id: id,
+ event: event::WindowEvent::RedrawRequested,
+ ..
+ } => {
let Some((id, window)) =
window_manager.get_mut_alias(id)
else {
continue;
};
+ // TODO: Avoid redrawing all the time by forcing widgets to
+ // request redraws on state changes
+ //
+ // Then, we can use the `interface_state` here to decide if a redraw
+ // is needed right away, or simply wait until a specific time.
+ let redraw_event = core::Event::Window(
+ id,
+ window::Event::RedrawRequested(Instant::now()),
+ );
+
+ let cursor = window.state.cursor();
+
+ let ui = user_interfaces
+ .get_mut(&id)
+ .expect("Get user interface");
+
+ let (ui_state, _) = ui.update(
+ &[redraw_event.clone()],
+ cursor,
+ &mut window.renderer,
+ &mut clipboard,
+ &mut messages,
+ );
+
+ debug.draw_started();
+ let new_mouse_interaction = ui.draw(
+ &mut window.renderer,
+ window.state.theme(),
+ &renderer::Style {
+ text_color: window.state.text_color(),
+ },
+ cursor,
+ );
+ debug.draw_finished();
+
+ if new_mouse_interaction != window.mouse_interaction {
+ window.raw.set_cursor_icon(
+ conversion::mouse_interaction(
+ new_mouse_interaction,
+ ),
+ );
+
+ window.mouse_interaction = new_mouse_interaction;
+ }
+
+ runtime.broadcast(
+ redraw_event.clone(),
+ core::event::Status::Ignored,
+ );
+
+ let _ = control_sender.start_send(Control::ChangeFlow(
+ match ui_state {
+ user_interface::State::Updated {
+ redraw_request: Some(redraw_request),
+ } => match redraw_request {
+ window::RedrawRequest::NextFrame => {
+ window.raw.request_redraw();
+
+ ControlFlow::Wait
+ }
+ window::RedrawRequest::At(at) => {
+ ControlFlow::WaitUntil(at)
+ }
+ },
+ _ => ControlFlow::Wait,
+ },
+ ));
+
let physical_size = window.state.physical_size();
if physical_size.width == 0 || physical_size.height == 0
@@ -638,14 +537,12 @@ async fn run_instance<A, E, C>(
continue;
}
- debug.render_started();
if window.viewport_version
!= window.state.viewport_version()
{
let logical_size = window.state.logical_size();
debug.layout_started();
-
let ui = user_interfaces
.remove(&id)
.expect("Remove user interface");
@@ -654,7 +551,6 @@ async fn run_instance<A, E, C>(
id,
ui.relayout(logical_size, &mut window.renderer),
);
-
debug.layout_finished();
debug.draw_started();
@@ -669,6 +565,7 @@ async fn run_instance<A, E, C>(
},
window.state.cursor(),
);
+ debug.draw_finished();
if new_mouse_interaction != window.mouse_interaction
{
@@ -681,7 +578,6 @@ async fn run_instance<A, E, C>(
window.mouse_interaction =
new_mouse_interaction;
}
- debug.draw_finished();
compositor.configure_surface(
&mut window.surface,
@@ -693,6 +589,7 @@ async fn run_instance<A, E, C>(
window.state.viewport_version();
}
+ debug.render_started();
match compositor.present(
&mut window.renderer,
&mut window.surface,
@@ -713,9 +610,11 @@ async fn run_instance<A, E, C>(
}
_ => {
debug.render_finished();
+
log::error!(
- "Error {error:?} when presenting surface."
- );
+ "Error {error:?} when \
+ presenting surface."
+ );
// Try rendering all windows again next frame.
for (_id, window) in
@@ -763,7 +662,7 @@ async fn run_instance<A, E, C>(
if let Some(event) = conversion::window_event(
id,
- &window_event,
+ window_event,
window.state.scale_factor(),
window.state.modifiers(),
) {
@@ -771,6 +670,109 @@ async fn run_instance<A, E, C>(
}
}
}
+ event::Event::AboutToWait => {
+ if events.is_empty() && messages.is_empty() {
+ continue;
+ }
+
+ debug.event_processing_started();
+ let mut uis_stale = false;
+
+ for (id, window) in window_manager.iter_mut() {
+ let mut window_events = vec![];
+
+ events.retain(|(window_id, event)| {
+ if *window_id == Some(id) || window_id.is_none()
+ {
+ window_events.push(event.clone());
+ false
+ } else {
+ true
+ }
+ });
+
+ if window_events.is_empty() && messages.is_empty() {
+ continue;
+ }
+
+ let (ui_state, statuses) = user_interfaces
+ .get_mut(&id)
+ .expect("Get user interface")
+ .update(
+ &window_events,
+ window.state.cursor(),
+ &mut window.renderer,
+ &mut clipboard,
+ &mut messages,
+ );
+
+ window.raw.request_redraw();
+
+ if !uis_stale {
+ uis_stale = matches!(
+ ui_state,
+ user_interface::State::Outdated
+ );
+ }
+
+ for (event, status) in window_events
+ .into_iter()
+ .zip(statuses.into_iter())
+ {
+ runtime.broadcast(event, status);
+ }
+ }
+
+ debug.event_processing_finished();
+
+ // TODO mw application update returns which window IDs to update
+ if !messages.is_empty() || uis_stale {
+ let mut cached_interfaces: HashMap<
+ window::Id,
+ user_interface::Cache,
+ > = ManuallyDrop::into_inner(user_interfaces)
+ .drain()
+ .map(|(id, ui)| (id, ui.into_cache()))
+ .collect();
+
+ // Update application
+ update(
+ &mut application,
+ &mut compositor,
+ &mut runtime,
+ &mut clipboard,
+ &mut control_sender,
+ &mut proxy,
+ &mut debug,
+ &mut messages,
+ &mut window_manager,
+ &mut cached_interfaces,
+ );
+
+ // we must synchronize all window states with application state after an
+ // application update since we don't know what changed
+ for (id, window) in window_manager.iter_mut() {
+ window.state.synchronize(
+ &application,
+ id,
+ &window.raw,
+ );
+
+ // TODO once widgets can request to be redrawn, we can avoid always requesting a
+ // redraw
+ window.raw.request_redraw();
+ }
+
+ // rebuild UIs with the synchronized states
+ user_interfaces =
+ ManuallyDrop::new(build_user_interfaces(
+ &application,
+ &mut debug,
+ &mut window_manager,
+ cached_interfaces,
+ ));
+ }
+ }
_ => {}
}
}
@@ -901,16 +903,12 @@ fn run_command<A, C, E>(
.expect("Send control action");
}
window::Action::Close(id) => {
- use winit::event_loop::ControlFlow;
-
let _ = window_manager.remove(id);
let _ = ui_caches.remove(&id);
if window_manager.is_empty() {
control_sender
- .start_send(Control::ChangeFlow(
- ControlFlow::ExitWithCode(0),
- ))
+ .start_send(Control::Exit)
.expect("Send control action");
}
}
@@ -921,10 +919,12 @@ fn run_command<A, C, E>(
}
window::Action::Resize(id, size) => {
if let Some(window) = window_manager.get_mut(id) {
- window.raw.set_inner_size(winit::dpi::LogicalSize {
- width: size.width,
- height: size.height,
- });
+ let _ = window.raw.request_inner_size(
+ winit::dpi::LogicalSize {
+ width: size.width,
+ height: size.height,
+ },
+ );
}
}
window::Action::FetchSize(id, callback) => {
@@ -1167,60 +1167,20 @@ where
/// Returns true if the provided event should cause an [`Application`] to
/// exit.
pub fn user_force_quit(
- event: &winit::event::WindowEvent<'_>,
- _modifiers: winit::event::ModifiersState,
+ event: &winit::event::WindowEvent,
+ _modifiers: winit::keyboard::ModifiersState,
) -> bool {
match event {
#[cfg(target_os = "macos")]
winit::event::WindowEvent::KeyboardInput {
- input:
- winit::event::KeyboardInput {
- virtual_keycode: Some(winit::event::VirtualKeyCode::Q),
+ event:
+ winit::event::KeyEvent {
+ logical_key: winit::keyboard::Key::Character(c),
state: winit::event::ElementState::Pressed,
..
},
..
- } if _modifiers.logo() => true,
+ } if c == "q" && _modifiers.super_key() => true,
_ => false,
}
}
-
-#[cfg(not(target_arch = "wasm32"))]
-mod platform {
- pub fn run<T, F>(
- mut event_loop: winit::event_loop::EventLoop<T>,
- event_handler: F,
- ) -> Result<(), super::Error>
- where
- F: 'static
- + FnMut(
- winit::event::Event<'_, T>,
- &winit::event_loop::EventLoopWindowTarget<T>,
- &mut winit::event_loop::ControlFlow,
- ),
- {
- use winit::platform::run_return::EventLoopExtRunReturn;
-
- let _ = event_loop.run_return(event_handler);
-
- Ok(())
- }
-}
-
-#[cfg(target_arch = "wasm32")]
-mod platform {
- pub fn run<T, F>(
- event_loop: winit::event_loop::EventLoop<T>,
- event_handler: F,
- ) -> !
- where
- F: 'static
- + FnMut(
- winit::event::Event<'_, T>,
- &winit::event_loop::EventLoopWindowTarget<T>,
- &mut winit::event_loop::ControlFlow,
- ),
- {
- event_loop.run(event_handler)
- }
-}
diff --git a/winit/src/multi_window/state.rs b/winit/src/multi_window/state.rs
index 03da5ad7..235771f4 100644
--- a/winit/src/multi_window/state.rs
+++ b/winit/src/multi_window/state.rs
@@ -21,7 +21,7 @@ where
viewport: Viewport,
viewport_version: u64,
cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
- modifiers: winit::event::ModifiersState,
+ modifiers: winit::keyboard::ModifiersState,
theme: <A::Renderer as core::Renderer>::Theme,
appearance: application::Appearance,
}
@@ -72,7 +72,7 @@ where
viewport,
viewport_version: 0,
cursor_position: None,
- modifiers: winit::event::ModifiersState::default(),
+ modifiers: winit::keyboard::ModifiersState::default(),
theme,
appearance,
}
@@ -119,7 +119,7 @@ where
}
/// Returns the current keyboard modifiers of the [`State`].
- pub fn modifiers(&self) -> winit::event::ModifiersState {
+ pub fn modifiers(&self) -> winit::keyboard::ModifiersState {
self.modifiers
}
@@ -142,7 +142,7 @@ where
pub fn update(
&mut self,
window: &Window,
- event: &WindowEvent<'_>,
+ event: &WindowEvent,
_debug: &mut crate::runtime::Debug,
) {
match event {
@@ -158,10 +158,9 @@ where
}
WindowEvent::ScaleFactorChanged {
scale_factor: new_scale_factor,
- new_inner_size,
+ ..
} => {
- let size =
- Size::new(new_inner_size.width, new_inner_size.height);
+ let size = self.viewport.physical_size();
self.viewport = Viewport::with_physical_size(
size,
@@ -180,13 +179,16 @@ where
self.cursor_position = None;
}
WindowEvent::ModifiersChanged(new_modifiers) => {
- self.modifiers = *new_modifiers;
+ self.modifiers = new_modifiers.state();
}
#[cfg(feature = "debug")]
WindowEvent::KeyboardInput {
- input:
- winit::event::KeyboardInput {
- virtual_keycode: Some(winit::event::VirtualKeyCode::F12),
+ event:
+ winit::event::KeyEvent {
+ logical_key:
+ winit::keyboard::Key::Named(
+ winit::keyboard::NamedKey::F12,
+ ),
state: winit::event::ElementState::Pressed,
..
},