fix crashes in tog when terminal is resized
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
diff --git a/tog/tog.c b/tog/tog.c
index 885bafc..dbd0f08 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -16,6 +16,7 @@
#include <sys/queue.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <errno.h>
#define _XOPEN_SOURCE_EXTENDED
@@ -287,6 +288,14 @@ static const struct got_error *input_tree_view(struct tog_view **,
struct tog_view **, struct tog_view **, struct tog_view *, int);
static const struct got_error *close_tree_view(struct tog_view *);
+static volatile sig_atomic_t tog_sigwinch_received;
+
+static void
+tog_sigwinch(int signo)
+{
+ tog_sigwinch_received = 1;
+}
+
static const struct got_error *
view_close(struct tog_view *view)
{
@@ -415,6 +424,7 @@ view_resize(struct tog_view *view)
return got_error_from_errno();
if (replace_panel(view->panel, view->window) == ERR)
return got_error_from_errno();
+ wclear(view->window);
view->nlines = nlines;
view->ncols = ncols;
@@ -467,6 +477,22 @@ view_is_splitscreen(struct tog_view *view)
return !view_is_parent_view(view) && view->begin_x > 0;
}
+static void
+tog_resizeterm()
+{
+ int cols, lines;
+ struct winsize size;
+
+ if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &size) < 0) {
+ cols = 80; /* Default */
+ lines = 24;
+ } else {
+ cols = size.ws_col;
+ lines = size.ws_row;
+ }
+ resize_term(lines, cols);
+}
+
static const struct got_error *
view_input(struct tog_view **new, struct tog_view **dead,
struct tog_view **focus, int *done, struct tog_view *view,
@@ -490,6 +516,20 @@ view_input(struct tog_view **new, struct tog_view **dead,
if (errcode)
return got_error_set_errno(errcode);
nodelay(stdscr, TRUE);
+
+ if (tog_sigwinch_received) {
+ tog_resizeterm();
+ tog_sigwinch_received = 0;
+ TAILQ_FOREACH(v, views, entry) {
+ err = view_resize(v);
+ if (err)
+ return err;
+ err = v->input(new, dead, focus, v, KEY_RESIZE);
+ if (err)
+ return err;
+ }
+ }
+
switch (ch) {
case ERR:
break;
@@ -538,14 +578,6 @@ view_input(struct tog_view **new, struct tog_view **dead,
}
break;
case KEY_RESIZE:
- TAILQ_FOREACH(v, views, entry) {
- err = view_resize(v);
- if (err)
- return err;
- err = v->input(new, dead, focus, v, ch);
- if (err)
- return err;
- }
break;
default:
err = view->input(new, dead, focus, view, ch);
@@ -3377,6 +3409,7 @@ done:
got_repo_close(repo);
return error;
}
+
static void
init_curses(void)
{
@@ -3388,6 +3421,7 @@ init_curses(void)
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
curs_set(0);
+ signal(SIGWINCH, tog_sigwinch);
}
__dead static void