diff --git a/render.c b/render.c index 91dac6a8..598141ef 100644 --- a/render.c +++ b/render.c @@ -665,59 +665,74 @@ render_worker_thread(void *_ctx) void render_csd(struct terminal *term) { - if (!term->window->use_csd) - return; + switch (term->window->use_csd) { + case CSD_UNKNOWN: + case CSD_NO: + break; - const int border_width = csd_border_size * term->scale; - const int title_height = csd_title_size * term->scale; + case CSD_YES: { + const int border_width = csd_border_size * term->scale; + const int title_height = csd_title_size * term->scale; - const int geom[5][4] = { - /* X, Y, WIDTH, HEIGHT */ - { border_width, border_width, term->width - 2 * border_width, title_height}, /* title */ - { 0, border_width, border_width, term->height - 2 * border_width}, /* left */ - {term->width - border_width, border_width, border_width, term->height - 2 * border_width}, /* right */ - { 0, 0, term->width, border_width}, /* top */ - { 0, term->height - border_width, term->width, border_width}, /* bottom */ - }; + const int geom[5][4] = { + /* X, Y, WIDTH, HEIGHT */ +#if FOOT_CSD_OUTSIDE + { 0, -title_height, term->width, title_height}, /* title */ + { -border_width, -title_height, border_width, title_height + term->height}, /* left */ + { term->width, -title_height, border_width, title_height + term->height}, /* right */ + { -border_width, -title_height - border_width, term->width + 2 * border_width, border_width}, /* top */ + { -border_width, term->height, term->width + 2 * border_width, border_width}, /* bottom */ +#else + { border_width, border_width, term->width - 2 * border_width, title_height}, /* title */ + { 0, border_width, border_width, term->height - 2 * border_width}, /* left */ + {term->width - border_width, border_width, border_width, term->height - 2 * border_width}, /* right */ + { 0, 0, term->width, border_width}, /* top */ + { 0, term->height - border_width, term->width, border_width}, /* bottom */ +#endif + }; - struct wl_region *region = wl_compositor_create_region(term->wl->compositor); - if (region != NULL) - wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); + struct wl_region *region = wl_compositor_create_region(term->wl->compositor); + if (region != NULL) + wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); - for (size_t i = 0; i < sizeof(geom) / sizeof(geom[0]); i++) { - struct wl_surface *surf = term->window->csd.surface[i]; - struct wl_subsurface *sub = term->window->csd.sub_surface[i]; + for (size_t i = 0; i < sizeof(geom) / sizeof(geom[0]); i++) { + struct wl_surface *surf = term->window->csd.surface[i]; + struct wl_subsurface *sub = term->window->csd.sub_surface[i]; - const int x = geom[i][0]; - const int y = geom[i][1]; - const int width = geom[i][2]; - const int height = geom[i][3]; + const int x = geom[i][0]; + const int y = geom[i][1]; + const int width = geom[i][2]; + const int height = geom[i][3]; - unsigned long cookie = shm_cookie_csd(term, i); - struct buffer *buf = shm_get_buffer(term->wl->shm, width, height, cookie); + unsigned long cookie = shm_cookie_csd(term, i); + struct buffer *buf = shm_get_buffer(term->wl->shm, width, height, cookie); - pixman_color_t color = color_hex_to_pixman(term->colors.fg); - if (!term->visual_focus) - pixman_color_dim(&color); + pixman_color_t color = color_hex_to_pixman(term->colors.fg); + if (!term->visual_focus) + pixman_color_dim(&color); - pixman_image_t *src = pixman_image_create_solid_fill(&color); + pixman_image_t *src = pixman_image_create_solid_fill(&color); - pixman_image_fill_rectangles( - PIXMAN_OP_SRC, buf->pix, &color, 1, - &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); - pixman_image_unref(src); + pixman_image_fill_rectangles( + PIXMAN_OP_SRC, buf->pix, &color, 1, + &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); + pixman_image_unref(src); - wl_subsurface_set_position(sub, x, y); + wl_subsurface_set_position(sub, x, y); - wl_surface_attach(surf, buf->wl_buf, 0, 0); - wl_surface_set_opaque_region(surf, region); - wl_surface_damage_buffer(surf, 0, 0, buf->width, buf->height); - wl_surface_set_buffer_scale(surf, term->scale); - wl_surface_commit(surf); + wl_surface_attach(surf, buf->wl_buf, 0, 0); + wl_surface_set_opaque_region(surf, region); + wl_surface_damage_buffer(surf, 0, 0, buf->width, buf->height); + wl_surface_set_buffer_scale(surf, term->scale); + wl_surface_commit(surf); + } + + if (region != NULL) + wl_region_destroy(region); + + break; + } } - - if (region != NULL) - wl_region_destroy(region); } static void frame_callback( @@ -1043,7 +1058,11 @@ render_search_box(struct terminal *term) assert(term->scale >= 1); const int scale = term->scale; - const int csd = term->window->use_csd ? csd_border_size * scale : 0; +#if FOOT_CSD_OUTSIDE + const int csd = 0; +#else + const int csd = term->window->use_csd == CSD_YES ? csd_border_size * scale : 0; +#endif const size_t margin = csd + 3 * scale; const size_t width = min( @@ -1144,8 +1163,14 @@ maybe_resize(struct terminal *term, int width, int height, bool force) height *= scale; /* Scaled CSD border + title bar sizes */ - const int csd_border = term->window->use_csd ? csd_border_size * scale : 0; - const int csd_title = term->window->use_csd ? csd_title_size * scale : 0; +#if FOOT_CSD_OUTSIDE + const int csd_border = 0; + const int csd_title = 0; +#else + const int csd_border = term->window->use_csd == CSD_YES ? csd_border_size * scale : 0; + const int csd_title = term->window->use_csd == CSD_YES ? ? csd_title_size * scale : 0; +#endif + const int csd_x = 2 * csd_border; const int csd_y = 2 * csd_border + csd_title; diff --git a/terminal.c b/terminal.c index b568731c..fe8860ad 100644 --- a/terminal.c +++ b/terminal.c @@ -1633,14 +1633,18 @@ term_visual_focus_in(struct terminal *term) if (term->cursor_blink.active) cursor_blink_start_timer(term); -#if 1 - for (int i = 0; i < 5; i++) - wl_subsurface_set_desync(term->window->csd.sub_surface[i]); +#if 1 /* Weston seems to be buggy with synchronized CSDs */ + if (term->window->use_csd == CSD_YES) { + for (int i = 0; i < 5; i++) + wl_subsurface_set_desync(term->window->csd.sub_surface[i]); + } #endif render_csd(term); #if 1 - for (int i = 0; i < 5; i++) - wl_subsurface_set_sync(term->window->csd.sub_surface[i]); + if (term->window->use_csd == CSD_YES) { + for (int i = 0; i < 5; i++) + wl_subsurface_set_sync(term->window->csd.sub_surface[i]); + } #endif cursor_refresh(term); } @@ -1656,13 +1660,17 @@ term_visual_focus_out(struct terminal *term) cursor_blink_stop_timer(term); #if 1 - for (int i = 0; i < 5; i++) - wl_subsurface_set_desync(term->window->csd.sub_surface[i]); + if (term->window->use_csd == CSD_YES) { + for (int i = 0; i < 5; i++) + wl_subsurface_set_desync(term->window->csd.sub_surface[i]); + } #endif render_csd(term); #if 1 - for (int i = 0; i < 5; i++) - wl_subsurface_set_sync(term->window->csd.sub_surface[i]); + if (term->window->use_csd == CSD_YES) { + for (int i = 0; i < 5; i++) + wl_subsurface_set_sync(term->window->csd.sub_surface[i]); + } #endif cursor_refresh(term); } diff --git a/wayland.c b/wayland.c index 1987c72a..140c3de9 100644 --- a/wayland.c +++ b/wayland.c @@ -551,12 +551,12 @@ xdg_toplevel_decoration_configure(void *data, switch (mode) { case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: LOG_DBG("using client-side decorations"); - win->use_csd = true; + win->use_csd = CSD_YES; break; case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: LOG_DBG("using server-side decorations"); - win->use_csd = false; + win->use_csd = CSD_NO; break; default: @@ -902,7 +902,7 @@ wayl_win_init(struct terminal *term) struct wl_window *win = calloc(1, sizeof(*win)); win->term = term; - win->use_csd = true; + win->use_csd = CSD_UNKNOWN; win->surface = wl_compositor_create_surface(wayl->compositor); if (win->surface == NULL) { diff --git a/wayland.h b/wayland.h index 243df207..617e8185 100644 --- a/wayland.h +++ b/wayland.h @@ -82,6 +82,7 @@ struct wl_primary { uint32_t serial; }; +#define FOOT_CSD_OUTSIDE 1 extern const int csd_border_size; extern const int csd_title_size; @@ -94,7 +95,7 @@ struct wl_window { struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration; - bool use_csd; + enum {CSD_UNKNOWN, CSD_NO, CSD_YES } use_csd; struct { struct wl_surface *surface[5];