summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-03-10 00:49:44 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-03-10 00:57:22 -0500
commitcd874b642ce9f86d63583b6a2d012d5f445895da (patch)
tree8b3a9cf45a99185fb5ee3ab1f39e47aa8ff81878
parent9d3938870c639fad97ea9b6cbb23b46cb049c801 (diff)
downloadscreen-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.
-rw-r--r--src/list_generic.c27
-rw-r--r--src/resize.c73
2 files changed, 67 insertions, 33 deletions
diff --git a/src/list_generic.c b/src/list_generic.c
index 2b3be4c..e32acf7 100644
--- a/src/list_generic.c
+++ b/src/list_generic.c
@@ -344,18 +344,33 @@ static void ListFree(void *d)
static void ListRedisplayLine(int y, int xs, int xe, int isblank)
{
+ struct ListData *ldata;
ASSERT(flayer);
+
+ ldata = flayer->l_data;
if (y < 0)
{
- glist_display_all(flayer->l_data);
+ glist_display_all(ldata);
return;
}
- if (y != 0 && y != flayer->l_height - 1)
- return;
- if (isblank)
- return;
- LClearArea(flayer, xs, y, xe, y, 0, 0);
+ if (!isblank)
+ LClearArea(flayer, xs, y, xe, y, 0, 0);
+
+ if (ldata->top && y < ldata->top->y)
+ ldata->list_fn->gl_printheader(ldata);
+ else if (y + 1 == flayer->l_height)
+ ldata->list_fn->gl_printfooter(ldata);
+ else
+ {
+ struct ListRow *row;
+ for (row = ldata->top; row && row->y != -1; row = row->next)
+ if (row->y == y)
+ {
+ ldata->list_fn->gl_printrow(ldata, row);
+ break;
+ }
+ }
}
static void ListClearLine(int y, int xs, int xe, int bce)
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;