Add and event and flag to report when a window has been occluded

Adds the SDL_EVENT_WINDOW_OCCLUDED events and the window flag SDL_WINDOW_OCCLUDED to report when the window occlusion state has changed, so that the application can take appropriate measures, as it may wish to suspend drawing, throttle, or otherwise behave in a more energy efficient manner when the window is not visible. When the window is no longer occluded, the SDL_EVENT_WINDOW_EXPOSED event is sent and the occlusion flag is cleared.

This is handled on macOS via the window occlusion state event (available as of 10.9), and via the xdg-shell protocol on Wayland (version 6, wayland-protocols 1.32, passed through in libdecor 0.1.2).
This commit is contained in:
Frank Praznik 2023-06-19 12:47:11 -04:00
parent 7aec9ad4a6
commit 44536b7537
12 changed files with 303 additions and 89 deletions

View file

@ -253,6 +253,7 @@ static void SDL_LogEvent(const SDL_Event *event)
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_ICCPROF_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_OCCLUDED);
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED);
#undef SDL_WINDOWEVENT_CASE

View file

@ -62,6 +62,9 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
}
window->flags |= SDL_WINDOW_HIDDEN;
break;
case SDL_EVENT_WINDOW_EXPOSED:
window->flags &= ~SDL_WINDOW_OCCLUDED;
break;
case SDL_EVENT_WINDOW_MOVED:
window->undefined_x = SDL_FALSE;
window->undefined_y = SDL_FALSE;
@ -144,6 +147,12 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
}
window->last_displayID = (SDL_DisplayID)data1;
break;
case SDL_EVENT_WINDOW_OCCLUDED:
if (window->flags & SDL_WINDOW_OCCLUDED) {
return 0;
}
window->flags |= SDL_WINDOW_OCCLUDED;
break;
default:
break;
}
@ -162,7 +171,8 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
if (windowevent == SDL_EVENT_WINDOW_MOVED ||
windowevent == SDL_EVENT_WINDOW_RESIZED ||
windowevent == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ||
windowevent == SDL_EVENT_WINDOW_EXPOSED) {
windowevent == SDL_EVENT_WINDOW_EXPOSED ||
windowevent == SDL_EVENT_WINDOW_OCCLUDED) {
SDL_FilterEvents(RemoveSupercededWindowEvents, &event);
}
posted = (SDL_PushEvent(&event) > 0);