Get background panel basically working on macOS

This commit is contained in:
Kovid Goyal
2025-04-23 12:42:24 +05:30
parent 88735743cf
commit 09eb5edcca

View File

@@ -1653,6 +1653,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
- (BOOL)canBecomeKeyWindow - (BOOL)canBecomeKeyWindow
{ {
if (glfw_window && glfw_window->ns.layer_shell.is_active) { if (glfw_window && glfw_window->ns.layer_shell.is_active) {
if (glfw_window->ns.layer_shell.config.type == GLFW_LAYER_SHELL_BACKGROUND) return NO;
switch(glfw_window->ns.layer_shell.config.focus_policy) { switch(glfw_window->ns.layer_shell.config.focus_policy) {
case GLFW_FOCUS_NOT_ALLOWED: return NO; case GLFW_FOCUS_NOT_ALLOWED: return NO;
case GLFW_FOCUS_EXCLUSIVE: return YES; case GLFW_FOCUS_EXCLUSIVE: return YES;
@@ -1665,7 +1666,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
- (BOOL)canBecomeMainWindow - (BOOL)canBecomeMainWindow
{ {
return YES; return !glfw_window->ns.layer_shell.is_active || glfw_window->ns.layer_shell.config.type != GLFW_LAYER_SHELL_BACKGROUND;
} }
static void static void
@@ -1928,42 +1929,63 @@ screen_for_window_center(_GLFWwindow *window) {
bool bool
_glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) { _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
#define config window->ns.layer_shell.config #define config window->ns.layer_shell.config
#define nswindow window->ns.object
window->resizable = false; window->resizable = false;
if (value) config = *value; if (value) config = *value;
const bool is_transparent = ![window->ns.object isOpaque]; const bool is_transparent = ![nswindow isOpaque];
int background_blur = config.related.background_blur; int background_blur = config.related.background_blur;
if (!is_transparent || config.related.background_opacity >= 1.f) { background_blur = 0; } if (!is_transparent || config.related.background_opacity >= 1.f) { background_blur = 0; }
[window->ns.object setBackgroundColor:nil]; [nswindow setBackgroundColor:nil];
_glfwPlatformSetWindowBlur(window, background_blur); _glfwPlatformSetWindowBlur(window, background_blur);
window->ns.titlebar_hidden = true; window->ns.titlebar_hidden = true;
window->decorated = false; window->decorated = false;
[window->ns.object setTitlebarAppearsTransparent:false]; [nswindow setTitlebarAppearsTransparent:false];
[window->ns.object setHasShadow:false]; [nswindow setHasShadow:false];
[window->ns.object setTitleVisibility:NSWindowTitleHidden]; [nswindow setTitleVisibility:NSWindowTitleHidden];
NSColorSpace *cs = nil; NSColorSpace *cs = nil;
switch (config.related.color_space) { switch (config.related.color_space) {
case SRGB_COLORSPACE: cs = [NSColorSpace sRGBColorSpace]; break; case SRGB_COLORSPACE: cs = [NSColorSpace sRGBColorSpace]; break;
case DISPLAY_P3_COLORSPACE: cs = [NSColorSpace displayP3ColorSpace]; break; case DISPLAY_P3_COLORSPACE: cs = [NSColorSpace displayP3ColorSpace]; break;
case DEFAULT_COLORSPACE: cs = nil; break; // using deviceRGBColorSpace causes a hang when transitioning to fullscreen case DEFAULT_COLORSPACE: cs = nil; break; // using deviceRGBColorSpace causes a hang when transitioning to fullscreen
} }
[window->ns.object setColorSpace:cs]; [nswindow setColorSpace:cs];
[[window->ns.object standardWindowButton: NSWindowCloseButton] setHidden:true]; [[nswindow standardWindowButton: NSWindowCloseButton] setHidden:true];
[[window->ns.object standardWindowButton: NSWindowMiniaturizeButton] setHidden:true]; [[nswindow standardWindowButton: NSWindowMiniaturizeButton] setHidden:true];
[[window->ns.object standardWindowButton: NSWindowZoomButton] setHidden:true]; [[nswindow standardWindowButton: NSWindowZoomButton] setHidden:true];
[window->ns.object setStyleMask:NSWindowStyleMaskBorderless]; [nswindow setStyleMask:NSWindowStyleMaskBorderless];
// HACK: Changing the style mask can cause the first responder to be cleared // HACK: Changing the style mask can cause the first responder to be cleared
[window->ns.object makeFirstResponder:window->ns.view]; [nswindow makeFirstResponder:window->ns.view];
uint32_t width = 0, height = 0;
NSScreen *screen = screen_for_window_center(window); NSScreen *screen = screen_for_window_center(window);
// CGFloat monitor_width = NSWidth(screen.frame), monitor_height = NSHeight(screen.frame);
unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing; unsigned cell_width, cell_height; double left_edge_spacing, top_edge_spacing, right_edge_spacing, bottom_edge_spacing;
float xscale = (float)config.expected.xscale, yscale = (float)config.expected.yscale; float xscale = (float)config.expected.xscale, yscale = (float)config.expected.yscale;
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale); _glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
config.size_callback((GLFWwindow*)window, xscale, yscale, &cell_width, &cell_height, &left_edge_spacing, &top_edge_spacing, &right_edge_spacing, &bottom_edge_spacing); config.size_callback((GLFWwindow*)window, xscale, yscale, &cell_width, &cell_height, &left_edge_spacing, &top_edge_spacing, &right_edge_spacing, &bottom_edge_spacing);
CGFloat x = NSMinX(screen.visibleFrame), y = NSMinY(screen.visibleFrame); CGFloat x = NSMinX(screen.visibleFrame), y = NSMinY(screen.visibleFrame) + 1, width = NSWidth(screen.visibleFrame), height = NSHeight(screen.visibleFrame);
[window->ns.object setFrame:NSMakeRect(x, y, (CGFloat)width, (CGFloat)height) display:YES]; CGFloat dock_height = NSMinY(screen.visibleFrame) - NSMinY(screen.frame);
CGFloat menubar_height = NSHeight(screen.frame) - NSHeight(screen.visibleFrame) - dock_height;
// Screen co-ordinate system is with origin in lower left and y increasing upwards and x increasing rightwards
// NSLog(@"frame: %@ visibleFrame: %@\n", NSStringFromRect(screen.frame), NSStringFromRect(screen.visibleFrame));
NSWindowLevel level = NSScreenSaverWindowLevel - 1;
NSWindowAnimationBehavior animation_behavior = NSWindowAnimationBehaviorUtilityWindow;
if (config.type == GLFW_LAYER_SHELL_BACKGROUND) {
x = NSMinX(screen.frame); height = NSHeight(screen.frame) - menubar_height + 1; y = NSMinY(screen.frame); width = NSWidth(screen.frame);
animation_behavior = NSWindowAnimationBehaviorNone;
// See: https://stackoverflow.com/questions/4982584/how-do-i-draw-the-desktop-on-mac-os-x/4982619#4982619
level = kCGDesktopWindowLevel;
}
x += config.requested_left_margin; width -= config.requested_left_margin + config.requested_right_margin;
y += config.requested_bottom_margin; height -= config.requested_top_margin + config.requested_bottom_margin;
[nswindow setAnimationBehavior:animation_behavior];
[nswindow setLevel:level];
[nswindow setCollectionBehavior: (NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorIgnoresCycle)];
[nswindow setFrame:NSMakeRect(x, y, width, height) display:YES animate:config.type != GLFW_LAYER_SHELL_BACKGROUND];
if (config.type == GLFW_LAYER_SHELL_BACKGROUND) [nswindow orderBack:nil];
else [nswindow orderFrontRegardless];
return true; return true;
#undef config #undef config
#undef nswindow
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
@@ -2135,7 +2157,9 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{ {
[window->ns.object orderFront:nil]; if (window->ns.layer_shell.is_active && window->ns.layer_shell.config.type == GLFW_LAYER_SHELL_BACKGROUND) {
[window->ns.object orderBack:nil];
} else [window->ns.object orderFront:nil];
} }
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformHideWindow(_GLFWwindow* window)