mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
wayland: handle outputs disappearing
That is, deal with monitors being unplugged. At least on Sway 1.4, surfaces are not unmapped before the output is removed. Thus, in addition to free:ing the monitor resources, we also need to update all terminals that are mapped on this output - remove the output from their "mapped on" list.
This commit is contained in:
parent
37871aad84
commit
9cfe720000
2 changed files with 51 additions and 11 deletions
61
wayland.c
61
wayland.c
|
|
@ -533,7 +533,7 @@ static void
|
|||
handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
LOG_DBG("global: %s, version=%u", interface, version);
|
||||
LOG_DBG("global: 0x%08x, interface=%s, version=%u", name, interface, version);
|
||||
struct wayland *wayl = data;
|
||||
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
|
|
@ -614,7 +614,8 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
wayl->registry, name, &wl_output_interface, required);
|
||||
|
||||
tll_push_back(
|
||||
wayl->monitors, ((struct monitor){.wayl = wayl, .output = output}));
|
||||
wayl->monitors,
|
||||
((struct monitor){.wayl = wayl, .output = output, .wl_name = name}));
|
||||
|
||||
struct monitor *mon = &tll_back(wayl->monitors);
|
||||
wl_output_add_listener(output, &output_listener, mon);
|
||||
|
|
@ -660,11 +661,55 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
monitor_destroy(struct monitor *mon)
|
||||
{
|
||||
free(mon->name);
|
||||
if (mon->xdg != NULL)
|
||||
zxdg_output_v1_destroy(mon->xdg);
|
||||
if (mon->output != NULL)
|
||||
wl_output_destroy(mon->output);
|
||||
free(mon->make);
|
||||
free(mon->model);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
||||
{
|
||||
LOG_WARN("global removed: %u", name);
|
||||
assert(false);
|
||||
LOG_DBG("global removed: %u", name);
|
||||
|
||||
struct wayland *wayl = data;
|
||||
|
||||
/* For now, we only support removal of outputs */
|
||||
tll_foreach(wayl->monitors, it) {
|
||||
if (it->item.wl_name != name)
|
||||
continue;
|
||||
|
||||
LOG_INFO("monitor unplugged: %s", it->item.name);
|
||||
|
||||
/*
|
||||
* Update all terminals that are mapped here. On Sway 1.4,
|
||||
* surfaces are *not* unmapped before the output is removed
|
||||
*/
|
||||
|
||||
tll_foreach(wayl->terms, t) {
|
||||
tll_foreach(t->item->window->on_outputs, o) {
|
||||
if (o->item != &it->item)
|
||||
continue;
|
||||
|
||||
/* Remove terminal from this output */
|
||||
tll_remove(t->item->window->on_outputs, o);
|
||||
update_term_for_output_change(t->item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
monitor_destroy(&it->item);
|
||||
tll_remove(wayl->monitors, it);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_WARN("unknown global removed: 0x%08x", name);
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
|
|
@ -901,13 +946,7 @@ wayl_destroy(struct wayland *wayl)
|
|||
fdm_del(wayl->fdm, wayl->kbd.repeat.fd);
|
||||
|
||||
tll_foreach(wayl->monitors, it) {
|
||||
free(it->item.name);
|
||||
if (it->item.xdg != NULL)
|
||||
zxdg_output_v1_destroy(it->item.xdg);
|
||||
if (it->item.output != NULL)
|
||||
wl_output_destroy(it->item.output);
|
||||
free(it->item.make);
|
||||
free(it->item.model);
|
||||
monitor_destroy(&it->item);
|
||||
tll_remove(wayl->monitors, it);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct monitor {
|
|||
struct wl_output *output;
|
||||
struct zxdg_output_v1 *xdg;
|
||||
char *name;
|
||||
uint32_t wl_name;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue