Skip to content

feat(ime-popup): support XWayland xprop and Wayland tag based IME popup#903

Open
glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:feat/im-popup
Open

feat(ime-popup): support XWayland xprop and Wayland tag based IME popup#903
glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:feat/im-popup

Conversation

@glyvut
Copy link
Copy Markdown
Contributor

@glyvut glyvut commented May 28, 2026

Add IME popup window behavior for both Wayland native clients via
xdg-toplevel-tag-v1 protocol and XWayland clients via
_DEEPIN_IM_CANDIDATE_PANEL xprop matching. IME popup windows get no
decoration, no focus stealing, no animation, and are visible across
all workspaces. Position follows text-input cursor rect with screen
edge adjustment. Extract readWindowProperty to common/xcbutils for
reuse, and move Output::adjustToOutputBounds from private to public.

通过 xdg-toplevel-tag-v1 协议和 _DEEPIN_IM_CANDIDATE_PANEL xprop
匹配为 Wayland 原生客户端和 XWayland 客户端添加 IME 弹窗行为。
IME 弹窗无装饰、无焦点抢占、无动画、跨工作区可见,位置跟随
text-input 光标并自动调整屏幕边缘溢出。提取 readWindowProperty
到公共 xcbutils 供复用,将 adjustToOutputBounds 从 private 移到
public。

Log: 添加 tag 和 xprop 双路径 IME 弹窗行为及光标跟随
Influence: 特殊标记的窗口将无装饰、无焦点抢占、无动画、跨工作区
可见,并跟随文本输入光标定位,超出屏幕边缘时自动调整。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: glyvut

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot
Copy link
Copy Markdown

Hi @glyvut. Thanks for your PR.

I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @glyvut, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Comment thread src/core/shellhandler.cpp Outdated
Comment thread src/core/shellhandler.cpp Outdated
Comment thread src/core/shellhandler.cpp
@glyvut glyvut force-pushed the feat/im-popup branch 2 times, most recently from ff557e2 to c63f959 Compare May 28, 2026 03:43
Add IME popup window behavior for both Wayland native clients via
xdg-toplevel-tag-v1 protocol and XWayland clients via
_DEEPIN_IM_CANDIDATE_PANEL xprop matching. IME popup windows get no
decoration, no focus stealing, no animation, and are visible across
all workspaces. Position follows text-input cursor rect with screen
edge adjustment. Extract readWindowProperty to common/xcbutils for
reuse, and move Output::adjustToOutputBounds from private to public.

通过 xdg-toplevel-tag-v1 协议和 _DEEPIN_IM_CANDIDATE_PANEL xprop
匹配为 Wayland 原生客户端和 XWayland 客户端添加 IME 弹窗行为。
IME 弹窗无装饰、无焦点抢占、无动画、跨工作区可见,位置跟随
text-input 光标并自动调整屏幕边缘溢出。提取 readWindowProperty
到公共 xcbutils 供复用,将 adjustToOutputBounds 从 private 移到
public。

Log: 添加 tag 和 xprop 双路径 IME 弹窗行为及光标跟随
Influence: 特殊标记的窗口将无装饰、无焦点抢占、无动画、跨工作区
可见,并跟随文本输入光标定位,超出屏幕边缘时自动调整。
Comment thread src/common/xcbutils.h
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xcbutils需要处理xproperty change的情况,推荐封装一个类,专门负责X11 Property。可以参考KWin。

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

监听事件可以用 wlr_xwayland 里的 user_event_handler,设置一个handler来处理窗口属性变化的事件。

Comment thread src/core/shellhandler.cpp
#include "shellhandler.h"

#include "common/treelandlogging.h"
#include "common/xcbutils.h"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

所有的cppcheck处理一下,让AI分析一下为什么cppcheck会误报。

@glyvut glyvut marked this pull request as ready for review May 28, 2026 07:00
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @glyvut, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds IME (input method) popup window behavior support for both Wayland-native clients (via the xdg-toplevel-tag-v1 protocol with tag org.deepin.treeland.im-candidate-panel) and XWayland clients (via the _DEEPIN_IM_CANDIDATE_PANEL xprop). Such windows are treated as IME candidate panels: no decoration, no focus stealing, no animation, shown on all workspaces, and re-positioned to follow the text-input cursor rect (with screen-edge clamping). It also refactors the XCB readWindowProperty helper out of helper.cpp into a shared common/xcbutils.{h,cpp} for reuse, and promotes Output::adjustToOutputBounds from private slots to public so ShellHandler can use it.

本 PR 通过 xdg-toplevel-tag-v1(Wayland 原生)和 _DEEPIN_IM_CANDIDATE_PANEL xprop(XWayland)两条路径,为输入法候选窗口添加专门行为:无装饰、不抢焦点、无动画、跨工作区显示、并跟随文本输入光标定位(带屏幕边缘调整)。同时把 XCB 属性读取工具 readWindowProperty 抽到 common/xcbutils,并将 Output::adjustToOutputBounds 从私有槽提升为公有方法。

Changes:

  • Add isIMEPopupBehavior property on SurfaceWrapper and bypass animations, focus, container additions, and activation logic for such surfaces.
  • Detect IME-popup surfaces in ShellHandler via xdg tag (tagChanged) and XWayland xprop, move them to the popup container, and reposition on textInputCursorRectChanged.
  • Extract readWindowProperty to src/common/xcbutils.{h,cpp}, expose WInputMethodHelper::textInputFocusSurface/textInputCursorRect and a new textInputCursorRectChanged signal, and make Output::adjustToOutputBounds public.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
waylib/src/server/protocols/winputmethodhelper.h Expose focus surface, cursor rect getters and cursor-rect-changed signal
waylib/src/server/protocols/winputmethodhelper.cpp Implement new getters and emit cursor-rect-changed on focused TI commit
src/surface/surfacewrapper.h Add isIMEPopupBehavior Q_PROPERTY, setter/getter, signal, bitfield
src/surface/surfacewrapper.cpp Initialize and apply IME popup behavior; skip animation; zero radius; show on all workspaces
src/seat/helper.cpp Use shared xcbutils; skip add/remove/activate paths for IME popup wrappers; remove inline readWindowProperty
src/output/output.h Make adjustToOutputBounds public for external use
src/core/shellhandler.h Declare IME-popup detection helpers, list of wrappers, and cursor-rect slot
src/core/shellhandler.cpp Detect IME popups (tag/xprop), move to popup container, follow cursor rect with edge clamping
src/common/xcbutils.h New header for shared XCB helpers
src/common/xcbutils.cpp Extracted readWindowProperty implementation
src/CMakeLists.txt Register new common/xcbutils.* sources

Comment thread src/seat/helper.cpp
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

创建xwayland对象后,要调用setAtomSupported声明自己支持 "_DEEPIN_IM_CANDIDATE_PANEL"

Comment thread src/common/xcbutils.h
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

监听事件可以用 wlr_xwayland 里的 user_event_handler,设置一个handler来处理窗口属性变化的事件。

Comment thread src/common/xcbutils.cpp

#include "xcbutils.h"

QByteArray readWindowProperty(xcb_connection_t *connection,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种比较通用的可以放到 waylib 的 wxwayland 里实现

Comment thread src/core/shellhandler.cpp

// Tag cannot be set before xdg_toplevel is created (protocol ordering),
// so IME popup matching only happens via tagChanged handler below.
Q_ASSERT_X(!shouldTreatAsIMEPopupByTag(surface->tag()), Q_FUNC_INFO,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个assert的理由是什么,ensureXdgWrapper在什么时机调用。xdg_toplevel_tag被要求在surface第一次commit的时候就需要设置。

Comment thread src/core/shellhandler.cpp
if (!container || container == m_popupContainer)
return;
container->removeSurface(wrapper);
applyIMEPopupBehavior(wrapper, surface->parentSurface());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IME-> Input Method Engine,这些简写都采用IM比较合适。

Comment thread src/core/shellhandler.cpp
xcb_flush(xcb_conn);
}

static const QLatin1String IME_POPUP_NAME("org.deepin.treeland.im-candidate-panel");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用IM_CANDIDATE_PANEL,和内容最好保持关联性。

Comment thread src/core/shellhandler.cpp
: nullptr;
if (parentWrapper)
wrapper->setOwnsOutput(parentWrapper->ownsOutput());
m_popupContainer->addSurface(wrapper);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用popupContainer会有和popup完全一致的行为吗?实际还是有些差异的。

uint m_confirmHideByLockScreen : 1;
uint m_blur : 1;
uint m_isActivated : 1;
uint m_isIMEPopupBehavior : 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isIMCandidatePanel,isXXXBehavior不行。

Comment thread src/core/shellhandler.h
Comment on lines +197 to +198
static bool shouldTreatAsIMEPopupByXprop(WAYLIB_SERVER_NAMESPACE::WXWaylandSurface *surface);
static bool shouldTreatAsIMEPopupByTag(const QString &tag);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果需要隐藏实现,使用函数重载shouldTreatAsIMPopup,一个参数是XdgSurface,一个参数是XWaylandSurface,这样写的话这个shouldTreatAsIMEPopupByTag就没有什么必要了,里面只有一行逻辑。

Comment thread src/common/xcbutils.cpp

if (reply->type == type) {
int len = xcb_get_property_value_length(reply);
char *datas = (char *)xcb_get_property_value(reply);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用static_cast<char*>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants