1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2026 FernTech
//! Window-level menubar key dispatcher.
//!
//! Allows a single `MenuBar` per window to intercept F10 and
//! `Alt+<letter>` key events BEFORE focus-based event dispatch — the
//! same architecture Win32 uses with `WM_SYSKEYDOWN` and
//! `DefWindowProc`. Without this hook, a `Key::F10` press would only
//! reach widgets that are strict ancestors of whatever widget
//! happens to be focused, which the menubar usually isn't.
//!
//! See [`docs/shortcut-intent-action.md`](../../../../docs/shortcut-intent-action.md)
//! for the broader keystroke pipeline.
//!
//! ### Lifetime model
//!
//! `MenuBar::build` constructs an `Rc<dyn MenubarDispatcher>` and
//! installs it via [`WindowState::install_menubar_dispatcher`](crate::window::WindowState::install_menubar_dispatcher),
//! receiving a `MenubarGuard`. The guard is stored on the MenuBar's
//! per-build state; dropping it (on rebuild or removal) clears the
//! window's slot. At most one dispatcher is registered per window
//! at a time — the most-recently-installed wins; a `debug_assert!`
//! fires in debug builds if a second installation happens while the
//! slot is still held.
//!
//! ### Mnemonic activation
//!
//! Mnemonics derived from `&File` / `&Edit` menubar labels are
//! deliberately **not** registered as `Shortcut`s in
//! `ShortcutRegistry`. They are derived from labels (which change
//! with locale), they are not user-rebindable per Win32 / GNOME
//! convention, and they would clutter `ShortcutSettings`. Routing
//! them through this dedicated window-level slot keeps the
//! Action/Intent/Shortcut pipeline free of derived noise.
//!
//! ### macOS limitation
//!
//! The dispatcher is installed on every platform, but its
//! `Alt+<letter>` branch is **compiled out on macOS** (see the
//! `#[cfg(not(target_os = "macos"))]` gate inside the impl). The
//! reason: macOS rewrites Option+letter for accented character
//! composition (Option+E → ´, Option+F → ƒ, …) *before* winit hands
//! the keystroke to the app. The post-rewrite character can never
//! match the mnemonic table, and silently intercepting the chord
//! would break accented text input system-wide. **F10** and
//! **bare-Alt-tap** continue to work on macOS (neither involves a
//! transformed letter), and **bare-letter activation inside an open
//! menu** is unaffected (the rewriting is Option+letter, not
//! letter-alone). The `MenuLabel` widget hides the visual
//! underline on macOS to match. macOS-native users typically
//! prefer F10 + arrows + Enter, plus the existing `Shortcut`
//! system for Cmd+? accelerators (which the OS does not rewrite).
use RefCell;
use Rc;
use crate;
use crateEventContext;
use crateWidgetId;
/// A closure that reveals a collapsed (hamburger) `MenuBar` — it shows
/// the bar as a floating overlay. Carried by [`MenubarAction`] so that
/// `teksilo-app` can run the reveal (which needs an [`EventContext`])
/// before performing the focus / open-menu step. Must be idempotent:
/// calling it when the bar is already revealed is a no-op.
pub type MenubarReveal = ;
/// A `KeyDown` event passed through the menubar dispatcher.
/// The result of `MenubarDispatcher::try_handle`. The caller (the
/// app-level event loop in `teksilo-app`) translates this into the
/// concrete WidgetTree calls.
///
/// Cannot derive `Debug` because of the `reveal` closure; a manual
/// impl is provided below.
/// Object-safe trait implemented by `MenuBar`. `teksilo-app` consults
/// the installed dispatcher (if any) BEFORE normal focus-based key
/// dispatch on every `KeyboardInput`, and separately on every
/// `ModifiersChanged` that detects the bare-Alt-tap pattern.
/// Internal storage type for the per-window dispatcher slot.
pub type MenubarDispatcherSlot = ;
/// RAII guard returned from [`WindowState::install_menubar_dispatcher`](crate::window::WindowState::install_menubar_dispatcher).
/// Dropping the guard clears the slot iff it still points at the same
/// dispatcher (`Rc::ptr_eq`); a later install + drop-of-stale-guard
/// is a no-op (so racing rebuilds don't accidentally clear each
/// other's slot).