Add window blur hint/attribute

This adds very basic support for a new GLFW_BLURRED window
hint/attribute, and support in the X11 and null platforms. It is
intended to get feedback on whether this is the right API for this
feature, before diving into the other per-platform
implementations/stubs.
This commit is contained in:
Lindsay Roberts 2022-05-08 19:25:42 +03:00
parent 62e175ef9f
commit 9dfb0fabd3
10 changed files with 51 additions and 0 deletions

View File

@ -927,6 +927,13 @@ extern "C" {
*/ */
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D #define GLFW_MOUSE_PASSTHROUGH 0x0002000D
/*! @brief Blur behind window hint and attribute
*
* Blur behind [window hint](@ref GLFW_BLURRED_hint) or
* [window attribute](@ref GLFW_BLURRED_attrib).
*/
#define GLFW_BLURRED 0x0002000E
/*! @brief Framebuffer bit depth hint. /*! @brief Framebuffer bit depth hint.
* *
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS). * Framebuffer bit depth [hint](@ref GLFW_RED_BITS).

View File

@ -410,6 +410,7 @@ struct _GLFWwndconfig
GLFWbool focusOnShow; GLFWbool focusOnShow;
GLFWbool mousePassthrough; GLFWbool mousePassthrough;
GLFWbool scaleToMonitor; GLFWbool scaleToMonitor;
GLFWbool blurred;
struct { struct {
GLFWbool retina; GLFWbool retina;
char frameName[256]; char frameName[256];
@ -531,6 +532,7 @@ struct _GLFWwindow
GLFWbool focusOnShow; GLFWbool focusOnShow;
GLFWbool mousePassthrough; GLFWbool mousePassthrough;
GLFWbool shouldClose; GLFWbool shouldClose;
GLFWbool blurred;
void* userPointer; void* userPointer;
GLFWbool doublebuffer; GLFWbool doublebuffer;
GLFWvidmode videoMode; GLFWvidmode videoMode;
@ -748,6 +750,7 @@ struct _GLFWplatform
void (*getRequiredInstanceExtensions)(char**); void (*getRequiredInstanceExtensions)(char**);
int (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t); int (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*); VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
void (*setWindowBlur)(_GLFWwindow*,GLFWbool);
}; };
// Library global data // Library global data

View File

@ -112,6 +112,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwGetRequiredInstanceExtensionsNull, _glfwGetRequiredInstanceExtensionsNull,
_glfwGetPhysicalDevicePresentationSupportNull, _glfwGetPhysicalDevicePresentationSupportNull,
_glfwCreateWindowSurfaceNull, _glfwCreateWindowSurfaceNull,
_glfwSetWindowBlurNull,
}; };
*platform = null; *platform = null;

View File

@ -51,6 +51,7 @@ typedef struct _GLFWwindowNull
GLFWbool floating; GLFWbool floating;
GLFWbool transparent; GLFWbool transparent;
float opacity; float opacity;
GLFWbool blurred;
} _GLFWwindowNull; } _GLFWwindowNull;
// Null-specific per-monitor data // Null-specific per-monitor data
@ -111,6 +112,7 @@ void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled); void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityNull(_GLFWwindow* window); float _glfwGetWindowOpacityNull(_GLFWwindow* window);
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity); void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity);
void _glfwSetWindowBlurNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled); void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedNull(void); GLFWbool _glfwRawMouseMotionSupportedNull(void);
void _glfwShowWindowNull(_GLFWwindow* window); void _glfwShowWindowNull(_GLFWwindow* window);

View File

@ -409,6 +409,11 @@ void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity)
window->null.opacity = opacity; window->null.opacity = opacity;
} }
void _glfwSetWindowBlurNull(_GLFWwindow* window, GLFWbool enable)
{
window->null.blurred = enable;
}
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled) void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled)
{ {
} }

View File

@ -359,6 +359,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_MOUSE_PASSTHROUGH: case GLFW_MOUSE_PASSTHROUGH:
_glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.mousePassthrough = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_BLURRED:
_glfw.hints.window.blurred = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:
_glfw.hints.context.client = value; _glfw.hints.context.client = value;
return; return;
@ -826,6 +829,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return window->focusOnShow; return window->focusOnShow;
case GLFW_MOUSE_PASSTHROUGH: case GLFW_MOUSE_PASSTHROUGH:
return window->mousePassthrough; return window->mousePassthrough;
case GLFW_BLURRED:
return window->blurred;
case GLFW_TRANSPARENT_FRAMEBUFFER: case GLFW_TRANSPARENT_FRAMEBUFFER:
return _glfw.platform.framebufferTransparent(window); return _glfw.platform.framebufferTransparent(window);
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
@ -907,6 +912,11 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
window->mousePassthrough = value; window->mousePassthrough = value;
_glfw.platform.setWindowMousePassthrough(window, value); _glfw.platform.setWindowMousePassthrough(window, value);
return; return;
case GLFW_BLURRED:
window->blurred = value;
_glfw.platform.setWindowBlur(window, value);
return;
} }
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);

View File

@ -972,6 +972,8 @@ static GLFWbool initExtensions(void)
XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False); XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False);
_glfw.x11.MOTIF_WM_HINTS = _glfw.x11.MOTIF_WM_HINTS =
XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
_glfw.x11.KDE_NET_WM_BLUR_BEHIND_REGION =
XInternAtom(_glfw.x11.display, "_KDE_NET_WM_BLUR_BEHIND_REGION", False);
// The compositing manager selection name contains the screen number // The compositing manager selection name contains the screen number
{ {
@ -1243,6 +1245,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
_glfwGetRequiredInstanceExtensionsX11, _glfwGetRequiredInstanceExtensionsX11,
_glfwGetPhysicalDevicePresentationSupportX11, _glfwGetPhysicalDevicePresentationSupportX11,
_glfwCreateWindowSurfaceX11, _glfwCreateWindowSurfaceX11,
_glfwSetWindowBlurX11,
}; };
// HACK: If the application has left the locale as "C" then both wide // HACK: If the application has left the locale as "C" then both wide

View File

@ -614,6 +614,7 @@ typedef struct _GLFWlibraryX11
Atom NET_FRAME_EXTENTS; Atom NET_FRAME_EXTENTS;
Atom NET_REQUEST_FRAME_EXTENTS; Atom NET_REQUEST_FRAME_EXTENTS;
Atom MOTIF_WM_HINTS; Atom MOTIF_WM_HINTS;
Atom KDE_NET_WM_BLUR_BEHIND_REGION;
// Xdnd (drag and drop) atoms // Xdnd (drag and drop) atoms
Atom XdndAware; Atom XdndAware;
@ -933,6 +934,7 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityX11(_GLFWwindow* window); float _glfwGetWindowOpacityX11(_GLFWwindow* window);
void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity); void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughX11(_GLFWwindow* window, GLFWbool enabled); void _glfwSetWindowMousePassthroughX11(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowBlurX11(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled); void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedX11(void); GLFWbool _glfwRawMouseMotionSupportedX11(void);

View File

@ -604,6 +604,9 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
if (!wndconfig->decorated) if (!wndconfig->decorated)
_glfwSetWindowDecoratedX11(window, GLFW_FALSE); _glfwSetWindowDecoratedX11(window, GLFW_FALSE);
if (wndconfig->blurred)
_glfwSetWindowBlurX11(window, GLFW_TRUE);
if (_glfw.x11.NET_WM_STATE && !window->monitor) if (_glfw.x11.NET_WM_STATE && !window->monitor)
{ {
Atom states[3]; Atom states[3];
@ -2699,6 +2702,17 @@ void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity)
PropModeReplace, (unsigned char*) &value, 1); PropModeReplace, (unsigned char*) &value, 1);
} }
void _glfwSetWindowBlurX11(_GLFWwindow* window, GLFWbool enable)
{
if (enable)
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.KDE_NET_WM_BLUR_BEHIND_REGION, XA_CARDINAL, 32,
PropModeReplace, NULL, 0);
else
XDeleteProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.KDE_NET_WM_BLUR_BEHIND_REGION);
}
void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled) void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled)
{ {
if (!_glfw.x11.xi.available) if (!_glfw.x11.xi.available)

View File

@ -406,6 +406,10 @@ int main(int argc, char** argv)
if (nk_checkbox_label(nk, "Auto Iconify", &auto_iconify)) if (nk_checkbox_label(nk, "Auto Iconify", &auto_iconify))
glfwSetWindowAttrib(window, GLFW_AUTO_ICONIFY, auto_iconify); glfwSetWindowAttrib(window, GLFW_AUTO_ICONIFY, auto_iconify);
int blurred = glfwGetWindowAttrib(window, GLFW_BLURRED);
if (nk_checkbox_label(nk, "Blur", &blurred))
glfwSetWindowAttrib(window, GLFW_BLURRED, blurred);
nk_value_bool(nk, "Focused", glfwGetWindowAttrib(window, GLFW_FOCUSED)); nk_value_bool(nk, "Focused", glfwGetWindowAttrib(window, GLFW_FOCUSED));
nk_value_bool(nk, "Hovered", glfwGetWindowAttrib(window, GLFW_HOVERED)); nk_value_bool(nk, "Hovered", glfwGetWindowAttrib(window, GLFW_HOVERED));
nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE)); nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE));