community icon indicating copy to clipboard operation
community copied to clipboard

Resizing on linux is incredibly slow [LINUX]

Open Neeko-iko opened this issue 5 months ago • 3 comments

Software Versions

  • Python: 3.12
  • OS: Arch Linux
  • Kivy: 2.3.1 from pip, and Archipelago bundled 2.3.1
  • Kivy installation method: pip wheel and bundled package

Describe the bug when resizing the window, it remembers every frame and takes ages to get to each when resizing videos showing what i mean:

https://github.com/user-attachments/assets/91d43995-b18e-4999-9ea5-f2d3d265ae54 https://github.com/user-attachments/assets/da24aa7d-0df5-4c6c-9c37-72c83b72c273 one is the Archipelago app the other is the text example found in this repo, using kivy 2.3.1 from pip

Expected behavior resizing to behave, this isn't my system being slow, other applications work fine even during this process.

To Reproduce be on Wayland (unsure if wayland only) desktop on Arch Linux and resize any kivy app, can even use the text example found at: https://github.com/kivy/kivy/blob/master/examples/text/pango_demo.py

Additional context unsure if this is at all related to https://github.com/kivy/kivy/issues/8150, i don't think it is, as many xwayland apps don't have this issue, but i can't find anything else even tangentially related

also, when this is happening the UI of either app becomes unusable until it finishes - which makes this much much more frusterating.

Neeko-iko avatar Aug 01 '25 01:08 Neeko-iko

I once had the same issue and worked around it by enabling "Don't show window content while dragging them" in my window manager settings. Your window manager probably has a similar option — I recommend trying it.

gottadiveintopython avatar Aug 10 '25 22:08 gottadiveintopython

Can confirm, same happening on Linux in the Sideband application, and it's super annoying.

The issue is caused by this line: https://github.com/kivy/kivy/blob/9cc56fbd0da3c2654afe09a827d814c365d01d46/kivy/core/window/window_sdl2.py#L244

elif action == 'windowresized':
    self._size = largs
    self._win.resize_window(*self._size)
    # Force kivy to render the frame now, so that the canvas is drawn.
    EventLoop.idle() # <-- This is the problem

Since resize events will be queued and can be sent at a very high rate, that line forces Kivy to render a frame for each of the received resize events!

Probably, it should just be removed, or at least have some sort of throttling applied. I can't imagine that rendering every single resize event as a separate frame is the intended behaviour ;)

markqvist avatar Nov 04 '25 13:11 markqvist

For anyone else who got too tired of this, here's a run-time patch to fix it from your own app:

###################################################
# Kivy/SDL2 run-time patch to fix horribly slow
# window resize updates on Linux. For more info:
# https://github.com/kivy/kivy/issues/9106
#
_sdl2_window_event_filter_original = None
_sdl2_window_event_filter_instance = None
def _sdl2_window_event_filter_proxy(action, *largs):
    global _sdl2_window_event_filter_original
    global _sdl2_window_event_filter_instance
    if not action == 'windowresized': return _sdl2_window_event_filter_original(action, *largs)
    else:
        _sdl2_window_event_filter_instance._size = largs
        _sdl2_window_event_filter_instance._win.resize_window(*_sdl2_window_event_filter_instance._size)
        # The only change this patched method makes is to
        # remove the offending "EventLoop.idle()" statement
        # EventLoop.idle()
        return 0
     
def patch_sdl_window_events(patch_target):
    if RNS.vendor.platformutils.is_linux():
        global _sdl2_window_event_filter_original
        global _sdl2_window_event_filter_instance
        _sdl2_window_event_filter_original = patch_target._event_filter
        _sdl2_window_event_filter_instance = patch_target
        patch_target._event_filter = _sdl2_window_event_filter_proxy
        patch_target._win.set_event_filter(patch_target._event_filter)
#
# End of Kivy/SDL2 patch ##########################

# Somewhere in your code after app init:
patch_sdl_window_events(Window)

markqvist avatar Nov 04 '25 14:11 markqvist