- struct Win * first_ceiling = win->prev; // first_ceiling determines column with;
- while (first_ceiling->start_y != 1) // default: place window in new column
- first_ceiling = first_ceiling->prev; // next to it
- win->start_x = first_ceiling->start_x + first_ceiling->width + 1;
- if (first_ceiling->width >= win->width) { // only place windows in prev column that fit into its width
- struct Win * win_p = first_ceiling;
- struct Win * lastrow_startwin = win_p;
- while (win_p != win) {
- if (win_p->start_x == first_ceiling->start_x)
- lastrow_startwin = win_p; // try to fit window at end of last
- win_p = win_p ->next; } // row of windows inside column; if
- int lastcol_start = win->prev->start_x + win->prev->width + 1; // failure, try opening new row below
- if (win->width <= first_ceiling->start_x + first_ceiling->width - lastcol_start
- && win->height <= lastrow_startwin->height) {
- win->start_x = lastcol_start;
- win->start_y = lastrow_startwin->start_y; }
- else if (win->height < win_meta->height - (lastrow_startwin->start_y + lastrow_startwin->height)
- && win->width <= first_ceiling->width) {
- win->start_x = first_ceiling->start_x;
- win->start_y = lastrow_startwin->start_y + lastrow_startwin->height + 1; } } } } }
-
-void update_windows (struct WinMeta * win_meta, struct Win * win) {
-// Update geometry of win and its next of kin. Before, destroy window, if visible. After, (re-)build it.
- if (0 != win->curses_win)
- destroy_window (win);
- place_window(win_meta, win);
- win->curses_win = newwin(win->height, win->width, win->start_y, win->start_x);
- if (0 != win->next)
- update_windows (win_meta, win->next); }
-
-void destroy_window (struct Win * win) {
-// Undraw and delete window.
- delwin(win->curses_win);
- win->curses_win = 0; }
-
-void draw_window_borders (struct Win * win, char active) {
+ struct Win * w_up = w->prev;
+ struct Win * w_upup = w_up;
+ uint16_t widthdiff;
+ while (w_up != w_top) {
+ w_upup = w_up->prev;
+ while (1) {
+ if (w_up->start.y != w_upup->start.y)
+ break;
+ w_upup = w_upup->prev; }
+ w_prev_maxy = w_upup->start.y + getmaxy(w_upup->frame.curses_win);
+ widthdiff = (w_upup->start.x + w_upup->frame.size.x) - (w_up->start.x + w_up->frame.size.x);
+ if (w->frame.size.y < wmeta->pad.size.y - w_prev_maxy && w->frame.size.x < widthdiff) {
+ w->start.x = w_up->start.x + w_up->frame.size.x + 1 ; // else try to open new sub column under
+ w->start.y = w_prev_maxy + 1; // last window below which enough space remains
+ break; }
+ w_up = w_upup; } } } }
+
+static void update_wins (struct WinMeta * wmeta, struct Win * w) {
+// Update geometry of win and its next of kin. Destroy (if visible), (re-)build window. If need, resize pad.
+ if (0 != w->frame.curses_win)
+ destroy_win (w);
+ place_win(wmeta, w);
+ refit_pad(wmeta);
+ w->frame.curses_win=subpad(wmeta->pad.curses_win, w->frame.size.y, w->frame.size.x, w->start.y, w->start.x);
+ if (0 != w->next)
+ update_wins (wmeta, w->next); }
+
+static void destroy_win (struct Win * w) {
+// Delete window.
+ delwin(w->frame.curses_win);
+ w->frame.curses_win = 0; }
+
+static void draw_win_borders (struct Win * w, char active) {