New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Option for transparent windows #197
Comments
This feature is also supported on Windows, and is as simple as calling a few winapi calls to enable the alpha blending. However, as far as I've tested, it doesn't seem to work for fullscreen borderless windows. |
It would be great if GLFW support this. For Linux I only know GLX that can do that. |
This would be possible to add but is not something most people would use. Will review this again when 3.1 is out. |
I want this feature for my app. The alternative would be to use glx directly, but I'd rather not do that. |
@nezumisama: I would love to see the git diff, please. I need this feature too. @elmindreda: this is maybe true for games and so on, but I think not really for desktop apps like Widgets or others like cairo-docks which uses GLX to do that. |
For windows vista and above DWM_BLURBEHIND bb;
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
DwmEnableBlurBehindWindow(handle, &bb); |
@K-Zero: OK, here it is: diff --git a/examples/gears.c b/examples/gears.c
index 2d44596..ef09df0 100644
--- a/examples/gears.c
+++ b/examples/gears.c
@@ -327,6 +327,9 @@ int main(int argc, char *argv[])
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
+ // Make the background transparent and hide decoration
+ glfwWindowHint(GLFW_ALPHA_MASK, GL_TRUE);
+ glfwWindowHint(GLFW_DECORATED, GL_FALSE);
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
if (!window)
diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h
index 0f97738..f357e6e 100644
--- a/include/GLFW/glfw3.h
+++ b/include/GLFW/glfw3.h
@@ -511,6 +511,7 @@ extern "C" {
#define GLFW_SAMPLES 0x0002100D
#define GLFW_SRGB_CAPABLE 0x0002100E
#define GLFW_REFRESH_RATE 0x0002100F
+#define GLFW_ALPHA_MASK 0x00021010
#define GLFW_CLIENT_API 0x00022001
#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002
diff --git a/src/context.c b/src/context.c
index 3bc86bc..a8d0dd5 100644
--- a/src/context.c
+++ b/src/context.c
@@ -221,6 +221,11 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
// Stereo is a hard constraint
continue;
}
+ if (desired->alphaMask > 0 && current->alphaMask == 0)
+ {
+ // Alpha mask is a hard constraint
+ continue;
+ }
// Count number of missing buffers
{
diff --git a/src/glx_context.c b/src/glx_context.c
index 6b87000..0c23fff 100644
--- a/src/glx_context.c
+++ b/src/glx_context.c
@@ -69,6 +69,8 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
int i, nativeCount, usableCount;
const char* vendor;
GLboolean trustWindowBit = GL_TRUE;
+ XVisualInfo *vi;
+ XRenderPictFormat *pf;
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (strcmp(vendor, "Chromium") == 0)
@@ -145,6 +147,14 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS);
u->stereo = getFBConfigAttrib(n, GLX_STEREO);
+ vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
+ if (vi)
+ {
+ pf = XRenderFindVisualFormat(_glfw.x11.display, vi->visual);
+ if (pf)
+ u->alphaMask = pf->direct.alphaMask;
+ }
+
if (_glfw.glx.ARB_multisample)
u->samples = getFBConfigAttrib(n, GLX_SAMPLES);
@@ -161,6 +171,7 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
XFree(nativeConfigs);
free(usableConfigs);
+ if (vi) XFree(vi);
return closest ? GL_TRUE : GL_FALSE;
}
diff --git a/src/internal.h b/src/internal.h
index 8a24959..014515b 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -185,6 +185,7 @@ struct _GLFWfbconfig
GLboolean stereo;
int samples;
GLboolean sRGB;
+ GLboolean alphaMask;
// This is defined in the context API's platform.h
_GLFW_PLATFORM_FBCONFIG;
@@ -289,6 +290,7 @@ struct _GLFWlibrary
GLboolean resizable;
GLboolean visible;
GLboolean decorated;
+ GLboolean alphaMask;
int samples;
GLboolean sRGB;
int refreshRate;
diff --git a/src/window.c b/src/window.c
index 4e2b277..db43c58 100644
--- a/src/window.c
+++ b/src/window.c
@@ -173,6 +173,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
fbconfig.stereo = _glfw.hints.stereo ? GL_TRUE : GL_FALSE;
fbconfig.samples = Max(_glfw.hints.samples, 0);
fbconfig.sRGB = _glfw.hints.sRGB ? GL_TRUE : GL_FALSE;
+ fbconfig.alphaMask = _glfw.hints.alphaMask ? GL_TRUE : GL_FALSE;
// Set up desired window config
wndconfig.width = width;
@@ -284,6 +285,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.alphaBits = 8;
_glfw.hints.depthBits = 24;
_glfw.hints.stencilBits = 8;
+ _glfw.hints.alphaMask = GL_FALSE;
}
GLFWAPI void glfwWindowHint(int target, int hint)
@@ -367,6 +369,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
case GLFW_OPENGL_PROFILE:
_glfw.hints.glProfile = hint;
break;
+ case GLFW_ALPHA_MASK:
+ _glfw.hints.alphaMask = hint;
+ break;
default:
_glfwInputError(GLFW_INVALID_ENUM, NULL);
break; Not sure if this exactly how it should be done, but it should work. This requires the xrender extension. Xrender is required by xrandr, so this links and works without -lXrender flag for the linker, but maybe that flag should be added (I don't know how to use cmake, so I don't know where to add it). |
i'd love to see this too :) |
I'd like it too. |
I want this too... :) I've started a branch trying to add support, implemented it for the OSX platform which seems to work: 7db465f. I'm using @nezumisama code as a starting point, i.e. GLFW_ALPHA_MASK window hint. Will try to add support for Windows soon, but I won't have access to a Linux box so if anyone wants to help out it would be appreciated. Or if @nezumisama code still works I might just borrow it? |
@andsve have you had any luck with this on Windows or Linux ? I'm really interested. |
@slimsag Hey, I haven't had the time to look into it sadly... However, I have a windows machine again at my disposal so will try to do some testing soonish! Let me know if you have any luck on your end. |
@andsve thank you for the response! Hopefully I get the chance to look into it sometime. If you need any testing done on Linux(X11), Windows, or OS X done please let me know. |
I'm interested in this feature for the purpose of creating a GUI toolkit, for example a menu with a drop shadow. |
same here, GUI purposes |
Funny thing, I'm also in need of it myself at the moment. I'll see if I have time to look into it this weekend, I think my branch is way out of sync with GLFW3 etc... |
Hey, if anyone is still interested in this, I just pushed a fix for Windows on this branch: https://github.com/andsve/glfw/tree/transparent-windows Interested in hearing if it works or not for everyone else. Haven't tested my OS X chnages since I last worked on this, so will do that next. Then maybe try integrating the Linux stuff from above in this thread. |
Works perfectly for me. Windows 8.1 64 bit (but building glfw as 32 bit) with Nvidia drivers. |
Tried to use the supplied X11 related changes that @nezumisama posted above, but I can't get it to work. I'm however running a debian install inside VirtualBox so I can't say for sure... Anyone with a Linux box that would like to apply this (using diff --git a/src/glx_context.c b/src/glx_context.c
index ec34e8f..28f0f7c 100644
--- a/src/glx_context.c
+++ b/src/glx_context.c
@@ -60,6 +60,8 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
int i, nativeCount, usableCount;
const char* vendor;
GLboolean trustWindowBit = GL_TRUE;
+ XVisualInfo *vi;
+ XRenderPictFormat *pf;
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (strcmp(vendor, "Chromium") == 0)
@@ -126,6 +128,14 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER))
u->doublebuffer = GL_TRUE;
+ vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
+ if (vi)
+ {
+ pf = XRenderFindVisualFormat(_glfw.x11.display, vi->visual);
+ if (pf)
+ u->alphaMask = pf->direct.alphaMask;
+ }
+
if (_glfw.glx.ARB_multisample)
u->samples = getFBConfigAttrib(n, GLX_SAMPLES);
@@ -142,6 +152,7 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
XFree(nativeConfigs);
free(usableConfigs);
+ if (vi) XFree(vi);
return closest ? GL_TRUE : GL_FALSE;
} |
|
Strange, what dist? I don't get any transparent window, but at least it compiles here. |
Ubuntu 14.10 Utopic Unicorn. I did not have xorg-dev installed, but after installing it, got the same error. Also, shouldn't cmake catch that? Compiles fine without the patch. Running the transparent example yields: glxinfo: |
Please see if the If you have a corresponding local branch you may need to reset it. |
@elmindreda Tested |
@andsve Yay, thank you for testing! I'll be away until Sunday. If no serious issues turn up, I will merge this next week. I believe the only thing left to do besides testing is a tiny bit of documentation. The only issue I've found so far is that the content area alpha channel on OS X 10.10.5 doesn't seem to be updated after the first frame. I don't consider that to be blocking. Things that (as far as I know) haven't been tested yet: WIndows Vista, 8 and 8.1, Radeon and Intel HD Windows OpenGL drivers as well as any X11 compositor other than Compton and Compiz. The code is based on the work you guys did but I've made changes on all platforms and may have broken something. |
Seems to work fine with XFCE's built-in compositor (Debian 8, Nvidia graphics). I can also test on Windows 8.1 (Nvidia) and Windows 10 (Intel) over the next few days. |
Ditto for x64 Release and Debug builds. (Note, this was just me running the |
Is there any way to check if the transparency hint succeeded or failed? On XFCE with desktop compositing disabled the gears window is non-transparent, but there is no warning or error printed to the console. (This doesn't bother me at all, but might be a good feature to add and/or document) |
If framebuffer selection fails due to lack of transparency, it simply trys again (silently) for a configuration without transparency. Internally, the framebuffer hint will actually remain true, even upon failure. So that could be a possible issue in regards of checking in the future for success/failure. There was an api for checking after the fact if the transparency hint was applied to the window. Maybe we can add a similar kind of checking to see if it was successful? |
Having a way to check the success would be good IMO. I have an application I want to create which rely on transparent background. If that fails I would want a way to handle/message that. |
@cosier This is fantastic, thank you for making this happen! 👍 |
Here are things that remain to be done. More items may be added as we think of them, but not all of them are blocking for merge or release.
|
Support for transparent window framebuffers has been merged. Thank you to everyone who contributed and apologies for the long wait. |
How to destroy input shape and set CWOwerrideRedirect attribute? |
@ashftw This addition doesn't include support for custom window shapes. There's currently no way to explicitly make a window override-redirect. |
If anyone here is interested in the other kind of window transparency, where you specify a single alpha value for the whole window including decorations, there is now an issue (#1089) for it. There is an initial implementation as well, but I won't have time to publish it until next week at the earliest. This will very likely force a rename of the glfwWindowHint(GLFW_TRANSPARENT, GLFW_FALSE);
glfwWindowHint(GLFW_OPACITY, 23); ...which will confusingly yield a transparent window. |
On X11, when using a compositor/compositing WM, windows can have alpha-enabled visuals, allowing the application to specify opacity of each pixel. This is not however supported by GLFW now.
Here's some example code from Nvidia (note this works on Mesa as well): ftp://download.nvidia.com/XFree86/Linux-x86/177.70/README/chapter-23.html
I hacked together a version of glxgears with transparent background, for reference: https://gist.github.com/nezumisama/8161902
The text was updated successfully, but these errors were encountered: