-
-
Save biochem-fan/df3adcb033a90cf31e148230e505279d to your computer and use it in GitHub Desktop.
| # 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() |
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
editresworks, can you test remoteeditresoverssh -X? If this fails, remote X programs might need other fixes. - Can you also test
gvimrunning locally? If this fails, this fix might not be sufficient for certain GUI toolkits.
adding
if attrs.win_class != 1:
return
before line 17 fixes BadMatch error (don't ask)
adding
if attrs.win_class != 1: returnbefore line 17 fixes BadMatch error (don't ask)
Confirm. Adding these two lines does seem to address the BadMatch errors.
Can you confirm this fixes
editresrunning locally? This is what I have tested. I haven't tested this on remote applications running overssh -X. Another possibility is that this fix is not enough for certain GUI toolkits.
- If local
editresworks, can you test remoteeditresoverssh -X? If this fails, remote X programs might need other fixes.- Can you also test
gvimrunning 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.
adding
if attrs.win_class != 1: returnbefore 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.
I use ssh to connect to multiple linux computers and use gvim for editing, viewing diffs across multiple files and servers. I also use gvimdiff with git to confirm changes before commits. I can eventually force a refresh by resizing but it can take several tries. The refresh bug with OSX 26 Tahoe has really interfered with my workflow as I'm now having to resize windows everytime I run gvim which can be dozens at a time.
I tried your repaint-upon-resize.py script after figuring out how to install python3-xlib and after uncommenting the repaint-window debug messages I do see those messages but I don't think the script is helping at least with gvim. I do see lots of the BadMatch errors you mention in the comments. I also run a lot of xterms for tailing logs and they don't seem to have a problem with the refresh.