Skip to content

Commit b8a965f

Browse files
committed
sdl3(display): handle window API changes
1 parent 9f82d6c commit b8a965f

File tree

2 files changed

+168
-7
lines changed

2 files changed

+168
-7
lines changed

src_c/display.c

Lines changed: 164 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,15 @@ pg_get_init(PyObject *self, PyObject *_null)
279279
static PyObject *
280280
pg_get_active(PyObject *self, PyObject *_null)
281281
{
282-
Uint32 flags = SDL_GetWindowFlags(pg_GetDefaultWindow());
282+
SDL_WindowFlags flags = SDL_GetWindowFlags(pg_GetDefaultWindow());
283+
284+
#if SDL_VERSION_ATLEAST(3, 0, 0)
285+
return PyBool_FromLong(!(flags & SDL_WINDOW_HIDDEN) &&
286+
!(flags & SDL_WINDOW_MINIMIZED));
287+
#else
283288
return PyBool_FromLong((flags & SDL_WINDOW_SHOWN) &&
284289
!(flags & SDL_WINDOW_MINIMIZED));
290+
#endif
285291
}
286292

287293
/* vidinfo object */
@@ -1077,6 +1083,82 @@ _get_display(SDL_Window *win)
10771083
return display;
10781084
}
10791085

1086+
/* Based on code from sdl2-compat */
1087+
static SDL_Window *
1088+
PG_CreateWindowCompat(const char *title, int x, int y, int w, int h,
1089+
SDL_WindowFlags flags)
1090+
{
1091+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1092+
SDL_Window *window = NULL;
1093+
1094+
SDL_PropertiesID props = SDL_CreateProperties();
1095+
if (!props) {
1096+
return NULL;
1097+
}
1098+
1099+
if (title && *title) {
1100+
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING,
1101+
title);
1102+
}
1103+
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x);
1104+
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
1105+
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, w);
1106+
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, h);
1107+
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags);
1108+
SDL_SetBooleanProperty(
1109+
props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN,
1110+
SDL_GetHintBoolean("SDL_VIDEO_EXTERNAL_CONTEXT", false));
1111+
1112+
window = SDL_CreateWindowWithProperties(props);
1113+
SDL_DestroyProperties(props);
1114+
return window;
1115+
#else
1116+
return SDL_CreateWindow(title, x, y, w, h, flags);
1117+
#endif
1118+
}
1119+
1120+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1121+
/* Returns 0 on success, negative on failure. */
1122+
static int
1123+
PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
1124+
bool non_desktop_fullscreen)
1125+
{
1126+
int ret = -1;
1127+
SDL_DisplayMode **modes = NULL;
1128+
SDL_DisplayMode *chosen_mode = NULL;
1129+
if (!SDL_SetWindowFullscreen(window, fullscreen)) {
1130+
goto end;
1131+
}
1132+
if (fullscreen) {
1133+
if (non_desktop_fullscreen) {
1134+
/* if not desktop fullscreen, get the first display mode available
1135+
*/
1136+
SDL_DisplayID disp = SDL_GetDisplayForWindow(window);
1137+
if (!disp) {
1138+
goto end;
1139+
}
1140+
modes = SDL_GetFullscreenDisplayModes(disp, NULL);
1141+
if (!modes) {
1142+
goto end;
1143+
}
1144+
chosen_mode = modes[0];
1145+
if (!chosen_mode) {
1146+
SDL_SetError("Could not get fullscreen display mode");
1147+
goto end;
1148+
}
1149+
}
1150+
if (!SDL_SetWindowFullscreenMode(window, chosen_mode)) {
1151+
goto end;
1152+
}
1153+
}
1154+
1155+
ret = 0;
1156+
end:
1157+
SDL_free(modes);
1158+
return ret;
1159+
}
1160+
#endif
1161+
10801162
static PyObject *
10811163
pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
10821164
{
@@ -1100,6 +1182,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
11001182
int display = _get_display(win);
11011183
char *title = state->title;
11021184
const char *scale_env, *winid_env;
1185+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1186+
int non_desktop_fullscreen = 0;
1187+
#endif
11031188

11041189
char *keywords[] = {"size", "flags", "depth", "display", "vsync", NULL};
11051190

@@ -1221,12 +1306,22 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12211306

12221307
if (flags & PGS_FULLSCREEN) {
12231308
if (flags & PGS_SCALED) {
1309+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1310+
sdl_flags |= SDL_WINDOW_FULLSCREEN;
1311+
non_desktop_fullscreen = 1;
1312+
#else
12241313
sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1314+
#endif
12251315
}
12261316
else if (w == display_mode->w && h == display_mode->h) {
12271317
/* No need to change physical resolution.
12281318
Borderless fullscreen is preferred when possible */
1319+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1320+
sdl_flags |= SDL_WINDOW_FULLSCREEN;
1321+
non_desktop_fullscreen = 1;
1322+
#else
12291323
sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
1324+
#endif
12301325
}
12311326
else {
12321327
sdl_flags |= SDL_WINDOW_FULLSCREEN;
@@ -1252,15 +1347,19 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12521347
SDL_AddEventWatch(pg_ResizeEventWatch, self);
12531348
}
12541349
}
1350+
#if !SDL_VERSION_ATLEAST(3, 0, 0)
12551351
if (flags & PGS_SHOWN) {
12561352
sdl_flags |= SDL_WINDOW_SHOWN;
12571353
}
1354+
#endif
12581355
if (flags & PGS_HIDDEN) {
12591356
sdl_flags |= SDL_WINDOW_HIDDEN;
12601357
}
1358+
#if !SDL_VERSION_ATLEAST(3, 0, 0)
12611359
if (!(sdl_flags & SDL_WINDOW_HIDDEN)) {
12621360
sdl_flags |= SDL_WINDOW_SHOWN;
12631361
}
1362+
#endif
12641363
if (flags & PGS_OPENGL) {
12651364
/* Must be called before creating context */
12661365
if (flags & PGS_DOUBLEBUF) {
@@ -1289,9 +1388,14 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12891388
if (win) {
12901389
if (SDL_GetWindowDisplayIndex(win) == display) {
12911390
// fullscreen windows don't hold window x and y as needed
1391+
1392+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1393+
if (SDL_GetWindowFlags(win) & SDL_WINDOW_FULLSCREEN) {
1394+
#else
12921395
if (SDL_GetWindowFlags(win) &
12931396
(SDL_WINDOW_FULLSCREEN |
12941397
SDL_WINDOW_FULLSCREEN_DESKTOP)) {
1398+
#endif
12951399
x = state->fullscreen_backup_x;
12961400
y = state->fullscreen_backup_y;
12971401

@@ -1380,19 +1484,27 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
13801484
// SDL doesn't preserve window position in fullscreen mode
13811485
// However, windows coming out of fullscreen need these to go back
13821486
// into the correct position
1487+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1488+
if (sdl_flags & SDL_WINDOW_FULLSCREEN) {
1489+
#else
13831490
if (sdl_flags &
13841491
(SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) {
1492+
#endif
13851493
state->fullscreen_backup_x = x;
13861494
state->fullscreen_backup_y = y;
13871495
}
13881496

13891497
if (!win) {
13901498
/*open window*/
13911499
if (hwnd != 0) {
1500+
/* TODO: figure SDL3 equivalent */
1501+
#if !SDL_VERSION_ATLEAST(3, 0, 0)
13921502
win = SDL_CreateWindowFrom((void *)hwnd);
1503+
#endif
13931504
}
13941505
else {
1395-
win = SDL_CreateWindow(title, x, y, w_1, h_1, sdl_flags);
1506+
win = PG_CreateWindowCompat(title, x, y, w_1, h_1,
1507+
sdl_flags);
13961508
w_actual = w_1;
13971509
h_actual = h_1;
13981510
}
@@ -1417,12 +1529,20 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
14171529
* resize/bordered/hidden changes due to SDL ignoring those
14181530
* changes if the window is fullscreen
14191531
* See https://github.com/pygame/pygame/issues/2711 */
1532+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1533+
if (0 != PG_SetWindowFullscreen(
1534+
win, sdl_flags & SDL_WINDOW_FULLSCREEN,
1535+
non_desktop_fullscreen)) {
1536+
return RAISE(pgExc_SDLError, SDL_GetError());
1537+
}
1538+
#else
14201539
if (0 !=
14211540
SDL_SetWindowFullscreen(
14221541
win, sdl_flags & (SDL_WINDOW_FULLSCREEN |
14231542
SDL_WINDOW_FULLSCREEN_DESKTOP))) {
14241543
return RAISE(pgExc_SDLError, SDL_GetError());
14251544
}
1545+
#endif
14261546

14271547
SDL_SetWindowResizable(win, flags & PGS_RESIZABLE);
14281548
SDL_SetWindowBordered(win, (flags & PGS_NOFRAME) == 0);
@@ -1713,7 +1833,11 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
17131833
!vsync && (((flags & PGS_RESIZABLE) == 0) || !zero_size)) {
17141834
if (((surface->surf->w != w_actual) ||
17151835
(surface->surf->h != h_actual)) &&
1836+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1837+
((surface->surf->flags & SDL_WINDOW_FULLSCREEN) != 0)) {
1838+
#else
17161839
((surface->surf->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0)) {
1840+
#endif
17171841
char buffer[150];
17181842
char *format_string =
17191843
"Requested window was forcibly resized by the OS.\n\t"
@@ -2675,14 +2799,18 @@ static PyObject *
26752799
pg_is_fullscreen(PyObject *self, PyObject *_null)
26762800
{
26772801
SDL_Window *win = pg_GetDefaultWindow();
2678-
int flags;
2802+
SDL_WindowFlags flags;
26792803

26802804
VIDEO_INIT_CHECK();
26812805
if (!win) {
26822806
return RAISE(pgExc_SDLError, "No open window");
26832807
}
26842808

2809+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2810+
flags = SDL_GetWindowFlags(win);
2811+
#else
26852812
flags = SDL_GetWindowFlags(win) & SDL_WINDOW_FULLSCREEN_DESKTOP;
2813+
#endif
26862814

26872815
if (flags & SDL_WINDOW_FULLSCREEN) {
26882816
Py_RETURN_TRUE;
@@ -2907,7 +3035,8 @@ static PyObject *
29073035
pg_toggle_fullscreen(PyObject *self, PyObject *_null)
29083036
{
29093037
SDL_Window *win = pg_GetDefaultWindow();
2910-
int result, flags;
3038+
int result;
3039+
SDL_WindowFlags flags;
29113040
int window_w, window_h, w, h, window_display, x, y;
29123041
pgSurfaceObject *display_surface;
29133042
_DisplayState *state = DISPLAY_MOD_STATE(self);
@@ -3122,8 +3251,12 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
31223251
}
31233252
}
31243253
}
3254+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3255+
else if ((flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) {
3256+
#else
31253257
else if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ==
31263258
SDL_WINDOW_FULLSCREEN_DESKTOP) {
3259+
#endif
31273260
result = SDL_SetWindowFullscreen(win, 0);
31283261
if (result != 0) {
31293262
return RAISE(pgExc_SDLError, SDL_GetError());
@@ -3144,9 +3277,13 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
31443277
1) != 0) {
31453278
return NULL;
31463279
}
3280+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3281+
flags &= ~SDL_WINDOW_FULLSCREEN;
3282+
#else
31473283
flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
3284+
#endif
31483285
/* SDL_WINDOW_FULLSCREEN_DESKTOP includes SDL_WINDOW_FULLSCREEN */
3149-
win = SDL_CreateWindow(state->title, wx, wy, w, h, flags);
3286+
win = PG_CreateWindowCompat(state->title, wx, wy, w, h, flags);
31503287
if (win == NULL) {
31513288
return RAISE(pgExc_SDLError, SDL_GetError());
31523289
}
@@ -3193,15 +3330,23 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
31933330
state->fullscreen_backup_y = y;
31943331

31953332
if (state->unscaled_render) {
3333+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3334+
result = PG_SetWindowFullscreen(win, 1, 0);
3335+
#else
31963336
result =
31973337
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3338+
#endif
31983339
if (result != 0) {
31993340
return RAISE(pgExc_SDLError, SDL_GetError());
32003341
}
32013342
}
32023343
else if (pg_renderer != NULL) {
3344+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3345+
result = PG_SetWindowFullscreen(win, 1, 0);
3346+
#else
32033347
result =
32043348
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3349+
#endif
32053350
if (result != 0) {
32063351
return RAISE(pgExc_SDLError, SDL_GetError());
32073352
}
@@ -3235,8 +3380,12 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32353380
#endif
32363381
}
32373382
else if (state->using_gl) {
3383+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3384+
result = PG_SetWindowFullscreen(win, 1, 0);
3385+
#else
32383386
result =
32393387
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3388+
#endif
32403389
if (result != 0) {
32413390
return RAISE(pgExc_SDLError, SDL_GetError());
32423391
}
@@ -3262,8 +3411,12 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32623411
}
32633412
}
32643413
else if (w == display_mode->w && h == display_mode->h) {
3414+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3415+
result = PG_SetWindowFullscreen(win, 1, 0);
3416+
#else
32653417
result =
32663418
SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP);
3419+
#endif
32673420
if (result != 0) {
32683421
return RAISE(pgExc_SDLError, SDL_GetError());
32693422
}
@@ -3290,7 +3443,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32903443
h != display_surface->surf->h) {
32913444
int wx = SDL_WINDOWPOS_UNDEFINED_DISPLAY(window_display);
32923445
int wy = SDL_WINDOWPOS_UNDEFINED_DISPLAY(window_display);
3293-
win = SDL_CreateWindow(state->title, wx, wy, w, h, flags);
3446+
win = PG_CreateWindowCompat(state->title, wx, wy, w, h, flags);
32943447
if (win == NULL) {
32953448
return RAISE(pgExc_SDLError, SDL_GetError());
32963449
}
@@ -3323,7 +3476,7 @@ pg_display_resize_event(PyObject *self, PyObject *event)
33233476
int wnew = PyLong_AsLong(PyObject_GetAttrString(event, "w"));
33243477
int hnew = PyLong_AsLong(PyObject_GetAttrString(event, "h"));
33253478
SDL_Window *win = pg_GetDefaultWindow();
3326-
int flags;
3479+
SDL_WindowFlags flags;
33273480
int w, h, result;
33283481
_DisplayState *state = DISPLAY_MOD_STATE(self);
33293482
GL_glViewport_Func p_glViewport = NULL;
@@ -3332,10 +3485,14 @@ pg_display_resize_event(PyObject *self, PyObject *event)
33323485
if (!win) {
33333486
return RAISE(pgExc_SDLError, "No open window");
33343487
}
3488+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3489+
flags = SDL_GetWindowFlags(win) & SDL_WINDOW_FULLSCREEN;
33353490

3491+
#else
33363492
flags = SDL_GetWindowFlags(win) &
33373493
(SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP);
33383494

3495+
#endif
33393496
if (flags) {
33403497
return PyLong_FromLong(-1);
33413498
}

src_c/window.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ pg_window_set_fullscreen(SDL_Window *window, int desktop)
331331
goto end;
332332
}
333333
}
334+
335+
if (!SDL_SetWindowFullscreen(window, 1)) {
336+
goto end;
337+
}
334338
if (!SDL_SetWindowFullscreenMode(window, chosen_mode)) {
335339
goto end;
336340
}

0 commit comments

Comments
 (0)