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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include(CMakePackageConfigHelpers)

# Public protocol XML files (for general application developers)
set(TREELAND_PROTOCOL_XML_FILES
public/treeland-snap-target-unstable-v1.xml
public/treeland-window-transition-unstable-v1.xml
public/treeland-appearance-unstable-v1.xml
public/treeland-decoration-unstable-v1.xml
Expand Down
1 change: 1 addition & 0 deletions public/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ For general application developers. Installed via `TREELAND_PROTOCOL_XML_FILES`.
| File | Protocol | Interfaces | Purpose |
|------|----------|-----------|---------|
| `treeland-window-transition-unstable-v1.xml` | `treeland_window_transition_unstable_v1` | `treeland_window_transition_manager_v1`, `treeland_window_transition_rect_v1` | Window open/close transition relative to a rectangle, with optional source image |
| `treeland-snap-target-unstable-v1.xml` | `treeland_snap_target_unstable_v1` | `treeland_snap_target_v1` | Compositor-side snap region hints; an optional pidfd event for window targets can be enabled via the `event_type.pidfd` bit of `start` |
| `treeland-appearance-unstable-v1.xml` | `treeland_appearance_unstable_v1` | `treeland_appearance_v1` | Query and observe user-level appearance settings: cursor theme/size, fonts, icon theme, accent color, window opacity, color scheme, titlebar height, corner radius |
| `treeland-decoration-unstable-v1.xml` | `treeland_decoration_unstable_v1` | `treeland_decoration_manager_v1`, `treeland_decoration_context_v1` | Per-window server-side decoration (SSD) customization by applications: corner radius, shadow, border, titlebar visibility; requires xdg-decoration SSD |
## Breaking changes
Expand Down
1 change: 1 addition & 0 deletions public/README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| 文件 | 协议 | 接口 | 用途 |
|------|----------|-----------|---------|
| `treeland-window-transition-unstable-v1.xml` | `treeland_window_transition_unstable_v1` | `treeland_window_transition_manager_v1`, `treeland_window_transition_rect_v1` | 相对某个矩形的窗口打开/关闭转场,可附带源图像 |
| `treeland-snap-target-unstable-v1.xml` | `treeland_snap_target_unstable_v1` | `treeland_snap_target_v1` | 合成器侧吸附区域提示;窗口目标的 pidfd 事件为可选项,需在 `start` 中置 `event_type.pidfd` 位启用 |
| `treeland-appearance-unstable-v1.xml` | `treeland_appearance_unstable_v1` | `treeland_appearance_v1` | 查询与订阅用户级外观设置:光标主题/大小、字体、图标主题、强调色、窗口不透明度、配色方案、标题栏高度、圆角 |
| `treeland-decoration-unstable-v1.xml` | `treeland_decoration_unstable_v1` | `treeland_decoration_manager_v1`, `treeland_decoration_context_v1` | 逐窗口服务端装饰(SSD)定制:圆角、阴影、边框、标题栏可见性;需先经 xdg-decoration 申请 SSD |

Expand Down
219 changes: 219 additions & 0 deletions public/treeland-snap-target-unstable-v1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="treeland_snap_target_unstable_v1">
<copyright><![CDATA[
SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
SPDX-License-Identifier: MIT
]]></copyright>
Comment on lines +2 to +6

<description summary="compositor-side snap region hint">
This protocol allows a client to request snap region hints from the
compositor. While snapping is active, the compositor tracks the cursor
position and notifies the client of the rectangle currently hovered by
the cursor (e.g., a window boundary or a full output). The client uses
these hints to draw its own snap preview UI.

Snap targets are computed against the window layout captured when the
snap session starts: the compositor records the position and stacking
order of every window at that moment and keeps them unchanged for the
whole session. Windows that move, are mapped or unmapped, change
stacking order, or are destroyed after start are not reflected in the
snap targets.

A client may identify an overlay surface by setting the xdg-toplevel-tag
"org.deepin.treeland.snap-mask" on that toplevel. When the compositor
detects this tag, it applies the following configuration to the surface:

1. Raises the surface above normal windows and their popup panels.
2. Disables window open/close animations.
3. Excludes the surface from the multitask view and window switcher.
4. Disables automatic positioning by the compositor's layout engine.

Such a surface does not affect the snapping protocol; snapping
behaves the same whether or not the surface exists. Surfaces
carrying the snap-mask tag are excluded from snapping, i.e., they
are never reported as snap targets.

Warning! This protocol is EXPERIMENTAL and under active development.
It may change at any time, including in backward-incompatible ways,
without incrementing the interface major version and without prior
notice. No compatibility guarantees of any kind are provided. Clients
and compositors must track the upstream definition in treeland-protocols
and must not rely on the current interface names, requests, events, or
semantics remaining stable across releases.
</description>

<interface name="treeland_snap_target_v1" version="1">
<description summary="snap region hint session">
This interface is a global singleton for requesting snap region hints
from the compositor. Each client binds at most one instance of this
global. The compositor tracks the cursor position and notifies the
client of the rectangle currently hovered by the cursor.

The snap object is created in an idle state. The client starts
snapping by calling start, which causes the compositor to capture the
current window positions and stacking order and begin tracking the
cursor position, providing snap region hints based on the captured
layout.

While snapping is active, the compositor sends a snap_region event
each time the snap target changes (i.e., when the cursor moves to a
different window or output). A client that also needs to know which
process owns a window snap target can enable the optional pidfd event
by setting the event_type.pidfd bit in the events argument of start;
without that bit the compositor sends no pidfd events. When enabled,
and when the new snap target is a window with a determinable owning
process, a pidfd event reporting that process is sent before the
snap_region event it applies to. The client can use these events to
update its snap preview UI.

When the client is done (e.g., the user has clicked or dragged to
confirm a selection in the client's UI), the client calls stop to
stop snap notifications. A stopped snap object may be restarted by
calling start again.

Only one snap session may be active across all clients at any time.
If another client's snap session is active, start fails with the
snap_busy reason.
</description>

<enum name="failure_reason">
<description summary="reasons why snapping failed"/>
<entry name="snap_busy" value="0"
summary="another client has an active snap session"/>
</enum>

<enum name="event_type" bitfield="true">
<description summary="optional events a client can enable at start">
Bitfield of optional events the client may request when starting a
snap session. Bits not listed here are reserved for future events
and are ignored by the compositor.
</description>
<entry name="pidfd" value="1"
summary="report the pidfd of the process owning window snap targets"/>
</enum>

<request name="destroy" type="destructor">
<description summary="destroy the snap object">
Destroy the treeland_snap_target_v1 object. If snapping is in
progress, the compositor automatically stops it (stops cursor
tracking). No further events are emitted on this object.
</description>
</request>

<request name="start">
<description summary="begin snap region hints">
Request the compositor to capture the current window positions and
stacking order and begin tracking the cursor, sending snap region
hints based on the captured layout.

The seat argument associates this snap session with a seat. How the
compositor uses the seat is compositor policy.

This request may be called again after stop to restart snapping; a
fresh capture of the window layout is taken on every start. start
must not be called on an already active snap object; the compositor
ignores such a request.
Comment on lines +112 to +115

The events argument selects which optional events the compositor may
send for this session. It is a bitfield of event_type values: only
the events whose bits are set are enabled, and passing 0 enables no
optional events. Bits that do not correspond to a known event_type
value are ignored. The selection applies to this session only; a
start after stop establishes a new selection.

If snapping cannot be started because another client's snap session
is already active, the compositor sends a failed event with the
snap_busy reason instead.
</description>
<arg name="seat" type="object" interface="wl_seat"
summary="seat associated with this snap session"/>
<arg name="events" type="uint" enum="event_type"
summary="optional events to enable for this session"/>
</request>

<request name="stop">
<description summary="stop snap region hints">
Signal that the client is done with snapping. The compositor stops
tracking the cursor and stops sending snap_region events.

This request is a no-op if snapping is not in progress (e.g., if
failed was already emitted or stop was already called).

The client should call destroy afterwards to free the snap object.
</description>
</request>

<event name="pidfd">
<description summary="pidfd of the process owning the snap target">
Reports the process owning the window that corresponds to the snap
target reported by the next snap_region event. This event is sent
only if the client enabled the event_type.pidfd bit in the events
argument of start; otherwise it is never sent. When enabled, the
compositor sends this event before the snap_region event it applies
to, and only when the snap target is a window whose owning process
can be determined. If the snap target is not a window (for example an
output or empty desktop space), or the owning process cannot be
determined, this event is omitted and snap_region is sent on its own.

No pidfd event is ever sent for a snap target whose window was
destroyed after start: the captured region remains a snap target,
but its owning process no longer exists.
Comment on lines +158 to +160

The client owns the received file descriptor and is responsible for
closing it. The descriptor stays valid independently of the snap
session.
</description>
<arg name="pidfd" type="fd"
summary="pidfd of the process owning the snap target"/>
</event>

<event name="snap_region">
<description summary="current snap target region">
Notifies the client of the current snap target rectangle. The snap
target set is captured at start and is fixed for the whole session:
a window that moves, is mapped or unmapped, changes stacking order,
or is destroyed after start does not add, remove, move, resize, or
reorder the targets captured at start. In particular, a window
destroyed after start keeps its captured region as a snap target.
This event is sent each time the snap target changes due to cursor
movement.

This event commits the snap target. A pidfd event, when sent for
this target, precedes it and reports the process owning the target.
When processing this event, the client should associate the most
recent preceding pidfd event, if any, with this target; if no pidfd
event precedes it, the target has no associated process.
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Resolved

The region is in global logical coordinates (i.e., the
xdg_output logical coordinate space). The client is responsible for
any coordinate transformation needed for its UI.

If width and height are both zero, there is no current snap target
(e.g., the cursor is over empty desktop space). The client should
hide its snap preview in this case.
</description>
<arg name="x" type="int"
summary="global logical x coordinate of the snap target"/>
<arg name="y" type="int"
summary="global logical y coordinate of the snap target"/>
<arg name="width" type="uint"
summary="width of the snap target (0 if no target)"/>
<arg name="height" type="uint"
summary="height of the snap target (0 if no target)"/>
</event>

<event name="failed">
<description summary="snapping failed">
Snapping could not be started. The compositor
will not send any more snap_region events. The client should call
destroy to free the snap object.

This event is sent when another client's snap session is already
active (reason snap_busy).
</description>
<arg name="reason" type="uint"
enum="failure_reason"
summary="why snapping failed"/>
</event>
</interface>
</protocol>
Loading