New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proper clipping of SwingPanel
interop
#915
Conversation
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/SwingPanel.desktop.kt
Outdated
Show resolved
Hide resolved
56232e4
to
2424eee
Compare
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/SwingPanel.desktop.kt
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
# Conflicts: # compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/SwingPanel.desktop.kt
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/WindowComposeBridge.desktop.kt
Show resolved
Hide resolved
# Conflicts: # gradle/libs.versions.toml
super.remove(component) | ||
} | ||
|
||
private fun addToLayer(component: Component, layer: Int) { | ||
if (renderApi == GraphicsApi.METAL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Alexander, we use so many hacks for transparency
that we can easily break the behavior in the future.
I tested main variations on Windows/macOs - it works, but to be safe, let's write java.awt.Robot
screenshot tests for different OS'es, as we wrote them in Skiko (look at SkiaLayerTest
).
Disable it for now, as we should run them only on CI. I will configure it later myself.
We can merge the PR now to receive feedback earlier, but If we agree that we can/should write the tests, we should write them before the 1.6.0 release (please, create a task).
Even if Robot tests can be flaky and it is hard to run them locally, they are very useful.
To write tests for transparency, we can place an opaque window behind a transparent window.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/SwingPanel.desktop.kt
Show resolved
Hide resolved
Hi @MatkovIvan, I've tried the newest alpha on Linux Desktop but Swing panels still seem to occlude all composables. Could you confirm that this PR affects MacOS and Windows, but not Linux? If so it would be worth opening another issue to keep track of that part of the problem. |
This PR is not included in the 1.6.0-alpha01.
Yes, it's explicitly mentioned in the description:
Also, please note that it's under the feature flag and does NOT enabled by default even on Windows/macOS. Mainly because it's not supported consistently across all platforms.
JetBrains/compose-multiplatform#2926 is not closed yet |
Sorry, I mean I tried the latest dev, 1.6.0-dev1340 (including using the feature flag). I was asking because I don't know the whole context of this PR. Closing the related issues suggests that the problem is addressed on all platforms. So I wasn't sure where Linux is standing. But if that's tracked via #2926 then all is well. Thanks for your response. |
Well, all of the mentioned issues were closed as duplicates, but not by this PR. I've updated the PR description to highlight that the solution only partially addresses it. Sorry for confusion |
This is a big improvement for Swing / JavaFX interop, much better experience mixing components. However as far as I can see it is not possible to interact with the Compose components that are "on top" of the SwingPanel? I tried the simple example in this PR and I could not click on the OK button in the SnackBar. Is it possible to make this work? |
@ahamilt thanks for feedback!
Let's track this as a separate issue. Lines 384 to 388 in 3f9010f
So, all input events go to interop view, so Compose just didn't aware of them. I'll try to find a workaround for this |
@ahamilt I've fixed handling mouse events above |
## Proposed Changes - Add one more mouse listener for a case when AWT dispatches all events only to interop view ## Testing Test: try to click on the button above `SwingPanel` on macOS ## Issues Fixed Fixes #915 (comment)
## Proposed Changes - Add one more mouse listener for a case when AWT dispatches all events only to interop view ## Testing Test: try to click on the button above `SwingPanel` on macOS ## Issues Fixed Fixes #915 (comment)
Hi @MatkovIvan, Thanks for the quick turnaround! I was able to test the Snackbar example with #1119 and could see interacting with the button on the Snackbar is now working on macos. Unfortunately it doesn't work for our use case. We are trying to show a JavaFX map component, and support showing a BottomSheet over the map. As far as I can tell, even a basic JavaFX Pane inside a SwingPanel is not allowing interaction with a Compose component on top, even with #1119. I had difficulty testing #915 on Windows (which is the main platform we are interested in), I was getting this message when launching the app, and the Swing component was always on top:
I assume #915 needs working DirectX12. I'll try on another Windows machine when I get access to one. |
@ahamilt Thanks for sharing your use case. Currently, I can only suggest manually redispatching AWT events to compose (see example below). In future, we'll try to find a way to catch such events out of the box.
|
Mixing Compose and JavaFX is even more complicated than just Compose and Swing. See JetBrains/compose-multiplatform#4094 |
Thanks again @MatkovIvan, our use case works well with the InteropPanel example you provided, we can show and interact with a Compose dialog over our JavaFX map view. Health warnings understood. @m-sasha we are working the other way around, our app is a Compose Multiplatform app with a Compose UI, but we need to use one JavaFX map component, embedded using a SwingPanel and working well. Where we were having problems was with showing a Compose dialog/bottom sheet over the map, which is now working well with this PR and the InteropPanel example. |
## Proposed Changes Currently on both Desktop and iOS interop views are added to the view hierarchy in order to add nodes to Compose. It works only if all intersecting interop views were added at the same time (frame). So it's basically last-added - above-displayed. This PR changes this behavior in a way that it will respect the order inside Compose like regular compose elements. **It does NOT make any changes in the ability to display Compose content above interop view on Desktop**, this fix was made in #915 Main changes: - Unify a way to work with interop on Desktop (`SwingPanel`) and iOS (`UIKitView`) - `LocalInteropContainer` -> `LocalUIKitInteropContainer` on iOS - `LocalLayerContainer` -> `LocalSwingInteropContainer` on Desktop - Reduce copy-pasting by moving `OverlayLayout` and `EmptyLayout` - Remove overriding `add` method on `ComposePanel` and `ComposeWindowPanel` - it was required to redirect interop, but now it's not required and it's better to avoid changing default AWT hierarchy behaviour - Do not use `JLayeredPane`'s layers anymore - it brings a lot of transparency issues (faced with it on Windows too after unrelated change). Sorting via indexes is used instead - Add `InteropOrder` page to mpp demo ### How it works It utilizes `TraversableNode` to traverse the tree in the right order and calculate the index based on interop views count that placed before the current node in the hierarchy. All interop nodes are marked via `Modifier.trackSwingInterop`/`Modifier.trackUIKitInterop` modifier to filter them from the `LayoutNode`s tree. ## Testing Test: run reproducers from the issues or look at "InteropOrder" page in mpp demo Desktop | iOS --- | --- <img width="400" alt="Screenshot 2024-02-27 at 12 51 06" src="https://github.com/JetBrains/compose-multiplatform-core/assets/1836384/534cbdc8-9671-4ab7-bd6d-b577d2004d1b"> | <img width="300" alt="Simulator Screenshot - iPhone 15 Pro - 2024-02-27 at 12 49 50" src="https://github.com/JetBrains/compose-multiplatform-core/assets/1836384/ac7553db-c2a4-4c4a-a270-5d6dbf82fb79"> ## Issues Fixed ### Desktop Fixes JetBrains/compose-multiplatform#2926 Fixes JetBrains/compose-multiplatform#1521 (comment) ### iOS Fixes JetBrains/compose-multiplatform#4004 Fixes JetBrains/compose-multiplatform#3848
Proposed Changes
Known limitations
compose.swing.render.on.graphics
)Testing
The new behavior is under a feature flag, so you can test it by setting system property:
Clipping
Overlapping
Issues Fixed
Fixes JetBrains/compose-multiplatform#1521
Fixes (partially) JetBrains/compose-multiplatform#3823
Fixes (partially) JetBrains/compose-multiplatform#3739
Fixes (partially) JetBrains/compose-multiplatform#3353
Fixes (partially) JetBrains/compose-multiplatform#3474