diff --git a/src/ui.rs b/src/ui.rs
index ea8dbb2fd3ac5a4c9c74de336cf88039d953c413..46926d541a2c15600212afe5fcb2dcb86bda982a 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -2,5 +2,6 @@ mod composable_view;
 mod layout_manager;
 mod panes;
 mod shortcuts;
+mod utils;
 
 pub use composable_view::ComposableView;
diff --git a/src/ui/composable_view.rs b/src/ui/composable_view.rs
index b2a0c5d8ce5f398c43e0c27081f9e71d063ba49b..7351601b00ded36cf8511ebbc8b90b6fff031910 100644
--- a/src/ui/composable_view.rs
+++ b/src/ui/composable_view.rs
@@ -1,7 +1,8 @@
 use super::{
     layout_manager::LayoutManager,
-    panes::{Pane, PaneBehavior},
+    panes::{Pane, PaneBehavior, PaneKind},
     shortcuts,
+    utils::maximized_pane_ui,
 };
 use std::{
     fs,
@@ -19,6 +20,7 @@ pub struct ComposableView {
 
     pub layout_manager: LayoutManager,
     behavior: ComposableBehavior,
+    maximized_pane: Option<TileId>,
 }
 
 // An app must implement the `App` trait to define how the ui is built
@@ -44,6 +46,8 @@ impl eframe::App for ComposableView {
                 ((Modifiers::NONE, Key::V), PaneAction::SplitV),
                 ((Modifiers::NONE, Key::H), PaneAction::SplitH),
                 ((Modifiers::NONE, Key::C), PaneAction::Close),
+                ((Modifiers::SHIFT, Key::Escape), PaneAction::Maximize),
+                ((Modifiers::NONE, Key::Escape), PaneAction::Exit),
             ];
             pane_action = pane_action.or(shortcuts::map_to_action(ctx, &key_action_pairs[..])
                 .map(|action| (action, hovered_pane)));
@@ -53,40 +57,70 @@ impl eframe::App for ComposableView {
         if let Some((action, hovered_tile)) = pane_action.take() {
             match action {
                 PaneAction::SplitH => {
-                    let hovered_tile_pane = panes_tree.tiles.remove(hovered_tile).unwrap();
-                    let left_pane = panes_tree.tiles.insert_new(hovered_tile_pane);
-                    let right_pane = panes_tree.tiles.insert_pane(Pane::default());
-                    panes_tree.tiles.insert(
-                        hovered_tile,
-                        Tile::Container(Container::Linear(Linear::new_binary(
-                            LinearDir::Horizontal,
-                            [left_pane, right_pane],
-                            0.5,
-                        ))),
-                    );
+                    if self.maximized_pane.is_none() {
+                        let hovered_tile_pane = panes_tree.tiles.remove(hovered_tile).unwrap();
+                        let left_pane = panes_tree.tiles.insert_new(hovered_tile_pane);
+                        let right_pane = panes_tree.tiles.insert_pane(Pane::default());
+                        panes_tree.tiles.insert(
+                            hovered_tile,
+                            Tile::Container(Container::Linear(Linear::new_binary(
+                                LinearDir::Horizontal,
+                                [left_pane, right_pane],
+                                0.5,
+                            ))),
+                        );
+                    }
                 }
                 PaneAction::SplitV => {
-                    let hovered_tile_pane = panes_tree.tiles.remove(hovered_tile).unwrap();
-                    let replaced = panes_tree.tiles.insert_new(hovered_tile_pane);
-                    let lower_pane = panes_tree.tiles.insert_pane(Pane::default());
-                    panes_tree.tiles.insert(
-                        hovered_tile,
-                        Tile::Container(Container::Linear(Linear::new_binary(
-                            LinearDir::Vertical,
-                            [replaced, lower_pane],
-                            0.5,
-                        ))),
-                    );
+                    if self.maximized_pane.is_none() {
+                        let hovered_tile_pane = panes_tree.tiles.remove(hovered_tile).unwrap();
+                        let replaced = panes_tree.tiles.insert_new(hovered_tile_pane);
+                        let lower_pane = panes_tree.tiles.insert_pane(Pane::default());
+                        panes_tree.tiles.insert(
+                            hovered_tile,
+                            Tile::Container(Container::Linear(Linear::new_binary(
+                                LinearDir::Vertical,
+                                [replaced, lower_pane],
+                                0.5,
+                            ))),
+                        );
+                    }
                 }
                 PaneAction::Close => {
                     // Ignore if the root pane is the only one
-                    if panes_tree.tiles.len() != 1 {
+                    if panes_tree.tiles.len() != 1 && self.maximized_pane.is_none() {
                         panes_tree.remove_recursively(hovered_tile);
                     }
                 }
                 PaneAction::Replace(new_pane) => {
                     panes_tree.tiles.insert(hovered_tile, Tile::Pane(*new_pane));
                 }
+                PaneAction::Maximize => {
+                    // This is a toggle: if there is not currently a maximized pane,
+                    // maximize the hovered pane, otherwize remove the maximized pane.
+                    if self.maximized_pane.is_some() {
+                        self.maximized_pane = None;
+                    } else {
+                        let hovered_pane_is_default = panes_tree
+                            .tiles
+                            .get(hovered_tile)
+                            .map(|hovered_pane| match hovered_pane {
+                                Tile::Pane(Pane {
+                                    pane: PaneKind::Default(_),
+                                }) => true,
+                                _ => false,
+                            })
+                            .unwrap_or(false);
+                        if !hovered_pane_is_default {
+                            self.maximized_pane = Some(hovered_tile);
+                        }
+                    }
+                }
+                PaneAction::Exit => {
+                    if self.maximized_pane.is_some() {
+                        self.maximized_pane = None;
+                    }
+                }
             }
         }
 
@@ -98,12 +132,25 @@ impl eframe::App for ComposableView {
                 if ui.button("Layout Manager").clicked() {
                     self.layout_manager.toggle_open_state();
                 }
+
+                // If a pane is maximized show a visual clue
+                if self.maximized_pane.is_some() {
+                    ui.label("Pane Maximized!");
+                }
             })
         });
 
         // A central panel covers the remainder of the screen, i.e. whatever area is left after adding other panels.
         egui::CentralPanel::default().show(ctx, |ui| {
-            panes_tree.ui(&mut self.behavior, ui);
+            if let Some(maximized_pane) = self.maximized_pane {
+                if let Some(Tile::Pane(pane)) = panes_tree.tiles.get_mut(maximized_pane) {
+                    maximized_pane_ui(ui, pane);
+                } else {
+                    panic!("Maximized pane not found in tree!");
+                }
+            } else {
+                panes_tree.ui(&mut self.behavior, ui);
+            }
         });
 
         LayoutManager::show(self, ctx);
@@ -246,4 +293,6 @@ pub enum PaneAction {
     SplitV,
     Close,
     Replace(Box<Pane>),
+    Maximize,
+    Exit,
 }
diff --git a/src/ui/utils.rs b/src/ui/utils.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b9f510bda78fab7513f25defa33d1377ffdd6cd7
--- /dev/null
+++ b/src/ui/utils.rs
@@ -0,0 +1,14 @@
+use egui::containers::Frame;
+use egui::{Shadow, Stroke, Style, Ui};
+
+use super::panes::{Pane, PaneBehavior};
+
+/// This function wraps a ui into a popup frame intended for the pane that needs
+/// to be maximized on screen.
+pub fn maximized_pane_ui(ui: &mut Ui, pane: &mut Pane) {
+    Frame::popup(&Style::default())
+        .fill(egui::Color32::TRANSPARENT)
+        .shadow(Shadow::NONE)
+        .stroke(Stroke::NONE)
+        .show(ui, |ui| pane.ui(ui));
+}