Merge branch 'refresh-on-csd-ssd-change'

This commit is contained in:
Daniel Eklöf 2021-06-23 15:10:56 +02:00
commit a5dd71bc7b
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 43 additions and 52 deletions

View file

@ -188,6 +188,7 @@
* Window title not being updated while window is hidden * Window title not being updated while window is hidden
(https://codeberg.org/dnkl/foot/issues/591). (https://codeberg.org/dnkl/foot/issues/591).
* Crash on badly formatted URIs in e.g. OSC-8 URLs. * Crash on badly formatted URIs in e.g. OSC-8 URLs.
* Window being incorrectly resized on CSD/SSD run-time changes.
### Security ### Security

View file

@ -46,7 +46,7 @@ quirk_weston_subsurface_desync_off(struct wl_subsurface *sub)
void void
quirk_weston_csd_on(struct terminal *term) quirk_weston_csd_on(struct terminal *term)
{ {
if (term->window->use_csd != CSD_YES) if (term->window->csd_mode != CSD_YES)
return; return;
if (term->window->is_fullscreen) if (term->window->is_fullscreen)
return; return;
@ -58,7 +58,7 @@ quirk_weston_csd_on(struct terminal *term)
void void
quirk_weston_csd_off(struct terminal *term) quirk_weston_csd_off(struct terminal *term)
{ {
if (term->window->use_csd != CSD_YES) if (term->window->csd_mode != CSD_YES)
return; return;
if (term->window->is_fullscreen) if (term->window->is_fullscreen)
return; return;

View file

@ -1454,7 +1454,7 @@ struct csd_data {
static struct csd_data static struct csd_data
get_csd_data(const struct terminal *term, enum csd_surface surf_idx) get_csd_data(const struct terminal *term, enum csd_surface surf_idx)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
/* Only title bar is rendered in maximized mode */ /* Only title bar is rendered in maximized mode */
const int border_width = !term->window->is_maximized const int border_width = !term->window->is_maximized
@ -1513,7 +1513,7 @@ render_csd_part(struct terminal *term,
struct wl_surface *surf, struct buffer *buf, struct wl_surface *surf, struct buffer *buf,
int width, int height, pixman_color_t *color) int width, int height, pixman_color_t *color)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
pixman_image_t *src = pixman_image_create_solid_fill(color); pixman_image_t *src = pixman_image_create_solid_fill(color);
@ -1526,7 +1526,7 @@ render_csd_part(struct terminal *term,
static void static void
render_csd_title(struct terminal *term) render_csd_title(struct terminal *term)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
struct csd_data info = get_csd_data(term, CSD_SURF_TITLE); struct csd_data info = get_csd_data(term, CSD_SURF_TITLE);
struct wl_surface *surf = term->window->csd.surface[CSD_SURF_TITLE].surf; struct wl_surface *surf = term->window->csd.surface[CSD_SURF_TITLE].surf;
@ -1559,7 +1559,7 @@ render_csd_title(struct terminal *term)
static void static void
render_csd_border(struct terminal *term, enum csd_surface surf_idx) render_csd_border(struct terminal *term, enum csd_surface surf_idx)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
xassert(surf_idx >= CSD_SURF_LEFT && surf_idx <= CSD_SURF_BOTTOM); xassert(surf_idx >= CSD_SURF_LEFT && surf_idx <= CSD_SURF_BOTTOM);
struct csd_data info = get_csd_data(term, surf_idx); struct csd_data info = get_csd_data(term, surf_idx);
@ -1745,7 +1745,7 @@ render_csd_button_close(struct terminal *term, struct buffer *buf)
static void static void
render_csd_button(struct terminal *term, enum csd_surface surf_idx) render_csd_button(struct terminal *term, enum csd_surface surf_idx)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
xassert(surf_idx >= CSD_SURF_MINIMIZE && surf_idx <= CSD_SURF_CLOSE); xassert(surf_idx >= CSD_SURF_MINIMIZE && surf_idx <= CSD_SURF_CLOSE);
struct csd_data info = get_csd_data(term, surf_idx); struct csd_data info = get_csd_data(term, surf_idx);
@ -1827,7 +1827,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx)
static void static void
render_csd(struct terminal *term) render_csd(struct terminal *term)
{ {
xassert(term->window->use_csd == CSD_YES); xassert(term->window->csd_mode == CSD_YES);
if (term->window->is_fullscreen) if (term->window->is_fullscreen)
return; return;
@ -3019,7 +3019,7 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
term->grid = term->url_grid_snapshot; term->grid = term->url_grid_snapshot;
} }
if (csd && term->window->use_csd == CSD_YES) { if (csd && term->window->csd_mode == CSD_YES) {
quirk_weston_csd_on(term); quirk_weston_csd_on(term);
render_csd(term); render_csd(term);
quirk_weston_csd_off(term); quirk_weston_csd_off(term);
@ -3168,7 +3168,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
width = term->conf->size.width; width = term->conf->size.width;
height = term->conf->size.height; height = term->conf->size.height;
if (term->window->use_csd == CSD_YES) { if (term->window->csd_mode == CSD_YES) {
/* Take CSD title bar into account */ /* Take CSD title bar into account */
xassert(!term->window->is_fullscreen); xassert(!term->window->is_fullscreen);
height -= term->conf->csd.title_height; height -= term->conf->csd.title_height;
@ -3338,7 +3338,7 @@ damage_view:
{ {
bool title_shown = !term->window->is_fullscreen && bool title_shown = !term->window->is_fullscreen &&
term->window->use_csd == CSD_YES; term->window->csd_mode == CSD_YES;
int title_height = title_shown ? term->conf->csd.title_height : 0; int title_height = title_shown ? term->conf->csd.title_height : 0;
xdg_surface_set_window_geometry( xdg_surface_set_window_geometry(
@ -3476,7 +3476,7 @@ fdm_hook_refresh_pending_terminals(struct fdm *fdm, void *data)
term->grid = term->url_grid_snapshot; term->grid = term->url_grid_snapshot;
} }
if (csd && term->window->use_csd == CSD_YES) { if (csd && term->window->csd_mode == CSD_YES) {
quirk_weston_csd_on(term); quirk_weston_csd_on(term);
render_csd(term); render_csd(term);
quirk_weston_csd_off(term); quirk_weston_csd_off(term);
@ -3549,7 +3549,7 @@ render_refresh(struct terminal *term)
void void
render_refresh_csd(struct terminal *term) render_refresh_csd(struct terminal *term)
{ {
if (term->window->use_csd == CSD_YES) if (term->window->csd_mode == CSD_YES)
term->render.refresh.csd = true; term->render.refresh.csd = true;
} }

View file

@ -597,14 +597,6 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
*/ */
struct wl_window *win = data; struct wl_window *win = data;
if (!is_fullscreen && win->use_csd == CSD_YES && width > 0 && height > 0) {
/*
* We include the CSD title bar in our window geometry. Thus,
* the height we call render_resize() with must be adjusted,
* since it expects the size to refer to the main grid only.
*/
height -= win->term->conf->csd.title_height;
}
win->configure.is_activated = is_activated; win->configure.is_activated = is_activated;
win->configure.is_fullscreen = is_fullscreen; win->configure.is_fullscreen = is_fullscreen;
win->configure.is_maximized = is_maximized; win->configure.is_maximized = is_maximized;
@ -642,23 +634,32 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
bool wasnt_configured = !win->is_configured; bool wasnt_configured = !win->is_configured;
bool was_resizing = win->is_resizing; bool was_resizing = win->is_resizing;
bool csd_was_enabled = win->csd_mode == CSD_YES && !win->is_fullscreen;
int new_width = win->configure.width;
int new_height = win->configure.height;
win->is_configured = true; win->is_configured = true;
win->is_maximized = win->configure.is_maximized; win->is_maximized = win->configure.is_maximized;
win->is_fullscreen = win->configure.is_fullscreen;
win->is_resizing = win->configure.is_resizing; win->is_resizing = win->configure.is_resizing;
win->is_tiled_top = win->configure.is_tiled_top; win->is_tiled_top = win->configure.is_tiled_top;
win->is_tiled_bottom = win->configure.is_tiled_bottom; win->is_tiled_bottom = win->configure.is_tiled_bottom;
win->is_tiled_left = win->configure.is_tiled_left; win->is_tiled_left = win->configure.is_tiled_left;
win->is_tiled_right = win->configure.is_tiled_right; win->is_tiled_right = win->configure.is_tiled_right;
win->is_tiled = win->is_tiled_top || win->is_tiled_bottom || win->is_tiled_left || win->is_tiled_right; win->is_tiled = (win->is_tiled_top ||
win->is_tiled_bottom ||
win->is_tiled_left ||
win->is_tiled_right);
win->csd_mode = win->configure.csd_mode;
if (win->is_fullscreen != win->configure.is_fullscreen && win->use_csd == CSD_YES) { bool enable_csd = win->csd_mode == CSD_YES && !win->is_fullscreen;
if (win->configure.is_fullscreen) if (!csd_was_enabled && enable_csd)
csd_destroy(win); csd_instantiate(win);
else else if (csd_was_enabled && !enable_csd)
csd_instantiate(win); csd_destroy(win);
}
win->is_fullscreen = win->configure.is_fullscreen; if (enable_csd && new_width > 0 && new_height > 0)
new_height -= win->term->conf->csd.title_height;
xdg_surface_ack_configure(xdg_surface, serial); xdg_surface_ack_configure(xdg_surface, serial);
@ -713,10 +714,10 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
* the last, forced, resize *is* necessary. * the last, forced, resize *is* necessary.
*/ */
bool resized = was_resizing && !win->is_resizing bool resized = was_resizing && !win->is_resizing
? render_resize_force(term, win->configure.width, win->configure.height) ? render_resize_force(term, new_width, new_height)
: render_resize(term, win->configure.width, win->configure.height); : render_resize(term, new_width, new_height);
#else #else
bool resized = render_resize(term, win->configure.width, win->configure.height); bool resized = render_resize(term, new_width, new_height);
#endif #endif
if (win->configure.is_activated) if (win->configure.is_activated)
@ -752,32 +753,18 @@ xdg_toplevel_decoration_configure(void *data,
switch (mode) { switch (mode) {
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
LOG_INFO("using CSD decorations"); LOG_INFO("using CSD decorations");
win->use_csd = CSD_YES; win->configure.csd_mode = CSD_YES;
csd_instantiate(win);
break; break;
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
LOG_INFO("using SSD decorations"); LOG_INFO("using SSD decorations");
win->use_csd = CSD_NO; win->configure.csd_mode = CSD_NO;
csd_destroy(win);
break; break;
default: default:
LOG_ERR("unimplemented: unknown XDG toplevel decoration mode: %u", mode); LOG_ERR("unimplemented: unknown XDG toplevel decoration mode: %u", mode);
break; break;
} }
if (win->is_configured && win->use_csd == CSD_YES) {
struct terminal *term = win->term;
int scale = term->scale;
int width = term->width / scale;
int height = term->height / scale;
/* Take CSD title bar into account */
height -= term->conf->csd.title_height;
render_resize_force(term, width, height);
}
} }
static const struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = { static const struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = {
@ -1345,7 +1332,7 @@ wayl_win_init(struct terminal *term)
} }
win->term = term; win->term = term;
win->use_csd = CSD_UNKNOWN; win->csd_mode = CSD_UNKNOWN;
win->csd.move_timeout_fd = -1; win->csd.move_timeout_fd = -1;
win->resize_timeout_fd = -1; win->resize_timeout_fd = -1;
@ -1378,7 +1365,7 @@ wayl_win_init(struct terminal *term)
if (conf->csd.preferred == CONF_CSD_PREFER_NONE) { if (conf->csd.preferred == CONF_CSD_PREFER_NONE) {
/* User specifically do *not* want decorations */ /* User specifically do *not* want decorations */
win->use_csd = CSD_NO; win->csd_mode = CSD_NO;
LOG_INFO("window decorations disabled by user"); LOG_INFO("window decorations disabled by user");
} else if (wayl->xdg_decoration_manager != NULL) { } else if (wayl->xdg_decoration_manager != NULL) {
win->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( win->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(
@ -1397,7 +1384,7 @@ wayl_win_init(struct terminal *term)
win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, win); win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, win);
} else { } else {
/* No decoration manager - thus we *must* draw our own decorations */ /* No decoration manager - thus we *must* draw our own decorations */
win->use_csd = CSD_YES; win->csd_mode = CSD_YES;
csd_instantiate(win); csd_instantiate(win);
LOG_WARN("no decoration manager available - using CSDs unconditionally"); LOG_WARN("no decoration manager available - using CSDs unconditionally");
} }

View file

@ -384,6 +384,8 @@ struct wl_url {
struct wl_surf_subsurf surf; struct wl_surf_subsurf surf;
}; };
enum csd_mode {CSD_UNKNOWN, CSD_NO, CSD_YES};
struct wayland; struct wayland;
struct wl_window { struct wl_window {
struct terminal *term; struct terminal *term;
@ -396,7 +398,7 @@ struct wl_window {
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration; struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;
enum {CSD_UNKNOWN, CSD_NO, CSD_YES } use_csd; enum csd_mode csd_mode;
struct { struct {
struct wl_surf_subsurf surface[CSD_SURF_COUNT]; struct wl_surf_subsurf surface[CSD_SURF_COUNT];
@ -433,6 +435,7 @@ struct wl_window {
bool is_tiled_bottom:1; bool is_tiled_bottom:1;
bool is_tiled_left:1; bool is_tiled_left:1;
bool is_tiled_right:1; bool is_tiled_right:1;
enum csd_mode csd_mode;
} configure; } configure;
int resize_timeout_fd; int resize_timeout_fd;