From 0bf228b0304fc5186dca3f3ec72ab20708a31220 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 10 Sep 2022 15:16:11 +0530 Subject: [PATCH] Wayland: Micro-optimization: Assume window will be shown on primary monitor so create it with its scale set to that of the primary monitor --- glfw/wl_window.c | 23 ++++++++++++++++++----- kitty/glfw.c | 5 +++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/glfw/wl_window.c b/glfw/wl_window.c index cd21e465d..4939906aa 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -380,11 +380,22 @@ static bool createSurface(_GLFWwindow* window, wl_surface_set_user_data(window->wl.surface, window); + // If we already have been notified of the primary monitor scale, assume + // the window will be created on it and so avoid a rescale roundtrip in the common + // case of the window being shown on the primary monitor or all monitors having the same scale. + // If you change this also change get_window_content_scale() in the kitty code. + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + float xscale = 1.0, yscale = 1.0; + int scale = 1; + if (monitor) { + glfwGetMonitorContentScale(monitor, &xscale, &yscale); + // see wl_monitor.c xscale is always == yscale + if (xscale <= 0.0001 || xscale != xscale || xscale >= 24) xscale = 1.0; + if (xscale > 1) scale = (int)xscale; + } - debug("Creating window at size: %dx%d and scale 1\n", wndconfig->width, wndconfig->height); - window->wl.native = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); + debug("Creating window at size: %dx%d and scale %d\n", wndconfig->width, wndconfig->height, scale); + window->wl.native = wl_egl_window_create(window->wl.surface, wndconfig->width * scale, wndconfig->height * scale); if (!window->wl.native) return false; @@ -392,11 +403,13 @@ static bool createSurface(_GLFWwindow* window, window->wl.height = wndconfig->height; window->wl.user_requested_content_size.width = wndconfig->width; window->wl.user_requested_content_size.height = wndconfig->height; - window->wl.scale = 1; + + window->wl.scale = scale; if (!window->wl.transparent) setOpaqueRegion(window, false); + wl_surface_set_buffer_scale(window->wl.surface, scale); return true; } diff --git a/kitty/glfw.c b/kitty/glfw.c index 6193d684a..ea489a3b0 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -641,6 +641,7 @@ set_os_window_size(OSWindow *os_window, int x, int y) { static void get_window_content_scale(GLFWwindow *w, float *xscale, float *yscale, double *xdpi, double *ydpi) { + // if you change this function also change createSurface() in wl_window.c *xscale = 1; *yscale = 1; if (w) glfwGetWindowContentScale(w, xscale, yscale); else { @@ -841,6 +842,10 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) { if (!global_state.is_wayland) { // On Wayland windows dont get a content scale until they receive an enterEvent anyway // which won't happen until the event loop ticks, so using a temp window is useless. + // The glfw backend assigns new windows a scale matching the primary monitor or 1 if + // no monitor has yet been reported. This is mimiced by get_window_content_scale() when + // using a null window, so we will match. Lets hope neither of these two change their algorithms + // in the future. temp_window = glfwCreateWindow(640, 480, "temp", NULL, common_context); if (temp_window == NULL) { fatal("Failed to create GLFW temp window! This usually happens because of old/broken OpenGL drivers. kitty requires working OpenGL 3.3 drivers."); } }