Turn Always On Display into a timed auto-lock setting - #338
Conversation
|
It looks like we could avoid some of the tracker work when this is in an off state which is currently creating some additional MainActor load and gesture recognizers. ie getting to a point that the overhead is only the conditional check and nothing more. |
|
Pushed three commits on top. Interaction tracking is no longer installed at launch. The two lifecycle observers ( Software-keyboard, IME and dictation text reaches |
|
Thanks. Looks good to me now. |
Always On Display was all-or-nothing: on meant the idle timer stayed disabled for as
long as rootshell was in front, so letting the screen lock again meant remembering to
switch it back off. It is now a duration on one slider — Off, 1 to 30 minutes, or
Always — under Settings -> Appearance -> Window -> Display.
A timed value behaves like a custom auto-lock interval rather than a countdown that
runs out. The idle timer is disabled and a one-shot timer runs for the chosen span,
and every interaction restarts it: walk away from a streaming log and the screen locks
that many minutes after the last touch or key press, keep working and it never locks.
The window is never spent, so the next interaction arms a fresh one. Always is the old
behavior, Off hands the screen back to the system's auto-lock schedule, and the row's
caption states what the selected value does.
Interaction sources
Four, because no single one covers everything:
with
cancelsTouchesInViewand both touch delays off, so it cannot claim a gesture,delay delivery or cancel touches below it. Attached as windows become visible, which
also picks up the keyboard-hosting windows absent from
UIWindowScene.windows.TerminalView.pressesBeganfor hardware typing: key events go to the responderchain, never to
touchesBegan.UITextFieldandUITextViewtext-change notifications, for typing in QuickConnect, search fields and dialogs.
TerminalViewis out ofthe responder chain.
Rearming is coalesced to once a second. Two paths still do not restart the window: a
UIKeyCommandhandled by a responder that is neither the terminal nor the fallback,and dictation into the terminal.
Lifecycle
The timer is scheduled in the common run-loop mode, so a long scroll or selection drag
cannot postpone the deadline, and it fires synchronously. Going through a
Taskwouldlet a rearm land between the fire and the callback, and the stale callback would then
tear down the newer hold: Always selected while the screen locks anyway. A
timer-identity check covers that shape regardless.
Entering the background drops the assertion and the pending timer while keeping the
setting, and arming is refused while the app is backgrounded, since
ProtectedDataGuardruns during background launches and unlocks by design. UIKit alsoasks for
isIdleTimerDisabledto be reset once it is no longer needed.Migration and scope
A persisted
alwaysOnDisplayEnabled = truebecomes Always on first launch and the oldkey is removed. The migration runs only where protected data is available, so a locked
launch cannot mistake an unreadable
UserDefaultsfor "never configured" and overwritea real setting.
iOS and iPadOS only, as before. Mac Catalyst exposes
isIdleTimerDisabledbut it doesnothing for Mac display sleep, which power assertions govern, and visionOS has no
auto-lock idle timer; the
#elsebranch keeps the App body and the key-input pathcompiling on both.