mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-03 07:15:29 -04:00
Merge branch 'cleanup-wayland-window-callbacks'
This commit is contained in:
commit
f2a745cfdb
5 changed files with 59 additions and 84 deletions
5
render.c
5
render.c
|
|
@ -960,7 +960,7 @@ reflow(struct row **new_grid, int new_cols, int new_rows,
|
||||||
|
|
||||||
/* Move to terminal.c? */
|
/* Move to terminal.c? */
|
||||||
void
|
void
|
||||||
render_resize(struct terminal *term, int width, int height, bool refresh)
|
render_resize(struct terminal *term, int width, int height)
|
||||||
{
|
{
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1086,8 +1086,7 @@ render_resize(struct terminal *term, int width, int height, bool refresh)
|
||||||
term->render.last_cursor.cell = NULL;
|
term->render.last_cursor.cell = NULL;
|
||||||
|
|
||||||
term_damage_view(term);
|
term_damage_view(term);
|
||||||
if (refresh)
|
render_refresh(term);
|
||||||
render_refresh(term);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
2
render.h
2
render.h
|
|
@ -6,7 +6,7 @@ struct font *attrs_to_font(
|
||||||
const struct terminal *term, const struct attributes *attrs);
|
const struct terminal *term, const struct attributes *attrs);
|
||||||
|
|
||||||
void grid_render(struct terminal *term);
|
void grid_render(struct terminal *term);
|
||||||
void render_resize(struct terminal *term, int width, int height, bool refresh);
|
void render_resize(struct terminal *term, int width, int height);
|
||||||
void render_set_title(struct terminal *term, const char *title);
|
void render_set_title(struct terminal *term, const char *title);
|
||||||
void render_refresh(struct terminal *term);
|
void render_refresh(struct terminal *term);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -654,7 +654,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Initialize the Wayland window backend */
|
/* Initialize the Wayland window backend */
|
||||||
if ((term->window = wayl_win_init(wayl)) == NULL)
|
if ((term->window = wayl_win_init(term)) == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Let the Wayland backend know we exist */
|
/* Let the Wayland backend know we exist */
|
||||||
|
|
@ -679,7 +679,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
/* Don't go below a single cell */
|
/* Don't go below a single cell */
|
||||||
width = max(width, term->cell_width);
|
width = max(width, term->cell_width);
|
||||||
height = max(height, term->cell_height);
|
height = max(height, term->cell_height);
|
||||||
render_resize(term, width, height, true);
|
render_resize(term, width, height);
|
||||||
|
|
||||||
return term;
|
return term;
|
||||||
|
|
||||||
|
|
|
||||||
118
wayland.c
118
wayland.c
|
|
@ -144,7 +144,7 @@ output_scale(void *data, struct wl_output *wl_output, int32_t factor)
|
||||||
struct terminal *term = it->item;
|
struct terminal *term = it->item;
|
||||||
int scale = term->scale;
|
int scale = term->scale;
|
||||||
|
|
||||||
render_resize(term, term->width / scale, term->height / scale, true);
|
render_resize(term, term->width / scale, term->height / scale);
|
||||||
wayl_reload_cursor_theme(mon->wayl, term);
|
wayl_reload_cursor_theme(mon->wayl, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -361,18 +361,18 @@ static void
|
||||||
surface_enter(void *data, struct wl_surface *wl_surface,
|
surface_enter(void *data, struct wl_surface *wl_surface,
|
||||||
struct wl_output *wl_output)
|
struct wl_output *wl_output)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wl_window *win = data;
|
||||||
struct terminal *term = wayl_terminal_from_surface(wayl, wl_surface);
|
struct terminal *term = win->term;
|
||||||
|
|
||||||
tll_foreach(wayl->monitors, it) {
|
tll_foreach(term->wl->monitors, it) {
|
||||||
if (it->item.output == wl_output) {
|
if (it->item.output == wl_output) {
|
||||||
LOG_DBG("mapped on %s", it->item.name);
|
LOG_DBG("mapped on %s", it->item.name);
|
||||||
tll_push_back(term->window->on_outputs, &it->item);
|
tll_push_back(term->window->on_outputs, &it->item);
|
||||||
|
|
||||||
/* Resize, since scale-to-use may have changed */
|
/* Resize, since scale-to-use may have changed */
|
||||||
int scale = term->scale;
|
int scale = term->scale;
|
||||||
render_resize(term, term->width / scale, term->height / scale, true);
|
render_resize(term, term->width / scale, term->height / scale);
|
||||||
wayl_reload_cursor_theme(wayl, term);
|
wayl_reload_cursor_theme(term->wl, term);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -384,8 +384,8 @@ static void
|
||||||
surface_leave(void *data, struct wl_surface *wl_surface,
|
surface_leave(void *data, struct wl_surface *wl_surface,
|
||||||
struct wl_output *wl_output)
|
struct wl_output *wl_output)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wl_window *win = data;
|
||||||
struct terminal *term = wayl_terminal_from_surface(wayl, wl_surface);
|
struct terminal *term = win->term;
|
||||||
|
|
||||||
tll_foreach(term->window->on_outputs, it) {
|
tll_foreach(term->window->on_outputs, it) {
|
||||||
if (it->item->output != wl_output)
|
if (it->item->output != wl_output)
|
||||||
|
|
@ -396,8 +396,8 @@ surface_leave(void *data, struct wl_surface *wl_surface,
|
||||||
|
|
||||||
/* Resize, since scale-to-use may have changed */
|
/* Resize, since scale-to-use may have changed */
|
||||||
int scale = term->scale;
|
int scale = term->scale;
|
||||||
render_resize(term, term->width / scale, term->height / scale, true);
|
render_resize(term, term->width / scale, term->height / scale);
|
||||||
wayl_reload_cursor_theme(wayl, term);
|
wayl_reload_cursor_theme(term->wl, term);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,7 +413,8 @@ static void
|
||||||
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||||
int32_t width, int32_t height, struct wl_array *states)
|
int32_t width, int32_t height, struct wl_array *states)
|
||||||
{
|
{
|
||||||
bool is_focused = false;
|
bool is_activated = false;
|
||||||
|
|
||||||
#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
|
#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
|
||||||
char state_str[2048];
|
char state_str[2048];
|
||||||
int state_chars = 0;
|
int state_chars = 0;
|
||||||
|
|
@ -434,7 +435,7 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||||
wl_array_for_each(state, states) {
|
wl_array_for_each(state, states) {
|
||||||
switch (*state) {
|
switch (*state) {
|
||||||
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
case XDG_TOPLEVEL_STATE_ACTIVATED:
|
||||||
is_focused = true;
|
is_activated = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
case XDG_TOPLEVEL_STATE_MAXIMIZED:
|
||||||
|
|
@ -467,22 +468,24 @@ xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
|
||||||
width, height, state_str);
|
width, height, state_str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct wayland *wayl = data;
|
/*
|
||||||
struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel);
|
* Changes done here are ignored until the configure event has
|
||||||
|
* been ack:ed in xdg_surface_configure().
|
||||||
if (is_focused)
|
*
|
||||||
term_visual_focus_in(term);
|
* So, just store the config data and apply it later, in
|
||||||
else
|
* xdg_surface_configure() after we've ack:ed the event.
|
||||||
term_visual_focus_out(term);
|
*/
|
||||||
|
struct wl_window *win = data;
|
||||||
render_resize(term, width, height, false);
|
win->configure.is_activated = is_activated;
|
||||||
|
win->configure.width = width;
|
||||||
|
win->configure.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
|
xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
|
||||||
{
|
{
|
||||||
struct wayland *wayl = data;
|
struct wl_window *win = data;
|
||||||
struct terminal *term = wayl_terminal_from_xdg_toplevel(wayl, xdg_toplevel);
|
struct terminal *term = win->term;
|
||||||
LOG_DBG("xdg-toplevel: close");
|
LOG_DBG("xdg-toplevel: close");
|
||||||
term_shutdown(term);
|
term_shutdown(term);
|
||||||
}
|
}
|
||||||
|
|
@ -499,20 +502,15 @@ xdg_surface_configure(void *data, struct xdg_surface *xdg_surface,
|
||||||
LOG_DBG("xdg-surface: configure");
|
LOG_DBG("xdg-surface: configure");
|
||||||
xdg_surface_ack_configure(xdg_surface, serial);
|
xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
|
|
||||||
/*
|
struct wl_window *win = data;
|
||||||
* Changes done in e.g. xdg-toplevel-configure will be ignored
|
struct terminal *term = win->term;
|
||||||
* since the 'configure' event hasn't been ack:ed yet.
|
|
||||||
*
|
if (win->configure.is_activated)
|
||||||
* Unfortunately, *this* function is called *last*, meaning we
|
term_visual_focus_in(term);
|
||||||
* have no way of acking the configure before we resize the
|
else
|
||||||
* terminal in xdg-toplevel-configure.
|
term_visual_focus_out(term);
|
||||||
*
|
|
||||||
* So, refresh here, to ensure changes take effect as soon as possible.
|
render_resize(term, win->configure.width, win->configure.height);
|
||||||
*/
|
|
||||||
struct wayland *wayl = data;
|
|
||||||
struct terminal *term = wayl_terminal_from_xdg_surface(wayl, xdg_surface);
|
|
||||||
if (term->width > 0 && term->height > 0)
|
|
||||||
render_refresh(term);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xdg_surface_listener xdg_surface_listener = {
|
static const struct xdg_surface_listener xdg_surface_listener = {
|
||||||
|
|
@ -825,10 +823,12 @@ wayl_destroy(struct wayland *wayl)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_window *
|
struct wl_window *
|
||||||
wayl_win_init(struct wayland *wayl)
|
wayl_win_init(struct terminal *term)
|
||||||
{
|
{
|
||||||
|
struct wayland *wayl = term->wl;
|
||||||
|
|
||||||
struct wl_window *win = calloc(1, sizeof(*win));
|
struct wl_window *win = calloc(1, sizeof(*win));
|
||||||
win->wayl = wayl;
|
win->term = term;
|
||||||
|
|
||||||
win->surface = wl_compositor_create_surface(wayl->compositor);
|
win->surface = wl_compositor_create_surface(wayl->compositor);
|
||||||
if (win->surface == NULL) {
|
if (win->surface == NULL) {
|
||||||
|
|
@ -836,13 +836,13 @@ wayl_win_init(struct wayland *wayl)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_add_listener(win->surface, &surface_listener, wayl);
|
wl_surface_add_listener(win->surface, &surface_listener, win);
|
||||||
|
|
||||||
win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface);
|
win->xdg_surface = xdg_wm_base_get_xdg_surface(wayl->shell, win->surface);
|
||||||
xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, wayl);
|
xdg_surface_add_listener(win->xdg_surface, &xdg_surface_listener, win);
|
||||||
|
|
||||||
win->xdg_toplevel = xdg_surface_get_toplevel(win->xdg_surface);
|
win->xdg_toplevel = xdg_surface_get_toplevel(win->xdg_surface);
|
||||||
xdg_toplevel_add_listener(win->xdg_toplevel, &xdg_toplevel_listener, wayl);
|
xdg_toplevel_add_listener(win->xdg_toplevel, &xdg_toplevel_listener, win);
|
||||||
|
|
||||||
xdg_toplevel_set_app_id(win->xdg_toplevel, "foot");
|
xdg_toplevel_set_app_id(win->xdg_toplevel, "foot");
|
||||||
|
|
||||||
|
|
@ -852,7 +852,7 @@ wayl_win_init(struct wayland *wayl)
|
||||||
zxdg_toplevel_decoration_v1_set_mode(
|
zxdg_toplevel_decoration_v1_set_mode(
|
||||||
win->xdg_toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
win->xdg_toplevel_decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
zxdg_toplevel_decoration_v1_add_listener(
|
zxdg_toplevel_decoration_v1_add_listener(
|
||||||
win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, wayl);
|
win->xdg_toplevel_decoration, &xdg_toplevel_decoration_listener, win);
|
||||||
|
|
||||||
/* Scrollback search box */
|
/* Scrollback search box */
|
||||||
win->search_surface = wl_compositor_create_surface(wayl->compositor);
|
win->search_surface = wl_compositor_create_surface(wayl->compositor);
|
||||||
|
|
@ -887,12 +887,12 @@ wayl_win_destroy(struct wl_window *win)
|
||||||
/* Scrollback search */
|
/* Scrollback search */
|
||||||
wl_surface_attach(win->search_surface, NULL, 0, 0);
|
wl_surface_attach(win->search_surface, NULL, 0, 0);
|
||||||
wl_surface_commit(win->search_surface);
|
wl_surface_commit(win->search_surface);
|
||||||
wl_display_roundtrip(win->wayl->display);
|
wl_display_roundtrip(win->term->wl->display);
|
||||||
|
|
||||||
/* Main window */
|
/* Main window */
|
||||||
wl_surface_attach(win->surface, NULL, 0, 0);
|
wl_surface_attach(win->surface, NULL, 0, 0);
|
||||||
wl_surface_commit(win->surface);
|
wl_surface_commit(win->surface);
|
||||||
wl_display_roundtrip(win->wayl->display);
|
wl_display_roundtrip(win->term->wl->display);
|
||||||
|
|
||||||
tll_free(win->on_outputs);
|
tll_free(win->on_outputs);
|
||||||
if (win->search_sub_surface != NULL)
|
if (win->search_sub_surface != NULL)
|
||||||
|
|
@ -910,7 +910,7 @@ wayl_win_destroy(struct wl_window *win)
|
||||||
if (win->surface != NULL)
|
if (win->surface != NULL)
|
||||||
wl_surface_destroy(win->surface);
|
wl_surface_destroy(win->surface);
|
||||||
|
|
||||||
wl_display_roundtrip(win->wayl->display);
|
wl_display_roundtrip(win->term->wl->display);
|
||||||
|
|
||||||
free(win);
|
free(win);
|
||||||
}
|
}
|
||||||
|
|
@ -1003,29 +1003,3 @@ wayl_terminal_from_surface(struct wayland *wayl, struct wl_surface *surface)
|
||||||
LOG_WARN("surface %p doesn't map to a terminal", surface);
|
LOG_WARN("surface %p doesn't map to a terminal", surface);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct terminal *
|
|
||||||
wayl_terminal_from_xdg_surface(struct wayland *wayl,
|
|
||||||
struct xdg_surface *surface)
|
|
||||||
{
|
|
||||||
tll_foreach(wayl->terms, it) {
|
|
||||||
if (it->item->window->xdg_surface == surface)
|
|
||||||
return it->item;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct terminal *
|
|
||||||
wayl_terminal_from_xdg_toplevel(struct wayland *wayl,
|
|
||||||
struct xdg_toplevel *toplevel)
|
|
||||||
{
|
|
||||||
tll_foreach(wayl->terms, it) {
|
|
||||||
if (it->item->window->xdg_toplevel == toplevel)
|
|
||||||
return it->item;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
14
wayland.h
14
wayland.h
|
|
@ -84,7 +84,7 @@ struct wl_primary {
|
||||||
|
|
||||||
struct wayland;
|
struct wayland;
|
||||||
struct wl_window {
|
struct wl_window {
|
||||||
struct wayland *wayl;
|
struct terminal *term;
|
||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
struct xdg_surface *xdg_surface;
|
struct xdg_surface *xdg_surface;
|
||||||
struct xdg_toplevel *xdg_toplevel;
|
struct xdg_toplevel *xdg_toplevel;
|
||||||
|
|
@ -98,6 +98,12 @@ struct wl_window {
|
||||||
struct wl_callback *frame_callback;
|
struct wl_callback *frame_callback;
|
||||||
|
|
||||||
tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */
|
tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool is_activated;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} configure;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config;
|
struct config;
|
||||||
|
|
@ -173,13 +179,9 @@ void wayl_destroy(struct wayland *wayl);
|
||||||
|
|
||||||
struct terminal *wayl_terminal_from_surface(
|
struct terminal *wayl_terminal_from_surface(
|
||||||
struct wayland *wayl, struct wl_surface *surface);
|
struct wayland *wayl, struct wl_surface *surface);
|
||||||
struct terminal *wayl_terminal_from_xdg_surface(
|
|
||||||
struct wayland *wayl, struct xdg_surface *surface);
|
|
||||||
struct terminal *wayl_terminal_from_xdg_toplevel(
|
|
||||||
struct wayland *wayl, struct xdg_toplevel *toplevel);
|
|
||||||
|
|
||||||
/* TODO: pass something other than 'term'? Need scale... */
|
/* TODO: pass something other than 'term'? Need scale... */
|
||||||
bool wayl_cursor_set(struct wayland *wayl, const struct terminal *term);
|
bool wayl_cursor_set(struct wayland *wayl, const struct terminal *term);
|
||||||
|
|
||||||
struct wl_window *wayl_win_init(struct wayland *wayl);
|
struct wl_window *wayl_win_init(struct terminal *term);
|
||||||
void wayl_win_destroy(struct wl_window *win);
|
void wayl_win_destroy(struct wl_window *win);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue