1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::sync::Arc;

use log::info;

use crate::api::EventHub;

use super::{unix_wayland, unix_x11, ClipboardCommon, ClipboardError, ClipboardResult, SelectionProvider};

pub enum Clipboard {
  Wayland(unix_wayland::Clipboard),
  X11(unix_x11::Clipboard),
}

impl ClipboardCommon for Clipboard {
  fn new<T>(selection_provider: T, event_hub: Arc<dyn EventHub>) -> ClipboardResult<Self>
  where
    T: SelectionProvider + Clone + 'static,
  {
    match unix_wayland::Clipboard::new(selection_provider.clone(), event_hub.clone()) {
      Ok(wayland) => Ok(Clipboard::Wayland(wayland)),
      Err(ClipboardError::Unavailable) => {
        info!("Wayland unavailable, fallback to x11");
        unix_x11::Clipboard::new(selection_provider, event_hub).map(Clipboard::X11)
      }
      Err(err) => Err(err),
    }
  }

  fn destroy(&self) {
    match self {
      Clipboard::Wayland(wayland) => wayland.destroy(),
      Clipboard::X11(x11) => x11.destroy(),
    }
  }

  fn is_open(&self) -> bool {
    match self {
      Clipboard::Wayland(wayland) => wayland.is_open(),
      Clipboard::X11(x11) => x11.is_open(),
    }
  }

  fn currently_providing(&self) -> Option<crate::api::ClipboardProviding> {
    match self {
      Clipboard::Wayland(wayland) => wayland.currently_providing(),
      Clipboard::X11(x11) => x11.currently_providing(),
    }
  }

  fn provide_next(&self) {
    match self {
      Clipboard::Wayland(wayland) => wayland.provide_next(),
      Clipboard::X11(x11) => x11.provide_next(),
    }
  }

  fn wait(&self) -> super::ClipboardResult<()> {
    match self {
      Clipboard::Wayland(wayland) => wayland.wait(),
      Clipboard::X11(x11) => x11.wait(),
    }
  }
}