SDL2:如何正确切换全屏?
SDL2: How to properly toggle fullscreen?
我在使用我的程序停用全屏模式时遇到问题。进入全屏正确,但尝试返回窗口模式不起作用,唯一的影响是光标再次显示。
这是为我重现问题的MCVE/SSCCE:
void ToggleFullscreen(SDL_Window* Window) {
Uint32 FullscreenFlag = SDL_WINDOW_FULLSCREEN;
bool IsFullscreen = SDL_GetWindowFlags(Window) & FullscreenFlag;
SDL_SetWindowFullscreen(Window, IsFullscreen ? 0 : FullscreenFlag);
SDL_ShowCursor(IsFullscreen);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* Window = SDL_CreateWindow("",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
bool Exit = false;
for (SDL_Event Event; !Exit;) {
SDL_WaitEvent(&Event);
if (Event.type == SDL_KEYDOWN) {
switch (Event.key.keysym.sym) {
case SDLK_f: ToggleFullscreen(Window); break;
case SDLK_q: Exit = true; break;
}
}
}
SDL_DestroyWindow(Window);
SDL_Quit();
}
SDL_SetWindowFullscreen
returns0
,好像操作成功了。我究竟做错了什么? (我在 OS X 10.10.3 上使用 SDL 2.0.3。)
这看起来像是一个已知问题。希望 SDL 开发人员会修复它。我发现了以下错误报告。
即使现在 SDL_SetWindowFullscreen
似乎仍然存在问题。我尝试使用此功能向我的视频播放器添加全屏功能。但是,在全屏和 windowed 模式之间转换时它会随机崩溃。
我找到了一个临时解决方法,目前看来可以正常工作。
SDL_DisplayMode dm;
if (SDL_GetDesktopDisplayMode(0, &dm))
{
printf("Error getting desktop display mode\n");
return -1;
}
if (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_f:
SDL_RestoreWindow(screen); //Incase it's maximized...
SDL_SetWindowSize(screen, dm.w, dm.h + 10);
SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
break;
}
}
基本上是 "fake" 全屏。它调整 window 的大小,使客户区覆盖整个屏幕,最小化、最大化、退出按钮不在屏幕上。
希望对您有所帮助。
我知道这可能是 5 年后的事了,但我遇到了同样的问题,我发现你的代码比需要的更复杂。所以我只是想补充一下然而来到这里:
//somewhere outside the loop
bool isFullScreen = true;
void toggleFullScreen(SDL_Window* window, bool currentState)
{
isFullScreen = !currentState;
SDL_SetWindowFullscreen(window, !currentState);
SDL_ShowCursor(currentState);
}
只需将 isFullscreen 置于 currenState,您就可以很好地切换按键事件。
这对我来说在 SDL2 中工作正常(按 f 切换它 on/off 和 q 退出):
SDL_Window* window = SDL_CreateWindow("Fullscreen demo", 0, 0, 640, 480, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Event event;
bool fullScreen = false;
SDL_bool running = SDL_TRUE;
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = SDL_FALSE;
break;
case SDL_KEYDOWN:
if(event.key.keysym.scancode == SDL_SCANCODE_F){
fullScreen = !fullScreen;
if(fullScreen){
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
}
else{
SDL_SetWindowFullscreen(window, 0);
}
}
if(event.key.keysym.scancode == SDL_SCANCODE_Q){
running = SDL_FALSE;
}
break;
default: break;
}
}
// drawing stuff here...
// swap and display buffer
SDL_RenderPresent(renderer);
}
我在使用我的程序停用全屏模式时遇到问题。进入全屏正确,但尝试返回窗口模式不起作用,唯一的影响是光标再次显示。
这是为我重现问题的MCVE/SSCCE:
void ToggleFullscreen(SDL_Window* Window) {
Uint32 FullscreenFlag = SDL_WINDOW_FULLSCREEN;
bool IsFullscreen = SDL_GetWindowFlags(Window) & FullscreenFlag;
SDL_SetWindowFullscreen(Window, IsFullscreen ? 0 : FullscreenFlag);
SDL_ShowCursor(IsFullscreen);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* Window = SDL_CreateWindow("",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
bool Exit = false;
for (SDL_Event Event; !Exit;) {
SDL_WaitEvent(&Event);
if (Event.type == SDL_KEYDOWN) {
switch (Event.key.keysym.sym) {
case SDLK_f: ToggleFullscreen(Window); break;
case SDLK_q: Exit = true; break;
}
}
}
SDL_DestroyWindow(Window);
SDL_Quit();
}
SDL_SetWindowFullscreen
returns0
,好像操作成功了。我究竟做错了什么? (我在 OS X 10.10.3 上使用 SDL 2.0.3。)
这看起来像是一个已知问题。希望 SDL 开发人员会修复它。我发现了以下错误报告。
即使现在 SDL_SetWindowFullscreen
似乎仍然存在问题。我尝试使用此功能向我的视频播放器添加全屏功能。但是,在全屏和 windowed 模式之间转换时它会随机崩溃。
我找到了一个临时解决方法,目前看来可以正常工作。
SDL_DisplayMode dm;
if (SDL_GetDesktopDisplayMode(0, &dm))
{
printf("Error getting desktop display mode\n");
return -1;
}
if (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYUP:
switch (event.key.keysym.sym)
{
case SDLK_f:
SDL_RestoreWindow(screen); //Incase it's maximized...
SDL_SetWindowSize(screen, dm.w, dm.h + 10);
SDL_SetWindowPosition(screen, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
break;
}
}
基本上是 "fake" 全屏。它调整 window 的大小,使客户区覆盖整个屏幕,最小化、最大化、退出按钮不在屏幕上。
希望对您有所帮助。
我知道这可能是 5 年后的事了,但我遇到了同样的问题,我发现你的代码比需要的更复杂。所以我只是想补充一下然而来到这里:
//somewhere outside the loop
bool isFullScreen = true;
void toggleFullScreen(SDL_Window* window, bool currentState)
{
isFullScreen = !currentState;
SDL_SetWindowFullscreen(window, !currentState);
SDL_ShowCursor(currentState);
}
只需将 isFullscreen 置于 currenState,您就可以很好地切换按键事件。
这对我来说在 SDL2 中工作正常(按 f 切换它 on/off 和 q 退出):
SDL_Window* window = SDL_CreateWindow("Fullscreen demo", 0, 0, 640, 480, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Event event;
bool fullScreen = false;
SDL_bool running = SDL_TRUE;
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = SDL_FALSE;
break;
case SDL_KEYDOWN:
if(event.key.keysym.scancode == SDL_SCANCODE_F){
fullScreen = !fullScreen;
if(fullScreen){
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
}
else{
SDL_SetWindowFullscreen(window, 0);
}
}
if(event.key.keysym.scancode == SDL_SCANCODE_Q){
running = SDL_FALSE;
}
break;
default: break;
}
}
// drawing stuff here...
// swap and display buffer
SDL_RenderPresent(renderer);
}