git.lucas.co / cce-system-interface
system settings
git clone https://git.lucas.co/cce-system-interface.git

commitb26012d69c1c93f8b61e77909073c1ae05b7f866
parent90eec56319
authorLucas Galante <[email protected]>
date2026-06-26 15:36
Implement AppPage trait, watcher index cleanup, and general renderer refactoring

 src/app.rs               |  40 +++
 src/input_handler.rs     | 586 +--------------------------------
 src/main.rs              |  10 -
 src/pages/accounts.rs    |  91 +++++
 src/pages/audio.rs       | 172 ++++++++++
 src/pages/display.rs     | 163 ++++++++-
 src/pages/input.rs       | 178 +++++++++-
 src/pages/interface.rs   | 842 ++++++++++++++++++++++++++++++++++++++++++-----
 src/pages/mod.rs         |  49 +++
 src/pages/network.rs     |  67 ++++
 src/pages/packages.rs    |  64 ++++
 src/pages/processes.rs   |  58 ++++
 src/pages/storage.rs     |  54 +++
 src/pages/system_info.rs |  86 ++++-
 src/renderer.rs          | 634 +----------------------------------
 src/watchers.rs          |  38 +--
 16 files changed, 1819 insertions(+), 1313 deletions(-)

diff --git a/src/app.rs b/src/app.rs
index 252beba..d5801eb 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -44,6 +44,46 @@ impl Default for AppState {
     }
 }
 
+impl AppState {
+    pub fn get_page(&self, page: Page) -> &dyn crate::pages::AppPage {
+        match page {
+            Page::Accounts => &self.accounts,
+            Page::Audio => &self.audio,
+            Page::Display => &self.display,
+            Page::Input => &self.input,
+            Page::Interface => &self.interface,
+            Page::Packages => &self.packages,
+            Page::Processes => &self.processes,
+            Page::Radios => &self.network,
+            Page::Storage => &self.storage,
+            Page::System => &self.system_info,
+        }
+    }
+
+    pub fn get_page_mut(&mut self, page: Page) -> &mut dyn crate::pages::AppPage {
+        match page {
+            Page::Accounts => &mut self.accounts,
+            Page::Audio => &mut self.audio,
+            Page::Display => &mut self.display,
+            Page::Input => &mut self.input,
+            Page::Interface => &mut self.interface,
+            Page::Packages => &mut self.packages,
+            Page::Processes => &mut self.processes,
+            Page::Radios => &mut self.network,
+            Page::Storage => &mut self.storage,
+            Page::System => &mut self.system_info,
+        }
+    }
+
+    pub fn get_current_page(&self) -> &dyn crate::pages::AppPage {
+        self.get_page(self.current_page)
+    }
+
+    pub fn get_current_page_mut(&mut self) -> &mut dyn crate::pages::AppPage {
+        self.get_page_mut(self.current_page)
+    }
+}
+
 #[derive(Debug, Clone)]
 pub enum AppAction {
     Exit,
diff --git a/src/input_handler.rs b/src/input_handler.rs
index 2fe5f6d..9e80d12 100644
--- a/src/input_handler.rs
+++ b/src/input_handler.rs
@@ -42,66 +42,12 @@ impl SystemInterface {
 
         // Drag updates are high-priority overrides
         let mut drag_handled = false;
-        if self.app.current_page == Page::Audio {
-            if let Some(idx) = self.audio_sink_dragging {
-                drag_handled = true;
-                if idx < self.app.audio.sink_sliders.len() {
-                    if self.app.audio.sink_sliders[idx].drag_update(lx, ly) {
-                        changed = true;
-                        let val = self.app.audio.sink_sliders[idx].value();
-                        if idx < self.app.audio.sink_spinboxes.len() {
-                            self.app.audio.sink_spinboxes[idx].value = (val * 100.0).round() as i32;
-                        }
-                        if idx < self.app.audio.sinks.len() {
-                            let id = self.app.audio.sinks[idx].id;
-                            self.handle_action(&AppAction::Audio(pages::audio::AudioMessage::SinkVolume(id, val)));
-                        }
-                    }
-                }
-            } else if let Some(idx) = self.audio_source_dragging {
-                drag_handled = true;
-                if idx < self.app.audio.source_sliders.len() {
-                    if self.app.audio.source_sliders[idx].drag_update(lx, ly) {
-                        changed = true;
-                        let val = self.app.audio.source_sliders[idx].value();
-                        if idx < self.app.audio.source_spinboxes.len() {
-                            self.app.audio.source_spinboxes[idx].value = (val * 100.0).round() as i32;
-                        }
-                        if idx < self.app.audio.sources.len() {
-                            let id = self.app.audio.sources[idx].id;
-                            self.handle_action(&AppAction::Audio(pages::audio::AudioMessage::SourceVolume(id, val)));
-                        }
-                    }
-                }
-            }
-        }
-        if self.app.current_page == Page::Display {
-            if self.display_brightness_dragging {
-                drag_handled = true;
-                if self.app.display.brightness_slider.drag_update(lx, ly) {
-                    changed = true;
-                    let val = self.app.display.brightness_slider.value();
-                    let pct = (val * 100.0).round() as u32;
-                    self.app.display.brightness_spinbox.value = pct as i32;
-                    self.handle_action(&AppAction::Display(pages::display::DisplayMessage::BrightnessSet(pct)));
-                }
-            }
-        }
-        if self.app.current_page == Page::Interface {
-            if self.status_box_opacity_dragging {
-                drag_handled = true;
-                if self.app.interface.status_box_opacity_slider.drag_update(lx, ly) {
-                    changed = true;
-                    let val = self.app.interface.status_box_opacity_slider.value();
-                    self.handle_action(&AppAction::Interface(pages::interface::InterfaceMessage::StatusSetBoxOpacity(val)));
-                }
-            } else if self.status_box_blur_dragging {
-                drag_handled = true;
-                if self.app.interface.status_box_blur_slider.drag_update(lx, ly) {
-                    changed = true;
-                    let val = self.app.interface.status_box_blur_slider.value();
-                    self.handle_action(&AppAction::Interface(pages::interface::InterfaceMessage::StatusSetBoxBlur(val)));
-                }
+        let mut drag_actions = Vec::new();
+        if self.app.get_current_page_mut().handle_pointer_move(lx, ly, &mut drag_actions, &mut self.ui_context) {
+            drag_handled = true;
+            changed = true;
+            for action in drag_actions {
+                self.handle_action(&action);
             }
         }
 
@@ -208,44 +154,8 @@ impl SystemInterface {
         if button != cce_ui::widget::MouseButton::Left && button != cce_ui::widget::MouseButton::Right { return false; }
         let mut actions = Vec::new();
         if button == cce_ui::widget::MouseButton::Left && state == cce_ui::widget::ElementState::Released {
-            if self.app.current_page == Page::Audio {
-                let mut ended = false;
-                if let Some(idx) = self.audio_sink_dragging {
-                    if idx < self.app.audio.sink_sliders.len() {
-                        self.app.audio.sink_sliders[idx].drag_end();
-                    }
-                    self.audio_sink_dragging = None;
-                    ended = true;
-                }
-                if let Some(idx) = self.audio_source_dragging {
-                    if idx < self.app.audio.source_sliders.len() {
-                        self.app.audio.source_sliders[idx].drag_end();
-                    }
-                    self.audio_source_dragging = None;
-                    ended = true;
-                }
-                if ended {
-                    self.needs_rebuild = true;
-                }
-            }
-            if self.app.current_page == Page::Display {
-                if self.display_brightness_dragging {
-                    self.app.display.brightness_slider.drag_end();
-                    self.display_brightness_dragging = false;
-                    self.needs_rebuild = true;
-                }
-            }
-            if self.app.current_page == Page::Interface {
-                if self.status_box_opacity_dragging {
-                    self.app.interface.status_box_opacity_slider.drag_end();
-                    self.status_box_opacity_dragging = false;
-                    self.needs_rebuild = true;
-                }
-                if self.status_box_blur_dragging {
-                    self.app.interface.status_box_blur_slider.drag_end();
-                    self.status_box_blur_dragging = false;
-                    self.needs_rebuild = true;
-                }
+            if self.app.get_current_page_mut().handle_pointer_up(&mut self.ui_context) {
+                self.needs_rebuild = true;
             }
         }
 
@@ -257,33 +167,7 @@ impl SystemInterface {
         }
 
         if state == cce_ui::widget::ElementState::Pressed {
-            if self.app.current_page == Page::Display {
-                if self.app.display.brightness_slider.is_dragging() {
-                    self.display_brightness_dragging = true;
-                }
-            }
-            if self.app.current_page == Page::Audio {
-                for (i, s) in self.app.audio.sink_sliders.iter().enumerate() {
-                    if s.is_dragging() {
-                        self.audio_sink_dragging = Some(i);
-                        break;
-                    }
-                }
-                for (i, s) in self.app.audio.source_sliders.iter().enumerate() {
-                    if s.is_dragging() {
-                        self.audio_source_dragging = Some(i);
-                        break;
-                    }
-                }
-            }
-            if self.app.current_page == Page::Interface {
-                if self.app.interface.status_box_opacity_slider.is_dragging() {
-                    self.status_box_opacity_dragging = true;
-                }
-                if self.app.interface.status_box_blur_slider.is_dragging() {
-                    self.status_box_blur_dragging = true;
-                }
-            }
+            self.app.get_current_page_mut().handle_pointer_down(lx, ly, &mut self.ui_context);
         }
 
         self.propagate_widget_changes(&mut actions);
@@ -300,457 +184,7 @@ impl SystemInterface {
     }
 
     pub(crate) fn propagate_widget_changes(&mut self, actions: &mut Vec<AppAction>) {
-        match self.app.current_page {
-            Page::Interface => {
-                for (i, cp) in self.app.interface.color_selectors.iter_mut().enumerate() {
-                    if cp.take_change() {
-                        actions.push(AppAction::Interface(match i {
-                            0 => pages::interface::InterfaceMessage::SetPageLowColor(cp.color),
-                            1 => pages::interface::InterfaceMessage::SetHighColor(cp.color),
-                            2 => pages::interface::InterfaceMessage::SetVisualGuidesColor(cp.color),
-                            3 => pages::interface::InterfaceMessage::SetDisabledColor(cp.color),
-                            4 => pages::interface::InterfaceMessage::SetSliderTrackColor(cp.color),
-                            5 => pages::interface::InterfaceMessage::SetColorBordersColor(cp.color),
-                            6 => pages::interface::InterfaceMessage::SetDesktopBackground(cp.color),
-                            7 => pages::interface::InterfaceMessage::SetNormalColor(cp.color),
-                            8 => pages::interface::InterfaceMessage::SetPaginatorSidebarColor(cp.color),
-                            9 => pages::interface::InterfaceMessage::SetPrimaryHighlightColor(cp.color),
-                            10 => pages::interface::InterfaceMessage::SetMenubarTabLabelColor(cp.color),
-                            11 => pages::interface::InterfaceMessage::SetToggleEnabledColor(cp.color),
-                            12 => pages::interface::InterfaceMessage::SetToggleDisabledColor(cp.color),
-                            13 => pages::interface::InterfaceMessage::SetScrollingListBgColor(cp.color),
-                            14 => pages::interface::InterfaceMessage::SetBreadcrumbBgColor(cp.color),
-                            15 => pages::interface::InterfaceMessage::SetPopoverBgColor(cp.color),
-                            16 => pages::interface::InterfaceMessage::SetNotificationBgColor(cp.color),
-                            17 => pages::interface::InterfaceMessage::SetBackplateColor(cp.color),
-                            18 => pages::interface::InterfaceMessage::SetPageColor(cp.color),
-                            19 => pages::interface::InterfaceMessage::SetLayerColor(cp.color),
-                            20 => pages::interface::InterfaceMessage::SetScrollingListEntryBgColor([cp.color[0], cp.color[1], cp.color[2], cp.alpha]),
-                            21 => pages::interface::InterfaceMessage::SetScrollingListEntryHighlightColor([cp.color[0], cp.color[1], cp.color[2], cp.alpha]),
-                            22 => pages::interface::InterfaceMessage::SetStatusBoxBackgroundColor(cp.color),
-                            23 => pages::interface::InterfaceMessage::SetDesktopGridColor([cp.color[0], cp.color[1], cp.color[2], cp.alpha]),
-                            _ => pages::interface::InterfaceMessage::SetDesktopBackground(cp.color),
-                        }));
-                    }
-                }
-                if self.app.interface.notification_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetNotificationOpacity(self.app.interface.notification_opacity_spinbox.value as f32 / 100.0)));
-                }
-                if self.app.interface.desktop_grid_scale_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetDesktopGridScale(self.app.interface.desktop_grid_scale_spinbox.value as u16)));
-                }
-                if self.app.interface.desktop_line_width_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetDesktopLineWidth(self.app.interface.desktop_line_width_spinbox.value as u16)));
-                }
-                if self.app.interface.menubar_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetMenubarOpacity(self.app.interface.menubar_opacity_spinbox.value as f32 / 100.0)));
-                }
-
-
-                if self.app.interface.status_box_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatusBoxCornerRadius(self.app.interface.status_box_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.status_padding_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatusPadding(self.app.interface.status_padding_spinbox.value as u16)));
-                }
-                if self.app.interface.status_module_spacing_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatusModuleSpacing(self.app.interface.status_module_spacing_spinbox.value as u16)));
-                }
-                if self.app.interface.status_separators_toggle.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::StatusToggleSeparators));
-                }
-                if self.app.interface.status_underline_toggle.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::StatusToggleUnderline));
-                }
-                if self.app.interface.status_box_opacity_slider.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::StatusSetBoxOpacity(self.app.interface.status_box_opacity_slider.value())));
-                }
-                if self.app.interface.status_box_blur_slider.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::StatusSetBoxBlur(self.app.interface.status_box_blur_slider.value())));
-                }
-
-                if self.app.interface.button_padding_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetButtonPadding(self.app.interface.button_padding_spinbox.value as u16)));
-                }
-                if self.app.interface.section_padding_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSectionPadding(self.app.interface.section_padding_spinbox.value as u16)));
-                }
-                if self.app.interface.label_alignment_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetNestedSectionLabelAlignment(self.app.interface.label_alignment_menu.selected)));
-                }
-                if self.app.interface.label_offset_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetNestedSectionLabelOffset(self.app.interface.label_offset_spinbox.value as i16)));
-                }
-                if self.app.interface.label_margin_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetLabelMargin(self.app.interface.label_margin_spinbox.value as u16)));
-                }
-                if self.app.interface.plate_padding_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetPlatePadding(self.app.interface.plate_padding_spinbox.value as u16)));
-                }
-                if self.app.interface.graph_show_grid_toggle.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGraphShowGrid(self.app.interface.graph_show_grid_toggle.toggled())));
-                }
-                if self.app.interface.graph_snap_enabled_toggle.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGraphSnapEnabled(self.app.interface.graph_snap_enabled_toggle.toggled())));
-                }
-                if self.app.interface.graph_uniform_background_toggle.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGraphUniformBackground(self.app.interface.graph_uniform_background_toggle.toggled())));
-                }
-                if self.app.interface.graph_cell_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGraphCellOpacity(self.app.interface.graph_cell_opacity_spinbox.value as f32 / 100.0)));
-                }
-                if self.app.interface.graph_gap_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGraphGapOpacity(self.app.interface.graph_gap_opacity_spinbox.value as f32 / 100.0)));
-                }
-                if self.app.interface.page_margin_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetPageMargin(self.app.interface.page_margin_spinbox.value as u16)));
-                }
-                if self.app.interface.grid_min_col_width_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetGridMinColWidth(self.app.interface.grid_min_col_width_spinbox.value as u16)));
-                }
-                if self.app.interface.spinbox_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSpinboxHeight(self.app.interface.spinbox_height_spinbox.value as u16)));
-                }
-                if self.app.interface.spinbox_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSpinboxCornerRadius(self.app.interface.spinbox_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.toggle_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetToggleHeight(self.app.interface.toggle_height_spinbox.value as u16)));
-                }
-                if self.app.interface.toggle_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetToggleCornerRadius(self.app.interface.toggle_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.plate_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetPlateOpacity(self.app.interface.plate_opacity_spinbox.value as f32 / 100.0)));
-                }
-                if self.app.interface.plate_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetPlateCornerRadius(self.app.interface.plate_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.backplate_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetBackplateCornerRadius(self.app.interface.backplate_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.page_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetPageOpacity(self.app.interface.page_opacity_spinbox.value as f32 / 100.0)));
-                }
-                if self.app.interface.layer_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetLayerOpacity(self.app.interface.layer_opacity_spinbox.value as f32 / 100.0)));
-                }
-
-
-                if self.app.interface.color_selector_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetColorSelectorHeight(self.app.interface.color_selector_height_spinbox.value as u16)));
-                }
-                if self.app.interface.color_selector_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetColorSelectorCornerRadius(self.app.interface.color_selector_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.color_selector_preview_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetColorSelectorPreviewCornerRadius(self.app.interface.color_selector_preview_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.color_selector_preview_margin_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetColorSelectorPreviewMargin(self.app.interface.color_selector_preview_margin_spinbox.value as u16)));
-                }
-                if self.app.interface.textbox_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetTextboxHeight(self.app.interface.textbox_height_spinbox.value as u16)));
-                }
-                if self.app.interface.textbox_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetTextboxCornerRadius(self.app.interface.textbox_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.slider_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSliderHeight(self.app.interface.slider_height_spinbox.value as u16)));
-                }
-                if self.app.interface.font_selector_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetFontSelectorHeight(self.app.interface.font_selector_height_spinbox.value as u16)));
-                }
-                if self.app.interface.font_selector_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetFontSelectorCornerRadius(self.app.interface.font_selector_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.dropdown_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetDropdownHeight(self.app.interface.dropdown_height_spinbox.value as u16)));
-                }
-                if self.app.interface.dropdown_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetDropdownCornerRadius(self.app.interface.dropdown_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.button_corner_radius_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetButtonCornerRadius(self.app.interface.button_corner_radius_spinbox.value as u16)));
-                }
-                if self.app.interface.sans_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSans(self.app.interface.sans_box.text.clone())));
-                }
-                if self.app.interface.serif_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSerif(self.app.interface.serif_box.text.clone())));
-                }
-                if self.app.interface.mono_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetMono(self.app.interface.mono_box.text.clone())));
-                }
-                if self.app.interface.borders_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetBordersMenu(self.app.interface.borders_menu.selected)));
-                }
-                if self.app.interface.borders_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetBorders(self.app.interface.borders_box.text.clone())));
-                }
-                if self.app.interface.status_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatusMenu(self.app.interface.status_menu.selected)));
-                }
-                if self.app.interface.status_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatus(self.app.interface.status_box.text.clone())));
-                }
-                if self.app.interface.fuzzel_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetFuzzelMenu(self.app.interface.fuzzel_menu.selected)));
-                }
-                if self.app.interface.fuzzel_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetFuzzel(self.app.interface.fuzzel_box.text.clone())));
-                }
-                if self.app.interface.terminal_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetTerminalMenu(self.app.interface.terminal_menu.selected)));
-                }
-                if self.app.interface.terminal_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetTerminal(self.app.interface.terminal_box.text.clone())));
-                }
-                if self.app.interface.color_selector_font_selector.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetColorSelectorFont(self.app.interface.color_selector_font_selector.font_family.clone())));
-                }
-                if self.app.interface.menubar_font_selector.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetMenubarFont(self.app.interface.menubar_font_selector.font_family.clone())));
-                }
-                if self.app.interface.section_label_font_selector.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetSectionLabelFont(self.app.interface.section_label_font_selector.font_family.clone())));
-                }
-                if self.app.interface.nested_section_label_font_selector.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetNestedSectionLabelFont(self.app.interface.nested_section_label_font_selector.font_family.clone())));
-                }
-                if self.app.interface.borders_size_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetBordersSize(self.app.interface.borders_size_box.value)));
-                }
-                if self.app.interface.status_size_box.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::SetStatusSize(self.app.interface.status_size_box.value)));
-                }
-
-                let tf = &mut self.app.interface.windows;
-                for (i, sb) in tf.spinboxes.iter_mut().enumerate() {
-                    if sb.take_change() {
-                        actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetWidth(pages::interface::WidthParam::ALL[i], sb.value as u16))));
-                    }
-                }
-                if tf.cascade_offset_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetCascadeOffset(tf.cascade_offset_spinbox.value as u16))));
-                }
-                if tf.edge_gap_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetEdgeGap(tf.edge_gap_spinbox.value as u16))));
-                }
-                if tf.top_gap_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetTopGap(tf.top_gap_spinbox.value as u16))));
-                }
-                if tf.grid_gap_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetGridGap(tf.grid_gap_spinbox.value as u16))));
-                }
-                if tf.transition_duration_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetTransitionDuration(tf.transition_duration_spinbox.value as u16))));
-                }
-                if tf.status_height_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetStatusHeight(tf.status_height_spinbox.value as u16))));
-                }
-                for (idx, menu) in tf.tag_layout_menus.iter_mut().enumerate() {
-                    if menu.take_change() {
-                        actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetTagLayout(idx + 1, menu.selected))));
-                    }
-                }
-                if tf.side_panel_behavior_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetSidePanelBehavior(tf.side_panel_behavior_menu.selected))));
-                }
-                if tf.side_panel_position_menu.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetSidePanelPosition(tf.side_panel_position_menu.selected))));
-                }
-                if tf.side_panel_width_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetSidePanelWidth(tf.side_panel_width_spinbox.value as u16))));
-                }
-                if tf.side_panel_border_gap_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetSidePanelBorderGap(tf.side_panel_border_gap_spinbox.value as u16))));
-                }
-                if tf.side_panel_border_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetSidePanelBorderOpacity(tf.side_panel_border_opacity_spinbox.value as u16))));
-                }
-                if tf.fullscreen_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetFullscreenOpacity(tf.fullscreen_opacity_spinbox.value as u16))));
-                }
-                if tf.cascade_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetCascadeOpacity(tf.cascade_opacity_spinbox.value as u16))));
-                }
-                if tf.grid_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetGridOpacity(tf.grid_opacity_spinbox.value as u16))));
-                }
-                if tf.floating_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetFloatingOpacity(tf.floating_opacity_spinbox.value as u16))));
-                }
-                if tf.pinned_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetPinnedOpacity(tf.pinned_opacity_spinbox.value as u16))));
-                }
-                if tf.popup_opacity_spinbox.take_change() {
-                    actions.push(AppAction::Interface(pages::interface::InterfaceMessage::Windows(pages::interface::WindowsMessage::SetPopupOpacity(tf.popup_opacity_spinbox.value as u16))));
-                }
-            }
-            Page::Input => {
-                if self.app.input.rate_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyRepeat));
-                }
-                if self.app.input.delay_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyRepeat));
-                }
-                if self.app.input.scroll_friction_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyScrollFriction));
-                }
-                if self.app.input.scroll_speed_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyScrollSpeed));
-                }
-                if self.app.input.pointer_friction_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyPointerFriction));
-                }
-                if self.app.input.trackpad_friction_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyTrackpadFriction));
-                }
-                if self.app.input.trackpoint_accel_speed_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyTrackpointAccelSpeed));
-                }
-                if self.app.input.cursor_size_spinbox.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyCursorSize));
-                }
-                if self.app.input.tap_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleTapToClick));
-                }
-                if self.app.input.scroll_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleInertialScroll));
-                }
-                if self.app.input.natural_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleNaturalScroll));
-                }
-                if self.app.input.pointer_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleInertialPointer));
-                }
-                if self.app.input.trackpad_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleInertialTrackpad));
-                }
-                if self.app.input.dwtp_toggle.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ToggleDwtp));
-                }
-                if self.app.input.trackpoint_accel_profile_menu.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyTrackpointAccelProfile(self.app.input.trackpoint_accel_profile_menu.selected)));
-                }
-                if self.app.input.cursor_theme_menu.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyCursorTheme(self.app.input.cursor_theme_menu.selected)));
-                }
-                if self.app.input.zoom_in_box.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyZoomIn));
-                }
-                if self.app.input.zoom_out_box.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ApplyZoomOut));
-                }
-                if self.app.input.keybinds_control.take_change() {
-                    actions.push(AppAction::Input(pages::input::InputMessage::ReloadKeybinds));
-                }
-            }
-            Page::Display => {
-                if self.app.display.screensaver_enable_toggle.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::ToggleScreensaverEnable));
-                }
-                if self.app.display.screensaver_lock_screen_toggle.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::ToggleScreensaverLockScreen));
-                }
-                if self.app.display.screensaver_style_menu.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::SetScreensaverStyle(self.app.display.screensaver_style_menu.selected)));
-                }
-                if self.app.display.brightness_spinbox.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::BrightnessSet(self.app.display.brightness_spinbox.value as u32)));
-                }
-                if self.app.display.brightness_slider.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::BrightnessSet((self.app.display.brightness_slider.value() * 100.0).round() as u32)));
-                }
-                if self.app.display.screensaver_timeout_spinbox.take_change() {
-                    actions.push(AppAction::Display(pages::display::DisplayMessage::SetScreensaverTimeout(self.app.display.screensaver_timeout_spinbox.value)));
-                }
-            }
-            Page::System => {
-                if self.app.system_info.cpu_gov_menu.take_change() {
-                    if self.app.system_info.cpu_gov_menu.selected == 0 {
-                        actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::SetCpuPerformance));
-                    } else {
-                        actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::SetCpuPowersave));
-                    }
-                }
-                if self.app.system_info.gpu_gov_menu.take_change() {
-                    if self.app.system_info.gpu_gov_menu.selected == 0 {
-                        actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::SetGpuDefault));
-                    } else {
-                        actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::SetGpuPowersave));
-                    }
-                }
-                if self.app.system_info.notifications_enable_toggle.take_change() {
-                    actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::ToggleNotificationsEnable));
-                }
-                if self.app.system_info.notifications_bell_toggle.take_change() {
-                    actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::ToggleNotificationsBell));
-                }
-                if self.app.system_info.notifications_duration_spinbox.take_change() {
-                    actions.push(AppAction::SystemInfo(pages::system_info::SystemMessage::SetNotificationsDuration(self.app.system_info.notifications_duration_spinbox.value)));
-                }
-
-            }
-            Page::Accounts => {
-                if self.app.accounts.adding_new && self.app.accounts.email_box.take_change() {
-                    let email_val = self.app.accounts.email_box.text.trim().to_lowercase();
-                    if email_val.ends_with("@gmail.com") {
-                        self.app.accounts.imap_box.text = "imap.gmail.com:993".to_string();
-                        self.app.accounts.imap_box.edit_buffer = "imap.gmail.com:993".to_string();
-                        self.app.accounts.smtp_box.text = "smtp.gmail.com:465".to_string();
-                        self.app.accounts.smtp_box.edit_buffer = "smtp.gmail.com:465".to_string();
-                    } else if email_val.ends_with("@icloud.com") {
-                        self.app.accounts.imap_box.text = "imap.mail.me.com:993".to_string();
-                        self.app.accounts.imap_box.edit_buffer = "imap.mail.me.com:993".to_string();
-                        self.app.accounts.smtp_box.text = "smtp.mail.me.com:587".to_string();
-                        self.app.accounts.smtp_box.edit_buffer = "smtp.mail.me.com:587".to_string();
-                    } else if email_val.ends_with("@outlook.com") || email_val.ends_with("@hotmail.com") {
-                        self.app.accounts.imap_box.text = "outlook.office365.com:993".to_string();
-                        self.app.accounts.imap_box.edit_buffer = "outlook.office365.com:993".to_string();
-                        self.app.accounts.smtp_box.text = "smtp.office365.com:587".to_string();
-                        self.app.accounts.smtp_box.edit_buffer = "smtp.office365.com:587".to_string();
-                    }
-                }
-            }
-            Page::Audio => {
-                for (i, sb) in self.app.audio.sink_spinboxes.iter_mut().enumerate() {
-                    if sb.take_change() {
-                        let id = self.app.audio.sinks[i].id;
-                        actions.push(AppAction::Audio(pages::audio::AudioMessage::SinkVolume(id, sb.value as f32 / 100.0)));
-                    }
-                }
-                for (i, sb) in self.app.audio.source_spinboxes.iter_mut().enumerate() {
-                    if sb.take_change() {
-                        let id = self.app.audio.sources[i].id;
-                        actions.push(AppAction::Audio(pages::audio::AudioMessage::SourceVolume(id, sb.value as f32 / 100.0)));
-                    }
-                }
-                for (i, slider) in self.app.audio.sink_sliders.iter_mut().enumerate() {
-                    if slider.take_change() {
-                        let id = self.app.audio.sinks[i].id;
-                        actions.push(AppAction::Audio(pages::audio::AudioMessage::SinkVolume(id, slider.value() as f32 / 100.0)));
-                    }
-                }
-                for (i, slider) in self.app.audio.source_sliders.iter_mut().enumerate() {
-                    if slider.take_change() {
-                        let id = self.app.audio.sources[i].id;
-                        actions.push(AppAction::Audio(pages::audio::AudioMessage::SourceVolume(id, slider.value() as f32 / 100.0)));
-                    }
-                }
-            }
-            Page::Radios => {
-                let net = &mut self.app.network;
-                if net.wifi_toggle.take_change() {
-                    actions.push(AppAction::Radios(pages::network::NetworkMessage::ToggleWifi));
-                }
-                if net.bt_toggle.take_change() {
-                    actions.push(AppAction::Radios(pages::network::NetworkMessage::ToggleBluetooth));
-                }
-            }
-            _ => {}
-        }
+        self.app.get_current_page_mut().propagate_widget_changes(actions);
     }
 
     pub(crate) fn handle_mouse_wheel_internal(&mut self, delta: &cce_ui::widget::MouseScrollDelta, px: f32, py: f32) -> bool {
diff --git a/src/main.rs b/src/main.rs
index 7a76fe6..02dda4c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -201,11 +201,6 @@ struct SystemInterface {
     scrollable_text_items_start_idx: usize,
     scrollable_buttons_start_idx: usize,
     last_scroll_y: f32,
-    audio_sink_dragging: Option<usize>,
-    audio_source_dragging: Option<usize>,
-    display_brightness_dragging: bool,
-    status_box_opacity_dragging: bool,
-    status_box_blur_dragging: bool,
     page_sec_containers: Vec<cce_ui::widget::SectionContainer>,
     root_window: cce_ui::widget::Backplate,
     menubar: cce_ui::widget::Paginator,
@@ -308,11 +303,6 @@ impl cce_ui::engine::Application for SystemInterface {
             scrollable_text_items_start_idx: 0,
             scrollable_buttons_start_idx: 0,
             last_scroll_y: 0.0,
-            audio_sink_dragging: None,
-            audio_source_dragging: None,
-            display_brightness_dragging: false,
-            status_box_opacity_dragging: false,
-            status_box_blur_dragging: false,
             page_sec_containers: Vec::new(),
             root_window: cce_ui::widget::Backplate::new(0.0, 0.0, 820.0, 680.0)
                 .with_background([
diff --git a/src/pages/accounts.rs b/src/pages/accounts.rs
index 3e16e3f..f326341 100644
--- a/src/pages/accounts.rs
+++ b/src/pages/accounts.rs
@@ -802,3 +802,94 @@ pub fn update(state: &mut AccountsState, msg: AccountsMessage) {
         }
     }
 }
+
+impl crate::pages::AppPage for AccountsState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.email_box.clear_children(ctx);
+        self.email_box.set_parent(None, ctx);
+        self.password_box.clear_children(ctx);
+        self.password_box.set_parent(None, ctx);
+        self.imap_box.clear_children(ctx);
+        self.imap_box.set_parent(None, ctx);
+        self.smtp_box.clear_children(ctx);
+        self.smtp_box.set_parent(None, ctx);
+        self.oauth_client_id_box.clear_children(ctx);
+        self.oauth_client_id_box.set_parent(None, ctx);
+        self.oauth_client_secret_box.clear_children(ctx);
+        self.oauth_client_secret_box.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Accounts").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Modify Accounts").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+
+        if self.editing_oauth_creds {
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.oauth_client_id_box, ctx);
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.oauth_client_secret_box, ctx);
+        } else if self.adding_new {
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.email_box, ctx);
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.password_box, ctx);
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.imap_box, ctx);
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.smtp_box, ctx);
+        }
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        _sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, _actions: &mut Vec<crate::app::AppAction>) {
+        if self.adding_new && self.email_box.take_change() {
+            let email_val = self.email_box.text.trim().to_lowercase();
+            if email_val.ends_with("@gmail.com") {
+                self.imap_box.text = "imap.gmail.com:993".to_string();
+                self.imap_box.edit_buffer = "imap.gmail.com:993".to_string();
+                self.smtp_box.text = "smtp.gmail.com:465".to_string();
+                self.smtp_box.edit_buffer = "smtp.gmail.com:465".to_string();
+            } else if email_val.ends_with("@icloud.com") {
+                self.imap_box.text = "imap.mail.me.com:993".to_string();
+                self.imap_box.edit_buffer = "imap.mail.me.com:993".to_string();
+                self.smtp_box.text = "smtp.mail.me.com:587".to_string();
+                self.smtp_box.edit_buffer = "smtp.mail.me.com:587".to_string();
+            } else if email_val.ends_with("@outlook.com") || email_val.ends_with("@hotmail.com") {
+                self.imap_box.text = "outlook.office365.com:993".to_string();
+                self.imap_box.edit_buffer = "outlook.office365.com:993".to_string();
+                self.smtp_box.text = "smtp.office365.com:587".to_string();
+                self.smtp_box.edit_buffer = "smtp.office365.com:587".to_string();
+            }
+        }
+    }
+}
+
diff --git a/src/pages/audio.rs b/src/pages/audio.rs
index 681cc30..6323738 100644
--- a/src/pages/audio.rs
+++ b/src/pages/audio.rs
@@ -29,6 +29,8 @@ pub struct AudioState {
     pub source_spinboxes: Vec<Box<Spinbox>>,
     pub sink_sliders: Vec<Box<Slider>>,
     pub source_sliders: Vec<Box<Slider>>,
+    pub sink_dragging: Option<usize>,
+    pub source_dragging: Option<usize>,
 }
 
 #[derive(Debug, Clone)]
@@ -128,6 +130,8 @@ pub async fn fetch_audio_state() -> AudioState {
         source_spinboxes: Vec::new(),
         sink_sliders: Vec::new(),
         source_sliders: Vec::new(),
+        sink_dragging: None,
+        source_dragging: None,
     }
 }
 
@@ -402,6 +406,174 @@ pub fn update(state: &mut AudioState, msg: AudioMessage) {
     }
 }
 
+impl crate::pages::AppPage for AudioState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        for sb in &mut self.sink_spinboxes {
+            sb.clear_children(ctx);
+            sb.set_parent(None, ctx);
+        }
+        for sb in &mut self.source_spinboxes {
+            sb.clear_children(ctx);
+            sb.set_parent(None, ctx);
+        }
+        for slider in &mut self.sink_sliders {
+            slider.clear_children(ctx);
+            slider.set_parent(None, ctx);
+        }
+        for slider in &mut self.source_sliders {
+            slider.clear_children(ctx);
+            slider.set_parent(None, ctx);
+        }
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Output").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Input").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+
+        for sb in &mut self.sink_spinboxes {
+            cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut **sb, ctx);
+        }
+        for sb in &mut self.source_spinboxes {
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut **sb, ctx);
+        }
+        for slider in &mut self.sink_sliders {
+            cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut **slider, ctx);
+        }
+        for slider in &mut self.source_sliders {
+            cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut **slider, ctx);
+        }
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        for (i, sb) in self.sink_spinboxes.iter_mut().enumerate() {
+            if sb.take_change() {
+                let id = self.sinks[i].id;
+                actions.push(AppAction::Audio(AudioMessage::SinkVolume(id, sb.value as f32 / 100.0)));
+            }
+        }
+        for (i, sb) in self.source_spinboxes.iter_mut().enumerate() {
+            if sb.take_change() {
+                let id = self.sources[i].id;
+                actions.push(AppAction::Audio(AudioMessage::SourceVolume(id, sb.value as f32 / 100.0)));
+            }
+        }
+        for (i, slider) in self.sink_sliders.iter_mut().enumerate() {
+            if slider.take_change() {
+                let id = self.sinks[i].id;
+                actions.push(AppAction::Audio(AudioMessage::SinkVolume(id, slider.value() as f32 / 100.0)));
+            }
+        }
+        for (i, slider) in self.source_sliders.iter_mut().enumerate() {
+            if slider.take_change() {
+                let id = self.sources[i].id;
+                actions.push(AppAction::Audio(AudioMessage::SourceVolume(id, slider.value() as f32 / 100.0)));
+            }
+        }
+    }
+
+    fn handle_pointer_move(
+        &mut self,
+        lx: f32,
+        ly: f32,
+        actions: &mut Vec<crate::app::AppAction>,
+        _ctx: &mut cce_ui::context::UiContext,
+    ) -> bool {
+        if let Some(idx) = self.sink_dragging {
+            if let Some(slider) = self.sink_sliders.get_mut(idx) {
+                if slider.drag_update(lx, ly) {
+                    let id = self.sinks[idx].id;
+                    let val = slider.value();
+                    if idx < self.sink_spinboxes.len() {
+                        self.sink_spinboxes[idx].value = (val * 100.0).round() as i32;
+                    }
+                    actions.push(AppAction::Audio(AudioMessage::SinkVolume(id, val)));
+                    return true;
+                }
+            }
+        } else if let Some(idx) = self.source_dragging {
+            if let Some(slider) = self.source_sliders.get_mut(idx) {
+                if slider.drag_update(lx, ly) {
+                    let id = self.sources[idx].id;
+                    let val = slider.value();
+                    if idx < self.source_spinboxes.len() {
+                        self.source_spinboxes[idx].value = (val * 100.0).round() as i32;
+                    }
+                    actions.push(AppAction::Audio(AudioMessage::SourceVolume(id, val)));
+                    return true;
+                }
+            }
+        }
+        false
+    }
+
+    fn handle_pointer_down(&mut self, _lx: f32, _ly: f32, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        for (i, s) in self.sink_sliders.iter().enumerate() {
+            if s.is_dragging() {
+                self.sink_dragging = Some(i);
+                return true;
+            }
+        }
+        for (i, s) in self.source_sliders.iter().enumerate() {
+            if s.is_dragging() {
+                self.source_dragging = Some(i);
+                return true;
+            }
+        }
+        false
+    }
+
+    fn handle_pointer_up(&mut self, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        let mut any = false;
+        if let Some(idx) = self.sink_dragging {
+            self.sink_sliders[idx].drag_end();
+            self.sink_dragging = None;
+            any = true;
+        }
+        if let Some(idx) = self.source_dragging {
+            self.source_sliders[idx].drag_end();
+            self.source_dragging = None;
+            any = true;
+        }
+        any
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/display.rs b/src/pages/display.rs
index 75187d1..e516eac 100644
--- a/src/pages/display.rs
+++ b/src/pages/display.rs
@@ -1,4 +1,4 @@
-use crate::app::{PageContent, SectionContextExt};
+use crate::app::{AppAction, PageContent, SectionContextExt};
 use cce_ui::layout::{PageLayoutBuilder, LayoutStrategy};
 use cce_ui::widget::{Spinbox, Label, Element, Toggle, Dropdown, Slider};
 
@@ -63,6 +63,7 @@ pub struct DisplayState {
     pub screensaver_lock_screen_toggle: Toggle,
     pub screensaver_style: String,
     pub screensaver_style_menu: Dropdown,
+    pub brightness_dragging: bool,
 }
 
 impl Default for DisplayState {
@@ -91,6 +92,7 @@ impl Default for DisplayState {
                 1,
             ).with_label("Screensaver Style")
             .with_config(CONFIG_PATH, "style"),
+            brightness_dragging: false,
         }
     }
 }
@@ -178,6 +180,7 @@ pub async fn fetch_display_state() -> DisplayState {
             style_idx,
         ).with_label("Screensaver Style")
         .with_config(CONFIG_PATH, "style"),
+        brightness_dragging: false,
     }
 }
 
@@ -454,6 +457,164 @@ pub fn update(state: &mut DisplayState, msg: DisplayMessage) {
     }
 }
 
+impl crate::pages::AppPage for DisplayState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.brightness_spinbox.clear_children(ctx);
+        self.brightness_spinbox.set_parent(None, ctx);
+        self.brightness_slider.clear_children(ctx);
+        self.brightness_slider.set_parent(None, ctx);
+        self.night_light_label.clear_children(ctx);
+        self.night_light_label.set_parent(None, ctx);
+        self.screensaver_enable_toggle.clear_children(ctx);
+        self.screensaver_enable_toggle.set_parent(None, ctx);
+        self.screensaver_lock_screen_toggle.clear_children(ctx);
+        self.screensaver_lock_screen_toggle.set_parent(None, ctx);
+        self.screensaver_timeout_spinbox.clear_children(ctx);
+        self.screensaver_timeout_spinbox.set_parent(None, ctx);
+        self.screensaver_style_menu.clear_children(ctx);
+        self.screensaver_style_menu.set_parent(None, ctx);
+        for out in &mut self.outputs {
+            out.name_label.clear_children(ctx);
+            out.name_label.set_parent(None, ctx);
+            out.resolution_label.clear_children(ctx);
+            out.resolution_label.set_parent(None, ctx);
+            if let Some(ref mut scale_lbl) = out.scale_label {
+                scale_lbl.clear_children(ctx);
+                scale_lbl.set_parent(None, ctx);
+            }
+        }
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Brightness").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Night Light").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Outputs").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Screensaver Settings").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[2], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[3], ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.brightness_slider, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.brightness_spinbox, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.night_light_label, ctx);
+
+        for out in &mut self.outputs {
+            cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut out.name_label, ctx);
+            cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut out.resolution_label, ctx);
+            if let Some(ref mut scale_lbl) = out.scale_label {
+                cce_ui::widget::link_parent_child(&mut sec_containers[2], scale_lbl, ctx);
+            }
+        }
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.screensaver_enable_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.screensaver_lock_screen_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.screensaver_timeout_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.screensaver_style_menu, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        _sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        if self.screensaver_enable_toggle.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::ToggleScreensaverEnable));
+        }
+        if self.screensaver_lock_screen_toggle.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::ToggleScreensaverLockScreen));
+        }
+        if self.screensaver_style_menu.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::SetScreensaverStyle(self.screensaver_style_menu.selected)));
+        }
+        if self.brightness_spinbox.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::BrightnessSet(self.brightness_spinbox.value as u32)));
+        }
+        if self.brightness_slider.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::BrightnessSet((self.brightness_slider.value() * 100.0).round() as u32)));
+        }
+        if self.screensaver_timeout_spinbox.take_change() {
+            actions.push(AppAction::Display(DisplayMessage::SetScreensaverTimeout(self.screensaver_timeout_spinbox.value)));
+        }
+    }
+
+    fn handle_pointer_move(
+        &mut self,
+        lx: f32,
+        ly: f32,
+        actions: &mut Vec<crate::app::AppAction>,
+        _ctx: &mut cce_ui::context::UiContext,
+    ) -> bool {
+        if self.brightness_dragging {
+            if self.brightness_slider.drag_update(lx, ly) {
+                let val = (self.brightness_slider.value() * 100.0).round() as u32;
+                self.brightness_spinbox.value = val as i32;
+                actions.push(AppAction::Display(DisplayMessage::BrightnessSet(val)));
+                return true;
+            }
+        }
+        false
+    }
+
+    fn handle_pointer_down(&mut self, _lx: f32, _ly: f32, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        if self.brightness_slider.is_dragging() {
+            self.brightness_dragging = true;
+            return true;
+        }
+        false
+    }
+
+    fn handle_pointer_up(&mut self, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        if self.brightness_dragging {
+            self.brightness_slider.drag_end();
+            self.brightness_dragging = false;
+            return true;
+        }
+        false
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/input.rs b/src/pages/input.rs
index 1238388..464688f 100644
--- a/src/pages/input.rs
+++ b/src/pages/input.rs
@@ -1,7 +1,7 @@
 use std::fs;
 use std::io::Write;
 
-use crate::app::PageContent;
+use crate::app::{AppAction, PageContent};
 use cce_ui::layout::{PageLayoutBuilder, LayoutStrategy};
 use cce_ui::widget::{Spinbox, Toggle, Trackpad, Dropdown, Finger, Element, TextBox, KeybindsControl};
 
@@ -591,6 +591,182 @@ pub fn update(state: &mut InputState, msg: InputMessage) {
     }
 }
 
+impl crate::pages::AppPage for InputState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.tap_toggle.clear_children(ctx);
+        self.tap_toggle.set_parent(None, ctx);
+        self.trackpad.clear_children(ctx);
+        self.trackpad.set_parent(None, ctx);
+
+        self.dwtp_toggle.clear_children(ctx);
+        self.dwtp_toggle.set_parent(None, ctx);
+        self.trackpoint_accel_speed_spinbox.clear_children(ctx);
+        self.trackpoint_accel_speed_spinbox.set_parent(None, ctx);
+        self.trackpoint_accel_profile_menu.clear_children(ctx);
+        self.trackpoint_accel_profile_menu.set_parent(None, ctx);
+
+        self.rate_spinbox.clear_children(ctx);
+        self.rate_spinbox.set_parent(None, ctx);
+        self.delay_spinbox.clear_children(ctx);
+        self.delay_spinbox.set_parent(None, ctx);
+
+        self.cursor_theme_menu.clear_children(ctx);
+        self.cursor_theme_menu.set_parent(None, ctx);
+        self.cursor_size_spinbox.clear_children(ctx);
+        self.cursor_size_spinbox.set_parent(None, ctx);
+
+        self.scroll_toggle.clear_children(ctx);
+        self.scroll_toggle.set_parent(None, ctx);
+        self.scroll_friction_spinbox.clear_children(ctx);
+        self.scroll_friction_spinbox.set_parent(None, ctx);
+        self.natural_toggle.clear_children(ctx);
+        self.natural_toggle.set_parent(None, ctx);
+        self.scroll_speed_spinbox.clear_children(ctx);
+        self.scroll_speed_spinbox.set_parent(None, ctx);
+
+        self.pointer_toggle.clear_children(ctx);
+        self.pointer_toggle.set_parent(None, ctx);
+        self.pointer_friction_spinbox.clear_children(ctx);
+        self.pointer_friction_spinbox.set_parent(None, ctx);
+        self.trackpad_toggle.clear_children(ctx);
+        self.trackpad_toggle.set_parent(None, ctx);
+        self.trackpad_friction_spinbox.clear_children(ctx);
+        self.trackpad_friction_spinbox.set_parent(None, ctx);
+
+        self.zoom_in_box.clear_children(ctx);
+        self.zoom_in_box.set_parent(None, ctx);
+        self.zoom_out_box.clear_children(ctx);
+        self.zoom_out_box.set_parent(None, ctx);
+        self.keybinds_control.clear_children(ctx);
+        self.keybinds_control.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Touchpad").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Trackpoint").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Keyboard").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Cursor").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Scrolling").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Inertial Input").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Graph").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Keyboard Bindings").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        for i in 0..8 {
+            cce_ui::widget::link_parent_child(page_root, &mut sec_containers[i], ctx);
+        }
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.tap_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.trackpad, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.dwtp_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.trackpoint_accel_speed_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.trackpoint_accel_profile_menu, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.rate_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.delay_spinbox, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.cursor_theme_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.cursor_size_spinbox, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.scroll_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.scroll_friction_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.natural_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.scroll_speed_spinbox, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.pointer_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.pointer_friction_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.trackpad_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.trackpad_friction_spinbox, ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.zoom_in_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.zoom_out_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.keybinds_control, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        if self.rate_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyRepeat));
+        }
+        if self.delay_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyRepeat));
+        }
+        if self.scroll_friction_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyScrollFriction));
+        }
+        if self.scroll_speed_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyScrollSpeed));
+        }
+        if self.pointer_friction_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyPointerFriction));
+        }
+        if self.trackpad_friction_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyTrackpadFriction));
+        }
+        if self.trackpoint_accel_speed_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyTrackpointAccelSpeed));
+        }
+        if self.cursor_size_spinbox.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyCursorSize));
+        }
+        if self.tap_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleTapToClick));
+        }
+        if self.scroll_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleInertialScroll));
+        }
+        if self.natural_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleNaturalScroll));
+        }
+        if self.pointer_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleInertialPointer));
+        }
+        if self.trackpad_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleInertialTrackpad));
+        }
+        if self.dwtp_toggle.take_change() {
+            actions.push(AppAction::Input(InputMessage::ToggleDwtp));
+        }
+        if self.trackpoint_accel_profile_menu.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyTrackpointAccelProfile(self.trackpoint_accel_profile_menu.selected)));
+        }
+        if self.cursor_theme_menu.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyCursorTheme(self.cursor_theme_menu.selected)));
+        }
+        if self.zoom_in_box.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyZoomIn));
+        }
+        if self.zoom_out_box.take_change() {
+            actions.push(AppAction::Input(InputMessage::ApplyZoomOut));
+        }
+        if self.keybinds_control.take_change() {
+            actions.push(AppAction::Input(InputMessage::ReloadKeybinds));
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/interface.rs b/src/pages/interface.rs
index 97bf528..04378e5 100644
--- a/src/pages/interface.rs
+++ b/src/pages/interface.rs
@@ -1,6 +1,6 @@
 use std::fs;
 use std::io::Write;
-use crate::app::{PageContent, SectionContextExt};
+use crate::app::{AppAction, PageContent, SectionContextExt};
 use cce_ui::layout::{render_widget, PageLayoutBuilder, LayoutStrategy};
 use cce_ui::widget::{
     ColorSelector, Spinbox, Element, Dropdown, TextBox, FontSelector, Toggle, MultiControl,
@@ -260,6 +260,45 @@ pub enum WindowsMessage {
     Refreshed(WindowsState),
 }
 
+#[derive(Debug, Clone)]
+pub struct StatusInterfaceControls {
+    pub loaded: bool,
+    pub font_size: u16,
+    pub separators: bool,
+    pub underline: bool,
+    pub running: bool,
+    pub label: Label,
+    pub separators_toggle: Toggle,
+    pub underline_toggle: Toggle,
+    pub box_opacity: f32,
+    pub box_blur: f32,
+    pub box_opacity_slider: Slider,
+    pub box_blur_slider: Slider,
+    pub opacity_dragging: bool,
+    pub blur_dragging: bool,
+}
+
+impl Default for StatusInterfaceControls {
+    fn default() -> Self {
+        Self {
+            loaded: false,
+            font_size: 11,
+            separators: true,
+            underline: true,
+            running: false,
+            label: Label::new("Status Interface: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
+            separators_toggle: Toggle::new().with_label("Show Separators").with_config(CONFIG_PATH, "status_separators"),
+            underline_toggle: Toggle::new().with_label("Show Underline").with_config(CONFIG_PATH, "status_underline"),
+            box_opacity: 1.0,
+            box_blur: 0.0,
+            box_opacity_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(1.0).with_label("Background Opacity").with_config(CONFIG_PATH, "status_box_opacity"),
+            box_blur_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(0.0).with_label("Background Blur").with_config(CONFIG_PATH, "status_box_blur"),
+            opacity_dragging: false,
+            blur_dragging: false,
+        }
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct InterfaceState {
     pub windows: WindowsState,
@@ -360,18 +399,7 @@ pub struct InterfaceState {
     pub status_padding_spinbox: Spinbox,
     pub status_module_spacing: u16,
     pub status_module_spacing_spinbox: Spinbox,
-    pub status_loaded: bool,
-    pub status_font_size: u16,
-    pub status_separators: bool,
-    pub status_underline: bool,
-    pub status_running: bool,
-    pub status_label: Label,
-    pub status_separators_toggle: Toggle,
-    pub status_underline_toggle: Toggle,
-    pub status_box_opacity: f32,
-    pub status_box_blur: f32,
-    pub status_box_opacity_slider: Slider,
-    pub status_box_blur_slider: Slider,
+    pub status_controls: StatusInterfaceControls,
     pub nested_section_label_alignment: u8,
     pub label_alignment_menu: Dropdown,
     pub nested_section_label_offset: i16,
@@ -614,18 +642,7 @@ impl Default for InterfaceState {
             status_padding_spinbox: Spinbox::new(8, 0, 32, 1).with_label("Padding").with_unit("px").with_config(CONFIG_PATH, "status_padding"),
             status_module_spacing: 8,
             status_module_spacing_spinbox: Spinbox::new(8, 0, 100, 1).with_label("Spacing").with_unit("px").with_config(CONFIG_PATH, "status_module_spacing"),
-            status_loaded: false,
-            status_font_size: 11,
-            status_separators: true,
-            status_underline: true,
-            status_running: false,
-            status_label: Label::new("Status Interface: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
-            status_separators_toggle: Toggle::new().with_label("Show Separators").with_config(CONFIG_PATH, "status_separators"),
-            status_underline_toggle: Toggle::new().with_label("Show Underline").with_config(CONFIG_PATH, "status_underline"),
-            status_box_opacity: 1.0,
-            status_box_blur: 0.0,
-            status_box_opacity_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(1.0).with_label("Background Opacity").with_config(CONFIG_PATH, "status_box_opacity"),
-            status_box_blur_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(0.0).with_label("Background Blur").with_config(CONFIG_PATH, "status_box_blur"),
+            status_controls: StatusInterfaceControls::default(),
             custom_multicontrol: MultiControl::new("custom_parameters".to_string()).with_label("custom_parameters"),
             layout_status: None,
         }
@@ -978,18 +995,7 @@ pub fn read_interface_config() -> InterfaceState {
         status_padding_spinbox: Spinbox::new(status_padding as i32, 0, 32, 1).with_label("Padding").with_unit("px").with_config(CONFIG_PATH, "status_padding"),
         status_module_spacing,
         status_module_spacing_spinbox: Spinbox::new(status_module_spacing as i32, 0, 100, 1).with_label("Spacing").with_unit("px").with_config(CONFIG_PATH, "status_module_spacing"),
-        status_loaded: false,
-        status_font_size: 11,
-        status_separators: true,
-        status_underline: true,
-        status_running: false,
-        status_label: Label::new("Status Interface: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
-        status_separators_toggle: Toggle::new().with_label("Show Separators").with_config(CONFIG_PATH, "status_separators"),
-        status_underline_toggle: Toggle::new().with_label("Show Underline").with_config(CONFIG_PATH, "status_underline"),
-        status_box_opacity: 1.0,
-        status_box_blur: 0.0,
-        status_box_opacity_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(1.0).with_label("Background Opacity").with_config(CONFIG_PATH, "status_box_opacity"),
-        status_box_blur_slider: Slider::new().with_range(0.0, 100.0).with_scroll(true).with_value(0.0).with_label("Background Blur").with_config(CONFIG_PATH, "status_box_blur"),
+        status_controls: StatusInterfaceControls::default(),
         nested_section_label_alignment,
         label_alignment_menu: Dropdown::new(
             vec!["Left".to_string(), "Center".to_string(), "Right".to_string()],
@@ -2803,42 +2809,42 @@ pub fn view(state: &mut InterfaceState, cx: f32, cy: f32, cw: f32, ch: f32, sec_
         sec.widget_full(&mut state.status_module_spacing_spinbox, 44.0, ctx);
         sec.spacing(8.0);
 
-        if !state.status_loaded {
+        if !state.status_controls.loaded {
             sec.text("Loading Status Interface status...", 12.0, 0.0, 12.0, TEXT_DIM);
             sec.spacing(8.0);
         } else {
             // Status
-            let status_text = if state.status_running { "Status Interface: Running" } else { "Status Interface: Stopped" };
-            let status_color = if state.status_running { [92, 143, 97] } else { [170, 51, 51] };
-            state.status_label.set_text(status_text);
-            state.status_label.set_color(status_color);
-            sec.widget_full(&mut state.status_label, 20.0, ctx);
+            let status_text = if state.status_controls.running { "Status Interface: Running" } else { "Status Interface: Stopped" };
+            let status_color = if state.status_controls.running { [92, 143, 97] } else { [170, 51, 51] };
+            state.status_controls.label.set_text(status_text);
+            state.status_controls.label.set_color(status_color);
+            sec.widget_full(&mut state.status_controls.label, 20.0, ctx);
             sec.spacing(8.0);
 
             // Separators toggle
-            state.status_separators_toggle.set_toggled(state.status_separators);
-            sec.widget_full(&mut state.status_separators_toggle, cce_ui::layout::toggle_height(), ctx);
+            state.status_controls.separators_toggle.set_toggled(state.status_controls.separators);
+            sec.widget_full(&mut state.status_controls.separators_toggle, cce_ui::layout::toggle_height(), ctx);
             sec.spacing(8.0);
 
             // Underline toggle
-            state.status_underline_toggle.set_toggled(state.status_underline);
-            sec.widget_full(&mut state.status_underline_toggle, cce_ui::layout::toggle_height(), ctx);
+            state.status_controls.underline_toggle.set_toggled(state.status_controls.underline);
+            sec.widget_full(&mut state.status_controls.underline_toggle, cce_ui::layout::toggle_height(), ctx);
             sec.spacing(8.0);
 
             // Opacity slider
-            state.status_box_opacity_slider.set_label(&format!("Background Opacity: {}%", (state.status_box_opacity * 100.0).round() as i32));
-            state.status_box_opacity_slider.set_value(state.status_box_opacity);
-            let label_h_op = cce_ui::widget::label_offset(&state.status_box_opacity_slider);
+            state.status_controls.box_opacity_slider.set_label(&format!("Background Opacity: {}%", (state.status_controls.box_opacity * 100.0).round() as i32));
+            state.status_controls.box_opacity_slider.set_value(state.status_controls.box_opacity);
+            let label_h_op = cce_ui::widget::label_offset(&state.status_controls.box_opacity_slider);
             let slider_h_op = cce_ui::layout::slider_height() + label_h_op;
-            sec.widget_full(&mut state.status_box_opacity_slider, slider_h_op, ctx);
+            sec.widget_full(&mut state.status_controls.box_opacity_slider, slider_h_op, ctx);
             sec.spacing(8.0);
 
             // Blur slider
-            state.status_box_blur_slider.set_label(&format!("Background Blur: {}%", (state.status_box_blur * 100.0).round() as i32));
-            state.status_box_blur_slider.set_value(state.status_box_blur);
-            let label_h_bl = cce_ui::widget::label_offset(&state.status_box_blur_slider);
+            state.status_controls.box_blur_slider.set_label(&format!("Background Blur: {}%", (state.status_controls.box_blur * 100.0).round() as i32));
+            state.status_controls.box_blur_slider.set_value(state.status_controls.box_blur);
+            let label_h_bl = cce_ui::widget::label_offset(&state.status_controls.box_blur_slider);
             let slider_h_bl = cce_ui::layout::slider_height() + label_h_bl;
-            sec.widget_full(&mut state.status_box_blur_slider, slider_h_bl, ctx);
+            sec.widget_full(&mut state.status_controls.box_blur_slider, slider_h_bl, ctx);
             sec.spacing(8.0);
 
             // Reload button
@@ -3598,35 +3604,35 @@ pub fn update(state: &mut InterfaceState, msg: InterfaceMessage) {
             apply_status_padding(padding);
         }
         InterfaceMessage::StatusRefreshed(new) => {
-            let was_status_hovered = state.status_label.hovered();
-            let was_separators_hovered = state.status_separators_toggle.hovered();
-            let was_underline_hovered = state.status_underline_toggle.hovered();
-            let was_opacity_hovered = state.status_box_opacity_slider.hovered();
-            let was_blur_hovered = state.status_box_blur_slider.hovered();
-
-            state.status_loaded = true;
-            state.status_font_size = new.font_size;
+            let was_status_hovered = state.status_controls.label.hovered();
+            let was_separators_hovered = state.status_controls.separators_toggle.hovered();
+            let was_underline_hovered = state.status_controls.underline_toggle.hovered();
+            let was_opacity_hovered = state.status_controls.box_opacity_slider.hovered();
+            let was_blur_hovered = state.status_controls.box_blur_slider.hovered();
+
+            state.status_controls.loaded = true;
+            state.status_controls.font_size = new.font_size;
             state.status_padding = new.padding;
-            state.status_separators = new.separators;
-            state.status_underline = new.underline;
-            state.status_running = new.running;
-            state.status_box_opacity = new.bg_opacity;
-            state.status_box_blur = new.bg_blur;
-
-            state.status_label.set_hovered(was_status_hovered);
-            state.status_separators_toggle.set_hovered(was_separators_hovered);
-            state.status_underline_toggle.set_hovered(was_underline_hovered);
-            state.status_box_opacity_slider.set_hovered(was_opacity_hovered);
-            state.status_box_blur_slider.set_hovered(was_blur_hovered);
+            state.status_controls.separators = new.separators;
+            state.status_controls.underline = new.underline;
+            state.status_controls.running = new.running;
+            state.status_controls.box_opacity = new.bg_opacity;
+            state.status_controls.box_blur = new.bg_blur;
+
+            state.status_controls.label.set_hovered(was_status_hovered);
+            state.status_controls.separators_toggle.set_hovered(was_separators_hovered);
+            state.status_controls.underline_toggle.set_hovered(was_underline_hovered);
+            state.status_controls.box_opacity_slider.set_hovered(was_opacity_hovered);
+            state.status_controls.box_blur_slider.set_hovered(was_blur_hovered);
         }
         InterfaceMessage::StatusToggleSeparators => {
-            state.status_separators = !state.status_separators;
-            write_status_separators(state.status_separators);
+            state.status_controls.separators = !state.status_controls.separators;
+            write_status_separators(state.status_controls.separators);
             status_interface_reload();
         }
         InterfaceMessage::StatusToggleUnderline => {
-            state.status_underline = !state.status_underline;
-            write_status_underline(state.status_underline);
+            state.status_controls.underline = !state.status_controls.underline;
+            write_status_underline(state.status_controls.underline);
             status_interface_reload();
         }
         InterfaceMessage::StatusSetPadding(val) => {
@@ -3635,12 +3641,12 @@ pub fn update(state: &mut InterfaceState, msg: InterfaceMessage) {
             status_interface_reload();
         }
         InterfaceMessage::StatusSetBoxOpacity(val) => {
-            state.status_box_opacity = val;
+            state.status_controls.box_opacity = val;
             write_status_box_opacity(val);
             status_interface_reload();
         }
         InterfaceMessage::StatusSetBoxBlur(val) => {
-            state.status_box_blur = val;
+            state.status_controls.box_blur = val;
             write_status_box_blur(val);
             status_interface_reload();
         }
@@ -6104,5 +6110,681 @@ mod tests {
     }
 }
 
+impl crate::pages::AppPage for InterfaceState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        for sb in &mut self.windows.spinboxes {
+            sb.clear_children(ctx);
+            sb.set_parent(None, ctx);
+        }
+        self.windows.cascade_offset_spinbox.clear_children(ctx);
+        self.windows.cascade_offset_spinbox.set_parent(None, ctx);
+        self.windows.edge_gap_spinbox.clear_children(ctx);
+        self.windows.edge_gap_spinbox.set_parent(None, ctx);
+        self.windows.top_gap_spinbox.clear_children(ctx);
+        self.windows.top_gap_spinbox.set_parent(None, ctx);
+        self.windows.grid_gap_spinbox.clear_children(ctx);
+        self.windows.grid_gap_spinbox.set_parent(None, ctx);
+        self.windows.transition_duration_spinbox.clear_children(ctx);
+        self.windows.transition_duration_spinbox.set_parent(None, ctx);
+        self.windows.status_height_spinbox.clear_children(ctx);
+        self.windows.status_height_spinbox.set_parent(None, ctx);
+
+        for cs in &mut self.color_selectors {
+            cs.clear_children(ctx);
+            cs.set_parent(None, ctx);
+        }
+        self.menubar_opacity_spinbox.clear_children(ctx);
+        self.menubar_opacity_spinbox.set_parent(None, ctx);
+        self.button_padding_spinbox.clear_children(ctx);
+        self.button_padding_spinbox.set_parent(None, ctx);
+        self.section_padding_spinbox.clear_children(ctx);
+        self.section_padding_spinbox.set_parent(None, ctx);
+        self.label_alignment_menu.clear_children(ctx);
+        self.label_alignment_menu.set_parent(None, ctx);
+        self.label_offset_spinbox.clear_children(ctx);
+        self.label_offset_spinbox.set_parent(None, ctx);
+        self.label_margin_spinbox.clear_children(ctx);
+        self.label_margin_spinbox.set_parent(None, ctx);
+        self.plate_padding_spinbox.clear_children(ctx);
+        self.plate_padding_spinbox.set_parent(None, ctx);
+        self.graph_show_grid_toggle.clear_children(ctx);
+        self.graph_show_grid_toggle.set_parent(None, ctx);
+        self.graph_snap_enabled_toggle.clear_children(ctx);
+        self.graph_snap_enabled_toggle.set_parent(None, ctx);
+        self.graph_uniform_background_toggle.clear_children(ctx);
+        self.graph_uniform_background_toggle.set_parent(None, ctx);
+        self.graph_cell_opacity_spinbox.clear_children(ctx);
+        self.graph_cell_opacity_spinbox.set_parent(None, ctx);
+        self.graph_gap_opacity_spinbox.clear_children(ctx);
+        self.graph_gap_opacity_spinbox.set_parent(None, ctx);
+        self.graph_gap_width_spinbox.clear_children(ctx);
+        self.graph_gap_width_spinbox.set_parent(None, ctx);
+        self.page_margin_spinbox.clear_children(ctx);
+        self.page_margin_spinbox.set_parent(None, ctx);
+        self.desktop_grid_scale_spinbox.clear_children(ctx);
+        self.desktop_grid_scale_spinbox.set_parent(None, ctx);
+        self.desktop_line_width_spinbox.clear_children(ctx);
+        self.desktop_line_width_spinbox.set_parent(None, ctx);
+        self.grid_min_col_width_spinbox.clear_children(ctx);
+        self.grid_min_col_width_spinbox.set_parent(None, ctx);
+        self.spinbox_height_spinbox.clear_children(ctx);
+        self.spinbox_height_spinbox.set_parent(None, ctx);
+        self.spinbox_corner_radius_spinbox.clear_children(ctx);
+        self.spinbox_corner_radius_spinbox.set_parent(None, ctx);
+        self.toggle_height_spinbox.clear_children(ctx);
+        self.toggle_height_spinbox.set_parent(None, ctx);
+        self.toggle_corner_radius_spinbox.clear_children(ctx);
+        self.toggle_corner_radius_spinbox.set_parent(None, ctx);
+
+        self.color_selector_height_spinbox.clear_children(ctx);
+        self.color_selector_height_spinbox.set_parent(None, ctx);
+        self.color_selector_corner_radius_spinbox.clear_children(ctx);
+        self.color_selector_corner_radius_spinbox.set_parent(None, ctx);
+        self.plate_opacity_spinbox.clear_children(ctx);
+        self.plate_opacity_spinbox.set_parent(None, ctx);
+        self.plate_corner_radius_spinbox.clear_children(ctx);
+        self.plate_corner_radius_spinbox.set_parent(None, ctx);
+        self.page_opacity_spinbox.clear_children(ctx);
+        self.page_opacity_spinbox.set_parent(None, ctx);
+        self.layer_opacity_spinbox.clear_children(ctx);
+        self.layer_opacity_spinbox.set_parent(None, ctx);
+
+        self.color_selector_preview_corner_radius_spinbox.clear_children(ctx);
+        self.color_selector_preview_corner_radius_spinbox.set_parent(None, ctx);
+        self.color_selector_preview_margin_spinbox.clear_children(ctx);
+        self.color_selector_preview_margin_spinbox.set_parent(None, ctx);
+        self.textbox_height_spinbox.clear_children(ctx);
+        self.textbox_height_spinbox.set_parent(None, ctx);
+        self.textbox_corner_radius_spinbox.clear_children(ctx);
+        self.textbox_corner_radius_spinbox.set_parent(None, ctx);
+        self.slider_height_spinbox.clear_children(ctx);
+        self.slider_height_spinbox.set_parent(None, ctx);
+        self.color_selector_font_selector.clear_children(ctx);
+        self.color_selector_font_selector.set_parent(None, ctx);
+        self.menubar_font_selector.clear_children(ctx);
+        self.menubar_font_selector.set_parent(None, ctx);
+        self.breadcrumb_font_selector.clear_children(ctx);
+        self.breadcrumb_font_selector.set_parent(None, ctx);
+        self.section_label_font_selector.clear_children(ctx);
+        self.section_label_font_selector.set_parent(None, ctx);
+        self.nested_section_label_font_selector.clear_children(ctx);
+        self.nested_section_label_font_selector.set_parent(None, ctx);
+        self.font_selector_height_spinbox.clear_children(ctx);
+        self.font_selector_height_spinbox.set_parent(None, ctx);
+        self.font_selector_corner_radius_spinbox.clear_children(ctx);
+        self.font_selector_corner_radius_spinbox.set_parent(None, ctx);
+        self.dropdown_height_spinbox.clear_children(ctx);
+        self.dropdown_height_spinbox.set_parent(None, ctx);
+        self.dropdown_corner_radius_spinbox.clear_children(ctx);
+        self.dropdown_corner_radius_spinbox.set_parent(None, ctx);
+        self.button_corner_radius_spinbox.clear_children(ctx);
+        self.button_corner_radius_spinbox.set_parent(None, ctx);
+        self.notification_opacity_spinbox.clear_children(ctx);
+        self.notification_opacity_spinbox.set_parent(None, ctx);
+        self.backplate_corner_radius_spinbox.clear_children(ctx);
+        self.backplate_corner_radius_spinbox.set_parent(None, ctx);
+        self.custom_multicontrol.clear_children(ctx);
+        self.custom_multicontrol.set_parent(None, ctx);
+        self.status_box_corner_radius_spinbox.clear_children(ctx);
+        self.status_box_corner_radius_spinbox.set_parent(None, ctx);
+        self.status_padding_spinbox.clear_children(ctx);
+        self.status_padding_spinbox.set_parent(None, ctx);
+        self.status_controls.separators_toggle.clear_children(ctx);
+        self.status_controls.separators_toggle.set_parent(None, ctx);
+        self.status_controls.underline_toggle.clear_children(ctx);
+        self.status_controls.underline_toggle.set_parent(None, ctx);
+        self.status_controls.box_opacity_slider.clear_children(ctx);
+        self.status_controls.box_opacity_slider.set_parent(None, ctx);
+        self.status_controls.box_blur_slider.clear_children(ctx);
+        self.status_controls.box_blur_slider.set_parent(None, ctx);
+
+        self.sans_box.clear_children(ctx);
+        self.sans_box.set_parent(None, ctx);
+        self.serif_box.clear_children(ctx);
+        self.serif_box.set_parent(None, ctx);
+        self.mono_box.clear_children(ctx);
+        self.mono_box.set_parent(None, ctx);
+        self.borders_box.clear_children(ctx);
+        self.borders_box.set_parent(None, ctx);
+        self.status_box.clear_children(ctx);
+        self.status_box.set_parent(None, ctx);
+        self.fuzzel_box.clear_children(ctx);
+        self.fuzzel_box.set_parent(None, ctx);
+        self.terminal_box.clear_children(ctx);
+        self.terminal_box.set_parent(None, ctx);
+        self.borders_menu.clear_children(ctx);
+        self.borders_menu.set_parent(None, ctx);
+        self.status_menu.clear_children(ctx);
+        self.status_menu.set_parent(None, ctx);
+        self.fuzzel_menu.clear_children(ctx);
+        self.fuzzel_menu.set_parent(None, ctx);
+        self.terminal_menu.clear_children(ctx);
+        self.terminal_menu.set_parent(None, ctx);
+        self.borders_size_box.clear_children(ctx);
+        self.borders_size_box.set_parent(None, ctx);
+        self.status_size_box.clear_children(ctx);
+        self.status_size_box.set_parent(None, ctx);
+        self.fuzzel_size_box.clear_children(ctx);
+        self.fuzzel_size_box.set_parent(None, ctx);
+        self.terminal_size_box.clear_children(ctx);
+        self.terminal_size_box.set_parent(None, ctx);
+
+        for menu in &mut self.windows.tag_layout_menus {
+            menu.clear_children(ctx);
+            menu.set_parent(None, ctx);
+        }
+        self.windows.side_panel_behavior_menu.clear_children(ctx);
+        self.windows.side_panel_behavior_menu.set_parent(None, ctx);
+        self.windows.side_panel_position_menu.clear_children(ctx);
+        self.windows.side_panel_position_menu.set_parent(None, ctx);
+        self.windows.side_panel_width_spinbox.clear_children(ctx);
+        self.windows.side_panel_width_spinbox.set_parent(None, ctx);
+        self.windows.side_panel_border_gap_spinbox.clear_children(ctx);
+        self.windows.side_panel_border_gap_spinbox.set_parent(None, ctx);
+        self.windows.side_panel_border_opacity_spinbox.clear_children(ctx);
+        self.windows.side_panel_border_opacity_spinbox.set_parent(None, ctx);
+
+        self.windows.fullscreen_opacity_spinbox.clear_children(ctx);
+        self.windows.fullscreen_opacity_spinbox.set_parent(None, ctx);
+        self.windows.cascade_opacity_spinbox.clear_children(ctx);
+        self.windows.cascade_opacity_spinbox.set_parent(None, ctx);
+        self.windows.grid_opacity_spinbox.clear_children(ctx);
+        self.windows.grid_opacity_spinbox.set_parent(None, ctx);
+        self.windows.floating_opacity_spinbox.clear_children(ctx);
+        self.windows.floating_opacity_spinbox.set_parent(None, ctx);
+        self.windows.pinned_opacity_spinbox.clear_children(ctx);
+        self.windows.pinned_opacity_spinbox.set_parent(None, ctx);
+        self.windows.popup_opacity_spinbox.clear_children(ctx);
+        self.windows.popup_opacity_spinbox.set_parent(None, ctx);
+        self.windows.blur_toggle.clear_children(ctx);
+        self.windows.blur_toggle.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Custom Parameters").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Layout").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Status").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Controls").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Indicators").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Notification").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Surfaces").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Fonts").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Containers").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Windows").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        for i in 0..10 {
+            cce_ui::widget::link_parent_child(page_root, &mut sec_containers[i], ctx);
+        }
+
+        // Section 0: Custom Parameters
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.custom_multicontrol, ctx);
+
+        // Section 1: Layout
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.color_selectors[1], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.color_selectors[2], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.grid_min_col_width_spinbox, ctx);
+
+        // Section 2: Status
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.color_selectors[7], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.color_selectors[3], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.color_selectors[22], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_box_corner_radius_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_padding_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_controls.separators_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_controls.underline_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_controls.box_opacity_slider, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[2], &mut self.status_controls.box_blur_slider, ctx);
+
+        // Section 3: Controls
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.color_selectors[5], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.color_selectors[4], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[3], &mut self.slider_height_spinbox, ctx);
+
+        // Section 4: Indicators
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.color_selectors[11], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.color_selectors[12], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.toggle_height_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.toggle_corner_radius_spinbox, ctx);
+
+        // Section 5: Notification
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.color_selectors[16], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.color_selectors[17], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.color_selectors[18], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.color_selectors[20], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.notification_opacity_spinbox, ctx);
+
+        // Section 6: Surfaces
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.color_selectors[0], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.color_selectors[6], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.color_selectors[23], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[6], &mut self.color_selectors[21], ctx);
+
+        // Section 7: Fonts
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.sans_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.serif_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.mono_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.borders_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.status_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.fuzzel_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.terminal_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.borders_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.status_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.fuzzel_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.terminal_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.borders_size_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.status_size_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.fuzzel_size_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.terminal_size_box, ctx);
+
+        // Section 8: Containers
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[9], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[10], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.button_corner_radius_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[8], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.button_padding_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[14], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[15], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.button_strip_spacing_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[19], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.section_padding_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.color_selectors[13], ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.plate_padding_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.plate_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.plate_corner_radius_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.page_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.layer_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[8], &mut self.page_margin_spinbox, ctx);
+
+        // Section 9: Windows
+        for menu in &mut self.windows.tag_layout_menus {
+            cce_ui::widget::link_parent_child(&mut sec_containers[9], menu, ctx);
+        }
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.side_panel_behavior_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.side_panel_position_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.side_panel_width_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.side_panel_border_gap_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.side_panel_border_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.pinned_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.popup_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.fullscreen_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.cascade_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.grid_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.floating_opacity_spinbox, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[9], &mut self.windows.blur_toggle, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        for (i, cp) in self.color_selectors.iter_mut().enumerate() {
+            if cp.take_change() {
+                actions.push(AppAction::Interface(match i {
+                    0 => InterfaceMessage::SetPageLowColor(cp.color),
+                    1 => InterfaceMessage::SetHighColor(cp.color),
+                    2 => InterfaceMessage::SetVisualGuidesColor(cp.color),
+                    3 => InterfaceMessage::SetDisabledColor(cp.color),
+                    4 => InterfaceMessage::SetSliderTrackColor(cp.color),
+                    5 => InterfaceMessage::SetColorBordersColor(cp.color),
+                    6 => InterfaceMessage::SetDesktopBackground(cp.color),
+                    7 => InterfaceMessage::SetNormalColor(cp.color),
+                    8 => InterfaceMessage::SetPaginatorSidebarColor(cp.color),
+                    9 => InterfaceMessage::SetPrimaryHighlightColor(cp.color),
+                    10 => InterfaceMessage::SetMenubarTabLabelColor(cp.color),
+                    11 => InterfaceMessage::SetToggleEnabledColor(cp.color),
+                    12 => InterfaceMessage::SetToggleDisabledColor(cp.color),
+                    13 => InterfaceMessage::SetScrollingListBgColor(cp.color),
+                    14 => InterfaceMessage::SetScrollingListEntryBgColor([cp.color[0], cp.color[1], cp.color[2], 255]),
+                    15 => InterfaceMessage::SetScrollingListEntryHighlightColor([cp.color[0], cp.color[1], cp.color[2], 255]),
+                    16 => InterfaceMessage::SetBreadcrumbBgColor(cp.color),
+                    17 => InterfaceMessage::SetPopoverBgColor(cp.color),
+                    18 => InterfaceMessage::SetNotificationBgColor(cp.color),
+                    19 => InterfaceMessage::SetBackplateColor(cp.color),
+                    20 => InterfaceMessage::SetPageColor(cp.color),
+                    21 => InterfaceMessage::SetLayerColor(cp.color),
+                    22 => InterfaceMessage::SetStatusBoxBackgroundColor(cp.color),
+                    23 => InterfaceMessage::SetDesktopGridColor([cp.color[0], cp.color[1], cp.color[2], 255]),
+                    _ => return,
+                }));
+            }
+        }
+
+        if self.status_box_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatusBoxCornerRadius(self.status_box_corner_radius_spinbox.value as u16)));
+        }
+        if self.status_padding_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatusPadding(self.status_padding_spinbox.value as u16)));
+        }
+        if self.status_module_spacing_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatusModuleSpacing(self.status_module_spacing_spinbox.value as u16)));
+        }
+        if self.status_controls.separators_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::StatusToggleSeparators));
+        }
+        if self.status_controls.underline_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::StatusToggleUnderline));
+        }
+        if self.status_controls.box_opacity_slider.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::StatusSetBoxOpacity(self.status_controls.box_opacity_slider.value())));
+        }
+        if self.status_controls.box_blur_slider.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::StatusSetBoxBlur(self.status_controls.box_blur_slider.value())));
+        }
+
+        if self.menubar_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetMenubarOpacity(self.menubar_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.button_padding_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetButtonPadding(self.button_padding_spinbox.value as u16)));
+        }
+        if self.button_strip_spacing_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetButtonStripSpacing(self.button_strip_spacing_spinbox.value as u16)));
+        }
+        if self.section_padding_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSectionPadding(self.section_padding_spinbox.value as u16)));
+        }
+        if self.plate_padding_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetPlatePadding(self.plate_padding_spinbox.value as u16)));
+        }
+        if self.plate_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetPlateOpacity(self.plate_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.plate_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetPlateCornerRadius(self.plate_corner_radius_spinbox.value as u16)));
+        }
+        if self.page_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetPageOpacity(self.page_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.layer_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetLayerOpacity(self.layer_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.page_margin_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetPageMargin(self.page_margin_spinbox.value as u16)));
+        }
+        if self.desktop_grid_scale_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetDesktopGridScale(self.desktop_grid_scale_spinbox.value as u16)));
+        }
+        if self.desktop_line_width_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetDesktopLineWidth(self.desktop_line_width_spinbox.value as u16)));
+        }
+        if self.grid_min_col_width_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGridMinColWidth(self.grid_min_col_width_spinbox.value as u16)));
+        }
+        if self.spinbox_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSpinboxHeight(self.spinbox_height_spinbox.value as u16)));
+        }
+        if self.spinbox_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSpinboxCornerRadius(self.spinbox_corner_radius_spinbox.value as u16)));
+        }
+        if self.toggle_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetToggleHeight(self.toggle_height_spinbox.value as u16)));
+        }
+        if self.toggle_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetToggleCornerRadius(self.toggle_corner_radius_spinbox.value as u16)));
+        }
+        if self.color_selector_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetColorSelectorHeight(self.color_selector_height_spinbox.value as u16)));
+        }
+        if self.color_selector_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetColorSelectorCornerRadius(self.color_selector_corner_radius_spinbox.value as u16)));
+        }
+        if self.color_selector_preview_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetColorSelectorPreviewCornerRadius(self.color_selector_preview_corner_radius_spinbox.value as u16)));
+        }
+        if self.color_selector_preview_margin_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetColorSelectorPreviewMargin(self.color_selector_preview_margin_spinbox.value as u16)));
+        }
+        if self.textbox_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetTextboxHeight(self.textbox_height_spinbox.value as u16)));
+        }
+        if self.textbox_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetTextboxCornerRadius(self.textbox_corner_radius_spinbox.value as u16)));
+        }
+        if self.slider_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSliderHeight(self.slider_height_spinbox.value as u16)));
+        }
+
+        if self.label_alignment_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetNestedSectionLabelAlignment(self.label_alignment_menu.selected)));
+        }
+        if self.label_offset_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetNestedSectionLabelOffset(self.label_offset_spinbox.value as i16)));
+        }
+        if self.label_margin_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetLabelMargin(self.label_margin_spinbox.value as u16)));
+        }
+
+        // Fonts
+        if self.sans_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSans(self.sans_box.text.clone())));
+        }
+        if self.serif_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSerif(self.serif_box.text.clone())));
+        }
+        if self.mono_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetMono(self.mono_box.text.clone())));
+        }
+        if self.borders_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetBorders(self.borders_box.text.clone())));
+        }
+        if self.status_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatus(self.status_box.text.clone())));
+        }
+        if self.fuzzel_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetFuzzel(self.fuzzel_box.text.clone())));
+        }
+        if self.terminal_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetTerminal(self.terminal_box.text.clone())));
+        }
+        if self.borders_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetBordersMenu(self.borders_menu.selected)));
+        }
+        if self.status_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatusMenu(self.status_menu.selected)));
+        }
+        if self.fuzzel_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetFuzzelMenu(self.fuzzel_menu.selected)));
+        }
+        if self.terminal_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetTerminalMenu(self.terminal_menu.selected)));
+        }
+        if self.borders_size_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetBordersSize(self.borders_size_box.value)));
+        }
+        if self.status_size_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetStatusSize(self.status_size_box.value)));
+        }
+        if self.fuzzel_size_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetFuzzelSize(self.fuzzel_size_box.value)));
+        }
+        if self.terminal_size_box.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetTerminalSize(self.terminal_size_box.value)));
+        }
+
+        // Windows Page Settings
+        for (idx, menu) in self.windows.tag_layout_menus.iter_mut().enumerate() {
+            if menu.take_change() {
+                actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetTagLayout(idx, menu.selected))));
+            }
+        }
+        if self.windows.side_panel_behavior_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetSidePanelBehavior(self.windows.side_panel_behavior_menu.selected))));
+        }
+        if self.windows.side_panel_position_menu.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetSidePanelPosition(self.windows.side_panel_position_menu.selected))));
+        }
+        if self.windows.side_panel_width_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetSidePanelWidth(self.windows.side_panel_width_spinbox.value as u16))));
+        }
+        if self.windows.side_panel_border_gap_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetSidePanelBorderGap(self.windows.side_panel_border_gap_spinbox.value as u16))));
+        }
+        if self.windows.side_panel_border_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetSidePanelBorderOpacity(self.windows.side_panel_border_opacity_spinbox.value as u16))));
+        }
+        if self.windows.fullscreen_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetFullscreenOpacity(self.windows.fullscreen_opacity_spinbox.value as u16))));
+        }
+        if self.windows.cascade_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetCascadeOpacity(self.windows.cascade_opacity_spinbox.value as u16))));
+        }
+        if self.windows.grid_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetGridOpacity(self.windows.grid_opacity_spinbox.value as u16))));
+        }
+        if self.windows.floating_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetFloatingOpacity(self.windows.floating_opacity_spinbox.value as u16))));
+        }
+        if self.windows.pinned_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetPinnedOpacity(self.windows.pinned_opacity_spinbox.value as u16))));
+        }
+        if self.windows.popup_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetPopupOpacity(self.windows.popup_opacity_spinbox.value as u16))));
+        }
+        if self.windows.blur_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::ToggleBlur)));
+        }
+
+        // Toggles in font_selector & graph
+        if self.graph_show_grid_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphShowGrid(self.graph_show_grid_toggle.toggled())));
+        }
+        if self.graph_snap_enabled_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphSnapEnabled(self.graph_snap_enabled_toggle.toggled())));
+        }
+        if self.graph_uniform_background_toggle.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphUniformBackground(self.graph_uniform_background_toggle.toggled())));
+        }
+        if self.graph_cell_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphCellOpacity(self.graph_cell_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.graph_gap_opacity_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphGapOpacity(self.graph_gap_opacity_spinbox.value as f32 / 100.0)));
+        }
+        if self.graph_gap_width_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetGraphGapWidth(self.graph_gap_width_spinbox.value as u16)));
+        }
+        if self.color_selector_font_selector.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetColorSelectorFont(self.color_selector_font_selector.font_family.clone())));
+        }
+        if self.menubar_font_selector.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetMenubarFont(self.menubar_font_selector.font_family.clone())));
+        }
+        if self.breadcrumb_font_selector.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetBreadcrumbFont(self.breadcrumb_font_selector.font_family.clone())));
+        }
+        if self.section_label_font_selector.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetSectionLabelFont(self.section_label_font_selector.font_family.clone())));
+        }
+        if self.nested_section_label_font_selector.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetNestedSectionLabelFont(self.nested_section_label_font_selector.font_family.clone())));
+        }
+        if self.font_selector_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetFontSelectorHeight(self.font_selector_height_spinbox.value as u16)));
+        }
+        if self.font_selector_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetFontSelectorCornerRadius(self.font_selector_corner_radius_spinbox.value as u16)));
+        }
+        if self.dropdown_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetDropdownHeight(self.dropdown_height_spinbox.value as u16)));
+        }
+        if self.dropdown_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetDropdownCornerRadius(self.dropdown_corner_radius_spinbox.value as u16)));
+        }
+        if self.button_corner_radius_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::SetButtonCornerRadius(self.button_corner_radius_spinbox.value as u16)));
+        }
+
+        // Windows Page Settings (rest)
+        if self.windows.status_height_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetStatusHeight(self.windows.status_height_spinbox.value as u16))));
+        }
+        if self.windows.cascade_offset_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetCascadeOffset(self.windows.cascade_offset_spinbox.value as u16))));
+        }
+        if self.windows.edge_gap_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetEdgeGap(self.windows.edge_gap_spinbox.value as u16))));
+        }
+        if self.windows.top_gap_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetTopGap(self.windows.top_gap_spinbox.value as u16))));
+        }
+        if self.windows.grid_gap_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetGridGap(self.windows.grid_gap_spinbox.value as u16))));
+        }
+        if self.windows.transition_duration_spinbox.take_change() {
+            actions.push(AppAction::Interface(InterfaceMessage::Windows(WindowsMessage::SetTransitionDuration(self.windows.transition_duration_spinbox.value as u16))));
+        }
+    }
+
+    fn handle_pointer_move(
+        &mut self,
+        lx: f32,
+        ly: f32,
+        actions: &mut Vec<crate::app::AppAction>,
+        _ctx: &mut cce_ui::context::UiContext,
+    ) -> bool {
+        if self.status_controls.opacity_dragging {
+            if self.status_controls.box_opacity_slider.drag_update(lx, ly) {
+                let val = self.status_controls.box_opacity_slider.value();
+                actions.push(AppAction::Interface(InterfaceMessage::StatusSetBoxOpacity(val)));
+                return true;
+            }
+        } else if self.status_controls.blur_dragging {
+            if self.status_controls.box_blur_slider.drag_update(lx, ly) {
+                let val = self.status_controls.box_blur_slider.value();
+                actions.push(AppAction::Interface(InterfaceMessage::StatusSetBoxBlur(val)));
+                return true;
+            }
+        }
+        false
+    }
+
+    fn handle_pointer_down(&mut self, _lx: f32, _ly: f32, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        if self.status_controls.box_opacity_slider.is_dragging() {
+            self.status_controls.opacity_dragging = true;
+            return true;
+        }
+        if self.status_controls.box_blur_slider.is_dragging() {
+            self.status_controls.blur_dragging = true;
+            return true;
+        }
+        false
+    }
+
+    fn handle_pointer_up(&mut self, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        let mut any = false;
+        if self.status_controls.opacity_dragging {
+            self.status_controls.box_opacity_slider.drag_end();
+            self.status_controls.opacity_dragging = false;
+            any = true;
+        }
+        if self.status_controls.blur_dragging {
+            self.status_controls.box_blur_slider.drag_end();
+            self.status_controls.blur_dragging = false;
+            any = true;
+        }
+        any
+    }
+}
+
 
 
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index c0ae57b..2e6850f 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -56,6 +56,55 @@ impl Page {
     pub fn icon(self) -> &'static str {
         ""
     }
+
+    pub fn index(self) -> usize {
+        Page::ALL.iter().position(|&p| p == self).unwrap()
+    }
+}
+
+pub trait AppPage {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext);
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer>;
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    );
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn cce_ui::layout::LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent;
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>);
+
+    fn handle_pointer_move(
+        &mut self,
+        _lx: f32,
+        _ly: f32,
+        _actions: &mut Vec<crate::app::AppAction>,
+        _ctx: &mut cce_ui::context::UiContext,
+    ) -> bool {
+        false
+    }
+
+    fn handle_pointer_down(&mut self, _lx: f32, _ly: f32, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        false
+    }
+
+    fn handle_pointer_up(&mut self, _ctx: &mut cce_ui::context::UiContext) -> bool {
+        false
+    }
 }
 
 
diff --git a/src/pages/network.rs b/src/pages/network.rs
index e4ac8d0..79ba600 100644
--- a/src/pages/network.rs
+++ b/src/pages/network.rs
@@ -515,6 +515,73 @@ pub fn update(state: &mut NetworkState, msg: NetworkMessage) {
     }
 }
 
+impl crate::pages::AppPage for NetworkState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.wifi_list_box.scroll_box.clear_children(ctx);
+        self.wifi_list_box.scroll_box.set_parent(None, ctx);
+        self.wifi_toggle.clear_children(ctx);
+        self.wifi_toggle.set_parent(None, ctx);
+        self.bt_toggle.clear_children(ctx);
+        self.bt_toggle.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("WiFi").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Bluetooth").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.wifi_toggle, ctx);
+        if self.wifi_enabled && !self.available.is_empty() {
+            cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.wifi_list_box.scroll_box, ctx);
+        }
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.bt_toggle, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        root_focused: bool,
+        _sec_focused: &[bool],
+        layout: &mut dyn LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, root_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        if self.wifi_toggle.take_change() {
+            actions.push(crate::app::AppAction::Radios(NetworkMessage::ToggleWifi));
+        }
+        if self.bt_toggle.take_change() {
+            actions.push(crate::app::AppAction::Radios(NetworkMessage::ToggleBluetooth));
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/packages.rs b/src/pages/packages.rs
index 9971f77..ee6e7f3 100644
--- a/src/pages/packages.rs
+++ b/src/pages/packages.rs
@@ -744,6 +744,70 @@ impl PackagesState {
     }
 }
 
+impl crate::pages::AppPage for PackagesState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.search_box.clear_children(ctx);
+        self.search_box.set_parent(None, ctx);
+        self.installed_list_box.scroll_box.clear_children(ctx);
+        self.installed_list_box.scroll_box.set_parent(None, ctx);
+        self.updates_list_box.scroll_box.clear_children(ctx);
+        self.updates_list_box.scroll_box.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Packages").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("System Update").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.search_box, ctx);
+        match self.active_tab {
+            PackageTab::Installed => {
+                cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.installed_list_box.scroll_box, ctx);
+            }
+            PackageTab::Updates => {
+                cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.updates_list_box.scroll_box, ctx);
+            }
+        }
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, _actions: &mut Vec<crate::app::AppAction>) {}
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/processes.rs b/src/pages/processes.rs
index af521cb..d1fc539 100644
--- a/src/pages/processes.rs
+++ b/src/pages/processes.rs
@@ -490,6 +490,64 @@ fn service_action(name: &str, action: &str, is_system: bool) {
     }
 }
 
+impl crate::pages::AppPage for ProcessesState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.cpu_list_box.scroll_box.clear_children(ctx);
+        self.cpu_list_box.scroll_box.set_parent(None, ctx);
+        self.services_search_box.clear_children(ctx);
+        self.services_search_box.set_parent(None, ctx);
+        self.services_list_box.scroll_box.clear_children(ctx);
+        self.services_list_box.scroll_box.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Processes").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Services").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+
+        cce_ui::widget::link_parent_child(&mut sec_containers[0], &mut self.cpu_list_box.scroll_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.services_search_box, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[1], &mut self.services_list_box.scroll_box, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, root_focused, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, _actions: &mut Vec<crate::app::AppAction>) {}
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/pages/storage.rs b/src/pages/storage.rs
index 9ec2f77..ac248ab 100644
--- a/src/pages/storage.rs
+++ b/src/pages/storage.rs
@@ -316,3 +316,57 @@ pub fn update(state: &mut StorageState, msg: StorageMessage) {
         }
     }
 }
+
+impl crate::pages::AppPage for StorageState {
+    fn clear_children(&mut self, _ctx: &mut cce_ui::context::UiContext) {}
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("Local Storage").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Memory").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+            cce_ui::widget::SectionContainer::new("Full System Backup").with_layout(cce_ui::widget::AdaptiveGridLayout {
+                min_col_width: 140.0,
+                gap: 8.0,
+                padding_x: 0.0,
+                padding_y: 0.0,
+            }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[0], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[1], ctx);
+        cce_ui::widget::link_parent_child(page_root, &mut sec_containers[2], ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        _root_focused: bool,
+        _sec_focused: &[bool],
+        layout: &mut dyn LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, _actions: &mut Vec<crate::app::AppAction>) {}
+}
diff --git a/src/pages/system_info.rs b/src/pages/system_info.rs
index 80b26c6..ba28692 100644
--- a/src/pages/system_info.rs
+++ b/src/pages/system_info.rs
@@ -1,6 +1,6 @@
 use crate::app::{AppAction, PageContent, SectionContextExt};
 use cce_ui::layout::{render_widget, PageLayoutBuilder, LayoutStrategy};
-use cce_ui::widget::{Label, Dropdown, InfoBox, Toggle, Spinbox};
+use cce_ui::widget::{Label, Dropdown, InfoBox, Toggle, Spinbox, Element};
 use crate::config_manager::CONFIG_PATH;
 use std::io::Write;
 use std::fs;
@@ -845,6 +845,90 @@ fn write_enable_notifications(enabled: bool) {
     send_ipc_command("reload");
 }
 
+impl crate::pages::AppPage for SystemState {
+    fn clear_children(&mut self, ctx: &mut cce_ui::context::UiContext) {
+        self.cpu_gov_menu.clear_children(ctx);
+        self.cpu_gov_menu.set_parent(None, ctx);
+        self.gpu_gov_menu.clear_children(ctx);
+        self.gpu_gov_menu.set_parent(None, ctx);
+        self.notifications_enable_toggle.clear_children(ctx);
+        self.notifications_enable_toggle.set_parent(None, ctx);
+        self.notifications_bell_toggle.clear_children(ctx);
+        self.notifications_bell_toggle.set_parent(None, ctx);
+        self.notifications_duration_spinbox.clear_children(ctx);
+        self.notifications_duration_spinbox.set_parent(None, ctx);
+    }
+
+    fn get_section_containers(&self) -> Vec<cce_ui::widget::SectionContainer> {
+        vec![
+            cce_ui::widget::SectionContainer::new("System").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("System Actions").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("CPU").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("GPU").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("CPU Governor").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("GPU Power").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("Battery").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+            cce_ui::widget::SectionContainer::new("System Notifications").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }),
+        ]
+    }
+
+    fn link_children(
+        &mut self,
+        page_root: &mut dyn cce_ui::widget::Element,
+        sec_containers: &mut [cce_ui::widget::SectionContainer],
+        ctx: &mut cce_ui::context::UiContext,
+    ) {
+        for sec in sec_containers.iter_mut() {
+            cce_ui::widget::link_parent_child(page_root, sec, ctx);
+        }
+        cce_ui::widget::link_parent_child(&mut sec_containers[4], &mut self.cpu_gov_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[5], &mut self.gpu_gov_menu, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.notifications_enable_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.notifications_bell_toggle, ctx);
+        cce_ui::widget::link_parent_child(&mut sec_containers[7], &mut self.notifications_duration_spinbox, ctx);
+    }
+
+    fn view(
+        &mut self,
+        cx: f32,
+        cy: f32,
+        cw: f32,
+        ch: f32,
+        root_focused: bool,
+        sec_focused: &[bool],
+        layout: &mut dyn LayoutStrategy,
+        ctx: &mut cce_ui::context::UiContext,
+    ) -> crate::app::PageContent {
+        view(self, cx, cy, cw, ch, root_focused, sec_focused, layout, ctx)
+    }
+
+    fn propagate_widget_changes(&mut self, actions: &mut Vec<crate::app::AppAction>) {
+        if self.cpu_gov_menu.take_change() {
+            if self.cpu_gov_menu.selected == 0 {
+                actions.push(crate::app::AppAction::SystemInfo(SystemMessage::SetCpuPerformance));
+            } else {
+                actions.push(crate::app::AppAction::SystemInfo(SystemMessage::SetCpuPowersave));
+            }
+        }
+        if self.gpu_gov_menu.take_change() {
+            if self.gpu_gov_menu.selected == 0 {
+                actions.push(crate::app::AppAction::SystemInfo(SystemMessage::SetGpuDefault));
+            } else {
+                actions.push(crate::app::AppAction::SystemInfo(SystemMessage::SetGpuPowersave));
+            }
+        }
+        if self.notifications_enable_toggle.take_change() {
+            actions.push(crate::app::AppAction::SystemInfo(SystemMessage::ToggleNotificationsEnable));
+        }
+        if self.notifications_bell_toggle.take_change() {
+            actions.push(crate::app::AppAction::SystemInfo(SystemMessage::ToggleNotificationsBell));
+        }
+        if self.notifications_duration_spinbox.take_change() {
+            actions.push(crate::app::AppAction::SystemInfo(SystemMessage::SetNotificationsDuration(self.notifications_duration_spinbox.value)));
+        }
+    }
+}
+
 thread_local! {
     static TEST_CONFIG_PATH: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
 }
diff --git a/src/renderer.rs b/src/renderer.rs
index 24b8bd4..9615829 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -1,6 +1,6 @@
 use crate::{SystemInterface, AppWidget, make_text_buffer, make_text_buffer_with_font};
 use cce_system_interface::app::PageContent;
-use cce_system_interface::pages::{self, Page};
+use cce_system_interface::pages::Page;
 use cce_ui::widget::{Element, TextItem, PageSelector};
 
 impl SystemInterface {
@@ -25,621 +25,17 @@ impl SystemInterface {
         }
 
         // Clear all widgets' hierarchy links
-        self.search_box.clear_children(&mut self.ui_context); self.search_box.set_parent(None, &mut self.ui_context);
-        self.app.processes.services_search_box.clear_children(&mut self.ui_context); self.app.processes.services_search_box.set_parent(None, &mut self.ui_context);
-        self.app.packages.search_box.clear_children(&mut self.ui_context); self.app.packages.search_box.set_parent(None, &mut self.ui_context);
-        self.app.packages.installed_list_box.scroll_box.clear_children(&mut self.ui_context); self.app.packages.installed_list_box.scroll_box.set_parent(None, &mut self.ui_context);
-        self.app.packages.updates_list_box.scroll_box.clear_children(&mut self.ui_context); self.app.packages.updates_list_box.scroll_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.email_box.clear_children(&mut self.ui_context); self.app.accounts.email_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.password_box.clear_children(&mut self.ui_context); self.app.accounts.password_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.imap_box.clear_children(&mut self.ui_context); self.app.accounts.imap_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.smtp_box.clear_children(&mut self.ui_context); self.app.accounts.smtp_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.oauth_client_id_box.clear_children(&mut self.ui_context); self.app.accounts.oauth_client_id_box.set_parent(None, &mut self.ui_context);
-        self.app.accounts.oauth_client_secret_box.clear_children(&mut self.ui_context); self.app.accounts.oauth_client_secret_box.set_parent(None, &mut self.ui_context);
+        self.search_box.clear_children(&mut self.ui_context);
+        self.search_box.set_parent(None, &mut self.ui_context);
 
-        self.app.processes.services_list_box.scroll_box.clear_children(&mut self.ui_context); self.app.processes.services_list_box.scroll_box.set_parent(None, &mut self.ui_context);
-        self.app.processes.cpu_list_box.scroll_box.clear_children(&mut self.ui_context); self.app.processes.cpu_list_box.scroll_box.set_parent(None, &mut self.ui_context);
-
-        self.app.network.wifi_list_box.scroll_box.clear_children(&mut self.ui_context); self.app.network.wifi_list_box.scroll_box.set_parent(None, &mut self.ui_context);
-
-        for sb in &mut self.app.interface.windows.spinboxes {
-            sb.clear_children(&mut self.ui_context);
-            sb.set_parent(None, &mut self.ui_context);
-        }
-        self.app.interface.windows.cascade_offset_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.cascade_offset_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.edge_gap_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.edge_gap_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.top_gap_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.top_gap_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.grid_gap_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.grid_gap_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.transition_duration_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.transition_duration_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.status_height_spinbox.clear_children(&mut self.ui_context); self.app.interface.windows.status_height_spinbox.set_parent(None, &mut self.ui_context);
-
-        for cs in &mut self.app.interface.color_selectors {
-            cs.clear_children(&mut self.ui_context);
-            cs.set_parent(None, &mut self.ui_context);
-        }
-        self.app.interface.menubar_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.menubar_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.button_padding_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.button_padding_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.section_padding_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.section_padding_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.label_alignment_menu.clear_children(&mut self.ui_context);
-        self.app.interface.label_alignment_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.label_offset_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.label_offset_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.label_margin_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.label_margin_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.plate_padding_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.plate_padding_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_show_grid_toggle.clear_children(&mut self.ui_context);
-        self.app.interface.graph_show_grid_toggle.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_snap_enabled_toggle.clear_children(&mut self.ui_context);
-        self.app.interface.graph_snap_enabled_toggle.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_uniform_background_toggle.clear_children(&mut self.ui_context);
-        self.app.interface.graph_uniform_background_toggle.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_cell_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.graph_cell_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_gap_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.graph_gap_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.graph_gap_width_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.graph_gap_width_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.page_margin_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.page_margin_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.desktop_grid_scale_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.desktop_grid_scale_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.desktop_line_width_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.desktop_line_width_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.grid_min_col_width_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.grid_min_col_width_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.spinbox_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.spinbox_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.spinbox_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.spinbox_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.toggle_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.toggle_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.toggle_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.toggle_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-
-        self.app.interface.color_selector_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.color_selector_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.color_selector_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.color_selector_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.plate_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.plate_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.plate_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.plate_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.page_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.page_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.layer_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.layer_opacity_spinbox.set_parent(None, &mut self.ui_context);
-
-        self.app.interface.color_selector_preview_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.color_selector_preview_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.color_selector_preview_margin_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.color_selector_preview_margin_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.textbox_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.textbox_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.textbox_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.textbox_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.slider_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.slider_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.color_selector_font_selector.clear_children(&mut self.ui_context);
-        self.app.interface.color_selector_font_selector.set_parent(None, &mut self.ui_context);
-        self.app.interface.menubar_font_selector.clear_children(&mut self.ui_context);
-        self.app.interface.menubar_font_selector.set_parent(None, &mut self.ui_context);
-        self.app.interface.breadcrumb_font_selector.clear_children(&mut self.ui_context);
-        self.app.interface.breadcrumb_font_selector.set_parent(None, &mut self.ui_context);
-        self.app.interface.section_label_font_selector.clear_children(&mut self.ui_context);
-        self.app.interface.section_label_font_selector.set_parent(None, &mut self.ui_context);
-        self.app.interface.nested_section_label_font_selector.clear_children(&mut self.ui_context);
-        self.app.interface.nested_section_label_font_selector.set_parent(None, &mut self.ui_context);
-        self.app.interface.font_selector_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.font_selector_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.font_selector_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.font_selector_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.dropdown_height_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.dropdown_height_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.dropdown_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.dropdown_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.button_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.button_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.notification_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.notification_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.backplate_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.backplate_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.custom_multicontrol.clear_children(&mut self.ui_context);
-        self.app.interface.custom_multicontrol.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_box_corner_radius_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.status_box_corner_radius_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_padding_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.status_padding_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_separators_toggle.clear_children(&mut self.ui_context);
-        self.app.interface.status_separators_toggle.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_underline_toggle.clear_children(&mut self.ui_context);
-        self.app.interface.status_underline_toggle.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_box_opacity_slider.clear_children(&mut self.ui_context);
-        self.app.interface.status_box_opacity_slider.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_box_blur_slider.clear_children(&mut self.ui_context);
-        self.app.interface.status_box_blur_slider.set_parent(None, &mut self.ui_context);
-
-        self.app.interface.sans_box.clear_children(&mut self.ui_context); self.app.interface.sans_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.serif_box.clear_children(&mut self.ui_context); self.app.interface.serif_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.mono_box.clear_children(&mut self.ui_context); self.app.interface.mono_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.borders_menu.clear_children(&mut self.ui_context); self.app.interface.borders_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.borders_box.clear_children(&mut self.ui_context); self.app.interface.borders_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_menu.clear_children(&mut self.ui_context); self.app.interface.status_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.status_box.clear_children(&mut self.ui_context); self.app.interface.status_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.fuzzel_menu.clear_children(&mut self.ui_context); self.app.interface.fuzzel_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.fuzzel_box.clear_children(&mut self.ui_context); self.app.interface.fuzzel_box.set_parent(None, &mut self.ui_context);
-        self.app.interface.terminal_menu.clear_children(&mut self.ui_context); self.app.interface.terminal_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.terminal_box.clear_children(&mut self.ui_context); self.app.interface.terminal_box.set_parent(None, &mut self.ui_context);
-
-        self.app.system_info.cpu_gov_menu.clear_children(&mut self.ui_context); self.app.system_info.cpu_gov_menu.set_parent(None, &mut self.ui_context);
-        self.app.system_info.gpu_gov_menu.clear_children(&mut self.ui_context); self.app.system_info.gpu_gov_menu.set_parent(None, &mut self.ui_context);
-        self.app.system_info.notifications_enable_toggle.clear_children(&mut self.ui_context); self.app.system_info.notifications_enable_toggle.set_parent(None, &mut self.ui_context);
-        self.app.system_info.notifications_bell_toggle.clear_children(&mut self.ui_context); self.app.system_info.notifications_bell_toggle.set_parent(None, &mut self.ui_context);
-
-
-        self.app.input.rate_spinbox.clear_children(&mut self.ui_context); self.app.input.rate_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.delay_spinbox.clear_children(&mut self.ui_context); self.app.input.delay_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.scroll_toggle.clear_children(&mut self.ui_context); self.app.input.scroll_toggle.set_parent(None, &mut self.ui_context);
-        self.app.input.scroll_friction_spinbox.clear_children(&mut self.ui_context); self.app.input.scroll_friction_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.natural_toggle.clear_children(&mut self.ui_context); self.app.input.natural_toggle.set_parent(None, &mut self.ui_context);
-        self.app.input.scroll_speed_spinbox.clear_children(&mut self.ui_context); self.app.input.scroll_speed_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.pointer_toggle.clear_children(&mut self.ui_context); self.app.input.pointer_toggle.set_parent(None, &mut self.ui_context);
-        self.app.input.pointer_friction_spinbox.clear_children(&mut self.ui_context); self.app.input.pointer_friction_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.trackpad_toggle.clear_children(&mut self.ui_context); self.app.input.trackpad_toggle.set_parent(None, &mut self.ui_context);
-        self.app.input.trackpad_friction_spinbox.clear_children(&mut self.ui_context); self.app.input.trackpad_friction_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.dwtp_toggle.clear_children(&mut self.ui_context); self.app.input.dwtp_toggle.set_parent(None, &mut self.ui_context);
-        self.app.input.trackpoint_accel_speed_spinbox.clear_children(&mut self.ui_context); self.app.input.trackpoint_accel_speed_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.trackpoint_accel_profile_menu.clear_children(&mut self.ui_context); self.app.input.trackpoint_accel_profile_menu.set_parent(None, &mut self.ui_context);
-        self.app.input.cursor_theme_menu.clear_children(&mut self.ui_context); self.app.input.cursor_theme_menu.set_parent(None, &mut self.ui_context);
-        self.app.input.cursor_size_spinbox.clear_children(&mut self.ui_context); self.app.input.cursor_size_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.input.zoom_in_box.clear_children(&mut self.ui_context); self.app.input.zoom_in_box.set_parent(None, &mut self.ui_context);
-        self.app.input.zoom_out_box.clear_children(&mut self.ui_context); self.app.input.zoom_out_box.set_parent(None, &mut self.ui_context);
-        self.app.input.keybinds_control.clear_children(&mut self.ui_context); self.app.input.keybinds_control.set_parent(None, &mut self.ui_context);
-
-        for sb in &mut self.app.audio.sink_spinboxes {
-            sb.clear_children(&mut self.ui_context);
-            sb.set_parent(None, &mut self.ui_context);
-        }
-        for sb in &mut self.app.audio.source_spinboxes {
-            sb.clear_children(&mut self.ui_context);
-            sb.set_parent(None, &mut self.ui_context);
-        }
-        for slider in &mut self.app.audio.sink_sliders {
-            slider.clear_children(&mut self.ui_context);
-            slider.set_parent(None, &mut self.ui_context);
-        }
-        for slider in &mut self.app.audio.source_sliders {
-            slider.clear_children(&mut self.ui_context);
-            slider.set_parent(None, &mut self.ui_context);
-        }
-
-        self.app.display.brightness_spinbox.clear_children(&mut self.ui_context); self.app.display.brightness_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.display.brightness_slider.clear_children(&mut self.ui_context); self.app.display.brightness_slider.set_parent(None, &mut self.ui_context);
-        self.app.display.night_light_label.clear_children(&mut self.ui_context); self.app.display.night_light_label.set_parent(None, &mut self.ui_context);
-        self.app.display.screensaver_enable_toggle.clear_children(&mut self.ui_context); self.app.display.screensaver_enable_toggle.set_parent(None, &mut self.ui_context);
-        self.app.display.screensaver_lock_screen_toggle.clear_children(&mut self.ui_context); self.app.display.screensaver_lock_screen_toggle.set_parent(None, &mut self.ui_context);
-        self.app.display.screensaver_timeout_spinbox.clear_children(&mut self.ui_context); self.app.display.screensaver_timeout_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.display.screensaver_style_menu.clear_children(&mut self.ui_context); self.app.display.screensaver_style_menu.set_parent(None, &mut self.ui_context);
-        for out in &mut self.app.display.outputs {
-            out.name_label.clear_children(&mut self.ui_context); out.name_label.set_parent(None, &mut self.ui_context);
-            out.resolution_label.clear_children(&mut self.ui_context); out.resolution_label.set_parent(None, &mut self.ui_context);
-            if let Some(ref mut scale_lbl) = out.scale_label {
-                scale_lbl.clear_children(&mut self.ui_context); scale_lbl.set_parent(None, &mut self.ui_context);
-            }
+        for p in Page::ALL {
+            self.app.get_page_mut(p).clear_children(&mut self.ui_context);
         }
 
+        let active_page = self.app.get_current_page_mut();
+        self.page_sec_containers = active_page.get_section_containers();
 
-        for menu in &mut self.app.interface.windows.tag_layout_menus {
-            menu.clear_children(&mut self.ui_context);
-            menu.set_parent(None, &mut self.ui_context);
-        }
-        self.app.interface.windows.side_panel_behavior_menu.clear_children(&mut self.ui_context);
-        self.app.interface.windows.side_panel_behavior_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.side_panel_position_menu.clear_children(&mut self.ui_context);
-        self.app.interface.windows.side_panel_position_menu.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.side_panel_width_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.side_panel_width_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.side_panel_border_gap_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.side_panel_border_gap_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.side_panel_border_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.side_panel_border_opacity_spinbox.set_parent(None, &mut self.ui_context);
-
-        self.app.interface.windows.fullscreen_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.fullscreen_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.cascade_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.cascade_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.grid_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.grid_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.floating_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.floating_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.pinned_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.pinned_opacity_spinbox.set_parent(None, &mut self.ui_context);
-        self.app.interface.windows.popup_opacity_spinbox.clear_children(&mut self.ui_context);
-        self.app.interface.windows.popup_opacity_spinbox.set_parent(None, &mut self.ui_context);
-
-        use cce_ui::widget::focus::link_parent_child;
-        match self.app.current_page {
-            Page::Accounts => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Accounts").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Modify Accounts").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..2 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                if self.app.accounts.editing_oauth_creds {
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.oauth_client_id_box, &mut self.ui_context);
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.oauth_client_secret_box, &mut self.ui_context);
-                } else if self.app.accounts.adding_new {
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.email_box, &mut self.ui_context);
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.password_box, &mut self.ui_context);
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.imap_box, &mut self.ui_context);
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.accounts.smtp_box, &mut self.ui_context);
-                }
-            }
-
-            Page::System => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("System").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("System Actions").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("CPU").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("GPU").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("CPU Governor").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("GPU Power").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Battery").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("System Notifications").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..8 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.system_info.cpu_gov_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.system_info.gpu_gov_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.system_info.notifications_enable_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.system_info.notifications_bell_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.system_info.notifications_duration_spinbox, &mut self.ui_context);
-            }
-            Page::Processes => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Processes").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Services").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..2 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.processes.cpu_list_box.scroll_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.processes.services_search_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.processes.services_list_box.scroll_box, &mut self.ui_context);
-            }
-            Page::Radios => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("WiFi").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Bluetooth").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..2 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.network.wifi_list_box.scroll_box, &mut self.ui_context);
-            }
-            Page::Interface => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Custom Parameters").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Layout").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Status").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Controls").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Indicators").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Notification").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Surfaces").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Fonts").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Containers").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Windows").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                
-                for i in 0..10 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                
-                // Section 0: Custom Parameters
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.interface.custom_multicontrol, &mut self.ui_context);
-                
-                // Section 1: Layout (parent of Grid Layout)
-                // (Layout widgets)
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.interface.color_selectors[1], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.interface.color_selectors[2], &mut self.ui_context);
-                // (Grid Layout child widgets)
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.interface.grid_min_col_width_spinbox, &mut self.ui_context);
-
-                
-                // Section 2: Status
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.color_selectors[7], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.color_selectors[3], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.color_selectors[22], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_box_corner_radius_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_padding_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_separators_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_underline_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_box_opacity_slider, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.interface.status_box_blur_slider, &mut self.ui_context);
-                
-                // Section 3: Controls (parent of: Slider, MenuBar, Toggles, Spinbox, ColorSelector, Textbox, FontSelector)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[5], &mut self.ui_context);
-                // (Slider child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[4], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.slider_height_spinbox, &mut self.ui_context);
-                
-                // (MenuBar child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[8], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[10], &mut self.ui_context);
-
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.button_padding_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.menubar_opacity_spinbox, &mut self.ui_context);
-                 // (Toggles child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[11], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[12], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.toggle_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.toggle_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (Breadcrumb child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selectors[14], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.breadcrumb_font_selector, &mut self.ui_context);
- 
-                // (Spinbox child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.spinbox_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.spinbox_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (ColorSelector child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selector_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selector_preview_corner_radius_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selector_preview_margin_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selector_corner_radius_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.color_selector_font_selector, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.menubar_font_selector, &mut self.ui_context);
-                
-                // (Textbox child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.textbox_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.textbox_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (FontSelector child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.font_selector_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.font_selector_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (Dropdown child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.dropdown_height_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.dropdown_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (Button child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.button_corner_radius_spinbox, &mut self.ui_context);
-                
-                // (Labels child widgets)
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.interface.label_margin_spinbox, &mut self.ui_context);
-                
-                // Section 4: Indicators (parent of Primary Highlight)
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.interface.color_selectors[9], &mut self.ui_context);
-                
-                // Section 5: Notification
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.interface.color_selectors[16], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.interface.notification_opacity_spinbox, &mut self.ui_context);
-                
-                // Section 6: Surfaces
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.color_selectors[17], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.backplate_corner_radius_spinbox, &mut self.ui_context);
-                // (Plate child widgets)
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.color_selectors[0], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.plate_padding_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.plate_opacity_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.plate_corner_radius_spinbox, &mut self.ui_context);
-                // (Popover child widgets)
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.color_selectors[15], &mut self.ui_context);
-                // (Desktop child widgets)
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.color_selectors[6], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.color_selectors[23], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.desktop_grid_scale_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.interface.desktop_line_width_spinbox, &mut self.ui_context);
-                
-                // Section 7: Fonts (parent of System Fonts and Program Fonts)
-                // (System Fonts)
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.sans_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.serif_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.mono_box, &mut self.ui_context);
-                
-                // (Program Fonts)
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.borders_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.borders_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.status_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.status_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.fuzzel_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.fuzzel_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.terminal_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.interface.terminal_box, &mut self.ui_context);
- 
-                // Section 8: Containers (parent of ScrollingList, Sections, Graph)
-                // (Sections child widgets)
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.section_padding_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.page_margin_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.section_label_font_selector, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.label_alignment_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.label_offset_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.nested_section_label_font_selector, &mut self.ui_context);
-                // (ScrollingList child widgets)
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.color_selectors[13], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.color_selectors[20], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.color_selectors[21], &mut self.ui_context);
-                // (Page child widgets)
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.color_selectors[18], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.page_opacity_spinbox, &mut self.ui_context);
-                // (Layer child widgets)
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.color_selectors[19], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.layer_opacity_spinbox, &mut self.ui_context);
-                // (Graph child widgets)
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_show_grid_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_snap_enabled_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_uniform_background_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_cell_opacity_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_gap_opacity_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[8], &mut self.app.interface.graph_gap_width_spinbox, &mut self.ui_context);
-
-                // Section 9: Windows (parent of Fullscreen, Cascade, Grid, Floating, Movement, Default Layouts, Side Panel, Effects)
-                // Fullscreen
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.spinboxes[0], &mut self.ui_context);
-                
-                // Cascade
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.spinboxes[1], &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.cascade_offset_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.edge_gap_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.top_gap_spinbox, &mut self.ui_context);
-                
-                // Grid
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.grid_gap_spinbox, &mut self.ui_context);
-                
-                // Floating
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.spinboxes[3], &mut self.ui_context);
-                
-                // Movement
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.transition_duration_spinbox, &mut self.ui_context);
-                
-                // Default Layouts
-                for menu in &mut self.app.interface.windows.tag_layout_menus {
-                    link_parent_child(&mut self.page_sec_containers[9], menu, &mut self.ui_context);
-                }
-
-                // Side Panel
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.side_panel_behavior_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.side_panel_position_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.side_panel_width_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.side_panel_border_gap_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.side_panel_border_opacity_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.pinned_opacity_spinbox, &mut self.ui_context);
-
-                // Popup
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.popup_opacity_spinbox, &mut self.ui_context);
-
-                // Fullscreen
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.fullscreen_opacity_spinbox, &mut self.ui_context);
-
-                // Cascade
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.cascade_opacity_spinbox, &mut self.ui_context);
-
-                // Grid
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.grid_opacity_spinbox, &mut self.ui_context);
-
-                // Floating
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.floating_opacity_spinbox, &mut self.ui_context);
-
-                // Effects
-                link_parent_child(&mut self.page_sec_containers[9], &mut self.app.interface.windows.blur_toggle, &mut self.ui_context);
-            }
-
-
-            Page::Input => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Touchpad").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Trackpoint").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Keyboard").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Cursor").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Scrolling").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Inertial Input").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Graph").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Keyboard Bindings").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..8 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.input.tap_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.input.trackpad, &mut self.ui_context);
-
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.input.dwtp_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.input.trackpoint_accel_speed_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.input.trackpoint_accel_profile_menu, &mut self.ui_context);
-                
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.input.rate_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.input.delay_spinbox, &mut self.ui_context);
-
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.input.cursor_theme_menu, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.input.cursor_size_spinbox, &mut self.ui_context);
-                
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.input.scroll_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.input.scroll_friction_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.input.natural_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[4], &mut self.app.input.scroll_speed_spinbox, &mut self.ui_context);
-                
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.input.pointer_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.input.pointer_friction_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.input.trackpad_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[5], &mut self.app.input.trackpad_friction_spinbox, &mut self.ui_context);
-
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.input.zoom_in_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[6], &mut self.app.input.zoom_out_box, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[7], &mut self.app.input.keybinds_control, &mut self.ui_context);
-            }
-            Page::Audio => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Output").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Input").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                link_parent_child(page_root, &mut self.page_sec_containers[0], &mut self.ui_context);
-                link_parent_child(page_root, &mut self.page_sec_containers[1], &mut self.ui_context);
-                
-                for sb in &mut self.app.audio.sink_spinboxes {
-                    link_parent_child(&mut self.page_sec_containers[0], &mut **sb, &mut self.ui_context);
-                }
-                for sb in &mut self.app.audio.source_spinboxes {
-                    link_parent_child(&mut self.page_sec_containers[1], &mut **sb, &mut self.ui_context);
-                }
-                for slider in &mut self.app.audio.sink_sliders {
-                    link_parent_child(&mut self.page_sec_containers[0], &mut **slider, &mut self.ui_context);
-                }
-                for slider in &mut self.app.audio.source_sliders {
-                    link_parent_child(&mut self.page_sec_containers[1], &mut **slider, &mut self.ui_context);
-                }
-            }
-            Page::Display => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Brightness").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Night Light").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Outputs").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Screensaver Settings").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                link_parent_child(page_root, &mut self.page_sec_containers[0], &mut self.ui_context);
-                link_parent_child(page_root, &mut self.page_sec_containers[1], &mut self.ui_context);
-                link_parent_child(page_root, &mut self.page_sec_containers[2], &mut self.ui_context);
-                link_parent_child(page_root, &mut self.page_sec_containers[3], &mut self.ui_context);
-
-                // Section 0: Brightness
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.display.brightness_slider, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.display.brightness_spinbox, &mut self.ui_context);
-
-                // Section 1: Night Light
-                link_parent_child(&mut self.page_sec_containers[1], &mut self.app.display.night_light_label, &mut self.ui_context);
-
-                // Section 2: Outputs
-                for out in &mut self.app.display.outputs {
-                    link_parent_child(&mut self.page_sec_containers[2], &mut out.name_label, &mut self.ui_context);
-                    link_parent_child(&mut self.page_sec_containers[2], &mut out.resolution_label, &mut self.ui_context);
-                    if let Some(ref mut scale_lbl) = out.scale_label {
-                        link_parent_child(&mut self.page_sec_containers[2], scale_lbl, &mut self.ui_context);
-                    }
-                }
-
-                // Section 3: Screensaver Settings
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.display.screensaver_enable_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.display.screensaver_lock_screen_toggle, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.display.screensaver_timeout_spinbox, &mut self.ui_context);
-                link_parent_child(&mut self.page_sec_containers[3], &mut self.app.display.screensaver_style_menu, &mut self.ui_context);
-            }
-            Page::Packages => {
-                self.page_sec_containers.clear();
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("Packages").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                self.page_sec_containers.push(cce_ui::widget::SectionContainer::new("System Update").with_layout(cce_ui::widget::AdaptiveGridLayout { min_col_width: 140.0, gap: 8.0, padding_x: 0.0, padding_y: 0.0 }));
-                for i in 0..2 {
-                    link_parent_child(page_root, &mut self.page_sec_containers[i], &mut self.ui_context);
-                }
-                link_parent_child(&mut self.page_sec_containers[0], &mut self.app.packages.search_box, &mut self.ui_context);
-                match self.app.packages.active_tab {
-                    pages::packages::PackageTab::Installed => {
-                        link_parent_child(&mut self.page_sec_containers[0], &mut self.app.packages.installed_list_box.scroll_box, &mut self.ui_context);
-                    }
-                    pages::packages::PackageTab::Updates => {
-                        link_parent_child(&mut self.page_sec_containers[0], &mut self.app.packages.updates_list_box.scroll_box, &mut self.ui_context);
-                    }
-                }
-            }
-            _ => {}
-        }
+        active_page.link_children(page_root, &mut self.page_sec_containers, &mut self.ui_context);
 
         self.sidebar_width = self.menubar.sidebar_w();
         self.header_height = 0.0; // No CSD Titlebar
@@ -1045,7 +441,6 @@ impl SystemInterface {
     }
 
     pub(crate) fn render_page_content(&mut self, cx: f32, cy: f32, cw: f32, ch: f32) -> PageContent {
-        use pages::*;
         use cce_ui::layout::AdaptiveGrid;
         let margin = cce_ui::layout::page_margin();
         let cx = cx + margin;
@@ -1058,18 +453,7 @@ impl SystemInterface {
         let sec_focused: Vec<bool> = self.page_sec_containers.iter()
             .map(|c| cce_ui::widget::focus::is_focused(c))
             .collect();
-        match self.app.current_page {
-            Page::Accounts => accounts::view(&mut self.app.accounts, cx, cy, cw, ch, &mut layout, &mut self.ui_context),
-            Page::Audio => audio::view(&mut self.app.audio, cx, cy, cw, ch, &sec_focused, &mut layout, &mut self.ui_context),
-            Page::Display => display::view(&mut self.app.display, cx, cy, cw, ch, &mut layout, &mut self.ui_context),
-            Page::Radios => network::view(&mut self.app.network, cx, cy, cw, ch, root_focused, &mut layout, &mut self.ui_context),
-            Page::Processes => processes::view(&mut self.app.processes, cx, cy, cw, ch, root_focused, &sec_focused, &mut layout, &mut self.ui_context),
-            Page::Input => input::view(&mut self.app.input, cx, cy, cw, ch, &sec_focused, &mut layout, &mut self.ui_context),
-            Page::System => system_info::view(&mut self.app.system_info, cx, cy, cw, ch, root_focused, &sec_focused, &mut layout, &mut self.ui_context),
-            Page::Storage => storage::view(&self.app.storage, cx, cy, cw, ch, &mut layout, &mut self.ui_context),
-            Page::Interface => interface::view(&mut self.app.interface, cx, cy, cw, ch, &sec_focused, &mut layout, &mut self.ui_context),
-            Page::Packages => packages::view(&mut self.app.packages, cx, cy, cw, ch, &sec_focused, &mut layout, &mut self.ui_context),
-        }
+        self.app.get_current_page_mut().view(cx, cy, cw, ch, root_focused, &sec_focused, &mut layout, &mut self.ui_context)
     }
 
 }
diff --git a/src/watchers.rs b/src/watchers.rs
index ac0f59c..80bba2f 100644
--- a/src/watchers.rs
+++ b/src/watchers.rs
@@ -1,7 +1,7 @@
 use std::sync::Arc;
 use std::sync::atomic::{AtomicU8, Ordering};
 use std::sync::mpsc::{channel, Receiver, Sender};
-use crate::pages::{audio, display, network, interface, input, processes, system_info, storage, packages, accounts};
+use crate::pages::{Page, audio, display, network, interface, input, processes, system_info, storage, packages, accounts};
 use cce_ui::widget::Finger;
 
 pub struct Watchers {
@@ -65,9 +65,9 @@ pub fn spawn_all(
     Sender<packages::PackagesMessage>,
     Receiver<packages::PackagesMessage>,
 ) {
-    let rx_audio = spawn_bg_active(current_page_shared.clone(), 1, 3, || audio::fetch_audio_state());
-    let rx_display = spawn_bg_active(current_page_shared.clone(), 2, 10, || display::fetch_display_state());
-    let rx_network = spawn_bg_active(current_page_shared.clone(), 7, 5, || network::fetch_network_state());
+    let rx_audio = spawn_bg_active(current_page_shared.clone(), Page::Audio.index() as u8, 3, || audio::fetch_audio_state());
+    let rx_display = spawn_bg_active(current_page_shared.clone(), Page::Display.index() as u8, 10, || display::fetch_display_state());
+    let rx_network = spawn_bg_active(current_page_shared.clone(), Page::Radios.index() as u8, 5, || network::fetch_network_state());
 
     let rx_layout = {
         let (tx, rx) = channel::<interface::WindowsState>();
@@ -76,7 +76,7 @@ pub fn spawn_all(
             let mut last_fetch: Option<std::time::Instant> = None;
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 4 { // Interface is index 4
+                if current_page == Page::Interface.index() as u8 {
                     let should_fetch = match last_fetch {
                         None => true,
                         Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
@@ -103,7 +103,7 @@ pub fn spawn_all(
             let mut last_fetch: Option<std::time::Instant> = None;
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 3 { // Input is index 3
+                if current_page == Page::Input.index() as u8 {
                     let should_fetch = match last_fetch {
                         None => true,
                         Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
@@ -132,13 +132,13 @@ pub fn spawn_all(
             };
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 3 { // Input is index 3
+                if current_page == Page::Input.index() as u8 {
                     if let Ok(stream) = tokio::net::UnixStream::connect(&socket_path).await {
                         use tokio::io::AsyncBufReadExt;
                         let reader = tokio::io::BufReader::new(stream);
                         let mut lines = reader.lines();
                         while let Ok(Some(line)) = lines.next_line().await {
-                            if current_page_shared.load(Ordering::SeqCst) != 3 {
+                            if current_page_shared.load(Ordering::SeqCst) != Page::Input.index() as u8 {
                                 break;
                             }
                             if let Ok(fingers) = serde_json::from_str::<Vec<Finger>>(&line) {
@@ -155,10 +155,10 @@ pub fn spawn_all(
         rx
     };
 
-    let rx_system = spawn_bg_active(current_page_shared.clone(), 9, 5, || system_info::fetch_system_state());
-    let rx_processes = spawn_bg_active(current_page_shared.clone(), 6, 3, || processes::fetch_processes_state());
-    let rx_status = spawn_bg_active(current_page_shared.clone(), 4, 10, || interface::fetch_status_state());
-    let rx_storage = spawn_bg_active(current_page_shared.clone(), 8, 10, || storage::fetch_storage_state());
+    let rx_system = spawn_bg_active(current_page_shared.clone(), Page::System.index() as u8, 5, || system_info::fetch_system_state());
+    let rx_processes = spawn_bg_active(current_page_shared.clone(), Page::Processes.index() as u8, 3, || processes::fetch_processes_state());
+    let rx_status = spawn_bg_active(current_page_shared.clone(), Page::Interface.index() as u8, 10, || interface::fetch_status_state());
+    let rx_storage = spawn_bg_active(current_page_shared.clone(), Page::Storage.index() as u8, 10, || storage::fetch_storage_state());
 
     let rx_notifications = {
         let (tx, rx) = channel::<system_info::NotificationsConfig>();
@@ -167,7 +167,7 @@ pub fn spawn_all(
             let mut last_fetch: Option<std::time::Instant> = None;
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 9 { // System is index 9
+                if current_page == Page::System.index() as u8 {
                     let should_fetch = match last_fetch {
                         None => true,
                         Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
@@ -186,9 +186,9 @@ pub fn spawn_all(
         rx
     };
 
-    let rx_typeface = spawn_bg_active(current_page_shared.clone(), 4, 30, || interface::fetch_typeface_state());
-    let rx_services = spawn_bg_active(current_page_shared.clone(), 6, 3, || processes::fetch_services());
-    let rx_accounts = spawn_bg_active(current_page_shared.clone(), 0, 3, || accounts::fetch_accounts());
+    let rx_typeface = spawn_bg_active(current_page_shared.clone(), Page::Interface.index() as u8, 30, || interface::fetch_typeface_state());
+    let rx_services = spawn_bg_active(current_page_shared.clone(), Page::Processes.index() as u8, 3, || processes::fetch_services());
+    let rx_accounts = spawn_bg_active(current_page_shared.clone(), Page::Accounts.index() as u8, 3, || accounts::fetch_accounts());
 
     let rx_interface = {
         let (tx, rx) = channel::<interface::InterfaceState>();
@@ -197,7 +197,7 @@ pub fn spawn_all(
             let mut last_fetch: Option<std::time::Instant> = None;
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 4 { // Interface is index 4
+                if current_page == Page::Interface.index() as u8 {
                     let should_fetch = match last_fetch {
                         None => true,
                         Some(t) => t.elapsed() >= std::time::Duration::from_secs(30),
@@ -223,7 +223,7 @@ pub fn spawn_all(
             let mut last_fetch: Option<std::time::Instant> = None;
             loop {
                 let current_page = current_page_shared.load(Ordering::SeqCst);
-                if current_page == 4 { // Interface is index 4
+                if current_page == Page::Interface.index() as u8 {
                     let should_fetch = match last_fetch {
                         None => true,
                         Some(t) => t.elapsed() >= std::time::Duration::from_millis(250),
@@ -243,7 +243,7 @@ pub fn spawn_all(
     };
 
     let (tx_backup, rx_backup) = channel();
-    let rx_packages = spawn_bg_active(current_page_shared.clone(), 5, 30, || packages::fetch_packages_state());
+    let rx_packages = spawn_bg_active(current_page_shared.clone(), Page::Packages.index() as u8, 30, || packages::fetch_packages_state());
     let (tx_update, rx_update) = channel();
 
     (