1use super::{EventCx, EventState, NavAdvance};
9#[allow(unused)] use crate::Events;
10use crate::event::{Command, Event, FocusSource};
11use crate::util::WidgetHierarchy;
12use crate::{Action, HasId};
13use crate::{Id, Node, geom::Rect, runner::WindowDataErased};
14use winit::event::{ElementState, Ime, KeyEvent};
15use winit::keyboard::{Key, ModifiersState, PhysicalKey};
16use winit::window::ImePurpose;
17
18#[derive(Debug)]
19pub(super) struct PendingSelFocus {
20 target: Option<Id>,
21 key_focus: bool,
22 ime: Option<ImePurpose>,
23 source: FocusSource,
24}
25
26impl EventState {
27 pub(crate) fn clear_access_key_bindings(&mut self) {
28 self.access_keys.clear();
29 }
30
31 pub(crate) fn add_access_key_binding(&mut self, id: &Id, key: &Key) -> bool {
32 if !self.modifiers.alt_key() && !self.config.alt_bypass {
33 return false;
34 }
35
36 if self.access_keys.contains_key(key) {
37 false
38 } else {
39 self.access_keys.insert(key.clone(), id.clone());
40 self.modifiers.alt_key()
41 }
42 }
43
44 #[inline]
46 pub fn modifiers(&self) -> ModifiersState {
47 self.modifiers
48 }
49
50 #[inline]
57 pub fn has_key_focus(&self, w_id: &Id) -> (bool, bool) {
58 let sel_focus = *w_id == self.sel_focus;
59 (sel_focus && self.key_focus, sel_focus)
60 }
61
62 #[inline]
63 pub(super) fn key_focus(&self) -> Option<Id> {
64 if self.key_focus { self.sel_focus.clone() } else { None }
65 }
66
67 pub(super) fn clear_key_focus(&mut self) {
68 if self.key_focus {
69 if let Some(ref mut pending) = self.pending_sel_focus {
70 if pending.target == self.sel_focus {
71 pending.key_focus = false;
72 }
73 } else {
74 self.pending_sel_focus = Some(PendingSelFocus {
75 target: None,
76 key_focus: false,
77 ime: None,
78 source: FocusSource::Synthetic,
79 });
80 }
81 }
82 }
83
84 pub(super) fn clear_sel_socus_on(&mut self, target: &Id) {
85 if let Some(id) = self.sel_focus.as_ref()
86 && target.is_ancestor_of(id)
87 {
88 if let Some(pending) = self.pending_sel_focus.as_mut() {
89 if pending.target.as_ref() == Some(id) {
90 pending.target = None;
91 pending.key_focus = false;
92 } else {
93 }
95 } else {
96 self.pending_sel_focus = Some(PendingSelFocus {
97 target: None,
98 key_focus: false,
99 ime: None,
100 source: FocusSource::Synthetic,
101 });
102 }
103 }
104 }
105
106 #[inline]
122 pub fn request_key_focus(&mut self, target: Id, ime: Option<ImePurpose>, source: FocusSource) {
123 if self.nav_focus.as_ref() != Some(&target) {
124 self.set_nav_focus(target.clone(), source);
125 }
126
127 self.pending_sel_focus = Some(PendingSelFocus {
128 target: Some(target),
129 key_focus: true,
130 ime,
131 source,
132 });
133 }
134
135 #[inline]
149 pub fn request_sel_focus(&mut self, target: Id, source: FocusSource) {
150 if self.nav_focus.as_ref() != Some(&target) {
151 self.set_nav_focus(target.clone(), source);
152 }
153
154 if let Some(ref pending) = self.pending_sel_focus
155 && pending.target.as_ref() == Some(&target)
156 {
157 return;
158 }
159
160 self.pending_sel_focus = Some(PendingSelFocus {
161 target: Some(target),
162 key_focus: false,
163 ime: None,
164 source,
165 });
166 }
167
168 pub fn depress_with_key(&mut self, id: impl HasId, code: impl Into<Option<PhysicalKey>>) {
181 fn inner(state: &mut EventState, id: Id, code: PhysicalKey) {
182 if state
183 .key_depress
184 .get(&code)
185 .map(|target| *target == id)
186 .unwrap_or(false)
187 {
188 return;
189 }
190
191 state.key_depress.insert(code, id.clone());
192 state.redraw(id);
193 }
194
195 if let Some(code) = code.into() {
196 inner(self, id.has_id(), code);
197 }
198 }
199
200 #[inline]
202 pub fn cancel_ime_focus(&mut self, target: Id) {
203 if let Some(pending) = self.pending_sel_focus.as_mut() {
204 if pending.target.as_ref() == Some(&target) {
205 pending.ime = None;
206 }
207 } else if self.ime.is_some() && self.sel_focus.as_ref() == Some(&target) {
208 self.pending_sel_focus = Some(PendingSelFocus {
209 target: Some(target),
210 key_focus: self.key_focus,
211 ime: None,
212 source: FocusSource::Synthetic,
213 });
214 }
215 }
216
217 #[inline]
228 pub fn set_ime_cursor_area(&mut self, target: &Id, rect: Rect) {
229 if self.ime.is_some() && self.sel_focus.as_ref() == Some(target) {
230 self.ime_cursor_area = rect;
231 }
232 }
233}
234
235impl<'a> EventCx<'a> {
236 pub(super) fn keyboard_input(
237 &mut self,
238 mut widget: Node<'_>,
239 mut event: KeyEvent,
240 is_synthetic: bool,
241 ) {
242 if let Some(id) = self.key_focus() {
243 let mut mods = self.modifiers;
245 mods.remove(ModifiersState::SHIFT);
246 if !mods.is_empty()
247 || event
248 .text
249 .as_ref()
250 .and_then(|t| t.chars().next())
251 .map(|c| c.is_control())
252 .unwrap_or(false)
253 {
254 event.text = None;
255 }
256
257 if self.send_event(widget.re(), id, Event::Key(&event, is_synthetic)) {
258 return;
259 }
260 }
261
262 if event.state == ElementState::Pressed && !is_synthetic {
263 self.start_key_event(widget, event.logical_key, event.physical_key);
264 } else if event.state == ElementState::Released
265 && let Some(id) = self.key_depress.remove(&event.physical_key)
266 {
267 self.redraw(id);
268 }
269 }
270
271 pub(super) fn start_key_event(&mut self, mut widget: Node<'_>, vkey: Key, code: PhysicalKey) {
272 let id = widget.id();
273 log::trace!("start_key_event: window={id}, vkey={vkey:?}, physical_key={code:?}");
274
275 let opt_cmd = self.config.shortcuts().try_match(self.modifiers, &vkey);
276
277 if Some(Command::Exit) == opt_cmd {
278 self.runner.exit();
279 return;
280 } else if Some(Command::Close) == opt_cmd {
281 self.handle_close();
282 return;
283 } else if let Some(cmd) = opt_cmd {
284 let mut targets = vec![];
285 let mut send = |_self: &mut Self, id: Id, cmd| -> bool {
286 if !targets.contains(&id) {
287 let event = Event::Command(cmd, Some(code));
288 let used = _self.send_event(widget.re(), id.clone(), event);
289 targets.push(id);
290 used
291 } else {
292 false
293 }
294 };
295
296 if (self.key_focus || cmd.suitable_for_sel_focus())
297 && let Some(id) = self.sel_focus.clone()
298 && send(self, id, cmd)
299 {
300 return;
301 }
302
303 if !self.modifiers.alt_key()
304 && let Some(id) = self.nav_focus.clone()
305 && send(self, id, cmd)
306 {
307 return;
308 }
309
310 if let Some(id) = self
311 .popups
312 .last()
313 .filter(|popup| popup.is_sized)
314 .map(|popup| popup.desc.id.clone())
315 && send(self, id, cmd)
316 {
317 return;
318 }
319
320 let fallback = self.nav_fallback.clone().unwrap_or(id);
321 if send(self, fallback, cmd) {
322 return;
323 }
324
325 if matches!(cmd, Command::Debug) {
326 let over_id = self.mouse.over_id();
327 let hier = WidgetHierarchy::new(widget.as_tile(), over_id.clone());
328 log::debug!("Widget heirarchy (filter={over_id:?}): {hier}");
329 return;
330 }
331 }
332
333 let target = self.access_keys.get(&vkey).cloned();
335
336 if let Some(id) = target {
337 self.close_non_ancestors_of(Some(&id));
338
339 if let Some(id) = self.nav_next(widget.re(), Some(&id), NavAdvance::None) {
340 self.request_nav_focus(id, FocusSource::Key);
341 }
342
343 let event = Event::Command(Command::Activate, Some(code));
344 self.send_event(widget, id, event);
345 } else if self.config.nav_focus && opt_cmd == Some(Command::Tab) {
346 let shift = self.modifiers.shift_key();
347 self.next_nav_focus(None, shift, FocusSource::Key);
348 }
349 }
350
351 pub(super) fn modifiers_changed(&mut self, state: ModifiersState) {
352 if state.alt_key() != self.modifiers.alt_key() {
353 self.window_action(Action::REDRAW);
355 }
356 self.modifiers = state;
357 }
358
359 pub(super) fn ime_event(&mut self, widget: Node<'_>, ime: Ime) {
360 match ime {
361 winit::event::Ime::Enabled => {
362 if self.ime.is_some()
364 && let Some(id) = self.sel_focus.clone()
365 {
366 self.send_event(widget, id, Event::ImeFocus);
367 }
368 }
369 winit::event::Ime::Disabled => {
370 let mut target = self.old_ime_target.take();
374 if target.is_none() && self.ime.is_some() {
375 target = self.sel_focus.clone();
376 self.ime = None;
377 self.ime_cursor_area = Rect::ZERO;
378 }
379 if let Some(id) = target {
380 self.send_event(widget, id, Event::LostImeFocus);
381 }
382 }
383 winit::event::Ime::Preedit(text, cursor) => {
384 if self.ime.is_some()
385 && let Some(id) = self.sel_focus.clone()
386 {
387 self.send_event(widget, id, Event::ImePreedit(&text, cursor));
388 }
389 }
390 winit::event::Ime::Commit(text) => {
391 if self.ime.is_some()
392 && let Some(id) = self.sel_focus.clone()
393 {
394 self.send_event(widget, id, Event::ImeCommit(&text));
395 }
396 }
397 }
398 }
399
400 pub(super) fn set_sel_focus(
402 &mut self,
403 window: &dyn WindowDataErased,
404 mut widget: Node<'_>,
405 pending: PendingSelFocus,
406 ) {
407 let PendingSelFocus {
408 target,
409 key_focus,
410 ime,
411 source,
412 } = pending;
413 let target_is_new = target != self.sel_focus;
414 let old_key_focus = self.key_focus;
415 self.key_focus = key_focus;
416
417 log::trace!("set_sel_focus: target={target:?}, key_focus={key_focus}");
418
419 if let Some(id) = self.sel_focus.clone() {
420 if self.ime.is_some() && (ime.is_none() || target_is_new) {
421 window.set_ime_allowed(None);
422 self.old_ime_target = Some(id.clone());
423 self.ime = None;
424 self.ime_cursor_area = Rect::ZERO;
425 }
426
427 if old_key_focus && (!key_focus || target_is_new) {
428 self.send_event(widget.re(), id.clone(), Event::LostKeyFocus);
430 }
431
432 if target.is_none() {
433 return;
435 } else if target_is_new {
436 self.send_event(widget.re(), id, Event::LostSelFocus);
438 }
439 }
440
441 if let Some(id) = target.clone() {
442 if target_is_new {
443 self.send_event(widget.re(), id.clone(), Event::SelFocus(source));
444 }
445
446 if key_focus && (!old_key_focus || target_is_new) {
447 self.send_event(widget.re(), id.clone(), Event::KeyFocus);
448 }
449
450 if ime.is_some() && (ime != self.ime || target_is_new) {
451 window.set_ime_allowed(ime);
452 self.ime = ime;
453 }
454 }
455
456 self.sel_focus = target;
457 }
458}