@@ -453,24 +453,6 @@ void wxGLCanvasEGL::OnWLFrameCallback()
453
453
#ifdef GDK_WINDOWING_WAYLAND
454
454
wxLogTrace (TRACE_EGL, " In frame callback handler for %p" , this );
455
455
456
- if ( !gs_alreadySetSwapInterval.count (this ) )
457
- {
458
- // Ensure that eglSwapBuffers() doesn't block, as we use the surface
459
- // callback to know when we should draw ourselves already.
460
- if ( eglSwapInterval (m_display, 0 ) )
461
- {
462
- wxLogTrace (TRACE_EGL, " Set EGL swap interval to 0 for %p" , this );
463
-
464
- // It shouldn't be necessary to set it again.
465
- gs_alreadySetSwapInterval.insert (this );
466
- }
467
- else
468
- {
469
- wxLogTrace (TRACE_EGL, " eglSwapInterval(0) failed for %p: %#x" ,
470
- this , eglGetError ());
471
- }
472
- }
473
-
474
456
m_readyToDraw = true ;
475
457
g_clear_pointer (&m_wlFrameCallbackHandler, wl_callback_destroy);
476
458
SendSizeEvent ();
@@ -803,15 +785,40 @@ void wxGLCanvasEGL::FreeDefaultConfig()
803
785
804
786
bool wxGLCanvasEGL::SwapBuffers ()
805
787
{
788
+ // Before doing anything else, ensure that eglSwapBuffers() doesn't block:
789
+ // under Wayland we don't want it to because we use the surface callback to
790
+ // know when we should draw anyhow and with X11 it blocks for up to a
791
+ // second when the window is entirely occluded and because we can't detect
792
+ // this currently (our IsShownOnScreen() doesn't account for all cases in
793
+ // which this happens) we must prevent it from blocking to avoid making the
794
+ // entire application completely unusable just because one of its windows
795
+ // using wxGLCanvas got occluded or unmapped (e.g. due to a move to another
796
+ // workspace).
797
+ if ( !gs_alreadySetSwapInterval.count (this ) )
798
+ {
799
+ // Ensure that eglSwapBuffers() doesn't block, as we use the surface
800
+ // callback to know when we should draw ourselves already.
801
+ if ( eglSwapInterval (m_display, 0 ) )
802
+ {
803
+ wxLogTrace (TRACE_EGL, " Set EGL swap interval to 0 for %p" , this );
804
+
805
+ // It shouldn't be necessary to set it again.
806
+ gs_alreadySetSwapInterval.insert (this );
807
+ }
808
+ else
809
+ {
810
+ wxLogTrace (TRACE_EGL, " eglSwapInterval(0) failed for %p: %#x" ,
811
+ this , eglGetError ());
812
+ }
813
+ }
814
+
806
815
GdkWindow* const window = GTKGetDrawingWindow ();
807
816
#ifdef GDK_WINDOWING_X11
808
817
if (wxGTKImpl::IsX11 (window))
809
818
{
810
819
if ( !IsShownOnScreen () )
811
820
{
812
- // Trying to draw on a hidden window is useless and can actually be
813
- // harmful if the compositor blocks in eglSwapBuffers() in this
814
- // case, so avoid it.
821
+ // Trying to draw on a hidden window is useless.
815
822
wxLogTrace (TRACE_EGL, " Window %p is hidden, not drawing" , this );
816
823
return false ;
817
824
}
0 commit comments