···175175 });
176176 }
177177178178+ // Enforced mode toggle — require password verification to turn off
179179+ // when a password has been set.
180180+ {
181181+ let win_em = self.window.clone_strong();
182182+ let cfg_arc_em = cfg_arc.clone();
183183+ self.window.on_enforced_mode_toggled(move |_checked| {
184184+ // The toggle was turned off with a password set.
185185+ // Open the password window for verification.
186186+ let hash = cfg_arc_em.lock().unwrap().enforced.password_hash.clone();
187187+ match PasswordSetupWindow::new() {
188188+ Ok(pw) => {
189189+ pw.set_verify_mode(true);
190190+ let pw_cancel = pw.clone_strong();
191191+ pw.on_cancel_clicked(move || {
192192+ pw_cancel.hide().unwrap_or_default();
193193+ });
194194+ let pw_submit = pw.clone_strong();
195195+ let hash_clone = hash.clone();
196196+ let win_disable = win_em.clone_strong();
197197+ pw.on_submit_clicked(move |password| {
198198+ if password::verify_password(password.as_str(), &hash_clone) {
199199+ win_disable.set_enforced_mode(false);
200200+ pw_submit.hide().unwrap_or_default();
201201+ } else {
202202+ pw_submit.set_error_text("Incorrect password.".into());
203203+ }
204204+ });
205205+ pw.show().unwrap_or_default();
206206+ }
207207+ Err(e) => log::warn!("Failed to create password window: {e}"),
208208+ }
209209+ });
210210+ }
211211+178212 self.window.show().unwrap_or_default();
179213 // Force the window to its intended size after the first show(). On
180214 // Linux/X11 the WM may not honour with_inner_size during initial window
+8-4
ui/password.slint
···66import "../assets/fonts/Nunito-Bold.ttf";
7788export component PasswordSetupWindow inherits Window {
99- title: "ioma — Set Emergency Password";
99+ title: root.verify-mode ? "ioma — Verify Password" : "ioma — Set Emergency Password";
1010 width: 420px;
1111 height: 260px;
1212 default-font-family: "Nunito";
13131414+ in property <bool> verify-mode: false;
1415 in-out property <string> error-text: "";
15161617 callback submit-clicked(string /* password */);
···2223 spacing: 12px;
23242425 Text {
2525- text: "Have someone you trust set an emergency unlock password.";
2626+ text: root.verify-mode
2727+ ? "Enter the emergency unlock password to turn off enforced mode."
2828+ : "Have someone you trust set an emergency unlock password.";
2629 wrap: word-wrap;
2730 color: #888888;
2831 font-size: Theme.font_body;
···3639 confirm-field := LineEdit {
3740 placeholder-text: "Confirm password";
3841 input-type: password;
4242+ visible: !root.verify-mode;
3943 }
40444145 if error-text != "" : Text {
···5357 clicked => { root.cancel-clicked(); }
5458 }
5559 Button {
5656- text: "Set Password";
6060+ text: root.verify-mode ? "Verify" : "Set Password";
5761 clicked => {
5862 if password-field.text == "" {
5963 root.error-text = "Password cannot be empty.";
6060- } else if password-field.text != confirm-field.text {
6464+ } else if !root.verify-mode && password-field.text != confirm-field.text {
6165 root.error-text = "Passwords do not match.";
6266 } else {
6367 root.error-text = "";