From 349f06d6321bc00ec5b44f84007f5691ee6b1314 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Thu, 21 Sep 2017 12:43:39 +0700 Subject: [PATCH 1/3] Add ability to check GLFW_TRANSPARENT hint outcome with `glfwGetWindowAttrib()` To make this possible, in situations where GLFW_TRANSPARENT is requested but failed to match with a FBConfig, the internal framebufer hint is set to GLFW_FALSE. glfwGetWindowAttrib() then relies on the internal `_glfw.framebuffer.hint.transparent` bool. --- docs/window.dox | 4 +++- src/context.c | 6 ++++++ src/window.c | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/window.dox b/docs/window.dox index 37debd6ee..8c637f655 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -289,7 +289,9 @@ constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. @anchor GLFW_TRANSPARENT __GLFW_TRANSPARENT__ specifies whether the framebuffer will support transparency -in the background. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +in the background. If transparency is not provided by your driver, GLFW will +gracefully fallback to opaque. It is possible to check for this outcome +with `glfwGetWindowAttrib()`. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. @subsubsection window_hints_mtr Monitor related hints diff --git a/src/context.c b/src/context.c index 3842f0a37..3c0d5e657 100644 --- a/src/context.c +++ b/src/context.c @@ -318,6 +318,12 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, } } + if (desired->transparent && closest->transparent != GLFW_TRUE) + { + // If we couldn't find a transparency match, + // update the fb hint for client checking. + _glfw.hints.framebuffer.transparent = GLFW_FALSE; + } return closest; } diff --git a/src/window.c b/src/window.c index 863f0ed23..3b53477c1 100644 --- a/src/window.c +++ b/src/window.c @@ -732,6 +732,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->resizable; case GLFW_DECORATED: return window->decorated; + case GLFW_TRANSPARENT: + return _glfw.hints.framebuffer.transparent; case GLFW_FLOATING: return window->floating; case GLFW_AUTO_ICONIFY: From 445e0c102dc54bbe700d7a9bbc47563e3dbeacb2 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Thu, 21 Sep 2017 12:47:55 +0700 Subject: [PATCH 2/3] Add attribute check and print error to the gears example --- examples/gears.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/gears.c b/examples/gears.c index f14b300a7..405dc89a8 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -322,6 +322,11 @@ int main(int argc, char *argv[]) exit( EXIT_FAILURE ); } + if (!glfwGetWindowAttrib(window, GLFW_TRANSPARENT)) + { + fprintf( stderr, "Failed to set GLFW_TRANSPARENT flag\n" ); + } + // Set callback functions glfwSetFramebufferSizeCallback(window, reshape); glfwSetKeyCallback(window, key); From 59fdba80571c02337594a89ac35a1627b0b76cf3 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Thu, 21 Sep 2017 15:09:26 +0700 Subject: [PATCH 3/3] Handle transparency checks per platform, instead of in context.c This is needed because windows uses DWM for transparency, and that happens at a different stage inside of win32_window.c. This commit ensures framebuffer.transparent hint is updated once a match is confirmed (or lack of a match). --- src/context.c | 6 ------ src/egl_context.c | 3 +++ src/glx_context.c | 3 +++ src/win32_window.c | 5 +++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/context.c b/src/context.c index 3c0d5e657..3842f0a37 100644 --- a/src/context.c +++ b/src/context.c @@ -318,12 +318,6 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, } } - if (desired->transparent && closest->transparent != GLFW_TRUE) - { - // If we couldn't find a transparency match, - // update the fb hint for client checking. - _glfw.hints.framebuffer.transparent = GLFW_FALSE; - } return closest; } diff --git a/src/egl_context.c b/src/egl_context.c index bf3130c64..587fd5d30 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -188,6 +188,9 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, if (closest) *result = (EGLConfig) closest->handle; + if (desired->transparent && closest->transparent != GLFW_TRUE) + _glfw.hints.framebuffer.transparent = GLFW_FALSE; + free(nativeConfigs); free(usableConfigs); diff --git a/src/glx_context.c b/src/glx_context.c index 48c0ac3a7..32d1ef517 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -141,6 +141,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, if (closest) *result = (GLXFBConfig) closest->handle; + if (desired->transparent && closest->transparent != GLFW_TRUE) + _glfw.hints.framebuffer.transparent = GLFW_FALSE; + XFree(nativeConfigs); free(usableConfigs); diff --git a/src/win32_window.c b/src/win32_window.c index a6491aee4..4356983e4 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -988,6 +988,7 @@ static int createNativeWindow(_GLFWwindow* window, WCHAR* wideTitle; DWORD style = getWindowStyle(window); DWORD exStyle = getWindowExStyle(window); + GLFWbool transparent = GLFW_FALSE; if (window->monitor) { @@ -1061,6 +1062,7 @@ static int createNativeWindow(_GLFWwindow* window, bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; bb.hRgnBlur = region; bb.fEnable = TRUE; + transparent = GLFW_TRUE; if (SUCCEEDED(DwmEnableBlurBehindWindow(window->win32.handle, &bb))) { @@ -1090,6 +1092,9 @@ static int createNativeWindow(_GLFWwindow* window, DeleteObject(region); } + // Need to let the framebuffer hint aware of the composition results. + _glfw.hints.framebuffer.transparent = transparent; + return GLFW_TRUE; }