diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 1e5b18fe4..7d26292ac 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1927,6 +1927,7 @@ screen_for_window_center(_GLFWwindow *window) { bool _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig *value) { +#define config window->ns.layer_shell.config window->resizable = false; const bool is_transparent = ![window->ns.object isOpaque]; int background_blur = value->related.background_blur; @@ -1953,11 +1954,15 @@ _glfwPlatformSetLayerShellConfig(_GLFWwindow* window, const GLFWLayerShellConfig [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 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]; return true; + #undef config } void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 8d3d4574a..3c50fdd84 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1319,8 +1319,8 @@ typedef struct GLFWLayerShellConfig { unsigned requested_right_margin; int requested_exclusive_zone; 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; + void (*size_callback)(GLFWwindow *window, float xscale, float yscale, unsigned *cell_width, unsigned *cell_height, double *left_edge_spacing, double *top_edge_spacing, double *right_edge_spacing, double *bottom_edge_spacing); + struct { float xscale, yscale; } expected; struct { float background_opacity; int background_blur, color_space; } related; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 9e8d27e8d..505cb3ceb 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -1035,6 +1035,48 @@ layer_set_properties(_GLFWwindow *window) { #undef surface } +static void +calculate_layer_size(_GLFWwindow *window, uint32_t *width, uint32_t *height) { + const GLFWLayerShellConfig *config = &window->wl.layer_shell.config; + GLFWvidmode m = {0}; + if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m); + const int y_margin = config->requested_bottom_margin + config->requested_top_margin, x_margin = config->requested_left_margin + config->requested_right_margin; + const int monitor_width = MAX(0, m.width - x_margin), monitor_height = MAX(0, m.height - y_margin); + float xscale = (float)config->expected.xscale, yscale = (float)config->expected.yscale; + if (window->wl.window_fully_created) _glfwPlatformGetWindowContentScale(window, &xscale, &yscale); + unsigned cell_width, cell_height; double 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); + double spacing_x = left_edge_spacing + right_edge_spacing; + double spacing_y = top_edge_spacing + bottom_edge_spacing; + if (config->type == GLFW_LAYER_SHELL_BACKGROUND) { + if (!*width) *width = monitor_width; + if (!*height) *height = monitor_height; + return; + } + debug("Calculating layer shell window size at scale: %f\n", xscale); + const unsigned xsz = config->x_size_in_pixels ? (unsigned)(config->x_size_in_pixels * xscale) : (cell_width * config->x_size_in_cells); + const unsigned ysz = config->y_size_in_pixels ? (unsigned)(config->y_size_in_pixels * yscale) : (cell_height * config->y_size_in_cells); + if (config->edge == GLFW_EDGE_LEFT || config->edge == GLFW_EDGE_RIGHT) { + if (!*height) *height = monitor_height; + double spacing = spacing_x; + spacing += xsz / xscale; + *width = (uint32_t)(1. + spacing); + } else if (config->edge == GLFW_EDGE_TOP || config->edge == GLFW_EDGE_BOTTOM) { + if (!*width) *width = monitor_width; + double spacing = spacing_y; + spacing += ysz / yscale; + *height = (uint32_t)(1. + spacing); + } else if (config->edge == GLFW_EDGE_CENTER) { + if (!*width) *width = monitor_width; + if (!*height) *height = monitor_height; + } else { + spacing_x += xsz / xscale; + spacing_y += ysz / yscale; + *width = (uint32_t)(1. + spacing_x); + *height = (uint32_t)(1. + spacing_y); + } +} + static void layer_surface_handle_configure(void* data, struct zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) { debug("Layer shell configure event: width: %u height: %u\n", width, height); @@ -1047,8 +1089,7 @@ layer_surface_handle_configure(void* data, struct zwlr_layer_surface_v1* surface } GLFWvidmode m = {0}; if (window->wl.monitorsCount) _glfwPlatformGetVideoMode(window->wl.monitors[0], &m); - window->wl.layer_shell.config.size_callback( - (GLFWwindow*)window, &window->wl.layer_shell.config, m.width, m.height, &width, &height); + calculate_layer_size(window, &width, &height); zwlr_layer_surface_v1_ack_configure(surface, serial); if ((int)width != window->wl.width || (int)height != window->wl.height) { debug("Layer shell size changed to %ux%u in layer_surface_handle_configure\n", width, height); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index f37adadcf..49d79337c 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1057,8 +1057,8 @@ typedef struct GLFWLayerShellConfig { unsigned requested_right_margin; int requested_exclusive_zone; 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; + void (*size_callback)(GLFWwindow *window, float xscale, float yscale, unsigned *cell_width, unsigned *cell_height, double *left_edge_spacing, double *top_edge_spacing, double *right_edge_spacing, double *bottom_edge_spacing); + struct { float xscale, yscale; } expected; struct { float background_opacity; int background_blur, color_space; } related; diff --git a/kitty/glfw.c b/kitty/glfw.c index 12db0848c..efd9e1473 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -1125,49 +1125,17 @@ edge_spacing(GLFWEdge which) { static void calculate_layer_shell_window_size( - GLFWwindow *window, const GLFWLayerShellConfig *config, unsigned monitor_width, unsigned monitor_height, uint32_t *width, uint32_t *height) { - request_tick_callback(); - if (config->type == GLFW_LAYER_SHELL_BACKGROUND) { - if (!*width) *width = monitor_width; - if (!*height) *height = monitor_height; - return; - } - float xscale = (float)config->expected.xscale, yscale = (float)config->expected.yscale; - double xdpi = config->expected.xdpi, ydpi = config->expected.ydpi; - if (global_state.is_apple || (global_state.is_wayland && glfwWaylandIsWindowFullyCreated(window))) { - glfwGetWindowContentScale(window, &xscale, &yscale); - dpi_from_scale(xscale, yscale, &xdpi, &ydpi); - } + GLFWwindow *window, float xscale, float yscale, unsigned *cell_width, unsigned *cell_height, double *left_edge_spacing, double *top_edge_spacing, double *right_edge_spacing, double *bottom_edge_spacing) { OSWindow *os_window = os_window_for_glfw_window(window); - debug("Calculating layer shell window size at scale: %f\n", xscale); + double xdpi, ydpi; + dpi_from_scale(xscale, yscale, &xdpi, &ydpi); FONTS_DATA_HANDLE fonts_data = load_fonts_data(os_window ? os_window->fonts_data->font_sz_in_pts : OPT(font_size), xdpi, ydpi); - const unsigned xsz = config->x_size_in_pixels ? (unsigned)(config->x_size_in_pixels * xscale) : (fonts_data->fcm.cell_width * config->x_size_in_cells); - const unsigned ysz = config->y_size_in_pixels ? (unsigned)(config->y_size_in_pixels * yscale) : (fonts_data->fcm.cell_height * config->y_size_in_cells); - if (config->edge == GLFW_EDGE_LEFT || config->edge == GLFW_EDGE_RIGHT) { - if (!*height) *height = monitor_height; - double spacing = edge_spacing(GLFW_EDGE_LEFT) + edge_spacing(GLFW_EDGE_RIGHT); - spacing *= xdpi / 72.; - spacing += xsz / xscale; - *width = (uint32_t)(1. + spacing); - } else if (config->edge == GLFW_EDGE_TOP || config->edge == GLFW_EDGE_BOTTOM) { - if (!*width) *width = monitor_width; - double spacing = edge_spacing(GLFW_EDGE_TOP) + edge_spacing(GLFW_EDGE_BOTTOM); - spacing *= ydpi / 72.; - spacing += ysz / yscale; - *height = (uint32_t)(1. + spacing); - } else if (config->edge == GLFW_EDGE_CENTER) { - if (!*width) *width = monitor_width; - if (!*height) *height = monitor_height; - } else { - double spacing_x = edge_spacing(GLFW_EDGE_LEFT) + edge_spacing(GLFW_EDGE_RIGHT); - spacing_x *= xdpi / 72.; - spacing_x += xsz / xscale; - double spacing_y = edge_spacing(GLFW_EDGE_TOP) + edge_spacing(GLFW_EDGE_BOTTOM); - spacing_y *= ydpi / 72.; - spacing_y += ysz / yscale; - *width = (uint32_t)(1. + spacing_x); - *height = (uint32_t)(1. + spacing_y); - } + *cell_width = fonts_data->fcm.cell_width; *cell_height = fonts_data->fcm.cell_height; + double x_factor = xdpi / 72., y_factor = ydpi / 72.; + *left_edge_spacing = edge_spacing(GLFW_EDGE_LEFT) * x_factor; + *top_edge_spacing = edge_spacing(GLFW_EDGE_TOP) * y_factor; + *right_edge_spacing = edge_spacing(GLFW_EDGE_RIGHT) * x_factor; + *bottom_edge_spacing = edge_spacing(GLFW_EDGE_BOTTOM) * y_factor; } static PyObject* @@ -1352,7 +1320,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) { Py_CLEAR(ret); if (lsc) { if (!layer_shell_config_from_python(layer_shell_config, lsc)) return NULL; - lsc->expected.xdpi = xdpi; lsc->expected.ydpi = ydpi; lsc->expected.xscale = xscale; lsc->expected.yscale = yscale; + lsc->expected.xscale = xscale; lsc->expected.yscale = yscale; } GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, temp_window ? temp_window : common_context, lsc); if (temp_window) { glfwDestroyWindow(temp_window); temp_window = NULL; }