Skip to content
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
45775b4
[WIP] Proposal for reworking WindowState and related types
m-sasha Mar 6, 2026
99ed5b1
Add `onBoundsChanged` argument to `Window`, `singleWindowApplication`…
m-sasha Mar 9, 2026
0cfc7b3
Use WindowState.bounds as initial bounds if it's not null
m-sasha Mar 9, 2026
bbf2923
Prevent setting WindowState.bounds to null
m-sasha Mar 9, 2026
1f592f9
Replace bounds setter with a function
m-sasha Mar 9, 2026
c24aa00
Fix v2.WindowState Saver
m-sasha Mar 9, 2026
739bb7a
Change new WindowState.bounds to be DpRect
m-sasha Mar 10, 2026
bacd18b
Enhance initial window positioning; allow selecting the screen.
m-sasha Mar 11, 2026
4dbdb6e
Added `fun WindowState.awtBounds()`
m-sasha Mar 11, 2026
73164bf
Change `Window.onBoundsChanged` to receive `DpRect`
m-sasha Mar 13, 2026
0be5208
Replace `WindowState._bounds` with `var bounds internal set`
m-sasha Mar 13, 2026
9b333cc
Make `intrinsicWindowSize` computation lazy
m-sasha Mar 16, 2026
1f99636
Separate actual and requested state in `WindowState`, and remove `onB…
m-sasha Mar 16, 2026
054b597
Set initial parameters of WindowState via requests.
m-sasha Mar 17, 2026
961ec7a
Minor documentation improvements
m-sasha Mar 17, 2026
035af0f
Add WindowState.requireProperty accessors
m-sasha Mar 18, 2026
c3e5e73
Fix initialization of placement and bounds
m-sasha Mar 18, 2026
b8c3c00
Fix packing the window correctly before displaying it
m-sasha Mar 18, 2026
74145f5
Add new window tests
m-sasha Mar 18, 2026
dd8d912
Initialize and nullify WindowState properties together
m-sasha Mar 23, 2026
f362649
Rename WindowState setters to `requestXXX`
m-sasha Mar 27, 2026
fac88db
Set window state as non-visible when Window composable is disposed
m-sasha Mar 28, 2026
6fe808c
Correctly restore state when re-showing a window from an existing state
m-sasha Mar 28, 2026
a0babea
Validate screen from current state before using it
m-sasha Mar 28, 2026
7c22eaf
Add test for saving/restoring WindowState
m-sasha Mar 29, 2026
b573a33
Store screen id, not Screen object in WindowState
m-sasha Mar 29, 2026
1e526a9
Added a convenient WindowState.requestBounds function that takes a la…
m-sasha Mar 29, 2026
2eea0a9
When saving `WindowState` before it has been shown, save and restore …
m-sasha Mar 29, 2026
b2d7dbd
Provide access to `Screen` instances in `WindowScreenProviderScope`
m-sasha Mar 29, 2026
beb808b
Add KDoc about not keeping long-term references to `Screen` objects.
m-sasha Mar 29, 2026
f4b3c67
Replace WindowState.isVisible with isInitialized and make all propert…
m-sasha Mar 30, 2026
63428e6
Change WindowState.awtBounds to a property
m-sasha Mar 30, 2026
acf1360
Remove @Deprecated from old WindowPosition API
m-sasha Mar 30, 2026
2f0b5db
Added documentation and split the code into more appropriate files.
m-sasha Mar 30, 2026
4a8e882
Rename v2 WindowTest to WindowTestV2 and fix it to actually use v2 AP…
m-sasha Apr 1, 2026
ca82deb
Added @Immutable annotation to `DpInsets`
m-sasha Apr 1, 2026
a0022a0
Add `WindowSizeLimits` and corresponding `Window` parameter
m-sasha Apr 1, 2026
dcba2f2
Add more @ExperimentalComposeUiApi where appropriate
m-sasha Apr 2, 2026
e00fcaf
Add `offset` parameter in `WindowBoundsProvider.AlignedToScreen`
m-sasha Apr 7, 2026
f2e86dd
Add the ability to size windows according to the real intrinsic conte…
m-sasha Apr 8, 2026
60f1c2f
Address PR feedback
m-sasha Apr 8, 2026
7be9fdc
Add `MinWidthMatchingHeight` and `MinHeightMatchingWidth` window size…
m-sasha Apr 9, 2026
580021b
Expose `MeasurableRootContent` in `WindowGeometryProviderScope`
m-sasha Apr 9, 2026
578ad64
Make sure to make the window displayable before MeasurableRootContent…
m-sasha Apr 9, 2026
c937810
Unconditionally make the window displayable before creating WindowGeo…
m-sasha Apr 9, 2026
7eb63f7
Correctly mark `ComposeWindow.measurableContent` as @ExperimentalComp…
m-sasha Apr 9, 2026
18c0843
Removed `MeasuredRootContent` in favor of `Measured`.
m-sasha Apr 9, 2026
8fab237
Added unit tests for the new WindowSizeProviders
m-sasha Apr 9, 2026
9a5475d
Add more flexible `WindowSizeProvider`s
m-sasha Apr 14, 2026
79ab162
Return simple versions of intrinsic WindowSizeProviders
m-sasha Apr 14, 2026
4547ce3
Minor improvement in tests
m-sasha Apr 14, 2026
a91887e
Make sure to round up the requested window size before passing it to …
m-sasha Apr 14, 2026
56feeb9
Add `sizeLimits` argument to `singleWindowApplication`.
m-sasha Apr 16, 2026
f142c94
Add link to ticket for supporting window focus management
m-sasha Apr 17, 2026
795fa9c
Minor refactoring of WindowSizeProviders
m-sasha Apr 17, 2026
55412c6
Fix flakiness of v2 window test of `window does not flash background …
m-sasha Apr 17, 2026
d12833e
Initial implementation of new Dialog State API
m-sasha Apr 20, 2026
979af57
Add `Current` window position/size providers to allow setting the siz…
m-sasha Apr 21, 2026
651c35c
Make `AlignedToScreen` a `WindowPositionProvider` rather than a `Wind…
m-sasha Apr 21, 2026
d4ece2a
Remove unused imports
m-sasha Apr 21, 2026
e538784
Hide constructor which creates uninitialized WindowState and DialogSt…
m-sasha Apr 21, 2026
22491bb
Add WindowV2StateTest
m-sasha Apr 21, 2026
5ae2d40
Added a note about being moved to a package below for all "v2" types …
m-sasha Apr 24, 2026
7b2bda6
Allow positioning dialogs relative to the parent window
m-sasha Apr 27, 2026
86ee8bf
Added size limits to dialogs too
m-sasha Apr 30, 2026
f15f296
Add initial DialogWindow state tests
m-sasha Apr 30, 2026
412214c
Change default modality of dialogs with no parent to `ApplicationModal`.
m-sasha Apr 30, 2026
2039c9d
Allow setting the initial screen for dialogs.
m-sasha Apr 30, 2026
c1034aa
Allow moving the window/dialog to a different screen after showing it
m-sasha Apr 30, 2026
5acbe24
Split window size limits into min and max parameters
m-sasha May 1, 2026
fc33341
Add v2 DialogWindow state tests
m-sasha May 1, 2026
7563ed2
Removed extraneous newlines
m-sasha May 2, 2026
91a3569
Addressed PR feedback
m-sasha May 5, 2026
5ef92d6
Update API files
m-sasha May 5, 2026
c0b6f48
Fixed bounds requests overwriting each other in the channel.
m-sasha May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compose/ui/ui-unit/api/ui-unit.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ final const val androidx.compose.ui.unit/MaxDimensionsAndFocusMask // androidx.c
final fun <get-MaxDimensionsAndFocusMask>(): kotlin/Long // androidx.compose.ui.unit/MaxDimensionsAndFocusMask.<get-MaxDimensionsAndFocusMask>|<get-MaxDimensionsAndFocusMask>(){}[0]

final val androidx.compose.ui.unit/androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop // androidx.compose.ui.unit/androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop|#static{}androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop[0]
final val androidx.compose.ui.unit/androidx_compose_ui_unit_DpInsets$stableprop // androidx.compose.ui.unit/androidx_compose_ui_unit_DpInsets$stableprop|#static{}androidx_compose_ui_unit_DpInsets$stableprop[0]
final val androidx.compose.ui.unit/androidx_compose_ui_unit_DpRect$stableprop // androidx.compose.ui.unit/androidx_compose_ui_unit_DpRect$stableprop|#static{}androidx_compose_ui_unit_DpRect$stableprop[0]
final val androidx.compose.ui.unit/androidx_compose_ui_unit_IntRect$stableprop // androidx.compose.ui.unit/androidx_compose_ui_unit_IntRect$stableprop|#static{}androidx_compose_ui_unit_IntRect$stableprop[0]
final val androidx.compose.ui.unit/center // androidx.compose.ui.unit/center|@androidx.compose.ui.unit.DpSize{}center[0]
Expand Down Expand Up @@ -467,6 +468,7 @@ final fun androidx.compose.ui.unit/IntRect(androidx.compose.ui.unit/IntOffset, k
final fun androidx.compose.ui.unit/TextUnit(kotlin/Float, androidx.compose.ui.unit/TextUnitType): androidx.compose.ui.unit/TextUnit // androidx.compose.ui.unit/TextUnit|TextUnit(kotlin.Float;androidx.compose.ui.unit.TextUnitType){}[0]
final fun androidx.compose.ui.unit/Velocity(kotlin/Float, kotlin/Float): androidx.compose.ui.unit/Velocity // androidx.compose.ui.unit/Velocity|Velocity(kotlin.Float;kotlin.Float){}[0]
final fun androidx.compose.ui.unit/androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop_getter(): kotlin/Int // androidx.compose.ui.unit/androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop_getter|androidx_compose_ui_unit_ComposeUiUnitFlags$stableprop_getter(){}[0]
final fun androidx.compose.ui.unit/androidx_compose_ui_unit_DpInsets$stableprop_getter(): kotlin/Int // androidx.compose.ui.unit/androidx_compose_ui_unit_DpInsets$stableprop_getter|androidx_compose_ui_unit_DpInsets$stableprop_getter(){}[0]
final fun androidx.compose.ui.unit/androidx_compose_ui_unit_DpRect$stableprop_getter(): kotlin/Int // androidx.compose.ui.unit/androidx_compose_ui_unit_DpRect$stableprop_getter|androidx_compose_ui_unit_DpRect$stableprop_getter(){}[0]
final fun androidx.compose.ui.unit/androidx_compose_ui_unit_IntRect$stableprop_getter(): kotlin/Int // androidx.compose.ui.unit/androidx_compose_ui_unit_IntRect$stableprop_getter|androidx_compose_ui_unit_IntRect$stableprop_getter(){}[0]
final fun androidx.compose.ui.unit/checkArithmetic(androidx.compose.ui.unit/TextUnit) // androidx.compose.ui.unit/checkArithmetic|checkArithmetic(androidx.compose.ui.unit.TextUnit){}[0]
Expand Down

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DpInsets.skiko.kt

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's just data structure (not window-insets or so), probably it should be part of ui-unit module

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.ui.unit

import androidx.compose.runtime.Immutable
import androidx.compose.ui.ExperimentalComposeUiApi


/**
* Represents a set of insets in [Dp] units.
*/
@ExperimentalComposeUiApi
@Immutable
class DpInsets(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must not introduce such API one more time as desktop only. Please reuse the existing one

cc Vendula Švastalová (@svastven)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one in ios is internal; this one is public (but experimental).

We could change ios to use this one, but I wouldn't say it's a "must". There are plenty of places where we have internal copies of code because we don't want to create a dependency.

Up to the ios team...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's public and in skikoMain

/**
* This class represents platform insets.
*/
@InternalComposeUiApi
interface PlatformInsets {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@InternalComposeUiApi is about using only inside our library. If you need really user-faced API - it should be existing foundation/commonMain one

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlatformInsets is not the same as DpInsets.
What I thought you meant was this:

internal data class DpInsets(val left: Dp, val top: Dp, val right: Dp, val bottom: Dp)

@svastven Vendula Švastalová (svastven) Apr 8, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DpInsets is currently internal to iosMain as convenience so that we don’t introduce an API that isn’t used anywhere else unless it’s actually needed.

Personally, I’m fine with having DpInsets as a dp-based convenience type alongside PlatformInsets, which is px-based and also internal API. I don’t see this as duplication, as long as DpInsets remains internal. If moved to skikoMain, then we can remove the one in iosMain.

If this new API is being used for window/platform insets, then I think we should use the existing WindowInsets / PlatformInsets APIs.

If we decide to introduce a public dp-based insets API, then I think it should live in common, at the same level as something like DpRect. But I am not sure this is the case.

As for PlatformInsets it is a px-based API. Its purpose is to represent the platform backing to WindowInsets, which are also px-based. The developer can then choose the PlatformInsets behavior they need for their particular case, for example dynamic getters, packed values, introduce new ones, etc.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved DpInsets to skikoMain. Not sure what else should be done here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
* A representation of window insets that tracks access to enable recomposition, relayout, and
* redrawing when values change. These values should not be read during composition to avoid doing
* composition for every frame of an animation. Use methods like [Modifier.windowInsetsPadding],
* [Modifier.systemBarsPadding], and [Modifier.windowInsetsTopHeight] for Modifiers that will not
* cause recomposition when values change.
*
* Use the [WindowInsets.Companion] extensions to retrieve [WindowInsets] for the current window.
*/
@Stable
interface WindowInsets {

/**
* Contains rulers used for window insets. The [current] values are available as well as values when
* the insets are [fully visible][maximum].
*
* Other animation properties can be retrieved with [getAnimation].
*/
sealed interface WindowInsetsRulers {

WindowInsets is related to DpInsets mostly just by name, and WindowRulers is even less related.

These are types for a concrete purpose, not generic geometry types like, for example, DpRect.

So I see no reason to forcibly use WindowInsets instead of a simple holder of 4 named Dp values. Also, WindowInsets is in foundation, while this new API is in ui.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have an issue with DpInsets, there is an option to remove it and keep only availableBounds public - insets can be derived from it.

I am also fine with keeping the current DpInsets public.

Another option is to rename them to DpScreenInsets

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything wrong with DpInsets.

val top: Dp,
val left: Dp,
val bottom: Dp,
val right: Dp
) {

/**
* Returns the sum of the insets.
*/
operator fun plus(other: DpInsets) = DpInsets(
top = top + other.top,
left = left + other.left,
bottom = bottom + other.bottom,
right = right + other.right
)

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is DpInsets) return false

if (top != other.top) return false
if (left != other.left) return false
if (bottom != other.bottom) return false
if (right != other.right) return false

return true
}

override fun hashCode(): Int {
var result = top.hashCode()
result = 31 * result + left.hashCode()
result = 31 * result + bottom.hashCode()
result = 31 * result + right.hashCode()
return result
}
}

/**
* Returns the rectangle remaining after applying the given insets.
*/
@ExperimentalComposeUiApi
operator fun DpRect.minus(insets: DpInsets): DpRect =
DpRect(
top = top + insets.top,
left = left + insets.left,
bottom = bottom - insets.bottom,
right = right - insets.right
)

/**
* Returns the size after adding the given insets.
*/
@ExperimentalComposeUiApi
operator fun DpSize.plus(insets: DpInsets): DpSize =
DpSize(
width = width + insets.left + insets.right,
height = height + insets.top + insets.bottom
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.InternalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.layout.MeasurableRootContent
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.semantics.dialog
import androidx.compose.ui.semantics.semantics
Expand Down Expand Up @@ -313,6 +314,14 @@ class ComposeDialog : JDialog {
return composePanel.saveState()
}

/**
* Returns an object through which the composable content of the window can be queried for its
* size preferences, such as its intrinsic size.
*/
@ExperimentalComposeUiApi
val measurableContent: MeasurableRootContent
get() = composePanel.measurableContent

override fun dispose() {
super.dispose()
composePanel.dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.InternalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.layout.MeasurableRootContent
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.semantics.SemanticsOwner
import androidx.compose.ui.unit.Dp
Expand All @@ -35,7 +36,7 @@ import java.awt.GraphicsConfiguration
import java.awt.event.MouseListener
import java.awt.event.MouseMotionListener
import java.awt.event.MouseWheelListener
import java.util.Locale
import java.util.*
import javax.swing.JFrame
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
Expand Down Expand Up @@ -196,6 +197,13 @@ class ComposeWindow @ExperimentalComposeUiApi constructor(
return composePanel.saveState()
}

/**
* Returns an object through which the composable content of the window can be queried for its
* size preferences, such as its intrinsic size.
*/
@ExperimentalComposeUiApi
val measurableContent: MeasurableRootContent by composePanel::measurableContent

override fun dispose() {
super.dispose()
composePanel.dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.ui.ComposeFeatureFlags
import androidx.compose.ui.LayerType
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.layout.MeasurableRootContent
import androidx.compose.ui.scene.ComposeContainer
import androidx.savedstate.SavedState
import java.awt.Component
Expand Down Expand Up @@ -116,6 +117,9 @@ internal class ComposeWindowPanel(
isFocusCycleRoot = true
}

val measurableContent: MeasurableRootContent
get() = composeContainer.measurableContent

override fun setBounds(x: Int, y: Int, width: Int, height: Int) {
super.setBounds(x, y, width, height)
composeContainer.setBounds(0, 0, width, height)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.input.key.KeyEvent
Expand Down Expand Up @@ -146,7 +147,12 @@ fun SwingDialog(
// - Make the dialog displayable
// - Size the dialog and the ComposeLayer correctly, so that we can draw it here
if (!wasDisplayable && it.isDisplayable) {
it.renderImmediately()
Snapshot.withoutReadObservation {
if (!it.isValid) {
it.validate()
}
it.renderImmediately()
}
}
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,14 @@ fun SwingWindow(

// If displaying for the first time, make sure we draw the first frame before making
// the window visible to avoid showing the window background
// It's the responsibility of setSizeSafely to
// It's the responsibility of update(it) to:
// - Make the window displayable
// - Size the window and the ComposeLayer correctly, so that we can draw it here
if (!wasDisplayable && it.isDisplayable) {
Snapshot.withoutReadObservation {
if (!it.isValid) {
it.validate()
}
it.renderImmediately()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package androidx.compose.ui.awt
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.DpRect
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.size
import androidx.compose.ui.util.fastRoundToInt
import java.awt.Component
import java.awt.EventQueue
Expand Down Expand Up @@ -60,14 +62,36 @@ internal fun toAwtRectangle(
return Rectangle(rleft, rtop, rwidth, rheight)
}

internal fun IntRect.toAwtRectangle(density: Density = Density(1f)) = toAwtRectangle(
internal fun IntRect.toAwtRectangle(density: Density) = toAwtRectangle(
Comment thread
m-sasha marked this conversation as resolved.
left = left.toFloat(),
top = top.toFloat(),
right = right.toFloat(),
bottom = bottom.toFloat(),
density = density.density
)

internal fun DpRect.toAwtRectangleRounded(): Rectangle {
val left = this.left.value.fastRoundToInt()
val top = this.top.value.fastRoundToInt()
val right = this.right.value.fastRoundToInt()
val bottom = this.bottom.value.fastRoundToInt()
return Rectangle(left, top, right - left, bottom - top)
}

/**
* Returns a [java.awt.Rectangle] corresponding to this [DpRect], in the given density.
*
* The size of the rectangle is rounded up to the nearest integer.
*/
internal fun DpRect.toAwtRectangleSizeRoundedUp(): Rectangle {
val left = this.left.value.fastRoundToInt()
val top = this.top.value.fastRoundToInt()
val size = this.size
val width = ceil(size.width.value).toInt()
val height = ceil(size.height.value).toInt()
return Rectangle(left, top, width, height)
}

/**
* Returns a [java.awt.Rectangle] corresponding to this [Rect], in the given density.
*
Expand Down Expand Up @@ -162,4 +186,4 @@ internal class DebouncingEdtExecutor {
}
}
}
}
}
Loading
Loading