diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp
index 38860ad40e9e9bd562437f90c245261d85d1dc6a..7d9f74b24b619b092fa6fd02dae1d27092ef1716 100644
--- a/src/ftxui/component/terminal_input_parser.cpp
+++ b/src/ftxui/component/terminal_input_parser.cpp
@@ -136,12 +136,11 @@ TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
   unsigned int first_zero = 8;            // NOLINT
   for (unsigned int i = 0; i < 8; ++i) {  // NOLINT
     mask |= selector;
-    if (head & selector) {
-      selector >>= 1U;
-      continue;
+    if (!(head & selector)) {
+      first_zero = i;
+      break;
     }
-    first_zero = i;
-    break;
+    selector >>= 1U;
   }
 
   // Accumulate the value of the first byte.
diff --git a/src/ftxui/component/terminal_input_parser_test.cpp b/src/ftxui/component/terminal_input_parser_test.cpp
index 863f9743f70521dc093a7694b47c4a924e1734a8..42d6d8b9d1c9948c54a95cf104c308511c392df0 100644
--- a/src/ftxui/component/terminal_input_parser_test.cpp
+++ b/src/ftxui/component/terminal_input_parser_test.cpp
@@ -72,7 +72,7 @@ TEST(Event, EscapeKeyEnoughWait) {
   EXPECT_FALSE(event_receiver->Receive(&received));
 }
 
-TEST(Event, MouseLeftClick) {
+TEST(Event, MouseLeftClickPressed) {
   auto event_receiver = MakeReceiver<Task>();
   {
     auto parser = TerminalInputParser(event_receiver->MakeSender());
@@ -95,6 +95,56 @@ TEST(Event, MouseLeftClick) {
   EXPECT_EQ(Mouse::Left, std::get<Event>(received).mouse().button);
   EXPECT_EQ(12, std::get<Event>(received).mouse().x);
   EXPECT_EQ(42, std::get<Event>(received).mouse().y);
+  EXPECT_EQ(std::get<Event>(received).mouse().motion, Mouse::Pressed);
+  EXPECT_FALSE(event_receiver->Receive(&received));
+}
+
+TEST(Event, MouseLeftClickReleased) {
+  auto event_receiver = MakeReceiver<Task>();
+  {
+    auto parser = TerminalInputParser(event_receiver->MakeSender());
+    parser.Add('\x1B');
+    parser.Add('[');
+    parser.Add('3');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('1');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('4');
+    parser.Add('2');
+    parser.Add('m');
+  }
+
+  Task received;
+  EXPECT_TRUE(event_receiver->Receive(&received));
+  EXPECT_TRUE(std::get<Event>(received).is_mouse());
+  EXPECT_EQ(Mouse::Left, std::get<Event>(received).mouse().button);
+  EXPECT_EQ(12, std::get<Event>(received).mouse().x);
+  EXPECT_EQ(42, std::get<Event>(received).mouse().y);
+  EXPECT_EQ(std::get<Event>(received).mouse().motion, Mouse::Released);
+  EXPECT_FALSE(event_receiver->Receive(&received));
+}
+
+TEST(Event, MouseReporting) {
+  auto event_receiver = MakeReceiver<Task>();
+  {
+    auto parser = TerminalInputParser(event_receiver->MakeSender());
+    parser.Add('\x1B');
+    parser.Add('[');
+    parser.Add('1');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('4');
+    parser.Add('2');
+    parser.Add('R');
+  }
+
+  Task received;
+  EXPECT_TRUE(event_receiver->Receive(&received));
+  EXPECT_TRUE(std::get<Event>(received).is_cursor_reporting());
+  EXPECT_EQ(42, std::get<Event>(received).cursor_x());
+  EXPECT_EQ(12, std::get<Event>(received).cursor_y());
   EXPECT_FALSE(event_receiver->Receive(&received));
 }
 
@@ -232,6 +282,105 @@ TEST(Event, UTF8) {
   }
 }
 
+TEST(Event, NewLine) {
+  for (char newline : {'\r', '\n'}) {
+    auto event_receiver = MakeReceiver<Task>();
+    {
+      auto parser = TerminalInputParser(event_receiver->MakeSender());
+      parser.Add(newline);
+    }
+    Task received;
+    EXPECT_TRUE(event_receiver->Receive(&received));
+    EXPECT_TRUE(std::get<Event>(received) == Event::Return);
+  }
+}
+
+TEST(Event, Control) {
+  struct TestCase {
+    char input;
+    bool cancel;
+  };
+  std::vector<TestCase> cases;
+  for (int i = 0; i < 32; ++i) {
+    if (i == 13 || i == 24 || i == 26 || i == 27)
+      continue;
+    cases.push_back({char(i), false});
+  }
+  cases.push_back({char(24), true});
+  cases.push_back({char(26), true});
+  cases.push_back({char(127), false});
+
+  for(auto test : cases) {
+    auto event_receiver = MakeReceiver<Task>();
+    {
+      auto parser = TerminalInputParser(event_receiver->MakeSender());
+      parser.Add(test.input);
+    }
+    Task received;
+    if (test.cancel) {
+      EXPECT_FALSE(event_receiver->Receive(&received));
+    } else {
+      EXPECT_TRUE(event_receiver->Receive(&received));
+      EXPECT_EQ(std::get<Event>(received), Event::Special({test.input}));
+    }
+  }
+}
+
+TEST(Event, Special) {
+  auto str = [](std::string input) {
+    std::vector<unsigned char> output;
+    for (auto it : input)
+      output.push_back(it);
+    return output;
+  };
+  struct {
+    std::vector<unsigned char> input;
+    Event expected;
+  } kTestCase[] = {
+      {str("\x1B[D"), Event::ArrowLeft},
+      {str("\x1B[C"), Event::ArrowRight},
+      {str("\x1B[A"), Event::ArrowUp},
+      {str("\x1B[B"), Event::ArrowDown},
+      {{127}, Event::Backspace},
+      {str("\x1B[3~"), Event::Delete},
+      //{str("\x1B"), Event::Escape},
+      {{10}, Event::Return},
+      {{9}, Event::Tab},
+      {{27, 91, 90}, Event::TabReverse},
+      //{str("\x1B[OP"), Event::F1},
+      //{str("\x1B[OQ"), Event::F2},
+      //{str("\x1B[OR"), Event::F3},
+      //{str("\x1B[OS"), Event::F4},
+      {str("\x1B[15~"), Event::F5},
+      {str("\x1B[17~"), Event::F6},
+      {str("\x1B[18~"), Event::F7},
+      {str("\x1B[19~"), Event::F8},
+      {str("\x1B[20~"), Event::F9},
+      {str("\x1B[21~"), Event::F10},
+      {str("\x1B[21~"), Event::F11},
+      {str("\x1B[24~"), Event::F12},
+      {{27, 91, 72}, Event::Home},
+      {{27, 91, 70}, Event::End},
+      {{27, 91, 53, 126}, Event::PageUp},
+      {{27, 91, 54, 126}, Event::PageDown},
+      {{0}, Event::Custom},
+  };
+
+  for (auto test : kTestCase) {
+    auto event_receiver = MakeReceiver<Task>();
+    {
+      auto parser = TerminalInputParser(event_receiver->MakeSender());
+      for (auto input : test.input) {
+        parser.Add(input);
+      }
+    }
+    Task received;
+    EXPECT_TRUE(event_receiver->Receive(&received));
+    EXPECT_EQ(std::get<Event>(received), test.expected);
+    EXPECT_FALSE(event_receiver->Receive(&received));
+  }
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/dom/canvas_test.cpp b/src/ftxui/dom/canvas_test.cpp
index c31c6d8500a475e1a1754a66dd370ae39e1357ee..274bdb9941b53d48c425d6dd84ae5c01be4e7d13 100644
--- a/src/ftxui/dom/canvas_test.cpp
+++ b/src/ftxui/dom/canvas_test.cpp
@@ -20,33 +20,49 @@ int Hash(const std::string s) {
 TEST(BorderTest, GoldPoint) {
   Terminal::SetColorSupport(Terminal::Color::TrueColor);
   auto element = canvas([](Canvas& c) {  //
-    c.DrawPoint(3, 3, 1, Color::Red);
+    c.DrawPoint(3, 3, 1);
     c.DrawPointToggle(2, 8);
-    c.DrawPointLine(3, 7, 10, 19, Color::Blue);
-    c.DrawPointCircle(10, 5, 3, Color::Yellow);
-    c.DrawPointCircleFilled(20, 5, 3, Color::Green);
-    c.DrawPointEllipse(10, 10, 5, 2, Color::Blue);
-    c.DrawPointEllipseFilled(10, 20, 5, 2, Color::DarkGreen);
+    c.DrawPointToggle(2, 8);
+    c.DrawPointToggle(2, 8);
+    c.DrawPointLine(3, 7, 10, 19);
+    c.DrawPointCircle(10, 5, 3);
+    c.DrawPointCircleFilled(20, 5, 3);
+    c.DrawPointEllipse(10, 10, 5, 2);
+    c.DrawPointEllipseFilled(10, 20, 5, 2);
   });
   Screen screen(30, 10);
   Render(screen, element);
-  EXPECT_EQ(Hash(screen.ToString()), 17651);
+  EXPECT_EQ(Hash(screen.ToString()), 1069);
 }
 
 TEST(BorderTest, GoldBlock) {
   Terminal::SetColorSupport(Terminal::Color::TrueColor);
   auto element = canvas([](Canvas& c) {  //
-    c.DrawBlock(3, 3, 1, Color::Red);
+    c.DrawBlock(3, 3, 1);
+    c.DrawBlockToggle(2, 8);
     c.DrawBlockToggle(2, 8);
-    c.DrawBlockLine(3, 7, 10, 19, Color::Blue);
-    c.DrawBlockCircle(10, 5, 3, Color::Yellow);
-    c.DrawBlockCircleFilled(20, 5, 3, Color::Green);
-    c.DrawBlockEllipse(10, 10, 5, 2, Color::Blue);
-    c.DrawBlockEllipseFilled(10, 20, 5, 2, Color::DarkGreen);
+    c.DrawBlockToggle(2, 8);
+    c.DrawBlockLine(3, 7, 10, 19);
+    c.DrawBlockCircle(10, 5, 3);
+    c.DrawBlockCircleFilled(20, 5, 3);
+    c.DrawBlockEllipse(10, 10, 5, 2);
+    c.DrawBlockEllipseFilled(10, 20, 5, 2);
   });
   Screen screen(30, 10);
   Render(screen, element);
-  EXPECT_EQ(Hash(screen.ToString()), 14383);
+  EXPECT_EQ(Hash(screen.ToString()), 472);
+}
+
+TEST(BorderTest, GoldText) {
+  Terminal::SetColorSupport(Terminal::Color::TrueColor);
+  Canvas c(10, 10);
+  c.DrawText(0, 0, "test");
+  c.DrawText(0, 5, "test");
+  c.DrawText(0, 10, "test");
+  auto element = canvas(c);
+  Screen screen(30, 10);
+  Render(screen, element);
+  EXPECT_EQ(Hash(screen.ToString()), 10447);
 }
 
 } // namespace ftxui