From dcc184b01b753dbecb500205391f6eaaa21c8683 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector@hecrj.dev>
Date: Fri, 25 Oct 2024 19:28:18 +0200
Subject: Replace `event::Status` in `Widget::on_event` with
 `Shell::capture_event`

---
 core/src/element.rs                       |  15 ++-
 core/src/overlay.rs                       |   6 +-
 core/src/overlay/element.rs               |  13 +--
 core/src/overlay/group.rs                 |  27 +++---
 core/src/shell.rs                         |  23 +++++
 core/src/widget.rs                        |   6 +-
 examples/loading_spinners/src/circular.rs |   5 +-
 examples/loading_spinners/src/linear.rs   |   5 +-
 examples/toast/src/main.rs                |  53 +++++-----
 runtime/src/overlay/nested.rs             |  74 +++++++-------
 runtime/src/user_interface.rs             |  10 +-
 widget/src/button.rs                      |  79 +++++++--------
 widget/src/canvas.rs                      |   8 +-
 widget/src/checkbox.rs                    |  11 +--
 widget/src/column.rs                      |  35 ++++---
 widget/src/combo_box.rs                   |  24 ++---
 widget/src/container.rs                   |   7 +-
 widget/src/helpers.rs                     |  38 +++-----
 widget/src/image/viewer.rs                |  30 +++---
 widget/src/keyed/column.rs                |  35 ++++---
 widget/src/lazy.rs                        |  18 ++--
 widget/src/lazy/component.rs              |  43 ++++----
 widget/src/lazy/responsive.rs             |  31 ++----
 widget/src/mouse_area.rs                  | 156 ++++++++++++------------------
 widget/src/overlay/menu.rs                |  17 ++--
 widget/src/pane_grid.rs                   |  49 +++++-----
 widget/src/pane_grid/content.rs           |  20 ++--
 widget/src/pane_grid/title_bar.rs         |  30 +++---
 widget/src/pick_list.rs                   |  25 ++---
 widget/src/radio.rs                       |  12 +--
 widget/src/row.rs                         |  37 ++++---
 widget/src/scrollable.rs                  |  62 ++++++------
 widget/src/shader.rs                      |  16 +--
 widget/src/shader/event.rs                |   2 -
 widget/src/shader/program.rs              |   4 +-
 widget/src/slider.rs                      |  23 ++---
 widget/src/stack.rs                       |  53 +++++-----
 widget/src/text/rich.rs                   |  18 ++--
 widget/src/text_editor.rs                 |  13 ++-
 widget/src/text_input.rs                  |  66 ++++++-------
 widget/src/themer.rs                      |  16 +--
 widget/src/toggler.rs                     |  18 ++--
 widget/src/tooltip.rs                     |   9 +-
 widget/src/vertical_slider.rs             |  19 ++--
 44 files changed, 556 insertions(+), 705 deletions(-)

diff --git a/core/src/element.rs b/core/src/element.rs
index 6ebb8a15..8276b70c 100644
--- a/core/src/element.rs
+++ b/core/src/element.rs
@@ -1,4 +1,3 @@
-use crate::event::{self, Event};
 use crate::layout;
 use crate::mouse;
 use crate::overlay;
@@ -6,8 +5,8 @@ use crate::renderer;
 use crate::widget;
 use crate::widget::tree::{self, Tree};
 use crate::{
-    Border, Clipboard, Color, Layout, Length, Rectangle, Shell, Size, Vector,
-    Widget,
+    Border, Clipboard, Color, Event, Layout, Length, Rectangle, Shell, Size,
+    Vector, Widget,
 };
 
 use std::borrow::Borrow;
@@ -319,11 +318,11 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, B>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let mut local_messages = Vec::new();
         let mut local_shell = Shell::new(&mut local_messages);
 
-        let status = self.widget.on_event(
+        self.widget.on_event(
             tree,
             event,
             layout,
@@ -335,8 +334,6 @@ where
         );
 
         shell.merge(local_shell, &self.mapper);
-
-        status
     }
 
     fn draw(
@@ -457,10 +454,10 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         self.element.widget.on_event(
             state, event, layout, cursor, renderer, clipboard, shell, viewport,
-        )
+        );
     }
 
     fn draw(
diff --git a/core/src/overlay.rs b/core/src/overlay.rs
index f09de831..e063bb94 100644
--- a/core/src/overlay.rs
+++ b/core/src/overlay.rs
@@ -5,13 +5,12 @@ mod group;
 pub use element::Element;
 pub use group::Group;
 
-use crate::event::{self, Event};
 use crate::layout;
 use crate::mouse;
 use crate::renderer;
 use crate::widget;
 use crate::widget::Tree;
-use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector};
+use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size, Vector};
 
 /// An interactive component that can be displayed on top of other widgets.
 pub trait Overlay<Message, Theme, Renderer>
@@ -65,8 +64,7 @@ where
         _renderer: &Renderer,
         _clipboard: &mut dyn Clipboard,
         _shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
-        event::Status::Ignored
+    ) {
     }
 
     /// Returns the current [`mouse::Interaction`] of the [`Overlay`].
diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs
index 32e987a3..4a242213 100644
--- a/core/src/overlay/element.rs
+++ b/core/src/overlay/element.rs
@@ -1,11 +1,10 @@
 pub use crate::Overlay;
 
-use crate::event::{self, Event};
 use crate::layout;
 use crate::mouse;
 use crate::renderer;
 use crate::widget;
-use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size};
+use crate::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size};
 
 /// A generic [`Overlay`].
 #[allow(missing_debug_implementations)]
@@ -58,9 +57,9 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
+    ) {
         self.overlay
-            .on_event(event, layout, cursor, renderer, clipboard, shell)
+            .on_event(event, layout, cursor, renderer, clipboard, shell);
     }
 
     /// Returns the current [`mouse::Interaction`] of the [`Element`].
@@ -157,11 +156,11 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, B>,
-    ) -> event::Status {
+    ) {
         let mut local_messages = Vec::new();
         let mut local_shell = Shell::new(&mut local_messages);
 
-        let event_status = self.content.on_event(
+        self.content.on_event(
             event,
             layout,
             cursor,
@@ -171,8 +170,6 @@ where
         );
 
         shell.merge(local_shell, self.mapper);
-
-        event_status
     }
 
     fn mouse_interaction(
diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs
index 6541d311..11ebd579 100644
--- a/core/src/overlay/group.rs
+++ b/core/src/overlay/group.rs
@@ -1,4 +1,3 @@
-use crate::event;
 use crate::layout;
 use crate::mouse;
 use crate::overlay;
@@ -81,21 +80,17 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
-        self.children
-            .iter_mut()
-            .zip(layout.children())
-            .map(|(child, layout)| {
-                child.on_event(
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                )
-            })
-            .fold(event::Status::Ignored, event::Status::merge)
+    ) {
+        for (child, layout) in self.children.iter_mut().zip(layout.children()) {
+            child.on_event(
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+            );
+        }
     }
 
     fn draw(
diff --git a/core/src/shell.rs b/core/src/shell.rs
index 7a92a2be..12ebbaa8 100644
--- a/core/src/shell.rs
+++ b/core/src/shell.rs
@@ -1,3 +1,4 @@
+use crate::event;
 use crate::time::Instant;
 use crate::window;
 
@@ -10,6 +11,7 @@ use crate::window;
 #[derive(Debug)]
 pub struct Shell<'a, Message> {
     messages: &'a mut Vec<Message>,
+    event_status: event::Status,
     redraw_request: Option<window::RedrawRequest>,
     is_layout_invalid: bool,
     are_widgets_invalid: bool,
@@ -20,6 +22,7 @@ impl<'a, Message> Shell<'a, Message> {
     pub fn new(messages: &'a mut Vec<Message>) -> Self {
         Self {
             messages,
+            event_status: event::Status::Ignored,
             redraw_request: None,
             is_layout_invalid: false,
             are_widgets_invalid: false,
@@ -36,6 +39,24 @@ impl<'a, Message> Shell<'a, Message> {
         self.messages.push(message);
     }
 
+    /// Marks the current event as captured. Prevents "event bubbling".
+    ///
+    /// A widget should capture an event when no ancestor should
+    /// handle it.
+    pub fn capture_event(&mut self) {
+        self.event_status = event::Status::Captured;
+    }
+
+    /// Returns the current [`event::Status`] of the [`Shell`].
+    pub fn event_status(&self) -> event::Status {
+        self.event_status
+    }
+
+    /// Returns whether the current event has been captured.
+    pub fn is_event_captured(&self) -> bool {
+        self.event_status == event::Status::Captured
+    }
+
     /// Requests a new frame to be drawn as soon as possible.
     pub fn request_redraw(&mut self) {
         self.redraw_request = Some(window::RedrawRequest::NextFrame);
@@ -114,5 +135,7 @@ impl<'a, Message> Shell<'a, Message> {
 
         self.are_widgets_invalid =
             self.are_widgets_invalid || other.are_widgets_invalid;
+
+        self.event_status = self.event_status.merge(other.event_status);
     }
 }
diff --git a/core/src/widget.rs b/core/src/widget.rs
index 9cfff83d..bddf99cc 100644
--- a/core/src/widget.rs
+++ b/core/src/widget.rs
@@ -10,12 +10,11 @@ pub use operation::Operation;
 pub use text::Text;
 pub use tree::Tree;
 
-use crate::event::{self, Event};
 use crate::layout::{self, Layout};
 use crate::mouse;
 use crate::overlay;
 use crate::renderer;
-use crate::{Clipboard, Length, Rectangle, Shell, Size, Vector};
+use crate::{Clipboard, Event, Length, Rectangle, Shell, Size, Vector};
 
 /// A component that displays information and allows interaction.
 ///
@@ -122,8 +121,7 @@ where
         _clipboard: &mut dyn Clipboard,
         _shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
-        event::Status::Ignored
+    ) {
     }
 
     /// Returns the current [`mouse::Interaction`] of the [`Widget`].
diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs
index 954a777e..e6b59cae 100644
--- a/examples/loading_spinners/src/circular.rs
+++ b/examples/loading_spinners/src/circular.rs
@@ -3,7 +3,6 @@ use iced::advanced::layout;
 use iced::advanced::renderer;
 use iced::advanced::widget::tree::{self, Tree};
 use iced::advanced::{self, Clipboard, Layout, Shell, Widget};
-use iced::event;
 use iced::mouse;
 use iced::time::Instant;
 use iced::widget::canvas;
@@ -272,7 +271,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
 
         if let Event::Window(window::Event::RedrawRequested(now)) = event {
@@ -285,8 +284,6 @@ where
             state.cache.clear();
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn draw(
diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs
index 81edde75..34576261 100644
--- a/examples/loading_spinners/src/linear.rs
+++ b/examples/loading_spinners/src/linear.rs
@@ -3,7 +3,6 @@ use iced::advanced::layout;
 use iced::advanced::renderer::{self, Quad};
 use iced::advanced::widget::tree::{self, Tree};
 use iced::advanced::{self, Clipboard, Layout, Shell, Widget};
-use iced::event;
 use iced::mouse;
 use iced::time::Instant;
 use iced::window;
@@ -186,7 +185,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
 
         if let Event::Window(window::Event::RedrawRequested(now)) = event {
@@ -194,8 +193,6 @@ where
 
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn draw(
diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs
index 0b46c74e..079b96b4 100644
--- a/examples/toast/src/main.rs
+++ b/examples/toast/src/main.rs
@@ -169,7 +169,6 @@ mod toast {
     use iced::advanced::renderer;
     use iced::advanced::widget::{self, Operation, Tree};
     use iced::advanced::{Clipboard, Shell, Widget};
-    use iced::event::{self, Event};
     use iced::mouse;
     use iced::theme;
     use iced::widget::{
@@ -177,8 +176,8 @@ mod toast {
     };
     use iced::window;
     use iced::{
-        Alignment, Center, Element, Fill, Length, Point, Rectangle, Renderer,
-        Size, Theme, Vector,
+        Alignment, Center, Element, Event, Fill, Length, Point, Rectangle,
+        Renderer, Size, Theme, Vector,
     };
 
     pub const DEFAULT_TIMEOUT: u64 = 5;
@@ -369,7 +368,7 @@ mod toast {
             clipboard: &mut dyn Clipboard,
             shell: &mut Shell<'_, Message>,
             viewport: &Rectangle,
-        ) -> event::Status {
+        ) {
             self.content.as_widget_mut().on_event(
                 &mut state.children[0],
                 event,
@@ -379,7 +378,7 @@ mod toast {
                 clipboard,
                 shell,
                 viewport,
-            )
+            );
         }
 
         fn draw(
@@ -498,7 +497,7 @@ mod toast {
             renderer: &Renderer,
             clipboard: &mut dyn Clipboard,
             shell: &mut Shell<'_, Message>,
-        ) -> event::Status {
+        ) {
             if let Event::Window(window::Event::RedrawRequested(now)) = &event {
                 self.instants.iter_mut().enumerate().for_each(
                     |(index, maybe_instant)| {
@@ -520,35 +519,33 @@ mod toast {
 
             let viewport = layout.bounds();
 
-            self.toasts
+            for (((child, state), layout), instant) in self
+                .toasts
                 .iter_mut()
                 .zip(self.state.iter_mut())
                 .zip(layout.children())
                 .zip(self.instants.iter_mut())
-                .map(|(((child, state), layout), instant)| {
-                    let mut local_messages = vec![];
-                    let mut local_shell = Shell::new(&mut local_messages);
-
-                    let status = child.as_widget_mut().on_event(
-                        state,
-                        event.clone(),
-                        layout,
-                        cursor,
-                        renderer,
-                        clipboard,
-                        &mut local_shell,
-                        &viewport,
-                    );
+            {
+                let mut local_messages = vec![];
+                let mut local_shell = Shell::new(&mut local_messages);
 
-                    if !local_shell.is_empty() {
-                        instant.take();
-                    }
+                child.as_widget_mut().on_event(
+                    state,
+                    event.clone(),
+                    layout,
+                    cursor,
+                    renderer,
+                    clipboard,
+                    &mut local_shell,
+                    &viewport,
+                );
 
-                    shell.merge(local_shell, std::convert::identity);
+                if !local_shell.is_empty() {
+                    instant.take();
+                }
 
-                    status
-                })
-                .fold(event::Status::Ignored, event::Status::merge)
+                shell.merge(local_shell, std::convert::identity);
+            }
         }
 
         fn draw(
diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs
index da3e6929..45f6b220 100644
--- a/runtime/src/overlay/nested.rs
+++ b/runtime/src/overlay/nested.rs
@@ -166,7 +166,7 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
+    ) {
         fn recurse<Message, Theme, Renderer>(
             element: &mut overlay::Element<'_, Message, Theme, Renderer>,
             layout: Layout<'_>,
@@ -175,31 +175,30 @@ where
             renderer: &Renderer,
             clipboard: &mut dyn Clipboard,
             shell: &mut Shell<'_, Message>,
-        ) -> (event::Status, bool)
+        ) -> bool
         where
             Renderer: renderer::Renderer,
         {
             let mut layouts = layout.children();
 
             if let Some(layout) = layouts.next() {
-                let (nested_status, nested_is_over) =
-                    if let Some((mut nested, nested_layout)) =
-                        element.overlay(layout, renderer).zip(layouts.next())
-                    {
-                        recurse(
-                            &mut nested,
-                            nested_layout,
-                            event.clone(),
-                            cursor,
-                            renderer,
-                            clipboard,
-                            shell,
-                        )
-                    } else {
-                        (event::Status::Ignored, false)
-                    };
+                let nested_is_over = if let Some((mut nested, nested_layout)) =
+                    element.overlay(layout, renderer).zip(layouts.next())
+                {
+                    recurse(
+                        &mut nested,
+                        nested_layout,
+                        event.clone(),
+                        cursor,
+                        renderer,
+                        clipboard,
+                        shell,
+                    )
+                } else {
+                    false
+                };
 
-                if matches!(nested_status, event::Status::Ignored) {
+                if shell.event_status() == event::Status::Ignored {
                     let is_over = nested_is_over
                         || cursor
                             .position()
@@ -212,30 +211,29 @@ where
                             })
                             .unwrap_or_default();
 
-                    (
-                        element.on_event(
-                            event,
-                            layout,
-                            if nested_is_over {
-                                mouse::Cursor::Unavailable
-                            } else {
-                                cursor
-                            },
-                            renderer,
-                            clipboard,
-                            shell,
-                        ),
-                        is_over,
-                    )
+                    element.on_event(
+                        event,
+                        layout,
+                        if nested_is_over {
+                            mouse::Cursor::Unavailable
+                        } else {
+                            cursor
+                        },
+                        renderer,
+                        clipboard,
+                        shell,
+                    );
+
+                    is_over
                 } else {
-                    (nested_status, nested_is_over)
+                    nested_is_over
                 }
             } else {
-                (event::Status::Ignored, false)
+                false
             }
         }
 
-        let (status, _) = recurse(
+        let _ = recurse(
             &mut self.overlay,
             layout,
             event,
@@ -244,8 +242,6 @@ where
             clipboard,
             shell,
         );
-
-        status
     }
 
     /// Returns the current [`mouse::Interaction`] of the [`Nested`] overlay.
diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs
index 8dfc97a7..cae17bcc 100644
--- a/runtime/src/user_interface.rs
+++ b/runtime/src/user_interface.rs
@@ -210,7 +210,7 @@ where
             for event in events.iter().cloned() {
                 let mut shell = Shell::new(messages);
 
-                let event_status = overlay.on_event(
+                overlay.on_event(
                     event,
                     Layout::new(&layout),
                     cursor,
@@ -219,7 +219,7 @@ where
                     &mut shell,
                 );
 
-                event_statuses.push(event_status);
+                event_statuses.push(shell.event_status());
 
                 match (redraw_request, shell.redraw_request()) {
                     (None, Some(at)) => {
@@ -308,7 +308,7 @@ where
 
                 let mut shell = Shell::new(messages);
 
-                let event_status = self.root.as_widget_mut().on_event(
+                self.root.as_widget_mut().on_event(
                     &mut self.state,
                     event,
                     Layout::new(&self.base),
@@ -319,7 +319,7 @@ where
                     &viewport,
                 );
 
-                if matches!(event_status, event::Status::Captured) {
+                if shell.event_status() == event::Status::Captured {
                     self.overlay = None;
                 }
 
@@ -347,7 +347,7 @@ where
                     outdated = true;
                 }
 
-                event_status.merge(overlay_status)
+                shell.event_status().merge(overlay_status)
             })
             .collect();
 
diff --git a/widget/src/button.rs b/widget/src/button.rs
index 46fd0e17..6be17f59 100644
--- a/widget/src/button.rs
+++ b/widget/src/button.rs
@@ -283,8 +283,8 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        if let event::Status::Captured = self.content.as_widget_mut().on_event(
+    ) {
+        self.content.as_widget_mut().on_event(
             &mut tree.children[0],
             event.clone(),
             layout.children().next().unwrap(),
@@ -293,62 +293,53 @@ where
             clipboard,
             shell,
             viewport,
-        ) {
-            return event::Status::Captured;
+        );
+
+        if shell.event_status() == event::Status::Captured {
+            return;
         }
 
-        let mut update = || {
-            match event {
-                Event::Mouse(mouse::Event::ButtonPressed(
-                    mouse::Button::Left,
-                ))
-                | Event::Touch(touch::Event::FingerPressed { .. }) => {
-                    if self.on_press.is_some() {
-                        let bounds = layout.bounds();
+        match event {
+            Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
+            | Event::Touch(touch::Event::FingerPressed { .. }) => {
+                if self.on_press.is_some() {
+                    let bounds = layout.bounds();
 
-                        if cursor.is_over(bounds) {
-                            let state = tree.state.downcast_mut::<State>();
+                    if cursor.is_over(bounds) {
+                        let state = tree.state.downcast_mut::<State>();
 
-                            state.is_pressed = true;
+                        state.is_pressed = true;
 
-                            return event::Status::Captured;
-                        }
+                        shell.capture_event();
                     }
                 }
-                Event::Mouse(mouse::Event::ButtonReleased(
-                    mouse::Button::Left,
-                ))
-                | Event::Touch(touch::Event::FingerLifted { .. }) => {
-                    if let Some(on_press) =
-                        self.on_press.as_ref().map(OnPress::get)
-                    {
-                        let state = tree.state.downcast_mut::<State>();
-
-                        if state.is_pressed {
-                            state.is_pressed = false;
+            }
+            Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
+            | Event::Touch(touch::Event::FingerLifted { .. }) => {
+                if let Some(on_press) = self.on_press.as_ref().map(OnPress::get)
+                {
+                    let state = tree.state.downcast_mut::<State>();
 
-                            let bounds = layout.bounds();
+                    if state.is_pressed {
+                        state.is_pressed = false;
 
-                            if cursor.is_over(bounds) {
-                                shell.publish(on_press);
-                            }
+                        let bounds = layout.bounds();
 
-                            return event::Status::Captured;
+                        if cursor.is_over(bounds) {
+                            shell.publish(on_press);
                         }
-                    }
-                }
-                Event::Touch(touch::Event::FingerLost { .. }) => {
-                    let state = tree.state.downcast_mut::<State>();
 
-                    state.is_pressed = false;
+                        shell.capture_event();
+                    }
                 }
-                _ => {}
             }
+            Event::Touch(touch::Event::FingerLost { .. }) => {
+                let state = tree.state.downcast_mut::<State>();
 
-            event::Status::Ignored
-        };
-
-        let update_status = update();
+                state.is_pressed = false;
+            }
+            _ => {}
+        }
 
         let current_status = if self.on_press.is_none() {
             Status::Disabled
@@ -369,8 +360,6 @@ where
         } else if self.status.is_some_and(|status| status != current_status) {
             shell.request_redraw();
         }
-
-        update_status
     }
 
     fn draw(
diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs
index 9fbccf82..a9c65bb6 100644
--- a/widget/src/canvas.rs
+++ b/widget/src/canvas.rs
@@ -223,7 +223,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let bounds = layout.bounds();
 
         let canvas_event = match event {
@@ -245,10 +245,10 @@ where
                 shell.publish(message);
             }
 
-            return event_status;
+            if event_status == event::Status::Captured {
+                shell.capture_event();
+            }
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs
index 6c5d7d6b..9b5f3602 100644
--- a/widget/src/checkbox.rs
+++ b/widget/src/checkbox.rs
@@ -31,7 +31,6 @@
 //! ```
 //! ![Checkbox drawn by `iced_wgpu`](https://github.com/iced-rs/iced/blob/7760618fb112074bc40b148944521f312152012a/docs/images/checkbox.png?raw=true)
 use crate::core::alignment;
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::renderer;
@@ -42,8 +41,8 @@ use crate::core::widget;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    Background, Border, Clipboard, Color, Element, Layout, Length, Pixels,
-    Rectangle, Shell, Size, Theme, Widget,
+    Background, Border, Clipboard, Color, Element, Event, Layout, Length,
+    Pixels, Rectangle, Shell, Size, Theme, Widget,
 };
 
 /// A box that can be checked.
@@ -313,7 +312,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
             | Event::Touch(touch::Event::FingerPressed { .. }) => {
@@ -322,7 +321,7 @@ where
                 if mouse_over {
                     if let Some(on_toggle) = &self.on_toggle {
                         shell.publish((on_toggle)(!self.is_checked));
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
             }
@@ -351,8 +350,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
diff --git a/widget/src/column.rs b/widget/src/column.rs
index 213f68fc..3fdc17f8 100644
--- a/widget/src/column.rs
+++ b/widget/src/column.rs
@@ -1,14 +1,13 @@
 //! Distribute content vertically.
 use crate::core::alignment::{self, Alignment};
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
 use crate::core::renderer;
 use crate::core::widget::{Operation, Tree};
 use crate::core::{
-    Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Shell,
-    Size, Vector, Widget,
+    Clipboard, Element, Event, Layout, Length, Padding, Pixels, Rectangle,
+    Shell, Size, Vector, Widget,
 };
 
 /// A container that distributes its contents vertically.
@@ -268,24 +267,24 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        self.children
+    ) {
+        for ((child, state), layout) in self
+            .children
             .iter_mut()
             .zip(&mut tree.children)
             .zip(layout.children())
-            .map(|((child, state), layout)| {
-                child.as_widget_mut().on_event(
-                    state,
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                    viewport,
-                )
-            })
-            .fold(event::Status::Ignored, event::Status::merge)
+        {
+            child.as_widget_mut().on_event(
+                state,
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+                viewport,
+            );
+        }
     }
 
     fn mouse_interaction(
diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs
index e300f1d0..1122861f 100644
--- a/widget/src/combo_box.rs
+++ b/widget/src/combo_box.rs
@@ -54,7 +54,7 @@
 //!     }
 //! }
 //! ```
-use crate::core::event::{self, Event};
+use crate::core::event;
 use crate::core::keyboard;
 use crate::core::keyboard::key;
 use crate::core::layout::{self, Layout};
@@ -65,7 +65,8 @@ use crate::core::text;
 use crate::core::time::Instant;
 use crate::core::widget::{self, Widget};
 use crate::core::{
-    Clipboard, Element, Length, Padding, Rectangle, Shell, Size, Theme, Vector,
+    Clipboard, Element, Event, Length, Padding, Rectangle, Shell, Size, Theme,
+    Vector,
 };
 use crate::overlay::menu;
 use crate::text::LineHeight;
@@ -519,7 +520,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let menu = tree.state.downcast_mut::<Menu<T>>();
 
         let started_focused = {
@@ -538,7 +539,7 @@ where
         let mut local_shell = Shell::new(&mut local_messages);
 
         // Provide it to the widget
-        let mut event_status = self.text_input.on_event(
+        self.text_input.on_event(
             &mut tree.children[0],
             event.clone(),
             layout,
@@ -549,13 +550,16 @@ where
             viewport,
         );
 
+        if local_shell.event_status() == event::Status::Captured {
+            shell.capture_event();
+        }
+
         // Then finally react to them here
         for message in local_messages {
             let TextInputEvent::TextChanged(new_value) = message;
 
             if let Some(on_input) = &self.on_input {
                 shell.publish((on_input)(new_value.clone()));
-                published_message_to_shell = true;
             }
 
             // Couple the filtered options with the `ComboBox`
@@ -619,7 +623,7 @@ where
                                 }
                             }
 
-                            event_status = event::Status::Captured;
+                            shell.capture_event();
                         }
 
                         (key::Named::ArrowUp, _) | (key::Named::Tab, true) => {
@@ -656,7 +660,7 @@ where
                                 }
                             }
 
-                            event_status = event::Status::Captured;
+                            shell.capture_event();
                         }
                         (key::Named::ArrowDown, _)
                         | (key::Named::Tab, false)
@@ -703,7 +707,7 @@ where
                                 }
                             }
 
-                            event_status = event::Status::Captured;
+                            shell.capture_event();
                         }
                         _ => {}
                     }
@@ -724,7 +728,7 @@ where
                 published_message_to_shell = true;
 
                 // Unfocus the input
-                let _ = self.text_input.on_event(
+                self.text_input.on_event(
                     &mut tree.children[0],
                     Event::Mouse(mouse::Event::ButtonPressed(
                         mouse::Button::Left,
@@ -761,8 +765,6 @@ where
                 }
             }
         }
-
-        event_status
     }
 
     fn mouse_interaction(
diff --git a/widget/src/container.rs b/widget/src/container.rs
index f4993ac9..f96c495c 100644
--- a/widget/src/container.rs
+++ b/widget/src/container.rs
@@ -21,7 +21,6 @@
 //! ```
 use crate::core::alignment::{self, Alignment};
 use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
 use crate::core::gradient::{self, Gradient};
 use crate::core::layout;
 use crate::core::mouse;
@@ -30,7 +29,7 @@ use crate::core::renderer;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::widget::{self, Operation};
 use crate::core::{
-    self, color, Background, Clipboard, Color, Element, Layout, Length,
+    self, color, Background, Clipboard, Color, Element, Event, Layout, Length,
     Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector,
     Widget,
 };
@@ -308,7 +307,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         self.content.as_widget_mut().on_event(
             tree,
             event,
@@ -318,7 +317,7 @@ where
             clipboard,
             shell,
             viewport,
-        )
+        );
     }
 
     fn mouse_interaction(
diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs
index 52290a54..13d69e1f 100644
--- a/widget/src/helpers.rs
+++ b/widget/src/helpers.rs
@@ -363,12 +363,11 @@ where
     Theme: 'a,
     Renderer: core::Renderer + 'a,
 {
-    use crate::core::event::{self, Event};
     use crate::core::layout::{self, Layout};
     use crate::core::mouse;
     use crate::core::renderer;
     use crate::core::widget::tree::{self, Tree};
-    use crate::core::{Rectangle, Shell, Size};
+    use crate::core::{Event, Rectangle, Shell, Size};
 
     struct Opaque<'a, Message, Theme, Renderer> {
         content: Element<'a, Message, Theme, Renderer>,
@@ -449,25 +448,19 @@ where
             clipboard: &mut dyn core::Clipboard,
             shell: &mut Shell<'_, Message>,
             viewport: &Rectangle,
-        ) -> event::Status {
+        ) {
             let is_mouse_press = matches!(
                 event,
                 core::Event::Mouse(mouse::Event::ButtonPressed(_))
             );
 
-            if let core::event::Status::Captured =
-                self.content.as_widget_mut().on_event(
-                    state, event, layout, cursor, renderer, clipboard, shell,
-                    viewport,
-                )
-            {
-                return event::Status::Captured;
-            }
+            self.content.as_widget_mut().on_event(
+                state, event, layout, cursor, renderer, clipboard, shell,
+                viewport,
+            );
 
             if is_mouse_press && cursor.is_over(layout.bounds()) {
-                event::Status::Captured
-            } else {
-                event::Status::Ignored
+                shell.capture_event();
             }
         }
 
@@ -530,12 +523,11 @@ where
     Theme: 'a,
     Renderer: core::Renderer + 'a,
 {
-    use crate::core::event::{self, Event};
     use crate::core::layout::{self, Layout};
     use crate::core::mouse;
     use crate::core::renderer;
     use crate::core::widget::tree::{self, Tree};
-    use crate::core::{Rectangle, Shell, Size};
+    use crate::core::{Event, Rectangle, Shell, Size};
 
     struct Hover<'a, Message, Theme, Renderer> {
         base: Element<'a, Message, Theme, Renderer>,
@@ -658,7 +650,7 @@ where
             clipboard: &mut dyn core::Clipboard,
             shell: &mut Shell<'_, Message>,
             viewport: &Rectangle,
-        ) -> event::Status {
+        ) {
             let mut children = layout.children().zip(&mut tree.children);
             let (base_layout, base_tree) = children.next().unwrap();
             let (top_layout, top_tree) = children.next().unwrap();
@@ -680,7 +672,7 @@ where
                 };
             }
 
-            let top_status = if matches!(
+            if matches!(
                 event,
                 Event::Mouse(
                     mouse::Event::CursorMoved { .. }
@@ -699,13 +691,11 @@ where
                     clipboard,
                     shell,
                     viewport,
-                )
-            } else {
-                event::Status::Ignored
+                );
             };
 
-            if top_status == event::Status::Captured {
-                return top_status;
+            if shell.is_event_captured() {
+                return;
             }
 
             self.base.as_widget_mut().on_event(
@@ -717,7 +707,7 @@ where
                 clipboard,
                 shell,
                 viewport,
-            )
+            );
         }
 
         fn mouse_interaction(
diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs
index b1aad22c..5787200b 100644
--- a/widget/src/image/viewer.rs
+++ b/widget/src/image/viewer.rs
@@ -1,13 +1,12 @@
 //! Zoom and pan on an image.
-use crate::core::event::{self, Event};
 use crate::core::image::{self, FilterMethod};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::renderer;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::{
-    Clipboard, ContentFit, Element, Image, Layout, Length, Pixels, Point,
-    Radians, Rectangle, Shell, Size, Vector, Widget,
+    Clipboard, ContentFit, Element, Event, Image, Layout, Length, Pixels,
+    Point, Radians, Rectangle, Shell, Size, Vector, Widget,
 };
 
 /// A frame that displays an image with the ability to zoom in/out and pan.
@@ -157,15 +156,15 @@ where
         cursor: mouse::Cursor,
         renderer: &Renderer,
         _clipboard: &mut dyn Clipboard,
-        _shell: &mut Shell<'_, Message>,
+        shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let bounds = layout.bounds();
 
         match event {
             Event::Mouse(mouse::Event::WheelScrolled { delta }) => {
                 let Some(cursor_position) = cursor.position_over(bounds) else {
-                    return event::Status::Ignored;
+                    return;
                 };
 
                 match delta {
@@ -216,29 +215,25 @@ where
                     }
                 }
 
-                event::Status::Captured
+                shell.capture_event();
             }
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
                 let Some(cursor_position) = cursor.position_over(bounds) else {
-                    return event::Status::Ignored;
+                    return;
                 };
 
                 let state = tree.state.downcast_mut::<State>();
 
                 state.cursor_grabbed_at = Some(cursor_position);
                 state.starting_offset = state.current_offset;
-
-                event::Status::Captured
+                shell.capture_event();
             }
             Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
                 let state = tree.state.downcast_mut::<State>();
 
                 if state.cursor_grabbed_at.is_some() {
                     state.cursor_grabbed_at = None;
-
-                    event::Status::Captured
-                } else {
-                    event::Status::Ignored
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::CursorMoved { position }) => {
@@ -278,13 +273,10 @@ where
                     };
 
                     state.current_offset = Vector::new(x, y);
-
-                    event::Status::Captured
-                } else {
-                    event::Status::Ignored
+                    shell.capture_event();
                 }
             }
-            _ => event::Status::Ignored,
+            _ => {}
         }
     }
 
diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs
index 5852ede1..1172785a 100644
--- a/widget/src/keyed/column.rs
+++ b/widget/src/keyed/column.rs
@@ -1,5 +1,4 @@
 //! Keyed columns distribute content vertically while keeping continuity.
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
@@ -7,8 +6,8 @@ use crate::core::renderer;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::widget::Operation;
 use crate::core::{
-    Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle,
-    Shell, Size, Vector, Widget,
+    Alignment, Clipboard, Element, Event, Layout, Length, Padding, Pixels,
+    Rectangle, Shell, Size, Vector, Widget,
 };
 
 /// A container that distributes its contents vertically while keeping continuity.
@@ -308,24 +307,24 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        self.children
+    ) {
+        for ((child, state), layout) in self
+            .children
             .iter_mut()
             .zip(&mut tree.children)
             .zip(layout.children())
-            .map(|((child, state), layout)| {
-                child.as_widget_mut().on_event(
-                    state,
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                    viewport,
-                )
-            })
-            .fold(event::Status::Ignored, event::Status::merge)
+        {
+            child.as_widget_mut().on_event(
+                state,
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+                viewport,
+            );
+        }
     }
 
     fn mouse_interaction(
diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs
index 232f254c..4a9a6154 100644
--- a/widget/src/lazy.rs
+++ b/widget/src/lazy.rs
@@ -10,7 +10,6 @@ pub use responsive::Responsive;
 
 mod cache;
 
-use crate::core::event::{self, Event};
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
@@ -19,7 +18,7 @@ use crate::core::widget::tree::{self, Tree};
 use crate::core::widget::{self, Widget};
 use crate::core::Element;
 use crate::core::{
-    self, Clipboard, Length, Point, Rectangle, Shell, Size, Vector,
+    self, Clipboard, Event, Length, Point, Rectangle, Shell, Size, Vector,
 };
 use crate::runtime::overlay::Nested;
 
@@ -206,7 +205,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         self.with_element_mut(|element| {
             element.as_widget_mut().on_event(
                 &mut tree.children[0],
@@ -217,8 +216,8 @@ where
                 clipboard,
                 shell,
                 viewport,
-            )
-        })
+            );
+        });
     }
 
     fn mouse_interaction(
@@ -395,11 +394,10 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
-        self.with_overlay_mut_maybe(|overlay| {
-            overlay.on_event(event, layout, cursor, renderer, clipboard, shell)
-        })
-        .unwrap_or(event::Status::Ignored)
+    ) {
+        let _ = self.with_overlay_mut_maybe(|overlay| {
+            overlay.on_event(event, layout, cursor, renderer, clipboard, shell);
+        });
     }
 
     fn is_over(
diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs
index e45c24ac..062e6f35 100644
--- a/widget/src/lazy/component.rs
+++ b/widget/src/lazy/component.rs
@@ -1,6 +1,5 @@
 //! Build and reuse custom widgets using The Elm Architecture.
 #![allow(deprecated)]
-use crate::core::event;
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
@@ -322,12 +321,12 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let mut local_messages = Vec::new();
         let mut local_shell = Shell::new(&mut local_messages);
 
         let t = tree.state.downcast_mut::<Rc<RefCell<Option<Tree>>>>();
-        let event_status = self.with_element_mut(|element| {
+        self.with_element_mut(|element| {
             element.as_widget_mut().on_event(
                 &mut t.borrow_mut().as_mut().unwrap().children[0],
                 event,
@@ -337,9 +336,13 @@ where
                 clipboard,
                 &mut local_shell,
                 viewport,
-            )
+            );
         });
 
+        if local_shell.is_event_captured() {
+            shell.capture_event();
+        }
+
         local_shell.revalidate_layout(|| shell.invalidate_layout());
 
         if let Some(redraw_request) = local_shell.redraw_request() {
@@ -377,8 +380,6 @@ where
 
             shell.invalidate_layout();
         }
-
-        event_status
     }
 
     fn operate(
@@ -608,22 +609,24 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
+    ) {
         let mut local_messages = Vec::new();
         let mut local_shell = Shell::new(&mut local_messages);
 
-        let event_status = self
-            .with_overlay_mut_maybe(|overlay| {
-                overlay.on_event(
-                    event,
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    &mut local_shell,
-                )
-            })
-            .unwrap_or(event::Status::Ignored);
+        let _ = self.with_overlay_mut_maybe(|overlay| {
+            overlay.on_event(
+                event,
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                &mut local_shell,
+            );
+        });
+
+        if local_shell.is_event_captured() {
+            shell.capture_event();
+        }
 
         local_shell.revalidate_layout(|| shell.invalidate_layout());
 
@@ -673,8 +676,6 @@ where
 
             shell.invalidate_layout();
         }
-
-        event_status
     }
 
     fn is_over(
diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs
index a6c40ab0..c17798a6 100644
--- a/widget/src/lazy/responsive.rs
+++ b/widget/src/lazy/responsive.rs
@@ -1,4 +1,3 @@
-use crate::core::event::{self, Event};
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
@@ -6,8 +5,8 @@ use crate::core::renderer;
 use crate::core::widget;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::{
-    self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector,
-    Widget,
+    self, Clipboard, Element, Event, Length, Point, Rectangle, Shell, Size,
+    Vector, Widget,
 };
 use crate::horizontal_space;
 use crate::runtime::overlay::Nested;
@@ -193,14 +192,14 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
         let mut content = self.content.borrow_mut();
 
         let mut local_messages = vec![];
         let mut local_shell = Shell::new(&mut local_messages);
 
-        let status = content.resolve(
+        content.resolve(
             &mut state.tree.borrow_mut(),
             renderer,
             layout,
@@ -215,7 +214,7 @@ where
                     clipboard,
                     &mut local_shell,
                     viewport,
-                )
+                );
             },
         );
 
@@ -224,8 +223,6 @@ where
         }
 
         shell.merge(local_shell, std::convert::identity);
-
-        status
     }
 
     fn draw(
@@ -425,28 +422,20 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
+    ) {
         let mut is_layout_invalid = false;
 
-        let event_status = self
-            .with_overlay_mut_maybe(|overlay| {
-                let event_status = overlay.on_event(
-                    event, layout, cursor, renderer, clipboard, shell,
-                );
-
-                is_layout_invalid = shell.is_layout_invalid();
+        let _ = self.with_overlay_mut_maybe(|overlay| {
+            overlay.on_event(event, layout, cursor, renderer, clipboard, shell);
 
-                event_status
-            })
-            .unwrap_or(event::Status::Ignored);
+            is_layout_invalid = shell.is_layout_invalid();
+        });
 
         if is_layout_invalid {
             self.with_overlay_mut(|(_overlay, layout)| {
                 **layout = None;
             });
         }
-
-        event_status
     }
 
     fn is_over(
diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs
index c5a37ae3..50188abd 100644
--- a/widget/src/mouse_area.rs
+++ b/widget/src/mouse_area.rs
@@ -1,5 +1,4 @@
 //! A container for capturing mouse events.
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
@@ -7,8 +6,8 @@ use crate::core::renderer;
 use crate::core::touch;
 use crate::core::widget::{tree, Operation, Tree};
 use crate::core::{
-    Clipboard, Element, Layout, Length, Point, Rectangle, Shell, Size, Vector,
-    Widget,
+    Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell, Size,
+    Vector, Widget,
 };
 
 /// Emit messages on mouse events.
@@ -226,8 +225,8 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        if let event::Status::Captured = self.content.as_widget_mut().on_event(
+    ) {
+        self.content.as_widget_mut().on_event(
             &mut tree.children[0],
             event.clone(),
             layout,
@@ -236,11 +235,13 @@ where
             clipboard,
             shell,
             viewport,
-        ) {
-            return event::Status::Captured;
+        );
+
+        if shell.is_event_captured() {
+            return;
         }
 
-        update(self, tree, event, layout, cursor, shell)
+        update(self, tree, event, layout, cursor, shell);
     }
 
     fn mouse_interaction(
@@ -329,7 +330,7 @@ fn update<Message: Clone, Theme, Renderer>(
     layout: Layout<'_>,
     cursor: mouse::Cursor,
     shell: &mut Shell<'_, Message>,
-) -> event::Status {
+) {
     let state: &mut State = tree.state.downcast_mut();
 
     let cursor_position = cursor.position();
@@ -363,104 +364,71 @@ fn update<Message: Clone, Theme, Renderer>(
     }
 
     if !cursor.is_over(layout.bounds()) {
-        return event::Status::Ignored;
+        return;
     }
 
-    if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
-    | Event::Touch(touch::Event::FingerPressed { .. }) = event
-    {
-        let mut captured = false;
-
-        if let Some(message) = widget.on_press.as_ref() {
-            captured = true;
-            shell.publish(message.clone());
-        }
+    match event {
+        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
+        | Event::Touch(touch::Event::FingerPressed { .. }) => {
+            if let Some(message) = widget.on_press.as_ref() {
+                shell.publish(message.clone());
+                shell.capture_event();
+            }
 
-        if let Some(position) = cursor_position {
-            if let Some(message) = widget.on_double_click.as_ref() {
-                let new_click = mouse::Click::new(
-                    position,
-                    mouse::Button::Left,
-                    state.previous_click,
-                );
+            if let Some(position) = cursor_position {
+                if let Some(message) = widget.on_double_click.as_ref() {
+                    let new_click = mouse::Click::new(
+                        position,
+                        mouse::Button::Left,
+                        state.previous_click,
+                    );
 
-                if matches!(new_click.kind(), mouse::click::Kind::Double) {
-                    shell.publish(message.clone());
-                }
+                    if matches!(new_click.kind(), mouse::click::Kind::Double) {
+                        shell.publish(message.clone());
+                    }
 
-                state.previous_click = Some(new_click);
+                    state.previous_click = Some(new_click);
 
-                // Even if this is not a double click, but the press is nevertheless
-                // processed by us and should not be popup to parent widgets.
-                captured = true;
+                    // Even if this is not a double click, but the press is nevertheless
+                    // processed by us and should not be popup to parent widgets.
+                    shell.capture_event();
+                }
             }
         }
-
-        if captured {
-            return event::Status::Captured;
-        }
-    }
-
-    if let Some(message) = widget.on_release.as_ref() {
-        if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
-        | Event::Touch(touch::Event::FingerLifted { .. }) = event
-        {
-            shell.publish(message.clone());
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
+        | Event::Touch(touch::Event::FingerLifted { .. }) => {
+            if let Some(message) = widget.on_release.as_ref() {
+                shell.publish(message.clone());
+            }
         }
-    }
-
-    if let Some(message) = widget.on_right_press.as_ref() {
-        if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) =
-            event
-        {
-            shell.publish(message.clone());
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) => {
+            if let Some(message) = widget.on_right_press.as_ref() {
+                shell.publish(message.clone());
+                shell.capture_event();
+            }
         }
-    }
-
-    if let Some(message) = widget.on_right_release.as_ref() {
-        if let Event::Mouse(mouse::Event::ButtonReleased(
-            mouse::Button::Right,
-        )) = event
-        {
-            shell.publish(message.clone());
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Right)) => {
+            if let Some(message) = widget.on_right_release.as_ref() {
+                shell.publish(message.clone());
+            }
         }
-    }
-
-    if let Some(message) = widget.on_middle_press.as_ref() {
-        if let Event::Mouse(mouse::Event::ButtonPressed(
-            mouse::Button::Middle,
-        )) = event
-        {
-            shell.publish(message.clone());
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Middle)) => {
+            if let Some(message) = widget.on_middle_press.as_ref() {
+                shell.publish(message.clone());
+                shell.capture_event();
+            }
         }
-    }
-
-    if let Some(message) = widget.on_middle_release.as_ref() {
-        if let Event::Mouse(mouse::Event::ButtonReleased(
-            mouse::Button::Middle,
-        )) = event
-        {
-            shell.publish(message.clone());
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Middle)) => {
+            if let Some(message) = widget.on_middle_release.as_ref() {
+                shell.publish(message.clone());
+            }
         }
-    }
-
-    if let Some(on_scroll) = widget.on_scroll.as_ref() {
-        if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event {
-            shell.publish(on_scroll(delta));
-
-            return event::Status::Captured;
+        Event::Mouse(mouse::Event::WheelScrolled { delta }) => {
+            if let Some(on_scroll) = widget.on_scroll.as_ref() {
+                shell.publish(on_scroll(delta));
+                shell.capture_event();
+            }
         }
+        _ => {}
     }
-
-    event::Status::Ignored
 }
diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs
index c1a0a5d8..78ee3da6 100644
--- a/widget/src/overlay/menu.rs
+++ b/widget/src/overlay/menu.rs
@@ -1,7 +1,6 @@
 //! Build and show dropdown menus.
 use crate::core::alignment;
 use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
@@ -11,8 +10,8 @@ use crate::core::touch;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    Background, Clipboard, Color, Length, Padding, Pixels, Point, Rectangle,
-    Size, Theme, Vector,
+    Background, Clipboard, Color, Event, Length, Padding, Pixels, Point,
+    Rectangle, Size, Theme, Vector,
 };
 use crate::core::{Element, Shell, Widget};
 use crate::scrollable::{self, Scrollable};
@@ -271,13 +270,13 @@ where
         renderer: &Renderer,
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
-    ) -> event::Status {
+    ) {
         let bounds = layout.bounds();
 
         self.list.on_event(
             self.state, event, layout, cursor, renderer, clipboard, shell,
             &bounds,
-        )
+        );
     }
 
     fn mouse_interaction(
@@ -397,14 +396,14 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
                 if cursor.is_over(layout.bounds()) {
                     if let Some(index) = *self.hovered_option {
                         if let Some(option) = self.options.get(index) {
                             shell.publish((self.on_selected)(option.clone()));
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                     }
                 }
@@ -460,7 +459,7 @@ where
                     if let Some(index) = *self.hovered_option {
                         if let Some(option) = self.options.get(index) {
                             shell.publish((self.on_selected)(option.clone()));
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                     }
                 }
@@ -477,8 +476,6 @@ where
         }) {
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs
index b4ed4b64..29b7ac87 100644
--- a/widget/src/pane_grid.rs
+++ b/widget/src/pane_grid.rs
@@ -79,7 +79,6 @@ pub use state::State;
 pub use title_bar::TitleBar;
 
 use crate::container;
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay::{self, Group};
@@ -88,7 +87,7 @@ use crate::core::touch;
 use crate::core::widget;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::{
-    self, Background, Border, Clipboard, Color, Element, Layout, Length,
+    self, Background, Border, Clipboard, Color, Element, Event, Layout, Length,
     Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
 };
 
@@ -433,9 +432,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        let mut event_status = event::Status::Ignored;
-
+    ) {
         let Memory { action, .. } = tree.state.downcast_mut();
         let node = self.internal.layout();
 
@@ -451,7 +448,7 @@ where
                 let bounds = layout.bounds();
 
                 if let Some(cursor_position) = cursor.position_over(bounds) {
-                    event_status = event::Status::Captured;
+                    shell.capture_event();
 
                     match &self.on_resize {
                         Some((leeway, _)) => {
@@ -556,9 +553,9 @@ where
                         }
                     }
 
-                    event_status = event::Status::Captured;
+                    shell.capture_event();
                 } else if action.picked_split().is_some() {
-                    event_status = event::Status::Captured;
+                    shell.capture_event();
                 }
 
                 *action = state::Action::Idle;
@@ -600,7 +597,7 @@ where
                                     ratio,
                                 }));
 
-                                event_status = event::Status::Captured;
+                                shell.capture_event();
                             }
                         }
                     }
@@ -611,7 +608,8 @@ where
 
         let picked_pane = action.picked_pane().map(|(pane, _)| pane);
 
-        self.panes
+        for (((pane, content), tree), layout) in self
+            .panes
             .iter()
             .copied()
             .zip(&mut self.contents)
@@ -622,22 +620,21 @@ where
                     .maximized()
                     .map_or(true, |maximized| *pane == maximized)
             })
-            .map(|(((pane, content), tree), layout)| {
-                let is_picked = picked_pane == Some(pane);
-
-                content.on_event(
-                    tree,
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                    viewport,
-                    is_picked,
-                )
-            })
-            .fold(event_status, event::Status::merge)
+        {
+            let is_picked = picked_pane == Some(pane);
+
+            content.on_event(
+                tree,
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+                viewport,
+                is_picked,
+            );
+        }
     }
 
     fn mouse_interaction(
diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs
index ec0676b1..81a5cc1e 100644
--- a/widget/src/pane_grid/content.rs
+++ b/widget/src/pane_grid/content.rs
@@ -1,12 +1,12 @@
 use crate::container;
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
 use crate::core::renderer;
 use crate::core::widget::{self, Tree};
 use crate::core::{
-    self, Clipboard, Element, Layout, Point, Rectangle, Shell, Size, Vector,
+    self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size,
+    Vector,
 };
 use crate::pane_grid::{Draggable, TitleBar};
 
@@ -250,13 +250,11 @@ where
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
         is_picked: bool,
-    ) -> event::Status {
-        let mut event_status = event::Status::Ignored;
-
+    ) {
         let body_layout = if let Some(title_bar) = &mut self.title_bar {
             let mut children = layout.children();
 
-            event_status = title_bar.on_event(
+            title_bar.on_event(
                 &mut tree.children[1],
                 event.clone(),
                 children.next().unwrap(),
@@ -272,9 +270,7 @@ where
             layout
         };
 
-        let body_status = if is_picked {
-            event::Status::Ignored
-        } else {
+        if !is_picked {
             self.body.as_widget_mut().on_event(
                 &mut tree.children[0],
                 event,
@@ -284,10 +280,8 @@ where
                 clipboard,
                 shell,
                 viewport,
-            )
-        };
-
-        event_status.merge(body_status)
+            );
+        }
     }
 
     pub(crate) fn mouse_interaction(
diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs
index 5002b4f7..ec1dc302 100644
--- a/widget/src/pane_grid/title_bar.rs
+++ b/widget/src/pane_grid/title_bar.rs
@@ -1,13 +1,12 @@
 use crate::container;
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
 use crate::core::renderer;
 use crate::core::widget::{self, Tree};
 use crate::core::{
-    self, Clipboard, Element, Layout, Padding, Point, Rectangle, Shell, Size,
-    Vector,
+    self, Clipboard, Element, Event, Layout, Padding, Point, Rectangle, Shell,
+    Size, Vector,
 };
 use crate::pane_grid::controls::Controls;
 
@@ -438,7 +437,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let mut children = layout.children();
         let padded = children.next().unwrap();
 
@@ -446,8 +445,9 @@ where
         let title_layout = children.next().unwrap();
         let mut show_title = true;
 
-        let control_status = if let Some(controls) = &mut self.controls {
+        if let Some(controls) = &mut self.controls {
             let controls_layout = children.next().unwrap();
+
             if title_layout.bounds().width + controls_layout.bounds().width
                 > padded.bounds().width
             {
@@ -463,7 +463,7 @@ where
                         clipboard,
                         shell,
                         viewport,
-                    )
+                    );
                 } else {
                     show_title = false;
 
@@ -476,7 +476,7 @@ where
                         clipboard,
                         shell,
                         viewport,
-                    )
+                    );
                 }
             } else {
                 controls.full.as_widget_mut().on_event(
@@ -488,13 +488,11 @@ where
                     clipboard,
                     shell,
                     viewport,
-                )
+                );
             }
-        } else {
-            event::Status::Ignored
-        };
+        }
 
-        let title_status = if show_title {
+        if show_title {
             self.content.as_widget_mut().on_event(
                 &mut tree.children[0],
                 event,
@@ -504,12 +502,8 @@ where
                 clipboard,
                 shell,
                 viewport,
-            )
-        } else {
-            event::Status::Ignored
-        };
-
-        control_status.merge(title_status)
+            );
+        }
     }
 
     pub(crate) fn mouse_interaction(
diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs
index 9c9ba9e9..9eb43e72 100644
--- a/widget/src/pick_list.rs
+++ b/widget/src/pick_list.rs
@@ -61,7 +61,6 @@
 //! }
 //! ```
 use crate::core::alignment;
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::layout;
 use crate::core::mouse;
@@ -73,8 +72,8 @@ use crate::core::touch;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    Background, Border, Clipboard, Color, Element, Layout, Length, Padding,
-    Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
+    Background, Border, Clipboard, Color, Element, Event, Layout, Length,
+    Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
 };
 use crate::overlay::menu::{self, Menu};
 
@@ -438,10 +437,10 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>();
 
-        let event_status = match event {
+        match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
             | Event::Touch(touch::Event::FingerPressed { .. }) => {
                 if state.is_open {
@@ -453,7 +452,7 @@ where
                         shell.publish(on_close.clone());
                     }
 
-                    event::Status::Captured
+                    shell.capture_event();
                 } else if cursor.is_over(layout.bounds()) {
                     let selected = self.selected.as_ref().map(Borrow::borrow);
 
@@ -468,9 +467,7 @@ where
                         shell.publish(on_open.clone());
                     }
 
-                    event::Status::Captured
-                } else {
-                    event::Status::Ignored
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::WheelScrolled {
@@ -512,17 +509,13 @@ where
                         shell.publish((self.on_select)(next_option.clone()));
                     }
 
-                    event::Status::Captured
-                } else {
-                    event::Status::Ignored
+                    shell.capture_event();
                 }
             }
             Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => {
                 state.keyboard_modifiers = modifiers;
-
-                event::Status::Ignored
             }
-            _ => event::Status::Ignored,
+            _ => {}
         };
 
         let status = if state.is_open {
@@ -541,8 +534,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event_status
     }
 
     fn mouse_interaction(
diff --git a/widget/src/radio.rs b/widget/src/radio.rs
index ed821532..70e1c423 100644
--- a/widget/src/radio.rs
+++ b/widget/src/radio.rs
@@ -58,7 +58,6 @@
 //! ```
 use crate::core::alignment;
 use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::renderer;
@@ -68,8 +67,8 @@ use crate::core::widget;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    Background, Clipboard, Color, Element, Layout, Length, Pixels, Rectangle,
-    Shell, Size, Theme, Widget,
+    Background, Clipboard, Color, Element, Event, Layout, Length, Pixels,
+    Rectangle, Shell, Size, Theme, Widget,
 };
 
 /// A circular button representing a choice.
@@ -334,14 +333,13 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
             | Event::Touch(touch::Event::FingerPressed { .. }) => {
                 if cursor.is_over(layout.bounds()) {
                     shell.publish(self.on_click.clone());
-
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             _ => {}
@@ -366,8 +364,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
diff --git a/widget/src/row.rs b/widget/src/row.rs
index 9c0fa97e..a4b6aa2a 100644
--- a/widget/src/row.rs
+++ b/widget/src/row.rs
@@ -1,13 +1,12 @@
 //! Distribute content horizontally.
 use crate::core::alignment::{self, Alignment};
-use crate::core::event::{self, Event};
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
 use crate::core::renderer;
 use crate::core::widget::{Operation, Tree};
 use crate::core::{
-    Clipboard, Element, Length, Padding, Pixels, Rectangle, Shell, Size,
+    Clipboard, Element, Event, Length, Padding, Pixels, Rectangle, Shell, Size,
     Vector, Widget,
 };
 
@@ -264,24 +263,24 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
-        self.children
+    ) {
+        for ((child, state), layout) in self
+            .children
             .iter_mut()
             .zip(&mut tree.children)
             .zip(layout.children())
-            .map(|((child, state), layout)| {
-                child.as_widget_mut().on_event(
-                    state,
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                    viewport,
-                )
-            })
-            .fold(event::Status::Ignored, event::Status::merge)
+        {
+            child.as_widget_mut().on_event(
+                state,
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+                viewport,
+            );
+        }
     }
 
     fn mouse_interaction(
@@ -503,10 +502,10 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         self.row.on_event(
             tree, event, layout, cursor, renderer, clipboard, shell, viewport,
-        )
+        );
     }
 
     fn mouse_interaction(
diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs
index abad6ea6..33d4f545 100644
--- a/widget/src/scrollable.rs
+++ b/widget/src/scrollable.rs
@@ -21,7 +21,6 @@
 //! ```
 use crate::container;
 use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::layout;
 use crate::core::mouse;
@@ -34,8 +33,8 @@ use crate::core::widget::operation::{self, Operation};
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    self, Background, Clipboard, Color, Element, Layout, Length, Padding,
-    Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
+    self, Background, Clipboard, Color, Element, Event, Layout, Length,
+    Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
 };
 use crate::runtime::task::{self, Task};
 use crate::runtime::Action;
@@ -519,7 +518,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
         let bounds = layout.bounds();
         let cursor_over_scrollable = cursor.position_over(bounds);
@@ -561,7 +560,7 @@ where
                         if let Some(scrollbar) = scrollbars.y {
                             let Some(cursor_position) = cursor.position()
                             else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             state.scroll_y_to(
@@ -581,7 +580,7 @@ where
                                 shell,
                             );
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                     }
                     _ => {}
@@ -593,7 +592,7 @@ where
                     ))
                     | Event::Touch(touch::Event::FingerPressed { .. }) => {
                         let Some(cursor_position) = cursor.position() else {
-                            return event::Status::Ignored;
+                            return;
                         };
 
                         if let (Some(scroller_grabbed_at), Some(scrollbar)) = (
@@ -621,7 +620,7 @@ where
                             );
                         }
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                     _ => {}
                 }
@@ -632,7 +631,7 @@ where
                     Event::Mouse(mouse::Event::CursorMoved { .. })
                     | Event::Touch(touch::Event::FingerMoved { .. }) => {
                         let Some(cursor_position) = cursor.position() else {
-                            return event::Status::Ignored;
+                            return;
                         };
 
                         if let Some(scrollbar) = scrollbars.x {
@@ -654,7 +653,7 @@ where
                             );
                         }
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                     _ => {}
                 }
@@ -665,7 +664,7 @@ where
                     ))
                     | Event::Touch(touch::Event::FingerPressed { .. }) => {
                         let Some(cursor_position) = cursor.position() else {
-                            return event::Status::Ignored;
+                            return;
                         };
 
                         if let (Some(scroller_grabbed_at), Some(scrollbar)) = (
@@ -692,20 +691,19 @@ where
                                 shell,
                             );
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                     }
                     _ => {}
                 }
             }
 
-            let content_status = if state.last_scrolled.is_some()
-                && matches!(
+            if state.last_scrolled.is_none()
+                || !matches!(
                     event,
                     Event::Mouse(mouse::Event::WheelScrolled { .. })
-                ) {
-                event::Status::Ignored
-            } else {
+                )
+            {
                 let cursor = match cursor_over_scrollable {
                     Some(cursor_position)
                         if !(mouse_over_x_scrollbar
@@ -739,7 +737,7 @@ where
                         x: bounds.x + translation.x,
                         ..bounds
                     },
-                )
+                );
             };
 
             if matches!(
@@ -754,11 +752,11 @@ where
                 state.x_scroller_grabbed_at = None;
                 state.y_scroller_grabbed_at = None;
 
-                return content_status;
+                return;
             }
 
-            if let event::Status::Captured = content_status {
-                return event::Status::Captured;
+            if shell.is_event_captured() {
+                return;
             }
 
             if let Event::Keyboard(keyboard::Event::ModifiersChanged(
@@ -767,13 +765,13 @@ where
             {
                 state.keyboard_modifiers = modifiers;
 
-                return event::Status::Ignored;
+                return;
             }
 
             match event {
                 Event::Mouse(mouse::Event::WheelScrolled { delta }) => {
                     if cursor_over_scrollable.is_none() {
-                        return event::Status::Ignored;
+                        return;
                     }
 
                     let delta = match delta {
@@ -827,9 +825,7 @@ where
                     let in_transaction = state.last_scrolled.is_some();
 
                     if has_scrolled || in_transaction {
-                        event::Status::Captured
-                    } else {
-                        event::Status::Ignored
+                        shell.capture_event();
                     }
                 }
                 Event::Touch(event)
@@ -841,7 +837,7 @@ where
                         touch::Event::FingerPressed { .. } => {
                             let Some(cursor_position) = cursor.position()
                             else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             state.scroll_area_touched_at =
@@ -853,7 +849,7 @@ where
                             {
                                 let Some(cursor_position) = cursor.position()
                                 else {
-                                    return event::Status::Ignored;
+                                    return;
                                 };
 
                                 let delta = Vector::new(
@@ -883,7 +879,7 @@ where
                         _ => {}
                     }
 
-                    event::Status::Captured
+                    shell.capture_event();
                 }
                 Event::Window(window::Event::RedrawRequested(_)) => {
                     let _ = notify_viewport(
@@ -893,14 +889,12 @@ where
                         content_bounds,
                         shell,
                     );
-
-                    event::Status::Ignored
                 }
-                _ => event::Status::Ignored,
+                _ => {}
             }
         };
 
-        let event_status = update();
+        update();
 
         let status = if state.y_scroller_grabbed_at.is_some()
             || state.x_scroller_grabbed_at.is_some()
@@ -933,8 +927,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event_status
     }
 
     fn draw(
diff --git a/widget/src/shader.rs b/widget/src/shader.rs
index fa692336..5e4d3915 100644
--- a/widget/src/shader.rs
+++ b/widget/src/shader.rs
@@ -97,7 +97,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let bounds = layout.bounds();
 
         let custom_shader_event = match event {
@@ -115,22 +115,14 @@ where
         if let Some(custom_shader_event) = custom_shader_event {
             let state = tree.state.downcast_mut::<P::State>();
 
-            let (event_status, message) = self.program.update(
+            self.program.update(
                 state,
                 custom_shader_event,
                 bounds,
                 cursor,
                 shell,
             );
-
-            if let Some(message) = message {
-                shell.publish(message);
-            }
-
-            return event_status;
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
@@ -195,8 +187,8 @@ where
         bounds: Rectangle,
         cursor: mouse::Cursor,
         shell: &mut Shell<'_, Message>,
-    ) -> (event::Status, Option<Message>) {
-        T::update(self, state, event, bounds, cursor, shell)
+    ) {
+        T::update(self, state, event, bounds, cursor, shell);
     }
 
     fn draw(
diff --git a/widget/src/shader/event.rs b/widget/src/shader/event.rs
index 005c8725..2d7c79bb 100644
--- a/widget/src/shader/event.rs
+++ b/widget/src/shader/event.rs
@@ -4,8 +4,6 @@ use crate::core::mouse;
 use crate::core::time::Instant;
 use crate::core::touch;
 
-pub use crate::core::event::Status;
-
 /// A [`Shader`] event.
 ///
 /// [`Shader`]: crate::Shader
diff --git a/widget/src/shader/program.rs b/widget/src/shader/program.rs
index 902c7c3b..5124a1cc 100644
--- a/widget/src/shader/program.rs
+++ b/widget/src/shader/program.rs
@@ -1,4 +1,3 @@
-use crate::core::event;
 use crate::core::mouse;
 use crate::core::{Rectangle, Shell};
 use crate::renderer::wgpu::Primitive;
@@ -31,8 +30,7 @@ pub trait Program<Message> {
         _bounds: Rectangle,
         _cursor: mouse::Cursor,
         _shell: &mut Shell<'_, Message>,
-    ) -> (event::Status, Option<Message>) {
-        (event::Status::Ignored, None)
+    ) {
     }
 
     /// Draws the [`Primitive`].
diff --git a/widget/src/slider.rs b/widget/src/slider.rs
index dbdb5f07..4a424bd9 100644
--- a/widget/src/slider.rs
+++ b/widget/src/slider.rs
@@ -29,7 +29,6 @@
 //! }
 //! ```
 use crate::core::border::{self, Border};
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::keyboard::key::{self, Key};
 use crate::core::layout;
@@ -39,8 +38,8 @@ use crate::core::touch;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    self, Background, Clipboard, Color, Element, Layout, Length, Pixels, Point,
-    Rectangle, Shell, Size, Theme, Widget,
+    self, Background, Clipboard, Color, Element, Event, Layout, Length, Pixels,
+    Point, Rectangle, Shell, Size, Theme, Widget,
 };
 
 use std::ops::RangeInclusive;
@@ -253,7 +252,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
 
         let mut update = || {
@@ -349,7 +348,7 @@ where
                             state.is_dragging = true;
                         }
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
                 Event::Mouse(mouse::Event::ButtonReleased(
@@ -363,7 +362,7 @@ where
                         }
                         state.is_dragging = false;
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
                 Event::Mouse(mouse::Event::CursorMoved { .. })
@@ -371,7 +370,7 @@ where
                     if state.is_dragging {
                         let _ = cursor.position().and_then(locate).map(change);
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
                 Event::Mouse(mouse::Event::WheelScrolled { delta })
@@ -389,7 +388,7 @@ where
                             let _ = increment(current_value).map(change);
                         }
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
                 Event::Keyboard(keyboard::Event::KeyPressed {
@@ -406,7 +405,7 @@ where
                             _ => (),
                         }
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
                 Event::Keyboard(keyboard::Event::ModifiersChanged(
@@ -416,11 +415,9 @@ where
                 }
                 _ => {}
             }
-
-            event::Status::Ignored
         };
 
-        let update_status = update();
+        update();
 
         let current_status = if state.is_dragging {
             Status::Dragged
@@ -435,8 +432,6 @@ where
         } else if self.status.is_some_and(|status| status != current_status) {
             shell.request_redraw();
         }
-
-        update_status
     }
 
     fn draw(
diff --git a/widget/src/stack.rs b/widget/src/stack.rs
index 6a44c328..2cb628ab 100644
--- a/widget/src/stack.rs
+++ b/widget/src/stack.rs
@@ -1,12 +1,12 @@
 //! Display content on top of other content.
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
 use crate::core::renderer;
 use crate::core::widget::{Operation, Tree};
 use crate::core::{
-    Clipboard, Element, Layout, Length, Rectangle, Shell, Size, Vector, Widget,
+    Clipboard, Element, Event, Layout, Length, Rectangle, Shell, Size, Vector,
+    Widget,
 };
 
 /// A container that displays children on top of each other.
@@ -214,40 +214,41 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let is_over = cursor.is_over(layout.bounds());
 
-        self.children
+        for ((child, state), layout) in self
+            .children
             .iter_mut()
             .rev()
             .zip(tree.children.iter_mut().rev())
             .zip(layout.children().rev())
-            .map(|((child, state), layout)| {
-                let status = child.as_widget_mut().on_event(
-                    state,
-                    event.clone(),
-                    layout,
-                    cursor,
-                    renderer,
-                    clipboard,
-                    shell,
-                    viewport,
+        {
+            child.as_widget_mut().on_event(
+                state,
+                event.clone(),
+                layout,
+                cursor,
+                renderer,
+                clipboard,
+                shell,
+                viewport,
+            );
+
+            if is_over && cursor != mouse::Cursor::Unavailable {
+                let interaction = child.as_widget().mouse_interaction(
+                    state, layout, cursor, viewport, renderer,
                 );
 
-                if is_over && cursor != mouse::Cursor::Unavailable {
-                    let interaction = child.as_widget().mouse_interaction(
-                        state, layout, cursor, viewport, renderer,
-                    );
-
-                    if interaction != mouse::Interaction::None {
-                        cursor = mouse::Cursor::Unavailable;
-                    }
+                if interaction != mouse::Interaction::None {
+                    cursor = mouse::Cursor::Unavailable;
                 }
+            }
 
-                status
-            })
-            .find(|&status| status == event::Status::Captured)
-            .unwrap_or(event::Status::Ignored)
+            if shell.is_event_captured() {
+                return;
+            }
+        }
     }
 
     fn mouse_interaction(
diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs
index 3d241375..f778b029 100644
--- a/widget/src/text/rich.rs
+++ b/widget/src/text/rich.rs
@@ -1,5 +1,4 @@
 use crate::core::alignment;
-use crate::core::event;
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::renderer;
@@ -365,7 +364,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Link>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
                 if let Some(position) = cursor.position_in(layout.bounds()) {
@@ -374,9 +373,16 @@ where
                         .downcast_mut::<State<Link, Renderer::Paragraph>>();
 
                     if let Some(span) = state.paragraph.hit_span(position) {
-                        state.span_pressed = Some(span);
-
-                        return event::Status::Captured;
+                        if self
+                            .spans
+                            .as_ref()
+                            .as_ref()
+                            .get(span)
+                            .is_some_and(|span| span.link.is_some())
+                        {
+                            state.span_pressed = Some(span);
+                            shell.capture_event();
+                        }
                     }
                 }
             }
@@ -409,8 +415,6 @@ where
             }
             _ => {}
         }
-
-        event::Status::Ignored
     }
 
     fn mouse_interaction(
diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs
index 3bb45494..292e584e 100644
--- a/widget/src/text_editor.rs
+++ b/widget/src/text_editor.rs
@@ -33,7 +33,6 @@
 //! ```
 use crate::core::alignment;
 use crate::core::clipboard::{self, Clipboard};
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::keyboard::key;
 use crate::core::layout::{self, Layout};
@@ -47,7 +46,7 @@ use crate::core::widget::operation;
 use crate::core::widget::{self, Widget};
 use crate::core::window;
 use crate::core::{
-    Background, Border, Color, Element, Length, Padding, Pixels, Point,
+    Background, Border, Color, Element, Event, Length, Padding, Pixels, Point,
     Rectangle, Shell, Size, SmolStr, Theme, Vector,
 };
 
@@ -606,9 +605,9 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let Some(on_edit) = self.on_edit.as_ref() else {
-            return event::Status::Ignored;
+            return;
         };
 
         let state = tree.state.downcast_mut::<State<Highlighter>>();
@@ -656,7 +655,7 @@ where
             cursor,
             self.key_binding.as_deref(),
         ) else {
-            return event::Status::Ignored;
+            return;
         };
 
         match update {
@@ -685,7 +684,7 @@ where
                 let bounds = self.content.0.borrow().editor.bounds();
 
                 if bounds.height >= i32::MAX as f32 {
-                    return event::Status::Ignored;
+                    return;
                 }
 
                 let lines = lines + state.partial_scroll;
@@ -798,7 +797,7 @@ where
             }
         }
 
-        event::Status::Captured
+        shell.capture_event();
     }
 
     fn draw(
diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs
index 8fa7889f..87dffb98 100644
--- a/widget/src/text_input.rs
+++ b/widget/src/text_input.rs
@@ -42,7 +42,6 @@ use editor::Editor;
 
 use crate::core::alignment;
 use crate::core::clipboard::{self, Clipboard};
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::keyboard::key;
 use crate::core::layout;
@@ -57,8 +56,8 @@ use crate::core::widget::operation::{self, Operation};
 use crate::core::widget::tree::{self, Tree};
 use crate::core::window;
 use crate::core::{
-    Background, Border, Color, Element, Layout, Length, Padding, Pixels, Point,
-    Rectangle, Shell, Size, Theme, Vector, Widget,
+    Background, Border, Color, Element, Event, Layout, Length, Padding, Pixels,
+    Point, Rectangle, Shell, Size, Theme, Vector, Widget,
 };
 use crate::runtime::task::{self, Task};
 use crate::runtime::Action;
@@ -638,7 +637,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let update_cache = |state, value| {
             replace_paragraph(
                 renderer,
@@ -754,7 +753,7 @@ where
                         shell.request_redraw();
                     }
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
@@ -809,7 +808,7 @@ where
                         shell.request_redraw();
                     }
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Keyboard(keyboard::Event::KeyPressed {
@@ -834,14 +833,15 @@ where
                                 );
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
+                            return;
                         }
                         keyboard::Key::Character("x")
                             if state.keyboard_modifiers.command()
                                 && !self.is_secure =>
                         {
                             let Some(on_input) = &self.on_input else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             if let Some((start, end)) =
@@ -859,18 +859,18 @@ where
 
                             let message = (on_input)(editor.contents());
                             shell.publish(message);
+                            shell.capture_event();
 
                             focus.updated_at = Instant::now();
                             update_cache(state, &self.value);
-
-                            return event::Status::Captured;
+                            return;
                         }
                         keyboard::Key::Character("v")
                             if state.keyboard_modifiers.command()
                                 && !state.keyboard_modifiers.alt() =>
                         {
                             let Some(on_input) = &self.on_input else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             let content = match state.is_pasting.take() {
@@ -897,12 +897,12 @@ where
                                 (on_input)(editor.contents())
                             };
                             shell.publish(message);
+                            shell.capture_event();
 
                             state.is_pasting = Some(content);
                             focus.updated_at = Instant::now();
                             update_cache(state, &self.value);
-
-                            return event::Status::Captured;
+                            return;
                         }
                         keyboard::Key::Character("a")
                             if state.keyboard_modifiers.command() =>
@@ -917,14 +917,15 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
+                            return;
                         }
                         _ => {}
                     }
 
                     if let Some(text) = text {
                         let Some(on_input) = &self.on_input else {
-                            return event::Status::Ignored;
+                            return;
                         };
 
                         state.is_pasting = None;
@@ -939,11 +940,11 @@ where
 
                             let message = (on_input)(editor.contents());
                             shell.publish(message);
+                            shell.capture_event();
 
                             focus.updated_at = Instant::now();
                             update_cache(state, &self.value);
-
-                            return event::Status::Captured;
+                            return;
                         }
                     }
 
@@ -951,13 +952,12 @@ where
                         keyboard::Key::Named(key::Named::Enter) => {
                             if let Some(on_submit) = self.on_submit.clone() {
                                 shell.publish(on_submit);
-
-                                return event::Status::Captured;
+                                shell.capture_event();
                             }
                         }
                         keyboard::Key::Named(key::Named::Backspace) => {
                             let Some(on_input) = &self.on_input else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             if modifiers.jump()
@@ -980,15 +980,14 @@ where
 
                             let message = (on_input)(editor.contents());
                             shell.publish(message);
+                            shell.capture_event();
 
                             focus.updated_at = Instant::now();
                             update_cache(state, &self.value);
-
-                            return event::Status::Captured;
                         }
                         keyboard::Key::Named(key::Named::Delete) => {
                             let Some(on_input) = &self.on_input else {
-                                return event::Status::Ignored;
+                                return;
                             };
 
                             if modifiers.jump()
@@ -1014,11 +1013,10 @@ where
 
                             let message = (on_input)(editor.contents());
                             shell.publish(message);
+                            shell.capture_event();
 
                             focus.updated_at = Instant::now();
                             update_cache(state, &self.value);
-
-                            return event::Status::Captured;
                         }
                         keyboard::Key::Named(key::Named::Home) => {
                             let cursor_before = state.cursor;
@@ -1038,7 +1036,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::End) => {
                             let cursor_before = state.cursor;
@@ -1058,7 +1056,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::ArrowLeft)
                             if modifiers.macos_command() =>
@@ -1080,7 +1078,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::ArrowRight)
                             if modifiers.macos_command() =>
@@ -1102,7 +1100,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::ArrowLeft) => {
                             let cursor_before = state.cursor;
@@ -1129,7 +1127,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::ArrowRight) => {
                             let cursor_before = state.cursor;
@@ -1156,7 +1154,7 @@ where
                                 shell.request_redraw();
                             }
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         keyboard::Key::Named(key::Named::Escape) => {
                             state.is_focused = None;
@@ -1166,7 +1164,7 @@ where
                             state.keyboard_modifiers =
                                 keyboard::Modifiers::default();
 
-                            return event::Status::Captured;
+                            shell.capture_event();
                         }
                         _ => {}
                     }
@@ -1179,7 +1177,7 @@ where
                     if let keyboard::Key::Character("v") = key.as_ref() {
                         state.is_pasting = None;
 
-                        return event::Status::Captured;
+                        shell.capture_event();
                     }
                 }
 
@@ -1257,8 +1255,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event::Status::Ignored
     }
 
     fn draw(
diff --git a/widget/src/themer.rs b/widget/src/themer.rs
index 499a9fe8..649cfbdd 100644
--- a/widget/src/themer.rs
+++ b/widget/src/themer.rs
@@ -1,5 +1,4 @@
 use crate::container;
-use crate::core::event::{self, Event};
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::overlay;
@@ -7,8 +6,8 @@ use crate::core::renderer;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::widget::Operation;
 use crate::core::{
-    Background, Clipboard, Color, Element, Layout, Length, Point, Rectangle,
-    Shell, Size, Vector, Widget,
+    Background, Clipboard, Color, Element, Event, Layout, Length, Point,
+    Rectangle, Shell, Size, Vector, Widget,
 };
 
 use std::marker::PhantomData;
@@ -121,10 +120,10 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         self.content.as_widget_mut().on_event(
             tree, event, layout, cursor, renderer, clipboard, shell, viewport,
-        )
+        );
     }
 
     fn mouse_interaction(
@@ -227,9 +226,10 @@ where
                 renderer: &Renderer,
                 clipboard: &mut dyn Clipboard,
                 shell: &mut Shell<'_, Message>,
-            ) -> event::Status {
-                self.content
-                    .on_event(event, layout, cursor, renderer, clipboard, shell)
+            ) {
+                self.content.on_event(
+                    event, layout, cursor, renderer, clipboard, shell,
+                );
             }
 
             fn operate(
diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs
index 2553a7e4..8461fbb2 100644
--- a/widget/src/toggler.rs
+++ b/widget/src/toggler.rs
@@ -31,7 +31,6 @@
 //! }
 //! ```
 use crate::core::alignment;
-use crate::core::event;
 use crate::core::layout;
 use crate::core::mouse;
 use crate::core::renderer;
@@ -317,26 +316,23 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let Some(on_toggle) = &self.on_toggle else {
-            return event::Status::Ignored;
+            return;
         };
 
-        let event_status = match event {
+        match event {
             Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
             | Event::Touch(touch::Event::FingerPressed { .. }) => {
                 let mouse_over = cursor.is_over(layout.bounds());
 
                 if mouse_over {
                     shell.publish(on_toggle(!self.is_toggled));
-
-                    event::Status::Captured
-                } else {
-                    event::Status::Ignored
+                    shell.capture_event();
                 }
             }
-            _ => event::Status::Ignored,
-        };
+            _ => {}
+        }
 
         let current_status = if self.on_toggle.is_none() {
             Status::Disabled
@@ -358,8 +354,6 @@ where
         {
             shell.request_redraw();
         }
-
-        event_status
     }
 
     fn mouse_interaction(
diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs
index e98f4da7..91151acc 100644
--- a/widget/src/tooltip.rs
+++ b/widget/src/tooltip.rs
@@ -22,7 +22,6 @@
 //! }
 //! ```
 use crate::container;
-use crate::core::event::{self, Event};
 use crate::core::layout::{self, Layout};
 use crate::core::mouse;
 use crate::core::overlay;
@@ -30,8 +29,8 @@ use crate::core::renderer;
 use crate::core::text;
 use crate::core::widget::{self, Widget};
 use crate::core::{
-    Clipboard, Element, Length, Padding, Pixels, Point, Rectangle, Shell, Size,
-    Vector,
+    Clipboard, Element, Event, Length, Padding, Pixels, Point, Rectangle,
+    Shell, Size, Vector,
 };
 
 /// An element to display a widget over another.
@@ -200,7 +199,7 @@ where
         clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
 
         let was_idle = *state == State::Idle;
@@ -225,7 +224,7 @@ where
             clipboard,
             shell,
             viewport,
-        )
+        );
     }
 
     fn mouse_interaction(
diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs
index 18633474..e7e36d2a 100644
--- a/widget/src/vertical_slider.rs
+++ b/widget/src/vertical_slider.rs
@@ -35,7 +35,6 @@ pub use crate::slider::{
 };
 
 use crate::core::border::Border;
-use crate::core::event::{self, Event};
 use crate::core::keyboard;
 use crate::core::keyboard::key::{self, Key};
 use crate::core::layout::{self, Layout};
@@ -44,8 +43,8 @@ use crate::core::renderer;
 use crate::core::touch;
 use crate::core::widget::tree::{self, Tree};
 use crate::core::{
-    self, Clipboard, Element, Length, Pixels, Point, Rectangle, Shell, Size,
-    Widget,
+    self, Clipboard, Element, Event, Length, Pixels, Point, Rectangle, Shell,
+    Size, Widget,
 };
 
 /// An vertical bar and a handle that selects a single value from a range of
@@ -254,7 +253,7 @@ where
         _clipboard: &mut dyn Clipboard,
         shell: &mut Shell<'_, Message>,
         _viewport: &Rectangle,
-    ) -> event::Status {
+    ) {
         let state = tree.state.downcast_mut::<State>();
         let is_dragging = state.is_dragging;
         let current_value = self.value;
@@ -350,7 +349,7 @@ where
                         state.is_dragging = true;
                     }
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
@@ -362,7 +361,7 @@ where
                     }
                     state.is_dragging = false;
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::CursorMoved { .. })
@@ -370,7 +369,7 @@ where
                 if is_dragging {
                     let _ = cursor.position().and_then(locate).map(change);
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Mouse(mouse::Event::WheelScrolled { delta })
@@ -388,7 +387,7 @@ where
                         let _ = increment(current_value).map(change);
                     }
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Keyboard(keyboard::Event::KeyPressed { key, .. }) => {
@@ -403,7 +402,7 @@ where
                         _ => (),
                     }
 
-                    return event::Status::Captured;
+                    shell.capture_event();
                 }
             }
             Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => {
@@ -411,8 +410,6 @@ where
             }
             _ => {}
         }
-
-        event::Status::Ignored
     }
 
     fn draw(
-- 
cgit