@@ -656,43 +656,46 @@ static void surface_frame_done(void *data, struct wl_callback *cb, uint32_t time
656
656
{
657
657
SDL_WindowData * wind = (SDL_WindowData * )data ;
658
658
659
- /* XXX: This is needed to work around an Nvidia egl-wayland bug due to buffer coordinates
660
- * being used with wl_surface_damage, which causes part of the output to not be
661
- * updated when using a viewport with an output region larger than the source region.
662
- */
663
- if (wl_compositor_get_version (wind -> waylandData -> compositor ) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION ) {
664
- wl_surface_damage_buffer (wind -> surface , 0 , 0 , SDL_MAX_SINT32 , SDL_MAX_SINT32 );
665
- } else {
666
- wl_surface_damage (wind -> surface , 0 , 0 , SDL_MAX_SINT32 , SDL_MAX_SINT32 );
667
- }
668
-
669
659
wind -> drop_interactive_resizes = false;
660
+ wind -> pending_client_viewport_dimensions = false;
670
661
671
- if (wind -> shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME ) {
672
- wind -> shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_SHOWN ;
673
-
674
- // If any child windows are waiting on this window to be shown, show them now
675
- for (SDL_Window * w = wind -> sdlwindow -> first_child ; w ; w = w -> next_sibling ) {
676
- if (w -> internal -> shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_SHOW_PENDING ) {
677
- Wayland_ShowWindow (SDL_GetVideoDevice (), w );
678
- } else if (w -> internal -> reparenting_required ) {
679
- Wayland_SetWindowParent (SDL_GetVideoDevice (), w , w -> parent );
680
- if (w -> flags & SDL_WINDOW_MODAL ) {
681
- Wayland_SetWindowModal (SDL_GetVideoDevice (), w , true);
662
+ if (!(wind -> sdlwindow -> flags & SDL_WINDOW_EXTERNAL )) {
663
+ /* XXX: This is needed to work around an Nvidia egl-wayland bug due to buffer coordinates
664
+ * being used with wl_surface_damage, which causes part of the output to not be
665
+ * updated when using a viewport with an output region larger than the source region.
666
+ */
667
+ if (wl_compositor_get_version (wind -> waylandData -> compositor ) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION ) {
668
+ wl_surface_damage_buffer (wind -> surface , 0 , 0 , SDL_MAX_SINT32 , SDL_MAX_SINT32 );
669
+ } else {
670
+ wl_surface_damage (wind -> surface , 0 , 0 , SDL_MAX_SINT32 , SDL_MAX_SINT32 );
671
+ }
672
+
673
+ if (wind -> shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_FRAME ) {
674
+ wind -> shell_surface_status = WAYLAND_SHELL_SURFACE_STATUS_SHOWN ;
675
+
676
+ // If any child windows are waiting on this window to be shown, show them now
677
+ for (SDL_Window * w = wind -> sdlwindow -> first_child ; w ; w = w -> next_sibling ) {
678
+ if (w -> internal -> shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_SHOW_PENDING ) {
679
+ Wayland_ShowWindow (SDL_GetVideoDevice (), w );
680
+ } else if (w -> internal -> reparenting_required ) {
681
+ Wayland_SetWindowParent (SDL_GetVideoDevice (), w , w -> parent );
682
+ if (w -> flags & SDL_WINDOW_MODAL ) {
683
+ Wayland_SetWindowModal (SDL_GetVideoDevice (), w , true);
684
+ }
682
685
}
683
686
}
684
- }
685
687
686
- /* If the window was initially set to the suspended state, send the occluded event now,
687
- * as we don't want to mark the window as occluded until at least one frame has been submitted.
688
- */
689
- if (wind -> suspended ) {
690
- SDL_SendWindowEvent (wind -> sdlwindow , SDL_EVENT_WINDOW_OCCLUDED , 0 , 0 );
688
+ /* If the window was initially set to the suspended state, send the occluded event now,
689
+ * as we don't want to mark the window as occluded until at least one frame has been submitted.
690
+ */
691
+ if (wind -> suspended ) {
692
+ SDL_SendWindowEvent (wind -> sdlwindow , SDL_EVENT_WINDOW_OCCLUDED , 0 , 0 );
693
+ }
691
694
}
692
695
}
693
696
694
697
wl_callback_destroy (cb );
695
- wind -> surface_frame_callback = wl_surface_frame (wind -> surface );
698
+ wind -> surface_frame_callback = wl_surface_frame (wind -> surface_wrapper );
696
699
wl_callback_add_listener (wind -> surface_frame_callback , & surface_frame_listener , data );
697
700
}
698
701
@@ -2331,6 +2334,13 @@ SDL_FullscreenResult Wayland_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Win
2331
2334
output = NULL ;
2332
2335
}
2333
2336
}
2337
+
2338
+ // Commit to preserve any pending client viewport dimensions before entering fullscreen.
2339
+ if (fullscreen == SDL_FULLSCREEN_OP_ENTER && !(window -> flags & SDL_WINDOW_MAXIMIZED ) &&
2340
+ wind -> pending_client_viewport_dimensions ) {
2341
+ wind -> pending_client_viewport_dimensions = false;
2342
+ wl_surface_commit (wind -> surface );
2343
+ }
2334
2344
SetFullscreen (window , output , !!fullscreen );
2335
2345
} else if (wind -> is_fullscreen ) {
2336
2346
/*
@@ -2459,8 +2469,11 @@ void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
2459
2469
return ; // Can't do anything yet, wait for ShowWindow
2460
2470
}
2461
2471
2462
- // Commit to preserve any pending size data.
2463
- wl_surface_commit (wind -> surface );
2472
+ // Commit to preserve any pending viewport size data.
2473
+ if (wind -> pending_client_viewport_dimensions ) {
2474
+ wind -> pending_client_viewport_dimensions = false;
2475
+ wl_surface_commit (wind -> surface );
2476
+ }
2464
2477
libdecor_frame_set_maximized (wind -> shell_surface .libdecor .frame );
2465
2478
2466
2479
++ wind -> window_state_deadline_count ;
@@ -2473,8 +2486,11 @@ void Wayland_MaximizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
2473
2486
return ; // Can't do anything yet, wait for ShowWindow
2474
2487
}
2475
2488
2476
- // Commit to preserve any pending size data.
2477
- wl_surface_commit (wind -> surface );
2489
+ // Commit to preserve any pending viewport size data.
2490
+ if (wind -> pending_client_viewport_dimensions ) {
2491
+ wind -> pending_client_viewport_dimensions = false;
2492
+ wl_surface_commit (wind -> surface );
2493
+ }
2478
2494
xdg_toplevel_set_maximized (wind -> shell_surface .xdg .toplevel .xdg_toplevel );
2479
2495
2480
2496
++ wind -> window_state_deadline_count ;
@@ -2716,12 +2732,10 @@ bool Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Proper
2716
2732
wl_callback_add_listener (data -> gles_swap_frame_callback , & gles_swap_frame_listener , data );
2717
2733
}
2718
2734
2719
- // No frame callback on external surfaces as it may already have one attached.
2720
- if (!external_surface ) {
2721
- // Fire a callback when the compositor wants a new frame to set the surface damage region.
2722
- data -> surface_frame_callback = wl_surface_frame (data -> surface );
2723
- wl_callback_add_listener (data -> surface_frame_callback , & surface_frame_listener , data );
2724
- }
2735
+ // Fire a callback when the compositor wants a new frame.
2736
+ data -> surface_wrapper = WAYLAND_wl_proxy_create_wrapper (data -> surface );
2737
+ data -> surface_frame_callback = wl_surface_frame (data -> surface_wrapper );
2738
+ wl_callback_add_listener (data -> surface_frame_callback , & surface_frame_listener , data );
2725
2739
2726
2740
if (window -> flags & SDL_WINDOW_TRANSPARENT ) {
2727
2741
if (_this -> gl_config .alpha_size == 0 ) {
@@ -2853,6 +2867,11 @@ void Wayland_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
2853
2867
wind -> requested .pixel_height = window -> pending .h ;
2854
2868
}
2855
2869
2870
+ if (wind -> requested .logical_width != wind -> current .logical_width ||
2871
+ wind -> requested .logical_height != wind -> current .logical_height ) {
2872
+ wind -> pending_client_viewport_dimensions = true;
2873
+ }
2874
+
2856
2875
ConfigureWindowGeometry (window );
2857
2876
} else {
2858
2877
// Can't resize the window.
0 commit comments