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
use std::io;
use crate::{ClipboardHandler, CallbackResult, Master};

use objc::runtime::{Object, Class};
use objc_id::{Id};

#[link(name = "AppKit", kind = "framework")]
extern "C" {}

impl<H: ClipboardHandler> Master<H> {
    ///Starts Master by polling clipboard for change
    pub fn run(&mut self) -> io::Result<()> {
        use objc::{msg_send, sel, sel_impl};

        let cls = match Class::get("NSPasteboard") {
            Some(cls) => cls,
            None => return Err(io::Error::new(io::ErrorKind::Other, "Unable to create mac pasteboard")),
        };
        let pasteboard: *mut Object = unsafe { msg_send![cls, generalPasteboard] };

        if pasteboard.is_null() {
            return Err(io::Error::new(io::ErrorKind::Other, "Unable to create mac pasteboard"));
        }

        let pasteboard: Id<Object> = unsafe { Id::from_ptr(pasteboard) };

        let mut prev_count = unsafe { msg_send![pasteboard, changeCount] };
        let mut result = Ok(());

        loop {
            let count: isize = unsafe { msg_send![pasteboard, changeCount] };

            if count == prev_count {
                std::thread::sleep(self.handler.sleep_interval());
                continue;
            }

            prev_count = count;

            match self.handler.on_clipboard_change() {
                CallbackResult::Next => (),
                CallbackResult::Stop => break,
                CallbackResult::StopWithError(error) => {
                    result = Err(error);
                    break;
                }
            }
        }

        result
    }
}