Skip to main content

cosmic/
action.rs

1// Copyright 2023 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4#[cfg(feature = "winit")]
5use crate::app;
6#[cfg(feature = "single-instance")]
7use crate::dbus_activation;
8
9pub const fn app<M>(message: M) -> Action<M> {
10    Action::App(message)
11}
12#[cfg(feature = "winit")]
13pub const fn cosmic<M>(message: app::Action) -> Action<M> {
14    Action::Cosmic(message)
15}
16
17pub const fn none<M>() -> Action<M> {
18    Action::None
19}
20
21/// Wrap a surface action, typically produced by a widget, to be handled by libcosmic.
22pub const fn surface<M>(action: crate::surface::Action<M>) -> Action<M> {
23    Action::Surface(action)
24}
25
26#[derive(Clone, Debug)]
27#[must_use]
28pub enum Action<M> {
29    /// Messages from the application, for the application.
30    App(M),
31    #[cfg(feature = "winit")]
32    /// Internal messages to be handled by libcosmic.
33    Cosmic(app::Action),
34    #[cfg(feature = "single-instance")]
35    /// Dbus activation messages
36    DbusActivation(dbus_activation::Message),
37    /// Surface (popup, subsurface, window, layer shell) requests, handled by libcosmic.
38    Surface(crate::surface::Action<M>),
39    /// Do nothing
40    None,
41}
42
43impl<M: 'static> Action<M> {
44    /// Map the application message inside, leaving libcosmic's own variants untouched.
45    #[must_use]
46    pub fn map<N: 'static>(self, f: impl Fn(M) -> N + Clone + Send + Sync + 'static) -> Action<N> {
47        match self {
48            Action::App(message) => Action::App(f(message)),
49            #[cfg(feature = "winit")]
50            Action::Cosmic(action) => Action::Cosmic(action),
51            #[cfg(feature = "single-instance")]
52            Action::DbusActivation(message) => Action::DbusActivation(message),
53            Action::Surface(action) => Action::Surface(action.map(f)),
54            Action::None => Action::None,
55        }
56    }
57}
58
59impl<M: 'static> Action<Action<M>> {
60    /// Collapse a doubly wrapped action, as produced by widgets whose message type is already
61    /// an [`Action`], into a single one.
62    #[must_use]
63    pub fn flatten(self) -> Action<M> {
64        match self {
65            Action::App(action) => action,
66            #[cfg(feature = "winit")]
67            Action::Cosmic(action) => Action::Cosmic(action),
68            #[cfg(feature = "single-instance")]
69            Action::DbusActivation(message) => Action::DbusActivation(message),
70            Action::Surface(action) => Action::Surface(action.flatten()),
71            Action::None => Action::None,
72        }
73    }
74}
75
76impl<M> From<M> for Action<M> {
77    fn from(value: M) -> Self {
78        Self::App(value)
79    }
80}