feat(treeland-debug): add adb-style window control, events and capture - #1280
feat(treeland-debug): add adb-style window control, events and capture#1280deepin-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 GuideExtends treeland-debug and the WindowTreeRemote debug source into an adb-style inspector/controller with window listing and control, client grouping, input event injection, image capture, and interactive shell/top modes, including necessary helper APIs and documentation updates. Sequence diagram for treeland-debug adb-style screenshot commandsequenceDiagram
actor User
participant TreelandDebug as treeland-debug
participant Replica as WindowTreeRemoteReplica
participant Source as TreelandRemoteSource
participant Helper as Helper
User->>TreelandDebug: run "screenshot window <id> [file]"
TreelandDebug->>Replica: captureWindow(id, filePath)
Replica->>Source: captureWindow(id, filePath)
Source->>Helper: rootSurfaceContainer()
Source->>Source: findSurfaceById(id)
Source->>Source: grabToImage(content, image)
Source->>Source: saveImage(image, filePath)
Source-->>Replica: return savedFilePath
Replica-->>TreelandDebug: return savedFilePath
TreelandDebug-->>User: print savedFilePath
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
TAG Bot New tag: 0.8.18 |
|
|
||
| uint32_t currentTimeMs() | ||
| { | ||
| return static_cast<uint32_t>(QDateTime::currentMSecsSinceEpoch() & 0xFFFFFFFF); |
| loop.exec(); | ||
| if (!watcher.isFinished()) | ||
| return false; | ||
| try { |
There was a problem hiding this comment.
这个函数会出异常吗,Qt应该不会抛出异常吧,有必要用try catch吗
| return !out->isNull(); | ||
| } | ||
|
|
||
| QString saveImage(const QImage &image, QString filePath) |
There was a problem hiding this comment.
server端不做文件存储,通过remote object或共享内存把数据给treeland-debug客户端,它自己保存
| int z) const | ||
| { | ||
| WindowInfo info; | ||
| info.setId(reinterpret_cast<qint64>(surface)); |
There was a problem hiding this comment.
我觉得应该用其对应的 wl_surface 的 wl_resource 资源id
| pid_t pid = 0; | ||
| uid_t uid = 0; | ||
| gid_t gid = 0; | ||
| wl_client_get_credentials(client, &pid, &uid, &gid); |
| } | ||
|
|
||
| for (const auto &entry : std::as_const(entries)) { | ||
| ClientInfo info; |
There was a problem hiding this comment.
ClientInfo里加上appid,我看现在是在window 里,应该是在clientinfo里,window可以通过自己的clientinfo拿到
| if (!m_instance || !m_renderWindow || !m_backend) | ||
| return false; | ||
|
|
||
| emitInputDebugEvent(watched, event); |
There was a problem hiding this comment.
不要这样,如果有需要,remote debug的实现方可以直接加事件过滤器。
|
|
||
| void currentModeChanged(); | ||
| void noAnimationChanged(); | ||
|
|
Address the inline review comments on PR linuxdeepin#1280 and make sure the debug source has no side effects and no resource consumption while no treeland-debug client is connected. - helper.{h,cpp}: remove the debugInputEvent signal and the emitInputDebugEvent hook in afterHandleEvent. The debug source now observes input events through its own event filter instead of coupling debug logic into the core seat event path. Restore the blank line that this PR had removed unrelatedly (review linuxdeepin#7, linuxdeepin#8). - treelandremotesource.{h,cpp}: the event filter is installed on the render window only while a client is actively polling getEvents() (5s idle tear-down), so there is zero per-event work when nobody is monitoring. cursorPosition() reads the live cursor on demand instead of keeping a WCursor::positionChanged connection, removing lingering pointer-motion overhead after a client disconnects. - The window id is now the wl_surface wl_resource id, not the SurfaceWrapper pointer (review linuxdeepin#4). - getClients() uses WClient::credentials()/appId() instead of wl_client_get_credentials, and ClientInfo now carries appId (review linuxdeepin#5, linuxdeepin#6). - capture{Output,Window,Screen} return PNG QByteArray to the client, which writes the file; the compositor no longer stores files (review linuxdeepin#3). grabToImage() no longer wraps result() in try/catch, since Qt does not throw (review linuxdeepin#2). The currentTimeMs() helper is dropped in favour of QDateTime::currentMSecsSinceEpoch(), matching waylib (review linuxdeepin#1). - README/README.zh_CN: document the wl_resource id, ClientInfo.appId, the frames/damage fields, and that the client (not the compositor) saves screenshots.
Code Review:
|
Code Review:
|
Code Review: 窗口 ID 非全局唯一,
|
Code Review:
|
Code Review: shell 模式下
|
Code Review:
|
Code Review:
|
Code Review:
|
f089626 to
167dc77
Compare
Address the inline review comments on PR linuxdeepin#1280 and make sure the debug source has no side effects and no resource consumption while no treeland-debug client is connected. - helper.{h,cpp}: remove the debugInputEvent signal and the emitInputDebugEvent hook in afterHandleEvent. The debug source now observes input events through its own event filter instead of coupling debug logic into the core seat event path. Restore the blank line that this PR had removed unrelatedly (review linuxdeepin#7, linuxdeepin#8). - treelandremotesource.{h,cpp}: the event filter is installed on the render window only while a client is actively polling getEvents() (5s idle tear-down), so there is zero per-event work when nobody is monitoring. cursorPosition() reads the live cursor on demand instead of keeping a WCursor::positionChanged connection, removing lingering pointer-motion overhead after a client disconnects. - The window id is now the wl_surface wl_resource id, not the SurfaceWrapper pointer (review linuxdeepin#4). - getClients() uses WClient::credentials()/appId() instead of wl_client_get_credentials, and ClientInfo now carries appId (review linuxdeepin#5, linuxdeepin#6). - capture{Output,Window,Screen} return PNG QByteArray to the client, which writes the file; the compositor no longer stores files (review linuxdeepin#3). grabToImage() no longer wraps result() in try/catch, since Qt does not throw (review linuxdeepin#2). The currentTimeMs() helper is dropped in favour of QDateTime::currentMSecsSinceEpoch(), matching waylib (review linuxdeepin#1). - README/README.zh_CN: document the wl_resource id, ClientInfo.appId, the frames/damage fields, and that the client (not the compositor) saves screenshots.
Expand treeland-debug from a read-only window-tree inspector into an adb-style tool supporting both shell (interactive REPL) and non-shell (one-shot subcommand) modes. Server side (treelandwindowtree.rep + TreelandRemoteSource): - add a stable window id and a flat getWindows() list - add getClients() enumerating connected Wayland clients (pid/executable) together with the toplevel windows each one owns - add window control: activate/close/minimize/maximize/fullscreen/move/ resize/set-workspace, resolved by stable id - add input injection: moveCursor, sendPointerButton, sendKey - add image capture: captureOutput/captureWindow/captureScreen via the existing GPU texture read-back, written to a PNG file - expose Helper::server() so the source can enumerate wl_display clients Client side (tools/treeland-debug): - subcommand CLI: tree/cursor/windows/clients/top, window control, event, screenshot, shell, with global --url/--name/--timeout-ms/--json - interactive `shell` REPL and a live, top-like refreshing `top` view - window/clients accept a numeric id or an appId as the control target - `listen` subcommand: optional HTTP/WebSocket server (Qt6::HttpServer/ WebSockets, guarded by CMake so the build still passes without them) - back compatible: --tree/--cursor still behave as before - unit tests covering parseCommand and all subcommands; documented in README
167dc77 to
1881c1d
Compare
Summary
Extend
treeland-debuginto an adb-style tool: window control (move workspace, minimize, maximize, fullscreen, resize, close), event injection (cursor move, pointer button, key), screen capture (grabToImage), plusshellandtopmodes for live client/window inspection.Changes
treelandwindowtree.rep— newWindowTreeRemoteslots:setWindowWorkspace,minimize,maximize,fullscreen,resize,close,moveCursor,sendPointerButton,sendKey,grabToImage,getClients,getCursorPos.treelandremotesource.{h,cpp}— server-side implementations with full null-safety (surface, seat, keyboard handle, content).setWindowWorkspaceusesWorkspace::moveSurfaceTo(handles remove→add, transient children, modal parent);moveCursorroutes throughHelper::setCursorPosition(ends in-progress move/resize).grabToImagehas a 5 s timeout guard with a documented main-thread nested-QEventLoopreentry risk (acceptable for opt-in debug source).helper.{h,cpp}—setCursorPositionmoved from private to public.tools/treeland-debug/main.cpp— new subcommands (workspace,minimize,maximize,fullscreen,resize,close,cursor,click,key,grab,shell,top),--timeout-mswith validation,--tree/--cursorbackward compat.README.md— updated usage docs.Commits
feat(treeland-debug): add adb-style window control, events and capturefix(treeland-debug): address code review (workspace move, cursor, nits)Testing
Built with
cmake --preset=ci(-Wall -Wextra -Werror) —libtreeland+treeland-debug, no warnings.--helpand connection-failure paths smoke-tested.Review
Code review passed (✅). All blocking and suggested items addressed:
setWindowWorkspace→Workspace::moveSurfaceTowith target validationmoveCursor→Helper::setCursorPositiongrabToImage→ documented reentry risksaveImageempty-if,--timeout-msvalidation,runShellcopy — all fixedworkspaceId() < 0guard narrowed to== -1soShowOnAllWorkspaceId(-2) windows are not rejectedMultica issue: WM-254 (
2d5cd7f2-24d6-4b50-b82a-6d6c456c65cf)Summary by Sourcery
Turn treeland-debug into a comprehensive local and network-capable Treeland inspection and control tool.
New Features:
Enhancements:
Build:
Documentation:
Tests: