Closed gojzdar closed 10 months ago
I have tried many hacks, like adding a delay between SDL_CreateWindow and every possible combination I could think of and set up environmental variables to toggle composition but still nothing.
SDL uses libdecor to draw the window decorations on Wayland.
At SDL build time, you need the libdecor-dev package. At runtime, you need libdecor.
(Verify SDL_WAYLAND_LIBDECOR
is enabled at the end of CMake configuration)
Wayland needs you to draw something before it creates a window.
Add the following code after the call to SDL_CreateWindow
SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
and do the following just before the SDL_Delay
.
SDL_RenderPresent(pRenderer);
@woxels About https://github.com/libsdl-org/SDL/issues/8185#issuecomment-1732209403. You might have the same problem.
Still nothing. And I doubt this has much to do with Wayland since the same issue occurs on KDE X11 and XFCE. Another thing. When l logged out I saw a message "amd topaz is not supported" or something similar. Still, I doubt this has anything to do with this, since I successfully compiled and ran SDL programs before on the exact same OS, exact same PC and zero updates in between except a few program installations (namely docker)
What I did:
Added SET(SDL_WAYLAND_LIBDECOR 1)
to the end of CMakeLists.txt
Modified the code to be:
#include <SDL_events.h>
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char** argv)
{
puts("Started program!\n");
if (SDL_Init(SDL_INIT_VIDEO) != 0 )
{
fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
return -1;
}
{
SDL_Window* pWindow = NULL;
auto fgs = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_ALWAYS_ON_TOP;
pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
643,
487,
fgs);
SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
if( pWindow )
{
for(int i = 0; i < 100; i++) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
// do nothing
switch(event.type) {
case SDL_QUIT:
i = 1000;
break;
}
}
SDL_RenderPresent(pRenderer);
SDL_Delay(100);
}
SDL_DestroyWindow(pWindow);
}
else
{
fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
}
}
SDL_Quit();
return 0;
}
SET(SDL_WAYLAND_LIBDECOR 1)
won't do anything.
SDL_WAYLAND_LIBDECOR
is merely a hint for the cmake script to look for it.
Please manually verify the output of the cmake configuration.
Since you didn't correct me, I guess it is a variable. The output of this block did not contain anything about wayland. Granted, I compiled it whilst on X11, but that shouldn't really make a difference since CMake instide the docker container can't see the difference. And again, not sure what Wayland has to do with the window not showing up since it doesn't work even outside of wayland.
get_cmake_property(_variableNames VARIABLES)
list (SORT _variableNames)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
Thank you for taking the time
Any other ideas? Still not working...
@woxels please create a new issue from scratch. One SDL binary is able to support both x11 and wayland.
Any other ideas? Still not working...
The above sample code works as expected when I build it on Fedora 38, although I had to drop the #include <SDL_events.h>
line, so the only thing I can think of is that there is some misconfiguration on your specific system.
Does it build cleanly and work if you build it with no docker or CMake, just g++ main.cpp -lSDL2 -o sdl_test
?
Any other ideas? Still not working...
The above sample code works as expected when I build it on Fedora 38, although I had to drop the
#include <SDL_events.h>
line, so the only thing I can think of is that there is some misconfiguration on your specific system.Does it build cleanly and work if you build it with no docker or CMake, just
g++ main.cpp -lSDL2 -o sdl_test
?
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char** argv)
{
puts("Started program!\n");
if (SDL_Init(SDL_INIT_VIDEO) != 0 )
{
fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
return -1;
}
{
SDL_Window* pWindow = NULL;
auto fgs = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_ALWAYS_ON_TOP;
pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
643,
900,
fgs);
SDL_Renderer *pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
if( pWindow )
{
for(int i = 0; i < 100; i++) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
// do nothing
switch(event.type) {
case SDL_QUIT:
i = 1000;
break;
}
}
SDL_RenderPresent(pRenderer);
SDL_Delay(100);
}
SDL_DestroyWindow(pWindow);
}
else
{
fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
}
}
SDL_Quit();
return 0;
}
Compiled with
g++ main.cpp -lSDL2 -o sdl_test
Resulted in no window appearing.
I can try using some library other than SDL, but not really sure which one I should try. And in that case, I would also appreciate the actual code I should compile so I can avoid some pitfalls which might result in the program not working.
If I can't fix this issue, I'll be forced to switch to an alternative. Any suggestions? Requirements:
Using x11docker, I get the following error:
INFO: SDL_CreateWindowAndRenderer failed (failed to create an EGL window surface)
@Kontrabant Do you know what I'm doing wrong?
Steps to reproduce:
gcc -o app app.c -lSDL2 -I/usr/include/SDL2
docker build -t vm_wayland .
(do this again whenever you rebuild the app)x11docker --wayland vm_wayland /app/app
Wayland still uses a hardware texture to scan out, even with software rendering. I think Docker needs to be started with --gpu
(Nvidia might require more configuration).
The only other suggestion I have for the original issue is to try and verify or reinstall all the relevant packages and maybe try building SDL from source to see if that helps. I can't replicate the issue, and if the sample code doesn't work for the OP even in the simplest case with no build systems or containers in the way, that would seem to suggest a bad package or misconfiguration on their specific system.
I got it working by also installing libgl1
. (--gpu
was not needed for my example)
So these are the minimal packages required to run sdl2 in a docker container:
libwayland-client0 libdecor-0-0 libsdl2-2.0-0 libegl1 libgl1
(add libgles2
for the opengles2
renderer)
try building SDL from source to see if that helps
I just built it from source and ran the tests. Both main and SDL2 branch are working, at least for testdrawchessboard and testdraw2 files. I don't have any time right now so I'll try more tomorrow.
The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.
Is it worth trying to build SDL from source inside a docker container? Would it should still work right? So the issue is that both the SDL apt package and SDL vcpkg package are not configured correctly for me? Is there a way to troubleshoot the issue now that I have a working copy, or is that too hard to do? I should probably try to build the same source code with my toolchain, SDL-dev packages and from source.
The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.
Some SDL3 tests have a --fullscreen
argument. Does it also happen with these?
Does the black screen delay happen when running the test outside the docker container?
Is it worth trying to build SDL from source inside a docker container? Would it should still work right?
If you install the same packages we install on ci, it should result in a working SDL3 FYI, you can download binaries from the actions page so you can compare with a "known good" (SDL2 does not provide binaries).
So the issue is that both the SDL apt package and SDL vcpkg package are not configured correctly for me? Is there a way to troubleshoot the issue now that I have a working copy, or is that too hard to do?
It would surprise me Ubuntu's package to be non-functional. In my use of docker above, I built the app with Fedora's SDL2 and ran it with Ubuntu's SDL2 inside a container. But you can always build the SDL2 tests and run them against various SDL2 libraries (using LD_LIBRARY_PATH
). vcpkg should allow you to compare the cmake configure arguments easily.
Progress update:
since I used cmake --install
on both SDL2 and SDL3 build directories. Now compiling with -lSDL2 and -lSDL3 works.
However SDL3 stopped working after installing SDL2. Not sure when exactly, if right after the installation or when I renamed the parent folder of the build dir from SDL to SDL3 to avoid confusion. However, the issue was fixed after I used sudo ldconfig
. And is it safe to alter/remove the build directories after I used cmake install?
So right now, compiling with the recommended CMake file works (the one provided in README-cmake.md) and also using the system libraries.
Just to makes things clear, I use docker only as a compilation tool chain. I run the compiled programs outside of it.
The only issue is that when I start the program, the whole screen turns black for half a second and the same happens when I stop it.
The issue seems to have fixed itself.
Some SDL3 tests have a --fullscreen argument. Does it also happen with these?
When I try to use the --fullscreen flag on SDL3 tests, the screen flickers a few times before the display resolution matches the app's.
If you install the same packages we install on ci, it should result in a working SDL3 FYI, you can download binaries from the actions page so you can compare with a "known good" (SDL2 does not provide binaries).
So I should install these (two?) inside the docker container? If yes -> why, the compilation works perfectly fine and I would think that if anything went wrong I would be notified If no -> how could that help with the window showing up outside the container?
But you can always build the SDL2 tests and run them against various SDL2 libraries (using LD_LIBRARY_PATH).
I tried using export LD_LIBRARY_PATH=/usr/local/lib
(the place where cmake --install places the files) and then running the result of my docker compilation toolchain (in the same shell session, outside of the docker container), but nothing changed.
I never specified that my project is to be statically linked, so I assume it isn't, however the file is still 6mb large (with debugging symbols) so I am not 100% sure. I also ran the command
file myProject
myProject: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=58a9930606a7b5cd258b55b6f9950d47008959ab, for GNU/Linux 3.2.0, with debug_info, not stripped
vcpkg should allow you to compare the cmake configure arguments easily.
How can I do that? And what exactly do you mean by that?
If I can't get vcpkg to play nicely, how can I port my compiled binaries inside of cmake Docker so it uses the working ones instead of the faulty ones it is using right now? Directly copying them into /usr/local/lib and modifying the CMake file?
Thank you for the response, thanks to you all I've come closer to SDL working and avoided a lot more potential hassle.
And is it safe to alter/remove the build directories after I used cmake install?
After doing cmake --install
, the build directory can be removed. Since it contains absolute paths, you can't move it and re-use elsewhere. The installed package is free of paths, so you can do whatever you want with it.
Some SDL3 tests have a --fullscreen argument. Does it also happen with these?
When I try to use the --fullscreen flag on SDL3 tests, the screen flickers a few times before the display resolution matches the app's.
For me, with SDL_VIDEO_DRIVER=wayland
testsprite
goes fullscreen immediately. With x11
, testsprite
appears with the 2nd attempt.
So I should install these (two?) inside the docker container? If yes -> why, the compilation works perfectly fine and I would think that if anything went wrong I would be notified If no -> how could that help with the window showing up outside the container?
If you have a working build and install procedure, then all is good. We often see reports of people having not installed e.g. libx11-dev libraries. The archive does still require the installation of non-development libwayland, libdecor and/or libx11 libraries.
I never specified that my project is to be statically linked, so I assume it isn't, however the file is still 6mb large (with debugging symbols) so I am not 100% sure. I also ran the command
We discourage linking to a static SDL library.
Your app is not stripped. With c++ code, I often see an explosion in debug information size. Try running strip
on the app.
Before stripping, using objdump
/nm
, you can see what symbols are available in the library and what ones are undefined. Undefined symbols are made available through dynamic libraries.
vcpkg should allow you to compare the cmake configure arguments easily.
How can I do that? And what exactly do you mean by that?
Again, I was thinking you had build problems. This comment says there are logs somewhere. I'm no vcpkg export so you'll have to look this one up elsewhere.
If I can't get vcpkg to play nicely, how can I port my compiled binaries inside of cmake so it uses the working ones instead of the faulty ones it is using right now? Directly copying them into /usr/local/lib and modifying the CMake file?
Make sure cmake finds the correct SDL2/3 package, and use rpaths.
Running ldd
on your app will show what libraries the dynamic loader will load.
CMake's default behavior is to use rpaths in the build directories. This way, executables will use the correct dynamic library.
At install time, CMake removes these. This is done such that no directories of the build machines end up in the final binaries.
But as written above, there are ways to modify rpaths.
I mistyped. I meant how to do so within a Docker image/container instead of CMake.
A possible option would be to build SDL from source inside a container, or maybe just copying the .so
files.
But I don't know much about these things so I am really not sure.
You can mount a volume using the -v
option.
Since it looks like you're no longer have SDL-specific issues, is it ok to close this issue?
Not really sure how the whole system works here on github, but I would like to find the reason why both vcpkg and apt SDL packages don't work on my machine, which I think is an SDL problem. The docker workaround is just a quick and dirty solution, but I would prefer something permanent and less awkward. I do realize that this may be a fault with my machine or (less likely) with apt and docker packages, so you make the call on that.
Thank you everyone for help.
You can mount a volume using the
-v
option.Since it looks like you're no longer have SDL-specific issues, is it ok to close this issue?
So I would just mount the /usr/local/lib during compilation and hope for the best?
I am writing a program with C++/SDL2, but I can't get a window to show up. Before switching to SDL2, I used SDL2pp (switched due to vcpkg issues, where I couldn't use vcpkg and imgui renderer + normal binding. Decided to put everything inside a docker container to ensure that if I get it to work once I can get it to work anytime). I had similar issues, but it magically fixed itself (not really sure why). I compiled it on my PC without a docker image. I tried compiling it again but it didn't work.
I know there is a somewhat related issue on MacOS where you have to pump events to get the window to show up and I did that, with no results. This project has over 4000 lines of code and I think I handled everything properly, including event handling, yet a window still doesn't show up.
OS: Kubuntu 23.04, x64 DE: KDE X11 / KDE Wayland / XFCE (tried on all of them) DM: SDDM
Compilation process:
CMakeListst.txt
CMake command `cmake -B build -S latest/src -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCPPFILENAME=$(f) -DCMAKE_TOOLCHAIN_FILE=/app/vcpkg/scripts/buildsystems/vcpkg.cmake
Docker images: vcpkg base image: (I haven't used them outside this project)
Project specific image:
Vcpkg version: (inside docker) 2023-08-09-9990a4c9026811a312cb2af78bf77f3d9d288416
Library versions:
Program: (the last one I tried, among literally a dozen others, most from tutorials and solutions for other's issues
Most of my setup was improvised and I haven't followed any tutorials.
Any help would be appreciated.