Handle monitor unplug
Floating widndows with "x < removed monitor's width" aren't resized (they used to disappear in negative coordinates). Actually delete monitors when they are unplugged, recalculate sgeom and give a new monitor to clients that were on the removed one with setmon() arrangefloat() funcion has been exploded to save iterations in cleanupmon(). Also if a monitor that supports auto suspension is turned off, dwl will count it as unplugged (it will become unreachable and all clients will be moved to the leftmost monitor). However, if at least one monitor isn't plugged in, dwl will still crash the same as before. Unlike sway, when the output configuration is changed and restored, (unplug + plug the same monitor for example) previous application positions aren't kept. This is due to the fact that on sway every workspace is unique among all monitors.
This commit is contained in:
parent
537ad7e3fd
commit
bece225934
1 changed files with 25 additions and 16 deletions
41
dwl.c
41
dwl.c
|
@ -195,7 +195,6 @@ static void applyexclusive(struct wlr_box *usable_area, uint32_t anchor,
|
||||||
int32_t margin_bottom, int32_t margin_left);
|
int32_t margin_bottom, int32_t margin_left);
|
||||||
static void applyrules(Client *c);
|
static void applyrules(Client *c);
|
||||||
static void arrange(Monitor *m);
|
static void arrange(Monitor *m);
|
||||||
static void arrangefloat(Monitor *m, int sign);
|
|
||||||
static void arrangelayer(Monitor *m, struct wl_list *list,
|
static void arrangelayer(Monitor *m, struct wl_list *list,
|
||||||
struct wlr_box *usable_area, bool exclusive);
|
struct wlr_box *usable_area, bool exclusive);
|
||||||
static void arrangelayers(Monitor *m);
|
static void arrangelayers(Monitor *m);
|
||||||
|
@ -470,17 +469,6 @@ arrange(Monitor *m)
|
||||||
/* XXX recheck pointer focus here... or in resize()? */
|
/* XXX recheck pointer focus here... or in resize()? */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
arrangefloat(Monitor *m, int sign)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
|
||||||
if (c->isfloating)
|
|
||||||
resize(c, c->geom.x + m->w.width * sign, c->geom.y,
|
|
||||||
c->geom.width, c->geom.height, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, bool exclusive)
|
arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, bool exclusive)
|
||||||
{
|
{
|
||||||
|
@ -699,13 +687,29 @@ void
|
||||||
cleanupmon(struct wl_listener *listener, void *data)
|
cleanupmon(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct wlr_output *wlr_output = data;
|
struct wlr_output *wlr_output = data;
|
||||||
Monitor *m = wlr_output->data;
|
Monitor *m = wlr_output->data, *newmon;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
wl_list_remove(&m->destroy.link);
|
wl_list_remove(&m->destroy.link);
|
||||||
free(m);
|
wl_list_remove(&m->frame.link);
|
||||||
|
wl_list_remove(&m->link);
|
||||||
|
wlr_output_layout_remove(output_layout, m->wlr_output);
|
||||||
|
|
||||||
|
sgeom = *wlr_output_layout_get_box(output_layout, NULL);
|
||||||
updatemons();
|
updatemons();
|
||||||
arrangefloat(m, -1);
|
|
||||||
|
wl_list_for_each(newmon, &mons, link) {
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->isfloating && c->geom.x > m->m.width) {
|
||||||
|
resize(c, c->geom.x - m->w.width, c->geom.y,
|
||||||
|
c->geom.width, c->geom.height, 0);
|
||||||
|
}
|
||||||
|
if (c->mon == m)
|
||||||
|
setmon(c, newmon, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -836,7 +840,12 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
updatemons();
|
updatemons();
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
/* the first monitor in the list is the most recently added */
|
/* the first monitor in the list is the most recently added */
|
||||||
arrangefloat(m, 1);
|
Client *c;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->isfloating)
|
||||||
|
resize(c, c->geom.x + m->w.width, c->geom.y,
|
||||||
|
c->geom.width, c->geom.height, 0);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue