Checked against io.Connect Desktop 10.3.0 and its shipped configuration schema, with v9 behavior checked against 9.13.0. Defaults do move between releases, so confirm against the changelog for the version you’re upgrading to, and where the official docs cover a property, trust them over this post.
In io.Connect Desktop 10, stickywindows.json is no longer where window behavior is configured. The file still loads and still works, with a deprecation warning, but its settings have moved under windowManagement in system.json: some renamed, some pinned to values you can’t set anymore, some gone for good.
The 10.0 changelog doc lists the new keys, but not the old ones, and there’s no property-level migration guide, so finding out where a particular setting went means putting the two schemas side by side. Here’s that mapping for all 45 properties the v9 file accepted.
Renamed properties
Same setting, new location under windowManagement in system.json.
v9 stickywindows.json |
v10 windowManagement.* |
|---|---|
enableStickiness |
snapping.enabled |
approachingDistance |
snapping.approachingDistance - 10–100, same meaning as v9: the distance at which approaching window edges highlight. Effective default is 30, though the schema description still cites the old v9 default of 50. |
edgeDistance |
snapping.edgeDistance - 2–10, default 4. v9 documented 0–10, so a kept 0 or 1 is reset to 4 with a warning. |
autoAlign |
snapping.autoAlign |
snapDistance |
snapToScreenEdges.distance - 5–30, default 20. Not available on macOS. |
snapToScreenEdges |
snapToScreenEdges.enabled - default false, and not available on macOS. The shape changed: a boolean in v9, an object with enabled and distance in v10. |
reverseAltSnapping |
alternateBehavior.snapping.reverse - default false |
reverseAltTabDrop |
alternateBehavior.dropInTabGroup.reverse - default false |
reverseAltWorkspaceDrop |
alternateBehavior.dropInWorkspace.reverse - default false |
groupType |
group.type - default is now "Web"; "Classic" also requires top-level "advancedMode": true |
groupMaximizedMode |
group.externalResizeMode - default "Fill" |
hideGroupCaption |
group.header.hide |
enableWindowGroupsCaptionEdit |
group.header.editTitle |
tabs.flatWhenSingle |
group.tabs.flatWhenSingle |
unlockWithLongMousePress |
group.unlockOnLongMousePress.enabled - default true |
unlockTimeout |
group.unlockOnLongMousePress.timeout - default 1000 |
unlockTolerance |
group.unlockOnLongMousePress.tolerance - default 5 |
enableWindowsCaptionEdit |
editWindowTitle |
collapseExpandMode |
collapseExpand.mode |
alignBordersWhenExpanding |
collapseExpand.alignBottomBordersWhenExpanding |
rendererTransparencyMode |
transparencyControl.mode - in the advanced platform mode, "Auto" resolves to "Transparent" with hardware acceleration off and "Regions" with it on; the default platform mode always uses "Transparent" |
rendererTransparencyKeyColor |
transparencyControl.keyColor - applies only when mode is "KeyColor" |
rendererHWTransparencyMode |
hardwareAcceleration.transparency.mode - "UseRegions" / "UseNative", default "UseRegions" |
rendererHWTransparencyMouseRedirectMode |
hardwareAcceleration.transparency.mouseEventRedirection - "UseRegions" / "UseRenderedContent", default "UseRegions" |
flydownShowDelay |
flydownWindows.showDelay |
flydownChangeDelay |
flydownWindows.zoneChangeCallbackTimeout |
flydownHideDelay |
flydownWindows.hideDelay |
flydownHideCheckInterval |
flydownWindows.hideCheckInterval |
One property moves outside windowManagement entirely:
v9 stickywindows.json |
v10 system.json |
|---|---|
minimumWindowSize |
Top-level windows.minWidth / windows.minHeight - a floor for windows that set no minimum of their own, overridable per app definition, honored while resizing a group. The floor is applied through the io.Connect window settings, so a native window that supplies its own size constraints may not pick it up - worth testing one rather than assuming. |
Properties now fixed
These still exist internally but are pinned - remove them from your config, since nothing you set will apply.
| v9 property | Pinned to |
|---|---|
identity |
The computed <region>-<env> string. Already the case in late v9, where the file’s value was overridden anyway. Environment isolation now rides on top-level region / env. |
targetMode |
Derived from top-level registerHtmlContainer - default false, giving "Glue". |
enableCrossProcess |
Always true. |
sizingMode |
Always "Proportional". |
enableWindowGroupsDropShadow |
Always true. |
tabs.buttonsAlwaysVisible |
Always true, reversing the v9 default of false - tab buttons are no longer hover-only. |
qtWindowClassnameRegex |
Always "Qt.*?QWindow.*?", the v9 default. |
Properties dropped
| v9 property | What happened |
|---|---|
autoCollapse, autoRemoveWindows, groupCaptionHeight, groupBorderSize |
Deprecated in 10.0 and deleted when the config loads. |
autoSnap, autoArrange |
Dropped and already inert on 9.13, where the platform overwrote both to true right after loading the file, so whatever you set never applied. Snapping is governed by snapping.enabled and snapping.autoAlign. |
movingGroupsFromTopWindowOnly |
Dropped and already dead on 9.13, where it was parsed but never read. Removing it changes nothing. |
hideSwimlaneFrameCaption, enableSwimlaneFrameDropShadow |
Dropped with the legacy Canvas (“swimlane”) frames, and no windowManagement equivalent exists - the modern Workspaces frame ignores both keys. Both were already inert on 9.13 unless you ran the legacy Canvas frames. |
Before and after
A representative v9 file:
{
"identity": "%IO_CD_REGION%-%IO_CD_ENV%",
"targetMode": "Glue",
"enableCrossProcess": true,
"sizingMode": "Proportional",
"enableWindowGroupsDropShadow": true,
"enableStickiness": true,
"approachingDistance": 30,
"edgeDistance": 4,
"autoAlign": true,
"snapToScreenEdges": true,
"snapDistance": 5,
"groupType": "Classic",
"groupMaximizedMode": "Fill",
"hideGroupCaption": false,
"enableWindowGroupsCaptionEdit": true,
"enableWindowsCaptionEdit": true,
"rendererTransparencyMode": "Auto",
"rendererTransparencyKeyColor": "#FE0000",
"minimumWindowSize": 100,
"flydownShowDelay": 200,
"flydownChangeDelay": 150,
"flydownHideDelay": 400,
"flydownHideCheckInterval": 100,
"autoSnap": true,
"autoArrange": true,
"movingGroupsFromTopWindowOnly": false,
"hideSwimlaneFrameCaption": true,
"enableSwimlaneFrameDropShadow": true,
"tabs": {
"buttonsAlwaysVisible": true,
"flatWhenSingle": false
}
}
The same configuration in v10 system.json:
{
"advancedMode": true,
"windows": {
"minWidth": 100,
"minHeight": 100
},
"windowManagement": {
"snapping": {
"enabled": true,
"approachingDistance": 30,
"edgeDistance": 4,
"autoAlign": true
},
"snapToScreenEdges": {
"enabled": true,
"distance": 5
},
"transparencyControl": {
"mode": "Auto"
},
"editWindowTitle": true,
"flydownWindows": {
"showDelay": 200,
"zoneChangeCallbackTimeout": 150,
"hideDelay": 400,
"hideCheckInterval": 100
},
"group": {
"type": "Classic",
"externalResizeMode": "Fill",
"header": {
"hide": false,
"editTitle": true
},
"tabs": {
"flatWhenSingle": false
}
}
}
}
Three things to notice. "advancedMode": true is what keeps "Classic" groups - without it the group type is forced to "Web"; if you don’t need classic groups or visual integration of native apps, drop both and stay in the default mode. minimumWindowSize lands in the top-level windows section, not under windowManagement. And rendererTransparencyKeyColor is gone, because under "Auto" the key color is never used - keep it only alongside an explicit "mode": "KeyColor".
Several values above equal their v10 defaults and could be omitted; they’re spelled out to show the mapping.
Defaults that changed
If a property was absent from your v9 file, you inherited the v9 default - and for these four the v10 default differs. Set them explicitly if the old behavior matters.
| Property | v9 default | v10 default | What you’ll notice |
|---|---|---|---|
snapToScreenEdges → snapToScreenEdges.enabled |
true |
false |
Windows no longer snap to screen edges. On late v9 the old file’s value was already being overridden, so check what you were actually running. |
groupType → group.type |
"Classic" |
"Web" |
Group decorations move from WPF and themes.json to HTML and CSS. |
groupMaximizedMode → group.externalResizeMode |
"Proportional" |
"Fill" |
Groups containing a size-restricted window resize differently. |
approachingDistance → snapping.approachingDistance |
50 |
30 |
Approaching window edges highlight later. |
The pinned values need the same check. The v9 config that shipped with the product already used them, so a file derived from it sees no change, but if you wrote a minimal file and let the v9 defaults apply, four of them flip: enableCrossProcess (false → always true), sizingMode ("Single" → always "Proportional"), enableWindowGroupsDropShadow (false → always true), and tabs.buttonsAlwaysVisible (false → always true). targetMode now resolves to "Glue" unless registerHtmlContainer is true, where the v9 default was "Connect".
Where each setting applies
A correctly migrated value can still look like it does nothing, because not every setting applies in every setup:
transparencyControlandflydownWindows- available in advanced platform mode only.collapseExpand- classic groups in the advanced platform mode only.snapToScreenEdges- not available on macOS.- Advanced mode itself is Windows-only. It’s recommended to enable it only if your use case requires using classic groups or visual integration of native apps, because doing so uses additional internal logic for processing native app windows which leads to overall performance disadvantages.
Two override rules matter once the file is in the right shape. windowManagement settings can be overridden per app from the app definition - with the documented exception of the window group settings - so a global value that appears ignored may be overridden downstream; snapToScreenEdges is the documented per-app example. And hardwareAcceleration.enabled is listed among the properties that “must be defined only locally and must not be overridden by any remote configuration source”, so setting it from a remote config store won’t work.
Mistakes that look right, but aren’t
group.externalResizeModeis the successor ofgroupMaximizedMode, not ofsizingMode. Moving yoursizingModevalue into it silently changes how maximized groups resize.sizingModeneeds no migration at all as it’s pinned.snapDistancedid not becomesnapping.edgeDistanceorsnapping.approachingDistance. Its v9 description called it the distance at which windows snap together into a group, which makessnapping.*look like the right home - but by 9.13 that was no longer what the value did; it fed snapping to screen edges, which is what the v10 key controls. Not a change, despite appearances: the v9 description gave the range as 5–20, but the engine already accepted up to 30, the same 5–30 the v10 key declares.- Values that were valid in v9 are rejected outright in v10.
"Default"was accepted forrendererTransparencyMode,collapseExpandMode, andgroupMaximizedMode, and"None"for the two hardware-transparency settings. None are valid for the correspondingwindowManagementkeys, and copying them across fails startup rather than being ignored. If you want the default, omit the property. transparencyControl.mode: "Auto"no longer means the key-color mechanism. That was v9 behavior with hardware acceleration off; it now resolves to"Transparent"there, and a migratedkeyColoris ignored unless you explicitly set"mode": "KeyColor". In the advanced platform mode with hardware acceleration on,"Regions"is used regardless of the configured mode - even an explicit"KeyColor"is overridden - so a key color can never take effect in that combination. Since"Auto"resolves per setup at startup, one shared transparency block works across configurations that differ onhardwareAcceleration.enabled. In the default platform mode none of this applies: the mode is forced to"Transparent"whatever you configure, even though hardware acceleration is forced on there."Classic"needsadvancedMode, and the default doesn’t give it to you.advancedModedefaults tofalse, and in that mode the group type is forced to"Web"whatever you configure - so a file migrated key-for-key still comes up with web groups unless"advancedMode": trueis set at the top level ofsystem.json. The only signal is an info-level log line:forcing group type to 'Web' when in 'universal' mode, where'universal'is the platform’s internal name for non-advanced mode.advancedMode: truedoes not commit you to classic groups. Platform mode andgroup.typeare independent, and advanced mode with the default"Web"group type is a valid combination. The changelog sentence saying native windows can’t be snapped to io.Connect windows describes the default mode only; advanced mode is what enables visual integration of native (Java, .NET) apps. Still worth choosing deliberately: classic groups are deprecated, won’t receive fixes, and the same changelog says they “will be entirely removed in a future release”.- Validation won’t catch a wrong key name. Unknown properties in
system.jsononly log warnings, so a misspelled key silently does nothing; a wrong value (bad enum or type) fails startup instead. Two refinements: the warning-only path applies when every validation error is an unknown-property error, so a typo combined with a bad enum value fails startup; and out-of-range numbers differ per key, because only some declare bounds in the schema.snapToScreenEdges.distance: 3fails validation, whilesnapping.approachingDistance: 500starts up and is clamped to the default with a warning. - Your old file may not be an accurate record of your v9 behavior.
windowManagementalready existed in v9’ssystem.json, and on 9.13 it already won for several keys:snapToScreenEdgeswas taken fromwindowManagement.snapToScreenEdges.enabled(falling back tofalse) no matter what the old file said,snapDistancecame from.distancewhenever edge snapping was on, and the three ALT-reverse settings were overwritten unconditionally.collapseExpandModeand the unlock-on-long-press trio were overwritten wheneversystem.jsonset them. Read your v9system.jsonalongside the old file before deciding what your baseline was. - Keeping
stickywindows.jsonin place does not preserve all your old values. For most settings the legacy file still acts as a fallback where you haven’t set the new key, butsnapToScreenEdges,collapseExpand, and thealternateBehaviorsettings ignore it entirely and take the new defaults. A kept"snapDistance": 5therefore becomes 20, silently. Migrate the values instead of relying on the old file.
Verifying your migration
On startup, application.log carries a line beginning effective window management config: - the fully resolved windowManagement section, and the fastest way to confirm a key took effect. The now-fixed values (identity, sizingMode, enableCrossProcess, and the rest) aren’t part of that section; they appear in the window engine’s own configuration dump in bridge.log, under the SW-Config logger. A legacy stickywindows.json that’s still present loads with a deprecation warning, and windowManagement values take precedence over it.
Looking up your v9 values
The v9 schema, with every property’s default, is published at assets/configuration/9-0/stickywindows.json. The page documenting those properties is io.Connect Windows configuration - note it’s scoped to the 9.0 stream, so it describes the old file, not the new one. The v10 keys live in the system configuration reference under windowManagement.
Applies to: io.Connect Desktop 10.x, verified on 10.3.0; v9 behavior statements verified on 9.13.0.