Skip to content

Typed keys are lost after keyboard focus change until pointer enters the mlterm window #159

@tsutsui

Description

@tsutsui

Summary

After switching keyboard focus to an mlterm window, keyboard input does not
work while the mouse pointer is outside the mlterm window.

If I type several keys in this state, most of them appear to be lost. When the
mouse pointer is moved into the mlterm window, sometimes the last typed key, or
a small part of the input, appears.

After testing, this appears to happen only on the XIM input method path:
mlterm --im=xim reproduces the problem, while mlterm --im=none and
mlterm --im=ibus work correctly.

This problem seems to appear on newer libX11 versions which include
XIM fixes.
https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/master/README.md

Environment

  • OS: NetBSD/i386
  • NetBSD versions tested:
    • NetBSD 10.1: no problem
    • NetBSD 11.0_RC3: problem occurs
  • Window manager: jwm 2.4.6 from pkgsrc
  • Terminal emulator: mlterm 3.9.4 from pkgsrc
  • Input method: ibus via XIM
  • Relevant environment:
    • LANG=ja_JP.UTF-8
    • XMODIFIERS=@im=ibus
  • Focus operation:
    • Use the window manager's keyboard shortcut to move keyboard focus to the
      mlterm window.
    • In my test environment, this is JWM's Alt+Tab window switching.
    • The mouse pointer is outside the mlterm window.

There are several reports about the similar XIM input issue even on Linux:

Both page suggest 'not to use XIM' (i.e. use --im=ibus etc.) to avoid the issue.

Reproduction steps

  1. Start ibus:
ibus-daemon -r -d -x
  1. Start mlterm with XIM:
mlterm --im=xim
  1. Move the mouse pointer outside the mlterm window.

  2. Use the window manager's keyboard shortcut to move keyboard focus to the
    mlterm window.

    In my environment, this is JWM's Alt+Tab.

  3. Type several keys.

Actual result

The mlterm window appears to have keyboard focus, but typed characters do not
appear in the terminal.

Most of the typed keys appear to be lost. When the mouse pointer is moved into
the mlterm window, sometimes the last typed key, or a small part of the input,
appears.

While typing in this state, the following warning is printed repeatedly:

/usr/xsrc/external/mit/libX11/dist/modules/im/ximcp/imDefLkup.c,419: The application disposed a key event with XXXX serial.

Expected result

If the mlterm window has keyboard focus, keyboard input should work regardless
of whether the mouse pointer is inside the mlterm window.

IME on/off keys should also work in the same situation.

Additional tests

The problem depends on the input method path.

This works correctly:

mlterm --im=none

This also works correctly:

mlterm --im=ibus

This reproduces the problem:

mlterm --im=xim

So this appears to be related to the XIM path.

Investigation

The relevant code appears to be in ui_window_receive_event() in
uitoolkit/xlib/ui_window.c.

There is a second XFilterEvent() call for events from the same window family:
https://github.com/arakiken/mlterm/blob/3.9.4/uitoolkit/xlib/ui_window.c#L1904-L1922

if (win->xic) {
  if (is_in_the_same_window_family(win, event->xany.window) &&
      XFilterEvent(event, win->my_window)) {
    return 1;
  }
}

As an experiment, I changed this code to skip the second XFilterEvent() call
for KeyPress and KeyRelease:

if (win->xic && event->type != KeyPress && event->type != KeyRelease) {
  if (is_in_the_same_window_family(win, event->xany.window) &&
      XFilterEvent(event, win->my_window)) {
    return 1;
  }
}

With this change, the main problem is fixed:

  • after keyboard focus is moved to mlterm,
  • with the mouse pointer outside the mlterm window,
  • normal key input works again with mlterm --im=xim.

Also, the imDefLkup.c warning no longer appears in this case.

However, this workaround is incomplete. A remaining issue is:

  • when the mlterm window has keyboard focus but the mouse pointer is outside
    the mlterm window, IME on/off does not work.

So the second XFilterEvent() call seems to be involved in the lost-key
problem, but simply skipping it for key events may not be the correct final
fix.

Notes

The warning from libX11:

The application disposed a key event with XXXX serial.

suggests that recent libX11 XIM expects a fabricated key event to be processed
by the application, but mlterm's event handling may dispose of it or disturb
the expected event order.

The second XFilterEvent(event, win->my_window) call looks suspicious because
XFilterEvent() is not a side-effect-free check; it can update XIM internal
state.

The current mlterm code comment says this second call is a hack to allow XIM
windows to open even when events occur on scrollbar/titlebar windows that do
not have XICs. That may explain why skipping it for key events fixes normal
typing but leaves IME on/off behavior unresolved.

Could you check whether this second XFilterEvent() call is still safe with
current libX11 XIM, and whether mlterm should instead align the actual X input
focus / XIC focus window with the terminal screen window after focus changes?

I do not think the above patch is necessarily the correct fix. It is only a
diagnostic workaround showing that the second XFilterEvent() call for key
events is involved in the problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions