Pārlūkot izejas kodu

Shell: Handle SIGWINCH to get a nice behavior when resizing.

When resizing the terminal, we now clear the entire current line and reset
the shell's LineEditor input state. This makes it look and feel kinda the
same as xterm.

Fixes #286.
Andreas Kling 6 gadi atpakaļ
vecāks
revīzija
fc4022d173
3 mainītis faili ar 18 papildinājumiem un 27 dzēšanām
  1. 1 0
      Shell/GlobalState.h
  2. 7 1
      Shell/LineEditor.cpp
  3. 10 26
      Shell/main.cpp

+ 1 - 0
Shell/GlobalState.h

@@ -13,6 +13,7 @@ struct GlobalState {
     uid_t uid;
     struct termios termios;
     bool was_interrupted { false };
+    bool was_resized { false };
 };
 
 extern GlobalState g;

+ 7 - 1
Shell/LineEditor.cpp

@@ -50,10 +50,16 @@ String LineEditor::get_line()
         if (nread < 0) {
             if (errno == EINTR) {
                 if (g.was_interrupted) {
+                    g.was_interrupted = false;
                     if (!m_buffer.is_empty())
                         printf("^C");
                 }
-                g.was_interrupted = false;
+                if (g.was_resized) {
+                    g.was_resized = false;
+                    printf("\033[2K\r");
+                    m_buffer.clear();
+                    return String::empty();
+                }
                 m_buffer.clear();
                 putchar('\n');
                 return String::empty();

+ 10 - 26
Shell/main.cpp

@@ -50,11 +50,6 @@ void did_receive_signal(int signum)
     g_got_signal = true;
 }
 
-void handle_sigint(int)
-{
-    g.was_interrupted = true;
-}
-
 static int sh_exit(int, char**)
 {
     printf("Good-bye!\n");
@@ -561,11 +556,6 @@ void save_history()
     }
 }
 
-void handle_sighup(int)
-{
-    save_history();
-}
-
 int main(int argc, char** argv)
 {
     g.uid = getuid();
@@ -573,23 +563,17 @@ int main(int argc, char** argv)
     tcsetpgrp(0, getpgrp());
     tcgetattr(0, &g.termios);
 
-    {
-        struct sigaction sa;
-        sa.sa_handler = handle_sigint;
-        sa.sa_flags = 0;
-        sa.sa_mask = 0;
-        int rc = sigaction(SIGINT, &sa, nullptr);
-        assert(rc == 0);
-    }
+    signal(SIGINT, [](int) {
+        g.was_interrupted = true;
+    });
 
-    {
-        struct sigaction sa;
-        sa.sa_handler = handle_sighup;
-        sa.sa_flags = 0;
-        sa.sa_mask = 0;
-        int rc = sigaction(SIGHUP, &sa, nullptr);
-        assert(rc == 0);
-    }
+    signal(SIGHUP, [](int) {
+        save_history();
+    });
+
+    signal(SIGWINCH, [](int) {
+        g.was_resized = true;
+    });
 
     int rc = gethostname(g.hostname, sizeof(g.hostname));
     if (rc < 0)