Repository navigation
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: LFRon 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 |
|
Hi @LFRon. 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 Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions 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. |
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThis PR ensures that when a temporary keyboard grab ends, the IME’s own keyboard grab is correctly restored, preventing situations where fcitx5 fails to appear or becomes unusable after other grabs interfere. Sequence diagram for restoring IME keyboard grab after other grab endssequenceDiagram
participant Seat
participant WInputMethodHelper
participant IMEKeyboardGrab
participant OtherKeyboardGrab
Seat->>WInputMethodHelper: notify_keyboard_grab_begin
WInputMethodHelper->>Seat: keyboard_start_grab(OtherKeyboardGrab)
Seat->>WInputMethodHelper: notify_keyboard_grab_end
WInputMethodHelper->>WInputMethodHelper: handleKeyboardGrabEnd()
alt [activeKeyboardGrab and current grab != keyboardGrab]
WInputMethodHelper->>Seat: keyboard_start_grab(keyboardGrab)
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
CLA Assistant Lite bot: |
6d84a13 to
f4d41e9
Compare
|
TAG Bot New tag: 0.8.17 |
c7ac3b3 to
60bf411
Compare
51bcb32 to
c676a1f
Compare
|
大佬们有没有好思路修复这个( |
49e9b4a to
502ecd5
Compare
|
TAG Bot New tag: 0.8.18 |
de1839c to
c363b5c
Compare
9d1ef55 to
6135a3f
Compare
|
TAG Bot New tag: 0.10.0 |
7fcbd2b to
fc61cfe
Compare
5008491 to
2cb9f46
Compare
868fe68 to
1933ed1
Compare
4d243a9 to
27af1d1
Compare
|
TAG Bot New tag: 0.11.0 |
What this fixes --------------- In WPS Office (and other XEmbed-based X11 apps) the input method is dead in the document editing area while it keeps working in the home/search frame. The editor is not a plain Qt child widget: it is an XEmbed plug window on a separate X client connection, reparented inside the Qt shell top-level. To route text into it the shell legitimately issues XSetInputFocus onto that subwindow, exactly what a real X11 window manager allows. Root cause ---------- xwm_handle_focus_in() guards against cross-application focus stealing: when a FocusIn arrives for a window xwm does not manage and whose pid does not match, it snaps input focus back to the previously tracked top-level. XEmbed plug windows are never xwm surfaces (xwm only tracks managed top-levels), so every legitimate in-client focus move into the plug is misread as a steal and yanked back to the shell. The embedded editor never keeps real X input focus, so input-method activation gated on real X focus (XIM/XIC set-focus) never fires: the input method looks dead even though plain X keys still reach the window. The fix ------- Before refocusing, check whether the window that just gained X input focus is located inside the currently focused surface's X subtree. That is an in-application focus move inside the client's own hierarchy -- what a bare X server and KWin leave alone -- so accept it silently instead of grabbing focus back. Genuine cross-application stealing still falls through to the existing refocus path. The check walks upwards from the newly focused window (XQueryTree parent pointers) with a hard cap of 8 hops, stopping at the root window, so it needs at most a handful of synchronous X queries in every case -- one for a plain top-level, two for a framed window. The previous top-down search visited the focused window's whole subtree, which is unbounded in width, on the compositor main loop for every FocusIn that needed the check. A WLR_DEBUG line (child, parent, queries, result) keeps the runtime cost of focus churn observable. Scope: only windows inside the focused top-level's own subtree are exempted; the same-pid (Steam-type) special case, override-redirect handling, the pointer-detail filter and the focus-serial race guard are untouched.
Combined input-method fix for treeland sessions: the Wayland input-method
stack in waylib, candidate-window anchoring and popup-grab bookkeeping in
treeland, the session environment that X11-side input methods depend on, and
the recovery paths for input methods that lose their seat connection.
Wayland input-method stack (waylib):
- Route input-method keys through a dedicated WSeat keyboard filter instead
of a synthetic wlr_seat_keyboard_grab. The IM grab object and xdg-popup /
drag grabs competed for one seat grab slot, and a displaced popup grab
left text-input focus, IM activation and keyboard delivery out of sync
(folder rename in dde-file-manager broke; XWayland windows stopped
receiving keys after popup close). Physical key/modifier events now go to
the active input-method keyboard endpoint only while the keyboard focus
surface owns an eligible text input, excluding the IM's own virtual
keyboards and active drags; popup and drag keep their own wlroots grabs
untouched.
- Activation stays strictly text-input driven. It is held on the anchor only
across the momentary null focus of a window switch, so a focus flickering
through null does not tear down and re-create the fcitx5 grab and virtual
keyboard. As soon as focus settles on a concrete surface without an
eligible text input (terminals, XWayland windows, the compositor's own
QML), the input method deactivates: those surfaces must keep their raw keys
so the client-side input-method path (XIM / D-Bus frontends) stays in
charge, and a held activation would leave the candidate window parented to
an unrelated text input. A destroyed or client-disabled anchor still falls
through to normal deactivation.
- Commits never follow the anchor: a commit is delivered only to the text
input exactly matching current keyboard focus. The virtual-keyboard typing
fallback stays as a defensive path for commits that arrive while a held
activation has not been reconciled against the new keyboard focus yet
(latin/symbol keysyms; CJK needs an xwayland-side text-input bridge, out
of scope here); other ineligible commits are discarded with a warning
instead of being typed at the wrong surface, and the synthetic key events
convert the xkb keycode of the keysym lookup back to the evdev keycode
wlr_keyboard_notify_key() expects.
- Text-input enablement follows the protocols again: a compositor-driven
enter/leave is a notification, not a disablement. For text-input-v1 the
client activate record is persistent (cleared only by the client's own
deactivate or the surface's destruction, enter/leave kept paired), so
focus returning to an activated surface re-arms it deterministically. For
text-input-v2 the leave no longer emits disabled(); revocation flows only
through the client disable request or enabled-surface destruction, and
every new enter is preceded by the obsolete leave.
- Adopt upstream's empty-preedit clearing (text-input v1/v2/v3): a commit
that does not carry a preedit means "clear it", and leave sends an empty
preedit while the client is still enabled, so composing text can no longer
stay rendered after the composing ended. The enabled-surface destroy
connection is tracked separately so clearing it never drops the
focused-surface listener installed by sendEnter(). Because compositor
leave no longer reports disabled(), the client's disable is authoritative
and reports disabled() unconditionally, so the helper never keeps a stale
enabled text input.
- Attach the IM keyboard endpoint to the keyboard group device when it is
created (fcitx5 recreates its virtual keyboard right before grab
requests), take keyboard-focus enter payloads from the group, restore the
group keyboard when a virtual keyboard dies, guard Qt repeat handling
against invalid keyboards/disabled rates, and re-run instead of dropping
re-entrant focus reconciliations.
- Input-method helper lifecycle: handleActiveIMDestroyed() sends leave to
every focused text input (each protocol's sendLeave() carries the empty
preedit) so clients drop composing state, and handleNewIMV2() re-announces
the keyboard focus before reconciling, so a text input left by a
disconnected input method is re-armed deterministically even though the
seat focus did not change.
- Popup focus tracking (seatsurfacemanager) validates exact
wlr_xdg_popup_grab membership, tracks replacement and end events
separately, restores the concrete pre-popup focus only while the tracked
popup still owns focus, and dismisses the concrete popup instead of
ending an arbitrary seat grab.
- Categorized transition logs (input-method / text-input / popup-focus)
carry object and state identifiers only, never key codes, surrounding
text, preedit or committed user input.
Input-method popup anchoring (waylib + treeland):
- Candidate windows (zwp_input_popup_surface_v2) are anchored to the text
input that currently owns the input-method focus, not to the surface that
happened to be focused when the input method created its panel, so the
candidate window follows one application switching text focus between its
own windows.
* waylib announces the settled focus surface through a new
textInputFocusSurfaceChanged signal, emitted once the focus
reconciliation settled (idempotent, nothing emitted during teardown).
* A popup surface that arrives before any text input is eligible is parked
in a pending list and attached on the next reconciliation. The input
method reuses its panel surface until the panel hides, so dropping the
popup kept the candidate window invisible for that whole period.
* treeland resolves the placement parent of an input popup dynamically
(the current text-input focus surface looked up in the root surface
container, falling back to the popup's own recorded parent), re-parents
the popup to the placement parent's output and re-arranges it whenever
the text-input focus surface changes.
* Input-popup add/remove handling is null-guarded on both sides: a popup
whose anchoring surface is already gone is skipped symmetrically instead
of dereferencing a wrapper that was never created.
Input-method session recovery (waylib + treeland + treeland-sd):
- fcitx5 opens its Wayland and X11 frontends exactly once, at its own
startup, and never reopens them. A start that raced the session socket, or
an instance replaced by `fcitx5 -r` (fcitx5 is started more than once at
login), used to leave the session without any input method until fcitx5
was restarted by hand: the replacement's request is rejected by the
compositor's one-input-method-per-seat rule while the previous instance
still holds the seat, and the rejected client never retries.
- WInputMethodHelper now announces when the seat's input method is accepted
or destroyed; treeland relays it as org.deepin.Compositor1
InputMethodChanged. treeland-sd reacts to the destroyed edge by handing a
fresh Wayland socket (ReopenWaylandConnectionSocket) to the still-running
fcitx5, which makes it re-request the input method. The handover is
coalesced and delayed by a settle window, so the events of one ownership
transition (owner change, socket activation, input method destroyed)
produce a single handover after the replaced instance had time to close
its connection; a connected edge cancels a pending handover and a working
connection is never replaced needlessly.
- Xwayland is started with `-terminate` and restarted in place by wlroots
when its last X11 client exits, which kills every X11 connection opened
before the restart while fcitx5 keeps running. After publishing the
refreshed DISPLAY/XAUTHORITY, and whenever fcitx5 (re)appears, treeland-sd
asks it to open an X11 connection; the request is idempotent ("already
exists" is ignored), so the XCBUI candidate window and XIM recover without
restarting fcitx5.
XWayland session environment (src/systemd-socket.cpp,
misc/systemd/.../treeland-xwayland.service.in):
- Publish DISPLAY and XAUTHORITY through systemd1.SetEnvironment in addition
to UpdateActivationEnvironment. Transient session units (How apps and
fcitx5 are started via StartTransientUnit) inherit the *manager*
environment, not the activation one, so X-side input methods were blind to
the XWayland display in treeland sessions; dde-session performs this same
call on KWin, which is why it only worked there. UnsetEnvironment and
ExecStop now clear XAUTHORITY alongside DISPLAY.
- Gate unit readiness on the compositor's ActivateWayland business reply: a
successful D-Bus call returning false means the compositor is registered
but not yet ready for this session socket (login handover). Retried in a
bounded ~20s window, then degraded to the historic publish-anyway path so
the session can never hang; this stops advertising WAYLAND_DISPLAY and
autostarting input methods against a socket nobody serves, where they
stayed permanently broken.
Stacking robustness (src/surface/surfacewrapper.cpp):
- SurfaceWrapper::stackAfter() falls back to the sub-chain head (validated
as a sibling by the entry guard) when its deepest stacked member lives in
a different QQuickItem container, as X11 transient children may:
QQuickItem::stackAfter() silently rejects non-siblings and aborted the
raise with the stacking bookkeeping left out of sync.
Together with the vendored wlroots XEmbed focus exemption committed
separately, the input method now works in native Wayland clients (folder
rename and others, including across popups and window switches, with the
candidate window following the focused window), in XWayland clients (WPS
Office document editing included), and survives a compositor restart, a
late or replaced fcitx5 start, and an in-place Xwayland restart without
fcitx5 having to be restarted by hand.
Log: Input methods keep working across boot-time instance races, late
starts, compositor restarts and Xwayland restarts; the transition and
recovery paths are observable in the treeland-sd, waylib.protocols.inputmethod
and waylib.protocols.textinput logs.
Influence:
1. Native Wayland clients: text input keeps its key routing, commits and
candidate window across focus changes, popups and window switches.
2. XWayland clients: WPS Office-style embedded editors keep IME; the X11
candidate window and XIM recover after an in-place Xwayland restart.
3. Boot with duplicate fcitx5 starts: the session recovers its input method
automatically within a few hundred milliseconds instead of staying dead
until fcitx5 is restarted by hand.
4. Compositors without the new InputMethodChanged signal still work;
treeland-sd logs a warning and keeps the activation-time handover.
handleNewKGV2() bound the new zwp_input_method_keyboard_grab_v2 endpoint to the seat's keyboard-group device unconditionally, even though the keyboard that actually delivers the filtered keys is the seat's current keyboard. The first key routed through filterKey() then made setKeyboard() rebind the endpoint, and wlroots' wlr_input_method_keyboard_grab_v2_set_keyboard() re-sent repeat-info and modifiers for the new keyboard. Together with the explicit virtual-keyboard modifiers request that is three modifiers events where the protocol sequence has two, which is what made test_input_method_unstable_v2 fail on the keyboard-grab block. Keep the keyboard-group fallback for the case it was written for - the seat's current keyboard being the input method's own virtual keyboard, which setKeyboard() deliberately skips to avoid a keymap echo loop - and bind to the seat keyboard otherwise.
fix(waylib/inputmethod): bind IME keyboard endpoint to the seat keyboard
该问题修复的是由于设置了QT_IM_MODULES, XMODIFIERS等环境变量后, 在treeland运行一段时间后一定会出现的几个问题:
该PR同时修复了上述问题
Summary by Sourcery
Restore reliable input-method operation across popup grabs, focus transitions, compositor restarts, and Wayland/XWayland session handovers.
New Features:
Bug Fixes:
Enhancements:
Deployment: