git.lucas.co / cce-display-manager
login greeter
git clone https://git.lucas.co/cce-display-manager.git

commitf9595713df9e6c13bbe260be16edccf365be3778
parent811fd09ffd
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-08 12:34
refactor(focus): drive focus through UiContext::focus_widget / unfocus_widget

A direct w.focus() / w.unfocus() left the window's record of focus (the Tab
walk, the accessibility tree) behind: on a widget that had let go, or beside
a newly focused one. The UiContext helpers do what the direct call did and
keep the record in step (cce-ui's global-state RFC, phase 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 src/main.rs | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 2baad9a..5368853 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -380,13 +380,13 @@ impl State {
         match field {
             Field::Username => {
                 self.ui_context.set_focused(&mut self.username_box);
-                self.password_box.unfocus();
-                self.username_box.focus();
+                self.ui_context.unfocus_widget(&mut self.password_box);
+                self.ui_context.focus_widget(&mut self.username_box);
             }
             Field::Password => {
                 self.ui_context.set_focused(&mut self.password_box);
-                self.username_box.unfocus();
-                self.password_box.focus();
+                self.ui_context.unfocus_widget(&mut self.username_box);
+                self.ui_context.focus_widget(&mut self.password_box);
             }
         }
     }
@@ -532,8 +532,8 @@ impl State {
         if button == MouseButton::Left && state == ElementState::Pressed {
             if !handled {
                 self.ui_context.clear_focus();
-                self.username_box.unfocus();
-                self.password_box.unfocus();
+                self.ui_context.unfocus_widget(&mut self.username_box);
+                self.ui_context.unfocus_widget(&mut self.password_box);
                 changed = true;
             }
         }
@@ -569,7 +569,7 @@ impl State {
             self.status_lbl.text = "Username cannot be empty".to_string();
             self.status_lbl.is_error = true;
             self.ui_context.set_focused(&mut self.username_box);
-            self.username_box.focus();
+            self.ui_context.focus_widget(&mut self.username_box);
         } else if password.is_empty() {
             if is_fprint_enabled() {
                 self.start_fprint_auth();
@@ -577,7 +577,7 @@ impl State {
                 self.status_lbl.text = "Password cannot be empty".to_string();
                 self.status_lbl.is_error = true;
                 self.ui_context.set_focused(&mut self.password_box);
-                self.password_box.focus();
+                self.ui_context.focus_widget(&mut self.password_box);
             }
         } else {
             // A typed password supersedes any fingerprint attempt still
@@ -730,8 +730,8 @@ impl cce_ui::engine::Application for State {
         let has_username = !app.username_box.text.trim().to_string().is_empty();
         let first = if has_username { Field::Password } else { Field::Username };
         match first {
-            Field::Password => app.password_box.focus(),
-            Field::Username => app.username_box.focus(),
+            Field::Password => app.ui_context.focus_widget(&mut app.password_box),
+            Field::Username => app.ui_context.focus_widget(&mut app.username_box),
         }
         app.initial_focus = Some(first);
 
@@ -916,7 +916,7 @@ impl cce_ui::engine::Application for State {
                                 app.password_box.text.clear();
                                 app.password_box.edit_buffer.clear();
                                 app.ui_context.set_focused(&mut app.password_box);
-                                app.password_box.focus();
+                                app.ui_context.focus_widget(&mut app.password_box);
                             }
                             AuthEvent::Info { msg, .. } => {
                                 app.status_lbl.text = msg;