Desktop: Update CEF to 142 (#3431)
* update CEF to 142 * fix win * fixup * post merge fix * use getter instead
This commit is contained in:
parent
e8ebcc2c21
commit
3fd0460d03
|
|
@ -1,28 +1,24 @@
|
|||
{ pkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
libcef = pkgs.libcef.overrideAttrs (
|
||||
_: _: {
|
||||
postInstall = ''
|
||||
strip $out/lib/*
|
||||
'';
|
||||
}
|
||||
);
|
||||
cefPath = pkgs.runCommand "cef-path" { } ''
|
||||
cef = pkgs.cef-binary.overrideAttrs (_: _: {
|
||||
postInstall = ''
|
||||
strip $out/Release/*.so*
|
||||
'';
|
||||
});
|
||||
|
||||
cefPath = pkgs.runCommand "cef-path" {} ''
|
||||
mkdir -p $out
|
||||
|
||||
ln -s ${libcef}/include $out/include
|
||||
find ${libcef}/lib -type f -name "*" -exec ln -s {} $out/ \;
|
||||
find ${libcef}/libexec -type f -name "*" -exec ln -s {} $out/ \;
|
||||
cp -r ${libcef}/share/cef/* $out/
|
||||
ln -s ${cef}/include $out/include
|
||||
find ${cef}/Release -name "*" -type f -exec ln -s {} $out/ \;
|
||||
find ${cef}/Resources -name "*" -maxdepth 1 -exec ln -s {} $out/ \;
|
||||
|
||||
echo '${
|
||||
builtins.toJSON {
|
||||
type = "minimal";
|
||||
name = builtins.baseNameOf libcef.src.url;
|
||||
sha1 = "";
|
||||
}
|
||||
}' > $out/archive.json
|
||||
echo '${builtins.toJSON {
|
||||
type = "minimal";
|
||||
name = builtins.baseNameOf cef.src.url;
|
||||
sha1 = "";
|
||||
}}' > $out/archive.json
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1762538466,
|
||||
"narHash": "sha256-8zrIPl6J+wLm9MH5ksHcW7BUHo7jSNOu0/hA0ohOOaM=",
|
||||
"lastModified": 1763938834,
|
||||
"narHash": "sha256-j8iB0Yr4zAvQLueCZ5abxfk6fnG/SJ5JnGUziETjwfg=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "0cea393fffb39575c46b7a0318386467272182fe",
|
||||
"rev": "d9e753122e51cee64eb8d2dddfe11148f339f5a2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -49,11 +49,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762363567,
|
||||
"narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=",
|
||||
"lastModified": 1764242076,
|
||||
"narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4",
|
||||
"rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -79,11 +79,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762569282,
|
||||
"narHash": "sha256-vINZAJpXQTZd5cfh06Rcw7hesH7sGSvi+Tn+HUieJn8=",
|
||||
"lastModified": 1764297505,
|
||||
"narHash": "sha256-qrLpVu2/hA9Cu6IovMEsgh9YRyvmmWS+bSx7C1JGChA=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a35a6144b976f70827c2fe2f5c89d16d8f9179d8",
|
||||
"rev": "9623580f8ce09ec444b9aca107566ec5db110e62",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ version = "0.38.0+1.3.281"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
"libloading 0.8.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -750,15 +750,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cef"
|
||||
version = "141.4.0+141.0.9"
|
||||
source = "git+https://github.com/timon-schelling/cef-rs.git?rev=98493a182928f1ff8d5bf8b9eea61483235df75d#98493a182928f1ff8d5bf8b9eea61483235df75d"
|
||||
version = "142.5.0+142.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32eab60854609591d365051497b1fb78b77b129d9e39ba69b1f71ee3f4ae9345"
|
||||
dependencies = [
|
||||
"ash",
|
||||
"cef-dll-sys",
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.9.0",
|
||||
"metal",
|
||||
"objc",
|
||||
"objc2",
|
||||
"objc2-io-surface",
|
||||
"thiserror 2.0.16",
|
||||
"tracing",
|
||||
|
|
@ -769,8 +771,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cef-dll-sys"
|
||||
version = "141.4.0+141.0.9"
|
||||
source = "git+https://github.com/timon-schelling/cef-rs.git?rev=98493a182928f1ff8d5bf8b9eea61483235df75d#98493a182928f1ff8d5bf8b9eea61483235df75d"
|
||||
version = "142.5.0+142.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a8c418c8eb6abff55f52668dbb8cba3cd5fcf057cf3eed46c04013a08ad9004"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cmake",
|
||||
|
|
@ -1370,7 +1373,7 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
"libloading 0.8.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1391,7 +1394,8 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
|||
[[package]]
|
||||
name = "download-cef"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/timon-schelling/cef-rs.git?rev=98493a182928f1ff8d5bf8b9eea61483235df75d#98493a182928f1ff8d5bf8b9eea61483235df75d"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d98178d9254efef0f69c1f584713d69c790ec00668cd98f783a5085fbefdbddc"
|
||||
dependencies = [
|
||||
"bzip2",
|
||||
"clap",
|
||||
|
|
@ -3114,7 +3118,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.8.8",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
|
|
@ -3211,6 +3215,16 @@ dependencies = [
|
|||
"windows-targets 0.53.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.15"
|
||||
|
|
@ -3764,9 +3778,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc"
|
||||
checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
|
||||
dependencies = [
|
||||
"objc2-encode",
|
||||
]
|
||||
|
|
@ -6994,7 +7008,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"khronos-egl",
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.8.8",
|
||||
"log",
|
||||
"metal",
|
||||
"naga 27.0.3",
|
||||
|
|
@ -7701,7 +7715,7 @@ dependencies = [
|
|||
"as-raw-xcb-connection",
|
||||
"gethostname",
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.8.8",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"x11rb-protocol",
|
||||
|
|
|
|||
|
|
@ -227,9 +227,8 @@ iai-callgrind = { version = "0.16" }
|
|||
ndarray = "0.16"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
dirs = "6.0"
|
||||
# TODO: remove fork usage when https://github.com/tauri-apps/cef-rs/pull/272 is merged and published
|
||||
cef = { git = "https://github.com/timon-schelling/cef-rs.git", rev = "98493a182928f1ff8d5bf8b9eea61483235df75d" }
|
||||
cef-dll-sys = { git = "https://github.com/timon-schelling/cef-rs.git", rev = "98493a182928f1ff8d5bf8b9eea61483235df75d" }
|
||||
cef = "142"
|
||||
cef-dll-sys = "142"
|
||||
include_dir = "0.7"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tracing = "0.1"
|
||||
|
|
@ -270,4 +269,3 @@ debug = true
|
|||
[patch.crates-io]
|
||||
# Force cargo to use only one version of the dpi crate (vendoring breaks without this)
|
||||
dpi = { git = "https://github.com/rust-windowing/winit.git" }
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ impl CefEventHandler for CefHandler {
|
|||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
format: wgpu::TextureFormat::Bgra8Unorm,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||
view_formats: &[],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
key_event.modifiers = input_state.cef_modifiers(&event.location, event.repeat).raw();
|
||||
key_event.modifiers = input_state.cef_modifiers(&event.location, event.repeat).into();
|
||||
|
||||
key_event.windows_key_code = match &event.logical_key {
|
||||
winit::keyboard::Key::Named(named) => named.to_vk_bits(),
|
||||
|
|
@ -130,8 +130,8 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
|
|||
let Some(host) = browser.host() else { return };
|
||||
|
||||
let mut mouse_event: MouseEvent = input_state.into();
|
||||
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_CONTROL_DOWN as u32;
|
||||
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_PRECISION_SCROLLING_DELTA as u32;
|
||||
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_CONTROL_DOWN.0 as u32;
|
||||
mouse_event.modifiers |= cef_event_flags_t::EVENTFLAG_PRECISION_SCROLLING_DELTA.0 as u32;
|
||||
|
||||
let delta = (delta * PINCH_ZOOM_SPEED).round() as i32;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
use cef::MouseEvent;
|
||||
use cef::sys::cef_event_flags_t;
|
||||
use std::time::Instant;
|
||||
use winit::dpi::PhysicalPosition;
|
||||
use winit::event::{ElementState, MouseButton};
|
||||
use winit::keyboard::{KeyLocation, ModifiersState};
|
||||
|
||||
use crate::cef::consts::{MULTICLICK_ALLOWED_TRAVEL, MULTICLICK_TIMEOUT};
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct InputState {
|
||||
modifiers: winit::keyboard::ModifiersState,
|
||||
modifiers: ModifiersState,
|
||||
mouse_position: MousePosition,
|
||||
mouse_state: MouseState,
|
||||
mouse_click_tracker: ClickTracker,
|
||||
}
|
||||
impl InputState {
|
||||
pub(crate) fn modifiers_changed(&mut self, modifiers: &winit::keyboard::ModifiersState) {
|
||||
pub(crate) fn modifiers_changed(&mut self, modifiers: &ModifiersState) {
|
||||
self.modifiers = *modifiers;
|
||||
}
|
||||
|
||||
|
|
@ -31,18 +33,18 @@ impl InputState {
|
|||
self.mouse_click_tracker.input(button, state, self.mouse_position)
|
||||
}
|
||||
|
||||
pub(crate) fn cef_modifiers(&self, location: &winit::keyboard::KeyLocation, is_repeat: bool) -> CefModifiers {
|
||||
pub(crate) fn cef_modifiers(&self, location: &KeyLocation, is_repeat: bool) -> CefModifiers {
|
||||
CefModifiers::new(self, location, is_repeat)
|
||||
}
|
||||
|
||||
pub(crate) fn cef_mouse_modifiers(&self) -> CefModifiers {
|
||||
self.cef_modifiers(&winit::keyboard::KeyLocation::Standard, false)
|
||||
self.cef_modifiers(&KeyLocation::Standard, false)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InputState> for CefModifiers {
|
||||
fn from(val: InputState) -> Self {
|
||||
CefModifiers::new(&val, &winit::keyboard::KeyLocation::Standard, false)
|
||||
CefModifiers::new(&val, &KeyLocation::Standard, false)
|
||||
}
|
||||
}
|
||||
impl From<&InputState> for MouseEvent {
|
||||
|
|
@ -50,7 +52,7 @@ impl From<&InputState> for MouseEvent {
|
|||
MouseEvent {
|
||||
x: val.mouse_position.x as i32,
|
||||
y: val.mouse_position.y as i32,
|
||||
modifiers: val.cef_mouse_modifiers().raw(),
|
||||
modifiers: val.cef_mouse_modifiers().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +61,7 @@ impl From<&mut InputState> for MouseEvent {
|
|||
MouseEvent {
|
||||
x: val.mouse_position.x as i32,
|
||||
y: val.mouse_position.y as i32,
|
||||
modifiers: val.cef_mouse_modifiers().raw(),
|
||||
modifiers: val.cef_mouse_modifiers().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -197,51 +199,51 @@ impl Default for ClickRecord {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct CefModifiers(u32);
|
||||
pub(crate) struct CefModifiers(cef_event_flags_t);
|
||||
impl CefModifiers {
|
||||
fn new(input_state: &InputState, location: &winit::keyboard::KeyLocation, is_repeat: bool) -> Self {
|
||||
use cef::sys::cef_event_flags_t;
|
||||
|
||||
let mut inner = 0;
|
||||
fn new(input_state: &InputState, location: &KeyLocation, is_repeat: bool) -> Self {
|
||||
let mut inner = cef_event_flags_t::EVENTFLAG_NONE;
|
||||
|
||||
if input_state.modifiers.shift_key() {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_SHIFT_DOWN as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_SHIFT_DOWN;
|
||||
}
|
||||
if input_state.modifiers.control_key() {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_CONTROL_DOWN as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_CONTROL_DOWN;
|
||||
}
|
||||
if input_state.modifiers.alt_key() {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_ALT_DOWN as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_ALT_DOWN;
|
||||
}
|
||||
if input_state.modifiers.meta_key() {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_COMMAND_DOWN as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_COMMAND_DOWN;
|
||||
}
|
||||
|
||||
if input_state.mouse_state.left {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_LEFT_MOUSE_BUTTON as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_LEFT_MOUSE_BUTTON;
|
||||
}
|
||||
if input_state.mouse_state.right {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_RIGHT_MOUSE_BUTTON as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_RIGHT_MOUSE_BUTTON;
|
||||
}
|
||||
if input_state.mouse_state.middle {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_MIDDLE_MOUSE_BUTTON as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_MIDDLE_MOUSE_BUTTON;
|
||||
}
|
||||
|
||||
if is_repeat {
|
||||
inner |= cef_event_flags_t::EVENTFLAG_IS_REPEAT as u32;
|
||||
inner |= cef_event_flags_t::EVENTFLAG_IS_REPEAT;
|
||||
}
|
||||
|
||||
inner |= match location {
|
||||
winit::keyboard::KeyLocation::Left => cef_event_flags_t::EVENTFLAG_IS_LEFT as u32,
|
||||
winit::keyboard::KeyLocation::Right => cef_event_flags_t::EVENTFLAG_IS_RIGHT as u32,
|
||||
winit::keyboard::KeyLocation::Numpad => cef_event_flags_t::EVENTFLAG_IS_KEY_PAD as u32,
|
||||
winit::keyboard::KeyLocation::Standard => 0,
|
||||
KeyLocation::Left => cef_event_flags_t::EVENTFLAG_IS_LEFT,
|
||||
KeyLocation::Right => cef_event_flags_t::EVENTFLAG_IS_RIGHT,
|
||||
KeyLocation::Numpad => cef_event_flags_t::EVENTFLAG_IS_KEY_PAD,
|
||||
KeyLocation::Standard => cef_event_flags_t::EVENTFLAG_NONE,
|
||||
};
|
||||
|
||||
Self(inner)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn raw(&self) -> u32 {
|
||||
self.0
|
||||
impl Into<u32> for CefModifiers {
|
||||
fn into(self) -> u32 {
|
||||
self.0.0 as u32
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,16 +31,7 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_paint(
|
||||
&self,
|
||||
_browser: Option<&mut Browser>,
|
||||
_type_: PaintElementType,
|
||||
_dirty_rect_count: usize,
|
||||
_dirty_rects: Option<&Rect>,
|
||||
buffer: *const u8,
|
||||
width: std::ffi::c_int,
|
||||
height: std::ffi::c_int,
|
||||
) {
|
||||
fn on_paint(&self, _browser: Option<&mut Browser>, _type_: PaintElementType, _dirty_rects: Option<&[Rect]>, buffer: *const u8, width: std::ffi::c_int, height: std::ffi::c_int) {
|
||||
let buffer_size = (width * height * 4) as usize;
|
||||
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer, buffer_size) };
|
||||
let frame_buffer = FrameBufferRef::new(buffer_slice, width as usize, height as usize).expect("Failed to create frame buffer");
|
||||
|
|
@ -49,7 +40,7 @@ impl<H: CefEventHandler> ImplRenderHandler for RenderHandlerImpl<H> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "accelerated_paint")]
|
||||
fn on_accelerated_paint(&self, _browser: Option<&mut Browser>, type_: PaintElementType, _dirty_rect_count: usize, _dirty_rects: Option<&Rect>, info: Option<&cef::AcceleratedPaintInfo>) {
|
||||
fn on_accelerated_paint(&self, _browser: Option<&mut Browser>, type_: PaintElementType, _dirty_rects: Option<&[Rect]>, info: Option<&cef::AcceleratedPaintInfo>) {
|
||||
use cef::osr_texture_import::SharedTextureHandle;
|
||||
|
||||
if type_ != PaintElementType::default() {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ var s_diffuse: sampler;
|
|||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let ui_linear = textureSample(t_ui, s_diffuse, in.tex_coords);
|
||||
let ui_linear = srgb_to_linear(textureSample(t_ui, s_diffuse, in.tex_coords));
|
||||
if (ui_linear.a >= 0.999) {
|
||||
return ui_linear;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ fn convert_layout_keys_to_shortcut(layout_keys: &Vec<LayoutKey>) -> Option<Short
|
|||
let mut key: Option<KeyCode> = None;
|
||||
let mut modifiers = Modifiers::default();
|
||||
for layout_key in layout_keys {
|
||||
match layout_key.key {
|
||||
match layout_key.key() {
|
||||
Key::Shift => modifiers |= Modifiers::SHIFT,
|
||||
Key::Control => modifiers |= Modifiers::CONTROL,
|
||||
Key::Alt => modifiers |= Modifiers::ALT,
|
||||
|
|
|
|||
|
|
@ -325,6 +325,12 @@ pub struct LayoutKey {
|
|||
label: String,
|
||||
}
|
||||
|
||||
impl LayoutKey {
|
||||
pub fn key(&self) -> Key {
|
||||
self.key
|
||||
}
|
||||
}
|
||||
|
||||
pub const NUMBER_OF_KEYS: usize = Key::_KeysVariantCount as usize - 1;
|
||||
|
||||
/// Only `Key`s that exist on a physical keyboard should be used.
|
||||
|
|
|
|||
Loading…
Reference in New Issue