diff --git a/crates/kas-core/src/event/cx/cx_pub.rs b/crates/kas-core/src/event/cx/cx_pub.rs index 36b046137..b4a8ad43b 100644 --- a/crates/kas-core/src/event/cx/cx_pub.rs +++ b/crates/kas-core/src/event/cx/cx_pub.rs @@ -399,7 +399,7 @@ impl EventState { #[inline] pub fn request_key_focus(&mut self, target: Id, source: FocusSource) { self.pending_sel_focus = Some(PendingSelFocus { - target, + target: Some(target), key_focus: true, source, }); @@ -421,13 +421,13 @@ impl EventState { #[inline] pub fn request_sel_focus(&mut self, target: Id, source: FocusSource) { if let Some(ref pending) = self.pending_sel_focus { - if pending.target == target { + if pending.target.as_ref() == Some(&target) { return; } } self.pending_sel_focus = Some(PendingSelFocus { - target, + target: Some(target), key_focus: false, source, }); diff --git a/crates/kas-core/src/event/cx/cx_shell.rs b/crates/kas-core/src/event/cx/cx_shell.rs index 944f5f39a..d4c62ff5b 100644 --- a/crates/kas-core/src/event/cx/cx_shell.rs +++ b/crates/kas-core/src/event/cx/cx_shell.rs @@ -200,10 +200,6 @@ impl EventState { } } - if let Some(pending) = cx.pending_sel_focus.take() { - cx.set_sel_focus(win.as_node(data), pending); - } - match std::mem::take(&mut cx.pending_nav_focus) { PendingNavFocus::None => (), PendingNavFocus::Set { target, source } => { @@ -216,6 +212,11 @@ impl EventState { } => cx.next_nav_focus_impl(win.as_node(data), target, reverse, source), } + // Update sel focus after nav focus: + if let Some(pending) = cx.pending_sel_focus.take() { + cx.set_sel_focus(win.as_node(data), pending); + } + while let Some((id, cmd)) = cx.pending_cmds.pop_front() { log::trace!(target: "kas_core::event", "sending pending command {cmd:?} to {id}"); cx.send_event(win.as_node(data), id, Event::Command(cmd, None)); diff --git a/crates/kas-core/src/event/cx/mod.rs b/crates/kas-core/src/event/cx/mod.rs index ee86b6bfb..280a466c3 100644 --- a/crates/kas-core/src/event/cx/mod.rs +++ b/crates/kas-core/src/event/cx/mod.rs @@ -143,8 +143,9 @@ struct PanGrab { coords: [(Coord, Coord); MAX_PAN_GRABS], } +#[derive(Debug)] struct PendingSelFocus { - target: Id, + target: Option, key_focus: bool, source: FocusSource, } @@ -233,6 +234,22 @@ impl EventState { } } + fn clear_key_focus(&mut self) { + if self.key_focus { + if let Some(ref mut pending) = self.pending_sel_focus { + if pending.target == self.sel_focus { + pending.key_focus = false; + } + } else { + self.pending_sel_focus = Some(PendingSelFocus { + target: None, + key_focus: false, + source: FocusSource::Synthetic, + }); + } + } + } + fn set_pan_on( &mut self, id: Id, @@ -607,12 +624,10 @@ impl<'a> EventCx<'a> { source, } = pending; - log::trace!("set_sel_focus: target={target}, key_focus={key_focus}"); - // The widget probably already has nav focus, but anyway: - self.set_nav_focus(target.clone(), FocusSource::Synthetic); + log::trace!("set_sel_focus: target={target:?}, key_focus={key_focus}"); if target == self.sel_focus { - self.key_focus = self.key_focus || key_focus; + self.key_focus = target.is_some() && (self.key_focus || key_focus); return; } @@ -627,11 +642,16 @@ impl<'a> EventCx<'a> { } self.key_focus = key_focus; - self.sel_focus = Some(target.clone()); + self.sel_focus = target.clone(); - self.send_event(widget.re(), target.clone(), Event::SelFocus(source)); - if key_focus { - self.send_event(widget, target, Event::KeyFocus); + if let Some(id) = target { + // The widget probably already has nav focus, but anyway: + self.set_nav_focus(id.clone(), FocusSource::Synthetic); + + self.send_event(widget.re(), id.clone(), Event::SelFocus(source)); + if key_focus { + self.send_event(widget, id, Event::KeyFocus); + } } } @@ -641,16 +661,13 @@ impl<'a> EventCx<'a> { return; } + self.clear_key_focus(); + if let Some(old) = self.nav_focus.take() { self.action(&old, Action::REDRAW); self.send_event(widget.re(), old, Event::LostNavFocus); } - if let Some(id) = self.key_focus() { - self.key_focus = false; - self.send_event(widget.re(), id, Event::LostKeyFocus); - } - self.nav_focus = target.clone(); log::debug!(target: "kas_core::event", "nav_focus = {target:?}"); if let Some(id) = target { @@ -702,32 +719,6 @@ impl<'a> EventCx<'a> { opt_id = self.nav_next(widget.re(), None, advance); } - log::trace!( - target: "kas_core::event", - "next_nav_focus: nav_focus={opt_id:?}", - ); - if opt_id == self.nav_focus { - return; - } - - if let Some(old) = self.nav_focus.take() { - self.redraw(&old); - self.send_event(widget.re(), old, Event::LostNavFocus); - } - - if let Some(id) = self.key_focus() { - self.key_focus = false; - self.send_event(widget.re(), id, Event::LostKeyFocus); - } - - self.nav_focus = opt_id.clone(); - if let Some(id) = opt_id { - log::debug!(target: "kas_core::event", "nav_focus = Some({id})"); - self.redraw(id.clone()); - self.send_event(widget, id, Event::NavFocus(source)); - } else { - log::debug!(target: "kas_core::event", "nav_focus = None"); - // Most likely an error occurred - } + self.set_nav_focus_impl(widget, opt_id, source); } } diff --git a/crates/kas-widgets/src/edit.rs b/crates/kas-widgets/src/edit.rs index 1050cd338..17a1dd17d 100644 --- a/crates/kas-widgets/src/edit.rs +++ b/crates/kas-widgets/src/edit.rs @@ -661,7 +661,7 @@ impl_scope! { if !self.has_key_focus { cx.request_key_focus(self.id(), source); } - if !self.class.multi_line() { + if source == FocusSource::Key && !self.class.multi_line() { self.selection.clear(); self.selection.set_edit_pos(self.text.str_len()); cx.redraw(self);