From 840373e9fe38f18a5660fdd1816cf26ba578bc72 Mon Sep 17 00:00:00 2001 From: cloudwalk Date: Mon, 15 Jun 2020 17:22:33 +0000 Subject: [PATCH] Properly implement borderless windowed mode support Several new cvars control behavior. It can ignore the Windows taskbar and compatibility with overlays (Steam, Discord, etc) should be fine with SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH. https://gitlab.com/xonotic/darkplaces/-/merge_requests/81 git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12679 d7cf8633-e32d-0410-b094-e92efae38249 --- vid.h | 5 +++++ vid_sdl.c | 34 +++++++++++++++++++++++++--------- vid_shared.c | 10 ++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/vid.h b/vid.h index ddb1d36b..2199ea0b 100644 --- a/vid.h +++ b/vid.h @@ -130,6 +130,7 @@ extern qboolean vid_activewindow; extern qboolean vid_supportrefreshrate; extern cvar_t vid_fullscreen; +extern cvar_t vid_borderless; extern cvar_t vid_width; extern cvar_t vid_height; extern cvar_t vid_bitsperpixel; @@ -141,6 +142,7 @@ extern cvar_t vid_touchscreen_xdpi; extern cvar_t vid_touchscreen_ydpi; extern cvar_t vid_vsync; extern cvar_t vid_mouse; +extern cvar_t vid_mouse_clickthrough; extern cvar_t vid_grabkeyboard; extern cvar_t vid_touchscreen; extern cvar_t vid_touchscreen_showkeyboard; @@ -148,6 +150,9 @@ extern cvar_t vid_touchscreen_supportshowkeyboard; extern cvar_t vid_stick_mouse; extern cvar_t vid_resizable; extern cvar_t vid_desktopfullscreen; +#ifdef WIN32 +extern cvar_t vid_ignore_taskbar; +#endif extern cvar_t vid_minwidth; extern cvar_t vid_minheight; extern cvar_t vid_sRGB; diff --git a/vid_sdl.c b/vid_sdl.c index a415ebce..8b0d1e3a 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -1418,6 +1418,11 @@ static void VID_OutputVersion(void) #ifdef WIN32 static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect) { + int workWidth; + int workHeight; + int titleBarPixels = 2; + int screenHeight; + RECT workArea; LONG width = mode->width; // vid_width LONG height = mode->height; // vid_height @@ -1428,16 +1433,14 @@ static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect) rect->bottom = height; AdjustWindowRectEx(rect, WS_CAPTION|WS_THICKFRAME, false, 0); - RECT workArea; SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); - int workWidth = workArea.right - workArea.left; - int workHeight = workArea.bottom - workArea.top; + workWidth = workArea.right - workArea.left; + workHeight = workArea.bottom - workArea.top; // SDL forces the window height to be <= screen height - 27px (on Win8.1 - probably intended for the title bar) // If the task bar is docked to the the left screen border and we move the window to negative y, // there would be some part of the regular desktop visible on the bottom of the screen. - int titleBarPixels = 2; - int screenHeight = GetSystemMetrics(SM_CYSCREEN); + screenHeight = GetSystemMetrics(SM_CYSCREEN); if (screenHeight == workHeight) titleBarPixels = -rect->top; @@ -1468,6 +1471,8 @@ extern cvar_t gl_info_driver; static qboolean VID_InitModeGL(viddef_mode_t *mode) { int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; + // currently SDL_WINDOWPOS_UNDEFINED behaves exactly like SDL_WINDOWPOS_CENTERED, this might change some day + // https://trello.com/c/j56vUcwZ/81-centered-vs-undefined-window-position int xPos = SDL_WINDOWPOS_UNDEFINED; int yPos = SDL_WINDOWPOS_UNDEFINED; #ifndef USE_GLES2 @@ -1520,16 +1525,27 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) vid_isfullscreen = true; } else { + if (vid_borderless.integer) + windowflags |= SDL_WINDOW_BORDERLESS; #ifdef WIN32 - RECT rect; - AdjustWindowBounds(mode, &rect); - xPos = rect.left; - yPos = rect.top; + if (vid_ignore_taskbar.integer) { + xPos = SDL_WINDOWPOS_CENTERED; + yPos = SDL_WINDOWPOS_CENTERED; + } + else { + RECT rect; + AdjustWindowBounds(mode, &rect); + xPos = rect.left; + yPos = rect.top; + } #endif } } //flags |= SDL_HWSURFACE; + if (vid_mouse_clickthrough.integer && !vid_isfullscreen) + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); + SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8); diff --git a/vid_shared.c b/vid_shared.c index 85590655..5b131517 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -133,6 +133,7 @@ cvar_t gl_info_platform = {CVAR_CLIENT | CVAR_READONLY, "gl_info_platform", "", cvar_t gl_info_driver = {CVAR_CLIENT | CVAR_READONLY, "gl_info_driver", "", "name of driver library (opengl32.dll, libGL.so.1, or whatever)."}; cvar_t vid_fullscreen = {CVAR_CLIENT | CVAR_SAVE, "vid_fullscreen", "1", "use fullscreen (1) or windowed (0)"}; +cvar_t vid_borderless = {CVAR_CLIENT | CVAR_SAVE, "vid_borderless", "0", "make the window borderless by removing all window decorations. has no effect in fullscreen mode"}; cvar_t vid_width = {CVAR_CLIENT | CVAR_SAVE, "vid_width", "640", "resolution"}; cvar_t vid_height = {CVAR_CLIENT | CVAR_SAVE, "vid_height", "480", "resolution"}; cvar_t vid_bitsperpixel = {CVAR_CLIENT | CVAR_READONLY, "vid_bitsperpixel", "32", "how many bits per pixel to render at (this is not currently configurable)"}; @@ -149,6 +150,7 @@ cvar_t vid_touchscreen_ydpi = {CVAR_CLIENT, "vid_touchscreen_ydpi", "300", "Vert cvar_t vid_vsync = {CVAR_CLIENT | CVAR_SAVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time), automatically disabled when doing timedemo benchmarks"}; cvar_t vid_mouse = {CVAR_CLIENT | CVAR_SAVE, "vid_mouse", "1", "whether to use the mouse in windowed mode (fullscreen always does)"}; +cvar_t vid_mouse_clickthrough = {CVAR_CLIENT | CVAR_SAVE, "vid_mouse_clickthrough", "0", "mouse behavior in windowed mode: 0 = click to focus, 1 = allow interaction even if the window is not focused (click-through behaviour, can be useful when using third-party game overlays)"}; cvar_t vid_grabkeyboard = {CVAR_CLIENT | CVAR_SAVE, "vid_grabkeyboard", "0", "whether to grab the keyboard when mouse is active (prevents use of volume control keys, music player keys, etc on some keyboards)"}; cvar_t vid_minwidth = {CVAR_CLIENT, "vid_minwidth", "0", "minimum vid_width that is acceptable (to be set in default.cfg in mods)"}; cvar_t vid_minheight = {CVAR_CLIENT, "vid_minheight", "0", "minimum vid_height that is acceptable (to be set in default.cfg in mods)"}; @@ -162,6 +164,9 @@ cvar_t vid_touchscreen_supportshowkeyboard = {CVAR_CLIENT | CVAR_READONLY, "vid_ cvar_t vid_stick_mouse = {CVAR_CLIENT | CVAR_SAVE, "vid_stick_mouse", "0", "have the mouse stuck in the center of the screen" }; cvar_t vid_resizable = {CVAR_CLIENT | CVAR_SAVE, "vid_resizable", "0", "0: window not resizable, 1: resizable, 2: window can be resized but the framebuffer isn't adjusted" }; cvar_t vid_desktopfullscreen = {CVAR_CLIENT | CVAR_SAVE, "vid_desktopfullscreen", "1", "force desktop resolution for fullscreen; also use some OS dependent tricks for better fullscreen integration"}; +#ifdef WIN32 +cvar_t vid_ignore_taskbar = {CVAR_CLIENT | CVAR_SAVE, "vid_ignore_taskbar", "0", "in windowed mode, prevent the Windows taskbar and window borders from affecting the size and placement of the window. it will be aligned centered and uses the unaltered vid_width/vid_height values"}; +#endif cvar_t v_gamma = {CVAR_CLIENT | CVAR_SAVE, "v_gamma", "1", "inverse gamma correction value, a brightness effect that does not affect white or black, and tends to make the image grey and dull"}; cvar_t v_contrast = {CVAR_CLIENT | CVAR_SAVE, "v_contrast", "1", "brightness of white (values above 1 give a brighter image with increased color saturation, unlike v_gamma)"}; @@ -1275,6 +1280,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&v_psycho); Cvar_RegisterVariable(&vid_fullscreen); + Cvar_RegisterVariable(&vid_borderless); Cvar_RegisterVariable(&vid_width); Cvar_RegisterVariable(&vid_height); Cvar_RegisterVariable(&vid_bitsperpixel); @@ -1287,6 +1293,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&vid_touchscreen_ydpi); Cvar_RegisterVariable(&vid_vsync); Cvar_RegisterVariable(&vid_mouse); + Cvar_RegisterVariable(&vid_mouse_clickthrough); Cvar_RegisterVariable(&vid_grabkeyboard); Cvar_RegisterVariable(&vid_touchscreen); Cvar_RegisterVariable(&vid_touchscreen_showkeyboard); @@ -1294,6 +1301,9 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&vid_stick_mouse); Cvar_RegisterVariable(&vid_resizable); Cvar_RegisterVariable(&vid_desktopfullscreen); +#ifdef WIN32 + Cvar_RegisterVariable(&vid_ignore_taskbar); +#endif Cvar_RegisterVariable(&vid_minwidth); Cvar_RegisterVariable(&vid_minheight); Cvar_RegisterVariable(&gl_finish); -- 2.39.2