mutt stable branch with some hacks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add window structures to use for screen layout.

This is a series of 11 patches, centralizing Mutt screen drawing
inside windows (mutt_window_t structures).

Currently, the screen drawing and cursor positioning logic is
distributed all over the code, resulting in many files having the same
logic of where the help, status, message windows are. Additionally,
the code directly uses move and mvadd*/mvprint* functions, which means
if the layouts are changed, the row/column computation logic needs to
be changed all over the place.

The patch creates a (very simple) mutt_window_t structure and
functions for moving, addch/str/printw, along with clearing the line.
The windows keep track of where they are on the screen, allowing the
Mutt code to simply position elements relative to the window.

During curses initalization, and when the window is resized, the
window sizes and positions and recomputed. Also, a new option flags,
R_REFLOW is added for options that need to force a reflow when they are changed.

Thanks to Richard Russon for pointing out the slang compilation issue.

+197 -2
+154
curs_lib.c
··· 63 63 static size_t UngetLen = 0; 64 64 static event_t *UngetKeyEvents; 65 65 66 + mutt_window_t *MuttHelpWindow = NULL; 67 + mutt_window_t *MuttIndexWindow = NULL; 68 + mutt_window_t *MuttStatusWindow = NULL; 69 + mutt_window_t *MuttMessageWindow = NULL; 70 + #ifdef USE_SIDEBAR 71 + mutt_window_t *MuttSidebarWindow = NULL; 72 + #endif 73 + 66 74 void mutt_refresh (void) 67 75 { 68 76 /* don't refresh when we are waiting for a child. */ ··· 478 486 if (pos >= progress->size) 479 487 mutt_clear_error (); 480 488 } 489 + 490 + void mutt_init_windows () 491 + { 492 + MuttHelpWindow = safe_calloc (sizeof (mutt_window_t), 1); 493 + MuttIndexWindow = safe_calloc (sizeof (mutt_window_t), 1); 494 + MuttStatusWindow = safe_calloc (sizeof (mutt_window_t), 1); 495 + MuttMessageWindow = safe_calloc (sizeof (mutt_window_t), 1); 496 + #ifdef USE_SIDEBAR 497 + MuttSidebarWindow = safe_calloc (sizeof (mutt_window_t), 1); 498 + #endif 499 + 500 + mutt_reflow_windows (); 501 + } 502 + 503 + void mutt_free_windows () 504 + { 505 + FREE (&MuttHelpWindow); 506 + FREE (&MuttIndexWindow); 507 + FREE (&MuttStatusWindow); 508 + FREE (&MuttMessageWindow); 509 + #ifdef USE_SIDEBAR 510 + FREE (&MuttSidebarWindow); 511 + #endif 512 + } 513 + 514 + void mutt_reflow_windows (void) 515 + { 516 + if (option (OPTNOCURSES)) 517 + return; 518 + 519 + dprint (2, (debugfile, "In mutt_reflow_windows\n")); 520 + 521 + MuttStatusWindow->rows = 1; 522 + MuttStatusWindow->cols = COLS; 523 + MuttStatusWindow->row_offset = option (OPTSTATUSONTOP) ? 0 : LINES - 2; 524 + MuttStatusWindow->col_offset = 0; 525 + 526 + memcpy (MuttHelpWindow, MuttStatusWindow, sizeof (mutt_window_t)); 527 + if (! option (OPTHELP)) 528 + MuttHelpWindow->rows = 0; 529 + else 530 + MuttHelpWindow->row_offset = option (OPTSTATUSONTOP) ? LINES - 2 : 0; 531 + 532 + memcpy (MuttMessageWindow, MuttStatusWindow, sizeof (mutt_window_t)); 533 + MuttMessageWindow->row_offset = LINES - 1; 534 + 535 + memcpy (MuttIndexWindow, MuttStatusWindow, sizeof (mutt_window_t)); 536 + MuttIndexWindow->rows = LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - 537 + MuttMessageWindow->rows; 538 + MuttIndexWindow->row_offset = option (OPTSTATUSONTOP) ? MuttStatusWindow->rows : 539 + MuttHelpWindow->rows; 540 + 541 + #ifdef USE_SIDEBAR 542 + if (option (OPTSIDEBAR)) 543 + { 544 + memcpy (MuttSidebarWindow, MuttIndexWindow, sizeof (mutt_window_t)); 545 + MuttSidebarWindow->cols = SidebarWidth; 546 + 547 + MuttIndexWindow->cols -= SidebarWidth; 548 + MuttIndexWindow->col_offset += SidebarWidth; 549 + } 550 + #endif 551 + } 552 + 553 + int mutt_window_move (mutt_window_t *win, int row, int col) 554 + { 555 + return move (win->row_offset + row, win->col_offset + col); 556 + } 557 + 558 + int mutt_window_mvaddch (mutt_window_t *win, int row, int col, const chtype ch) 559 + { 560 + return mvaddch (win->row_offset + row, win->col_offset + col, ch); 561 + } 562 + 563 + int mutt_window_mvaddstr (mutt_window_t *win, int row, int col, const char *str) 564 + { 565 + return mvaddstr (win->row_offset + row, win->col_offset + col, str); 566 + } 567 + 568 + #ifdef USE_SLANG_CURSES 569 + static int vw_printw (SLcurses_Window_Type *win, const char *fmt, va_list ap) 570 + { 571 + char buf[LONG_STRING]; 572 + 573 + (void) SLvsnprintf (buf, sizeof (buf), (char *)fmt, ap); 574 + SLcurses_waddnstr (win, buf, -1); 575 + return 0; 576 + } 577 + #endif 578 + 579 + int mutt_window_mvprintw (mutt_window_t *win, int row, int col, const char *fmt, ...) 580 + { 581 + va_list ap; 582 + int rv; 583 + 584 + if ((rv = mutt_window_move (win, row, col) != ERR)) 585 + { 586 + va_start (ap, fmt); 587 + rv = vw_printw (stdscr, fmt, ap); 588 + va_end (ap); 589 + } 590 + 591 + return rv; 592 + } 593 + 594 + /* Assumes the cursor has already been positioned within the 595 + * window. 596 + */ 597 + void mutt_window_clrtoeol (mutt_window_t *win) 598 + { 599 + int row, col, curcol; 600 + 601 + if (win->col_offset + win->cols == COLS) 602 + clrtoeol (); 603 + else 604 + { 605 + getyx (stdscr, row, col); 606 + curcol = col; 607 + while (curcol < win->col_offset + win->cols) 608 + { 609 + addch (' '); 610 + curcol++; 611 + } 612 + move (row, col); 613 + } 614 + } 615 + 616 + void mutt_window_clearline (mutt_window_t *win, int row) 617 + { 618 + mutt_window_move (win, row, 0); 619 + mutt_window_clrtoeol (win); 620 + } 621 + 622 + /* Assumes the current position is inside the window. 623 + * Otherwise it will happily return negative or values outside 624 + * the window boundaries 625 + */ 626 + void mutt_window_getyx (mutt_window_t *win, int *y, int *x) 627 + { 628 + int row, col; 629 + 630 + getyx (stdscr, row, col); 631 + *y = row - win->row_offset; 632 + *x = col - win->col_offset; 633 + } 634 + 481 635 482 636 void mutt_show_error (void) 483 637 {
+4
init.c
··· 1611 1611 set_option (OPTRESORTINIT); 1612 1612 if (p->flags & R_TREE) 1613 1613 set_option (OPTREDRAWTREE); 1614 + if (p->flags & R_REFLOW) 1615 + mutt_reflow_windows (); 1614 1616 } 1615 1617 1616 1618 static size_t escape_string (char *dst, size_t len, const char* src) ··· 2226 2228 set_option (OPTRESORTINIT); 2227 2229 if (MuttVars[idx].flags & R_TREE) 2228 2230 set_option (OPTREDRAWTREE); 2231 + if (MuttVars[idx].flags & R_REFLOW) 2232 + mutt_reflow_windows (); 2229 2233 } 2230 2234 } 2231 2235 return (r);
+3 -2
init.h
··· 61 61 #define R_RESORT_SUB (1<<3) /* resort subthreads */ 62 62 #define R_RESORT_INIT (1<<4) /* resort from scratch */ 63 63 #define R_TREE (1<<5) /* redraw the thread tree */ 64 + #define R_REFLOW (1<<6) /* reflow window layout */ 64 65 #define R_BOTH (R_INDEX | R_PAGER) 65 66 #define R_RESORT_BOTH (R_RESORT | R_RESORT_SUB) 66 67 ··· 977 978 */ 978 979 #endif /* HAVE_GDBM || HAVE_DB4 */ 979 980 #endif /* USE_HCACHE */ 980 - { "help", DT_BOOL, R_BOTH, OPTHELP, 1 }, 981 + { "help", DT_BOOL, R_BOTH|R_REFLOW, OPTHELP, 1 }, 981 982 /* 982 983 ** .pp 983 984 ** When \fIset\fP, help lines describing the bindings for the major functions ··· 3287 3288 ** will replace any dots in the expansion by underscores. This might be helpful 3288 3289 ** with IMAP folders that don't like dots in folder names. 3289 3290 */ 3290 - { "status_on_top", DT_BOOL, R_BOTH, OPTSTATUSONTOP, 0 }, 3291 + { "status_on_top", DT_BOOL, R_BOTH|R_REFLOW, OPTSTATUSONTOP, 0 }, 3291 3292 /* 3292 3293 ** .pp 3293 3294 ** Setting this variable causes the ``status bar'' to be displayed on
+6
main.c
··· 547 547 meta (stdscr, TRUE); 548 548 #endif 549 549 init_extended_keys(); 550 + mutt_init_windows (); 550 551 } 551 552 552 553 #define M_IGNORE (1<<0) /* -z */ ··· 859 860 if (!option (OPTNOCURSES)) 860 861 mutt_flushinp (); 861 862 ci_send_message (SENDPOSTPONED, NULL, NULL, NULL, NULL); 863 + mutt_free_windows (); 862 864 mutt_endwin (NULL); 863 865 } 864 866 else if (subject || msg || sendflags || draftFile || includeFile || attach || ··· 1148 1150 } 1149 1151 1150 1152 if (!option (OPTNOCURSES)) 1153 + { 1154 + mutt_free_windows (); 1151 1155 mutt_endwin (NULL); 1156 + } 1152 1157 1153 1158 if (rv) 1154 1159 exit(1); ··· 1217 1222 mutt_sasl_done (); 1218 1223 #endif 1219 1224 mutt_free_opts (); 1225 + mutt_free_windows (); 1220 1226 mutt_endwin (Errorbuf); 1221 1227 } 1222 1228
+29
mutt_curses.h
··· 161 161 * was initialized with positive size, otherwise no percentage is shown */ 162 162 void mutt_progress_update (progress_t* progress, long pos, int percent); 163 163 164 + /* Windows for different parts of the screen */ 165 + typedef struct 166 + { 167 + int rows; 168 + int cols; 169 + int row_offset; 170 + int col_offset; 171 + } mutt_window_t; 172 + 173 + extern mutt_window_t *MuttHelpWindow; 174 + extern mutt_window_t *MuttIndexWindow; 175 + extern mutt_window_t *MuttStatusWindow; 176 + extern mutt_window_t *MuttMessageWindow; 177 + #ifdef USE_SIDEBAR 178 + extern mutt_window_t *MuttSidebarWindow; 179 + #endif 180 + 181 + void mutt_init_windows (void); 182 + void mutt_free_windows (void); 183 + void mutt_reflow_windows (void); 184 + int mutt_window_move (mutt_window_t *, int row, int col); 185 + int mutt_window_mvaddch (mutt_window_t *, int row, int col, const chtype ch); 186 + int mutt_window_mvaddstr (mutt_window_t *, int row, int col, const char *str); 187 + int mutt_window_mvprintw (mutt_window_t *, int row, int col, const char *fmt, ...); 188 + void mutt_window_clrtoeol (mutt_window_t *); 189 + void mutt_window_clearline (mutt_window_t *, int row); 190 + void mutt_window_getyx (mutt_window_t *, int *y, int *x); 191 + 192 + 164 193 static inline int mutt_term_width(short wrap) 165 194 { 166 195 if (wrap < 0)
+1
resize.c
··· 76 76 #else 77 77 resizeterm (SLtt_Screen_Rows, SLtt_Screen_Cols); 78 78 #endif 79 + mutt_reflow_windows (); 79 80 }