bool InputProvider.IInputReceiver.OnKeyPressed(Key key, KeyState key_state, bool is_modifier) { lock (Helpers.locker) { // If you hold a key pressed for a second it will start to produce a sequence of rrrrrrrrrrepeated |KeyState.Down| events. // For some keys we don't want to handle such events and assume that a key stays pressed until |KeyState.Up| appears. bool is_repetition = interaction_history[0].Key == key && interaction_history[0].State == key_state && key_state == KeyState.Down; if (!is_repetition) { interaction_history[2] = interaction_history[1]; interaction_history[1] = interaction_history[0]; interaction_history[0].Key = key; interaction_history[0].State = key_state; interaction_history[0].Time = DateTime.Now; } float speed_up = 1.0f; if (is_repetition) { speed_up = 2.0f; } else if (key_state == KeyState.Down && interaction_history[1].Key == key && interaction_history[2].Key == key) { if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.quadriple_speed_up_press_time_ms) { speed_up = 4.0f; } else if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.double_speedup_press_time_ms) { speed_up = 2.0f; } } bool is_short_modifier_press = key_state == KeyState.Up && interaction_history[1].Key == key && (DateTime.Now - interaction_history[1].Time).TotalMilliseconds < Options.Instance.modifier_short_press_duration_ms; return(eye_tracking_mouse.OnKeyPressed(key, key_state, speed_up, is_short_modifier_press, is_repetition, is_modifier, input_provider)); } }
bool InputProvider.IInputReceiver.OnKeyPressed(Key key, KeyState key_state, bool is_modifier) { lock (Helpers.locker) { // If you hold a key pressed for a second it will start to produce a sequence of rrrrrrrrrrepeated |KeyState.Down| events. // For some keys we don't want to handle such events and assume that a key stays pressed until |KeyState.Up| appears. bool is_repetition = interaction_history[0].Key == key && interaction_history[0].State == key_state && key_state == KeyState.Down; if (!is_repetition) { interaction_history[2] = interaction_history[1]; interaction_history[1] = interaction_history[0]; interaction_history[0].Key = key; interaction_history[0].State = key_state; interaction_history[0].Time = DateTime.Now; } float speed_up = 1.0f; if (is_repetition) { speed_up = 2.0f; } else if (key_state == KeyState.Down && interaction_history[1].Key == key && interaction_history[2].Key == key) { if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.quadriple_speed_up_press_time_ms) { speed_up = 4.0f; } else if ((DateTime.Now - interaction_history[2].Time).TotalMilliseconds < Options.Instance.double_speedup_press_time_ms) { speed_up = 2.0f; } } // Single and double modifier presses have different functions // Single press goes to OS (this allows using WINDOWS MENU) // Double press enables |always_on| mode. if (is_waiting_for_second_modifier_press) { is_waiting_for_second_modifier_press = false; if (key == Key.Modifier && key_state == KeyState.Down && (DateTime.Now - interaction_history[1].Time).TotalMilliseconds < 300) { always_on = true; eye_tracking_mouse.StartControlling(); return(true); } } // IF user pressed and released modifier key without pressing other buttons in between... if (key == Key.Modifier && key_state == KeyState.Up && interaction_history[1].Key == key && !always_on) { double press_duration_ms = (DateTime.Now - interaction_history[1].Time).TotalMilliseconds; // THEN it might be a beginning of a double press... if (press_duration_ms < 300) { is_waiting_for_second_modifier_press = true; } // OR it might be a single modifier press that should go to OS. if (press_duration_ms < Options.Instance.modifier_short_press_duration_ms && (DateTime.Now - always_on_disabled_time).TotalMilliseconds > 300) { is_waiting_for_second_modifier_press = true; App.Current.Dispatcher.InvokeAsync((async() => { await Task.Delay(300); lock (Helpers.locker) { if (!is_waiting_for_second_modifier_press) { return; } is_waiting_for_second_modifier_press = false; input_provider.SendModifierDown(); input_provider.SendModifierUp(); } })); } } if (always_on) { if (key == Key.Modifier && key_state == KeyState.Up) { return(true); } if (key == Key.Unbound || (key == Key.Modifier && key_state == KeyState.Down)) { always_on = false; always_on_disabled_time = DateTime.Now; eye_tracking_mouse.StopControlling(); } } return(eye_tracking_mouse.OnKeyPressed(key, key_state, speed_up, is_repetition, is_modifier, input_provider)); } }