From c1f8372efc80ea222466079fba399b146e382363 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 27 Mar 2021 00:41:21 +0530 Subject: [PATCH] Hide edges when not focused --- glfw/wl_client_side_decorations.c | 60 ++++++++++++++----------------- glfw/wl_platform.h | 1 + glfw/wl_window.c | 1 + 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/glfw/wl_client_side_decorations.c b/glfw/wl_client_side_decorations.c index 2de6d4909..02301a8fc 100644 --- a/glfw/wl_client_side_decorations.c +++ b/glfw/wl_client_side_decorations.c @@ -71,7 +71,7 @@ create_shm_buffers_for_title_bar(_GLFWwindow* window) { struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, mapping_sz); close(fd); #define c(offset) wl_shm_pool_create_buffer( \ - pool, offset, window->wl.width, window->wl.decorations.metrics.top, stride, WL_SHM_FORMAT_ARGB8888); + pool, offset, width, height, stride, WL_SHM_FORMAT_ARGB8888); tb.front_buffer = c(0); tb.back_buffer = c(tb.buffer_sz); #undef c wl_shm_pool_destroy(pool); @@ -79,14 +79,15 @@ create_shm_buffers_for_title_bar(_GLFWwindow* window) { } static void -render_left_edge(uint8_t *data, size_t width, size_t height) { - for (uint32_t *px = (uint32_t*)data, *end = (uint32_t*)(data + 4 * width * height); px < end; px++) *px = bg_color; +render_left_edge(uint8_t *data, size_t width, size_t height, bool is_focused) { + if (is_focused) for (uint32_t *px = (uint32_t*)data, *end = (uint32_t*)(data + 4 * width * height); px < end; px++) *px = bg_color; + else memset(data, 0, 4 * width * height); } #define render_right_edge render_left_edge #define render_bottom_edge render_left_edge static bool -create_shm_buffers_for_edges(_GLFWwindow* window) { +create_shm_buffers_for_edges(_GLFWwindow* window, bool is_focused) { free_edge_resources(window); int scale = window->wl.scale; if (scale < 1) scale = 1; @@ -111,9 +112,9 @@ create_shm_buffers_for_edges(_GLFWwindow* window) { close(fd); return false; } - render_left_edge(data, vertical_width, vertical_height); - render_right_edge(data + 4 * vertical_width * vertical_height, vertical_width, vertical_height); - render_bottom_edge(data + 8 * vertical_width * vertical_height, horizontal_width, horizontal_height); + render_left_edge(data, vertical_width, vertical_height, is_focused); + render_right_edge(data + 4 * vertical_width * vertical_height, vertical_width, vertical_height, is_focused); + render_bottom_edge(data + 8 * vertical_width * vertical_height, horizontal_width, horizontal_height, is_focused); struct wl_shm_pool* pool = wl_shm_create_pool(_glfw.wl.shm, fd, mapping_sz); close(fd); eb.left = wl_shm_pool_create_buffer( @@ -136,56 +137,47 @@ free_csd_surfaces(_GLFWwindow *window) { #undef d } -#define position_decoration_surfaces(which, x, y) { \ - wl_subsurface_set_position(decs.subsurfaces.which, x, y); \ - wl_surface_commit(decs.surfaces.which); \ -} - -#define create_decoration_surfaces(which, buffer) { \ +#define create_decoration_surfaces(which, buffer, x, y) { \ decs.surfaces.which = wl_compositor_create_surface(_glfw.wl.compositor); \ wl_surface_set_buffer_scale(decs.surfaces.which, window->wl.scale < 1 ? 1 : window->wl.scale); \ decs.subsurfaces.which = wl_subcompositor_get_subsurface(_glfw.wl.subcompositor, decs.surfaces.which, window->wl.surface); \ wl_surface_attach(decs.surfaces.which, buffer, 0, 0); \ + wl_subsurface_set_position(decs.subsurfaces.which, x, y); \ + wl_surface_commit(decs.surfaces.which); \ } bool ensure_csd_resources(_GLFWwindow *window) { - const bool size_changed = ( + const bool is_focused = window->id == _glfw.focusedWindowId; + const bool state_changed = ( decs.for_window_state.width != window->wl.width || decs.for_window_state.height != window->wl.height || - decs.for_window_state.scale != window->wl.scale + decs.for_window_state.scale != window->wl.scale || + decs.for_window_state.focused != is_focused ); - if (size_changed) { - free_title_bar_resources(window); - free_edge_resources(window); - } - if (!decs.edges.left) { - if (!create_shm_buffers_for_edges(window)) return false; - } - if (!decs.title_bar.front_buffer) { - if (!create_shm_buffers_for_title_bar(window)) return false; - } - int x, y; + if (state_changed) free_all_csd_resources(window); + else if (decs.edges.left && decs.title_bar.front_buffer) return true; + if (!create_shm_buffers_for_edges(window, is_focused)) return false; + if (!create_shm_buffers_for_title_bar(window)) return false; + + int x, y; x = 0; y = -decs.metrics.top; - if (!decs.surfaces.top) create_decoration_surfaces(top, decs.title_bar.front_buffer); - position_decoration_surfaces(top, x, y); + create_decoration_surfaces(top, decs.title_bar.front_buffer, x, y); x = -decs.metrics.width; y = -decs.metrics.top; - if (!decs.surfaces.left) create_decoration_surfaces(left, decs.edges.left); - position_decoration_surfaces(left, x, y); + create_decoration_surfaces(left, decs.edges.left, x, y); x = window->wl.width; y = -decs.metrics.top; - if (!decs.surfaces.right) create_decoration_surfaces(right, decs.edges.right); - position_decoration_surfaces(right, x, y); + create_decoration_surfaces(right, decs.edges.right, x, y); x = -decs.metrics.width; y = window->wl.height; - if (!decs.surfaces.bottom) create_decoration_surfaces(bottom, decs.edges.bottom); - position_decoration_surfaces(bottom, x, y); + create_decoration_surfaces(bottom, decs.edges.bottom, x, y); decs.for_window_state.width = window->wl.width; decs.for_window_state.height = window->wl.height; decs.for_window_state.scale = window->wl.scale; + decs.for_window_state.focused = is_focused; return true; } diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 4492b19b5..518e2011f 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -164,6 +164,7 @@ typedef struct _GLFWwindowWayland struct { int width, height, scale; + bool focused; } for_window_state; struct { diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 8d680a716..c84c33547 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -460,6 +460,7 @@ static void xdgToplevelHandleConfigure(void* data, } dispatchChangesAfterConfigure(window, width, height); _glfwInputWindowFocus(window, activated); + ensure_csd_resources(window); } static void xdgToplevelHandleClose(void* data,