Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/test_set_xwindow_position/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ qt_add_executable(test-set-xwindow-position

qt_generate_wayland_protocol_client_sources(test-set-xwindow-position
FILES
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-dde-shell-v1.xml
${TREELAND_PROTOCOLS_DATA_DIR}/treeland-xwindow-control-unstable-v1.xml
NO_INCLUDE_CORE_ONLY
)

Expand Down
28 changes: 16 additions & 12 deletions examples/test_set_xwindow_position/main.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
// Copyright (C) 2025 UnionTech Software Technology Co., Ltd.
// Copyright (C) 2025-2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include <QDebug>

Check warning on line 4 in examples/test_set_xwindow_position/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDebug> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QFile>
#include <QGuiApplication>
#include <QtWidgets/QtWidgets>
#include <QtWaylandClient/QWaylandClientExtension>
#include <QTimer>

#include <qpa/qplatformnativeinterface.h>

Check warning on line 11 in examples/test_set_xwindow_position/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qpa/qplatformnativeinterface.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <qwayland-treeland-dde-shell-v1.h>
#include <qwayland-treeland-xwindow-control-unstable-v1.h>

Check warning on line 13 in examples/test_set_xwindow_position/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwayland-treeland-xwindow-control-unstable-v1.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <cstdlib>

Check warning on line 15 in examples/test_set_xwindow_position/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <cstdlib> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unistd.h>

Check warning on line 16 in examples/test_set_xwindow_position/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <unistd.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

class DDEShellManagerV1
: public QWaylandClientExtensionTemplate<DDEShellManagerV1>
, public QtWayland::treeland_dde_shell_manager_v1
class XWindowControlV1
: public QWaylandClientExtensionTemplate<XWindowControlV1>
, public QtWayland::treeland_xwindow_control_v1
{
Q_OBJECT
public:
DDEShellManagerV1()
: QWaylandClientExtensionTemplate<DDEShellManagerV1>(
treeland_dde_shell_manager_v1_interface.version)
XWindowControlV1()
: QWaylandClientExtensionTemplate<XWindowControlV1>(
treeland_xwindow_control_v1_interface.version)
{
}
};
Expand Down Expand Up @@ -71,7 +71,7 @@
return 1;
}

DDEShellManagerV1 manager;
XWindowControlV1 control;

struct wl_callback_listener callback_listener = { .done = []([[maybe_unused]] void *data,
wl_callback *callback,
Expand All @@ -85,8 +85,8 @@

QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&] {
if (!manager.isActive()) {
qCritical() << "DDEShellManagerV1 is not active!";
if (!control.isActive()) {
qCritical() << "XWindowControlV1 is not active!";
return;
}
struct wl_surface *surface = static_cast<wl_surface *>(
Expand All @@ -97,7 +97,11 @@
wl_fixed_t dx = wl_fixed_from_int(640);
wl_fixed_t dy = wl_fixed_from_int(0);

wl_callback *callback = manager.set_xwindow_position_relative(wid, surface, dx, dy);
wl_callback *callback = control.set_xwindow_position_relative(wid, surface, dx, dy);
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
if (!callback) {
qCritical() << "Failed to send set_xwindow_position_relative request!";
return;
}
wl_callback_add_listener(callback, &callback_listener, nullptr);
qWarning() << "Setting xwindow position relative, wait for result...";
});
Expand Down
1 change: 1 addition & 0 deletions src/modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_subdirectory(personalization)
add_subdirectory(shortcut)
add_subdirectory(wallpaper-color)
add_subdirectory(show-desktop)
add_subdirectory(xwindow-control)
add_subdirectory(virtual-output)
add_subdirectory(dde-shell)
add_subdirectory(capture)
Expand Down
18 changes: 1 addition & 17 deletions src/modules/dde-shell/ddeshellmanagerinterfacev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

#include "ddeshellmanagerinterfacev1.h"

#include "qwayland-server-treeland-dde-shell-v1.h"

Check warning on line 6 in src/modules/dde-shell/ddeshellmanagerinterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "qwayland-server-treeland-dde-shell-v1.h" not found.

#include "helper.h"
#include <wsurface.h>

Check warning on line 8 in src/modules/dde-shell/ddeshellmanagerinterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wsurface.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <woutput.h>

Check warning on line 10 in src/modules/dde-shell/ddeshellmanagerinterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <woutput.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <wayland-server.h>

Expand All @@ -34,11 +34,9 @@
void get_treeland_multitaskview(Resource *resource, uint32_t id) override;
void get_treeland_window_picker(Resource *resource, uint32_t id) override;
void get_treeland_lockscreen(Resource *resource, uint32_t id) override;
void set_xwindow_position_relative(Resource *resource, uint32_t callback, uint32_t wid,
struct ::wl_resource *anchor, wl_fixed_t dx, wl_fixed_t dy) override;
};

void DDEShellManagerInterfaceV1Private::get_treeland_lockscreen(Resource *resource,

Check warning on line 39 in src/modules/dde-shell/ddeshellmanagerinterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'get_treeland_lockscreen' is never used.
uint32_t id)
{
wl_resource *lockscreen_resource = wl_resource_create(resource->client(),
Expand All @@ -59,20 +57,6 @@
Q_EMIT q->lockScreenCreated(lockScreen);
}

void DDEShellManagerInterfaceV1Private::set_xwindow_position_relative(Resource *resource,
uint32_t callback,
uint32_t wid,
struct ::wl_resource *anchor,
wl_fixed_t dx,
wl_fixed_t dy)
{
WSurface *wsurface = WSurface::fromHandle(wlr_surface_from_resource(anchor));
uint32_t ok = (wsurface && Helper::instance()->setXWindowPositionRelative(wid, wsurface, dx, dy)) ? 0 : 1;
wl_resource *cb = wl_resource_create(resource->client(), &wl_callback_interface, 1, callback);
wl_callback_send_done(cb, ok);
wl_resource_destroy(cb);
}

DDEShellManagerInterfaceV1Private::DDEShellManagerInterfaceV1Private(DDEShellManagerInterfaceV1 *_q)
: QtWaylandServer::treeland_dde_shell_manager_v1()
, q(_q)
Expand Down
20 changes: 20 additions & 0 deletions src/modules/xwindow-control/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
find_package(TreelandProtocols REQUIRED)

waylib_generate_qtwayland_server_protocol(libtreeland
PROTOCOL ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-xwindow-control-unstable-v1.xml
BASENAME treeland-xwindow-control-unstable-v1
)

impl_treeland(
NAME
module_xwindow_control
SOURCE
${CMAKE_SOURCE_DIR}/src/modules/xwindow-control/xwindowcontrolinterfacev1.h
${CMAKE_SOURCE_DIR}/src/modules/xwindow-control/xwindowcontrolinterfacev1.cpp
LINK
Wlroots::wlroots
Waylib::WaylibServer
Qt6::Core
Qt6::Gui
Qt6::Quick
)
92 changes: 92 additions & 0 deletions src/modules/xwindow-control/xwindowcontrolinterfacev1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (C) 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "xwindowcontrolinterfacev1.h"
#include "qwayland-server-treeland-xwindow-control-unstable-v1.h"

Check warning on line 5 in src/modules/xwindow-control/xwindowcontrolinterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "qwayland-server-treeland-xwindow-control-unstable-v1.h" not found.

#include "seat/helper.h"

#include <wserver.h>
#include <wsurface.h>

#include <wayland-server-core.h>

#include <cstring>

class XWindowControlInterfaceV1Private : public QtWaylandServer::treeland_xwindow_control_v1
{
public:
XWindowControlInterfaceV1Private(XWindowControlInterfaceV1 *_q);
wl_global *global() const;

XWindowControlInterfaceV1 *q;

protected:
void destroy(Resource *resource) override;
void set_xwindow_position_relative(Resource *resource, uint32_t callback, uint32_t wid,
struct ::wl_resource *anchor, wl_fixed_t dx, wl_fixed_t dy) override;
};

XWindowControlInterfaceV1Private::XWindowControlInterfaceV1Private(XWindowControlInterfaceV1 *_q)
: QtWaylandServer::treeland_xwindow_control_v1()
, q(_q)
{
}

wl_global *XWindowControlInterfaceV1Private::global() const
{
return m_global;
}

void XWindowControlInterfaceV1Private::destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}

void XWindowControlInterfaceV1Private::set_xwindow_position_relative(Resource *resource,
uint32_t callback,
uint32_t wid,
struct ::wl_resource *anchor,
wl_fixed_t dx,
wl_fixed_t dy)
{
WSurface *wsurface = nullptr;
if (anchor && strcmp(wl_resource_get_class(anchor), "wl_surface") == 0)
wsurface = WSurface::fromHandle(wlr_surface_from_resource(anchor));
uint32_t ok = (wsurface && Helper::instance()->setXWindowPositionRelative(wid, wsurface, dx, dy)) ? 0 : 1;
wl_resource *cb = wl_resource_create(resource->client(), &wl_callback_interface, 1, callback);
if (!cb) {
wl_client_post_no_memory(resource->client());
return;
}
wl_callback_send_done(cb, ok);
wl_resource_destroy(cb);
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
}

XWindowControlInterfaceV1::XWindowControlInterfaceV1(QObject *parent)
: QObject(parent)
, d(new XWindowControlInterfaceV1Private(this))
{
}

XWindowControlInterfaceV1::~XWindowControlInterfaceV1() = default;

void XWindowControlInterfaceV1::create(WServer *server)
{
d->init(server->handle(), InterfaceVersion);
}

void XWindowControlInterfaceV1::destroy([[maybe_unused]] WServer *server)
{
d->globalRemove();
}

wl_global *XWindowControlInterfaceV1::global() const
{
return d->global();
}

QByteArrayView XWindowControlInterfaceV1::interfaceName() const
{
return d->interfaceName();
}
34 changes: 34 additions & 0 deletions src/modules/xwindow-control/xwindowcontrolinterfacev1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#pragma once

#include <wserver.h>

#include <QQmlEngine>

WAYLIB_SERVER_USE_NAMESPACE

class XWindowControlInterfaceV1Private;
class XWindowControlInterfaceV1
: public QObject
, public WAYLIB_SERVER_NAMESPACE::WServerInterface
{
Q_OBJECT

public:
explicit XWindowControlInterfaceV1(QObject *parent = nullptr);
~XWindowControlInterfaceV1() override;

QByteArrayView interfaceName() const override;

static constexpr int InterfaceVersion = 1;

protected:
void create(WServer *server) override;
void destroy(WServer *server) override;
wl_global *global() const override;

private:
std::unique_ptr<XWindowControlInterfaceV1Private> d;
};
1 change: 1 addition & 0 deletions src/seat/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1931,6 +1931,7 @@ void Helper::init(Treeland::Treeland *treeland)
&SessionManager::syncActiveSessionXWaylandPrimaryOutput);
m_wallpaperColorV1 = m_server->attach<WallpaperColorInterfaceV1>();
m_showDesktopInterfaceV1 = m_server->attach<ShowDesktopInterfaceV1>();
m_xWindowControlInterfaceV1 = m_server->attach<XWindowControlInterfaceV1>();
m_virtualOutputInterfaceV1 = m_server->attach<VirtualOutputManagerInterfaceV1>();

auto captureManagerV1 = m_server->attach<CaptureManagerV1>();
Expand Down
2 changes: 2 additions & 0 deletions src/seat/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "modules/wallpaper/wallpapermanagerinterfacev1.h"
#include "modules/wallpaper/wallpapernotifierinterfacev1.h"
#include "modules/show-desktop/showdesktopinterfacev1.h"
#include "modules/xwindow-control/xwindowcontrolinterfacev1.h"
#include "utils/fpsdisplaymanager.h"

#include <xcb/xproto.h>
Expand Down Expand Up @@ -471,6 +472,7 @@ private Q_SLOTS:
WOutputManagerV1 *m_outputManager = nullptr;
WXdgOutputManager *m_xwaylandOutputManager = nullptr;
ShowDesktopInterfaceV1 *m_showDesktopInterfaceV1 = nullptr;
XWindowControlInterfaceV1 *m_xWindowControlInterfaceV1 = nullptr;
ShowDesktopInterfaceV1::State m_showDesktop = ShowDesktopInterfaceV1::State::Normal;
DDEShellManagerInterfaceV1 *m_ddeShellV1 = nullptr;
VirtualOutputManagerInterfaceV1 *m_virtualOutputInterfaceV1 = nullptr;
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_subdirectory(test_protocol_shortcut)
add_subdirectory(test_protocol_virtual-output)
add_subdirectory(test_protocol_wallpaper-color)
add_subdirectory(test_protocol_show-desktop)
add_subdirectory(test_protocol_xwindow-control)
add_subdirectory(test_protocol_prelaunch-splash)
add_subdirectory(test_protocol_pointerconstraints)
add_subdirectory(test_effect_glass)
Expand Down
1 change: 1 addition & 0 deletions tests/protocols/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ add_subdirectory(treeland-wallpaper-manager-unstable-v1)
add_subdirectory(treeland-wallpaper-shell-unstable-v1)
add_subdirectory(treeland-wallpaper-desktop-v1)
add_subdirectory(treeland-show-desktop-v1)
add_subdirectory(treeland-xwindow-control-unstable-v1)
Comment thread
wineee marked this conversation as resolved.
add_subdirectory(treeland-show-desktop-desktop-v1)
add_subdirectory(treeland-wine-window-state-unstable-v1)
add_subdirectory(treeland-wine-window-management-unstable-v1)
3 changes: 2 additions & 1 deletion tests/protocols/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Wayland 线上请求与事件;本文档规定发出请求后,测试必须观
| [wallpaper-shell-unstable-v1](treeland-wallpaper-shell-unstable-v1/README.md) | I / P | wallpaper shell 与 notifier 生命周期 |
| [wallpaper desktop 联合路径](treeland-wallpaper-desktop-v1/README.md) | P / E | manager 配置、shell surface 与真实 output 的关联 |
| [show-desktop-v1](treeland-show-desktop-v1/README.md) | E / P | show-desktop 隐藏并恢复真实窗口 |
| [treeland-xwindow-control-unstable-v1](treeland-xwindow-control-unstable-v1/README.md) | P | `set_xwindow_position_relative` 失败回调;成功路径需 Xwayland,当前环境未覆盖 |
| [wine-window-management-unstable-v1](treeland-wine-window-management-unstable-v1/README.md) | P / E | 真实 wrapper 的位置与置顶层同步 |
| [wine-window-state-unstable-v1](treeland-wine-window-state-unstable-v1/README.md) | P / E | 真实 wrapper 的最小化、attention 与可见性同步 |
| [drm (`wl_drm`)](drm/README.md) | P / V(GPU 条件) | wlroots native global、GBM DMA-BUF 与真实纹理 readback |
Expand Down Expand Up @@ -78,7 +79,7 @@ request stub 算作 request 覆盖;生成的 client-protocol 文件本身不
| --- | --- | --- | --- |
| app-id-resolver-v1 | 4 / 4 | `identify_request` 的 id、真实 pidfd;`respond` 转换同一 splash wrapper 并写入 app-id | resolver 断开 fallback、sandbox 后续策略、XWayland |
| capture-unstable-v1 | 8 / 11 | `source_ready/failed`、`buffer/buffer_done/ready/failed`;64×64 红色像素读回 | session 的 `start/frame_done`,及 `frame/object/ready/cancel` 持久流;OUTPUT/REGION、cursor、mask |
| dde-shell-v1 | 26 / 27 | checker/active/picker 事件;真实 wrapper DDE 元数据、lockscreen、picker PID | `set_xwindow_position_relative`;multitask 只证明 `toggle` 请求/信号,未证明真实 UI 状态;`shutdown/switch_user` 外部会话流程 |
| dde-shell-v1 | 26 / 27 | checker/active/picker 事件;真实 wrapper DDE 元数据、lockscreen、picker PID | multitask 只证明 `toggle` 请求/信号,未证明真实 UI 状态;`shutdown/switch_user` 外部会话流程(`set_xwindow_position_relative` 已迁移至 `treeland-xwindow-control-unstable-v1`) |
| ddm-v1 | 0 / 7 | 无未请求 VT event;生产连接生命周期 | 所有会话/渲染控制 request 与 `switch_to_vt/acquire_vt` 的实际系统流程 |
| foreign-toplevel-manager-v2 | 16 / 16 | `toplevel/identifier/closed`;真实最小化、最大化、全屏、焦点与 icon rectangle;最小化与布局状态正交(含取消布局后不卡在最小化) | `pid/title/app_id/output_enter/output_leave/state/done/parent` payload;指定 `wl_output` 的 fullscreen hint、preview 像素;`Tiling` 组合 |
| input-manager-unstable-v1 | 1 / 22 | 默认测试仅证明空设备 manager 可绑定;uinput target 断言 Keyboard capability 热插拔 | settings/apply、真实 mouse/touchpad 配置生效、无设备 failed;uinput E 层需显式启用并实际执行 |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

treeland_add_protocol_test(
NAME treeland_xwindow_control_v1
XML "${TREELAND_PROTOCOLS_DATA_DIR}/treeland-xwindow-control-unstable-v1.xml"
SETUP "${CMAKE_CURRENT_SOURCE_DIR}/setup.cpp"
CLIENT "${CMAKE_CURRENT_SOURCE_DIR}/treeland-xwindow-control-unstable-v1.c"
)
40 changes: 40 additions & 0 deletions tests/protocols/treeland-xwindow-control-unstable-v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# `treeland-xwindow-control-unstable-v1` 测试规范

## 范围

- XML / interface:`treeland_xwindow_control_v1`(v1)
- 测试源码:`tests/protocols/treeland-xwindow-control-unstable-v1/`
- Fixture:`protocol_test_setup` 注册生产 `XWindowControlInterfaceV1` 全局并创建
headless output(仅协议/资源级,无需 mapped 窗口)
- 覆盖等级:**P**

## 必须观察到的结果

| 场景 | 客户端动作 | 必须观察到的结果 | 证据层级 |
| --- | --- | --- | --- |
| 初始化 | bind `treeland_xwindow_control_v1` | manager 非空 | P |
| 请求(失败) | `set_xwindow_position_relative`,anchor 为无对应 `SurfaceWrapper` 的裸 `wl_surface`、wid=0 | `wl_callback.done(1)` | P |
| 资源销毁 | `destroy` | 资源销毁,无协议错误 | P |

## 生产结果

`set_xwindow_position_relative` 在服务端解析 anchor `wl_surface` 为 `WSurface`,再交给
`Helper::setXWindowPositionRelative(wid, wsurface, dx, dy)`。失败路径测试证明:当 anchor
`wl_surface` 没有 `SurfaceWrapper`(裸 surface)且 wid 为 0 时,`Helper` 返回 false,
服务端把结果 `1` 通过新建的 `wl_callback` 回传并销毁该 callback。

`XWindowControlInterfaceV1Private` 在 `wl_resource_create` 分配 callback 失败时会调用
`wl_client_post_no_memory` 并中止该请求,避免对 null callback 解引用导致合成器崩溃;该
OOM 分支不在测试中强制触发(无法稳定注入 Wayland 内存分配失败)。

## 已知边界 / 下一项结果

- **成功路径(callback.done(0))未覆盖**:`Helper::setXWindowPositionRelative` 要求 anchor
拥有真实 `SurfaceWrapper`,且 wid 匹配一个已映射的 `Type::XWayland` `SurfaceWrapper`。
生成一个真实的 XWayland 窗口需要可用的 Xwayland 实例;treeland 协议测试在
`WLR_BACKENDS=headless`、`WLR_RENDERER=pixman` 下运行,Xwayland 启动时 glamor 需要
GBM Wayland 接口,无 GPU 环境下无法启动,因此无法在当前 CI 中产出 XWayland
`SurfaceWrapper`。成功路径(wid 匹配、目标位置 == anchor.topLeft + (dx,dy))作为下一项
待验证结果,前提是具备可运行的 Xwayland 测试环境(GPU 或软件 glamor)。
- 无效 anchor(客户端传入 null 或非 `wl_surface` 对象)已被服务端守卫为失败结果
(`callback.done(1)`),但未单列为测试用例;可在具备成功路径环境后补充错误注入用例。
13 changes: 13 additions & 0 deletions tests/protocols/treeland-xwindow-control-unstable-v1/setup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "modules/xwindow-control/xwindowcontrolinterfacev1.h"
#include "server-bridge.h"

#include <wserver.h>

WAYLIB_SERVER_USE_NAMESPACE

void protocol_test_setup(Helper *helper)
{
find_server_interface<XWindowControlInterfaceV1>(helper);
}
Loading
Loading