Frontmatter
| id | 9356 |
| title | Chrome Windows: Multi Window Drag & Drop |
| state | Closed |
| labels | bug |
| assignees | tobiu |
| createdAt | Mar 6, 2026, 10:10 AM |
| updatedAt | Mar 15, 2026, 11:34 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9356 |
| author | kmunk-klarso |
| commentsCount | 1 |
| parentIssue | null |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Mar 15, 2026, 11:29 PM |
Chrome Windows: Multi Window Drag & Drop

- Open Docked Window -- auf weiterem fenster Position rechts und links macht keinen Unterschied -- Create Dialog lässt sich nicht zwischen Fenster hin und herziehen, Dialog verschwindet dabei

Input from Gemini 3.1 Pro:
✦ Hi @kmunk-klarso, thanks a lot for reporting this issue! It was an incredibly subtle bug involving a regression in the component styling system.
Here is an in-depth breakdown of what was happening and how we fixed it:
The Problem
- The Drop Calculation: In the multi-window
SharedDialogapp, when a dialog was dropped into the other window, theMainContainerControllercalculated the newleftandtopcoordinates and applied them todialog.wrapperStyle.- The Merge Conflict: The base
Componenthandles styling via two reactive configs:style_andwrapperStyle_. When you modify either, it triggersupdateStyle(), which merges them into the actual VDOM tree:vdom.style = {...me.wrapperStyle, ...me.style}.- The Regression: Because
...me.stylecomes last in the merge, the old coordinates from the previous window (which were stored inme.styleby theDragZoneupon drag completion) completely overrode the newly calculated coordinates inme.wrapperStyle. This caused the dialog to render at its old coordinates in the new window, effectively vanishing from view (likely off-screen).The Puzzling Part: Why did it work in older Neo.mjs versions?
The reason this used to work fine in older versions of the framework comes down to a side effect that was present in the
wrapperStyle_getter insidesrc/component/Base.mjs:// Old buggy version beforeGetWrapperStyle(value) { return {...Object.assign(this.vdom.style || {}, value)} }
Object.assign()mutates its first argument in place! In older versions of Neo, this side effect accidentally masked the merge conflict. The timing of property accesses under the old config system meantthis.vdom.stylewas mutated directly before the VDOM was mounted, effectively sneaking the correct coordinates into the tree.With the introduction of the new
core.Configreactivity system, the timing of these getters and setters became stricter and more predictable. The side effect was no longer triggered at the exact moment needed to mask the bug. Interestingly, while diagnosing this, we temporarily addedconsole.log(dialog.wrapperStyle)which artificially triggered the getter. This caused the mutation to fire right when it was needed, "fixing" the bug locally and ultimately guiding us to the root cause!The Fix
- Fixed the Side Effect: We removed the mutating
Object.assignside effect fromsrc/component/Base.mjs->beforeGetWrapperStyle. It now safely returns a merged object without mutating the VDOM directly:return {...this.vdom.style, ...value}.- Fixed the Controller: We updated the
SharedDialogapp'sMainContainerControllerto correctly apply the new drop coordinates todialog.styleinstead ofdialog.wrapperStyle. SinceDialog.mjsusesstylefor its drag positioning, the controller must also usestylewhen calculating new positions to prevent the old style from overriding the new coordinates.- Cleaned up Routing: We also took the opportunity to clean up
onDragStart, ensuring thewindowIdis correctly passed to the remoteNeo.Main.getWindowData()call, adhering to the strict architectural constraints of ourRemoteMethodAccesssystem.The changes have been pushed to the
devbranch. Thanks again for the report!