First implementation of espanso-inject on macOS
This commit is contained in:
		
							parent
							
								
									e3e1ad720f
								
							
						
					
					
						commit
						e0bf94013d
					
				| 
						 | 
				
			
			@ -42,6 +42,8 @@ pub trait Injector {
 | 
			
		|||
  fn send_key_combination(&self, keys: &[keys::Key], delay: i32) -> Result<()>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[allow(dead_code)]
 | 
			
		||||
pub struct InjectorOptions {
 | 
			
		||||
  // Only relevant in Linux systems
 | 
			
		||||
  use_evdev: bool,
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +64,7 @@ pub fn get_injector(_options: InjectorOptions) -> impl Injector {
 | 
			
		|||
 | 
			
		||||
#[cfg(target_os = "macos")]
 | 
			
		||||
pub fn get_injector(_options: InjectorOptions) -> impl Injector {
 | 
			
		||||
  // TODO
 | 
			
		||||
  mac::MacInjector::new()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(target_os = "linux")]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										109
									
								
								espanso-inject/src/mac/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								espanso-inject/src/mac/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,109 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
mod raw_keys;
 | 
			
		||||
 | 
			
		||||
use std::{ffi::CString, os::raw::c_char};
 | 
			
		||||
 | 
			
		||||
use log::error;
 | 
			
		||||
use raw_keys::convert_key_to_vkey;
 | 
			
		||||
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
use crate::{keys, Injector};
 | 
			
		||||
 | 
			
		||||
#[allow(improper_ctypes)]
 | 
			
		||||
#[link(name = "espansoinject", kind = "static")]
 | 
			
		||||
extern "C" {
 | 
			
		||||
  pub fn inject_string(string: *const c_char);
 | 
			
		||||
  pub fn inject_separate_vkeys(vkey_array: *const i32, vkey_count: i32, delay: i32);
 | 
			
		||||
  pub fn inject_vkeys_combination(vkey_array: *const i32, vkey_count: i32, delay: i32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct MacInjector {}
 | 
			
		||||
 | 
			
		||||
#[allow(clippy::new_without_default)]
 | 
			
		||||
impl MacInjector {
 | 
			
		||||
  pub fn new() -> Self {
 | 
			
		||||
    Self {}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pub fn convert_to_vk_array(keys: &[keys::Key]) -> Result<Vec<i32>> {
 | 
			
		||||
    let mut virtual_keys: Vec<i32> = Vec::new();
 | 
			
		||||
    for key in keys.iter() {
 | 
			
		||||
      let vk = convert_key_to_vkey(key);
 | 
			
		||||
      if let Some(vk) = vk {
 | 
			
		||||
        virtual_keys.push(vk)
 | 
			
		||||
      } else {
 | 
			
		||||
        return Err(MacInjectorError::MappingFailure(key.clone()).into());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    Ok(virtual_keys)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Injector for MacInjector {
 | 
			
		||||
  fn send_string(&self, string: &str) -> Result<()> {
 | 
			
		||||
    let c_string = CString::new(string)?;
 | 
			
		||||
    unsafe {
 | 
			
		||||
      inject_string(c_string.as_ptr());
 | 
			
		||||
    }
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fn send_keys(&self, keys: &[keys::Key], delay: i32) -> Result<()> {
 | 
			
		||||
    let virtual_keys = Self::convert_to_vk_array(keys)?;
 | 
			
		||||
 | 
			
		||||
    unsafe {
 | 
			
		||||
      inject_separate_vkeys(virtual_keys.as_ptr(), virtual_keys.len() as i32, delay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fn send_key_combination(&self, keys: &[keys::Key], delay: i32) -> Result<()> {
 | 
			
		||||
    let virtual_keys = Self::convert_to_vk_array(keys)?;
 | 
			
		||||
 | 
			
		||||
    unsafe {
 | 
			
		||||
      inject_vkeys_combination(virtual_keys.as_ptr(), virtual_keys.len() as i32, delay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Error, Debug)]
 | 
			
		||||
pub enum MacInjectorError {
 | 
			
		||||
  #[error("missing vkey mapping for key `{0}`")]
 | 
			
		||||
  MappingFailure(keys::Key),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
  use super::*;
 | 
			
		||||
 | 
			
		||||
  #[test]
 | 
			
		||||
  fn convert_raw_to_virtual_key_array() {
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
      MacInjector::convert_to_vk_array(&[keys::Key::Alt, keys::Key::V]).unwrap(),
 | 
			
		||||
      vec![0x3A, 0x09]
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								espanso-inject/src/mac/native.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								espanso-inject/src/mac/native.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ESPANSO_INJECT_H
 | 
			
		||||
#define ESPANSO_INJECT_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// Inject a complete string using the KEYEVENTF_UNICODE flag
 | 
			
		||||
extern "C" void inject_string(char * string);
 | 
			
		||||
 | 
			
		||||
// Send a sequence of vkey presses and releases
 | 
			
		||||
extern "C" void inject_separate_vkeys(int32_t *vkey_array, int32_t vkey_count, int32_t delay);
 | 
			
		||||
 | 
			
		||||
// Send a combination of vkeys, first pressing all the vkeys and then releasing
 | 
			
		||||
// This is needed for keyboard shortcuts, for example.
 | 
			
		||||
extern "C" void inject_vkeys_combination(int32_t *vkey_array, int32_t vkey_count, int32_t delay);
 | 
			
		||||
 | 
			
		||||
#endif //ESPANSO_INJECT_H
 | 
			
		||||
							
								
								
									
										142
									
								
								espanso-inject/src/mac/native.mm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								espanso-inject/src/mac/native.mm
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,142 @@
 | 
			
		|||
/*
 | 
			
		||||
 * This file is part of espanso.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019-2021 Federico Terzi
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * espanso is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with espanso.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "native.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
void inject_string(char *string)
 | 
			
		||||
{
 | 
			
		||||
  char * stringCopy = strdup(string);
 | 
			
		||||
  dispatch_async(dispatch_get_main_queue(), ^(void) {
 | 
			
		||||
    // Convert the c string to a UniChar array as required by the CGEventKeyboardSetUnicodeString method
 | 
			
		||||
    NSString *nsString = [NSString stringWithUTF8String:stringCopy];
 | 
			
		||||
    CFStringRef cfString = (__bridge CFStringRef) nsString;
 | 
			
		||||
    std::vector <UniChar> buffer(nsString.length);
 | 
			
		||||
    CFStringGetCharacters(cfString, CFRangeMake(0, nsString.length), buffer.data());
 | 
			
		||||
 | 
			
		||||
    free(stringCopy);
 | 
			
		||||
 | 
			
		||||
    // Send the event
 | 
			
		||||
 | 
			
		||||
    // Check if the shift key is down, and if so, release it
 | 
			
		||||
    // To see why: https://github.com/federico-terzi/espanso/issues/279
 | 
			
		||||
    if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, 0x38)) {
 | 
			
		||||
      CGEventRef e2 = CGEventCreateKeyboardEvent(NULL, 0x38, false);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, e2);
 | 
			
		||||
      CFRelease(e2);
 | 
			
		||||
 | 
			
		||||
      usleep(2000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Because of a bug ( or undocumented limit ) of the CGEventKeyboardSetUnicodeString method
 | 
			
		||||
    // the string gets truncated after 20 characters, so we need to send multiple events.
 | 
			
		||||
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    while (i < buffer.size()) {
 | 
			
		||||
      int chunk_size = 20;
 | 
			
		||||
      if ((i+chunk_size) >  buffer.size()) {
 | 
			
		||||
        chunk_size = buffer.size() - i;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      UniChar * offset_buffer = buffer.data() + i;
 | 
			
		||||
      CGEventRef e = CGEventCreateKeyboardEvent(NULL, 0x31, true);
 | 
			
		||||
      CGEventKeyboardSetUnicodeString(e, chunk_size, offset_buffer);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, e);
 | 
			
		||||
      CFRelease(e);
 | 
			
		||||
 | 
			
		||||
      usleep(2000);
 | 
			
		||||
 | 
			
		||||
      // Some applications require an explicit release of the space key
 | 
			
		||||
      // For more information: https://github.com/federico-terzi/espanso/issues/159
 | 
			
		||||
      CGEventRef e2 = CGEventCreateKeyboardEvent(NULL, 0x31, false);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, e2);
 | 
			
		||||
      CFRelease(e2);
 | 
			
		||||
 | 
			
		||||
      usleep(2000);
 | 
			
		||||
 | 
			
		||||
      i += chunk_size;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void inject_separate_vkeys(int32_t *_vkey_array, int32_t vkey_count, int32_t delay)
 | 
			
		||||
{
 | 
			
		||||
  long udelay = delay * 1000;
 | 
			
		||||
  
 | 
			
		||||
  // Create an heap allocated copy of the array, so that it doesn't get freed within the block
 | 
			
		||||
  int32_t *vkey_array = (int32_t*)malloc(sizeof(int32_t)*vkey_count);
 | 
			
		||||
  memcpy(vkey_array, _vkey_array, sizeof(int32_t)*vkey_count);
 | 
			
		||||
 | 
			
		||||
  dispatch_async(dispatch_get_main_queue(), ^(void) {
 | 
			
		||||
    for (int i = 0; i<vkey_count; i++) {
 | 
			
		||||
      CGEventRef keydown;
 | 
			
		||||
      keydown = CGEventCreateKeyboardEvent(NULL, vkey_array[i], true);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, keydown);
 | 
			
		||||
      CFRelease(keydown);
 | 
			
		||||
 | 
			
		||||
      usleep(udelay);
 | 
			
		||||
 | 
			
		||||
      CGEventRef keyup;
 | 
			
		||||
      keyup = CGEventCreateKeyboardEvent(NULL, vkey_array[i], false);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, keyup);
 | 
			
		||||
      CFRelease(keyup);
 | 
			
		||||
 | 
			
		||||
      usleep(udelay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(vkey_array);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void inject_vkeys_combination(int32_t *_vkey_array, int32_t vkey_count, int32_t delay)
 | 
			
		||||
{
 | 
			
		||||
  long udelay = delay * 1000;
 | 
			
		||||
  
 | 
			
		||||
  // Create an heap allocated copy of the array, so that it doesn't get freed within the block
 | 
			
		||||
  int32_t *vkey_array = (int32_t*)malloc(sizeof(int32_t)*vkey_count);
 | 
			
		||||
  memcpy(vkey_array, _vkey_array, sizeof(int32_t)*vkey_count);
 | 
			
		||||
 | 
			
		||||
  dispatch_async(dispatch_get_main_queue(), ^(void) {
 | 
			
		||||
    // First send the presses
 | 
			
		||||
    for (int i = 0; i < vkey_count; i++)
 | 
			
		||||
    {
 | 
			
		||||
      CGEventRef keydown;
 | 
			
		||||
      keydown = CGEventCreateKeyboardEvent(NULL, vkey_array[i], true);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, keydown);
 | 
			
		||||
      CFRelease(keydown);
 | 
			
		||||
 | 
			
		||||
      usleep(udelay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Then the releases
 | 
			
		||||
    for (int i = (vkey_count - 1); i >= 0; i--)
 | 
			
		||||
    {
 | 
			
		||||
      CGEventRef keyup;
 | 
			
		||||
      keyup = CGEventCreateKeyboardEvent(NULL, vkey_array[i], false);
 | 
			
		||||
      CGEventPost(kCGHIDEventTap, keyup);
 | 
			
		||||
      CFRelease(keyup);
 | 
			
		||||
 | 
			
		||||
      usleep(udelay);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    free(vkey_array);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								espanso-inject/src/mac/raw_keys.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								espanso-inject/src/mac/raw_keys.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
use crate::keys::Key;
 | 
			
		||||
 | 
			
		||||
pub fn convert_key_to_vkey(key: &Key) -> Option<i32> {
 | 
			
		||||
  match key {
 | 
			
		||||
    Key::Alt => Some(0x3A),
 | 
			
		||||
    Key::CapsLock => Some(0x39),
 | 
			
		||||
    Key::Control => Some(0x3B),
 | 
			
		||||
    Key::Meta => Some(0x37),
 | 
			
		||||
    Key::NumLock => None,
 | 
			
		||||
    Key::Shift => Some(0x38),
 | 
			
		||||
    Key::Enter => Some(0x24),
 | 
			
		||||
    Key::Tab => Some(0x30),
 | 
			
		||||
    Key::Space => Some(0x31),
 | 
			
		||||
    Key::ArrowDown => Some(0x7D),
 | 
			
		||||
    Key::ArrowLeft => Some(0x7B),
 | 
			
		||||
    Key::ArrowRight => Some(0x7C),
 | 
			
		||||
    Key::ArrowUp => Some(0x7E),
 | 
			
		||||
    Key::End => Some(0x77),
 | 
			
		||||
    Key::Home => Some(0x73),
 | 
			
		||||
    Key::PageDown => Some(0x79),
 | 
			
		||||
    Key::PageUp => Some(0x74),
 | 
			
		||||
    Key::Escape => Some(0x35),
 | 
			
		||||
    Key::Backspace => Some(0x33),
 | 
			
		||||
    Key::Insert => None,
 | 
			
		||||
    Key::Delete => Some(0x75),
 | 
			
		||||
    Key::F1 => Some(0x7A),
 | 
			
		||||
    Key::F2 => Some(0x78),
 | 
			
		||||
    Key::F3 => Some(0x63),
 | 
			
		||||
    Key::F4 => Some(0x76),
 | 
			
		||||
    Key::F5 => Some(0x60),
 | 
			
		||||
    Key::F6 => Some(0x61),
 | 
			
		||||
    Key::F7 => Some(0x62),
 | 
			
		||||
    Key::F8 => Some(0x64),
 | 
			
		||||
    Key::F9 => Some(0x65),
 | 
			
		||||
    Key::F10 => Some(0x6D),
 | 
			
		||||
    Key::F11 => Some(0x67),
 | 
			
		||||
    Key::F12 => Some(0x6F),
 | 
			
		||||
    Key::F13 => Some(0x69),
 | 
			
		||||
    Key::F14 => Some(0x6B),
 | 
			
		||||
    Key::F15 => Some(0x71),
 | 
			
		||||
    Key::F16 => Some(0x6A),
 | 
			
		||||
    Key::F17 => Some(0x40),
 | 
			
		||||
    Key::F18 => Some(0x4F),
 | 
			
		||||
    Key::F19 => Some(0x50),
 | 
			
		||||
    Key::F20 => Some(0x5A),
 | 
			
		||||
    Key::A => Some(0x00),
 | 
			
		||||
    Key::B => Some(0x0B),
 | 
			
		||||
    Key::C => Some(0x08),
 | 
			
		||||
    Key::D => Some(0x02),
 | 
			
		||||
    Key::E => Some(0x0E),
 | 
			
		||||
    Key::F => Some(0x03),
 | 
			
		||||
    Key::G => Some(0x05),
 | 
			
		||||
    Key::H => Some(0x04),
 | 
			
		||||
    Key::I => Some(0x22),
 | 
			
		||||
    Key::J => Some(0x26),
 | 
			
		||||
    Key::K => Some(0x28),
 | 
			
		||||
    Key::L => Some(0x25),
 | 
			
		||||
    Key::M => Some(0x2E),
 | 
			
		||||
    Key::N => Some(0x2D),
 | 
			
		||||
    Key::O => Some(0x1F),
 | 
			
		||||
    Key::P => Some(0x23),
 | 
			
		||||
    Key::Q => Some(0x0C),
 | 
			
		||||
    Key::R => Some(0x0F),
 | 
			
		||||
    Key::S => Some(0x01),
 | 
			
		||||
    Key::T => Some(0x11),
 | 
			
		||||
    Key::U => Some(0x20),
 | 
			
		||||
    Key::V => Some(0x09),
 | 
			
		||||
    Key::W => Some(0x0D),
 | 
			
		||||
    Key::X => Some(0x07),
 | 
			
		||||
    Key::Y => Some(0x10),
 | 
			
		||||
    Key::Z => Some(0x06),
 | 
			
		||||
    Key::N0 => Some(0x1D),
 | 
			
		||||
    Key::N1 => Some(0x12),
 | 
			
		||||
    Key::N2 => Some(0x13),
 | 
			
		||||
    Key::N3 => Some(0x14),
 | 
			
		||||
    Key::N4 => Some(0x15),
 | 
			
		||||
    Key::N5 => Some(0x17),
 | 
			
		||||
    Key::N6 => Some(0x16),
 | 
			
		||||
    Key::N7 => Some(0x1A),
 | 
			
		||||
    Key::N8 => Some(0x1C),
 | 
			
		||||
    Key::N9 => Some(0x19),
 | 
			
		||||
    Key::Numpad0 => Some(0x52),
 | 
			
		||||
    Key::Numpad1 => Some(0x53),
 | 
			
		||||
    Key::Numpad2 => Some(0x54),
 | 
			
		||||
    Key::Numpad3 => Some(0x55),
 | 
			
		||||
    Key::Numpad4 => Some(0x56),
 | 
			
		||||
    Key::Numpad5 => Some(0x57),
 | 
			
		||||
    Key::Numpad6 => Some(0x58),
 | 
			
		||||
    Key::Numpad7 => Some(0x59),
 | 
			
		||||
    Key::Numpad8 => Some(0x5B),
 | 
			
		||||
    Key::Numpad9 => Some(0x5C),
 | 
			
		||||
    Key::Raw(code) => Some(*code),
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
use espanso_detect::event::{InputEvent, Status};
 | 
			
		||||
use espanso_inject::{get_injector, Injector};
 | 
			
		||||
use espanso_inject::{get_injector, Injector, keys};
 | 
			
		||||
use espanso_ui::{event::UIEvent::*, icons::TrayIcon, menu::*};
 | 
			
		||||
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,23 +36,23 @@ fn main() {
 | 
			
		|||
    ),
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  let (remote, mut eventloop) = espanso_ui::win32::create(espanso_ui::win32::Win32UIOptions {
 | 
			
		||||
    show_icon: true,
 | 
			
		||||
    icon_paths: &icon_paths,
 | 
			
		||||
    notification_icon_path: r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreensmall.png"
 | 
			
		||||
      .to_string(),
 | 
			
		||||
  });
 | 
			
		||||
  // let (remote, mut eventloop) = espanso_ui::mac::create(MacUIOptions {
 | 
			
		||||
  // let (remote, mut eventloop) = espanso_ui::win32::create(espanso_ui::win32::Win32UIOptions {
 | 
			
		||||
  //   show_icon: true,
 | 
			
		||||
  //   icon_paths: &icon_paths,
 | 
			
		||||
  //   notification_icon_path: r"C:\Users\Freddy\Insync\Development\Espanso\Images\icongreensmall.png"
 | 
			
		||||
  //     .to_string(),
 | 
			
		||||
  // });
 | 
			
		||||
  let (remote, mut eventloop) = espanso_ui::mac::create(espanso_ui::mac::MacUIOptions {
 | 
			
		||||
    show_icon: true,
 | 
			
		||||
    icon_paths: &icon_paths,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  eventloop.initialize();
 | 
			
		||||
 | 
			
		||||
  let handle = std::thread::spawn(move || {
 | 
			
		||||
    let mut source = espanso_detect::win32::Win32Source::new();
 | 
			
		||||
    //let mut source = espanso_detect::win32::Win32Source::new();
 | 
			
		||||
    //let mut source = espanso_detect::x11::X11Source::new();
 | 
			
		||||
    //let mut source = espanso_detect::mac::CocoaSource::new();
 | 
			
		||||
    let mut source = espanso_detect::mac::CocoaSource::new();
 | 
			
		||||
    source.initialize();
 | 
			
		||||
    source.eventloop(Box::new(move |event: InputEvent| {
 | 
			
		||||
      let injector = get_injector(Default::default());
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +64,7 @@ fn main() {
 | 
			
		|||
            //remote.update_tray_icon(espanso_ui::icons::TrayIcon::Disabled);
 | 
			
		||||
            //remote.show_notification("Espanso is running!");
 | 
			
		||||
            injector.send_string("hey guys");
 | 
			
		||||
            //injector.send_key_combination(&[keys::Key::Meta, keys::Key::V], 2);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user