mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
wayland: instantiate sub-surfaces on-demand
While most compositors handle instantiated but not-yet-mapped sub-surfaces correctly, e.g. kwin does not. For example, it will incorrectly offset the main surface both horizontally and vertically with a couple of pixels, leaving two transparent areas at the top and left, between the SSDs and the main surface. Note that a workaround is to position the sub-surfaces inside the main surface while they're unmapped. However, since the surfaces may be larger than the main surface (the CSDs, for examples, always are), this doesn't quite work since kwin, at least, resizes the window to include the sub-surfaces, even when unmapped. So, instead we instantiate all sub-surfaces on demand, when we know where to position them, and when they should be mapped.
This commit is contained in:
parent
f960e7aff7
commit
ea97a0dc87
2 changed files with 71 additions and 32 deletions
23
search.c
23
search.c
|
|
@ -40,8 +40,14 @@ search_ensure_size(struct terminal *term, size_t wanted_size)
|
|||
static void
|
||||
search_cancel_keep_selection(struct terminal *term)
|
||||
{
|
||||
wl_surface_attach(term->window->search_surface, NULL, 0, 0);
|
||||
wl_surface_commit(term->window->search_surface);
|
||||
struct wl_window *win = term->window;
|
||||
if (win->search_sub_surface != NULL)
|
||||
wl_subsurface_destroy(win->search_sub_surface);
|
||||
if (win->search_surface != NULL)
|
||||
wl_surface_destroy(win->search_surface);
|
||||
|
||||
win->search_surface = NULL;
|
||||
win->search_sub_surface = NULL;
|
||||
|
||||
free(term->search.buf);
|
||||
term->search.buf = NULL;
|
||||
|
|
@ -65,6 +71,19 @@ search_begin(struct terminal *term)
|
|||
search_cancel_keep_selection(term);
|
||||
selection_cancel(term);
|
||||
|
||||
/* On-demand instantiate wayland surface */
|
||||
struct wl_window *win = term->window;
|
||||
struct wayland *wayl = term->wl;
|
||||
win->search_surface = wl_compositor_create_surface(wayl->compositor);
|
||||
win->search_sub_surface = wl_subcompositor_get_subsurface(
|
||||
wayl->sub_compositor, win->search_surface, win->surface);
|
||||
wl_subsurface_set_desync(win->search_sub_surface);
|
||||
|
||||
struct wl_region *region = wl_compositor_create_region(term->wl->compositor);
|
||||
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
|
||||
wl_surface_set_opaque_region(win->search_surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
term->search.original_view = term->grid->view;
|
||||
term->search.view_followed_offset = term->grid->view == term->grid->offset;
|
||||
term->is_searching = true;
|
||||
|
|
|
|||
80
wayland.c
80
wayland.c
|
|
@ -29,6 +29,7 @@
|
|||
#include "render.h"
|
||||
#include "selection.h"
|
||||
|
||||
#define ALEN(v) (sizeof(v) / sizeof(v[0]))
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
|
|
@ -541,6 +542,39 @@ static const struct xdg_surface_listener xdg_surface_listener = {
|
|||
.configure = &xdg_surface_configure,
|
||||
};
|
||||
|
||||
static void
|
||||
csd_instantiate(struct wl_window *win)
|
||||
{
|
||||
struct wayland *wayl = win->term->wl;
|
||||
assert(wayl != NULL);
|
||||
|
||||
for (size_t i = 0; i < ALEN(win->csd.surface); i++) {
|
||||
assert(win->csd.surface[i] == NULL);
|
||||
assert(win->csd.sub_surface[i] == NULL);
|
||||
|
||||
win->csd.surface[i] = wl_compositor_create_surface(wayl->compositor);
|
||||
win->csd.sub_surface[i] = wl_subcompositor_get_subsurface(
|
||||
wayl->sub_compositor, win->csd.surface[i], win->surface);
|
||||
|
||||
wl_subsurface_set_sync(win->csd.sub_surface[i]);
|
||||
wl_surface_commit(win->csd.surface[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
csd_destroy(struct wl_window *win)
|
||||
{
|
||||
for (size_t i = 0; i < ALEN(win->csd.surface); i++) {
|
||||
if (win->csd.sub_surface[i] != NULL)
|
||||
wl_subsurface_destroy(win->csd.sub_surface[i]);
|
||||
if (win->csd.surface[i] != NULL)
|
||||
wl_surface_destroy(win->csd.surface[i]);
|
||||
|
||||
win->csd.surface[i] = NULL;
|
||||
win->csd.sub_surface[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_toplevel_decoration_configure(void *data,
|
||||
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
|
||||
|
|
@ -552,11 +586,13 @@ xdg_toplevel_decoration_configure(void *data,
|
|||
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE:
|
||||
LOG_DBG("using client-side decorations");
|
||||
win->use_csd = CSD_YES;
|
||||
csd_instantiate(win);
|
||||
break;
|
||||
|
||||
case ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE:
|
||||
LOG_DBG("using server-side decorations");
|
||||
win->use_csd = CSD_NO;
|
||||
csd_destroy(win);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -941,26 +977,12 @@ wayl_win_init(struct terminal *term)
|
|||
#endif
|
||||
zxdg_toplevel_decoration_v1_add_listener(
|
||||
win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, win);
|
||||
} else {
|
||||
/* No decoration manager - thus we *must* draw our own decorations */
|
||||
win->use_csd = CSD_YES;
|
||||
csd_instantiate(win);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
win->csd.surface[i] = wl_compositor_create_surface(wayl->compositor);
|
||||
win->csd.sub_surface[i] = wl_subcompositor_get_subsurface(
|
||||
wayl->sub_compositor, win->csd.surface[i], win->surface);
|
||||
wl_subsurface_set_sync(win->csd.sub_surface[i]);
|
||||
}
|
||||
|
||||
/* Scrollback search box */
|
||||
win->search_surface = wl_compositor_create_surface(wayl->compositor);
|
||||
win->search_sub_surface = wl_subcompositor_get_subsurface(
|
||||
wayl->sub_compositor, win->search_surface, win->surface);
|
||||
wl_subsurface_set_desync(win->search_sub_surface);
|
||||
|
||||
struct wl_region *region = wl_compositor_create_region(term->wl->compositor);
|
||||
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
|
||||
wl_surface_set_opaque_region(win->search_surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
wl_surface_commit(win->surface);
|
||||
return win;
|
||||
|
||||
|
|
@ -986,13 +1008,17 @@ wayl_win_destroy(struct wl_window *win)
|
|||
*/
|
||||
|
||||
/* Scrollback search */
|
||||
wl_surface_attach(win->search_surface, NULL, 0, 0);
|
||||
wl_surface_commit(win->search_surface);
|
||||
if (win->search_surface != NULL) {
|
||||
wl_surface_attach(win->search_surface, NULL, 0, 0);
|
||||
wl_surface_commit(win->search_surface);
|
||||
}
|
||||
|
||||
/* CSD */
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
wl_surface_attach(win->csd.surface[i], NULL, 0, 0);
|
||||
wl_surface_commit(win->csd.surface[i]);
|
||||
for (size_t i = 0; i < ALEN(win->csd.surface); i++) {
|
||||
if (win->csd.surface[i] != NULL) {
|
||||
wl_surface_attach(win->csd.surface[i], NULL, 0, 0);
|
||||
wl_surface_commit(win->csd.surface[i]);
|
||||
}
|
||||
}
|
||||
|
||||
wayl_roundtrip(win->term->wl);
|
||||
|
|
@ -1004,13 +1030,7 @@ wayl_win_destroy(struct wl_window *win)
|
|||
|
||||
tll_free(win->on_outputs);
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
if (win->csd.sub_surface[i] != NULL)
|
||||
wl_subsurface_destroy(win->csd.sub_surface[i]);
|
||||
if (win->csd.surface[i] != NULL)
|
||||
wl_surface_destroy(win->csd.surface[i]);
|
||||
}
|
||||
|
||||
csd_destroy(win);
|
||||
if (win->search_sub_surface != NULL)
|
||||
wl_subsurface_destroy(win->search_sub_surface);
|
||||
if (win->search_surface != NULL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue