Started upgrading to winit 0.29.

This commit is contained in:
Samuel Guerra 2023-10-21 15:00:09 -03:00
parent a8fde15a37
commit 19ccec5559
11 changed files with 266 additions and 375 deletions

View File

@ -1,3 +1,9 @@
# Winit Upgrade
* Fix all "!!:".
* Test all.
* Test run_same_process twice (headless example can do this).
# TextInput
* Implement `txt_selectable` text.

View File

@ -8,7 +8,7 @@ description = "Run tasks for managing this project. Implemented in \"./tools/do-
[dependencies]
ansi_term = "0.12"
glob = "0.3"
opener = "0.5"
opener = "0.6"
regex = "1"
[workspace]

View File

@ -111,7 +111,7 @@ parking_lot = "0.12"
futures-timer = "3"
isahc = { version = "1", features = ["cookies", "json"], optional = true }
futures-lite = "1"
async-fs = "1.5"
async-fs = "2"
http-cache-semantics = { version = "1", optional = true }
http-serde = { version = "1", optional = true }
@ -128,7 +128,7 @@ rand = "0.8"
base64 = "0.21"
hashbrown = { version = "0.14", features = ["rayon"] }
sha2 = "0.10"
fs4 = "0.6"
fs4 = "0.7"
remove_dir_all = "0.8"
async-trait = "0.1"
async-recursion = "1"

View File

@ -28,6 +28,10 @@ pub enum MouseButton {
Right,
/// Middle button.
Middle,
/// Back button.
Back,
/// Forward button.
Forward,
/// Any other button.
Other(u16),
}

View File

@ -579,124 +579,178 @@ impl WindowStateAll {
}
/// Describes the appearance of the mouse cursor.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
pub enum CursorIcon {
/// The platform-dependent default cursor.
/// The platform-dependent default cursor. Often rendered as arrow.
#[default]
Default,
/// A simple crosshair.
Crosshair,
/// A hand (often used to indicate links in web browsers).
Hand,
/// Self explanatory.
Arrow,
/// Indicates something is to be moved.
Move,
/// Indicates horizontal text that may be selected or edited.
Text,
/// Program busy indicator.
Wait,
/// Help indicator (often rendered as a "?")
/// A context menu is available for the object under the cursor. Often
/// rendered as an arrow with a small menu-like graphic next to it.
ContextMenu,
/// Help is available for the object under the cursor. Often rendered as a
/// question mark or a balloon.
Help,
/// Progress indicator. Shows that processing is being done. But in contrast
/// with "Wait" the user may still interact with the program. Often rendered
/// as a spinning beach ball, or an arrow with a watch or hourglass.
/// The cursor is a pointer that indicates a link. Often rendered as the
/// backside of a hand with the index finger extended.
Pointer,
/// A progress indicator. The program is performing some processing, but is
/// different from [`CursorIcon::Wait`] in that the user may still interact
/// with the program.
Progress,
/// Cursor showing that something cannot be done.
NotAllowed,
/// Indicates that a context menu is available.
ContextMenu,
/// Indicates a table cell or set of cells can be selected.
Cell,
/// Indicates vertical text that may be selected or edited.
VerticalText,
/// Indicates an alias or shortcut is to be created.
Alias,
/// Indicates something is to be copied.
Copy,
/// An item may not be dropped at the current location.
NoDrop,
/// Indicates something can be grabbed.
Grab,
/// Indicates something is grabbed.
Grabbing,
/// Something can be scrolled in any direction (panned).
AllScroll,
/// Something can be zoomed (magnified) in.
ZoomIn,
/// Something can be zoomed (magnified) out.
ZoomOut,
/// Indicates that the program is busy and the user should wait. Often
/// rendered as a watch or hourglass.
Wait,
/// Indicate that the right vertical edge is to be moved left/right.
/// Indicates that a cell or set of cells may be selected. Often rendered as
/// a thick plus-sign with a dot in the middle.
Cell,
/// A simple crosshair (e.g., short line segments resembling a "+" sign).
/// Often used to indicate a two dimensional bitmap selection mode.
Crosshair,
/// Indicates text that may be selected. Often rendered as an I-beam.
Text,
/// Indicates vertical-text that may be selected. Often rendered as a
/// horizontal I-beam.
VerticalText,
/// Indicates an alias of/shortcut to something is to be created. Often
/// rendered as an arrow with a small curved arrow next to it.
Alias,
/// Indicates something is to be copied. Often rendered as an arrow with a
/// small plus sign next to it.
Copy,
/// Indicates something is to be moved.
Move,
/// Indicates that the dragged item cannot be dropped at the current cursor
/// location. Often rendered as a hand or pointer with a small circle with a
/// line through it.
NoDrop,
/// Indicates that the requested action will not be carried out. Often
/// rendered as a circle with a line through it.
NotAllowed,
/// Indicates that something can be grabbed (dragged to be moved). Often
/// rendered as the backside of an open hand.
Grab,
/// Indicates that something is being grabbed (dragged to be moved). Often
/// rendered as the backside of a hand with fingers closed mostly out of
/// view.
Grabbing,
/// The east border to be moved.
EResize,
/// Indicates that the top horizontal edge is to be moved up/down.
/// The north border to be moved.
NResize,
/// Indicates that top-right corner is to be moved.
/// The north-east corner to be moved.
NeResize,
/// Indicates that the top-left corner is to be moved.
/// The north-west corner to be moved.
NwResize,
/// Indicates that the bottom vertical edge is to be moved up/down.
/// The south border to be moved.
SResize,
/// Indicates that the bottom-right corner is to be moved.
/// The south-east corner to be moved.
SeResize,
/// Indicates that the bottom-left corner is to be moved.
/// The south-west corner to be moved.
SwResize,
/// Indicates that the left vertical edge is to be moved left/right.
/// The west border to be moved.
WResize,
/// Indicates that the any of the vertical edges is to be moved left/right.
/// The east and west borders to be moved.
EwResize,
/// Indicates that the any of the horizontal edges is to be moved up/down.
/// The south and north borders to be moved.
NsResize,
/// Indicates that the top-right or bottom-left corners are to be moved.
/// The north-east and south-west corners to be moved.
NeswResize,
/// Indicates that the top-left or bottom-right corners are to be moved.
/// The north-west and south-east corners to be moved.
NwseResize,
/// Indicates that the item/column can be resized horizontally.
/// Indicates that the item/column can be resized horizontally. Often
/// rendered as arrows pointing left and right with a vertical bar
/// separating them.
ColResize,
/// Indicates that the item/row can be resized vertically.
/// Indicates that the item/row can be resized vertically. Often rendered as
/// arrows pointing up and down with a horizontal bar separating them.
RowResize,
/// Indicates that the something can be scrolled in any direction. Often
/// rendered as arrows pointing up, down, left, and right with a dot in the
/// middle.
AllScroll,
/// Indicates that something can be zoomed in. Often rendered as a
/// magnifying glass with a "+" in the center of the glass.
ZoomIn,
/// Indicates that something can be zoomed in. Often rendered as a
/// magnifying glass with a "-" in the center of the glass.
ZoomOut,
}
impl CursorIcon {
/// All cursor icons.
pub const ALL: &'static [CursorIcon] = &[
CursorIcon::Default,
CursorIcon::Crosshair,
CursorIcon::Hand,
CursorIcon::Arrow,
CursorIcon::Move,
CursorIcon::Text,
CursorIcon::Wait,
CursorIcon::Help,
CursorIcon::Progress,
CursorIcon::NotAllowed,
CursorIcon::ContextMenu,
CursorIcon::Cell,
CursorIcon::VerticalText,
CursorIcon::Alias,
CursorIcon::Copy,
CursorIcon::NoDrop,
CursorIcon::Grab,
CursorIcon::Grabbing,
CursorIcon::AllScroll,
CursorIcon::ZoomIn,
CursorIcon::ZoomOut,
CursorIcon::EResize,
CursorIcon::NResize,
CursorIcon::NeResize,
CursorIcon::NwResize,
CursorIcon::SResize,
CursorIcon::SeResize,
CursorIcon::SwResize,
CursorIcon::WResize,
CursorIcon::EwResize,
CursorIcon::NsResize,
CursorIcon::NeswResize,
CursorIcon::NwseResize,
CursorIcon::ColResize,
CursorIcon::RowResize,
];
pub const ALL: &'static [CursorIcon] = {
use CursorIcon::*;
&[
Default,
ContextMenu,
Help,
Pointer,
Progress,
Wait,
Cell,
Crosshair,
Text,
VerticalText,
Alias,
Copy,
Move,
NoDrop,
NotAllowed,
Grab,
Grabbing,
EResize,
NResize,
NeResize,
NwResize,
SResize,
SeResize,
SwResize,
WResize,
EwResize,
NsResize,
NeswResize,
NwseResize,
ColResize,
RowResize,
AllScroll,
ZoomIn,
ZoomOut,
]
};
/// Estimated icon size and click spot in that size.
pub fn size_and_spot(&self) -> (DipSize, DipPoint) {

View File

@ -70,9 +70,9 @@ zero-ui-view-api = { path = "../zero-ui-view-api", default-features = false }
tracing = "0.1"
gleam = "0.15.0" # matches webrender
winit = { version = "0.28", default-features = false, features = ["x11", "wayland", "wayland-dlopen"] }
glutin = "0.30"
raw-window-handle = "0.5"
winit = { version = "0.29", default-features = false, features = ["x11", "wayland", "wayland-dlopen", "rwh_05"] }
glutin = "0.31"
raw-window-handle = "0.5" # matches glutin
flume = "0.11"
is_main_thread = "0.1"
image = "0.24"
@ -117,7 +117,7 @@ arboard = "3"
sys-locale = "0.3"
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
wayland-client = { version = "0.29.5", default_features = false } # matches winit
wayland-client = { version = "0.31", default_features = false } # matches winit
x11-dl = "2.18.5" # matches winit
tempfile = "3"

View File

@ -128,7 +128,7 @@ impl GlContextManager {
window_target: &EventLoopWindowTarget<AppEvent>,
hardware: Option<bool>,
) -> Result<GlContext, Box<dyn Error>> {
let display_handle = window_target.raw_display_handle();
let display_handle = window_target.raw_display_handle(); // !!: TODO, try from window too.
let window_handle = window.raw_window_handle();
#[cfg(windows)]
@ -684,9 +684,9 @@ mod blit {
#[cfg(windows)]
mod windows_blit {
use raw_window_handle::HasRawWindowHandle;
use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::Graphics::Gdi::*;
use winit::platform::windows::WindowExtWindows;
pub struct GdiBlit {
hwnd: HWND,
@ -694,7 +694,10 @@ mod blit {
impl GdiBlit {
pub fn new(window: &winit::window::Window) -> Self {
GdiBlit { hwnd: window.hwnd() as _ }
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::Win32(h) => GdiBlit { hwnd: h.hwnd as _ },
_ => unreachable!(),
}
}
pub fn supported() -> bool {

View File

@ -112,10 +112,11 @@ use gl::GlContextManager;
use image_cache::ImageCache;
use util::WinitToPx;
use winit::{
event::{DeviceEvent, ModifiersState, WindowEvent},
event::{DeviceEvent, WindowEvent},
event_loop::{ControlFlow, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
keyboard::ModifiersState,
monitor::MonitorHandle,
platform::run_return::EventLoopExtRunReturn,
platform::modifier_supplement::KeyEventExtModifierSupplement,
};
mod config;
@ -144,7 +145,7 @@ use zero_ui_view_api::{
dialog::{DialogId, FileDialog, MsgDialog, MsgDialogResponse},
image::{ImageId, ImageLoadedData, ImageMaskMode, ImageRequest},
ipc::{IpcBytes, IpcBytesReceiver},
keyboard::{Key, KeyCode, KeyState, NativeKeyCode},
keyboard::{Key, KeyCode, KeyState},
mouse::ButtonId,
touch::{TouchId, TouchUpdate},
units::*,
@ -413,11 +414,11 @@ impl App {
self.device_events = false;
if let Some(t) = t {
t.set_device_event_filter(winit::event_loop::DeviceEventFilter::Always);
t.listen_device_events(winit::event_loop::DeviceEvents::Never);
}
#[cfg(windows)]
util::unregister_raw_input();
util::unregister_raw_input(); // !!: TODO, test if we still need this.
}
pub fn run_headless(c: ipc::ViewChannels, ext: ViewExtensions) {
@ -437,7 +438,7 @@ impl App {
app.headless = true;
let winit_span = tracing::trace_span!("winit::EventLoop::new").entered();
let event_loop = EventLoopBuilder::<AppEvent>::with_user_event().build();
let event_loop = EventLoopBuilder::<AppEvent>::with_user_event().build().unwrap();
drop(winit_span);
@ -514,7 +515,7 @@ impl App {
gl::warmup();
let winit_span = tracing::trace_span!("winit::EventLoop::new").entered();
let mut event_loop = EventLoopBuilder::with_user_event().build();
let mut event_loop = EventLoopBuilder::with_user_event().build().unwrap();
drop(winit_span);
let app_sender = event_loop.create_proxy();
@ -543,15 +544,14 @@ impl App {
let mut idle = IdleTrace(None);
idle.enter();
event_loop.run_return(move |event, target, flow| {
event_loop.run(move |event, target| {
idle.exit();
app.window_target = target;
*flow = ControlFlow::Wait;
target.set_control_flow(ControlFlow::Wait);
if app.exited {
*flow = ControlFlow::Exit;
target.exit();
} else {
use winit::event::Event as WEvent;
match event {
@ -567,7 +567,7 @@ impl App {
if rsp.must_be_send() && app.response_sender.send(rsp).is_err() {
// lost connection to app-process
app.exited = true;
*flow = ControlFlow::Exit;
target.exit();
}
}
RequestEvent::FrameReady(wid, msg) => app.on_frame_ready(wid, msg),
@ -579,7 +579,7 @@ impl App {
AppEvent::RefreshMonitors => app.refresh_monitors(),
AppEvent::ParentProcessExited => {
app.exited = true;
*flow = ControlFlow::Exit;
target.exit();
}
AppEvent::ImageLoaded(data) => {
app.image_cache.loaded(data);
@ -596,7 +596,7 @@ impl App {
},
WEvent::Suspended => {}
WEvent::Resumed => {}
WEvent::MainEventsCleared => {
WEvent::AboutToWait => {
app.finish_cursor_entered_move();
app.update_modifiers();
app.flush_coalesced();
@ -605,9 +605,10 @@ impl App {
app.skip_ralt = false;
}
}
WEvent::RedrawRequested(w_id) => app.on_redraw(w_id),
WEvent::RedrawEventsCleared => {}
WEvent::LoopDestroyed => {}
WEvent::MemoryWarning => {
// !!: TODO, create a memory pressure event, flush caches?
}
WEvent::LoopExiting => {}
}
}
@ -722,6 +723,7 @@ impl App {
}
match event {
WindowEvent::RedrawRequested => self.windows[i].redraw(),
WindowEvent::Resized(_) => {
let size = if let Some(size) = self.windows[i].resized() {
size
@ -888,37 +890,34 @@ impl App {
}
WindowEvent::KeyboardInput {
device_id,
input,
event,
is_synthetic,
} => {
linux_modal_dialog_bail!();
if !is_synthetic && self.windows[i].is_focused() {
// see the Window::focus comments.
#[cfg(windows)]
if self.skip_ralt {
// see the Window::focus comments.
if let Some(winit::event::VirtualKeyCode::RAlt) = input.virtual_keycode {
if let winit::keyboard::PhysicalKey::Code(winit::keyboard::KeyCode::AltRight) = event.physical_key {
return;
}
}
let state = util::element_state_to_key_state(input.state);
let key = input.virtual_keycode.map(util::v_key_to_key);
let state = util::element_state_to_key_state(event.state);
let key = util::winit_key_to_key(event.key_without_modifiers());
let key_modified = util::winit_key_to_key(event.logical_key);
let key_code = util::winit_physical_key_to_key_code(event.physical_key);
let d_id = self.device_id(device_id);
let mut send_event = true;
if let Some(key) = key.clone() {
if key.is_modifier() {
match state {
KeyState::Pressed => {
send_event = self
.pressed_modifiers
.insert(key, (d_id, util::scan_code_to_key(input.scancode)))
.is_none();
}
KeyState::Released => send_event = self.pressed_modifiers.remove(&key).is_some(),
if key.is_modifier() {
match state {
KeyState::Pressed => {
send_event = self.pressed_modifiers.insert(key, (d_id, key_code)).is_none();
}
KeyState::Released => send_event = self.pressed_modifiers.remove(&key).is_some(),
}
}
@ -926,32 +925,19 @@ impl App {
self.notify(Event::KeyboardInput {
window: id,
device: d_id,
key_code: util::scan_code_to_key(input.scancode),
key_code,
state,
key: key.clone(),
key_modified: key.clone(),
text: String::new(),
key: Some(key), // !!: TODO, remove option
key_modified: Some(key_modified),
text: event.text.map(|s| s.as_str().to_owned()).unwrap_or_default(),
});
}
}
}
WindowEvent::ReceivedCharacter(c) => {
linux_modal_dialog_bail!();
// merged with previous key press.
self.notify(Event::KeyboardInput {
window: id,
device: DeviceId::INVALID,
key_code: KeyCode::Unidentified(NativeKeyCode::Unidentified),
state: KeyState::Pressed,
key: None,
key_modified: None,
text: c.to_string(),
})
}
WindowEvent::ModifiersChanged(m) => {
linux_modal_dialog_bail!();
if self.windows[i].is_focused() {
self.pending_modifiers_update = Some(m);
self.pending_modifiers_update = Some(m.state());
}
}
WindowEvent::CursorMoved { device_id, position, .. } => {
@ -1122,6 +1108,7 @@ impl App {
// TODO
}
WindowEvent::Occluded(_) => {}
WindowEvent::ActivationTokenDone { .. } => {}
}
}
@ -1154,7 +1141,7 @@ impl App {
let mut notify = vec![];
self.pressed_modifiers.retain(|key, (d_id, s_code)| {
let mut retain = true;
if matches!(key, Key::Super) && !m.logo() {
if matches!(key, Key::Super) && !m.super_key() {
retain = false;
notify.push(Event::KeyboardInput {
window: id,
@ -1166,7 +1153,7 @@ impl App {
text: String::new(),
});
}
if matches!(key, Key::Shift) && !m.shift() {
if matches!(key, Key::Shift) && !m.shift_key() {
retain = false;
notify.push(Event::KeyboardInput {
window: id,
@ -1178,7 +1165,7 @@ impl App {
text: String::new(),
});
}
if matches!(key, Key::Alt | Key::AltGraph) && !m.alt() {
if matches!(key, Key::Alt | Key::AltGraph) && !m.alt_key() {
retain = false;
notify.push(Event::KeyboardInput {
window: id,
@ -1190,7 +1177,7 @@ impl App {
text: String::new(),
});
}
if matches!(key, Key::Ctrl) && !m.ctrl() {
if matches!(key, Key::Ctrl) && !m.control_key() {
retain = false;
notify.push(Event::KeyboardInput {
window: id,
@ -1366,10 +1353,9 @@ impl App {
}),
DeviceEvent::Key(k) => self.notify(Event::DeviceKey {
device: d_id,
key_code: util::scan_code_to_key(k.scancode),
key_code: util::winit_physical_key_to_key_code(k.physical_key),
state: util::element_state_to_key_state(k.state),
}),
DeviceEvent::Text { .. } => {}
}
}
}

View File

@ -6,7 +6,7 @@ use zero_ui_view_api::access::AccessNodeId;
use zero_ui_view_api::clipboard as clipboard_api;
use zero_ui_view_api::{
config::ColorScheme,
keyboard::{Key, KeyCode, KeyState, NativeKeyCode},
keyboard::{Key, KeyCode, KeyState},
mouse::{ButtonState, MouseButton, MouseScrollDelta},
touch::{TouchForce, TouchPhase},
units::*,
@ -241,26 +241,22 @@ impl CursorToWinit for CursorIcon {
use winit::window::CursorIcon::*;
match self {
CursorIcon::Default => Default,
CursorIcon::Crosshair => Crosshair,
CursorIcon::Hand => Hand,
CursorIcon::Arrow => Arrow,
CursorIcon::Move => Move,
CursorIcon::Text => Text,
CursorIcon::Wait => Wait,
CursorIcon::Help => Help,
CursorIcon::Progress => Progress,
CursorIcon::NotAllowed => NotAllowed,
CursorIcon::ContextMenu => ContextMenu,
CursorIcon::Help => Help,
CursorIcon::Pointer => Pointer,
CursorIcon::Progress => Progress,
CursorIcon::Wait => Wait,
CursorIcon::Cell => Cell,
CursorIcon::Crosshair => Crosshair,
CursorIcon::Text => Text,
CursorIcon::VerticalText => VerticalText,
CursorIcon::Alias => Alias,
CursorIcon::Copy => Copy,
CursorIcon::Move => Move,
CursorIcon::NoDrop => NoDrop,
CursorIcon::NotAllowed => NotAllowed,
CursorIcon::Grab => Grab,
CursorIcon::Grabbing => Grabbing,
CursorIcon::AllScroll => AllScroll,
CursorIcon::ZoomIn => ZoomIn,
CursorIcon::ZoomOut => ZoomOut,
CursorIcon::EResize => EResize,
CursorIcon::NResize => NResize,
CursorIcon::NeResize => NeResize,
@ -275,6 +271,10 @@ impl CursorToWinit for CursorIcon {
CursorIcon::NwseResize => NwseResize,
CursorIcon::ColResize => ColResize,
CursorIcon::RowResize => RowResize,
CursorIcon::AllScroll => AllScroll,
CursorIcon::ZoomIn => ZoomIn,
CursorIcon::ZoomOut => ZoomOut,
_ => Default,
}
}
}
@ -351,6 +351,8 @@ pub(crate) fn winit_mouse_button_to_zui(b: winit::event::MouseButton) -> MouseBu
winit::event::MouseButton::Left => MouseButton::Left,
winit::event::MouseButton::Right => MouseButton::Right,
winit::event::MouseButton::Middle => MouseButton::Middle,
winit::event::MouseButton::Back => MouseButton::Back,
winit::event::MouseButton::Forward => MouseButton::Forward,
winit::event::MouseButton::Other(btn) => MouseButton::Other(btn),
}
}
@ -362,195 +364,28 @@ pub(crate) fn winit_theme_to_zui(t: winit::window::Theme) -> ColorScheme {
}
}
use winit::event::VirtualKeyCode as VKey;
pub(crate) fn v_key_to_key(v_key: VKey) -> Key {
match v_key {
// this is temporary until winit releases (chars are localized by the system)
VKey::Key1 => Key::Char('1'),
VKey::Key2 => Key::Char('2'),
VKey::Key3 => Key::Char('3'),
VKey::Key4 => Key::Char('4'),
VKey::Key5 => Key::Char('5'),
VKey::Key6 => Key::Char('6'),
VKey::Key7 => Key::Char('7'),
VKey::Key8 => Key::Char('8'),
VKey::Key9 => Key::Char('9'),
VKey::Key0 => Key::Char('0'),
VKey::A => Key::Char('A'),
VKey::B => Key::Char('B'),
VKey::C => Key::Char('C'),
VKey::D => Key::Char('D'),
VKey::E => Key::Char('E'),
VKey::F => Key::Char('F'),
VKey::G => Key::Char('G'),
VKey::H => Key::Char('H'),
VKey::I => Key::Char('I'),
VKey::J => Key::Char('J'),
VKey::K => Key::Char('K'),
VKey::L => Key::Char('L'),
VKey::M => Key::Char('M'),
VKey::N => Key::Char('N'),
VKey::O => Key::Char('O'),
VKey::P => Key::Char('P'),
VKey::Q => Key::Char('Q'),
VKey::R => Key::Char('R'),
VKey::S => Key::Char('S'),
VKey::T => Key::Char('T'),
VKey::U => Key::Char('U'),
VKey::V => Key::Char('V'),
VKey::W => Key::Char('W'),
VKey::X => Key::Char('X'),
VKey::Y => Key::Char('Y'),
VKey::Z => Key::Char('Z'),
VKey::Escape => Key::Escape,
VKey::F1 => Key::F1,
VKey::F2 => Key::F2,
VKey::F3 => Key::F3,
VKey::F4 => Key::F4,
VKey::F5 => Key::F5,
VKey::F6 => Key::F6,
VKey::F7 => Key::F7,
VKey::F8 => Key::F8,
VKey::F9 => Key::F9,
VKey::F10 => Key::F10,
VKey::F11 => Key::F11,
VKey::F12 => Key::F12,
VKey::F13 => Key::F13,
VKey::F14 => Key::F14,
VKey::F15 => Key::F15,
VKey::F16 => Key::F16,
VKey::F17 => Key::F17,
VKey::F18 => Key::F18,
VKey::F19 => Key::F19,
VKey::F20 => Key::F20,
VKey::F21 => Key::F21,
VKey::F22 => Key::F22,
VKey::F23 => Key::F23,
VKey::F24 => Key::F24,
VKey::Snapshot => Key::PrintScreen,
VKey::Scroll => Key::ScrollLock,
VKey::Pause => Key::Pause,
VKey::Insert => Key::Insert,
VKey::Home => Key::Home,
VKey::Delete => Key::Delete,
VKey::End => Key::End,
VKey::PageDown => Key::PageDown,
VKey::PageUp => Key::PageUp,
VKey::Left => Key::ArrowLeft,
VKey::Up => Key::ArrowUp,
VKey::Right => Key::ArrowRight,
VKey::Down => Key::ArrowDown,
VKey::Back => Key::Backspace,
VKey::Return => Key::Enter,
VKey::Space => Key::Space,
VKey::Compose => Key::Compose,
VKey::Caret => Key::Unidentified,
VKey::Numlock => Key::NumLock,
VKey::Numpad0 => Key::Char('0'),
VKey::Numpad1 => Key::Char('1'),
VKey::Numpad2 => Key::Char('2'),
VKey::Numpad3 => Key::Char('3'),
VKey::Numpad4 => Key::Char('4'),
VKey::Numpad5 => Key::Char('5'),
VKey::Numpad6 => Key::Char('6'),
VKey::Numpad7 => Key::Char('7'),
VKey::Numpad8 => Key::Char('8'),
VKey::Numpad9 => Key::Char('9'),
VKey::NumpadAdd => Key::Char('+'),
VKey::NumpadDivide => Key::Char('/'),
VKey::NumpadDecimal => Key::Char('.'),
VKey::NumpadComma => Key::Char(','),
VKey::NumpadEnter => Key::Enter,
VKey::NumpadEquals => Key::Char('='),
VKey::NumpadMultiply => Key::Char('*'),
VKey::NumpadSubtract => Key::Char('-'),
VKey::AbntC1 => Key::Char('/'),
VKey::AbntC2 => Key::Char('ç'),
VKey::Apostrophe => Key::Char('\''),
VKey::Apps => Key::AppSwitch,
VKey::Asterisk => Key::Char('*'),
VKey::At => Key::Char('@'),
VKey::Ax => Key::Unidentified,
VKey::Backslash => Key::Char('\\'),
VKey::Calculator => Key::LaunchApplication2,
VKey::Capital => Key::Unidentified,
VKey::Colon => Key::Char(':'),
VKey::Comma => Key::Char(','),
VKey::Convert => Key::Convert,
VKey::Equals => Key::Char('='),
VKey::Grave => Key::Char('`'),
VKey::Kana => Key::KanaMode,
VKey::Kanji => Key::KanjiMode,
VKey::LAlt => Key::Alt,
VKey::LBracket => Key::Char('['),
VKey::LControl => Key::Ctrl,
VKey::LShift => Key::Shift,
VKey::LWin => Key::Super,
VKey::Mail => Key::LaunchMail,
VKey::MediaSelect => Key::MediaApps,
VKey::MediaStop => Key::MediaStop,
VKey::Minus => Key::Char('-'),
VKey::Mute => Key::AudioVolumeMute,
VKey::MyComputer => Key::Unidentified,
VKey::NavigateForward => Key::NavigateNext,
VKey::NavigateBackward => Key::NavigatePrevious,
VKey::NextTrack => Key::MediaTrackNext,
VKey::NoConvert => Key::NonConvert,
VKey::OEM102 => Key::Unidentified,
VKey::Period => Key::Char('.'),
VKey::PlayPause => Key::MediaPlayPause,
VKey::Plus => Key::Char('+'),
VKey::Power => Key::Power,
VKey::PrevTrack => Key::MediaTrackPrevious,
VKey::RAlt => Key::AltGraph,
VKey::RBracket => Key::Char(']'),
VKey::RControl => Key::Ctrl,
VKey::RShift => Key::Shift,
VKey::RWin => Key::Super,
VKey::Semicolon => Key::Char(';'),
VKey::Slash => Key::Char('/'),
VKey::Sleep => Key::Standby,
VKey::Stop => Key::MediaStop,
VKey::Sysrq => Key::PrintScreen,
VKey::Tab => Key::Tab,
VKey::Underline => Key::Char('_'),
VKey::Unlabeled => Key::Unidentified,
VKey::VolumeDown => Key::AudioVolumeDown,
VKey::VolumeUp => Key::AudioVolumeUp,
VKey::Wake => Key::WakeUp,
VKey::WebBack => Key::BrowserBack,
VKey::WebFavorites => Key::BrowserFavorites,
VKey::WebForward => Key::BrowserForward,
VKey::WebHome => Key::BrowserHome,
VKey::WebRefresh => Key::BrowserRefresh,
VKey::WebSearch => Key::BrowserSearch,
VKey::WebStop => Key::BrowserStop,
VKey::Yen => Key::Char('¥'),
VKey::Copy => Key::Copy,
VKey::Paste => Key::Paste,
VKey::Cut => Key::Cut,
#[cfg(windows)]
pub(crate) fn winit_to_hwnd(window: &winit::window::Window) -> isize {
use raw_window_handle::HasRawWindowHandle;
match window.raw_window_handle() {
raw_window_handle::RawWindowHandle::Win32(w) => w.hwnd as _,
_ => unreachable!(),
}
}
pub(crate) fn scan_code_to_key(scan: winit::event::ScanCode) -> KeyCode {
let k = if cfg!(windows) {
NativeKeyCode::Windows(scan as _)
} else if cfg!(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
)) {
NativeKeyCode::Xkb(scan as _)
} else if cfg!(target_os = "macos") {
NativeKeyCode::MacOS(scan as _)
} else if cfg!(target_os = "android") {
NativeKeyCode::Android(scan as _)
} else {
NativeKeyCode::Unidentified
};
KeyCode::Unidentified(k)
use winit::keyboard::Key as WinitKey;
pub(crate) fn winit_key_to_key(key: WinitKey) -> Key {
todo!() // !!: TODO
}
use winit::keyboard::KeyCode as WinitKeyCode;
pub(crate) fn winit_key_code_to_key_code(key: WinitKeyCode) -> KeyCode {
todo!() // !!: TODO
}
use winit::keyboard::PhysicalKey as WinitPhysicalKey;
pub(crate) fn winit_physical_key_to_key_code(key: WinitPhysicalKey) -> KeyCode {
todo!() // !!: TODO
}
thread_local! {
@ -604,7 +439,8 @@ pub(crate) extern "system" fn minimal_wndproc(
}
#[cfg(windows)]
pub fn get_instance_handle() -> winit::platform::windows::HINSTANCE {
pub fn get_instance_handle() -> isize {
// HINSTANCE
// Gets the instance handle by taking the address of the
// pseudo-variable created by the Microsoft linker:
// https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483

View File

@ -227,12 +227,11 @@ impl Window {
#[cfg(windows)]
{
let event_sender = event_sender.clone();
use winit::platform::windows::WindowExtWindows;
let mut first_focus = false;
let window_id = winit_window.id();
let hwnd = winit_window.hwnd() as _;
let hwnd = crate::util::winit_to_hwnd(&winit_window);
crate::util::set_raw_windows_event_handler(hwnd, u32::from_ne_bytes(*b"alf4") as _, move |_, msg, wparam, _| {
if !first_focus && unsafe { windows_sys::Win32::UI::WindowsAndMessaging::GetForegroundWindow() } == hwnd {
// Windows sends a `WM_SETFOCUS` when the window open, even if the user changed focus to something
@ -502,10 +501,8 @@ impl Window {
#[cfg(windows)]
fn windows_is_foreground(&self) -> bool {
use winit::platform::windows::WindowExtWindows;
let foreground = unsafe { windows_sys::Win32::UI::WindowsAndMessaging::GetForegroundWindow() };
foreground == self.window.hwnd()
foreground == crate::util::winit_to_hwnd(&self.window)
}
pub fn is_focused(&self) -> bool {
@ -598,10 +595,9 @@ impl Window {
#[cfg(windows)]
pub fn bring_to_top(&mut self) {
use windows_sys::Win32::UI::WindowsAndMessaging::*;
use winit::platform::windows::WindowExtWindows;
if !self.is_always_on_top {
let hwnd = self.window.hwnd();
let hwnd = crate::util::winit_to_hwnd(&self.window);
unsafe {
let _ = SetWindowPos(
@ -712,10 +708,10 @@ impl Window {
Foundation::{POINT, RECT},
UI::WindowsAndMessaging::*,
};
use winit::platform::windows::{MonitorHandleExtWindows, WindowExtWindows};
use winit::platform::windows::MonitorHandleExtWindows;
if let Some(monitor) = self.window.current_monitor() {
let hwnd = self.window.hwnd() as _;
let hwnd = crate::util::winit_to_hwnd(&self.window) as _;
let mut placement = WINDOWPLACEMENT {
length: mem::size_of::<WINDOWPLACEMENT>() as _,
flags: 0,
@ -835,7 +831,7 @@ impl Window {
fn is_maximized(&self) -> bool {
#[cfg(windows)]
{
let hwnd = winit::platform::windows::WindowExtWindows::hwnd(&self.window);
let hwnd = crate::util::winit_to_hwnd(&self.window);
// SAFETY: function does not fail.
return unsafe { windows_sys::Win32::UI::WindowsAndMessaging::IsZoomed(hwnd as _) } != 0;
}
@ -856,7 +852,7 @@ impl Window {
#[cfg(windows)]
{
let hwnd = winit::platform::windows::WindowExtWindows::hwnd(&self.window);
let hwnd = crate::util::winit_to_hwnd(&self.window);
// SAFETY: function does not fail.
return unsafe { windows_sys::Win32::UI::WindowsAndMessaging::IsIconic(hwnd as _) } != 0;
}
@ -913,7 +909,14 @@ impl Window {
new_state.restore_rect = self.state.restore_rect;
self.set_inner_position(new_state.restore_rect.origin);
self.window.set_inner_size(new_state.restore_rect.size.to_winit());
let new_size = new_state.restore_rect.size.to_winit();
if let Some(immediate_new_size) = self.window.request_inner_size(new_size) {
if immediate_new_size == new_size.to_physical(self.window.scale_factor()) {
// size changed immediately, winit says: "resize event in such case may not be generated"
// * Review of Windows and Linux shows that the resize event is send.
tracing::debug!("immediate resize may not have notified, new size: {immediate_new_size:?}");
}
}
self.window.set_min_inner_size(Some(new_state.min_size.to_winit()));
self.window.set_max_inner_size(Some(new_state.max_size.to_winit()));
@ -988,7 +991,6 @@ impl Window {
self.taskbar_visible = visible;
use windows_sys::Win32::System::Com::*;
use winit::platform::windows::WindowExtWindows;
use crate::util::taskbar_com;
@ -1006,10 +1008,10 @@ impl Window {
0 => {
let result = if visible {
let add_tab = (*(*taskbar_list2).lpVtbl).parent.AddTab;
add_tab(taskbar_list2.cast(), self.window.hwnd() as _)
add_tab(taskbar_list2.cast(), crate::util::winit_to_hwnd(&self.window) as _)
} else {
let delete_tab = (*(*taskbar_list2).lpVtbl).parent.DeleteTab;
delete_tab(taskbar_list2.cast(), self.window.hwnd() as _)
delete_tab(taskbar_list2.cast(), crate::util::winit_to_hwnd(&self.window) as _)
};
if result != 0 {
let mtd_name = if visible { "AddTab" } else { "DeleteTab" };
@ -1131,7 +1133,7 @@ impl Window {
self.state = new_state;
if self.state.state == WindowState::Normal {
self.window.set_inner_size(self.state.restore_rect.size.to_winit());
self.window.request_inner_size(self.state.restore_rect.size.to_winit());
self.window.set_min_inner_size(Some(self.state.min_size.to_winit()));
self.window.set_max_inner_size(Some(self.state.max_size.to_winit()));

View File

@ -141,7 +141,7 @@ impl LinkStyle {
widget_set! {
self;
text::font_color = color_scheme_map(web_colors::LIGHT_BLUE, colors::BLUE);
crate::properties::cursor = CursorIcon::Hand;
crate::properties::cursor = CursorIcon::Pointer;
access_role = AccessRole::Link;
when *#is_cap_hovered {