diff --git a/CHANGELOG.md b/CHANGELOG.md
index 817f5b8baee7aebb63bedc30bc4042c0f29cadd4..55a255e390b714b25b6bb2ba4b3c1751c52ea8c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ Changelog
 current (development) 
 ---------------------
 
+### DOM
+- Bugfix: Fix `focus`/`select` when the `vbox`/`hbox`/`dbox` contains a
+  `flexbox`
+
+### Screen
+- Feature: add `Box::Union(a,b) -> Box`
+
 3.0.0
 -----
 
diff --git a/include/ftxui/screen/box.hpp b/include/ftxui/screen/box.hpp
index 9edcd9e7ac33102a7469d2c7177aa917543c8cb9..7e0dcdc2153fc584c7a20dce9fd30cf73b026cf8 100644
--- a/include/ftxui/screen/box.hpp
+++ b/include/ftxui/screen/box.hpp
@@ -10,6 +10,7 @@ struct Box {
   int y_max = 0;
 
   static auto Intersection(Box a, Box b) -> Box;
+  static auto Union(Box a, Box b) -> Box;
   bool Contain(int x, int y) const;
   bool operator==(const Box& other) const;
   bool operator!=(const Box& other) const;
diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp
index 674276f7151e2f7009c7389b12ca86d72f3e068b..88609b270060848e988d3bda0f7cf1dd9fd2a7b6 100644
--- a/src/ftxui/component/screen_interactive.cpp
+++ b/src/ftxui/component/screen_interactive.cpp
@@ -297,8 +297,9 @@ ScreenInteractive ScreenInteractive::FitComponent() {
 void ScreenInteractive::Post(Task task) {
   // Task/Events sent toward inactive screen or screen waiting to become
   // inactive are dropped.
-  if (!task_sender_)
+  if (!task_sender_) {
     return;
+  }
 
   task_sender_->Send(std::move(task));
 }
diff --git a/src/ftxui/dom/dbox.cpp b/src/ftxui/dom/dbox.cpp
index bf1c244a2d7706c06143648dd044f7aa6e819339..2c4ec263bab2026ad1b7ee6d7dd84b095a8ade8b 100644
--- a/src/ftxui/dom/dbox.cpp
+++ b/src/ftxui/dom/dbox.cpp
@@ -21,6 +21,7 @@ class DBox : public Node {
     requirement_.flex_grow_y = 0;
     requirement_.flex_shrink_x = 0;
     requirement_.flex_shrink_y = 0;
+    requirement_.selection = Requirement::NORMAL;
     for (auto& child : children_) {
       child->ComputeRequirement();
       requirement_.min_x =
diff --git a/src/ftxui/dom/flexbox.cpp b/src/ftxui/dom/flexbox.cpp
index 0c4bb3a790593d03fe10b380e1679201d4c163b0..b2ebb9b9a5c07aca075e9b682b071ac43a206665 100644
--- a/src/ftxui/dom/flexbox.cpp
+++ b/src/ftxui/dom/flexbox.cpp
@@ -99,41 +99,63 @@ class Flexbox : public Node {
     }
     Layout(global, true);
 
+    // Reset:
+    requirement_.selection = Requirement::Selection::NORMAL;
+    requirement_.selected_box = Box();
+    requirement_.min_x = 0;
+    requirement_.min_y = 0;
+
     if (global.blocks.empty()) {
-      requirement_.min_x = 0;
-      requirement_.min_y = 0;
       return;
     }
 
+    // Compute the union of all the blocks:
     Box box;
     box.x_min = global.blocks[0].x;
     box.y_min = global.blocks[0].y;
     box.x_max = global.blocks[0].x + global.blocks[0].dim_x;
     box.y_max = global.blocks[0].y + global.blocks[0].dim_y;
-
     for (auto& b : global.blocks) {
       box.x_min = std::min(box.x_min, b.x);
       box.y_min = std::min(box.y_min, b.y);
       box.x_max = std::max(box.x_max, b.x + b.dim_x);
       box.y_max = std::max(box.y_max, b.y + b.dim_y);
     }
-
     requirement_.min_x = box.x_max - box.x_min;
     requirement_.min_y = box.y_max - box.y_min;
+
+    // Find the selection:
+    for (size_t i = 0; i < children_.size(); ++i) {
+      if (requirement_.selection >= children_[i]->requirement().selection) {
+        continue;
+      }
+      requirement_.selection = children_[i]->requirement().selection;
+      Box selected_box = children_[i]->requirement().selected_box;
+
+      // Shift |selected_box| according to its position inside this component:
+      auto& b = global.blocks[i];
+      selected_box.x_min += b.x;
+      selected_box.y_min += b.y;
+      selected_box.x_max += b.x;
+      selected_box.y_max += b.y;
+      requirement_.selected_box = Box::Intersection(selected_box, box);
+    }
   }
 
   void SetBox(Box box) override {
     Node::SetBox(box);
 
+    int asked_previous = asked_;
     asked_ = std::min(asked_, IsColumnOriented() ? box.y_max - box.y_min + 1
                                                  : box.x_max - box.x_min + 1);
+    need_iteration_ = (asked_ != asked_previous);
+
     flexbox_helper::Global global;
     global.config = config_;
     global.size_x = box.x_max - box.x_min + 1;
     global.size_y = box.y_max - box.y_min + 1;
     Layout(global);
 
-    need_iteration_ = false;
     for (size_t i = 0; i < children_.size(); ++i) {
       auto& child = children_[i];
       auto& b = global.blocks[i];
diff --git a/src/ftxui/dom/flexbox_test.cpp b/src/ftxui/dom/flexbox_test.cpp
index 78fff80d85448cdfe601157d4bda32951363df69..b5175f6d483b4c392eea51d3a2383c65e449273f 100644
--- a/src/ftxui/dom/flexbox_test.cpp
+++ b/src/ftxui/dom/flexbox_test.cpp
@@ -432,6 +432,29 @@ TEST(FlexboxTest, GapY) {
             "       ");
 }
 
+TEST(FlexboxTest, Focus) {
+  auto document = vbox({
+    paragraph("0 -"),
+    paragraph("1 -"),
+    paragraph("2 -"),
+    paragraph("3 -"),
+    paragraph("4 -"),
+    paragraph("5 -"),
+    paragraph("6 -"),
+    paragraph("7 -") | focus,
+    paragraph("8 -"),
+    paragraph("9 -"),
+  }) | yframe | flex;
+
+  Screen screen(1, 3);
+  Render(screen, document);
+  EXPECT_EQ(screen.ToString(),
+            "7\r\n"
+            "-\r\n"
+            "8"
+            );
+}
+
 }  // namespace ftxui
 
 // Copyright 2021 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/dom/hbox.cpp b/src/ftxui/dom/hbox.cpp
index 75bba74b21c4c87019b28fec7b01d68fd87c01c7..d2684390765894b7e464d635f25ed25ee37d2e59 100644
--- a/src/ftxui/dom/hbox.cpp
+++ b/src/ftxui/dom/hbox.cpp
@@ -23,6 +23,7 @@ class HBox : public Node {
     requirement_.flex_grow_y = 0;
     requirement_.flex_shrink_x = 0;
     requirement_.flex_shrink_y = 0;
+    requirement_.selection = Requirement::NORMAL;
     for (auto& child : children_) {
       child->ComputeRequirement();
       if (requirement_.selection < child->requirement().selection) {
diff --git a/src/ftxui/dom/vbox.cpp b/src/ftxui/dom/vbox.cpp
index ecd63da3142ab60f7dbb63fcfaa6272071a39e35..5b4c33191ca1d1d3ce7186868aa6f6c49fc75477 100644
--- a/src/ftxui/dom/vbox.cpp
+++ b/src/ftxui/dom/vbox.cpp
@@ -23,6 +23,7 @@ class VBox : public Node {
     requirement_.flex_grow_y = 0;
     requirement_.flex_shrink_x = 0;
     requirement_.flex_shrink_y = 0;
+    requirement_.selection = Requirement::NORMAL;
     for (auto& child : children_) {
       child->ComputeRequirement();
       if (requirement_.selection < child->requirement().selection) {
diff --git a/src/ftxui/screen/box.cpp b/src/ftxui/screen/box.cpp
index 4b96ff70202dbdbc33cfb378c95ebe4e2d601988..15a60bac1e8741b616b046c3313da662da65e8f3 100644
--- a/src/ftxui/screen/box.cpp
+++ b/src/ftxui/screen/box.cpp
@@ -15,6 +15,18 @@ Box Box::Intersection(Box a, Box b) {
   };
 }
 
+/// @return the smallest Box containing both |a| and |b|.
+/// @ingroup screen
+// static
+Box Box::Union(Box a, Box b) {
+  return Box{
+      std::min(a.x_min, b.x_min),
+      std::max(a.x_max, b.x_max),
+      std::min(a.y_min, b.y_min),
+      std::max(a.y_max, b.y_max),
+  };
+}
+
 /// @return whether (x,y) is contained inside the box.
 /// @ingroup screen
 bool Box::Contain(int x, int y) const {
diff --git a/src/ftxui/screen/terminal.cpp b/src/ftxui/screen/terminal.cpp
index 971db344a680117c001bfbb9516ed3b2fa36aa36..4ea48a6b71ecd55e3ce0dcd065597212fd9c96ff 100644
--- a/src/ftxui/screen/terminal.cpp
+++ b/src/ftxui/screen/terminal.cpp
@@ -20,8 +20,8 @@ namespace ftxui {
 
 namespace {
 
-bool g_cached = false;
-Terminal::Color g_cached_supported_color;
+bool g_cached = false;                     // NOLINT
+Terminal::Color g_cached_supported_color;  // NOLINT
 
 Dimensions& FallbackSize() {
 #if defined(__EMSCRIPTEN__)