Skip to main content

fret_runtime/capabilities/
qualities.rs

1use serde::{Deserialize, Serialize};
2
3/// Quality of cursor/position updates during external OS drag sessions (e.g. file drag hover).
4///
5/// This is used to express *degradation*, not just availability:
6/// a backend may support external drops but not provide reliable per-frame hover coordinates.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
8#[serde(rename_all = "snake_case")]
9pub enum ExternalDragPositionQuality {
10    /// External drag is unsupported (or position updates are unavailable).
11    None,
12    /// The backend provides external drag events, but pointer positions are best-effort / may be
13    /// stale or missing (e.g. macOS winit file DnD hover limitations).
14    BestEffort,
15    /// The backend provides reliable pointer position updates during external drag hover.
16    #[default]
17    Continuous,
18}
19
20impl ExternalDragPositionQuality {
21    pub fn as_str(self) -> &'static str {
22        match self {
23            Self::None => "none",
24            Self::BestEffort => "best_effort",
25            Self::Continuous => "continuous",
26        }
27    }
28
29    pub fn clamp_to_available(self, available: Self) -> Self {
30        use ExternalDragPositionQuality::*;
31        match (self, available) {
32            (None, _) => None,
33            (_, None) => None,
34            (BestEffort, BestEffort | Continuous) => BestEffort,
35            (Continuous, Continuous) => Continuous,
36            (Continuous, BestEffort) => BestEffort,
37        }
38    }
39}
40
41/// Windowing quality signal: whether the backend can reliably determine which window is under the
42/// cursor.
43///
44/// This is used as a degradation signal for editor-grade multi-window UX (e.g. docking tear-off
45/// hover target selection under overlap).
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
47#[serde(rename_all = "snake_case")]
48pub enum WindowHoverDetectionQuality {
49    /// The backend cannot reliably determine window-under-cursor (or cannot provide global cursor
50    /// position updates needed to infer it).
51    None,
52    /// Best-effort: selection may be stale/missing or ambiguous under overlap.
53    BestEffort,
54    /// Reliable enough for editor-grade hover selection.
55    #[default]
56    Reliable,
57}
58
59impl WindowHoverDetectionQuality {
60    pub fn as_str(self) -> &'static str {
61        match self {
62            Self::None => "none",
63            Self::BestEffort => "best_effort",
64            Self::Reliable => "reliable",
65        }
66    }
67
68    pub fn clamp_to_available(self, available: Self) -> Self {
69        use WindowHoverDetectionQuality::*;
70        match (self, available) {
71            (None, _) => None,
72            (_, None) => None,
73            (BestEffort, BestEffort | Reliable) => BestEffort,
74            (Reliable, Reliable) => Reliable,
75            (Reliable, BestEffort) => BestEffort,
76        }
77    }
78}
79
80/// Windowing quality signal: whether programmatic window movement via outer-position requests is
81/// reliable enough for "follow cursor" UX.
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
83#[serde(rename_all = "snake_case")]
84pub enum WindowSetOuterPositionQuality {
85    None,
86    BestEffort,
87    #[default]
88    Reliable,
89}
90
91impl WindowSetOuterPositionQuality {
92    pub fn as_str(self) -> &'static str {
93        match self {
94            Self::None => "none",
95            Self::BestEffort => "best_effort",
96            Self::Reliable => "reliable",
97        }
98    }
99
100    pub fn clamp_to_available(self, available: Self) -> Self {
101        use WindowSetOuterPositionQuality::*;
102        match (self, available) {
103            (None, _) => None,
104            (_, None) => None,
105            (BestEffort, BestEffort | Reliable) => BestEffort,
106            (Reliable, Reliable) => Reliable,
107            (Reliable, BestEffort) => BestEffort,
108        }
109    }
110}
111
112/// Windowing quality signal: whether OS z-level requests (e.g. AlwaysOnTop during drags) behave
113/// predictably.
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
115#[serde(rename_all = "snake_case")]
116pub enum WindowZLevelQuality {
117    None,
118    BestEffort,
119    #[default]
120    Reliable,
121}
122
123impl WindowZLevelQuality {
124    pub fn as_str(self) -> &'static str {
125        match self {
126            Self::None => "none",
127            Self::BestEffort => "best_effort",
128            Self::Reliable => "reliable",
129        }
130    }
131
132    pub fn clamp_to_available(self, available: Self) -> Self {
133        use WindowZLevelQuality::*;
134        match (self, available) {
135            (None, _) => None,
136            (_, None) => None,
137            (BestEffort, BestEffort | Reliable) => BestEffort,
138            (Reliable, Reliable) => Reliable,
139            (Reliable, BestEffort) => BestEffort,
140        }
141    }
142}