From 902328e77dcbf90a455d9e24ebc5172c433c435f Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Tue, 3 Jun 2014 21:38:41 -0700 Subject: [PATCH] Add command to cleanup old screens after monitor disconnect. --- cmd/wmii/column.c | 4 ++-- cmd/wmii/dat.h | 4 +++- cmd/wmii/fns.h | 4 +++- cmd/wmii/frame.c | 3 ++- cmd/wmii/main.c | 26 +++++++++++++++++++------- cmd/wmii/message.c | 6 ++++++ cmd/wmii/view.c | 37 +++++++++++++++++++++++++++++++++++-- 7 files changed, 70 insertions(+), 14 deletions(-) diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c index 098e9642..25a95671 100644 --- a/cmd/wmii/column.c +++ b/cmd/wmii/column.c @@ -1,5 +1,5 @@ /* Copyright ©2004-2006 Anselm R. Garbe - * Copyright ©2006-2010 Kris Maglione + * Copyright ©2006-2014 Kris Maglione * See LICENSE file for license details. */ #include "dat.h" @@ -156,7 +156,7 @@ column_detach(Frame *f) { if(first) stack_scale(first, dy); column_arrange(a, false); - }else if(a->view->areas[a->screen]->next) + }else if(a->view->areas[a->screen]->next && !a->permanent) column_destroy(a); } diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h index 1b32f9a1..f17734f4 100644 --- a/cmd/wmii/dat.h +++ b/cmd/wmii/dat.h @@ -1,4 +1,4 @@ -/* Copyright ©2007-2010 Kris Maglione +/* Copyright ©2007-2014 Kris Maglione * See LICENSE file for license details. */ @@ -149,6 +149,7 @@ struct Area { int mode; int screen; bool max; + bool permanent; Rectangle r; Rectangle r_old; }; @@ -371,6 +372,7 @@ EXTERN long ignoreenter; EXTERN bool resizing; EXTERN int starting; EXTERN char* user; +EXTERN long nscreens_new; EXTERN Client* kludge; diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h index cc2e7e05..a0da74d6 100644 --- a/cmd/wmii/fns.h +++ b/cmd/wmii/fns.h @@ -1,4 +1,4 @@ -/* Copyright ©2007-2010 Kris Maglione +/* Copyright ©2007-2014 Kris Maglione * See LICENSE file for license details. */ @@ -207,6 +207,7 @@ void update_keys(void); /* main.c */ void init_screens(void); void spawn_command(const char*); +void wipe_screens(void); /* message.c */ char* mask(char**, int*, int*); @@ -280,6 +281,7 @@ void view_select(const char*); void view_update(View*); void view_update_all(void); void view_update_rect(View*); +void view_update_screens(View*); void view_update_urgency(View*, char*); Rectangle* view_rects(View*, uint *num, Frame *ignore); diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c index 7feaafc5..85f7f828 100644 --- a/cmd/wmii/frame.c +++ b/cmd/wmii/frame.c @@ -1,4 +1,4 @@ -/* Copyright ©2006-2010 Kris Maglione +/* Copyright ©2006-2014 Kris Maglione * See LICENSE file for license details. */ #include "dat.h" @@ -559,6 +559,7 @@ move_focus(Frame *old_f, Frame *f) { noinput = (old_f && old_f->client->noinput) || (f && f->client->noinput) || disp.hasgrab != &c_root; + if(noinput || true) { if(old_f) frame_draw(old_f); diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c index e58b8588..5ef023bc 100644 --- a/cmd/wmii/main.c +++ b/cmd/wmii/main.c @@ -1,5 +1,5 @@ /* Copyright ©2004-2006 Anselm R. Garbe - * Copyright ©2006-2010 Kris Maglione + * Copyright ©2006-2014 Kris Maglione * See LICENSE file for license details. */ #define EXTERN @@ -158,6 +158,8 @@ regerror(char *err) { fprint(2, "%s: %s\n", argv0, err); } +static bool keep_screens = true; + void init_screens(void) { static int old_n, old_nscreens; @@ -177,14 +179,14 @@ init_screens(void) { /* Reallocate screens, zero any new ones. */ rects = xinerama_screens(&n); m = nscreens; - nscreens = max(n, nscreens); + nscreens_new = keep_screens ? max(n, nscreens) : n; + + for(v=view; v; v=v->next) + view_update_screens(v); + + nscreens = nscreens_new; screens = erealloc(screens, (nscreens + 1) * sizeof *screens); screens[nscreens] = nil; - for(v=view; v; v=v->next) { - v->areas = erealloc(v->areas, nscreens * sizeof *v->areas); - v->r = erealloc(v->r, nscreens * sizeof *v->r); - v->pad = erealloc(v->pad, nscreens * sizeof *v->pad); - } /* Reallocate buffers. */ freeimage(disp.ibuf); @@ -207,9 +209,11 @@ init_screens(void) { screen->r = rects[i]; else screen->r = rectsetorigin(screen->r, scr.rect.max); + if(i >= m) for(v=view; v; v=v->next) view_init(v, i); + def.snap = Dy(screen->r) / 63; bar_init(screens[i]); } @@ -219,10 +223,18 @@ init_screens(void) { if (old_n != n || old_nscreens != nscreens) event("ScreenChange %d %d\n", n, nscreens); + old_n = n; old_nscreens = nscreens; } +void +wipe_screens(void) { + keep_screens = false; + init_screens(); + keep_screens = true; +} + static void cleanup(void) { starting = -1; diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c index 8282b574..01276054 100644 --- a/cmd/wmii/message.c +++ b/cmd/wmii/message.c @@ -62,6 +62,7 @@ enum { LUP, LURGENT, LVIEW, + LWIPESCREENS, LTILDE, }; char *symtab[] = { @@ -103,6 +104,7 @@ char *symtab[] = { "up", "urgent", "view", + "wipescreens", "~", }; @@ -690,6 +692,10 @@ message_root(void *p, IxpMsg *m) { view_select(m->pos); break; + case LWIPESCREENS: + wipe_screens(); + break; + case LQUIT: srv.running = 0; break; diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c index 5bf43c5d..780442f6 100644 --- a/cmd/wmii/view.c +++ b/cmd/wmii/view.c @@ -1,5 +1,5 @@ /* Copyright ©2004-2006 Anselm R. Garbe - * Copyright ©2006-2010 Kris Maglione + * Copyright ©2006-2014 Kris Maglione * See LICENSE file for license details. */ #include "dat.h" @@ -112,6 +112,38 @@ view_init(View *v, int iscreen) { column_new(v, nil, iscreen, 0); } +void +view_update_screens(View *v) { + Area *a; + Frame *f; + int s; + + if (v->sel->screen > (long)nscreens) + v->sel = v->floating->next; + + v->selscreen = min(v->selscreen, nscreens); + + if (nscreens_new < nscreens) { + foreach_frame(v, s, a, f) { + f->oldscreen = min(f->oldscreen, nscreens_new); + if (a->screen >= nscreens_new) { + a->permanent = true; + area_detach(f); + view_attach(v, f); + } + } + + foreach_area(v, s, a) { + if (a->screen >= nscreens_new) + area_destroy(a); + } + } + + v->areas = erealloc(v->areas, nscreens_new * sizeof *v->areas); + v->r = erealloc(v->r, nscreens_new * sizeof *v->r); + v->pad = erealloc(v->pad, nscreens_new * sizeof *v->pad); +} + void view_destroy(View *v) { View **vp; @@ -393,7 +425,8 @@ view_attach(View *v, Frame *f) { a = v->floating; } else if((ff = client_groupframe(c, v))) { - a = ff->area; + if (ff->client != c && ff->area->screen < nscreens_new) + a = ff->area; if(v->oldsel && ff->client == view_selclient(v)) a = v->oldsel; }