https://bugs.kde.org/show_bug.cgi?id=525542

[email protected] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #2 from [email protected] ---
  Workaround and additional diagnostic results from an OpenAI Codex session on
another affected system:

  Environment:

  Fedora 44
  KWin 6.7.5-1.fc44
  Plasma Wayland
  Two EVE Online clients running through Proton/XWayland
  Each client configured as “Fixed Window” and placed on a separate adjacent
virtual desktop

  Reproduction:

Have two Eve clients running on desktops next to each other.  Switching between
the desktops with Ctrl+Alt+Left or Ctrl+Alt+Right displays the destination EVE
client without making it interactive. The client cannot be clicked and the
Plasma panel remains visible.  Switching to another desktop and back, or
toggling Yakuake, immediately clears the condition. 

A live KWin scripting probe captured the failed state:
workspace.currentDesktop referred to the destination desktop.
workspace.activeWindow still referred to the EVE client on the previous
desktop.

The visible destination client had active=false.

KWin reported both EVE windows as fullScreen=true, even though EVE was
configured for “Fixed Window.”

Both windows exposed:
WM_HINTS: Client accepts input or input focus: False
WM_PROTOCOLS containing WM_TAKE_FOCUS

The WM_CLASS on this particular installation was:
steam_app_3379096540

(That Steam identifier is probably installation-specific)

The behaviour appears directly related to this KWin 6.7.5 change:
https://invent.kde.org/plasma/kwin/-/commit/da716de0db06a6323e3604be9585b2ae0f9df6ae

The changed requestFocus() path calls takeFocus(), but does not immediately
call setActiveWindow() when takesAsyncFocus() returns true.
For X11/XWayland windows, takesAsyncFocus() returns true when the client has
WM_HINTS Input=False and advertises WM_TAKE_FOCUS. EVE therefore enters this
asynchronous path, but apparently does not complete the focus acknowledgement
expected by KWin. The previously active EVE client consequently remains active
after the virtual desktop changes.

Two attempted KWin-level workarounds were ineffective:
Setting workspace.activeWindow from a KWin script still uses
Workspace::activateWindow(), reaching the same asynchronous-focus path.
A KWin window rule forcing “Accept Focus” did not resolve it.
X11Window::takesAsyncFocus() calls acceptsFocus() directly and does not use the
window-rule-adjusted wantsInput() result.

A reliable diagnostic workaround was found:
Preserve each EVE window’s existing WM_HINTS, but change only its input field
from 0 to 1.
After applying that change, xprop reports:
Client accepts input or input focus: True

Direct desktop switching then works normally in both directions. The
destination EVE client becomes active and clickable, and the Plasma panel
remains hidden.

A small Python Xlib helper was used to apply this only to top-level windows
whose title begins with “EVE -” and whose WM_CLASS matches the affected local
installation. It was also tested against a newly created matching window and
changed its input hint automatically.

This is only a diagnostic workaround, not a proposed upstream solution. The
result suggests that KWin may require a fallback when a globally-active
XWayland client does not complete the expected asynchronous focus handoff.

 _________________________

The following script is used to work around:

  #!/usr/bin/python3
  """Work around KWin 6.7.5 async-focus handling for EVE XWayland windows."""

  import time

  from Xlib import Xatom, display, error


  EVE_CLASS = "steam_app_3379096540"
  POLL_SECONDS = 2 


  def correct_eve_windows(connection):
      root = connection.screen().root
      client_list_atom = connection.intern_atom("_NET_CLIENT_LIST")
      clients = root.get_full_property(client_list_atom, Xatom.WINDOW)

      for window_id in clients.value if clients else []: 
          try:
              window = connection.create_resource_object("window",
int(window_id))
              wm_class = tuple(value.lower() for value in
(window.get_wm_class() or ()))
              name = window.get_wm_name() or ""
              if EVE_CLASS not in wm_class or not name.startswith("EVE - "):
                  continue

              current_hints = window.get_wm_hints()
              hints = dict(current_hints._data) if current_hints else {}
              if hints.get("input") == 1:
                  continue

              hints["input"] = 1 
              window.set_wm_hints(hints)
              connection.sync()
              print(f"Corrected focus hint for {name} ({int(window_id):#x})",
flush=True)
          except error.XError:
              continue


  def main():
      connection = display.Display()
      while True:
          correct_eve_windows(connection)
          time.sleep(POLL_SECONDS)


  if __name__ == "__main__":
      main()
~

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to