Repository navigation
Conversation
Add the server-side implementation of treeland-window-transition-unstable-v1, which plays a window open/close transition relative to a source rectangle attached to an xdg-activation token. A client attaches a persistent transition rectangle (geometry plus an optional source image) to an xdg_activation_token_v1 before committing the token. At activation the compositor associates the rectangle with the target window, animating from the rectangle's global position on open and back to it on close. The rectangle stays alive, so set_geometry and set_source_buffer update it immediately. 新增 treeland-window-transition-unstable-v1 的服务端实现,基于关联到 xdg-activation token 的源矩形播放窗口打开/关闭转场。 客户端在提交 token 前挂载一个持久的转场矩形(几何信息及可选源图像)。 激活时合成器将矩形关联到目标窗口,打开时从矩形的全局位置播放动画, 关闭时过渡回该矩形。矩形持续存活,set_geometry / set_source_buffer 可立即更新。 Log: 实现窗口转场协议,基于激活 token 的源矩形播放开/关转场 Influence: 新增窗口转场模块、QML 动画组件及 test-window-transition 样例; 激活流程支持矩形关联并播放开/关动画。
|
[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 GuideImplements treeland-window-transition-unstable-v1 end to end: clients attach persistent geometry and optional source buffers to xdg-activation tokens, the compositor carries that metadata through activation, associates it with the target surface, and runs QML-based open/close animations with lifecycle, expiration, fallback, and resource cleanup handling; a Qt test client demonstrates the protocol. Sequence diagram for window transition token activationsequenceDiagram
participant Client
participant Activation as ActivationManagerInterfaceV1
participant Transition as WindowTransitionManagerInterfaceV1
participant Helper
participant Target as SurfaceWrapper
participant QML as WindowTransition
Client->>Transition: get_window_transition_rect(token)
Client->>Transition: set_geometry(x, y, width, height)
Client->>Transition: set_source_buffer(buffer)
Client->>Activation: commit()
Activation->>Transition: takeCommittedRect(token, tokenResource)
Client->>Activation: activate(token, targetSurface)
Activation->>Helper: activateRequested(token, disposition, target, seat, origin)
Helper->>Transition: associatePendingRect(token, target, origin)
Transition->>Target: setWindowTransitionRect(rect, origin)
Transition->>Target: setWindowTransitionSourceImage(image)
Target->>QML: createWindowTransition(fromGeometry, toGeometry, sourceBuffer, OPEN_ANIMATION)
QML-->>Target: finished
Target-->>Client: window opens from source rectangle
Sequence diagram for window transition close animationsequenceDiagram
participant Target as SurfaceWrapper
participant QML as WindowTransition
participant Origin as SourceSurface
participant Client
Target->>Target: computeGlobalWindowTransitionRect()
Target->>QML: createWindowTransition(fromGeometry, toGeometry, sourceBuffer, CLOSE_ANIMATION)
QML->>QML: start()
QML-->>Target: finished
Target->>Target: onHideAnimationFinished()
Target->>Target: dropWindowTransitionSourceBuffer()
Target-->>Client: window closes toward source rectangle
State diagram for transition rectangle lifecyclestateDiagram-v2
[*] --> Created: get_window_transition_rect
Created --> Committed: set_geometry
Committed --> Pending: commit token
Pending --> Associated: activate token
Pending --> Discarded: token expires or invalid target
Associated --> Associated: set_geometry / set_source_buffer
Associated --> Opening: target maps
Opening --> Active: animation finished
Active --> Closing: target unmaps
Closing --> Closed: animation finished
Discarded --> [*]
Closed --> [*]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/modules/activation/activationmanagerinterfacev1.cpp" line_range="231-240" />
<code_context>
WSeat *tokenSeat = nullptr;
+ WSurface *originatingSurface = nullptr;
+
auto it = std::find_if(m_tokens.begin(), m_tokens.end(),
[&token](const TokenInfo &t) { return t.token == token; });
if (it != m_tokens.end()) {
tokenSeat = it->seat.data();
- m_tokens.erase(it);
+ originatingSurface = it->originatingSurface;
+ disposition = it->fromTrustedSurface
+ ? (it->serial.has_value()
+ ? ActivationManagerInterfaceV1::TokenDisposition::Active
+ : ActivationManagerInterfaceV1::TokenDisposition::Attention)
+ : ActivationManagerInterfaceV1::TokenDisposition::Attention;
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Expired activation tokens are accepted because the lookup computes disposition without checking `it->expiry.hasExpired()`. A token that has remained in `m_tokens` past its 60-second lifetime is consumed and activation proceeds as Active or Attention instead of being rejected as Invalid.
**Triggers:** When a client activates a committed token after its expiry deadline but before the periodic sweep removes it.
**Suggested fix:** Treat an expired iterator as invalid before reading its fields, or call the existing expiry validation logic during the single lookup.
</issue_to_address>
### Comment 2
<location path="examples/test-window-transition/CMakeLists.txt" line_range="1" />
<code_context>
+ Qt6::Gui
+ Qt6::Widgets
+ Qt6::WaylandClient
+ Qt6::GuiPrivate
+ Qt6::WaylandClientPrivate
+)
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The example links `Qt6::GuiPrivate` and `Qt6::WaylandClientPrivate` unconditionally, although those components are found only when Qt6 is at least 6.10. On older supported Qt6 versions the configure step references unavailable imported targets and the example cannot be configured or built.
**Triggers:** When configuring with Qt6 older than 6.10.
**Suggested fix:** Make the private-module links conditional as well, or require Qt6 6.10+ unconditionally before configuring this example.
```suggestion
find_package(Qt6 6.10 REQUIRED COMPONENTS Gui WaylandClient Widgets)
```
</issue_to_address>| auto it = std::find_if(m_tokens.begin(), m_tokens.end(), | ||
| [&token](const TokenInfo &t) { return t.token == token; }); | ||
| if (it != m_tokens.end()) { | ||
| tokenSeat = it->seat.data(); | ||
| m_tokens.erase(it); | ||
| originatingSurface = it->originatingSurface; | ||
| disposition = it->fromTrustedSurface | ||
| ? (it->serial.has_value() | ||
| ? ActivationManagerInterfaceV1::TokenDisposition::Active | ||
| : ActivationManagerInterfaceV1::TokenDisposition::Attention) | ||
| : ActivationManagerInterfaceV1::TokenDisposition::Attention; |
There was a problem hiding this comment.
issue (bug_risk): Expired activation tokens are accepted because the lookup computes disposition without checking it->expiry.hasExpired(). A token that has remained in m_tokens past its 60-second lifetime is consumed and activation proceeds as Active or Attention instead of being rejected as Invalid.
Triggers: When a client activates a committed token after its expiry deadline but before the periodic sweep removes it.
Suggested fix: Treat an expired iterator as invalid before reading its fields, or call the existing expiry validation logic during the single lookup.
| @@ -0,0 +1,30 @@ | |||
| find_package(Qt6 REQUIRED COMPONENTS Gui WaylandClient Widgets) | |||
There was a problem hiding this comment.
issue (bug_risk): The example links Qt6::GuiPrivate and Qt6::WaylandClientPrivate unconditionally, although those components are found only when Qt6 is at least 6.10. On older supported Qt6 versions the configure step references unavailable imported targets and the example cannot be configured or built.
Triggers: When configuring with Qt6 older than 6.10.
Suggested fix: Make the private-module links conditional as well, or require Qt6 6.10+ unconditionally before configuring this example.
| find_package(Qt6 REQUIRED COMPONENTS Gui WaylandClient Widgets) | |
| find_package(Qt6 6.10 REQUIRED COMPONENTS Gui WaylandClient Widgets) |
|
此 PR 不应被创建,已关闭。修复内容已通过 glyvut#8 交付。 |
feat(window-transition): implement window transition protocol
Add the server-side implementation of treeland-window-transition-unstable-v1,
which plays a window open/close transition relative to a source rectangle
attached to an xdg-activation token.
A client attaches a persistent transition rectangle (geometry plus an
optional source image) to an xdg_activation_token_v1 before committing the
token. At activation the compositor associates the rectangle with the target
window, animating from the rectangle's global position on open and back to it
on close. The rectangle stays alive, so set_geometry and set_source_buffer
update it immediately.
新增 treeland-window-transition-unstable-v1 的服务端实现,基于关联到
xdg-activation token 的源矩形播放窗口打开/关闭转场。
客户端在提交 token 前挂载一个持久的转场矩形(几何信息及可选源图像)。
激活时合成器将矩形关联到目标窗口,打开时从矩形的全局位置播放动画,
关闭时过渡回该矩形。矩形持续存活,set_geometry / set_source_buffer
可立即更新。
Code Review Fixes
All 4 review issues resolved:
wl_buffer.release— reverted to originalwlr_buffer_unlock(confirmed correct via wlroots source)#include <QtCore>fromsurfacewrapper.cpp(already hasQTimerandQVariant)WindowTransition.qml— replacedopacity: 0+Component.onCompletedwith direct bindingopacity: root.direction === 1 ? 1 : 0QtQuick.Effectsimport — no change needed (gated byenableBlurproperty)Note
This PR supersedes #1394 due to push permission limitations on the original fork (
glyvut/treeland). The branch is pushed todeepin-wm/treelandfork instead.WM-480
Summary by Sourcery
Implement server-side window transitions driven by persistent activation-token source rectangles and optional source images.
New Features:
Bug Fixes:
Enhancements:
Build:
Tests: