BRUCE BLOG / ENGINEERING
Tracing a Tauri window dragging slowdown
A multi-monitor centering bug led to blank-window controls, native parent relationships and a titlebar regression. What we measured, where the investigation went astray, and how we checked the repair.
Yang Yong'an and Codex · Published · Originally recorded
Three problems in one window
Bruce is a desktop development tool built with Tauri 2, React and Rust. The report started with multiple displays: opening Git Push did not center its dialog on the display containing the current project window.
After centering was corrected, more feedback followed. Opening still felt slow. Dragging was jerky. Settings behaved the same way. Multiple windows are a basic desktop capability, so why did an ordinary dialog feel so awkward?
We worked on position, opening latency and continuous dragging, but initially failed to accept them as separate behaviors. Seeing the window appear sooner made us underestimate the dragging problem that remained.
Desktop coordinates can be negative
The old implementation clamped the computed vertical position to zero or greater. A display above the primary display can have negative coordinates: the reported project window was at y = -901. Clamping its dialog's centered position to zero pushed the dialog toward another display.
The correction preserves negative coordinates, centers against the owning window and fits the result within that display's usable area. It uses the outer frame, including the native titlebar, with consistent coordinate units.
Project window: y = -901, height = 840
Dialog outer height = 674
Centered y = -901 + (840 - 674) / 2 = -818
Preserve the valid negative coordinate.Measure opening and dragging separately
To reduce repeated initialization, we moved Push onto the existing drawn-window mechanism. The project opens a native window and renders into its document through a React portal, sharing existing business state and the Host connection. We wait for actual stylesheet readiness and apply the content and native appearance together.
This improved opening latency, while dragging remained awkward. Opening measures time until content becomes visible. Dragging measures how closely the window follows sustained pointer input. They need separate measurements.
We had assumed native dragging would be reliable and concentrated on React, the DOM and page loading. That assumption kept the investigation at the wrong layer for too long.
A blank window established the control
The turning point was a direct request: remove all business DOM, open the simplest Tauri window and see whether it still stutters. We created an independent blank window without React or business connections, then kept the document unchanged and added only a native parent.
We injected the same 120 native drag events and recorded window position changes. The independent window updated 120 times. Adding the parent reduced that to 38, with the longest update interval rising from 25 to 147 ms. An empty AppKit parent-and-child control reproduced a similar slowdown without a WebView.
This located the problem in the native parent-and-child drag path on the tested Mac. Counts refer to observed position changes, not rendered frames. Maximum intervals exclude the initial wait after pressing. These are controlled observations from several runs, rather than cross-device benchmarks or repeated-run averages.
A parent changes native window behavior
Parenting is an official system mechanism. Apple's addChildWindow maintains relative ordering and makes the child move with its parent. Keeping Push above its project window was a concrete reason to use it.
Business ownership and native attachment are separate relationships. Tauri's parent interface establishes an owned window on Windows, a transient relationship on Linux and a native child window on macOS. One interface name covers different platform behaviors.
The experiment established that adding native parenting reproduced the dragging pauses in this Mac's environment. The internal system reason remained unresolved. The result does not establish that every macOS or Tauri window has the same problem.
Detach for the duration of the drag
We applied a bounded workaround to the demonstrated behavior. At the native titlebar press, temporarily detach the child. After the actual button release, restore the relationship on the main thread. Business ownership, modal state and close management remain intact throughout.
One local measurement mattered: performWindowDragWithEvent returned almost immediately while the gesture was still in progress. Restoring the parent as soon as that call returned put the window straight back onto the slow path. We therefore read the left-button state through CoreGraphics and restore after release.
Before reattaching, we check that both windows still exist, are visible and retain the same business relationship. Validation also moves the parent after release to confirm that the child still follows it.
A titlebar regression from the drag repair
Another report followed: the child window's title was incomplete and overlapped the macOS traffic lights. This was a regression we had introduced. Native measurements found the text present, but positioned at x = -10 pt.
Disabling the new drag hit view restored the title. Adding that transparent view directly to NSThemeFrame had changed AppKit's titlebar hierarchy in the tested environment. We moved it inside the existing titlebar, preserving the system container and button layout.
The Settings title returned to x = 82 pt, beyond the traffic lights' right edge at x = 69 pt. Both captures below show the same Appearance settings page. The article focuses on their titlebars; opening an image reveals the complete original capture.
Native captions and complete interaction checks
Loaded dialogs, portal-drawn dialogs and separate panel windows now share caption configuration. macOS shows the native title with content below the strip. Windows and Linux retain system decorations. Drawn windows also set their native caption explicitly before showing, reducing reliance on title-change notifications from a blank document.
After the titlebar correction, Settings and Push each still produced 113 position updates. Maximum intervals were 27 and 35 ms; opening took 162 and 204 ms. An earlier full-window run recorded 239–248 ms opening. Individual observations vary and need to stay attached to their test conditions.
Settings, Push and Diff titles were inspected in real macOS windows. Windows and Linux configuration is covered, but visual behavior has not yet been checked on those systems. Passing tests, type checks and builds cannot replace that inspection.
- Position: center the child against its current parent and fit the display's usable area.
- Drag: record continuous movement, final displacement and whether titlebar presses enter the page.
- Restore: confirm parent movement carries the child after release, and Cancel clears the modal blocker.
- Native appearance: inspect caption text, system controls and the content boundary together in the actual window.
Start the next investigation with an empty window
The largest change should be to the order of investigation. We trusted native dragging too early and treated better opening latency as evidence of a better overall window. The blank-window control should have come first.
Bruce's companion browser helps inspect DOM, business flows and requests. The real macOS window uses WKWebView, and its titlebar and native movement need measurements from that surface. Establish where the gesture lands, then choose the tool that reaches it.
Next time, we will begin with an independent empty window, add the parent relationship, then introduce the page, styles and business state, and finally check displays, themes and window ordering. Measure again at each step so every change answers a specific question.

