Skip to content

Instantly share code, notes, and snippets.

@biochem-fan
Created November 26, 2025 06:03
Show Gist options
  • Select an option

  • Save biochem-fan/df3adcb033a90cf31e148230e505279d to your computer and use it in GitHub Desktop.

Select an option

Save biochem-fan/df3adcb033a90cf31e148230e505279d to your computer and use it in GitHub Desktop.
Force X Window repaint upon resize
# This is a hacky workaround for the XQuartz repaint bug reported in
# https://github.com/XQuartz/XQuartz/issues/438.
# This requires python-xlib.
#
# FIXME:
# - I don't know how to get rid of BadMatch errors.
# - Sometimes you need to explicitly set DISPLAY as:
# DISPLAY=:0 python repaint-upon-resize.py
# - Ctrl-C does not work even though I catch KeyboardInterrupt.
import sys
from Xlib import X, display, error
def redraw_window_recursively(window, d):
try:
attrs = window.get_attributes()
if attrs.map_state == X.IsViewable:
# print("Repaint window", window)
window.clear_area(x=0, y=0, width=0, height=0, exposures=True)
tree = window.query_tree()
for child in tree.children:
redraw_window_recursively(child, d)
except error.XError:
pass
def detect_window_resize():
try:
d = display.Display()
except error.DisplayError:
print("Cannot connect to the X server.", file=sys.stderr)
sys.exit(1)
root = d.screen().root
event_mask = X.SubstructureNotifyMask | X.StructureNotifyMask
root.change_attributes(event_mask=event_mask)
while True:
try:
event = d.next_event()
if event.type == X.ConfigureNotify:
window_id = event.window.id
window = d.create_resource_object('window', window_id)
redraw_window_recursively(window, d)
except KeyboardInterrupt:
break
except:
continue
if __name__ == "__main__":
detect_window_resize()
@cafelizardo
Copy link

Can you confirm this fixes editres running locally? This is what I have tested. I haven't tested this on remote applications running over ssh -X. Another possibility is that this fix is not enough for certain GUI toolkits.

  • If local editres works, can you test remote editres over ssh -X? If this fails, remote X programs might need other fixes.
  • Can you also test gvim running locally? If this fails, this fix might not be sufficient for certain GUI toolkits.

I am not familiar with editors and it does not appear to be installed on the remote linux machines. It does run on my Mac and comes up okay initially but as soon as I resize I get the black panels.

On my Mac I use mvim which I believe is a native app, not X11, with simlinks for vi* and gv* so it's transparent for me.

This pretty much breaks my workflow so I will be downgrading my Mac Mini M1 back to sequoia as soon as I can. Hopefully someone finds a workable solution before I need to update to 26.

@cafelizardo
Copy link

adding

    if attrs.win_class != 1:
        return

before line 17 fixes BadMatch error (don't ask)

Confirm. Adding these two lines does seem to address the BadMatch errors.

oops. let me retract the confirmation. If I add the lines to return early then I don't see my debug message saying it is repainting the window at new line 22 so it's skipping everything.

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