Skip to main content

slowshell_plugin_abi/
event.rs

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}