Desktop: Mac menu workaround (#3398)
This commit is contained in:
parent
788e82a7d0
commit
548e0df1a1
|
|
@ -1695,16 +1695,6 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fontconfig-cache-parser"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a7f8afb20c8069fd676d27b214559a337cc619a605d25a87baa90b49a06f3b18"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"thiserror 1.0.69",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fontconfig-parser"
|
name = "fontconfig-parser"
|
||||||
version = "0.5.8"
|
version = "0.5.8"
|
||||||
|
|
@ -1744,25 +1734,25 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fontique"
|
name = "fontique"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39f97079e1293b8c1e9fb03a2875d328bd2ee8f3b95ce62959c0acc04049c708"
|
checksum = "ff3336bc0b87fe42305047263fa60d2eabd650d29cbe62fdeb2a66c7a0a595f9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"fontconfig-cache-parser",
|
|
||||||
"hashbrown 0.15.5",
|
"hashbrown 0.15.5",
|
||||||
"icu_locid",
|
"icu_locale_core",
|
||||||
|
"linebender_resource_handle",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-text",
|
"objc2-core-text",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
"peniko 0.4.0",
|
"read-fonts 0.35.0",
|
||||||
"read-fonts 0.29.3",
|
|
||||||
"roxmltree",
|
"roxmltree",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows",
|
"windows",
|
||||||
"windows-core 0.58.0",
|
"windows-core 0.58.0",
|
||||||
|
"yeslogic-fontconfig-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2265,6 +2255,9 @@ dependencies = [
|
||||||
"graphite-desktop-embedded-resources",
|
"graphite-desktop-embedded-resources",
|
||||||
"graphite-desktop-wrapper",
|
"graphite-desktop-wrapper",
|
||||||
"muda",
|
"muda",
|
||||||
|
"objc2",
|
||||||
|
"objc2-app-kit",
|
||||||
|
"objc2-foundation",
|
||||||
"open",
|
"open",
|
||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"rfd",
|
"rfd",
|
||||||
|
|
@ -2446,6 +2439,19 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "harfrust"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92c020db12c71d8a12a3fe7607873cade3a01a6287e29d540c8723276221b9d8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.3",
|
||||||
|
"bytemuck",
|
||||||
|
"core_maths",
|
||||||
|
"read-fonts 0.35.0",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
|
|
@ -2691,24 +2697,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
|
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"litemap 0.8.0",
|
"litemap",
|
||||||
"tinystr 0.8.1",
|
"tinystr",
|
||||||
"writeable 0.6.1",
|
"writeable",
|
||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "icu_locid"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
"litemap 0.7.5",
|
|
||||||
"tinystr 0.7.6",
|
|
||||||
"writeable 0.5.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_normalizer"
|
name = "icu_normalizer"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
|
@ -2761,8 +2755,8 @@ dependencies = [
|
||||||
"displaydoc",
|
"displaydoc",
|
||||||
"icu_locale_core",
|
"icu_locale_core",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
"tinystr 0.8.1",
|
"tinystr",
|
||||||
"writeable 0.6.1",
|
"writeable",
|
||||||
"yoke",
|
"yoke",
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
"zerotrie",
|
"zerotrie",
|
||||||
|
|
@ -3236,12 +3230,6 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "litemap"
|
|
||||||
version = "0.7.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
@ -3811,9 +3799,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-core-text"
|
name = "objc2-core-text"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ba833d4a1cb1aac330f8c973fd92b6ff1858e4aef5cdd00a255eefb28022fb5"
|
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.9.3",
|
"bitflags 2.9.3",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
|
|
@ -4038,14 +4026,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parley"
|
name = "parley"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13e57638545cf2ba4c3e72cc5715e53b1880b829cc3dbefda3d1700c58efe723"
|
checksum = "26746861bb76dbc9bcd5ed1b0b55d2fedf291100961251702a031ab2abd2ce52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontique",
|
"fontique",
|
||||||
|
"harfrust",
|
||||||
"hashbrown 0.15.5",
|
"hashbrown 0.15.5",
|
||||||
"peniko 0.4.0",
|
"linebender_resource_handle",
|
||||||
"skrifa 0.31.3",
|
"skrifa 0.37.0",
|
||||||
"swash",
|
"swash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -4095,17 +4084,6 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "peniko"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9"
|
|
||||||
dependencies = [
|
|
||||||
"color",
|
|
||||||
"kurbo 0.11.3",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peniko"
|
name = "peniko"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
|
@ -4769,16 +4747,6 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "read-fonts"
|
|
||||||
version = "0.29.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "04ca636dac446b5664bd16c069c00a9621806895b8bb02c2dc68542b23b8f25d"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"font-types 0.9.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "read-fonts"
|
name = "read-fonts"
|
||||||
version = "0.34.0"
|
version = "0.34.0"
|
||||||
|
|
@ -4796,6 +4764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
|
checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"core_maths",
|
||||||
"font-types 0.10.0",
|
"font-types 0.10.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -5434,16 +5403,6 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "skrifa"
|
|
||||||
version = "0.31.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dbeb4ca4399663735553a09dd17ce7e49a0a0203f03b706b39628c4d913a8607"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"read-fonts 0.29.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.36.0"
|
version = "0.36.0"
|
||||||
|
|
@ -5715,11 +5674,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swash"
|
name = "swash"
|
||||||
version = "0.2.5"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f745de914febc7c9ab4388dfaf94bbc87e69f57bb41133a9b0c84d4be49856f3"
|
checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"skrifa 0.31.3",
|
"skrifa 0.37.0",
|
||||||
"yazi",
|
"yazi",
|
||||||
"zeno",
|
"zeno",
|
||||||
]
|
]
|
||||||
|
|
@ -5971,15 +5930,6 @@ dependencies = [
|
||||||
"strict-num",
|
"strict-num",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tinystr"
|
|
||||||
version = "0.7.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
|
|
||||||
dependencies = [
|
|
||||||
"displaydoc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinystr"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -6580,7 +6530,7 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"futures-intrusive",
|
"futures-intrusive",
|
||||||
"log",
|
"log",
|
||||||
"peniko 0.5.0",
|
"peniko",
|
||||||
"png",
|
"png",
|
||||||
"skrifa 0.37.0",
|
"skrifa 0.37.0",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
|
|
@ -6597,7 +6547,7 @@ source = "git+https://github.com/linebender/vello#8f2f2564127812362d2c57ded20cad
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"guillotiere",
|
"guillotiere",
|
||||||
"peniko 0.5.0",
|
"peniko",
|
||||||
"skrifa 0.37.0",
|
"skrifa 0.37.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
@ -7715,12 +7665,6 @@ version = "0.45.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
|
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "writeable"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "writeable"
|
name = "writeable"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
|
|
@ -7819,6 +7763,17 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
|
checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yeslogic-fontconfig-sys"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "503a066b4c037c440169d995b869046827dbc71263f6e8f3be6d77d4f3229dbd"
|
||||||
|
dependencies = [
|
||||||
|
"dlib",
|
||||||
|
"once_cell",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ image = { version = "0.25", default-features = false, features = [
|
||||||
"jpeg",
|
"jpeg",
|
||||||
"bmp",
|
"bmp",
|
||||||
] }
|
] }
|
||||||
parley = "0.5"
|
parley = "0.6"
|
||||||
skrifa = "0.36"
|
skrifa = "0.36"
|
||||||
pretty_assertions = "1.4"
|
pretty_assertions = "1.4"
|
||||||
fern = { version = "0.7", features = ["colored"] }
|
fern = { version = "0.7", features = ["colored"] }
|
||||||
|
|
|
||||||
|
|
@ -58,5 +58,8 @@ windows = { version = "0.58.0", features = [
|
||||||
|
|
||||||
# macOS-specific dependencies
|
# macOS-specific dependencies
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
objc2 = { version = "0.6.1", default-features = false }
|
||||||
|
objc2-foundation = { version = "0.3.2", default-features = false }
|
||||||
|
objc2-app-kit = { version = "0.3.2", default-features = false }
|
||||||
muda = { git = "https://github.com/tauri-apps/muda.git", rev = "3f460b8fbaed59cda6d95ceea6904f000f093f15", default-features = false }
|
muda = { git = "https://github.com/tauri-apps/muda.git", rev = "3f460b8fbaed59cda6d95ceea6904f000f093f15", default-features = false }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ pub(crate) struct App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
pub(crate) fn init() {
|
||||||
|
Window::init();
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
cef_context: Box<dyn cef::CefContext>,
|
cef_context: Box<dyn cef::CefContext>,
|
||||||
cef_view_info_sender: Sender<cef::ViewInfoUpdate>,
|
cef_view_info_sender: Sender<cef::ViewInfoUpdate>,
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,27 @@ pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputStat
|
||||||
key_event.native_key_code = event.physical_key.to_native_keycode();
|
key_event.native_key_code = event.physical_key.to_native_keycode();
|
||||||
|
|
||||||
key_event.character = event.logical_key.to_char_representation() as u16;
|
key_event.character = event.logical_key.to_char_representation() as u16;
|
||||||
key_event.unmodified_character = event.key_without_modifiers.to_char_representation() as u16;
|
|
||||||
|
// Mitigation for CEF on Mac bug to prevent NSMenu being triggered by this key event.
|
||||||
|
//
|
||||||
|
// CEF converts the key event into an `NSEvent` internally and passes that to Chromium.
|
||||||
|
// In some cases the `NSEvent` gets to the native Cocoa application, is considered "unhandled" and can trigger menus.
|
||||||
|
//
|
||||||
|
// Why mitigation works:
|
||||||
|
// Leaving `key_event.unmodified_character = 0` still leads to CEF forwarding a "unhandled" event to the native application
|
||||||
|
// but that event is discarded because `key_event.unmodified_character = 0` is considered non-printable and not used for shortcut matching.
|
||||||
|
//
|
||||||
|
// See https://github.com/chromiumembedded/cef/issues/3857
|
||||||
|
//
|
||||||
|
// TODO: Remove mitigation once bug is fixed or a better solution is found.
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
{
|
||||||
|
key_event.unmodified_character = event.key_without_modifiers.to_char_representation() as u16;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")] // See https://www.magpcss.org/ceforum/viewtopic.php?start=10&t=11650
|
#[cfg(target_os = "macos")] // See https://www.magpcss.org/ceforum/viewtopic.php?start=10&t=11650
|
||||||
if key_event.character == 0 && key_event.unmodified_character == 0 && event.text_with_all_modifiers.is_some() {
|
if key_event.character == 0 && key_event.unmodified_character == 0 && event.text_with_all_modifiers.is_some() {
|
||||||
key_event.unmodified_character = 1;
|
key_event.character = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if key_event.type_ == cef_key_event_type_t::KEYEVENT_CHAR.into() {
|
if key_event.type_ == cef_key_event_type_t::KEYEVENT_CHAR.into() {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ pub fn start() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App::init();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context());
|
let wgpu_context = futures::executor::block_on(gpu_context::create_wgpu_context());
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ use winit::window::{Window as WinitWindow, WindowAttributes};
|
||||||
|
|
||||||
use crate::consts::APP_NAME;
|
use crate::consts::APP_NAME;
|
||||||
use crate::event::AppEventScheduler;
|
use crate::event::AppEventScheduler;
|
||||||
|
use crate::window::mac::NativeWindowImpl;
|
||||||
use crate::wrapper::messages::MenuItem;
|
use crate::wrapper::messages::MenuItem;
|
||||||
|
|
||||||
pub(crate) trait NativeWindow {
|
pub(crate) trait NativeWindow {
|
||||||
|
fn init() {}
|
||||||
fn configure(attributes: WindowAttributes, event_loop: &dyn ActiveEventLoop) -> WindowAttributes;
|
fn configure(attributes: WindowAttributes, event_loop: &dyn ActiveEventLoop) -> WindowAttributes;
|
||||||
fn new(window: &dyn WinitWindow, app_event_scheduler: AppEventScheduler) -> Self;
|
fn new(window: &dyn WinitWindow, app_event_scheduler: AppEventScheduler) -> Self;
|
||||||
fn update_menu(&self, _entries: Vec<MenuItem>) {}
|
fn update_menu(&self, _entries: Vec<MenuItem>) {}
|
||||||
|
|
@ -34,6 +36,10 @@ pub(crate) struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
pub(crate) fn init() {
|
||||||
|
NativeWindowImpl::init();
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn new(event_loop: &dyn ActiveEventLoop, app_event_scheduler: AppEventScheduler) -> Self {
|
pub(crate) fn new(event_loop: &dyn ActiveEventLoop, app_event_scheduler: AppEventScheduler) -> Self {
|
||||||
let mut attributes = WindowAttributes::default()
|
let mut attributes = WindowAttributes::default()
|
||||||
.with_title(APP_NAME)
|
.with_title(APP_NAME)
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,21 @@ use winit::event_loop::ActiveEventLoop;
|
||||||
use winit::platform::macos::WindowAttributesMacOS;
|
use winit::platform::macos::WindowAttributesMacOS;
|
||||||
use winit::window::{Window, WindowAttributes};
|
use winit::window::{Window, WindowAttributes};
|
||||||
|
|
||||||
use crate::consts::APP_NAME;
|
|
||||||
use crate::event::AppEventScheduler;
|
use crate::event::AppEventScheduler;
|
||||||
use crate::wrapper::messages::MenuItem;
|
use crate::wrapper::messages::MenuItem;
|
||||||
|
|
||||||
|
mod app;
|
||||||
|
mod menu;
|
||||||
|
|
||||||
pub(super) struct NativeWindowImpl {
|
pub(super) struct NativeWindowImpl {
|
||||||
menu: menu::Menu,
|
menu: menu::Menu,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::NativeWindow for NativeWindowImpl {
|
impl super::NativeWindow for NativeWindowImpl {
|
||||||
|
fn init() {
|
||||||
|
app::init();
|
||||||
|
}
|
||||||
|
|
||||||
fn configure(attributes: WindowAttributes, _event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
fn configure(attributes: WindowAttributes, _event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
||||||
let mac_window = WindowAttributesMacOS::default()
|
let mac_window = WindowAttributesMacOS::default()
|
||||||
.with_titlebar_transparent(true)
|
.with_titlebar_transparent(true)
|
||||||
|
|
@ -20,7 +26,7 @@ impl super::NativeWindow for NativeWindowImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(_window: &dyn Window, app_event_scheduler: AppEventScheduler) -> Self {
|
fn new(_window: &dyn Window, app_event_scheduler: AppEventScheduler) -> Self {
|
||||||
let menu = menu::Menu::new(app_event_scheduler, APP_NAME);
|
let menu = menu::Menu::new(app_event_scheduler);
|
||||||
|
|
||||||
NativeWindowImpl { menu }
|
NativeWindowImpl { menu }
|
||||||
}
|
}
|
||||||
|
|
@ -29,5 +35,3 @@ impl super::NativeWindow for NativeWindowImpl {
|
||||||
self.menu.update(entries);
|
self.menu.update(entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod menu;
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
use objc2::{ClassType, define_class, msg_send};
|
||||||
|
use objc2_app_kit::{NSApplication, NSEvent, NSEventType, NSResponder};
|
||||||
|
use objc2_foundation::NSObject;
|
||||||
|
|
||||||
|
pub(super) fn init() {
|
||||||
|
unsafe {
|
||||||
|
let _: &NSApplication = msg_send![GraphiteApplication::class(), sharedApplication];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_class!(
|
||||||
|
#[unsafe(super(NSApplication, NSResponder, NSObject))]
|
||||||
|
#[name = "GraphiteApplication"]
|
||||||
|
pub(super) struct GraphiteApplication;
|
||||||
|
|
||||||
|
impl GraphiteApplication {
|
||||||
|
#[unsafe(method(sendEvent:))]
|
||||||
|
fn send_event(&self, event: &NSEvent) {
|
||||||
|
// Route keyDown events straight to the key window to skip native menu shortcut handling.
|
||||||
|
if event.r#type() == NSEventType::KeyDown && let Some(key_window) = self.keyWindow() {
|
||||||
|
unsafe { msg_send![&key_window, sendEvent: event] }
|
||||||
|
} else {
|
||||||
|
unsafe { msg_send![super(self), sendEvent: event] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use muda::Menu as MudaMenu;
|
use muda::Menu as MudaMenu;
|
||||||
use muda::accelerator::Accelerator;
|
use muda::accelerator::Accelerator;
|
||||||
use muda::{AboutMetadataBuilder, CheckMenuItem, IsMenuItem, MenuEvent, MenuId, MenuItem, MenuItemKind, PredefinedMenuItem, Result, Submenu};
|
use muda::{CheckMenuItem, IsMenuItem, MenuEvent, MenuId, MenuItem, MenuItemKind, PredefinedMenuItem, Result, Submenu};
|
||||||
|
|
||||||
use crate::event::{AppEvent, AppEventScheduler};
|
use crate::event::{AppEvent, AppEventScheduler};
|
||||||
use crate::wrapper::messages::MenuItem as WrapperMenuItem;
|
use crate::wrapper::messages::MenuItem as WrapperMenuItem;
|
||||||
|
|
@ -10,18 +10,9 @@ pub(super) struct Menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Menu {
|
impl Menu {
|
||||||
pub(super) fn new(event_scheduler: AppEventScheduler, app_name: &str) -> Self {
|
pub(super) fn new(event_scheduler: AppEventScheduler) -> Self {
|
||||||
let about = PredefinedMenuItem::about(None, Some(AboutMetadataBuilder::new().name(Some(app_name)).build()));
|
// TODO: Remove as much app submenu special handling as possible
|
||||||
let hide = PredefinedMenuItem::hide(None);
|
let app_submenu = Submenu::with_items("", true, &[]).unwrap();
|
||||||
let hide_others = PredefinedMenuItem::hide_others(None);
|
|
||||||
let show_all = PredefinedMenuItem::show_all(None);
|
|
||||||
let quit = PredefinedMenuItem::quit(None);
|
|
||||||
let app_submenu = Submenu::with_items(
|
|
||||||
"",
|
|
||||||
true,
|
|
||||||
&[&about, &PredefinedMenuItem::separator(), &hide, &hide_others, &show_all, &PredefinedMenuItem::separator(), &quit],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let menu = MudaMenu::new();
|
let menu = MudaMenu::new();
|
||||||
menu.prepend(&app_submenu).unwrap();
|
menu.prepend(&app_submenu).unwrap();
|
||||||
|
|
@ -29,6 +20,16 @@ impl Menu {
|
||||||
menu.init_for_nsapp();
|
menu.init_for_nsapp();
|
||||||
|
|
||||||
MenuEvent::set_event_handler(Some(move |event: MenuEvent| {
|
MenuEvent::set_event_handler(Some(move |event: MenuEvent| {
|
||||||
|
let mtm = objc2::MainThreadMarker::new().expect("only ever called from main thread");
|
||||||
|
let is_shortcut_triggered = objc2_app_kit::NSApplication::sharedApplication(mtm)
|
||||||
|
.mainMenu()
|
||||||
|
.map(|m| m.highlightedItem().is_some())
|
||||||
|
.unwrap_or_default();
|
||||||
|
if is_shortcut_triggered {
|
||||||
|
tracing::error!("A keyboard input triggered a menu event. This is most likely a bug. Please report!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(id) = menu_id_to_u64(event.id()) {
|
if let Some(id) = menu_id_to_u64(event.id()) {
|
||||||
event_scheduler.schedule(AppEvent::MenuEvent { id });
|
event_scheduler.schedule(AppEvent::MenuEvent { id });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,7 @@ fn convert_menu_bar_entry_to_menu_item(
|
||||||
}
|
}
|
||||||
|
|
||||||
let shortcut = match shortcut {
|
let shortcut = match shortcut {
|
||||||
//TODO: Reenable shortcuts once a workaround for missing keyboard events is found
|
Some(ActionKeys::Keys(LayoutKeysGroup(keys))) => convert_layout_keys_to_shortcut(keys),
|
||||||
Some(ActionKeys::Keys(LayoutKeysGroup(keys))) if false => convert_layout_keys_to_shortcut(keys),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ impl From<TextAlign> for parley::Alignment {
|
||||||
fn from(val: TextAlign) -> Self {
|
fn from(val: TextAlign) -> Self {
|
||||||
match val {
|
match val {
|
||||||
TextAlign::Left => parley::Alignment::Left,
|
TextAlign::Left => parley::Alignment::Left,
|
||||||
TextAlign::Center => parley::Alignment::Middle,
|
TextAlign::Center => parley::Alignment::Center,
|
||||||
TextAlign::Right => parley::Alignment::Right,
|
TextAlign::Right => parley::Alignment::Right,
|
||||||
TextAlign::JustifyLeft => parley::Alignment::Justified,
|
TextAlign::JustifyLeft => parley::Alignment::Justify,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ impl From<TextAlign> for parley::Alignment {
|
||||||
fn from(val: TextAlign) -> Self {
|
fn from(val: TextAlign) -> Self {
|
||||||
match val {
|
match val {
|
||||||
TextAlign::Left => parley::Alignment::Left,
|
TextAlign::Left => parley::Alignment::Left,
|
||||||
TextAlign::Center => parley::Alignment::Middle,
|
TextAlign::Center => parley::Alignment::Center,
|
||||||
TextAlign::Right => parley::Alignment::Right,
|
TextAlign::Right => parley::Alignment::Right,
|
||||||
TextAlign::JustifyLeft => parley::Alignment::Justified,
|
TextAlign::JustifyLeft => parley::Alignment::Justify,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue