Features
Constraint Layout Improvements
Constraints got a major round of work in this release, with new building blocks and a lot of correctness and performance fixes in ConstraintLayout and the Solver.
preferssuggests a value for a constraint property without enforcing it or limiting the property's range. It supportsStrength.lerpinterpolates between a number and an expression, or between two expressions.ColorPickernow uses it.min/maxconstraint functions now usen + 1constraints instead of2n, and useWeakstrength.readonlyreplaces the previous snapshot-only behavior, andidealwidth/height/size values are now supported in constraint layouts.- Constraints now have a
positionproperty that maps totop/left. ConstraintLayouthas newparentWidthPreservationandparentHeightPreservationproperties that control how strongly parents preserve their size duringpreferredSizecalls.ConstraintLayoutImplnow enforces the parent size on layout. It usessuggestValuewhen a preferred value changes instead of removing and re-adding the constraint.centerhelpers now treat the item'swidth/heightasreadonly.
AnnotatedString
StyledText is now AnnotatedString, and the feature set has grown.
- Segments can be marked "selectable", which enables automatic text selection on platforms that support it.
AnnotatedString.Annotationsupports URLs, and newlinkextension methods create URL sections. This works in the Browser as well.TextDecoration.Linecan be used directly in theAnnotatedStringDSL.
Breaking Changes
StyledText→AnnotatedStringStyledTextVisualizer→AnnotatedStringVisualizer- Slider "tick(s)" → "mark(s)" throughout the slider APIs
- Constraint
hint→prefers readOnlyreplaced withvaluein constraintExpression,Position,AreaandEdgesBasicTabbedPanelBehaviornow takes selected/unselectedColors and no longer takesselectedColorMapperScrollPanel'scontentWidthConstraintsandcontentHeightConstraintsreplaced by a singlecontentConstraintspropertyPresenter.presentandPresenter.distanceToNextno longer take anitemsparameter. Use the newCarousel.itemextension API instead.Size.coerceInAspectnow takes atargetSizeinstead of a min and maxTextMetricsno longer has a defaultlineSpacing- Most
Rectanglemethods moved to extensions. Add the extension imports where needed. GridPanelnow takes aGridPanelBehavior- Removed the deprecated Kodein binding and other old deprecations
APIs
-
General
Positionablehas new properties for more ergonomic layout logic, includingassume, which lets aLayoutset size/min/max all at oncePolygonnow hasareaandcentroidproperties- New
ConvexPolygon.centroidextension property - New
Size.coerceInAspectmethod that retains aspect ratio while coercing aSizeinto a min/max Carousel.PresentedItemnow has anidealSizemethod- New
allNextandallPreviousmethods forPresenter.Positionthat return iterators to the items after and before the current one SlicerPresenternow takes acutRelativeToparameter to change how slices are constructedTreeTableBehaviornow has explicit header and footer cell generators for the tree columnBasicSliderBehaviorandBasicRangeSliderBehaviornow allow overriding their groove inset ratioLabelnow allows disabling auto size suggestionResizernow notifies of changes to the bounds it suggests for itsView- New vararg builder for
SimpleMutableListModel - Methods that guarded against incorrect arity usage are replaced by varargs, with deprecated overloads in their place
-
Browser
- New URL support within
AnnotatedString
- New URL support within
Fixes | Improvements
-
General
- Constraint layout failures when parent constraints change based on limits imposed by a grandparent
Solver.updateConstantnot working for non-RequiredstrengthSolvernot tracking and cleaning up negative guards- Solver range computation,
isUnderConstrainedaccuracy, andreadonly/ideal handling Solvernow clamps values very close to 0 to 0- Constraint
hashCodechanging after being added to a context, or going stale when strength is updated - Constraint updates across layouts now track only adds/removes instead of a list diff
- Constraint properties not updating when only modified by a single
preferscall - Bugs with offset constraints and internal constraint variable equality checks
- Layout bugs in
List,GridPanel,FlexLayout,Table,Carousel,PopupManager,InteractiveLayout,ListItem,SplitPanelandColorPicker ListLayoutnow lets items take any size within constraints instead of bounding them to their ideal size- Table contents not extending to the parent size when the ideal size was smaller
- Layout issues in
BasicTabbedPanelBehaviorandTreeRow, plus a more accurate internal rendering ofBasicTabbedPanelBehavior BasicTreeTableBehaviornow trims the header/footer tree column cell region so it aligns with the icon widthTableBehaviorandTreeTableBehaviorcolumn renderers now get expanded canvases that stretch to the bottom of the table- Visual tweaks and preferred-size handling for
BasicSpinButtonBehavior,BasicMutableSpinButtonBehaviorandBasicButtonBehavior Viewgiving a stale current size when callingLayout.preferredSizeViewresetting its children incorrectly during layout, and calculating preferred size changing children's bounds- Top-level
Views not being laid out when their preferred size changed - Size not being set properly during layout, and
Display.relayoutnot updating positionables properly View.visibilityChangedfiring even when set to the same value- Better
Viewsync when bounds are suggested during render/bounds syncing Labelissues withpreferredSize- Removed the phantom
Viewused byScrollPanelin its internal layout AnimatingTabContainerupdating tab locations a frame early, which looked like phantom pointer eventspausedevent firing incorrectly for grouped animationsDampedTransitioneranimation accuracyCarouselnot performing subsequent updates if its model was empty on the first oneCarouselrender issue when an item'sclipPathis usedSlicerPresenternot calculating the next item's size correctly- Concurrent modification in the render pipeline
- List selection allowing items outside
firstSelectableandlastSelectable Vector3D.as2d()still returning a 3D vectorRectangleconstructor not allowing defaultsTreeColumnRowdefault- Constraint usage in the
switchListform control - Conflicting overloads in
Vector2D - Misspelled API names
-
Browser
- Native
ScrollPanelbehavior now disables scrolling when the panel is disabled - Apps nested within DOM elements now lazy load when the element has a valid
offsetParent - Native control detection issues that regressed drag-and-drop and broke key event handling
- Regression in drag-drop visualization
NativeScrollPanelincorrectly discarding elements for old content it no longer contains- Canvas clip regions being clipped to the canvas bounds, limiting how large they could be
TextMetricsImplinterfering with view ordering because it adds elements to the DOMTextMetricsImplnot cleaning up its cached node for measuring wrapped text- Sub-pixel element measurement
- Text measurement being incorrect when a null
Fontwas provided - Font not being reset on reused elements
- Default
line-heightnot being used correctly, which caused text clipping - Text width measurement for
AnnotatedString - First
Displaysize change being missed in some cases - Concurrent modification bug in SchedulerImpl
- WASM casting bug
- Issue with incorrect default lineHeight
- Native
-
Desktop
- Updated deprecated
needRedrawcalls for Skiko
- Updated deprecated
Performance
-
General
- Various performance improvements across the framework, some more significant for Browser
- Fewer constraints needed for
minandmax(2n→n + 1) - Less reflection in
ConstraintLayoutImpl,Solverand other hot spots, which matters most for browser targets - Less object creation in
Solverby usingforEachdirectly on maps - Less object creation within
RectangleandSize - Explicit
Doubleversions of functions that previously tookNumber Viewonly requests layout for its parent when its layout size differs from its current size while using layout-basedpreferredSize, which cuts duplicate preferred-size calls- Less overhead in
Viewlayout and preferred-size calls RenderManagerImpluses sets more efficiently, along with other changes that improve render performanceLinearPresenterno longer accesses items unnecessarilybasicVerticalListBehavioruses aColorPaintinstead of aPatternPaintwhen the even and odd colors are the same- Constraint exceptions are no longer thrown for some cases
-
Browser
- Replaced the
box-sizing: inheritCSS style withbox-sizing: border-box, which has the same effect without referencing parent nodes - Replaced the
DisplayImpl.layoutdelegate with a simple property AnimationSchedulerImplavoids multiplerequestAnimationFramecalls in a single frame- Better font serialization caching
TextMetricsImpluses the canvas more heavily when supportedTextFactoryImplreuses more elementsPathMetricsImplminimizes element add/remove cycles when measuring pathsFillHandlerno longer clears children ofSVGPatternElement, since they can be reused- Less use of
observableinLabelto avoid reflection - Check-before-set in DOM operations
viewPortOffsetis only checked in Safari, since it's in a hot path
- Replaced the
Build
- Re-added Kover through a convention plugin
- Added a convention plugin to handle publishing
- Moved Dokka external link config for Measured into the convention plugin
- Migrated to the Dokka 2 API
- Fixed a Gradle dependency issue with
test-fixture - Fixed compiler issues caused by formerly lax code
- Fixed nmcp publication logic
Tests
- Expanded
Viewtest coverage - New
SolverandInteractiveLayoutunit tests - Fixed
Solver,SchedulerImpland other unit tests
Versions
- Kotlin -> 2.4.21
- Gradle -> 9.5.0
- Dokka -> 2.1.0
- JUnit -> 5.10.1
- Measured -> 0.5.0
- ncp -> 1.6.2