Implement notification on MacOS
This commit is contained in:
		
							parent
							
								
									68fd2fccc1
								
							
						
					
					
						commit
						fbd053f67d
					
				
							
								
								
									
										75
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										75
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,10 @@
 | 
			
		|||
# This file is automatically @generated by Cargo.
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "adler32"
 | 
			
		||||
version = "1.0.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "aho-corasick"
 | 
			
		||||
version = "0.7.6"
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +96,24 @@ name = "byteorder"
 | 
			
		|||
version = "1.3.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bzip2"
 | 
			
		||||
version = "0.3.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "bzip2-sys"
 | 
			
		||||
version = "0.1.7"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "cc"
 | 
			
		||||
version = "1.0.41"
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +170,14 @@ name = "constant_time_eq"
 | 
			
		|||
version = "0.1.4"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "crc32fast"
 | 
			
		||||
version = "1.2.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "crossbeam-utils"
 | 
			
		||||
version = "0.6.6"
 | 
			
		||||
| 
						 | 
				
			
			@ -194,6 +225,7 @@ dependencies = [
 | 
			
		|||
 "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "simplelog 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "zip 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
| 
						 | 
				
			
			@ -216,6 +248,16 @@ dependencies = [
 | 
			
		|||
 "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "flate2"
 | 
			
		||||
version = "1.0.11"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "fuchsia-cprng"
 | 
			
		||||
version = "0.1.1"
 | 
			
		||||
| 
						 | 
				
			
			@ -249,6 +291,14 @@ name = "memchr"
 | 
			
		|||
version = "2.2.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "miniz_oxide"
 | 
			
		||||
version = "0.3.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "nodrop"
 | 
			
		||||
version = "0.1.13"
 | 
			
		||||
| 
						 | 
				
			
			@ -271,6 +321,11 @@ dependencies = [
 | 
			
		|||
 "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "podio"
 | 
			
		||||
version = "0.1.6"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "0.4.30"
 | 
			
		||||
| 
						 | 
				
			
			@ -546,7 +601,20 @@ dependencies = [
 | 
			
		|||
 "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "zip"
 | 
			
		||||
version = "0.5.3"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
 "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[metadata]
 | 
			
		||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
 | 
			
		||||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
 | 
			
		||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 | 
			
		||||
"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
 | 
			
		||||
| 
						 | 
				
			
			@ -559,6 +627,8 @@ dependencies = [
 | 
			
		|||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
 | 
			
		||||
"checksum blake2b_simd 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bf775a81bb2d464e20ff170ac20316c7b08a43d11dbc72f0f82e8e8d3d6d0499"
 | 
			
		||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
 | 
			
		||||
"checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
 | 
			
		||||
"checksum bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6584aa36f5ad4c9247f5323b0a42f37802b37a836f0ad87084d7a33961abe25f"
 | 
			
		||||
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
 | 
			
		||||
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
 | 
			
		||||
"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
 | 
			
		||||
| 
						 | 
				
			
			@ -566,21 +636,25 @@ dependencies = [
 | 
			
		|||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
 | 
			
		||||
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
 | 
			
		||||
"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120"
 | 
			
		||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
 | 
			
		||||
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
 | 
			
		||||
"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
 | 
			
		||||
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
 | 
			
		||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
 | 
			
		||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
 | 
			
		||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
 | 
			
		||||
"checksum flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "2adaffba6388640136149e18ed080b77a78611c1e1d6de75aedcdf78df5d4682"
 | 
			
		||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
 | 
			
		||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 | 
			
		||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
 | 
			
		||||
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
 | 
			
		||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
 | 
			
		||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
 | 
			
		||||
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
 | 
			
		||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
 | 
			
		||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
 | 
			
		||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
 | 
			
		||||
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
 | 
			
		||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
 | 
			
		||||
"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
 | 
			
		||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
 | 
			
		||||
| 
						 | 
				
			
			@ -616,3 +690,4 @@ dependencies = [
 | 
			
		|||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 | 
			
		||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
			
		||||
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
 | 
			
		||||
"checksum zip 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c21bb410afa2bd823a047f5bda3adb62f51074ac7e06263b2c97ecdd47e9fc6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ clap = "2.33.0"
 | 
			
		|||
regex = "1.3.1"
 | 
			
		||||
log = "0.4.8"
 | 
			
		||||
simplelog = "0.7.1"
 | 
			
		||||
zip = "0.5.3"
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
cmake = "0.1.31"
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -22,10 +22,12 @@
 | 
			
		|||
    
 | 
			
		||||
    NSString *title = @"Title";
 | 
			
		||||
    NSString *desc = @"Description";
 | 
			
		||||
    double delay = 1.5;
 | 
			
		||||
    
 | 
			
		||||
    if ([args count] > 2) {
 | 
			
		||||
    if ([args count] > 3) {
 | 
			
		||||
        title = args[1];
 | 
			
		||||
        desc = args[2];
 | 
			
		||||
        delay = [args[3] doubleValue];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSUserNotification *notification = [[NSUserNotification alloc] init];
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +37,8 @@
 | 
			
		|||
    
 | 
			
		||||
    [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
 | 
			
		||||
    
 | 
			
		||||
    [[NSUserNotificationCenter defaultUserNotificationCenter] performSelector:@selector(removeDeliveredNotification:) withObject:notification afterDelay:delay];
 | 
			
		||||
    
 | 
			
		||||
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
 | 
			
		||||
        NSRunningApplication *app = [NSRunningApplication currentApplication];
 | 
			
		||||
        [app terminate];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								src/bridge/macos.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/bridge/macos.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
use std::os::raw::{c_void, c_char};
 | 
			
		||||
 | 
			
		||||
#[allow(improper_ctypes)]
 | 
			
		||||
#[link(name="macbridge", kind="static")]
 | 
			
		||||
extern {
 | 
			
		||||
    pub fn register_keypress_callback(s: *const c_void,
 | 
			
		||||
                                  cb: extern fn(_self: *mut c_void, *const u8,
 | 
			
		||||
                                                i32, i32, i32));
 | 
			
		||||
    pub fn initialize();
 | 
			
		||||
    pub fn eventloop();
 | 
			
		||||
    pub fn send_string(string: *const c_char);
 | 
			
		||||
    pub fn send_vkey(vk: i32);
 | 
			
		||||
    pub fn delete_string(count: i32);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/clipboard/macos.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/clipboard/macos.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
pub struct MacClipboardManager {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl super::ClipboardManager for MacClipboardManager {
 | 
			
		||||
    fn get_clipboard(&self) -> Option<String>  {
 | 
			
		||||
        unimplemented!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_clipboard(&self, payload: &str) {
 | 
			
		||||
        unimplemented!();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MacClipboardManager {
 | 
			
		||||
    pub fn new() -> MacClipboardManager {
 | 
			
		||||
        MacClipboardManager{}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,11 +8,12 @@ mod linux;
 | 
			
		|||
mod macos;
 | 
			
		||||
 | 
			
		||||
pub trait ClipboardManager {
 | 
			
		||||
    fn initialize(&self);
 | 
			
		||||
    fn get_clipboard(&self) -> Option<String>;
 | 
			
		||||
    fn set_clipboard(&self, payload: &str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: change windows and linux implementations to avoid initialize() call and use constructor instead
 | 
			
		||||
 | 
			
		||||
// LINUX IMPLEMENTATION
 | 
			
		||||
#[cfg(target_os = "linux")]
 | 
			
		||||
pub fn get_manager() -> impl ClipboardManager {
 | 
			
		||||
| 
						 | 
				
			
			@ -27,4 +28,10 @@ pub fn get_manager() -> impl ClipboardManager {
 | 
			
		|||
    let manager = windows::WindowsClipboardManager{};
 | 
			
		||||
    manager.initialize();
 | 
			
		||||
    manager
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MAC IMPLEMENTATION
 | 
			
		||||
#[cfg(target_os = "macos")]
 | 
			
		||||
pub fn get_manager() -> impl ClipboardManager {
 | 
			
		||||
    macos::MacClipboardManager::new()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
use std::sync::mpsc;
 | 
			
		||||
use std::os::raw::c_char;
 | 
			
		||||
use std::os::raw::{c_char, c_void};
 | 
			
		||||
use std::ffi::CString;
 | 
			
		||||
use crate::keyboard::{KeyEvent, KeyModifier};
 | 
			
		||||
use crate::keyboard::KeyModifier::*;
 | 
			
		||||
use crate::bridge::macos::*;
 | 
			
		||||
 | 
			
		||||
#[repr(C)]
 | 
			
		||||
pub struct MacKeyboardInterceptor {
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +13,8 @@ pub struct MacKeyboardInterceptor {
 | 
			
		|||
impl super::KeyboardInterceptor for MacKeyboardInterceptor {
 | 
			
		||||
    fn initialize(&self) {
 | 
			
		||||
        unsafe {
 | 
			
		||||
            register_keypress_callback(self,keypress_callback);
 | 
			
		||||
            let self_ptr = self as *const MacKeyboardInterceptor as *const c_void;
 | 
			
		||||
            register_keypress_callback(self_ptr,keypress_callback);
 | 
			
		||||
            initialize();
 | 
			
		||||
        }  // TODO: check initialization return codes
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +43,10 @@ impl super::KeyboardSender for MacKeyboardSender {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn trigger_paste(&self) {
 | 
			
		||||
        unimplemented!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn delete_string(&self, count: i32) {
 | 
			
		||||
        unsafe {delete_string(count)}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -48,9 +54,11 @@ impl super::KeyboardSender for MacKeyboardSender {
 | 
			
		|||
 | 
			
		||||
// Native bridge code
 | 
			
		||||
 | 
			
		||||
extern fn keypress_callback(_self: *mut MacKeyboardInterceptor, raw_buffer: *const u8, len: i32,
 | 
			
		||||
extern fn keypress_callback(_self: *mut c_void, raw_buffer: *const u8, len: i32,
 | 
			
		||||
                            is_modifier: i32, key_code: i32) {
 | 
			
		||||
    unsafe {
 | 
			
		||||
        let _self = _self as *mut MacKeyboardInterceptor;
 | 
			
		||||
 | 
			
		||||
        if is_modifier == 0 {  // Char event
 | 
			
		||||
            // Convert the received buffer to a character
 | 
			
		||||
            let buffer = std::slice::from_raw_parts(raw_buffer, len as usize);
 | 
			
		||||
| 
						 | 
				
			
			@ -75,17 +83,4 @@ extern fn keypress_callback(_self: *mut MacKeyboardInterceptor, raw_buffer: *con
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(improper_ctypes)]
 | 
			
		||||
#[link(name="macbridge", kind="static")]
 | 
			
		||||
extern {
 | 
			
		||||
    fn register_keypress_callback(s: *const MacKeyboardInterceptor,
 | 
			
		||||
                                  cb: extern fn(_self: *mut MacKeyboardInterceptor, *const u8,
 | 
			
		||||
                                                i32, i32, i32));
 | 
			
		||||
    fn initialize();
 | 
			
		||||
    fn eventloop();
 | 
			
		||||
    fn send_string(string: *const c_char);
 | 
			
		||||
    fn send_vkey(vk: i32);
 | 
			
		||||
    fn delete_string(count: i32);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +95,7 @@ fn espanso_background(rxc: Receiver<KeyEvent>, config_set: ConfigSet) {
 | 
			
		|||
    let config_manager = RuntimeConfigManager::new(config_set, system_manager);
 | 
			
		||||
 | 
			
		||||
    let ui_manager = ui::get_uimanager();
 | 
			
		||||
    ui_manager.notify("espanso is running!");
 | 
			
		||||
 | 
			
		||||
    let clipboard_manager = clipboard::get_manager();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -8,10 +8,6 @@ pub struct LinuxSystemManager {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl super::SystemManager for LinuxSystemManager {
 | 
			
		||||
    fn initialize(&self) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_current_window_title(&self) -> Option<String> {
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let mut buffer : [c_char; 100] = [0; 100];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								src/system/macos.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/system/macos.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
use std::os::raw::c_char;
 | 
			
		||||
 | 
			
		||||
use std::ffi::CStr;
 | 
			
		||||
 | 
			
		||||
pub struct MacSystemManager {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl super::SystemManager for MacSystemManager {
 | 
			
		||||
    fn get_current_window_title(&self) -> Option<String> {
 | 
			
		||||
        unimplemented!()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_current_window_class(&self) -> Option<String> {
 | 
			
		||||
        unimplemented!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_current_window_executable(&self) -> Option<String> {
 | 
			
		||||
        unimplemented!()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MacSystemManager {
 | 
			
		||||
    pub fn new() -> MacSystemManager {
 | 
			
		||||
        MacSystemManager{
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,12 +8,13 @@ mod linux;
 | 
			
		|||
mod macos;
 | 
			
		||||
 | 
			
		||||
pub trait SystemManager {
 | 
			
		||||
    fn initialize(&self);
 | 
			
		||||
    fn get_current_window_title(&self) -> Option<String>;
 | 
			
		||||
    fn get_current_window_class(&self) -> Option<String>;
 | 
			
		||||
    fn get_current_window_executable(&self) -> Option<String>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: change windows and linux implementations to avoid initialize() call and use constructor instead
 | 
			
		||||
 | 
			
		||||
// LINUX IMPLEMENTATION
 | 
			
		||||
#[cfg(target_os = "linux")]
 | 
			
		||||
pub fn get_manager() -> impl SystemManager {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,4 +29,10 @@ pub fn get_manager() -> impl SystemManager {
 | 
			
		|||
    let manager = windows::WindowsSystemManager{};
 | 
			
		||||
    manager.initialize();
 | 
			
		||||
    manager
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MAC IMPLEMENTATION
 | 
			
		||||
#[cfg(target_os = "macos")]
 | 
			
		||||
pub fn get_manager() -> impl SystemManager {
 | 
			
		||||
    macos::MacSystemManager::new()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,10 +6,6 @@ pub struct WindowsSystemManager {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl super::SystemManager for WindowsSystemManager {
 | 
			
		||||
    fn initialize(&self) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_current_window_title(&self) -> Option<String> {
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let mut buffer : [u16; 100] = [0; 100];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,35 +1,93 @@
 | 
			
		|||
use std::fs::create_dir_all;
 | 
			
		||||
use std::{fs, io};
 | 
			
		||||
use std::io::{BufReader, Cursor};
 | 
			
		||||
use zip::ZipArchive;
 | 
			
		||||
use log::{info, debug, error};
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
 | 
			
		||||
const NOTIFY_HELPER_BINARY : &'static [u8] = include_bytes!("res/mac/EspansoNotifyHelper.zip");
 | 
			
		||||
const NOTIFY_HELPER_BINARY : &'static [u8] = include_bytes!("../res/mac/EspansoNotifyHelper.zip");
 | 
			
		||||
const DEFAULT_NOTIFICATION_DELAY : f64 = 1.5;
 | 
			
		||||
 | 
			
		||||
pub struct MacUIManager {
 | 
			
		||||
 | 
			
		||||
    notify_helper_path: PathBuf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl super::UIManager for MacUIManager {
 | 
			
		||||
    fn initialize(&self) {
 | 
			
		||||
        self.initialize_notify_helper();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn notify(&self, message: &str) {
 | 
			
		||||
        unimplemented!()
 | 
			
		||||
        let executable_path = self.notify_helper_path.join("Contents");
 | 
			
		||||
        let executable_path = executable_path.join("MacOS");
 | 
			
		||||
        let executable_path = executable_path.join("EspansoNotifyHelper");
 | 
			
		||||
 | 
			
		||||
        let res = Command::new(executable_path)
 | 
			
		||||
            .args(&["espanso", message, &DEFAULT_NOTIFICATION_DELAY.to_string()])
 | 
			
		||||
            .spawn();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl MacUIManager {
 | 
			
		||||
    fn initialize_notify_helper(&self) {
 | 
			
		||||
        let res = dirs::data_dir();
 | 
			
		||||
        if let Some(data_dir) = res {
 | 
			
		||||
            let espanso_dir = data_dir.join("espanso");
 | 
			
		||||
    pub fn new() -> MacUIManager {
 | 
			
		||||
        let notify_helper_path = MacUIManager::initialize_notify_helper();
 | 
			
		||||
 | 
			
		||||
            let res = create_dir_all(espanso_dir);
 | 
			
		||||
        MacUIManager{
 | 
			
		||||
            notify_helper_path
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn initialize_notify_helper() -> PathBuf {
 | 
			
		||||
        let data_dir = dirs::data_dir().expect("Can't obtain data_dir(), terminating.");
 | 
			
		||||
 | 
			
		||||
        let espanso_dir = data_dir.join("espanso");
 | 
			
		||||
 | 
			
		||||
        let res = create_dir_all(&espanso_dir);
 | 
			
		||||
 | 
			
		||||
        info!("Initializing EspansoNotifyHelper in {}", espanso_dir.as_path().display());
 | 
			
		||||
 | 
			
		||||
        let espanso_target = espanso_dir.join("EspansoNotifyHelper.app");
 | 
			
		||||
 | 
			
		||||
        if espanso_target.exists() {
 | 
			
		||||
            info!("EspansoNotifyHelper already initialized, skipping.");
 | 
			
		||||
        }else{
 | 
			
		||||
            if let Ok(_) = res {
 | 
			
		||||
                // TODO: extract zip file
 | 
			
		||||
                // Extract zip file
 | 
			
		||||
                let reader = Cursor::new(NOTIFY_HELPER_BINARY);
 | 
			
		||||
 | 
			
		||||
                let mut archive = zip::ZipArchive::new(reader).unwrap();
 | 
			
		||||
 | 
			
		||||
                for i in 0..archive.len() {
 | 
			
		||||
                    let mut file = archive.by_index(i).unwrap();
 | 
			
		||||
                    let outpath = espanso_dir.join(file.sanitized_name());
 | 
			
		||||
 | 
			
		||||
                    {
 | 
			
		||||
                        let comment = file.comment();
 | 
			
		||||
                        if !comment.is_empty() {
 | 
			
		||||
                            debug!("File {} comment: {}", i, comment);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (&*file.name()).ends_with('/') {
 | 
			
		||||
                        debug!("File {} extracted to \"{}\"", i, outpath.as_path().display());
 | 
			
		||||
                        fs::create_dir_all(&outpath).unwrap();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        debug!("File {} extracted to \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size());
 | 
			
		||||
                        if let Some(p) = outpath.parent() {
 | 
			
		||||
                            if !p.exists() {
 | 
			
		||||
                                fs::create_dir_all(&p).unwrap();
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        let mut outfile = fs::File::create(&outpath).unwrap();
 | 
			
		||||
                        io::copy(&mut file, &mut outfile).unwrap();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    use std::os::unix::fs::PermissionsExt;
 | 
			
		||||
 | 
			
		||||
                    if let Some(mode) = file.unix_mode() {
 | 
			
		||||
                        fs::set_permissions(&outpath, fs::Permissions::from_mode(mode)).unwrap();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO: print error message
 | 
			
		||||
        espanso_target
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -14,9 +14,7 @@ pub trait UIManager {
 | 
			
		|||
// MAC IMPLEMENTATION
 | 
			
		||||
#[cfg(target_os = "macos")]
 | 
			
		||||
pub fn get_uimanager() -> impl UIManager {
 | 
			
		||||
    let manager = macos::MacUIManager{};
 | 
			
		||||
    manager.initialize();
 | 
			
		||||
    manager
 | 
			
		||||
    macos::MacUIManager::new()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LINUX IMPLEMENTATION
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user