-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Use of Compose over (on top of) Swing/AWT Heavyweight component #1521
Use of Compose over (on top of) Swing/AWT Heavyweight component #1521
Comments
In addition to this, when we try to make overlays on top of Heavyweight components on Mac we can make it transparent but on Windows, it always gives you the White background. |
Okay. I went deeper. Switched to 1.0.0. The same problem with no pointer event responses.
|
compose-overlay-bug.2021-12-14.14.06.25.movAfter some testing, I found that pointer-events are processed by overlay, but only when you trigger recomposition. |
screen-capture.2021-12-14.14.40.15.movI just commented Swing panel with the Heavyweight component and got the same behavior. So the problem with my temporary solution of using overlays over heavyweight components is related to the use of ComposePanel inside SwingPanel. In this video, you can see that we can't interact with ComposePanel content inside SwingPanel. @akurasov, please pay attention to these details. Maybe you have some solution or workaround for this case. |
This single problem is one of the most annoying things about Compose for me. Drawing on top as a default/only behavior is kind of crappy and feels like a half implementation. EDIT: I feel as though I should say Compose is great, this is a huge annoyance, but It really is great work. |
Updated https://github.com/JetBrains/compose-jb/tree/master/tutorials/Swing_Integration to cover this case |
@akurasov Great! Thanks! Will try it with the heavyweight 3d-Map Swing component soon. Please tell from which version of Compose the documented overlaying approach is available? |
They didn't fix the issue of rendering compose over a SwingPanel. They just made a semi informative page about it and said literally "or stop using the SwingPanel and still try to implement the missing component, thereby contributing to the development of technology and making life easier for other developers.". hahaha such a smug response that didnt help the issue AT ALL, basically just said not our problem when IT IS. You basically automatically lose the ability to Scaffold as well as many other typical features when using Swing in Compose if the SwingPanel happens to be your main component. 👎 Might as well not support Swing at all if you are going to have a broken implementation. |
@zeruth They released a stable version of compose for desktop(and for web using dom) and they are now working hard on bringing this to ios and web(using canvas). They also have to reimplement base compose(by google for android) to support the latest changes. I have used compose with I think this is not a rude comment from Jetbrains, but pushing a fix for this into the future, as everybody is more excited and waits for multiplatform support. |
I think this issue should not be closed. Another use case is to overlay controls on the current experimental video player. |
Any update on this? Since there is no official WebView on the desktop. We can now only one choice: JavaFx WebView and can only use it on SwingPanel? |
I use another SwingPanel in PoupUp, and now it can pop over the SwingPanel with JavaFx WebView. But seems that the theme color is wrong. There is a background color with SwingPanel, how can we make it |
JetBrains/compose-multiplatform-core#915
There is no such way due to heavyweight/lightweight AWT components mixing limitations |
@MatkovIvan @igordmn The version 1.6.0-alpha01 is the last version where I controlled z-order mixing Heavyweight component with SwingPanels+Compose overlays. The trick was to show the SwingPanels in the Box element AFTER (some fixed milliseconds period) Heavyweight component is rendered. It was good because I could optionally show/hide the overlaying SwingPanels and had flexible UI. But starting 1.6.0-beta01 I lost this possibility. The only way I can show SwingPanel overlays over the 3D-map after hiding it is to hide/show the actual Heavyweight compoent(3D-map). It seems like the order of rendering changed or something. In cases described above I don't use compose.interop.blending and compose.swing.render.on.graphics flags. Because in some cases and another OS's it becomes more complicated. I tested with flags - there'is no helpful impact for Heavyweight components case. Additional comments: On Windows: 1) Heavyweight component is not rendered (only parent's JPanel background visible) if blending = true. 2) Generally can't hide/show SwingPanel overlays - it's possible only by hiding/showing Heavyweight component. On Ubuntu: 1) Same as on Windows - can't hide/show SwingPanel overlays As a result, the situation with current issue became better only if we talk about regular Lightweight Swing components. But with Heavyweight component it became worse. You can find the project with sample application where you can play with elements placed side-by-side and over the Heavyweight WorldWind 3D-map component. There are 2 branches: compose-1.5.12 where I can hide/show overlays and compose-1.6.0-rc03 where there's no such possibility. |
Hi @yaroslavkulinich, thanks for the update!
It's essentially just 1.5.x + WASM, so it didn't contain any code changes for 1.6.x
That's tricky. On macOS I managed to overlap
Yeah, it's unrelated, known one - there are some cases where
It's a known limitation on windows - rendering by GPU just wipes everything that was drawn before via the same method. It's even reproducible via two overlapping As you can see, there are a lot of OS specifics and hacks for this. The issue with The only fixable thing from your post is missing re-draws of But aside from this long list of corner cases, it's totally not clear why you need to rely on |
@MatkovIvan thank you for the answer. Thanks for pointing me to I have tested Ubuntu:Expectations: We do not expect to see raw Screencast.from.26-02-24.19_26_46.webmWindows:2 tests were made: with and without windows-no-flags.movWith blending: Surprisingly good results. Raw windows-blending.movMacOS:2 tests with and without mac-no-flags.movWith blending: Same result as without blending but non-clickable row mac-blending.movSummary for 1.6.* migration:
|
Another hack needed 😅 : JetBrains/compose-multiplatform-core#915 (comment) As for order of adding/rendering - I already see how to impllement interop order not by adding but by render order, I'll defenitely recheck your case during the fix (no ETA though). An issue for tracking it #2926 |
Actually restoring the order based on adding like it was before is easy. Made it in JetBrains/compose-multiplatform-core#1143 |
## Proposed Changes - Inserting interop views in the reverse order to get direct order rendering. It's a hotfix to restore [1.5.x behaviour](https://github.com/JetBrains/compose-multiplatform-core/blob/v1.5.12/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt#L77), the right order should rely on _rendering_, not adding order in the future. ## Testing Test: run repruduction from the issue or "nasa" demo from this commit MatkovIvan@6a3663d (not in the main repo because it requires manually added jar) ## Issues Fixed Fixes JetBrains/compose-multiplatform#1521 (comment)
## 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 - Inserting interop views in the reverse order to get direct order rendering. It's a hotfix to restore [1.5.x behaviour](https://github.com/JetBrains/compose-multiplatform-core/blob/v1.5.12/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt#L77), the right order should rely on _rendering_, not adding order in the future. ## Testing Test: run repruduction from the issue or "nasa" demo from this commit MatkovIvan@6a3663d (not in the main repo because it requires manually added jar) ## Issues Fixed Fixes JetBrains/compose-multiplatform#1521 (comment)
@yaroslavkulinich Let me know if you still have issues with it |
@MatkovIvan Great news! Thank you! |
I've added a few force invalidations to cover some cases, but I know that there are more. Not sure what case exactly you mean. It's better to track it as a separate issue with simple reproduction. |
@MatkovIvan thanks again for your insights. I need your opinion about about new theoretical approach of better overlaying over Heavyweight components. The WorldWindowGLJPanel, you have suggested, with blending feature perfectly deals with overlaying, rounded corners, and transparency. However, WorldWindowGLJPanel performance is noticeably poorer compared to the heavyweight WorldWindowGLCanvas, even during simple map dragging tasks, which prevents us from replacing the GLCanvas entirely. So we fallback to old overlaying approach. In the recent 1.6.* versions of Compose Multiplatform, I noticed the introduction of a WINDOW layer, mainly for handling dialogs and popups. I'm curious if this feature could be used to improve our overlaying of heavyweight components. I'm thinking of using popups (or similar elements) fixed over the main UI containing the heavyweight component. For this to work, we would need:
Could the WINDOW layer potentially solve our problem with proper overlaying? Your thoughts or any alternative suggestions would be invaluable. ***Additional aspect and reason for searching new overlaying approach for us: Thank you |
It will work only for out-of-bounds interactions (currently
Works with some delays caused by AWT
Just works
Please note that it will be real separate OS windows, with some side effects like participating in OS window switcher. So, I'm not sure that this is what you want. But it will solve sorting issues for sure. Also, I doubt that it will require less RAM |
Problem
Very often in modern user interfaces, you need to place some UI elements over the main component of the application, like 'locate to my position' button over the Map component (in GoogleMaps), or 'play/pause' button over VideoPlayer. It's common practice.
But there is NO normal way of using jb-compose components over Swing/AWT Heavyweight components like 3D Maps, video players, etc... When you try to use the normal method of layering (Box composable) with Heavyweight Swing/AWT components, you will never see your Compose overlay content, because the Heavyweight Swing/AWT component always redraws your Compose layer.
Temporary solution
After many failed attempts I found the way of using Compose over Heavyweight Swing/AWT component (in my case it's 3DMap - WoldWindGLCanvas component). The trick is to use Swing/Compose switching for hierarchy root and then use Box component overlaying with 1) Heavyweight Swing/AWT component wrapped in SwingPanel and 2) Compose content wrapped into SwingPanel and switched back to ComposePanel (Swing/Compose switching).
So the hierarchy looks like this:
You can find the working sample in this repository in the master branch. And you can watch how it works on this YouTube video. I used beta5 version of jb-compose.
But starting from version 1.0.0-beta6-dev455 of jb-compose the temporary solution is not working.
You see the overlay, but you can't do any actions with it (all mouse events not recognized).
You can find described NOT working behavior in this repo in broken branch. And watch how it looks like on this YouTube video. I used the rc3 version of jb-compose.
Request
Dear jb-compose developers. @igordmn .
Please add the ability to use Compose components over Heavyweight Swing/AWT components in the normal way with Box component or similar. It would be a huge step! It's a missing piece for many devs.
If there is no possibility to make it the normal way, please, return the ability to use Compose over Heavyweight components like described in my temporary solution. Because after 1.0.0-beta6-dev455 it doesn't work. And in my personal case, I need to stay on beta5 or use ugly UI techniques without overlaying.
Thank you. You do a great job!
The text was updated successfully, but these errors were encountered: