Skip to main content

halley_config/layout/
guards.rs

1use super::{CursorConfig, FontConfig, KeyboardConfig, RuntimeTuning};
2
3impl RuntimeTuning {
4    pub fn enforce_guards(&mut self) {
5        self.clamp_values();
6    }
7
8    pub(crate) fn clamp_values(&mut self) {
9        self.viewport_center.x = self.viewport_center.x.clamp(-100_000.0, 100_000.0);
10        self.viewport_center.y = self.viewport_center.y.clamp(-100_000.0, 100_000.0);
11        self.viewport_size.x = self.viewport_size.x.clamp(320.0, 16_000.0);
12        self.viewport_size.y = self.viewport_size.y.clamp(240.0, 16_000.0);
13
14        self.focus_ring_rx = self.focus_ring_rx.clamp(8.0, 16_000.0);
15        self.focus_ring_ry = self.focus_ring_ry.clamp(8.0, 16_000.0);
16        self.focus_ring_offset_x = self.focus_ring_offset_x.clamp(-16_000.0, 16_000.0);
17        self.focus_ring_offset_y = self.focus_ring_offset_y.clamp(-16_000.0, 16_000.0);
18
19        self.primary_hot_inner_frac = self.primary_hot_inner_frac.clamp(0.1, 1.0);
20        self.primary_to_node_ms = self.primary_to_node_ms.clamp(250, 7_200_000);
21        self.node_icon_size = self.node_icon_size.clamp(0.35, 0.95);
22        self.decorations.border.size_px = self.decorations.border.size_px.clamp(0, 64);
23        self.decorations.border.radius_px = self.decorations.border.radius_px.clamp(0, 256);
24        self.decorations.secondary_border.size_px =
25            self.decorations.secondary_border.size_px.clamp(0, 64);
26        self.decorations.secondary_border.gap_px =
27            self.decorations.secondary_border.gap_px.clamp(0, 8);
28        for shadow in [
29            &mut self.decorations.shadows.window,
30            &mut self.decorations.shadows.node,
31            &mut self.decorations.shadows.overlay,
32        ] {
33            shadow.blur_radius = shadow.blur_radius.clamp(0.0, 256.0);
34            shadow.spread = shadow.spread.clamp(0.0, 256.0);
35            shadow.offset_x = shadow.offset_x.clamp(-256.0, 256.0);
36            shadow.offset_y = shadow.offset_y.clamp(-256.0, 256.0);
37            shadow.color.r = shadow.color.r.clamp(0.0, 1.0);
38            shadow.color.g = shadow.color.g.clamp(0.0, 1.0);
39            shadow.color.b = shadow.color.b.clamp(0.0, 1.0);
40            shadow.color.a = shadow.color.a.clamp(0.0, 1.0);
41        }
42        self.bearings.fade_distance = self.bearings.fade_distance.clamp(120.0, 100_000.0);
43        self.rail.offset_x = self.rail.offset_x.clamp(-16_000, 16_000);
44        self.rail.offset_y = self.rail.offset_y.clamp(-16_000, 16_000);
45        self.rail.width = self.rail.width.clamp(0, 16_000);
46        self.rail.height = self.rail.height.clamp(0, 16_000);
47        self.rail.icon_size = self.rail.icon_size.clamp(12, 256);
48        self.rail.gap = self.rail.gap.clamp(0, 256);
49        self.rail.padding = self.rail.padding.clamp(0, 256);
50        self.rail.radius = self.rail.radius.clamp(0, 512);
51
52        self.cluster_distance_px = self.cluster_distance_px.clamp(24.0, 4_000.0);
53        self.cluster_dwell_ms = self.cluster_dwell_ms.clamp(0, 30_000);
54        self.tile_gaps_inner_px = self.tile_gaps_inner_px.clamp(0.0, 256.0);
55        self.tile_gaps_outer_px = self.tile_gaps_outer_px.clamp(0.0, 512.0);
56        self.tile_max_stack = self.tile_max_stack.clamp(0, 64);
57        self.stacking_max_visible = self.stacking_max_visible.clamp(0, 64);
58        self.trail_history_length = self.trail_history_length.clamp(1, 512);
59        self.input.repeat_rate = self.input.repeat_rate.clamp(0, 1000);
60        self.input.repeat_delay = self.input.repeat_delay.clamp(0, 10_000);
61        self.input.keyboard.layout = self.input.keyboard.layout.trim().to_string();
62        if self.input.keyboard.layout.is_empty() {
63            self.input.keyboard.layout = KeyboardConfig::default().layout;
64        }
65        self.input.keyboard.variant = self.input.keyboard.variant.trim().to_string();
66        self.input.keyboard.options = self.input.keyboard.options.trim().to_string();
67        self.cursor.size = self.cursor.size.clamp(8, 128);
68        if self.cursor.theme.trim().is_empty() {
69            self.cursor.theme = CursorConfig::default().theme;
70        }
71        self.font.size = self.font.size.clamp(8, 32);
72        if self.font.family.trim().is_empty() {
73            self.font.family = FontConfig::default().family;
74        }
75
76        self.active_outside_ring_delay_ms = self.active_outside_ring_delay_ms.clamp(0, 7_200_000);
77        self.inactive_outside_ring_delay_ms =
78            self.inactive_outside_ring_delay_ms.clamp(0, 7_200_000);
79        self.docked_offscreen_delay_ms = self.docked_offscreen_delay_ms.clamp(0, 7_200_000);
80
81        self.non_overlap_gap_px = self.non_overlap_gap_px.clamp(0.0, 256.0);
82        self.field_active_windows_allowed = self.field_active_windows_allowed.clamp(0, 64);
83        self.pins.size = self.pins.size.clamp(0.5, 3.0);
84        self.zoom_step = self.zoom_step.clamp(1.001, 4.0);
85        self.zoom_min = self.zoom_min.clamp(0.05, 1.0);
86        self.zoom_max = self.zoom_max.clamp(1.0, 16.0);
87        if self.zoom_max < self.zoom_min {
88            self.zoom_max = self.zoom_min;
89        }
90        self.zoom_smooth_rate = self.zoom_smooth_rate.clamp(0.1, 120.0);
91        self.non_overlap_active_gap_scale = self.non_overlap_active_gap_scale.clamp(0.0, 1.2);
92        self.non_overlap_bump_damping = self.non_overlap_bump_damping.clamp(0.05, 1.0);
93        self.drag_smoothing_boost = self.drag_smoothing_boost.clamp(0.1, 20.0);
94        self.animations.smooth_resize.duration_ms =
95            self.animations.smooth_resize.duration_ms.clamp(1, 10_000);
96        self.animations.maximize.duration_ms =
97            self.animations.maximize.duration_ms.clamp(1, 10_000);
98        self.animations.fullscreen.duration_ms =
99            self.animations.fullscreen.duration_ms.clamp(1, 10_000);
100        self.animations.window_close.duration_ms =
101            self.animations.window_close.duration_ms.clamp(1, 10_000);
102        self.animations.window_open.duration_ms =
103            self.animations.window_open.duration_ms.clamp(1, 10_000);
104        self.animations.tile.duration_ms = self.animations.tile.duration_ms.clamp(1, 10_000);
105        self.animations.stack.duration_ms = self.animations.stack.duration_ms.clamp(1, 10_000);
106        self.animations.raise.duration_ms = self.animations.raise.duration_ms.clamp(1, 10_000);
107        self.animations.raise.scale = self.animations.raise.scale.clamp(1.0, 1.2);
108        self.animations.raise.shadow_boost = self.animations.raise.shadow_boost.clamp(0.0, 1.0);
109    }
110}
111
112#[cfg(test)]
113mod tests {
114    use super::*;
115
116    #[test]
117    fn secondary_border_gap_is_clamped_to_small_range() {
118        let mut tuning = RuntimeTuning::default();
119        tuning.decorations.secondary_border.gap_px = 99;
120
121        tuning.enforce_guards();
122
123        assert_eq!(tuning.decorations.secondary_border.gap_px, 8);
124    }
125}