1use abi_stable::{
2 StableAbi,
3 std_types::{RString, RVec},
4};
5
6use crate::payload::PayloadBox;
7
8#[repr(C)]
9#[derive(StableAbi, Clone, Copy, Debug, PartialEq, Eq)]
10pub enum WidgetEventKind {
11 Input,
12 Submit,
13 Custom,
14 Scroll,
15}
16
17#[repr(C)]
18#[derive(StableAbi, Clone, Debug, PartialEq)]
19pub struct WidgetEvent {
20 pub id: RString,
21 pub kind: WidgetEventKind,
22 pub value: RString,
23 pub scroll: [f32; 2],
24}
25#[repr(C)]
26#[derive(StableAbi, Clone, Copy, Debug, Default, PartialEq, Eq)]
27pub struct CompositorEvent(pub u8);
28
29impl CompositorEvent {
30 pub const NONE: Self = Self(0);
31 pub const WINDOWS: Self = Self(1 << 0);
32 pub const FOCUS: Self = Self(1 << 1);
33 pub const WORKSPACES: Self = Self(1 << 2);
34 pub const MONITORS: Self = Self(1 << 3);
35 pub const OVERVIEW: Self = Self(1 << 4);
36 pub const ALL: Self = Self(0b1_1111);
37
38 pub const fn bits(self) -> u8 {
39 self.0
40 }
41
42 pub const fn from_bits(bits: u8) -> Self {
43 Self(bits)
44 }
45
46 pub const fn is_empty(self) -> bool {
47 self.0 == 0
48 }
49
50 pub const fn contains(self, other: Self) -> bool {
51 self.0 & other.0 == other.0
52 }
53
54 pub const fn intersects(self, other: Self) -> bool {
55 self.0 & other.0 != 0
56 }
57
58 pub fn insert(&mut self, other: Self) {
59 self.0 |= other.0;
60 }
61}
62
63impl core::ops::BitOr for CompositorEvent {
64 type Output = Self;
65
66 fn bitor(self, rhs: Self) -> Self {
67 Self(self.0 | rhs.0)
68 }
69}
70
71impl core::ops::BitOrAssign for CompositorEvent {
72 fn bitor_assign(&mut self, rhs: Self) {
73 self.0 |= rhs.0;
74 }
75}
76
77#[repr(C)]
78#[derive(StableAbi, Clone, Debug, PartialEq, Eq)]
79pub enum EventFilter {
80 Tick,
81 Fd,
82 Widget,
83 ConfigReload,
84 CompositorUpdate,
85 Compositor(CompositorEvent),
86 Frame,
87 Named(RString),
88 Payload(RString),
89 Ipc(RString),
90 StartUp,
91 All,
92}
93
94impl EventFilter {
95 pub const fn tick() -> Self {
96 Self::Tick
97 }
98
99 pub const fn frame() -> Self {
100 Self::Frame
101 }
102
103 pub const fn compositor() -> Self {
104 Self::CompositorUpdate
105 }
106
107 pub fn named(name: impl Into<RString>) -> Self {
108 Self::Named(name.into())
109 }
110
111 pub fn payload(name: impl Into<RString>) -> Self {
112 Self::Payload(name.into())
113 }
114
115 pub fn ipc(name: impl Into<RString>) -> Self {
116 Self::Ipc(name.into())
117 }
118}
119
120#[repr(C)]
121#[derive(StableAbi, Clone, Debug)]
122pub enum Event {
123 Tick {
124 tag: u32,
125 fd: i32,
126 },
127 Fd {
128 action: u32,
129 fd: i32,
130 },
131 ConfigReload,
132 CompositorUpdate(CompositorEvent),
133 Frame,
134 Named(RString),
135 Payload {
136 name: RString,
137 payload: PayloadBox,
138 },
139 Ipc {
140 name: RString,
141 command: RString,
142 args: RVec<RString>,
143 },
144 StartUp,
145 Widget(WidgetEvent),
146 Other(u32),
147}
148
149#[repr(C)]
150#[derive(StableAbi, Clone, Copy, Debug, PartialEq, Eq)]
151pub enum ItemEffect {
152 None,
153 Redraw,
154 Subscribe,
155 Hide,
156 Show,
157 ReallyHide,
158 Destroy,
159 ReallyDestroy,
160 Custom([usize; 4]),
161}
162
163#[repr(C)]
164#[derive(StableAbi, Clone, Debug, PartialEq, Eq)]
165pub enum Message {
166 Noop,
167 Effect(ItemEffect),
168 Action(RString),
169 EffectAction(ItemEffect, RString),
170}
171
172#[repr(C)]
173#[derive(StableAbi, Clone, Debug, PartialEq, Eq)]
174pub struct ArgEntry {
175 pub key: RString,
176 pub value: RString,
177}
178
179#[repr(C)]
180#[derive(StableAbi, Clone, Debug, Default, PartialEq, Eq)]
181pub struct Args {
182 entries: RVec<ArgEntry>,
183}
184
185impl Args {
186 pub fn new(entries: impl IntoIterator<Item = (RString, RString)>) -> Self {
187 Self {
188 entries: entries
189 .into_iter()
190 .map(|(key, value)| ArgEntry { key, value })
191 .collect(),
192 }
193 }
194
195 pub fn get(&self, key: &str) -> Option<&str> {
196 self
197 .entries
198 .iter()
199 .find(|entry| &*entry.key == key)
200 .map(|entry| &*entry.value)
201 }
202
203 pub fn get_f64(&self, key: &str) -> Option<f64> {
204 self.get(key).and_then(|value| value.parse().ok())
205 }
206
207 pub fn get_i64(&self, key: &str) -> Option<i64> {
208 self.get(key).and_then(|value| value.parse().ok())
209 }
210
211 pub fn get_bool(&self, key: &str) -> Option<bool> {
212 self.get(key).and_then(|value| value.parse().ok())
213 }
214
215 pub fn contains(&self, key: &str) -> bool {
216 self.entries.iter().any(|entry| &*entry.key == key)
217 }
218
219 pub fn is_empty(&self) -> bool {
220 self.entries.is_empty()
221 }
222
223 pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
224 self
225 .entries
226 .iter()
227 .map(|entry| (&*entry.key, &*entry.value))
228 }
229
230 pub fn render(&self) -> String {
231 self
232 .entries
233 .iter()
234 .map(|entry| format!("{}={}", entry.key, entry.value))
235 .collect::<Vec<_>>()
236 .join(" ")
237 }
238}