-
Notifications
You must be signed in to change notification settings - Fork 72
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
Provide a way to calculate ComposeScene preferredSize that is needed for Swing #884
Conversation
internal fun measureInConstraints(constraints: Constraints): IntSize { | ||
val oldConstraints = this.constraints | ||
try { | ||
// TODO: is it possible to measure without reassigning root constraints? |
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 couldn't find a better way to measure in given constraints...
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.
Also, as I understand it will break layout caches...
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.
But it should be called on parent relayout which should happen a lot
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 checked, and Swing doesn't call getPreferredSize on window resize in the initial panel size of LazyColumn with border layout
test. So, we are safe, and we only have an additional measure at startup?
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.
It depends on LayoutManager, in case of window resize everything should be fine, since PreferredSize is used only for initial size. But other LayoutManagers may call preferredSize any time :(
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeBridge.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeBridge.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeBridge.desktop.kt
Outdated
Show resolved
Hide resolved
val mainOwner = mainOwner ?: return IntSize.Zero | ||
mainOwner.measureAndLayout() | ||
return mainOwner.contentSize | ||
return contentSizeInConstraints(mainOwner.constraints) |
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.
We should cache this or turn it into a function. Code that previously assumed this was a quick operation will need to be rewritten. For example in SemanticsNode.isInScreenBounds()
:
return nodeBoundsInWindow.top >= 0 &&
nodeBoundsInWindow.left >= 0 &&
nodeBoundsInWindow.right <= composeView.contentSize.width &&
nodeBoundsInWindow.bottom <= composeView.contentSize.height
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.
Actually, are you sure this isn't breaking anything? Before, contentSize was the actual size of the scene. Now it's the result of some computation - why is it guaranteed to match the real size of the scene?
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.
Ah, I missed this particular case, indeed this one can break, thank you
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.
Mentioned code was recently changed by Ivan. Also, this API always was not that cheap, since it did measure and layout.
So, nothing is changed here, code still works the same
* Provides a way to measure Owner's content in given [constraints] | ||
* Draw/pointer and other callbacks won't be called here like in [measureAndLayout] functions | ||
*/ | ||
internal fun measureInConstraints(constraints: Constraints): IntSize { |
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.
Let's make it public and experimental. The policy for ComposeScene - if something is needed for one platform, it can be needed for other platforms, implemented by users.
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.
Also, let's add TODO for contentSize
:
TODO: investigate all internal usages, and deprecated it, if it isn't actually needed
I found one usage in ui-test
, and I am not sure that is correct usage of contentSize
there.
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.
It seems that this is not used anymore. Anyway, contentSize
api is not changed. It still returns the size in mainOwner constraints
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.
@igordmn contentSize
is public API, and calculateContentSize
is not a replacement, as it does something else entirely.
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeBridge.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeBridge.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
Outdated
Show resolved
Hide resolved
internal fun measureInConstraints(constraints: Constraints): IntSize { | ||
val oldConstraints = this.constraints | ||
try { | ||
// TODO: is it possible to measure without reassigning root constraints? |
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 checked, and Swing doesn't call getPreferredSize on window resize in the initial panel size of LazyColumn with border layout
test. So, we are safe, and we only have an additional measure at startup?
…aBasedOwner should be public not internal
69a182e
to
28345c5
Compare
val mainOwner = mainOwner ?: return IntSize.Zero | ||
mainOwner.measureAndLayout() | ||
return mainOwner.contentSize | ||
return contentSizeInConstraints(mainOwner.constraints) |
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.
Just note, that after my changes this code doesn't perform layout anymore
@igordmn @m-sasha Folks, sorry for the delay. I've answered on comments and pushed recent changes, please take a look. I've changed max constraints to infinity, so exception will be thrown if user doesn't provide maxSize for lazy layouts. It seems that |
compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
Outdated
Show resolved
Hide resolved
…Scene.skiko.kt Co-authored-by: Igor Demin <igordmn@users.noreply.github.com>
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.
LGTM. Let's wait for the second approval from @m-sasha
Don't know how important this is, but some of the javadocs exceed 100 columns. |
*/ | ||
// TODO: make stable and deprecate contentSize in 1.7 | ||
@ExperimentalComposeUiApi | ||
fun calculateContentSize(): IntSize { |
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.
Maybe call it preferredSize()
?
@@ -477,14 +477,36 @@ class ComposeScene internal constructor( | |||
/** | |||
* Returns the current content size | |||
*/ | |||
// TODO: make calculateContentSize stable in 1.7 and mark it as | |||
// @Deprecated("Use calculateContentSize() instead", replaceWith = ReplaceWith("calculateContentSize()")) |
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.
It seems to me that "current content size" and "preferred size" (in infinite constraints) are not at all the same thing. If so, why do we want to deprecate getting the current size?
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.
@igordmn told that by design contentSize was expected to provide size in infinity constraints, so there is no usecase to get current size and should be received in another way
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.
Yes, there wasn't an intention to provide current content size, and I am not aware of use cases where we need it. It was added to determine the size of the window/panel before its construction.
* Provides a way to measure Owner's content in given [constraints] | ||
* Draw/pointer and other callbacks won't be called here like in [measureAndLayout] functions | ||
*/ | ||
internal fun measureInConstraints(constraints: Constraints): IntSize { |
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.
@igordmn contentSize
is public API, and calculateContentSize
is not a replacement, as it does something else entirely.
compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ImageComposeScene.skikoMain.kt
Show resolved
Hide resolved
…for Swing (#884) --------- Co-authored-by: Igor Demin <igordmn@users.noreply.github.com>
Proposed Changes
Previous solution with preferred size didn't work well because constraints with maxSize taken from component.size were used, but component.size is not set (0 by default).
See issue: JetBrains/compose-multiplatform#3834
By Swing design preferred size should be calculated without incoming constraints. It is not possible in Compose, so I artificially set max constraints taking sum of displays dimensions here. Not the best solution, but I couldn't imagine better one..
Testing
Test: run ComposePanelTest.kt
Issues Fixed
Fixes: JetBrains/compose-multiplatform#3834