macOS: Implement background blurring

Uses a private API that allows us to control the amount of blurring.
While using a private API is obviously not ideal, it is used by both
iTerm.app and Apple's own Terminal.app, so hopefully it should stick
around. Fixes #6135
This commit is contained in:
Kovid Goyal
2023-06-27 08:48:16 +05:30
parent 326b81a970
commit 7a1bdb4ff1
15 changed files with 89 additions and 1 deletions

View File

@@ -139,6 +139,7 @@ typedef struct _GLFWwindowNS
int width, height;
int fbWidth, fbHeight;
float xscale, yscale;
int blur_radius;
// The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed

View File

@@ -36,6 +36,8 @@
#include <string.h>
GLFWAPI int glfwCocoaSetBackgroundBlur(GLFWwindow *w, int radius);
static const char*
polymorphic_string_as_utf8(id string) {
if (string == nil) return "(nil)";
@@ -1835,6 +1837,7 @@ static bool createNativeWindow(_GLFWwindow* window,
_glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height);
_glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight);
if (wndconfig->ns.blur_radius > 0) glfwCocoaSetBackgroundBlur((GLFWwindow*)window, wndconfig->ns.blur_radius);
return true;
}
@@ -2969,6 +2972,18 @@ GLFWAPI void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun
requestRenderFrame((_GLFWwindow*)w, callback);
}
GLFWAPI int glfwCocoaSetBackgroundBlur(GLFWwindow *w, int radius) {
_GLFWwindow* window = (_GLFWwindow*)w;
int orig = window->ns.blur_radius;
if (radius > -1 && radius != window->ns.blur_radius) {
extern OSStatus CGSSetWindowBackgroundBlurRadius(void* connection, NSInteger windowNumber, int radius);
extern void* CGSDefaultConnectionForThread(void);
CGSSetWindowBackgroundBlurRadius(CGSDefaultConnectionForThread(), [window->ns.object windowNumber], radius);
window->ns.blur_radius = radius;
}
return orig;
}
GLFWAPI int glfwGetCurrentSystemColorTheme(void) {
int theme_type = 0;
NSAppearance *changedAppearance = NSApp.effectiveAppearance;

View File

@@ -249,6 +249,7 @@ def generate_wrappers(glfw_header: str) -> None:
GLFWapplicationwillfinishlaunchingfun glfwSetApplicationWillFinishLaunching(GLFWapplicationwillfinishlaunchingfun callback)
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)
void* glfwGetX11Display(void)
int32_t glfwGetX11Window(GLFWwindow* window)
void glfwSetPrimarySelectionString(GLFWwindow* window, const char* string)

4
glfw/glfw3.h vendored
View File

@@ -1034,6 +1034,10 @@ typedef enum {
SRGB_COLORSPACE = 1,
DISPLAY_P3_COLORSPACE = 2,
} GlfwCocoaColorSpaces;
/*! @brief macOS specific
* [window hint](@ref GLFW_COCOA_BLUR_RADIUS_hint).
*/
#define GLFW_COCOA_BLUR_RADIUS 0x00023005
/*! @brief X11 specific
* [window hint](@ref GLFW_X11_CLASS_NAME_hint).

1
glfw/internal.h vendored
View File

@@ -313,6 +313,7 @@ struct _GLFWwndconfig
struct {
bool retina;
int color_space;
int blur_radius;
char frameName[256];
} ns;
struct {

5
glfw/window.c vendored
View File

@@ -334,6 +334,8 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.ns.retina = true;
// use the default colorspace assigned by the system
_glfw.hints.window.ns.color_space = 0;
// no blur
_glfw.hints.window.ns.blur_radius = 0;
}
GLFWAPI void glfwWindowHint(int hint, int value)
@@ -417,6 +419,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_COCOA_COLOR_SPACE:
_glfw.hints.window.ns.color_space = value;
return;
case GLFW_COCOA_BLUR_RADIUS:
_glfw.hints.window.ns.blur_radius = value;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? true : false;
return;