Skip to content

Cache find_client_win results to avoid repeated XQueryTree scans - #41

Open
jEsuSdA wants to merge 1 commit into
tycho-kirchner:masterfrom
jEsuSdA:fix/cache-client-win-lookup
Open

Cache find_client_win results to avoid repeated XQueryTree scans#41
jEsuSdA wants to merge 1 commit into
tycho-kirchner:masterfrom
jEsuSdA:fix/cache-client-win-lookup

Conversation

@jEsuSdA

@jEsuSdA jEsuSdA commented Jul 2, 2026

Copy link
Copy Markdown

Summary

Caches find_client_win() results to eliminate repeated expensive XQueryTree() recursive scans on every frame.

Problem

find_client_win() recursively calls XQueryTree() to locate the actual client window within a toplevel window hierarchy. This is expensive and currently called:

  • on every call to get_frame_extents() (which reads _NET_FRAME_EXTENTS)
  • in win_paint_needed() when the hidden state is still HIDDEN_UNKNOWN

For windows without a client window (e.g. override_redirect windows, or windows where the WM doesn't create a client), this results in a full recursive scan of the window hierarchy on every frame.

Solution

Add Bool client_id_resolved and Window client_id fields to the win struct. The first call to find_client_win() stores the result; subsequent calls reuse the cached value.

The cache is invalidated on ReparentNotify events because the window hierarchy may have changed (e.g., when the window manager restarts and reparents windows).

Changes

  • cm-window.h — adds client_id_resolved and client_id fields to win struct
  • fastcompmgr.c — uses the cache in get_frame_extents() and win_paint_needed(), invalidates on reparent in add_damage_if_hidden_changed()

Scope

  • cm-window.h and fastcompmgr.c only
  • make clean && make produces zero warnings, zero errors
  • Fields are zero-initialized by calloc() in add_win()

Impact

Eliminates repeated XQueryTree() recursive scans for windows whose client window doesn't change. Most noticeable for windows without a client (e.g. override_redirect popups, menus), which previously triggered a full hierarchy scan on every frame.

find_client_win() recursively calls XQueryTree() to locate the actual
client window within a toplevel window hierarchy. This is expensive and
currently called on every frame for windows where the hidden state is
unknown or for every call to get_frame_extents().

Add a client_id_resolved flag and client_id Window field to the win struct.
The first call to find_client_win() stores the result; subsequent calls
reuse the cached value. This eliminates the repeated XQueryTree scans.

The cache is invalidated on ReparentNotify events because the window
hierarchy may have changed (e.g., when the window manager restarts and
reparents windows).
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