WM-448: fix: place new windows on cursor's output instead of primary output - #1389
WM-448: fix: place new windows on cursor's output instead of primary output#1389deepin-wm wants to merge 1 commit into
Conversation
|
Skipping CI for Draft Pull Request. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: deepin-wm The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's guide (collapsed on small PRs)Reviewer's GuideFix multi-monitor placement by initially assigning new top-level windows to the cursor’s output, while preserving parent-output behavior and switching to geometry-based tracking after the window is moved. Sequence diagram for cursor-based new window output assignmentsequenceDiagram
participant WindowManager
participant RootSurfaceContainer
participant Workspace
participant Cursor
participant Outputs
WindowManager->>RootSurfaceContainer: addBySubContainer(sub, surface)
RootSurfaceContainer->>RootSurfaceContainer: parentSurface()
alt top-level window
RootSurfaceContainer->>Cursor: cursorOutput()
Cursor-->>RootSurfaceContainer: cursor output or null
opt cursor output unavailable
RootSurfaceContainer->>Outputs: primaryOutput()
Outputs-->>RootSurfaceContainer: primary output
end
else child window
RootSurfaceContainer->>RootSurfaceContainer: ownsOutput()
end
RootSurfaceContainer->>Workspace: updateSurfaceOwnsOutput(surface)
alt positionAutomatic and ownsOutput exists
Workspace->>Workspace: ownsOutput()
else geometry-based tracking
Workspace->>Workspace: getIntersectedOutputs(outputs)
end
State diagram for window output tracking after placementstateDiagram-v2
[*] --> CursorOutputAssigned: new top-level window
CursorOutputAssigned --> CursorOutputAssigned: positionAutomatic()
CursorOutputAssigned --> GeometryOutputTracking: beginMoveResize()
GeometryOutputTracking --> GeometryOutputTracking: getIntersectedOutputs(outputs)
CursorOutputAssigned --> PrimaryOutputFallback: cursorOutput unavailable
PrimaryOutputFallback --> CursorOutputAssigned: window created
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
9ae733f to
699d797
Compare
|
TAG Bot New tag: 0.10.0 |
Use cursorOutput() instead of primaryOutput() in addBySubContainer for new top-level windows, with null fallback to primaryOutput(). Also preserve existing ownsOutput for positionAutomatic windows in updateSurfaceOwnsOutput to prevent geometry-based override when the window receives its initial size at position (0,0). 多屏环境下新窗口的 ownsOutput 原先使用 primaryOutput() 而非 cursorOutput(),且窗口获得初始尺寸时 updateSurfaceOwnsOutput 会用 基于几何位置的输出覆盖光标所在输出。修改两处:addBySubContainer 改用 cursorOutput() 并在空值时回退 primaryOutput(); updateSurfaceOwnsOutput 对 positionAutomatic 窗口优先保留已有 ownsOutput,用户拖拽后 positionAutomatic 变 false 仍按几何跟随。 Log: 修复多屏时新窗口位置不跟随光标所在屏幕的问题 PMS: BUG-376719 Issue: Fixes WM-448 Influence: 多屏环境下新窗口将出现在光标所在屏幕而非固定主屏, 用户拖拽窗口跨屏后 ownsOutput 正常跟随,单屏行为不变。
699d797 to
6d610f1
Compare
|
|
||
| Output *output = nullptr; | ||
| if (!outputs.isEmpty()) | ||
| if (surface->positionAutomatic() && surface->ownsOutput()) |
修复多屏时新开窗口位置不正确
多屏环境下,新开的顶层窗口始终出现在主屏或左屏,而非光标所在的屏幕。
根因
存在两条代码路径导致新窗口位置错误:
路径一:
addBySubContainer使用primaryOutput()而非cursorOutput()RootSurfaceContainer::addBySubContainer()在为无父窗口的顶层窗口分配ownsOutput时使用primaryOutput(),导致所有新窗口被固定到主屏。Workspace::updateSurfaceOwnsOutput()的早退守卫if (surface->ownsOutput() && outputs.contains(surface->ownsOutput()->output())) return;在新窗口初始getIntersectedOutputs恰好返回含主屏的列表时会命中,旧代码因ownsOutput=primary早退后保留主屏(即 bug)。路径二:
updateSurfaceOwnsOutput中 geometry-based 覆盖 cursor-basedownsOutput仅修复路径一不够充分。当新窗口获得初始尺寸时:
addBySubContainer设置ownsOutput = cursorOutput()(如右屏)✅geometryChanged触发 →updateSurfaceOutputs→getIntersectedOutputs(QRect(0,0,w,h))(0,0),在多屏布局中(0,0)落在左屏 → 返回左屏的 outputupdateSurfaceOwnsOutput发现 cursor output(右屏)不在 geometry-based outputs 列表中 → 不触发早退守卫 →outputs.first()→ 覆盖为左屏 ❌这就是窗口总是出现在左屏的原因。
修复
Commit 1:
addBySubContainer中primaryOutput()→cursorOutput()将无父窗口分支的
primaryOutput()替换为cursorOutput(),并在光标不在任何输出上时回退到primaryOutput():Commit 2:
updateSurfaceOwnsOutput中防止 geometry-based 覆盖 cursor-basedownsOutput当窗口
positionAutomatic()为true(即尚未被用户手动定位)且ownsOutput已设置时,优先保留现有ownsOutput,而非使用 geometry-basedoutputs.first():安全性分析
parentSurface->ownsOutput()getIntersectedOutputs返回空(常见情形)时,早退守卫不触发,fallback 链本身已优先cursorOutput(),行为不变cursorOutput()与primaryOutput()等价,行为不变beginMoveResize会将positionAutomatic设为false,因此用户拖拽窗口到其他屏幕时,仍会使用 geometry-based 交集来更新ownsOutputmoveSurfacesToOutput显式设置ownsOutput,不经过updateSurfaceOwnsOutput变更文件
src/core/rootsurfacecontainer.cpp—addBySubContainer中primaryOutput()→cursorOutput()+ 空值回退src/workspace/workspace.cpp—updateSurfaceOwnsOutput中positionAutomatic守卫防止 geometry 覆盖关联
Multica Issue: WM-448
PMS: https://pms.uniontech.com/bug-view-376719.html
Summary by Sourcery
Place new windows on the cursor's display while retaining existing behavior for parented and manually positioned windows.
Bug Fixes: