Closed Be-ing closed 10 months ago
The timer example is helpful to test this:
cargo run -p _7guis --bin timer
With SLINT_BACKEND=Qt
, I cannot reproduce this, but I can with SLINT_BACKEND=winit-femtovg
and SLINT_BACKEND=winit-skia
.
I cannot reproduce this with winit-femtovg
nor winit-skia
on X11. It seems to be specific to winit on Wayland. Maybe there is an upstream bug in winit?
Slint relies on the Event::NewEvent in winit's EventLoop callback to update timers. Evidently that isn't sufficient on Wayland.
I cannot reproduce this on GNOME, but GNOME doesn't really have a concept of minimizing windows.
This is also not reproducible on macOS.
I can reproduce this on Linux with Weston.
I can't reproduce this (yet) with winit's control_flow example, so there's still a chance that this is an issue with Slint's use of winit.
Hm, I tried a minimal Slint example that doesn't even show a window, so just replacing the run()
in the timer example with slint::run_event_loop();
- but oddly enough that works! So it really seems somehow related to minimising the window.
I cannot reproduce this on GNOME, but GNOME doesn't really have a concept of minimizing windows.
I can recreate this on gnome just by having the window fully hidden.
Edit: to clarify, hidden behind another window. For example I have a small slint window and when I drag a bigger window over it the timer stops. I meant to capture a video but forgot to hit record, where I was half tiling the VSCodium window, and would make it bigger until it fully overlapped my Slint window. As soon as the Slint window was fully covered the timer stopped, and would start again when I shrank the Code window again....I'll see if I can make a recording
Edit 2: I should test what happens when its not on the active workspace, see if that also stops the timer.
I can reproduce with weston. If i add a println in the printerdemo when the timer is executed, and minimize the window, it is clear that the timer is only ran once.
Slint recieve a RedrawRequested
event from winit for the hidden window. Then nothing else (no AboutToWait
In fact, the process is blocked in eglSwapBuffers
within femtovg.
Full backtrace:
#0 0x00007ffff7d1a18f in __GI___poll (fds=fds@entry=0x7fffffff9240, nfds=nfds@entry=1, timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1 0x00007ffff7fb2f3c in poll (__timeout=-1, __nfds=1, __fds=0x7fffffff9240) at /usr/include/x86_64-linux-gnu/bits/poll2.h:39
#2 wl_display_poll (display=0x5555572e58b0, events=1) at ../src/wayland-client.c:1914
#3 wl_display_dispatch_queue (queue=<optimized out>, display=<optimized out>) at ../src/wayland-client.c:1987
#4 wl_display_dispatch_queue (display=0x5555572e58b0, queue=0x55555738f0e0) at ../src/wayland-client.c:1960
#5 0x00007ffff777a5a4 in dri2_wl_swap_buffers_with_damage (disp=<optimized out>, draw=0x5555573a7720, rects=0x0, n_rects=0) at ../src/egl/drivers/dri2/platform_wayland.c:1616
#6 0x00007ffff776f087 in dri2_swap_buffers (disp=0x555557427370, surf=0x5555573a7720) at ../src/egl/drivers/dri2/egl_dri2.c:1881
#7 0x00007ffff77636bd in eglSwapBuffers (dpy=<optimized out>, surface=0x5555573a7720) at ../src/egl/main/eglapi.c:1433
#8 0x0000555555c65091 in glutin_egl_sys::egl::Egl::SwapBuffers (self=0x5555572d9260 <glutin::api::egl::EGL+16>, dpy=0x555557427370, surface=0x5555573a7720)
at target/debug/build/glutin_egl_sys-3a172a1d9b482170/out/egl_bindings.rs:593
#9 0x0000555555cd180d in glutin::api::egl::surface::{impl#3}::swap_buffers<glutin::surface::WindowSurface> (self=0x555557394388, context=0x555557394368)
at /home/olivier/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glutin-0.31.1/src/api/egl/surface.rs:358
#10 0x0000555555ccf418 in glutin::surface::{impl#11}::swap_buffers<glutin::surface::WindowSurface> (self=0x555557394388, context=0x555557394360)
at /home/olivier/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glutin-0.31.1/src/surface.rs:319
#11 0x0000555555c49b64 in i_slint_backend_winit::renderer::femtovg::glcontext::{impl#0}::swap_buffers (self=0x555557394360) at internal/backends/winit/renderer/femtovg/glcontext.rs:30
#12 0x000055555611758a in i_slint_renderer_femtovg::FemtoVGRenderer::internal_render_with_post_callback (self=0x5555581d46d0, rotation_angle_degrees=0, translation=..., surface_size=..., post_render_cb=...)
at internal/renderers/femtovg/lib.rs:317
#13 0x0000555556116d87 in i_slint_renderer_femtovg::FemtoVGRenderer::render (self=0x5555581d46d0) at internal/renderers/femtovg/lib.rs:174
#14 0x0000555555c991ab in i_slint_backend_winit::renderer::femtovg::{impl#1}::render (self=0x5555581d46d0, _window=0x555557331ca8) at internal/backends/winit/renderer/femtovg.rs:58
#15 0x0000555555bcdd6f in i_slint_backend_winit::winitwindowadapter::WinitWindowAdapter::draw (self=0x555557331b90) at internal/backends/winit/winitwindowadapter.rs:256
#16 0x0000555555c623ba in i_slint_backend_winit::event_loop::EventLoopState::process_event (self=0x7fffffffd6b8, event=..., event_loop_target=0x5555572f6640) at internal/backends/winit/event_loop.rs:456
#17 0x0000555555be0ed2 in i_slint_backend_winit::event_loop::{impl#6}::run::{closure#2}::{closure#0} () at internal/backends/winit/event_loop.rs:640
#18 0x0000555555be17d1 in i_slint_backend_winit::event_loop::CURRENT_WINDOW_TARGET::set<i_slint_backend_winit::event_loop::{impl#6}::run::{closure#2}::{closure_env#0}, ()> (
self=0x5555571afed8 <i_slint_backend_winit::event_loop::CURRENT_WINDOW_TARGET>, t=0x7fffffffa160, f=...) at /home/olivier/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-hkt-0.1.4/src/lib.rs:265
#19 0x0000555555be0e7e in i_slint_backend_winit::event_loop::{impl#6}::run::{closure#2} (event=..., event_loop_target=0x5555572f6640) at internal/backends/winit/event_loop.rs:639
#20 0x0000555555bdef2f in core::ops::function::impls::{impl#3}::call_mut<(winit::event::Event<i_slint_backend_winit::SlintUserEvent>, &winit::event_loop::EventLoopWindowTarget<i_slint_backend_winit::SlintUserEvent>), i_sl
int_backend_winit::event_loop::{impl#6}::run::{closure_env#2}> (self=0x7fffffffbd60, args=...) at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:294
#21 0x0000555555bdf020 in core::ops::function::impls::{impl#3}::call_mut<(winit::event::Event<i_slint_backend_winit::SlintUserEvent>, &winit::event_loop::EventLoopWindowTarget<i_slint_backend_winit::SlintUserEvent>), &mut
i_slint_backend_winit::event_loop::{impl#6}::run::{closure_env#2}> (self=0x7fffffffbbb0, args=...) at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:294
#22 0x0000555555c2ecaf in winit::platform_impl::platform::wayland::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>::single_iteration<i_slint_backend_winit::SlintUserEvent, &mut &mut i_slint_backend_winit::eve
nt_loop::{impl#6}::run::{closure_env#2}> (self=0x5555572f6590, callback=0x7fffffffbbb0, cause=...)
at /home/olivier/.cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.29.4/src/platform_impl/linux/wayland/event_loop/mod.rs:504
#23 0x0000555555c342b8 in winit::platform_impl::platform::wayland::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>::poll_events_with_timeout<i_slint_backend_winit::SlintUserEvent, &mut &mut i_slint_backend_wi
nit::event_loop::{impl#6}::run::{closure_env#2}> (self=0x5555572f6590, timeout=..., callback=0x7fffffffbd60)
at /home/olivier/.cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.29.4/src/platform_impl/linux/wayland/event_loop/mod.rs:323
#24 0x0000555555c2de75 in winit::platform_impl::platform::wayland::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>::pump_events<i_slint_backend_winit::SlintUserEvent, &mut i_slint_backend_winit::event_loop::{
@tronical: should we somehow detect in Slint that the window is minimized or and avoid calling swap_buffers until the window is back visible?
(the problem is not reproducable with the software renderer, but can be reproduced with femtovg and skia renderer)
should we somehow detect in Slint that the window is minimized or and avoid calling swap_buffers until the window is back visible?
Perhaps that's indeed be the only way out :(. It sucks that we're even getting a RedrawRequest in the first place. The only alternative I can think of is #4200 . Winit's API here that we should use will use wayland frame callbacks, which should cover this.
Olivier, could you give the wayland-throttle
branch a try?
The wayland-throttle branch doesn't solve the problem.
(But it changes the backtrace a bit so the draw
is now called from AboutToWait in https://github.com/slint-ui/slint/blob/0dd46ad4b79dd8a57a14690176dd9310855861cf/internal/backends/winit/event_loop.rs#L561 , and it is still blocked in eglSwapBuffers
)
Removing the windows_with_pending_redraw_requests
hack entirely seems to fix the problem. Maybe this should only be done on platform which have that bug?
I can confirm. The hack might be safe to remove after https://github.com/rust-windowing/winit/issues/3150 . It works for me only with the frame callbacks and the hack removed.
I'll try to verify that the hack can be safely removed and make a PR for that. After that I can try to implement the frame throttling - we need it anyway.
Removing the windows_with_pending_redraw_requests hack entirely seems to fix the problem. Maybe this should only be done on platform which have that bug?
Just tried Slint master branch after #4253 was merged and I can still reproduce https://codeberg.org/moire/moire/issues/73
Yes, https://github.com/slint-ui/slint/pull/4258 is also needed. That's why I haven't closed this issue yet :)
After merging #4258 this works for me now :)
Now it works after a cargo update
:)
Using renderer-winit-femtovg feature on Wayland (KWin), Timer callbacks do not get executed when the window is minimized.
Context: https://codeberg.org/moire/moire/issues/73