mirror of
https://github.com/glfw/glfw.git
synced 2026-09-21 00:30:57 +00:00
Add glfwGetWindowOpacity and glfwSetWindowOpacity
This adds support for setting the opacity of the whole window, including any decorations. Fixes #1089.
This commit is contained in:
@@ -1493,6 +1493,16 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
[window->ns.object setLevel:NSNormalWindowLevel];
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
return (float) [window->ns.object alphaValue];
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
[window->ns.object setAlphaValue:opacity];
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
for (;;)
|
||||
|
||||
@@ -687,9 +687,11 @@ int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||
|
||||
void _glfwPlatformPollEvents(void);
|
||||
void _glfwPlatformWaitEvents(void);
|
||||
|
||||
@@ -648,6 +648,15 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
EventNode* node = NULL;
|
||||
|
||||
@@ -182,6 +182,15 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1591,6 +1591,39 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
BYTE alpha;
|
||||
DWORD flags;
|
||||
|
||||
if ((GetWindowLongW(window->win32.handle, GWL_EXSTYLE) & WS_EX_LAYERED) &&
|
||||
GetLayeredWindowAttributes(window->win32.handle, NULL, &alpha, &flags))
|
||||
{
|
||||
if (flags & LWA_ALPHA)
|
||||
return alpha / 255.f;
|
||||
}
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
if (opacity < 1.f)
|
||||
{
|
||||
const BYTE alpha = (BYTE) (255 * opacity);
|
||||
DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||
style |= WS_EX_LAYERED;
|
||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
|
||||
SetLayeredWindowAttributes(window->win32.handle, 0, alpha, LWA_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD style = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||
style &= ~WS_EX_LAYERED;
|
||||
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, style);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
@@ -648,6 +648,34 @@ GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
|
||||
_glfwPlatformGetWindowContentScale(window, xscale, yscale);
|
||||
}
|
||||
|
||||
GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(1.f);
|
||||
return _glfwPlatformGetWindowOpacity(window);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(opacity == opacity);
|
||||
assert(opacity >= 0.f);
|
||||
assert(opacity <= 1.f);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (opacity != opacity || opacity < 0.f || opacity > 1.f)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformSetWindowOpacity(window, opacity);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
@@ -692,6 +692,15 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
handleEvents(0);
|
||||
|
||||
@@ -737,9 +737,18 @@ static GLFWbool initExtensions(void)
|
||||
XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);
|
||||
_glfw.x11.NET_WM_BYPASS_COMPOSITOR =
|
||||
XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);
|
||||
_glfw.x11.NET_WM_WINDOW_OPACITY =
|
||||
XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False);
|
||||
_glfw.x11.MOTIF_WM_HINTS =
|
||||
XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
|
||||
|
||||
// The compositing manager selection name contains the screen number
|
||||
{
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
|
||||
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -257,6 +257,8 @@ typedef struct _GLFWlibraryX11
|
||||
Atom NET_WM_STATE_DEMANDS_ATTENTION;
|
||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom NET_WM_WINDOW_OPACITY;
|
||||
Atom NET_WM_CM_Sx;
|
||||
Atom NET_ACTIVE_WINDOW;
|
||||
Atom NET_FRAME_EXTENTS;
|
||||
Atom NET_REQUEST_FRAME_EXTENTS;
|
||||
|
||||
+32
-5
@@ -2449,11 +2449,7 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
if (!window->x11.transparent)
|
||||
return GLFW_FALSE;
|
||||
|
||||
// Check whether a compositing manager is running
|
||||
char name[32];
|
||||
snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
|
||||
const Atom selection = XInternAtom(_glfw.x11.display, name, False);
|
||||
return XGetSelectionOwner(_glfw.x11.display, selection) != None;
|
||||
return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
@@ -2559,6 +2555,37 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
|
||||
{
|
||||
float opacity = 1.f;
|
||||
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx))
|
||||
{
|
||||
CARD32* value = NULL;
|
||||
|
||||
if (_glfwGetWindowPropertyX11(window->x11.handle,
|
||||
_glfw.x11.NET_WM_WINDOW_OPACITY,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &value))
|
||||
{
|
||||
opacity = (float) (*value / (double) 0xffffffffu);
|
||||
}
|
||||
|
||||
if (value)
|
||||
XFree(value);
|
||||
}
|
||||
|
||||
return opacity;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
|
||||
{
|
||||
const CARD32 value = (CARD32) (0xffffffffu * (double) opacity);
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
|
||||
PropModeReplace, (unsigned char*) &value, 1);
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
Reference in New Issue
Block a user