Conversation
There was a problem hiding this comment.
Sorry @deepin-wm, your pull request is larger than the review limit of 150,000 diff characters
|
[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 |
84c7804 to
9125186
Compare
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
f0482f5 to
50324cf
Compare
|
TAG Bot New tag: 0.9.1 |
59c3c86 to
f716da5
Compare
| } | ||
|
|
||
| struct wp_alpha_modifier_v1 *manager = | ||
| client_bind(&conn, "wp_alpha_modifier_v1", &wp_alpha_modifier_v1_interface, 1); |
There was a problem hiding this comment.
"wp_alpha_modifier_v1"应该可以使用wp_alpha_modifier_v1_interface中的name替代
|
|
||
| struct wp_alpha_modifier_v1 *manager = | ||
| client_bind(&conn, "wp_alpha_modifier_v1", &wp_alpha_modifier_v1_interface, 1); | ||
| if (!manager) { |
| struct wp_alpha_modifier_v1 *manager = | ||
| client_bind(&conn, "wp_alpha_modifier_v1", &wp_alpha_modifier_v1_interface, 1); | ||
| if (!manager) { | ||
| fprintf(stderr, "alpha-modifier: failed to bind wp_alpha_modifier_v1\n"); |
There was a problem hiding this comment.
使用wlr_log_errno,里面有strerror(errno)可以方便打印内存申请为什么报错
| wp_alpha_modifier_v1_get_surface(manager, tc.surface); | ||
| if (!am_surface) { | ||
| fprintf(stderr, "alpha-modifier: get_surface returned NULL\n"); | ||
| wp_alpha_modifier_v1_destroy(manager); |
|
|
||
| wp_alpha_modifier_surface_v1_destroy(am_surface); | ||
| wp_alpha_modifier_v1_destroy(manager); | ||
| xdg_toplevel_client_destroy(&tc); |
76414e8 to
2dab4c5
Compare
|
TAG Bot New tag: 0.10.0 |
403d794 to
aac6d2d
Compare
| add_subdirectory(treeland-wine-window-state-unstable-v1) | ||
| add_subdirectory(treeland-wine-window-management-unstable-v1) | ||
|
|
||
| # --- Standard wayland-protocols (1.49) served by Treeland --- |
There was a problem hiding this comment.
commit message 里写 “All 55 protocol tests pass”,但树对不上:父提交注册 44 个 add_subdirectory(去掉受 TREELAND_ENABLE_UINPUT_PROTOCOL_TESTS 保护的 uinput 是 43 个,与本地旧 build 的 ctest -N -L protocols 完全一致),本提交 +24 → 默认注册 67 个 target。43 + 24 = 67,55 这个数无法解释。
既然 add_headless_output 现在会显式 enable+commit output,请在本 PR 贴上全量 ctest --test-dir build -L protocols --output-on-failure 的结果(passed/skipped 数),并特别确认这两个既有测试没受影响:wlr-output-power-management-unstable-v1(断言 bind 后首个 mode == ON,直接依赖 output->enabled)和 wlr-output-management-unstable-v1。
There was a problem hiding this comment.
- 全量
ctest -L protocols的输出还没贴。这次改了共享 fixture(output 真的被 enable 了),请贴 passed/skipped 数,并给出wlr-output-power-management-unstable-v1(断言 bind 后首个mode == ON)的结果。 - commit body 里的 "C test client code follows wlroots coding style" 现在与实现不符——这一轮已把
wlr_log换成TEST_ERROR/fprintf+ 本地镜像枚举,建议改成 "plain C + fprintf",避免读者按 wlroots 风格去理解。
|
|
||
| auto *mgr = find_server_interface<WSecurityContextManager>(helper); | ||
| if (mgr) { | ||
| auto *g = static_cast<SecurityContextAccessor *>(mgr)->global(); |
There was a problem hiding this comment.
这里两个问题:
static_cast<SecurityContextAccessor *>(mgr)把一个实际类型为WSecurityContextManager的对象转成从未实例化过的派生类指针,是 UB(该类还是WObject+WServerInterface多继承 + 虚函数)。“为了让 protectedglobal()可见而造派生类”不是合法的下转。- 整条
global()→wl_global_get_user_data()链路是多余的:WServerInterface::handle()/nativeInterface<T>()是 public(waylib/src/server/kernel/wserver.h:36,44),并且WSecurityContextManager::create()里m_handle = wlr_security_context_manager_v1_create(...)(wsecuritycontextmanager.cpp:562),也就是和 global user_data 同一个指针(wl_global_create(..., manager, manager_bind),:494)。同 PR 的wayland-cursor-shape-v1/setup.cpp:63就已经用g_mgr->handle()了。
删掉 Accessor、global 查找和 wl_global_get_user_data(约 20 行):
auto *mgr = find_server_interface<WSecurityContextManager>(helper);
if (mgr) {
auto *wlr_mgr = static_cast<struct local_mgr *>(mgr->handle());
if (wlr_mgr)
wl_signal_add(&wlr_mgr->events.commit, &g_commit_listener);
}注意 local_mgr 不能改成 #include <wlr/types/wlr_security_context_v1.h>:waylib 在自己的 .cpp 里抄了一份结构(wsecuritycontextmanager.cpp:32),events 里比 vendored wlroots 头多一个 new_client。所以注释要改成“mirror of waylib/src/server/protocols/wsecuritycontextmanager.cpp:32”。真正干净的解法是把该 struct 挪进 waylib 的 _p.h,实现与测试共用一份定义——可开后续单。
There was a problem hiding this comment.
SecurityContextAccessor 和 UB 下转删除,改用 public mgr->handle()。改反:我明确写过不要用 #include <wlr/types/wlr_security_context_v1.h>,因为这行实现走的是 waylib 在 wsecuritycontextmanager.cpp:32 自抄的一份 struct(events 里比 vendored wlroots 头多一个 new_client)。现在测试用 vendored 头的类型去解释 waylib 分配的对象,见新评论。
| * on client-initiated unlock, so we only flush the request. */ | ||
| ext_session_lock_v1_unlock_and_destroy(lock); | ||
| wl_display_roundtrip(conn.display); | ||
| } else { |
There was a problem hiding this comment.
收到 finished 就静默通过,把 E 级断言变成了条件断言。而这个 fixture 里 finished 不应出现:Helper::onExtSessionLock() 只有在 m_lockScreen->isLocked() 时才 lock->finish()(src/seat/helper.cpp:3170-3173),协议测试进程里没有已锁定的锁屏。
当前写法的后果:哪天产品变成无条件拒绝锁屏(真回归),测试仍然绿。请至少改成失败:
} else {
wlr_log(WLR_ERROR, "ext-session-lock: compositor rejected the lock (finished)");
ext_session_lock_v1_destroy(lock);
failed = 1;
}如果确实要容忍该分支,请用框架已有的 skip 通道(return 77 / 输出 SKIP :),并在 README 的“已知边界”里写明,而不是 Pass。
There was a problem hiding this comment.
✅ 代码已修(finished → failed = 1,文件头注释同步)。❗文档没跟上:README.md:27 仍写 "此时测试回退到 P 级通过",INDEX.md:184 仍写 "允许 300ms grace timer 后收到 locked 或立即收到 finished"。行为变了就必须同步这两处(skill 里明说 coverage/边界变化要同时更新 README 与 INDEX)。
| // Attach a real pointer device so the seat advertises pointer capability | ||
| // and wl_seat_get_pointer yields a real wl_pointer resource for | ||
| // cursor/gesture/relative managers. | ||
| WSeat *seat = helper->seat(); |
There was a problem hiding this comment.
helper->seat() 没判空就直接 seat->attachInputDevice(device),而同一份“注入虚拟指针设备”的代码块在另外 3 个文件里都有 if (seat):wayland-cursor-shape-v1/setup.cpp:49、wayland-pointer-constraints-unstable-v1/setup.cpp:33、wayland-relative-pointer-unstable-v1/setup.cpp:30。
建议 4 份合并成一个框架函数(server-bridge.h):
void attach_test_pointer_device(Helper *helper); // 内部判空 + calloc + wlr_pointer_init + new WInputDevice(..., true) + attachInputDevicenew WInputDevice(&pointer->base, /*isVirtual=*/true) 与 waylib 既有先例一致(waylib/src/server/protocols/winputmethodhelper.cpp:416),这块逻辑本身没问题,只是不该抄 4 遍并留下一个漏判空的副本。
There was a problem hiding this comment.
seat->attachInputDevice(device) 被 if (seat) 包住,calloc + wlr_pointer_init + new WInputDevice 仍在 guard 外——seat 为空时照样造设备、照样不挂,只是把失败推迟到客户端断连超时报错,比原来更难查。fixture 应当断言生产对象存在(skill:assert that the production object is present),建议 Q_ASSERT(seat)。另外"4 份重复的指针设备注入"这一条完全没动(cursor-shape:49 / pointer-constraints:33 / relative-pointer:30 / 这里 :62 仍是 4 份)。
| .resumed = resumed, | ||
| }; | ||
|
|
||
| static int wait_for_idled( |
There was a problem hiding this comment.
这个文件和 wayland-ext-idle-notify-v1/*.c 是同一个测试写了两遍:idle_state、idled/resumed listener、wait_for_idled()(本文件 :66-84 与对方 :68-86 逐行相同)、seat listener、三步 inhibitor 状态机全部一致,只有日志前缀不同。约 200 行 ×2。
两个问题:
wait_for_idled、idle_state、seat listener 请挪进 framework(已有framework/xdg-toplevel-client.c这种共享 C helper 的先例)。- 既然两边都靠 ext-idle-notify 的
idled判断,idle-inhibit 这个 target 实际上没有断言自己的生产对象。建议让它回读 idle-inhibit 侧状态(inhibitor 是否挂在被抑制 surface 上),而不是再驱动一遍 ext-idle-notify——否则 24 个协议实际只有 23 个独立场景,INDEX 里也是两行相同描述。
另外 wait_for_idled() 里 elapsed += 50 与实际 poll 结果无关,且 ret < 0(EINTR)被忽略,长时间窗口下会空转;顺手把 if (ret > 0) 改成对 ret < 0 && errno == EINTR 的 continue 更稳。
There was a problem hiding this comment.
wait_for_idled 的 nit 已修(改成 CLOCK_MONOTONIC 真实计时 + EINTR continue + poll 出错返回 -1,两份都改了 👍)。但结构性问题未动:两个文件仍然各自定义一份 wait_for_idled/idle_state/seat listener,idle-inhibit 依然靠 ext-idle-notify 的 idled 判据,没有回读自己的生产对象。如果留到后续,请在 PR 描述或 TODO 里明确挂出来。
| #include <stdint.h> | ||
| #include <wlr/util/log.h> | ||
|
|
||
| static int read_server(struct alpha_modifier_server_state *state) { |
There was a problem hiding this comment.
本 PR +6048 行里,同一段代码被抄了很多遍(扫过 24 个目录的统计):
| 重复块 | 份数 |
|---|---|
static int read_server(...)(memset + invoke_on_server_thread + 判 0 + log) |
15 |
seat_caps/seat_name/seat_listener + g_caps |
9 |
| 虚拟指针设备注入 | 4 |
镜像 wlroots/waylib 结构的 .h |
24 |
这份就是 15 份 copy 之一(只有结构体类型不同)。建议按 framework/client-connection.h / framework/xdg-toplevel-client.c 的既有做法,在 framework 里补两样共享件:
bind_pointer_seat()(含 capability 断言,替掉 9 份 seat listener);- 一个
TEST_READ_SERVER(fn, ptr)宏或read_server_state(fn, void*, size_t)(内部 memset + invoke + 判 0 + log),把 15 份收敛成 15 次调用。
不要求在本 PR 做完,但 24 个协议不该等于 24 份样板,后续再加协议时这个成本会线性长。
There was a problem hiding this comment.
❌ 未处理(可接受为后续项,但请显式登记)。新 head 统计:read_server 仍 15 份、seat_listener 仍 9 份、指针设备注入仍 4 份、镜像结构 .h 仍 24 份。
| /* | ||
| * E-level readback: the production WPointerConstraintsV1 resolves the active | ||
| * constraint for the client's surface+seat via constraintForSurface(). The | ||
| * constraint type must be Locked (1), proving the lock_pointer request reached |
There was a problem hiding this comment.
注释与自身矛盾:这里写 "must be Locked (1)",而同文件 :20 和 :25 都写 0=Locked, 1=Confined,.c:114 断言的也是 != 0。enum wlr_pointer_constraint_v1_type(3rdparty/wlroots/include/wlr/types/wlr_pointer_constraints_v1.h)确实是 LOCKED=0。请改成 "Locked (0)"。
顺带建议 client 里用枚举名替代魔数(scanner 头里都有):ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT 已在 .c:101 用了魔数 1 + 注释、WL_SEAT_CAPABILITY_POINTER 在 .c:63 写成 0x1。同一模式在 cursor-shape、relative-pointer、primary-selection(g_caps & 2)等文件也有,用枚举名后注释就不可能写错。
There was a problem hiding this comment.
.h:17 改成 "Locked (0)",并新增 POINTER_CONSTRAINT_TYPE_LOCKED/CONFINED 供 client 断言使用(同时补了 .unlocked 立即解锁的负向断言,比原评审要求更严 👍)。未修:g_caps & 0x1(cursor-shape:63、pointer-constraints:75、relative-pointer:63、pointer-gestures:64)、g_caps & 2(primary-selection:128)、1 /* LIFETIME_ONESHOT */(:122)、1 /* CLIENT_SIDE */(xdg-decoration:82)仍是魔数——WL_SEAT_CAPABILITY_POINTER 来自 wayland-client-protocol.h(client-connection.h 已 include),这几处零成本。见 cursor-shape:63 的新评论。
| * globals served by Treeland (wlr_ext_image_copy_capture_manager_v1_create and | ||
| * wlr_ext_output_image_capture_source_manager_v1_create in Helper). | ||
| * The client binds both managers and verifies they are advertised by the | ||
| * compositor. (Creating a capture session in headless mode can deadlock in |
There was a problem hiding this comment.
两点:
- 即使绕开 swapchain,也能低成本多验一层:
ext_output_image_capture_source_manager_v1.create_source(output)(请求确认存在,见staging/ext-image-capture-source/ext-image-capture-source-v1.xml)+ 断言非空再 destroy。fixture 已经建好 headless output,这一步不碰会话,就能把“全局存在”升级成“output→source 工厂可用”。 - 注释说“创建捕获会话可能在
wlr_output_configure_primary_swapchain死锁”——这是疑似产品缺陷,只写在测试注释里等于没人跟进。建议开 issue 并把编号写在这里,同时同步到 INDEX 的“已知边界”。
There was a problem hiding this comment.
create_source(wl_output) + 非空断言 + destroy,并引用 issue #1407 记录 swapchain 死锁)。❗文档现在与代码相反:README.md 的"必须观察到的结果"仍列 create_session(source, 0) → buffer_size,"生产结果"写"启动 copy-capture 会话后,服务端下发 buffer_size……证明捕获源/会话路径完整接入输出"——测试根本没建会话(正是绕开死锁的原因);而 INDEX.md:72 又只写"验证全局存在"。README 与 INDEX 互相矛盾、且 README 描述的是未实现的行为,请改成实际断言(绑定 + create_source 非空),把 session/buffer_size 移到"已知边界"。顺带:这里 client_bind 取第一个 wl_output,xdg-output 用 client_bind_last,同一 fixture 两套取法,建议统一。
| } else if (!srv.valid) { | ||
| wlr_log(WLR_ERROR, "xdg-activation: no activateRequested captured"); | ||
| failed = 1; | ||
| } else if (srv.disposition == 0 /* Invalid */) { |
There was a problem hiding this comment.
disposition != Invalid 证明的东西很少(token 是自己刚申请来的,非 Invalid 基本是必然)。ActivationManagerInterfaceV1::activateRequested 的签名带了 surface 和 seat(src/modules/activation/activationmanagerinterfacev1.h:43-45):
void activateRequested(TokenDisposition disposition, WSurface *surface, WSeat *seat);所以回读结构里再带上 WSurface*,与 tc.surface 对应的生产 surface 比对,并断言 disposition 是具体的期望值(Success 而非“非 Invalid”),这才算 INDEX 里写的端到端业务结果。
There was a problem hiding this comment.
disposition == Attention(1) 并新增 surface_captured。期望值我核过,activationmanagerinterfacev1.cpp:236-241 在无 serial 时返回 Attention,测试不发 set_serial,所以是确定的。未做的部分:surface_captured 只证明"信号里带了个非空 surface",不证明它就是我们刚激活的 tc.surface;setup 里已经有 ShellHandler/WXdgToplevelSurface 那套捕获模式(alpha-modifier、xdg-dialog 都在用),比一次 g_surface_ptr == wrapper->surface() 就能把"激活到了正确窗口"钉死。
| if (outputs.isEmpty()) | ||
| return; | ||
|
|
||
| auto *woutput = outputs.first()->output(); |
There was a problem hiding this comment.
outputs.first() 隐含“测试进程里只有一个 output”。xdg-output 同(wayland-xdg-output-unstable-v1/setup.cpp:42)。本 PR 刚让 add_headless_output 真正 enable 了 output,一旦 fixture 或生产哪天多出一个 output,这两个断言就会对错对象,且失败信息看不出原因。
建议让 add_headless_output() 返回创建出的 WOutput *(现在只返回 bool),setup 里保存自己创建的那个再回读;顺带也能满足“E 级回读的对象必须是 fixture 自己造的”这一约定。
There was a problem hiding this comment.
add_headless_output 返回 WOutput *,两个测试改存 fixture 自己的 output),但引入两个新问题,见 setup.cpp:41 / xdg-output.c:84 的新评论:outputs.isEmpty() 变成装饰性检查 + 裸指针缓存;client 用 client_bind_last 猜 output、server 用 g_woutput,两边没有一致性校验。
aac6d2d to
2016163
Compare
2016163 to
d67d95b
Compare
| #include <wbackend.h> | ||
| #include <protocols/wsecuritycontextmanager.h> | ||
|
|
||
| #include <wlr/types/wlr_security_context_v1.h> |
There was a problem hiding this comment.
这一轮把 UB 下转修好了(改用 public mgr->handle() 👍),但把 local_mgr/local_state 换成了 vendored wlroots 的类型——这正是上轮评论里提醒不要做的方向。
运行时对象是 waylib 自己分配的那份:waylib/src/server/protocols/wsecuritycontextmanager.cpp:32 里有一份 struct wlr_security_context_manager_v1 的私有抄本,events 是 {destroy, commit, new_client};vendored 头(3rdparty/wlroots/include/wlr/types/wlr_security_context_v1.h)是 {destroy, commit}。今天两者 events.commit 都落在 offset 16,所以能跑;但这是巧合级别的兼容:waylib 那份在 commit 之前插字段、或 wlr_security_context_v1_state 调序,测试不会编译失败也不会报错,只会静默读错内存(app_id 读到别的指针,断言可能假通过)。原来至少有 local_* + 注释表达"这是人工同步的抄本",现在这个信号也没了。
建议(择一,成本都很低):
- 把 waylib 那份 struct 挪进
waylib/src/server/protocols/private/wsecuritycontextmanager_p.h,实现与测试 include 同一个定义(真正的单一事实来源,推荐); - 本 PR 先回退成
local_*抄本 + 注明"mirror of wsecuritycontextmanager.cpp:32,注意与 vendored 头不同(多一个new_client)",1 另开单子跟 waylib 侧收敛。
| if (outputs.isEmpty()) | ||
| return; | ||
|
|
||
| auto *woutput = g_woutput; |
There was a problem hiding this comment.
g_woutput 修好了"断错 output"的问题,但带来两个新的:
outputs.isEmpty()(:38)现在是装饰性检查:它校验的是 layout 的列表,而真正被读的是缓存指针。缓存的WOutput*变野时它拦不住。WOutput是 QObject 且有beforeDestroy()信号(waylib/src/server/kernel/woutput.h:34,110),所以一行就能自保:
static QPointer<WOutput> g_woutput; // + #include <QPointer>
...
auto *woutput = g_woutput.data();
if (!woutput)
return;或者反过来用 layout 校验身份:if (!container->outputs().contains(g_woutput)) return;,保留现有 guard 的意义。
- 上面那段
helper->rootSurfaceContainer()→outputs()的取数路径已经不再决定结果,可以整段删掉(只留 QPointer 的 null 检查),少一半样板。
wayland-xdg-output-unstable-v1/setup.cpp:44 同一模式,一并改。
| } | ||
|
|
||
| /* Bind the LAST wl_output global — it is the one created by protocol_test_setup. | ||
| * Using client_bind_last ensures the client reads the same WOutput that the |
There was a problem hiding this comment.
注释说 "Using client_bind_last ensures the client reads the same WOutput that the server-side read_server_state cross-checks via g_woutput"——这个 ensures 并不成立:client_bind_last(取 registry 里最后一个 wl_output global)和 g_woutput(setup 里 add_headless_output 返回的那个)是两个互相独立的猜测,没有任何一处校验它们指向同一个 output。今天只有一个 output 所以恒等;一旦 initTestCase 之后再有 output 产生(virtual-output、xwayland、dconf 热插拔),E 级断言就会拿 A 的几何去比 B 的事件——恰好是最难查的假通过。
要真正确认,得有一侧把身份传给另一侧,两种做法:
- fixture 侧收口(便宜):
xdg_output_read_server_state()里除了几何,再把wlr_output_get_name()(headless 是HEADLESS-n)填进回读结构,client 断言与它绑到的 global 名字一致——但 client 拿不到 wl_output 的 name 事件?其实可以:wl_output.name()事件就有,比一次 name 字符串即可。 - 至少加个响亮的守卫:setup 里
Q_ASSERT(container->outputs().size() == 1 && container->outputs().contains(g_woutput)),让"多于一个 output"直接失败而不是猜错。
另外 wayland-ext-image-copy-capture-v1/*.c:43 对同一个 fixture 的 wl_output 用的是 client_bind(第一个),这里用最后一个,两种取法并存容易误读,建议统一(image 那边选哪个都一样,不妨也用 _last)。
| wl_seat_add_listener(seat, &seat_listener, NULL); | ||
| wl_display_roundtrip(conn.display); | ||
|
|
||
| if (!(g_caps & 0x1 /* WL_SEAT_CAPABILITY_POINTER */)) { |
There was a problem hiding this comment.
同一模式还剩 5 处魔数没换成枚举名(本行 + :pointer-constraints:75、relative-pointer:63、pointer-gestures:64 的 g_caps & 0x1;primary-selection:128 的 g_caps & 2;pointer-constraints:122 的 1 /* LIFETIME_ONESHOT */、xdg-decoration:82 的 1 /* CLIENT_SIDE */)。
WL_SEAT_CAPABILITY_POINTER / WL_SEAT_CAPABILITY_KEYBOARD 来自 wayland-client-protocol.h,client-connection.h 已经 include 了 <wayland-client.h>,不需要任何额外依赖;ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT、ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE 在各自生成的 client-protocol 头里,也都已经 include。值都是对的,纯一致性/可读性问题,但既然本次已经为 constraint type 建了 POINTER_CONSTRAINT_TYPE_LOCKED 这种本地镜像枚举,用现成的生成枚举更省事。
| TEST_ERROR("xdg-toplevel-tag: no mapped SurfaceWrapper captured\n"); | ||
| failed = 1; | ||
| } else if (strcmp(server.tag, TEST_TAG) != 0) { | ||
| TEST_ERROR("xdg-toplevel-tag: real tag \"%s\" != \"%s\"", server.tag, TEST_TAG); |
There was a problem hiding this comment.
本 PR 全部 TEST_ERROR 调用里唯一漏 的一处(其余都带)。失败时这行会和后续 stderr( compositor 日志 / QTest 输出)拼在同一行,日志检索时会很难看:
TEST_ERROR("xdg-toplevel-tag: real tag \"%s\" != \"%s\"\n", server.tag, TEST_TAG);Add comprehensive E-level (end-to-end) and P-level (protocol-level) tests for all 24 standard wayland-protocols served by Treeland/wlroots at runtime, plus xdg-shell coverage via shared fixture. Coverage breakdown: - 23 E-level tests (end-to-end business-level with production state readback) - 1 P-level test (ext-image-copy-capture-v1, blocked by headless GPU limitation) E-level tests verify real production state through: - wlroots handle readback (wlr_seat, wlr_idle_notifier, wlr_pointer_gestures) - wl_resource_get_user_data for protocols with private d-pointer handles - SurfaceWrapper shellSurface() dynamic_cast for xdg-foreign parent readback - ShellHandler::surfaceWrapperAdded signal for surface lifecycle tracking Protocols covered (24 tested + 1 implicit): alpha-modifier, cursor-shape, ext-data-control, ext-foreign-toplevel-list, ext-idle-notify, ext-image-copy-capture, ext-session-lock, fractional-scale, idle-inhibit, pointer-constraints, pointer-gestures, primary-selection, relative-pointer, security-context, single-pixel-buffer, text-input-v1, text-input-v3, viewporter, xdg-activation, xdg-decoration, xdg-dialog, xdg-foreign, xdg-output, xdg-toplevel-tag, (xdg-shell implicit) All 67 protocol tests pass in headless CI (WLR_BACKENDS=headless, WLR_RENDERER=pixman). C test client code uses plain C + fprintf. 为 wayland-protocols 全部 24 个标准协议添加 E 级与 P 级测试覆盖, 复用 PR linuxdeepin#1297 建立的测试框架与 wayland-protocol-test skill。 Log: 扩展协议测试覆盖至全部标准 wayland 协议 Influence: 新增 24 个标准协议测试,无头 CI 全部通过,增强协议回归保障。
d67d95b to
3237285
Compare
Summary
Add 24 standard wayland-protocols tests covering every protocol Treeland provides at runtime via wlroots (wayland-protocols 1.49.0-1).
Coverage levels
E-level tests
Each E-level test reads real production object state over the server bridge and cross-checks it against client-side protocol observation:
logical_position/logical_sizevs realWOutput::position()/effectiveSize()SurfaceWrapper::modal()flips false → true afterset_modalWXdgToplevelSurface::tag()equals client-set valueWOutput::scale()vspreferred_scale(round(scale×120))wlr_surface::current.buffer_width/height== 1×1 on mapped toplevelwlr_surface::current.viewportdst state afterset_destination(320,240)wlr_alpha_modifier_surface_v1_state::multipliertransitions 0.0 → 1.0WSessionLock::isLocked()== true afterlockedeventTest results
All 24 tests pass on headless backend (WLR_BACKENDS=headless, WLR_RENDERER=pixman).
Closes #1332 (resubmitted with correct commit author).
Multica: WM-328