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..16774e910a1651a03a32088e68aac41aef7a0264 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,7 @@ 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),
             ];
             pane_action = pane_action.or(shortcuts::map_to_action(ctx, &key_action_pairs[..])
                 .map(|action| (action, hovered_pane)));
@@ -87,6 +90,27 @@ impl eframe::App for ComposableView {
                 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);
+                        }
+                    }
+                }
             }
         }
 
@@ -103,7 +127,15 @@ impl eframe::App for ComposableView {
 
         // 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 +278,5 @@ pub enum PaneAction {
     SplitV,
     Close,
     Replace(Box<Pane>),
+    Maximize,
 }
diff --git a/src/ui/utils.rs b/src/ui/utils.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e9121eedef63af0d73069a8befb728255e042fa2
--- /dev/null
+++ b/src/ui/utils.rs
@@ -0,0 +1,13 @@
+use egui::containers::Frame;
+use egui::{Shadow, 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)
+        .show(ui, |ui| pane.ui(ui));
+}