Skip to content

linux(wayland): proactive text_input enable + fix infinite loop + deduplicate preedit events#17

Open
FurryR wants to merge 2 commits into
warpdotdev:masterfrom
FurryR:clean-fix
Open

linux(wayland): proactive text_input enable + fix infinite loop + deduplicate preedit events#17
FurryR wants to merge 2 commits into
warpdotdev:masterfrom
FurryR:clean-fix

Conversation

@FurryR

@FurryR FurryR commented Jun 28, 2026

Copy link
Copy Markdown

Summary

This PR fixes three issues in the Wayland text-input (IME) handling path in winit:

  1. Proactive enable for KWin compatibility — KWin expects zwp_text_input_v3.enable() to be sent *before* the compositor delivers enter. Winit now proactively enables text_input in three places: when a new text_input capability appears, when WlKeyboard::enter fires, and when a new window is created.
  2. Infinite loop in Done handler — The upstream Done handler unconditionally emitted Ime::Preedit("") whenever pending_preedit was None, creating a feedback loop: Preedit("")SetMarkedText("")set_ime_cursor_areacommit() → another empty done → repeat. The fix consumes pending_commit and pending_preedit before deciding what to emit, emitting nothing when neither is present.
  3. Deduplicate redundant preedit events — fcitx5/KWin may send multiple done events with identical preedit text per keystroke. Forwarding all of them floods the application with SetMarkedText dispatches, each triggering a re-render + set_ime_cursor_area + commit() that can overwhelm the compositor. Track the last sent preedit and skip when unchanged.

Changes

File Change
seat/mod.rs Register + enable text_input for existing windows in new_capability
window/mod.rs Pre-populate text_inputs from existing seats on window creation
seat/keyboard/mod.rs Proactive enable() + commit() on WlKeyboard::enter
seat/text_input/mod.rs Remove redundant enable/commit from Enter handler; add dedup tracking to Done handler

Testing

Tested on KDE Wayland (Manjaro Linux) with fcitx5 IME. Both Chinese (pinyin) and Japanese (mozc) input work correctly with no crash, no infinite loop, and no broken pipe errors.

Proactive enable (KWin compatibility):
- new_capability: register text_input with existing windows + enable if ime_allowed
- WlKeyboard::enter: send enable+commit on focus entry
- Window::new: pre-populate text_inputs from existing seats
- Enter handler: remove redundant enable+commit to avoid double-activation

Infinite loop fix:
- Only emit Ime::Preedit/Commit when the Done event carries actual content
- A commit-only or empty Done produces no events, breaking the
  Preedit("") -> cursor update -> commit -> Done -> Preedit("") cycle
@FurryR

FurryR commented Jun 28, 2026

Copy link
Copy Markdown
Author

I'm not sure if this change should be added to changelog.

I'm now working on other issues so it may take a long while for me to respond.

If possible you can directly modify CHANGELOG. Thanks for a lot!

@FurryR

FurryR commented Jun 28, 2026

Copy link
Copy Markdown
Author

Update:

Chinese IME works while Japanese IME still causes crash. I'm marking this PR as a draft.

@FurryR FurryR marked this pull request as draft June 28, 2026 08:36
@FurryR FurryR changed the title linux(wayland): proactive text_input enable + fix infinite loop on Done linux(wayland): proactive text_input enable + fix infinite loop + deduplicate preedit events Jun 28, 2026
fcitx5/KWin may send multiple identical done events per keystroke,
each carrying the same preedit text. Forwarding all of them floods
the application with redundant SetMarkedText dispatches, each
triggering a re-render cycle (set_ime_cursor_area + commit) that
can overwhelm the compositor.

Adds a cached_preedit field to TextInputData. The Done handler
now compares the incoming preedit against the last sent value and
skips dispatching Ime::Preedit when unchanged, breaking the
feedback loop while preserving responsiveness for real changes.

Also fixes the missing ZwpTextInputV3Ext import in keyboard/mod.rs.
@FurryR

FurryR commented Jun 28, 2026

Copy link
Copy Markdown
Author

Ready for review.

@FurryR FurryR marked this pull request as ready for review June 28, 2026 09:29
@FurryR

FurryR commented Jun 28, 2026

Copy link
Copy Markdown
Author

This seems irrelevant, but after applying the fix, I'm able to use FeatureFlag::ImeMarkedText on Linux (still need cargo run --feature .

diff --git a/crates/warp_features/src/lib.rs b/crates/warp_features/src/lib.rs
index 3dbdd8b..03a2c93 100644
--- a/crates/warp_features/src/lib.rs
+++ b/crates/warp_features/src/lib.rs
@@ -982,8 +982,6 @@ pub const RELEASE_FLAGS: &[FeatureFlag] = &[
     FeatureFlag::Autoupdate,
     FeatureFlag::Changelog,
     FeatureFlag::CrashReporting,
-    // Marked text is currently only supported on MacOS.
-    #[cfg(target_os = "macos")]
     FeatureFlag::ImeMarkedText,
     // Remote server binary is not yet supported on Windows.
     #[cfg(not(windows))]

But after all this is out of my reach. I'm just testing and it works fine.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant