mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 01:38:02 +02:00
Factor out Cocoa layer shell code into the proper function
This commit is contained in:
6
glfw/cocoa_platform.h
vendored
6
glfw/cocoa_platform.h
vendored
@@ -152,8 +152,10 @@ typedef struct _GLFWwindowNS
|
||||
UInt32 deadKeyState;
|
||||
|
||||
// Layer shell windows
|
||||
bool is_layer_shell;
|
||||
GLFWLayerShellConfig layer_shell_config;
|
||||
struct {
|
||||
bool is_active;
|
||||
GLFWLayerShellConfig config;
|
||||
} layer_shell;
|
||||
|
||||
// Whether a render frame has been requested for this window
|
||||
bool renderFrameRequested;
|
||||
|
||||
@@ -1652,8 +1652,8 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
if (glfw_window && glfw_window->ns.is_layer_shell) {
|
||||
switch(glfw_window->ns.layer_shell_config.focus_policy) {
|
||||
if (glfw_window && glfw_window->ns.layer_shell.is_active) {
|
||||
switch(glfw_window->ns.layer_shell.config.focus_policy) {
|
||||
case GLFW_FOCUS_NOT_ALLOWED: return NO;
|
||||
case GLFW_FOCUS_EXCLUSIVE: return YES;
|
||||
case GLFW_FOCUS_ON_DEMAND: return YES;
|
||||
@@ -1829,9 +1829,9 @@ static bool createNativeWindow(_GLFWwindow* window,
|
||||
int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, const GLFWLayerShellConfig *lsc) {
|
||||
window->ns.deadKeyState = 0;
|
||||
if (lsc) {
|
||||
window->ns.is_layer_shell = true;
|
||||
window->ns.layer_shell_config = *lsc;
|
||||
} else window->ns.is_layer_shell = false;
|
||||
window->ns.layer_shell.is_active = true;
|
||||
window->ns.layer_shell.config = *lsc;
|
||||
} else window->ns.layer_shell.is_active = false;
|
||||
if (!_glfw.ns.finishedLaunching)
|
||||
{
|
||||
[NSApp run];
|
||||
@@ -1913,9 +1913,51 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
window->ns.object = nil;
|
||||
}
|
||||
|
||||
bool _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
(void)window; (void)value;
|
||||
return false;
|
||||
static NSScreen*
|
||||
screen_for_window_center(_GLFWwindow *window) {
|
||||
NSRect windowFrame = [window->ns.object frame];
|
||||
NSPoint windowCenter = NSMakePoint(NSMidX(windowFrame), NSMidY(windowFrame));
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
if (NSPointInRect(windowCenter, [screen frame])) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
return NSScreen.mainScreen;
|
||||
}
|
||||
|
||||
bool
|
||||
_glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
|
||||
window->resizable = false;
|
||||
const bool is_transparent = ![window->ns.object isOpaque];
|
||||
int background_blur = value->related.background_blur;
|
||||
if (!is_transparent || value->related.background_opacity >= 1.f) { background_blur = 0; }
|
||||
[window->ns.object setBackgroundColor:nil];
|
||||
_glfwPlatformSetWindowBlur(window, background_blur);
|
||||
window->ns.titlebar_hidden = true;
|
||||
window->decorated = false;
|
||||
[window->ns.object setTitlebarAppearsTransparent:false];
|
||||
[window->ns.object setHasShadow:false];
|
||||
[window->ns.object setTitleVisibility:NSWindowTitleHidden];
|
||||
NSColorSpace *cs = nil;
|
||||
switch (value->related.color_space) {
|
||||
case SRGB_COLORSPACE: cs = [NSColorSpace sRGBColorSpace]; break;
|
||||
case DISPLAY_P3_COLORSPACE: cs = [NSColorSpace displayP3ColorSpace]; break;
|
||||
case DEFAULT_COLORSPACE: cs = nil; break; // using deviceRGBColorSpace causes a hang when transitioning to fullscreen
|
||||
}
|
||||
[window->ns.object setColorSpace:cs];
|
||||
[[window->ns.object standardWindowButton: NSWindowCloseButton] setHidden:true];
|
||||
[[window->ns.object standardWindowButton: NSWindowMiniaturizeButton] setHidden:true];
|
||||
[[window->ns.object standardWindowButton: NSWindowZoomButton] setHidden:true];
|
||||
[window->ns.object setStyleMask:NSWindowStyleMaskBorderless];
|
||||
// HACK: Changing the style mask can cause the first responder to be cleared
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
uint32_t width = 0, height = 0;
|
||||
NSScreen *screen = screen_for_window_center(window);
|
||||
CGFloat monitor_width = NSWidth(screen.frame), monitor_height = NSHeight(screen.frame);
|
||||
window->ns.layer_shell.config.size_callback((GLFWwindow*)window, &window->ns.layer_shell.config, (unsigned)monitor_width, (unsigned)monitor_height, &width, &height);
|
||||
CGFloat x = NSMinX(screen.visibleFrame), y = NSMinY(screen.visibleFrame);
|
||||
[window->ns.object setFrame:NSMakeRect(x, y, (CGFloat)width, (CGFloat)height) display:YES];
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
@@ -1966,7 +2008,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (window->ns.is_layer_shell) return;
|
||||
if (window->ns.layer_shell.is_active) return;
|
||||
if (window->monitor)
|
||||
{
|
||||
if (window->monitor->window == window)
|
||||
@@ -3003,67 +3045,9 @@ GLFWAPI GLFWcocoarenderframefun glfwCocoaSetWindowResizeCallback(GLFWwindow *w,
|
||||
return current;
|
||||
}
|
||||
|
||||
static NSScreen*
|
||||
screen_for_window_center(_GLFWwindow *window) {
|
||||
NSRect windowFrame = [window->ns.object frame];
|
||||
NSPoint windowCenter = NSMakePoint(NSMidX(windowFrame), NSMidY(windowFrame));
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
if (NSPointInRect(windowCenter, [screen frame])) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
return NSScreen.mainScreen;
|
||||
}
|
||||
|
||||
static void
|
||||
apply_layer_shell_properties(_GLFWwindow *window, int background_blur, unsigned system_color, int color_space) {
|
||||
window->resizable = false;
|
||||
const bool is_transparent = ![window->ns.object isOpaque];
|
||||
if (!is_transparent) { background_blur = 0; }
|
||||
NSAppearance *appearance = nil;
|
||||
NSAppearance *light_appearance = is_transparent ? [NSAppearance appearanceNamed:NSAppearanceNameVibrantLight] : [NSAppearance appearanceNamed:NSAppearanceNameAqua];
|
||||
NSAppearance *dark_appearance = is_transparent ? [NSAppearance appearanceNamed:NSAppearanceNameVibrantDark] : [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
|
||||
NSColor *background = nil;
|
||||
switch (system_color) {
|
||||
case 1:
|
||||
appearance = light_appearance; break;
|
||||
case 2:
|
||||
appearance = dark_appearance; break;
|
||||
}
|
||||
[window->ns.object setBackgroundColor:background];
|
||||
[window->ns.object setAppearance:appearance];
|
||||
_glfwPlatformSetWindowBlur(window, background_blur);
|
||||
window->ns.titlebar_hidden = true;
|
||||
window->decorated = false;
|
||||
[window->ns.object setTitlebarAppearsTransparent:false];
|
||||
[window->ns.object setHasShadow:false];
|
||||
[window->ns.object setTitleVisibility:NSWindowTitleHidden];
|
||||
NSColorSpace *cs = nil;
|
||||
switch (color_space) {
|
||||
case SRGB_COLORSPACE: cs = [NSColorSpace sRGBColorSpace]; break;
|
||||
case DISPLAY_P3_COLORSPACE: cs = [NSColorSpace displayP3ColorSpace]; break;
|
||||
case DEFAULT_COLORSPACE: cs = nil; break; // using deviceRGBColorSpace causes a hang when transitioning to fullscreen
|
||||
}
|
||||
[window->ns.object setColorSpace:cs];
|
||||
[[window->ns.object standardWindowButton: NSWindowCloseButton] setHidden:true];
|
||||
[[window->ns.object standardWindowButton: NSWindowMiniaturizeButton] setHidden:true];
|
||||
[[window->ns.object standardWindowButton: NSWindowZoomButton] setHidden:true];
|
||||
[window->ns.object setStyleMask:NSWindowStyleMaskBorderless];
|
||||
// HACK: Changing the style mask can cause the first responder to be cleared
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
uint32_t width = 0, height = 0;
|
||||
NSScreen *screen = screen_for_window_center(window);
|
||||
NSRect frame = screen.frame;
|
||||
CGFloat monitor_width = NSWidth(frame), monitor_height = NSHeight(frame);
|
||||
window->ns.layer_shell_config.size_callback((GLFWwindow*)window, &window->ns.layer_shell_config, (unsigned)monitor_width, (unsigned)monitor_height, &width, &height);
|
||||
NSRect window_frame = [window->ns.object frame];
|
||||
CGFloat x = 0, y = NSMinY(window_frame);
|
||||
[window->ns.object setFrame:NSMakeRect(x, y, (CGFloat)width, (CGFloat)height) display:YES];
|
||||
}
|
||||
|
||||
GLFWAPI void glfwCocoaSetWindowChrome(GLFWwindow *w, unsigned int color, bool use_system_color, unsigned int system_color, int background_blur, unsigned int hide_window_decorations, bool show_text_in_titlebar, int color_space, float background_opacity, bool resizable) { @autoreleasepool {
|
||||
_GLFWwindow* window = (_GLFWwindow*)w;
|
||||
if (window->ns.is_layer_shell) { apply_layer_shell_properties(window, background_blur, system_color, color_space); return; }
|
||||
if (window->ns.layer_shell.is_active) return;
|
||||
const bool is_transparent = ![window->ns.object isOpaque];
|
||||
if (!is_transparent) { background_opacity = 1.0; background_blur = 0; }
|
||||
NSColor *background = nil;
|
||||
|
||||
3
glfw/glfw3.h
vendored
3
glfw/glfw3.h
vendored
@@ -1321,6 +1321,9 @@ typedef struct GLFWLayerShellConfig {
|
||||
unsigned override_exclusive_zone;
|
||||
void (*size_callback)(GLFWwindow *window, const struct GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height);
|
||||
struct { double xdpi, ydpi, xscale, yscale; } expected;
|
||||
struct {
|
||||
float background_opacity; int background_blur, color_space;
|
||||
} related;
|
||||
} GLFWLayerShellConfig;
|
||||
|
||||
typedef struct GLFWDBUSNotificationData {
|
||||
|
||||
Reference in New Issue
Block a user