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
{
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) {
case GLFW_FOCUS_NOT_ALLOWED: return NO;
case GLFW_FOCUS_EXCLUSIVE: return YES;
@@ -1665,7 +1666,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) {
- (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
@@ -1928,42 +1929,63 @@ screen_for_window_center(_GLFWwindow *window) {
bool
_glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) {
#define config window->ns.layer_shell.config
#define nswindow window->ns.object
window->resizable = false;
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;
if (!is_transparent || config.related.background_opacity >= 1.f) { background_blur = 0; }
[window->ns.object setBackgroundColor:nil];
[nswindow 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];
[nswindow setTitlebarAppearsTransparent:false];
[nswindow setHasShadow:false];
[nswindow setTitleVisibility:NSWindowTitleHidden];
NSColorSpace *cs = nil;
switch (config.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];
[nswindow setColorSpace:cs];
[[nswindow standardWindowButton: NSWindowCloseButton] setHidden:true];
[[nswindow standardWindowButton: NSWindowMiniaturizeButton] setHidden:true];
[[nswindow standardWindowButton: NSWindowZoomButton] setHidden:true];
[nswindow 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;
[nswindow makeFirstResponder:window->ns.view];
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;
float xscale = (float)config.expected.xscale, yscale = (float)config.expected.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);
CGFloat x = NSMinX(screen.visibleFrame), y = NSMinY(screen.visibleFrame);
[window->ns.object setFrame:NSMakeRect(x, y, (CGFloat)width, (CGFloat)height) display:YES];
CGFloat x = NSMinX(screen.visibleFrame), y = NSMinY(screen.visibleFrame) + 1, width = NSWidth(screen.visibleFrame), height = NSHeight(screen.visibleFrame);
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;
#undef config
#undef nswindow
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
@@ -2135,7 +2157,9 @@ void _glfwPlatformMaximizeWindow(_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)