Environment
- FileKit 0.15.0 (
filekit-dialogs-compose)
- Compose Multiplatform 1.11.1, Kotlin 2.4.10
- iOS 17, physical iPhone 15
Summary
Follow-up to #618 (whose two titled problems were fixed by #619 and released in 0.15.0). The remaining problem, previously only discussed in the comments there: the default camera presenter breaks touch handling app-wide when the picker is launched from a Compose Multiplatform 1.11+ Dialog/Popup.
Since CMP 1.11.0-alpha02, Compose dialogs and popups are hosted in a dedicated UIWindow placed above modal view controllers (JetBrains/compose-multiplatform-core#2270, CMP-9772). When no custom presenter is supplied, openCameraPicker presents the in-process fullscreen UIImagePickerController from topMostViewController() — i.e. in the app's main window, underneath the Compose dialog window.
What happens
Launch the camera from a composable hosted inside a Compose Dialog (in our case, a Navigation 3 dialog-scene entry), take a photo or cancel. After the picker dismissal, every subsequent tap shows the press indication (ripple) but never completes a click — the whole app becomes unresponsive to clicks until process restart. The gallery path is unaffected because PHPickerViewController is out-of-process and doesn't fight the dialog window.
The deliver-after-dismissal fix from #619 is necessary but not sufficient: the corruption comes from the presentation itself happening below the dialog window, not from the result ordering.
Confirmed workaround
Presenting the camera from a dedicated app-managed transparent UIWindow (made key above UIWindowLevelAlert, restored afterwards) via FileKitOpenCameraSettings(presenter = ...) fully resolves the interaction issue on device. This matches the JetBrains-recommended pattern for presenting native modals alongside CMP 1.11 dialog windows.
Proposal
When FileKitOpenCameraSettings.presenter is null, host the camera presentation in a FileKit-managed dedicated window instead of topMostViewController(): create a transparent UIWindow on the active scene, make it key and visible, present the picker from its root view controller, and on completion (result, cancel or failure) hide the window and restore the previous key window. Apps passing an explicit presenter keep the current behavior.
I have a working implementation of this and will open a PR shortly.
Environment
filekit-dialogs-compose)Summary
Follow-up to #618 (whose two titled problems were fixed by #619 and released in 0.15.0). The remaining problem, previously only discussed in the comments there: the default camera presenter breaks touch handling app-wide when the picker is launched from a Compose Multiplatform 1.11+
Dialog/Popup.Since CMP 1.11.0-alpha02, Compose dialogs and popups are hosted in a dedicated
UIWindowplaced above modal view controllers (JetBrains/compose-multiplatform-core#2270, CMP-9772). When no custom presenter is supplied,openCameraPickerpresents the in-process fullscreenUIImagePickerControllerfromtopMostViewController()— i.e. in the app's main window, underneath the Compose dialog window.What happens
Launch the camera from a composable hosted inside a Compose
Dialog(in our case, a Navigation 3 dialog-scene entry), take a photo or cancel. After the picker dismissal, every subsequent tap shows the press indication (ripple) but never completes a click — the whole app becomes unresponsive to clicks until process restart. The gallery path is unaffected becausePHPickerViewControlleris out-of-process and doesn't fight the dialog window.The deliver-after-dismissal fix from #619 is necessary but not sufficient: the corruption comes from the presentation itself happening below the dialog window, not from the result ordering.
Confirmed workaround
Presenting the camera from a dedicated app-managed transparent
UIWindow(made key aboveUIWindowLevelAlert, restored afterwards) viaFileKitOpenCameraSettings(presenter = ...)fully resolves the interaction issue on device. This matches the JetBrains-recommended pattern for presenting native modals alongside CMP 1.11 dialog windows.Proposal
When
FileKitOpenCameraSettings.presenterisnull, host the camera presentation in a FileKit-managed dedicated window instead oftopMostViewController(): create a transparentUIWindowon the active scene, make it key and visible, present the picker from its root view controller, and on completion (result, cancel or failure) hide the window and restore the previous key window. Apps passing an explicitpresenterkeep the current behavior.I have a working implementation of this and will open a PR shortly.