]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Properly implement borderless windowed mode support
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Jun 2020 17:22:33 +0000 (17:22 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Jun 2020 17:22:33 +0000 (17:22 +0000)
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
vid_sdl.c
vid_shared.c

diff --git a/vid.h b/vid.h
index ddb1d36be1fe6e3560d91610a8d02c800aa372d6..2199ea0b6bc98eb34722b15e373080e43572f24e 100644 (file)
--- 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;
index a415ebce0e661836645369854d0f7b3dbfba102a..8b0d1e3af2f77022ce9ae74dc2574ae217642a83 100644 (file)
--- 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);
index 85590655989d9e5c1ae965e75f1d8973416d032e..5b131517aacc3aafe1431706283b345b6d0515e9 100644 (file)
@@ -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);