From e5756348c1b23be269ee4033628fdf8d4373b15f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 22:10:51 +0000 Subject: [PATCH 1/2] CI: also build the app for the iOS Simulator Catches changes that break the Xcode project (missing file references, compile errors in the app target), which swift test on VisuStructCore cannot see. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01Cp4EQgFQyGbM8MVLiWbJKQ --- .github/workflows/core-tests.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/core-tests.yml b/.github/workflows/core-tests.yml index b9263bb7..01bc2764 100644 --- a/.github/workflows/core-tests.yml +++ b/.github/workflows/core-tests.yml @@ -1,4 +1,4 @@ -name: VisuStructCore tests +name: CI on: push: @@ -17,3 +17,17 @@ jobs: run: swift --version - name: Build and test run: swift test + + app-build: + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + - name: Xcode version + run: xcodebuild -version + - name: Build app for iOS Simulator + run: | + xcodebuild build \ + -project VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct.xcodeproj \ + -scheme VisuStruct \ + -destination 'generic/platform=iOS Simulator' \ + CODE_SIGNING_ALLOWED=NO From 38d3caf01b137d7d5dad7d4e84c4371b19ac6055 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 06:42:50 +0000 Subject: [PATCH 2/2] Inspector: don't pop up the keyboard on open or selection - The line editor no longer becomes first responder just because it was created (its focus token started out "changed"), which opened the keyboard as soon as the inspector appeared, on iPhone too. - Auto-focus after selecting a line only on Mac and on iPad with a hardware keyboard (taken from cursor/ipad-inspector-focus-293e). Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01Cp4EQgFQyGbM8MVLiWbJKQ --- .../VisuStruct/ContentView.swift | 4 ++- .../VisuStruct/Editing/CodeLineEditor.swift | 2 ++ .../Supporting/DiagramEditorFocusTarget.swift | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift index 09309a11..5e1b2613 100644 --- a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift +++ b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/ContentView.swift @@ -2007,7 +2007,9 @@ struct ContentView: View { tabs[i].lineEditorText = el.textLines.joined(separator: "\n") tabsModel.tabs = tabs - if !isPhone, focusedField == nil, el.type != .forSchleife { + if DiagramInspectorAutoFocus.shouldFocusOnSelection, + focusedField == nil, + el.type != .forSchleife { focusedField = .textEditor editorFocusToken = UUID() } diff --git a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Editing/CodeLineEditor.swift b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Editing/CodeLineEditor.swift index ac8e0553..4eabb030 100644 --- a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Editing/CodeLineEditor.swift +++ b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Editing/CodeLineEditor.swift @@ -110,6 +110,8 @@ private struct CodeLineEditorUIKit: UIViewRepresentable { tv.commitOnReturn = commitOnReturn tv.onCommit = onCommit tv.delegate = context.coordinator + // Beim Erzeugen nicht fokussieren: Nur ein späterer Token-Wechsel holt die Tastatur. + context.coordinator.lastFocusToken = focusToken return tv } diff --git a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Supporting/DiagramEditorFocusTarget.swift b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Supporting/DiagramEditorFocusTarget.swift index 8091f424..46901894 100644 --- a/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Supporting/DiagramEditorFocusTarget.swift +++ b/VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Supporting/DiagramEditorFocusTarget.swift @@ -1,4 +1,10 @@ import SwiftUI +#if canImport(GameController) +import GameController +#endif +#if canImport(UIKit) +import UIKit +#endif /// Gemeinsame Fokus-Markierung für Diagrammtitel, Inspector-Felder und Zeileneditor. enum DiagramEditorFocusTarget: Hashable { @@ -8,3 +14,32 @@ enum DiagramEditorFocusTarget: Hashable { /// Zählschleife: drei Kopf-Felder (Start / Bedingung / Schritt). case forLoopPart(Int) } + +/// Ob der Inspector nach einer Zeilenauswahl automatisch den Cursor bekommt. +/// +/// Auf dem iPhone nie (zu wenig Platz). Auf dem Mac (Designed for iPad) immer. +/// Auf dem iPad nur, wenn eine Hardware-Tastatur verbunden ist — sonst würde die +/// Software-Tastatur das Diagramm verdecken. +enum DiagramInspectorAutoFocus { + static var shouldFocusOnSelection: Bool { + if ProcessInfo.processInfo.isiOSAppOnMac { + return true + } + #if canImport(UIKit) + switch UIDevice.current.userInterfaceIdiom { + case .phone: + return false + case .pad: + #if canImport(GameController) + return GCKeyboard.coalesced != nil + #else + return false + #endif + default: + return false + } + #else + return false + #endif + } +}