@@ -707,6 +707,9 @@ final class HardwareInput: ObservableObject {
707707 /// and ignores it. No API reports this, so the idiom is the detection.
708708 static var pointerLockAvailable : Bool { lockEnabled && UIDevice . current . userInterfaceIdiom != . phone }
709709
710+ /// iPhone: the mouse arrives only through AssistiveTouch.
711+ static var isPhone : Bool { UIDevice . current . userInterfaceIdiom == . phone }
712+
710713 /// The desktop session (explorer on a virtual desktop). Read per use: the
711714 /// app sets MADEIRA_DESKTOP for each launch.
712715 static var desktopMode : Bool {
@@ -1031,7 +1034,10 @@ final class HardwareInput: ObservableObject {
10311034 installTouchObserver ( )
10321035 let base = computeBaseFocus ( )
10331036 let keyboard = base && ! typingElsewhere ( ) && ! libraryTypingOwnsKeys
1034- let over = hoverSeen ? pointerOver : clickFocus . onGame
1037+ // iPhone: the AssistiveTouch pointer's hover ends whenever it stops
1038+ // against a screen edge, while GCMouse deltas keep coming; following
1039+ // hover there dropped mouse-look at every edge. Clicks decide instead.
1040+ let over = hoverSeen && ! Self . isPhone ? pointerOver : clickFocus . onGame
10351041 let mouse = base && ( ! Self . focusEnabled || pointerLocked || over || ! gameButtons . isEmpty )
10361042 baseFocused = base
10371043 updateButtonPolling ( active : Self . mouseRoutingEnabled && appActive && mouseConnected )
@@ -1113,7 +1119,7 @@ final class HardwareInput: ObservableObject {
11131119 guard Self . enabled , let game = MetalBackedView . keyboardTarget else { return }
11141120 let onGame = t . view . map { $0 . isDescendant ( of : game ) } ?? false
11151121 clickFocus . touchBegan ( onGame : onGame , at : CACurrentMediaTime ( ) )
1116- if ! hoverSeen { refreshFocus ( onGame ? " tap on the game view " : " tap elsewhere " ) }
1122+ if ! hoverSeen || Self . isPhone { refreshFocus ( onGame ? " tap on the game view " : " tap elsewhere " ) }
11171123 }
11181124
11191125 // MARK: - keyboard
@@ -2659,8 +2665,7 @@ struct HardwareInputSettings: View {
26592665 /// device is routed through AssistiveTouch.
26602666 private var hint : some View {
26612667 HStack ( alignment : . top , spacing : 8 ) {
2662- Text ( " Mouse detected. iPhone needs AssistiveTouch: "
2663- + " Settings > Accessibility > Touch > AssistiveTouch > On, then Devices " )
2668+ Text ( " Using a mouse? Turn on AssistiveTouch (Settings > Accessibility > Touch), then reopen Madeira. " )
26642669 . font ( . system ( size : 12 ) )
26652670 . foregroundColor ( . secondary )
26662671 . fixedSize ( horizontal : false , vertical : true )
0 commit comments