Implement background blur for KDE on X11 as well

This commit is contained in:
Kovid Goyal 2023-06-27 14:56:35 +05:30
parent 7a1bdb4ff1
commit 7c6d40fa0c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
11 changed files with 52 additions and 7 deletions

View File

@ -250,6 +250,7 @@ def generate_wrappers(glfw_header: str) -> None:
uint32_t glfwGetCocoaKeyEquivalent(uint32_t glfw_key, int glfw_mods, int* cocoa_mods)
void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun callback)
int glfwCocoaSetBackgroundBlur(GLFWwindow *w, int blur_radius)
bool glfwSetX11WindowBlurred(GLFWwindow *w, bool enable_blur)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
void glfwSetPrimarySelectionString(GLFWwindow* window, const char* string)

1
glfw/glfw3.h vendored
View File

@ -1047,6 +1047,7 @@ typedef enum {
* [window hint](@ref GLFW_X11_CLASS_NAME_hint).
*/
#define GLFW_X11_INSTANCE_NAME 0x00024002
#define GLFW_X11_BLUR 0x00024003
#define GLFW_WAYLAND_APP_ID 0x00025001
/*! @} */

1
glfw/internal.h vendored
View File

@ -319,6 +319,7 @@ struct _GLFWwndconfig
struct {
char className[256];
char instanceName[256];
int enable_blur;
} x11;
struct {
char appId[256];

4
glfw/window.c vendored
View File

@ -336,6 +336,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.ns.color_space = 0;
// no blur
_glfw.hints.window.ns.blur_radius = 0;
_glfw.hints.window.x11.enable_blur = 0;
}
GLFWAPI void glfwWindowHint(int hint, int value)
@ -422,6 +423,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_COCOA_BLUR_RADIUS:
_glfw.hints.window.ns.blur_radius = value;
return;
case GLFW_X11_BLUR:
_glfw.hints.window.x11.enable_blur = value;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? true : false;
return;

1
glfw/x11_init.c vendored
View File

@ -651,6 +651,7 @@ int _glfwPlatformInit(void)
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
_glfw.x11.context = XUniqueContext();
_glfw.x11.RESOURCE_MANAGER = XInternAtom(_glfw.x11.display, "RESOURCE_MANAGER", True);
_glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION = None;
XSelectInput(_glfw.x11.display, _glfw.x11.root, PropertyChangeMask);
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, false);

2
glfw/x11_platform.h vendored
View File

@ -299,6 +299,8 @@ typedef struct _GLFWlibraryX11
// XRM database atom
Atom RESOURCE_MANAGER;
// KDE window blur
Atom _KDE_NET_WM_BLUR_BEHIND_REGION;
// Atoms for MIME types
AtomArray mime_atoms, clipboard_atoms, primary_atoms;

27
glfw/x11_window.c vendored
View File

@ -64,6 +64,7 @@
// covers GLX functions
//
static unsigned _glfwDispatchX11Events(void);
GLFWAPI bool glfwSetX11WindowBlurred(GLFWwindow *w, bool enable_blur);
static void
handleEvents(monotonic_t timeout) {
@ -713,6 +714,10 @@ static bool createNativeWindow(_GLFWwindow* window,
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
if (_glfw.hints.window.x11.enable_blur) {
glfwSetX11WindowBlurred((GLFWwindow*)window, 1);
}
return true;
}
@ -2687,7 +2692,7 @@ _glfwDispatchX11Events(void) {
if (window->x11.lastCursorPosX != width / 2 ||
window->x11.lastCursorPosY != height / 2)
{
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
_glfwPlatformSetCursorPos(window, width / 2.f, height / 2.f);
}
}
@ -3215,6 +3220,26 @@ GLFWAPI void glfwSetX11WindowAsDock(int32_t x11_window_id) {
PropModeReplace, (unsigned char*) &type, 1);
}
GLFWAPI bool glfwSetX11WindowBlurred(GLFWwindow *w, bool enable_blur) {
_GLFW_REQUIRE_INIT_OR_RETURN(0);
_GLFWwindow *window = (_GLFWwindow*)w;
if (_glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION == None) {
_glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION = XInternAtom(_glfw.x11.display, "_KDE_NET_WM_BLUR_BEHIND_REGION", False);
}
if (_glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION != None) {
uint32_t data = 0;
if (enable_blur) {
XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION,
XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &data, 1);
} else {
XDeleteProperty(_glfw.x11.display, window->x11.handle, _glfw.x11._KDE_NET_WM_BLUR_BEHIND_REGION);
}
return true;
}
return false;
}
GLFWAPI void glfwSetX11WindowStrut(int32_t x11_window_id, uint32_t dimensions[12]) {
_GLFW_REQUIRE_INIT();
XChangeProperty(_glfw.x11.display, x11_window_id,

3
kitty/glfw-wrapper.c generated
View File

@ -446,6 +446,9 @@ load_glfw(const char* path) {
*(void **) (&glfwCocoaSetBackgroundBlur_impl) = dlsym(handle, "glfwCocoaSetBackgroundBlur");
if (glfwCocoaSetBackgroundBlur_impl == NULL) dlerror(); // clear error indicator
*(void **) (&glfwSetX11WindowBlurred_impl) = dlsym(handle, "glfwSetX11WindowBlurred");
if (glfwSetX11WindowBlurred_impl == NULL) dlerror(); // clear error indicator
*(void **) (&glfwGetX11Display_impl) = dlsym(handle, "glfwGetX11Display");
if (glfwGetX11Display_impl == NULL) dlerror(); // clear error indicator

5
kitty/glfw-wrapper.h generated
View File

@ -785,6 +785,7 @@ typedef enum {
* [window hint](@ref GLFW_X11_CLASS_NAME_hint).
*/
#define GLFW_X11_INSTANCE_NAME 0x00024002
#define GLFW_X11_BLUR 0x00024003
#define GLFW_WAYLAND_APP_ID 0x00025001
/*! @} */
@ -2224,6 +2225,10 @@ typedef int (*glfwCocoaSetBackgroundBlur_func)(GLFWwindow*, int);
GFW_EXTERN glfwCocoaSetBackgroundBlur_func glfwCocoaSetBackgroundBlur_impl;
#define glfwCocoaSetBackgroundBlur glfwCocoaSetBackgroundBlur_impl
typedef bool (*glfwSetX11WindowBlurred_func)(GLFWwindow*, bool);
GFW_EXTERN glfwSetX11WindowBlurred_func glfwSetX11WindowBlurred_impl;
#define glfwSetX11WindowBlurred glfwSetX11WindowBlurred_impl
typedef void* (*glfwGetX11Display_func)(void);
GFW_EXTERN glfwGetX11Display_func glfwGetX11Display_impl;
#define glfwGetX11Display glfwGetX11Display_impl

View File

@ -900,14 +900,16 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
#endif
}
const bool set_blur = OPT(background_blur) > 0 && OPT(background_opacity) < 1.f;
#ifdef __APPLE__
glfwWindowHint(GLFW_COCOA_COLOR_SPACE, OPT(macos_colorspace));
if (OPT(background_blur) > 0 && OPT(background_opacity) < 1.f) {
if (set_blur) {
glfwWindowHint(GLFW_COCOA_BLUR_RADIUS, MIN(OPT(background_blur), 128));
} else {
glfwWindowHint(GLFW_COCOA_BLUR_RADIUS, 0);
}
#else
if (!global_state.is_wayland) glfwWindowHint(GLFW_X11_BLUR, set_blur);
glfwWindowHintString(GLFW_X11_INSTANCE_NAME, wm_class_name);
glfwWindowHintString(GLFW_X11_CLASS_NAME, wm_class_class);
glfwWindowHintString(GLFW_WAYLAND_APP_ID, wm_class_class);
@ -1088,12 +1090,11 @@ os_window_update_size_increments(OSWindow *window) {
void
update_background_blur(OSWindow *os_window) {
const bool should_blur = os_window->background_opacity < 1.f && OPT(background_blur) > 0 && os_window->is_semi_transparent;
#ifdef __APPLE__
int new_blur_radius = 0;
if (os_window->background_opacity < 1.f && OPT(background_blur) > -1) new_blur_radius = OPT(background_blur);
glfwCocoaSetBackgroundBlur(os_window->handle, new_blur_radius);
glfwCocoaSetBackgroundBlur(os_window->handle, should_blur ? OPT(background_blur) : 0);
#else
(void)os_window;
if (!global_state.is_wayland) glfwSetX11WindowBlurred(os_window->handle, should_blur);
#endif
}

View File

@ -1379,7 +1379,8 @@
control the :italic:`blur radius` (amount of blurring). Setting it to too high
a value will cause severe performance issues and/or rendering artifacts.
Usually, values up to 64 work well. Note that this might cause performance issues,
depending on how the platform implements it, so use with care.
depending on how the platform implements it, so use with care. Currently supported
on macOS and KDE/X11.
''')
opt('background_image', 'none',