feat(portal): 接入合成器传送门,暂存区固定/消耗语义

- 新增 PortalClient:org.gxde.Portal 的 BeginPortal / CancelPortal 与 drag 信号
- 传送门区域悬停 150ms 后打开合成器 overview;无窗口/不支持时给出提示
- 拖拽开始时自动弹出面板(120ms 延迟,mime 过滤),拖拽结束自动收起
- 暂存区每行新增固定按钮;默认拖出后消耗,固定后保留;取消拖拽不消耗
- 拒绝自身拖拽落入暂存区,避免重复条目
This commit is contained in:
2026-10-30 19:55:25 +08:00
parent f9204a03d1
commit 68d3eb1a24
10 changed files with 314 additions and 6 deletions
+46
View File
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2026 GXDE OS Team
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QObject>
/**
* Client for the compositor side "portal" (org.gxde.Portal).
*
* Start with \a beginPortal() while a drag hovers the portal zone. The
* compositor opens the window overview in portal mode and forwards the drag
* to the window under the cursor, so the target application receives a real
* wl_data_device drop at the cursor position.
*/
class PortalClient : public QObject
{
Q_OBJECT
public:
static PortalClient *instance();
bool available() const { return m_available; }
/** @return true when the compositor opened the overview. */
bool beginPortal();
void cancelPortal();
/** Filter the drag mime types we want to react to. */
static bool mimeInteresting(const QString &mimeTypes);
signals:
void dragStarted(const QString &mimeTypes);
void dragEnded();
void dropped(const QString &uuid, bool accepted);
private slots:
void onDragStarted(const QString &mimeTypes);
void onDragEnded();
void onDropped(const QString &uuid, bool accepted);
private:
explicit PortalClient(QObject *parent = nullptr);
bool m_available = false;
};