diff options
author | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-03-10 00:49:44 -0500 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-03-10 00:57:22 -0500 |
commit | cd874b642ce9f86d63583b6a2d012d5f445895da (patch) | |
tree | 8b3a9cf45a99185fb5ee3ab1f39e47aa8ff81878 /src/resize.c | |
parent | 9d3938870c639fad97ea9b6cbb23b46cb049c801 (diff) | |
download | screen-cd874b642ce9f86d63583b6a2d012d5f445895da.tar.gz |
Make layer-resizing a bit more robust and readable
Instead of killing all overlays when resizing, just kill the ones
that cannot be resized, and the resized the rest. This fixes a bug
where the window-list (or a group-window) is aborted when
layer-size changes (because window-size changed, or
caption/hardstatus etc. was toggled). This also makes the code
robust. So if you are looking at a window/display list, and the
window-size is changed, the list won't go away.
Diffstat (limited to 'src/resize.c')
-rw-r--r-- | src/resize.c | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/src/resize.c b/src/resize.c index 10dfd8e..7782c2b 100644 --- a/src/resize.c +++ b/src/resize.c @@ -323,6 +323,34 @@ kaablamm() Msg(0, "Aborted because of window size change."); } +/* Kills non-resizable layers. */ +#define RESIZE_OR_KILL_LAYERS(l, wi, he) do \ + { \ + struct layer *_last = NULL, *_iter; \ + flayer = (l); \ + while (flayer->l_next) \ + { \ + if (LayResize(wi, he) == 0) \ + { \ + _last = flayer; \ + flayer = flayer->l_next; \ + } \ + else \ + { \ + struct canvas *_cv; \ + for (_cv = flayer->l_cvlist; _cv; _cv = _cv->c_lnext) \ + _cv->c_display->d_kaablamm = 1; \ + ExitOverlayPage(); \ + if (_last) \ + _last->l_next = flayer; \ + } \ + } \ + /* We assume that the bottom-most layer, i.e. when flayer->l_next == 0, \ + * is always resizable. Currently, WinLf and BlankLf can be the bottom-most layers. \ + */ \ + LayResize(wi, he); \ + } while (0) + void ResizeLayer(l, wi, he, norefdisp) struct layer *l; @@ -338,52 +366,40 @@ struct display *norefdisp; return; p = Layer2Window(l); + /* If 'flayer' and 'l' are for the same window, then we will not + * restore 'flayer'. */ if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p)) while (oldflayer->l_next) oldflayer = oldflayer->l_next; - + + flayer = l; + if (p) { + /* It's a window layer. Kill the overlays on it in all displays. */ for (d = displays; d; d = d->d_next) for (cv = d->d_cvlist; cv; cv = cv->c_next) { if (p == Layer2Window(cv->c_layer)) { - flayer = cv->c_layer; - if (flayer->l_next) - d->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* Canvas 'cv' on display 'd' shows this window. Remove any non-resizable + * layers over it. */ + RESIZE_OR_KILL_LAYERS(cv->c_layer, wi, he); } } - l = p->w_savelayer; - } - flayer = l; - if (p == 0 && flayer->l_next && flayer->l_next->l_next == 0 && LayResize(wi, he) == 0) - { - flayer = flayer->l_next; - LayResize(wi, he); - flayer = l; } else { - if (flayer->l_next) - for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) - cv->c_display->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* It's a Blank layer. Just kill the non-resizable overlays over it. */ + RESIZE_OR_KILL_LAYERS(flayer, wi, he); } - if (p) - flayer = &p->w_layer; - LayResize(wi, he); - /* now everybody is on flayer, redisplay */ - l = flayer; + for (display = displays; display; display = display->d_next) { if (display == norefdisp) continue; for (cv = D_cvlist; cv; cv = cv->c_next) - if (cv->c_layer == l) + if (Layer2Window(cv->c_layer) == p) { CV_CALL(cv, LayRedisplayLine(-1, -1, -1, 0)); RefreshArea(cv->c_xs, cv->c_ys, cv->c_xe, cv->c_ye, 0); @@ -394,11 +410,14 @@ struct display *norefdisp; D_kaablamm = 0; } } - flayer = oldflayer; + + /* If we started resizing a non-flayer layer, then restore the flayer. + * Otherwise, flayer should already be updated to the topmost foreground layer. */ + if (Layer2Window(flayer) != Layer2Window(oldflayer)) + flayer = oldflayer; display = olddisplay; } - static void FreeMline(ml) struct mline *ml; |