mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
FancyZones and Shortcut Guide initial commit
Co-authored-by: Alexis Campailla <alexis@janeasystems.com> Co-authored-by: Bret Anderson <bretan@microsoft.com> Co-authored-by: Enrico Giordani <enrico.giordani@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> Co-authored-by: Jeff Bogdan <jeffbog@microsoft.com> Co-authored-by: March Rogers <marchr@microsoft.com> Co-authored-by: Mike Harsh <mharsh@microsoft.com> Co-authored-by: Nachum Bundak <Nachum.Bundak@microsoft.com> Co-authored-by: Oliver Jones <ojones@microsoft.com> Co-authored-by: Patrick Little <plittle@microsoft.com>
This commit is contained in:
committed by
Bartosz Sosnowski
parent
10c5396099
commit
8431b80e48
147
src/modules/shortcut_guide/target_state.cpp
Normal file
147
src/modules/shortcut_guide/target_state.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "pch.h"
|
||||
#include "target_state.h"
|
||||
#include "common/start_visible.h"
|
||||
#include "keyboard_state.h"
|
||||
|
||||
TargetState::TargetState(int ms_delay) : delay(std::chrono::milliseconds(ms_delay)), thread(&TargetState::thread_proc, this)
|
||||
{ }
|
||||
|
||||
bool TargetState::signal_event(unsigned vk_code, bool key_down) {
|
||||
std::unique_lock lock(mutex);
|
||||
if (!events.empty() && events.back().key_down == key_down && events.back().vk_code == vk_code) {
|
||||
return false;
|
||||
}
|
||||
bool supress = false;
|
||||
if (!key_down && (vk_code == VK_LWIN || vk_code == VK_RWIN) &&
|
||||
state == Shown &&
|
||||
std::chrono::system_clock::now() - singnal_timestamp > std::chrono::seconds(1) &&
|
||||
!key_was_pressed) {
|
||||
supress = true;
|
||||
}
|
||||
events.push_back({ key_down, vk_code });
|
||||
lock.unlock();
|
||||
cv.notify_one();
|
||||
if (supress) {
|
||||
INPUT input[3] = { {},{},{} };
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_LWIN;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
SendInput(3, input, sizeof(INPUT));
|
||||
}
|
||||
return supress;
|
||||
}
|
||||
|
||||
void TargetState::was_hiden() {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
state = Hidden;
|
||||
events.clear();
|
||||
lock.unlock();
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
void TargetState::exit() {
|
||||
std::unique_lock lock(mutex);
|
||||
events.clear();
|
||||
state = Exiting;
|
||||
lock.unlock();
|
||||
cv.notify_one();
|
||||
thread.join();
|
||||
}
|
||||
|
||||
KeyEvent TargetState::next() {
|
||||
auto e = events.front();
|
||||
events.pop_front();
|
||||
return e;
|
||||
}
|
||||
|
||||
void TargetState::handle_hidden() {
|
||||
std::unique_lock lock(mutex);
|
||||
if (events.empty())
|
||||
cv.wait(lock);
|
||||
if (events.empty() || state == Exiting)
|
||||
return;
|
||||
auto event = next();
|
||||
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN)) {
|
||||
state = Timeout;
|
||||
winkey_timestamp = std::chrono::system_clock::now();
|
||||
}
|
||||
}
|
||||
|
||||
void TargetState::handle_shown() {
|
||||
std::unique_lock lock(mutex);
|
||||
if (events.empty()) {
|
||||
cv.wait(lock);
|
||||
}
|
||||
if (events.empty() || state == Exiting) {
|
||||
return;
|
||||
}
|
||||
auto event = next();
|
||||
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN)) {
|
||||
return;
|
||||
}
|
||||
if (!event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN) || !winkey_held()) {
|
||||
state = Hidden;
|
||||
lock.unlock();
|
||||
return;
|
||||
}
|
||||
if (event.key_down) {
|
||||
key_was_pressed = true;
|
||||
lock.unlock();
|
||||
instance->on_held_press(event.vk_code);
|
||||
}
|
||||
}
|
||||
|
||||
void TargetState::thread_proc() {
|
||||
while (true) {
|
||||
switch (state) {
|
||||
case Hidden:
|
||||
handle_hidden();
|
||||
break;
|
||||
case Timeout:
|
||||
handle_timeout();
|
||||
break;
|
||||
case Shown:
|
||||
handle_shown();
|
||||
break;
|
||||
case Exiting:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TargetState::handle_timeout() {
|
||||
std::unique_lock lock(mutex);
|
||||
auto wait_time = delay - (std::chrono::system_clock::now() - winkey_timestamp);
|
||||
if (events.empty())
|
||||
cv.wait_for(lock, delay);
|
||||
if (state == Exiting)
|
||||
return;
|
||||
while (!events.empty()) {
|
||||
auto event = events.front();
|
||||
if (event.key_down && (event.vk_code == VK_LWIN || event.vk_code == VK_RWIN))
|
||||
events.pop_front();
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!events.empty() || !only_winkey_key_held() || is_start_visible()) {
|
||||
state = Hidden;
|
||||
return;
|
||||
}
|
||||
if (std::chrono::system_clock::now() - winkey_timestamp < delay)
|
||||
return;
|
||||
singnal_timestamp = std::chrono::system_clock::now();
|
||||
key_was_pressed = false;
|
||||
state = Shown;
|
||||
lock.unlock();
|
||||
instance->on_held();
|
||||
}
|
||||
|
||||
void TargetState::set_delay(int ms_delay) {
|
||||
delay = std::chrono::milliseconds(ms_delay);
|
||||
}
|
||||
Reference in New Issue
Block a user