Skip to content

Commit d1d0a50

Browse files
smcvslouken
authored andcommitted
wayland: If GTK is disabled, try to avoid libdecor's GTK plugin
As described in the previous commit, loading GTK while setuid or setgid would result in the process exiting. This is equally true if it's loaded indirectly, for a libdecor plugin. libdecor doesn't currently have any API by which it can be asked to avoid specific plugins, but its GTK plugin declines to initialize if it detects a non-main thread (because GTK documents that it must only be used from the main thread), resulting in libdecor falling back to the lower-priority Cairo plugin. We can make use of this by intentionally initializing libdecor on another thread if we have been asked to avoid GTK. This is a bit of a hack, but at worst it should be harmless. Resolves: libsdl-org/sdl2-compat#564 Signed-off-by: Simon McVittie <[email protected]> (cherry picked from commit 370e940)
1 parent aeca6a7 commit d1d0a50

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/video/wayland/SDL_waylandvideo.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#ifdef SDL_VIDEO_DRIVER_WAYLAND
2525

2626
#include "../../core/linux/SDL_system_theme.h"
27+
#include "../../core/unix/SDL_gtk.h"
2728
#include "../../events/SDL_events_c.h"
2829

2930
#include "SDL_waylandclipboard.h"
@@ -1380,6 +1381,19 @@ static bool should_use_libdecor(SDL_VideoData *data, bool ignore_xdg)
13801381

13811382
return true;
13821383
}
1384+
1385+
static void LibdecorNew(SDL_VideoData *data)
1386+
{
1387+
data->shell.libdecor = libdecor_new(data->display, &libdecor_interface);
1388+
}
1389+
1390+
// Called in another thread, but the UI thread is blocked in SDL_WaitThread
1391+
// during that time, so it should be OK to dereference data without locks
1392+
static int SDLCALL LibdecorNewInThread(void *data)
1393+
{
1394+
LibdecorNew((SDL_VideoData *)data);
1395+
return 0;
1396+
}
13831397
#endif
13841398

13851399
bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg)
@@ -1389,7 +1403,18 @@ bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg)
13891403
return true; // Already loaded!
13901404
}
13911405
if (should_use_libdecor(data, ignore_xdg)) {
1392-
data->shell.libdecor = libdecor_new(data->display, &libdecor_interface);
1406+
if (SDL_CanUseGtk()) {
1407+
LibdecorNew(data);
1408+
} else {
1409+
// Intentionally initialize libdecor in a non-main thread
1410+
// so that it will not use its GTK plugin, but instead will
1411+
// fall back to the Cairo or dummy plugin
1412+
SDL_Thread *thread = SDL_CreateThread(LibdecorNewInThread, "SDL_LibdecorNew", (void *)data);
1413+
// Note that the other thread now "owns" data until we have
1414+
// waited for it, so don't touch data here
1415+
SDL_WaitThread(thread, NULL);
1416+
}
1417+
13931418
return data->shell.libdecor != NULL;
13941419
}
13951420
#endif

0 commit comments

Comments
 (0)