Some more fixes for the 1.4.10 client
This commit is contained in:
parent
02d683954b
commit
3611718bc7
@ -12,6 +12,7 @@ export async function close() {
|
||||
break;
|
||||
} catch(error) {} /* error will be already logged */
|
||||
}
|
||||
|
||||
if(global_window) {
|
||||
global_window.close();
|
||||
global_window = undefined;
|
||||
|
@ -1,15 +1,14 @@
|
||||
/* --------------- bootstrap --------------- */
|
||||
import * as RequireProxy from "../renderer/RequireProxy";
|
||||
import * as path from "path";
|
||||
|
||||
RequireProxy.initialize(path.join(__dirname, "backend-impl"));
|
||||
|
||||
/* --------------- entry point --------------- */
|
||||
import * as loader from "tc-loader";
|
||||
import {Stage} from "tc-loader";
|
||||
import {Arguments, process_args} from "../shared/process-arguments";
|
||||
import {remote} from "electron";
|
||||
|
||||
RequireProxy.initialize(path.join(__dirname, "backend-impl"));
|
||||
|
||||
export function initialize(manifestTarget: string) {
|
||||
console.log("Initializing native client for manifest target %s", manifestTarget);
|
||||
|
||||
@ -42,12 +41,10 @@ export function initialize(manifestTarget: string) {
|
||||
loader.register_task(loader.Stage.JAVASCRIPT, {
|
||||
name: "teaclient jquery",
|
||||
function: async () => {
|
||||
//const jquery = require("jquery");
|
||||
//console.error(jquery);
|
||||
//window.$ = jquery;
|
||||
window.$ = require("jquery");
|
||||
|
||||
//window.jQuery = window.$;
|
||||
//Object.assign(window.$, window.jsrender = require('jsrender'));
|
||||
window.jQuery = window.$;
|
||||
Object.assign(window.$, window.jsrender = require('jsrender'));
|
||||
},
|
||||
priority: 80
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ set(MODULE_NAME "teaclient_ppt")
|
||||
|
||||
set(SOURCE_FILES src/KeyboardHook.cpp)
|
||||
if (MSVC)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} src/Win32KeyboardHook.cpp src/Win32KeyboardHookLL.cpp src/Win32KeyboardRawInput.cpp)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} src/Win32KeyboardHook.cpp src/Win32KeyboardRawInput.cpp)
|
||||
else()
|
||||
set(SOURCE_FILES ${SOURCE_FILES} src/X11KeyboardHook.cpp)
|
||||
endif()
|
||||
|
@ -13,8 +13,7 @@ using namespace std;
|
||||
#include "src/Win32KeyboardHook.h"
|
||||
#else
|
||||
#include "src/KeyboardHook.h"
|
||||
#include "src/X11KeyboardHook.h"
|
||||
|
||||
#include "src/X11KeyboardHook.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -6,16 +6,10 @@
|
||||
|
||||
enum struct KeyboardHookType {
|
||||
X11,
|
||||
|
||||
RAW_INPUT,
|
||||
SYSTEM_HOOK
|
||||
RAW_INPUT
|
||||
};
|
||||
|
||||
class KeyboardHook {
|
||||
#ifdef HOOK_WIN32_LL
|
||||
friend LRESULT CALLBACK _keyboard_hook_callback(int, WPARAM, LPARAM);
|
||||
friend LRESULT CALLBACK _mouse_hook_callback(int, WPARAM, LPARAM);
|
||||
#endif
|
||||
public:
|
||||
typedef unsigned int KeyID;
|
||||
|
||||
|
@ -9,29 +9,6 @@ namespace hooks {
|
||||
extern std::string key_string_from_vk(DWORD code, bool extended);
|
||||
extern std::string key_string_from_sc(USHORT code);
|
||||
|
||||
class Win32SystemHook : public KeyboardHook {
|
||||
public:
|
||||
Win32SystemHook();
|
||||
|
||||
bool attach() override;
|
||||
void detach() override;
|
||||
|
||||
bool keytype_supported() const override { return true; }
|
||||
private:
|
||||
static LRESULT CALLBACK _keyboard_hook_callback(int, WPARAM, LPARAM);
|
||||
static LRESULT CALLBACK _mouse_hook_callback(int, WPARAM, LPARAM);
|
||||
|
||||
HHOOK keyboad_hook_id{nullptr};
|
||||
bool keyboard_hook_callback(int, WPARAM, LPARAM);
|
||||
|
||||
HHOOK mouse_hook_id{nullptr};
|
||||
bool mouse_hook_callback(int, WPARAM, LPARAM);
|
||||
|
||||
bool active{false};
|
||||
std::thread poll_thread;
|
||||
void poll_events();
|
||||
};
|
||||
|
||||
class Win32RawHook : public KeyboardHook {
|
||||
public:
|
||||
Win32RawHook();
|
||||
@ -39,12 +16,12 @@ namespace hooks {
|
||||
bool attach() override;
|
||||
void detach() override;
|
||||
|
||||
bool keytype_supported() const override { return true; }
|
||||
[[nodiscard]] bool keytype_supported() const override { return true; }
|
||||
private:
|
||||
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||
|
||||
std::thread wthread;
|
||||
void wloop();
|
||||
std::thread window_thread;
|
||||
void window_loop();
|
||||
|
||||
enum struct WorkerStatus {
|
||||
STOPPED,
|
||||
@ -63,6 +40,6 @@ namespace hooks {
|
||||
void set_wstatus(WorkerStatus);
|
||||
void handle_raw_input(RAWINPUT&);
|
||||
|
||||
HWND hwnd{0};
|
||||
HWND hwnd{nullptr};
|
||||
};
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include "./Win32KeyboardHook.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace hooks {
|
||||
void init_global_ed();
|
||||
void shutdown_global_ed();
|
||||
|
||||
typedef KBDLLHOOKSTRUCT KeyboardHookStruct;
|
||||
thread_local Win32SystemHook* thread_hook{nullptr};
|
||||
|
||||
Win32SystemHook::Win32SystemHook() : KeyboardHook{KeyboardHookType::SYSTEM_HOOK} {}
|
||||
|
||||
bool Win32SystemHook::attach() {
|
||||
if(!KeyboardHook::attach())
|
||||
return false;
|
||||
|
||||
init_global_ed();
|
||||
|
||||
this->active = true;
|
||||
this->poll_thread = std::thread(std::bind(&Win32SystemHook::poll_events, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win32SystemHook::detach() {
|
||||
this->active = false;
|
||||
{
|
||||
//TODO trigger no message!
|
||||
}
|
||||
if(this->poll_thread.joinable())
|
||||
this->poll_thread.join();
|
||||
|
||||
/* will flush all events */
|
||||
shutdown_global_ed();
|
||||
|
||||
KeyboardHook::detach();
|
||||
}
|
||||
|
||||
|
||||
LRESULT Win32SystemHook::_mouse_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) {
|
||||
assert(thread_hook);
|
||||
auto consume = thread_hook->mouse_hook_callback(nCode, event, ptr_keyboard);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
if(consume)
|
||||
return 1;
|
||||
return CallNextHookEx(nullptr, nCode, event, ptr_keyboard);
|
||||
}
|
||||
|
||||
LRESULT Win32SystemHook::_keyboard_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) {
|
||||
assert(thread_hook);
|
||||
auto consume = thread_hook->keyboard_hook_callback(nCode, event, ptr_keyboard);
|
||||
if(consume)
|
||||
return 1;
|
||||
return CallNextHookEx(nullptr, nCode, event, ptr_keyboard);
|
||||
}
|
||||
|
||||
void Win32SystemHook::poll_events() {
|
||||
thread_hook = this;
|
||||
|
||||
if(!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS))
|
||||
std::cerr << "Failed to set priority class to realtime!" << std::endl;
|
||||
|
||||
#if 0
|
||||
std::string msg_box{"Priority Class: "};
|
||||
msg_box += std::to_string((int) GetPriorityClass(GetCurrentProcess()));
|
||||
msg_box += " Priority: ";
|
||||
msg_box += std::to_string((int) GetThreadPriority(GetCurrentProcess()));
|
||||
MessageBox(nullptr, msg_box.c_str(), "PPT-Thread", MB_OK);
|
||||
#endif
|
||||
#if 0
|
||||
int cur_priority = GetThreadPriority(GetCurrentThread());
|
||||
DWORD cur_priority_class = GetPriorityClass(GetCurrentProcess());
|
||||
std::cout << "P: " << cur_priority << " C: " << cur_priority_class << std::endl;
|
||||
#endif
|
||||
|
||||
this->keyboad_hook_id = SetWindowsHookEx(WH_KEYBOARD_LL, &Win32SystemHook::_keyboard_hook_callback, GetModuleHandle(nullptr), 0);
|
||||
if(!this->keyboad_hook_id) {
|
||||
cerr << "Failed to register keyboard hook" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1
|
||||
this->mouse_hook_id = SetWindowsHookEx(WH_MOUSE_LL, &Win32SystemHook::_mouse_hook_callback, GetModuleHandle(nullptr), 0);
|
||||
if(!this->keyboad_hook_id) {
|
||||
UnhookWindowsHookEx(this->keyboad_hook_id);
|
||||
cerr << "Failed to register mouse hook" << endl;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
this->mouse_hook_id = 0;
|
||||
#endif
|
||||
|
||||
|
||||
MSG msg;
|
||||
while(!GetMessage(&msg, nullptr, 0, 0) && this->active) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
if(this->mouse_hook_id > 0)
|
||||
UnhookWindowsHookEx(this->mouse_hook_id);
|
||||
UnhookWindowsHookEx(this->keyboad_hook_id);
|
||||
thread_hook = nullptr;
|
||||
}
|
||||
|
||||
inline std::string key_code(KeyboardHookStruct* keyboard) {
|
||||
return key_string_from_vk(keyboard->vkCode, (keyboard->flags & LLKHF_EXTENDED) > 0);
|
||||
}
|
||||
|
||||
using KeyType = KeyboardHook::KeyType;
|
||||
|
||||
bool Win32SystemHook::keyboard_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) {
|
||||
auto keyboard = (KeyboardHookStruct*) ptr_keyboard;
|
||||
if(event == WM_KEYDOWN || event == WM_SYSKEYDOWN) {
|
||||
auto& state = this->map_key[keyboard->vkCode];
|
||||
bool typed = state;
|
||||
state = true;
|
||||
|
||||
auto type = key_type_from_vk(keyboard->vkCode);
|
||||
if(type != KeyType::KEY_NORMAL)
|
||||
this->map_special[type] = true;
|
||||
else
|
||||
this->map_special[type] = keyboard->vkCode;
|
||||
|
||||
if(!typed)
|
||||
this->trigger_key_event(KeyEvent::PRESS, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_string_from_vk(this->map_special[KeyType::KEY_NORMAL], false));
|
||||
this->trigger_key_event(KeyEvent::TYPE, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_string_from_vk(this->map_special[KeyType::KEY_NORMAL], false));
|
||||
} else if(event == WM_KEYUP || event == WM_SYSKEYUP) {
|
||||
auto& state = this->map_key[keyboard->vkCode];
|
||||
if(!state) return false; //Duplicate
|
||||
state = false;
|
||||
|
||||
auto type = key_type_from_vk(keyboard->vkCode);
|
||||
if(type != KeyType::KEY_NORMAL)
|
||||
this->map_special[type] = false;
|
||||
else if(this->map_special[KeyType::KEY_NORMAL] == keyboard->vkCode)
|
||||
this->map_special[KeyType::KEY_NORMAL] = 0;
|
||||
|
||||
this->trigger_key_event(KeyEvent::RELEASE, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_string_from_vk(this->map_special[KeyType::KEY_NORMAL], false));
|
||||
}
|
||||
|
||||
//Consume the event: return 1
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef MSLLHOOKSTRUCT MouseLLHookStruct;
|
||||
|
||||
struct MouseButtonEventEntry {
|
||||
MouseButtonEventEntry* next;
|
||||
KeyboardHook* hook;
|
||||
|
||||
enum KeyboardHook::KeyEvent::type type;
|
||||
std::string key;
|
||||
};
|
||||
|
||||
inline MouseButtonEventEntry* allocate_mb_event() {
|
||||
return new MouseButtonEventEntry{};
|
||||
}
|
||||
|
||||
inline void delete_mb_event(MouseButtonEventEntry* event) {
|
||||
delete event;
|
||||
}
|
||||
|
||||
struct MouseButtonEventDispatcher {
|
||||
bool active{true};
|
||||
|
||||
std::thread dispatcher{};
|
||||
|
||||
CRITICAL_SECTION mutex;
|
||||
CONDITION_VARIABLE cv_flushed;
|
||||
CONDITION_VARIABLE cv_work;
|
||||
|
||||
MouseButtonEventEntry* event_head{nullptr};
|
||||
MouseButtonEventEntry** event_tail{&event_head};
|
||||
};
|
||||
|
||||
MouseButtonEventDispatcher* global_event_dispatcher{};
|
||||
size_t global_ed_ref_count{0};
|
||||
|
||||
void init_global_ed() {
|
||||
if(global_event_dispatcher) {
|
||||
global_ed_ref_count++;
|
||||
return;
|
||||
}
|
||||
|
||||
global_event_dispatcher = new MouseButtonEventDispatcher{};
|
||||
InitializeCriticalSection(&global_event_dispatcher->mutex);
|
||||
InitializeConditionVariable(&global_event_dispatcher->cv_flushed);
|
||||
InitializeConditionVariable(&global_event_dispatcher->cv_work);
|
||||
|
||||
global_event_dispatcher->dispatcher = std::thread([]{
|
||||
auto ed = global_event_dispatcher;
|
||||
|
||||
while(ed->active) {
|
||||
MouseButtonEventEntry* entry{nullptr};
|
||||
{
|
||||
EnterCriticalSection(&ed->mutex);
|
||||
while(!global_event_dispatcher->event_head && ed->active) {
|
||||
WakeAllConditionVariable(&ed->cv_flushed);
|
||||
SleepConditionVariableCS(&ed->cv_work, &ed->mutex, INFINITE);
|
||||
}
|
||||
|
||||
entry = global_event_dispatcher->event_head;
|
||||
global_event_dispatcher->event_head = nullptr;
|
||||
global_event_dispatcher->event_tail = &global_event_dispatcher->event_head;
|
||||
LeaveCriticalSection(&ed->mutex);
|
||||
}
|
||||
|
||||
while(entry) {
|
||||
entry->hook->trigger_key_event(entry->type, std::string{entry->key});
|
||||
|
||||
auto next = entry->next;
|
||||
delete_mb_event(entry);
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void shutdown_global_ed() {
|
||||
/* flush all events */
|
||||
EnterCriticalSection(&global_event_dispatcher->mutex);
|
||||
WakeAllConditionVariable(&global_event_dispatcher->cv_work);
|
||||
SleepConditionVariableCS(&global_event_dispatcher->cv_flushed, &global_event_dispatcher->mutex, INFINITE);
|
||||
LeaveCriticalSection(&global_event_dispatcher->mutex);
|
||||
|
||||
if(--global_ed_ref_count > 0) return;
|
||||
|
||||
auto ed = std::exchange(global_event_dispatcher, nullptr);
|
||||
ed->active = false;
|
||||
WakeAllConditionVariable(&ed->cv_work);
|
||||
|
||||
if(ed->dispatcher.joinable())
|
||||
ed->dispatcher.join();
|
||||
|
||||
DeleteCriticalSection(&ed->mutex);
|
||||
delete ed;
|
||||
}
|
||||
|
||||
bool Win32SystemHook::mouse_hook_callback(int nCode, WPARAM event, LPARAM ptr_mouse) {
|
||||
MouseButtonEventEntry* mb_event;
|
||||
switch (event) {
|
||||
case WM_LBUTTONDOWN:
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::PRESS;
|
||||
mb_event->key = "MOUSE1";
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::RELEASE;
|
||||
mb_event->key = "MOUSE1";
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::PRESS;
|
||||
mb_event->key = "MOUSE3";
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::RELEASE;
|
||||
mb_event->key = "MOUSE3";
|
||||
break;
|
||||
|
||||
case WM_XBUTTONDOWN: {
|
||||
auto mouse = (MouseLLHookStruct*) ptr_mouse;
|
||||
auto x_index = GET_XBUTTON_WPARAM(mouse->mouseData);
|
||||
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::PRESS;
|
||||
mb_event->key = "MOUSEX" + std::to_string(x_index);
|
||||
break;
|
||||
}
|
||||
case WM_XBUTTONUP: {
|
||||
auto mouse = (MouseLLHookStruct*) ptr_mouse;
|
||||
auto x_index = GET_XBUTTON_WPARAM(mouse->mouseData);
|
||||
|
||||
mb_event = allocate_mb_event();
|
||||
mb_event->type = KeyEvent::RELEASE;
|
||||
mb_event->key = "MOUSEX" + std::to_string(x_index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
mb_event->next = nullptr;
|
||||
mb_event->hook = thread_hook;
|
||||
|
||||
EnterCriticalSection(&global_event_dispatcher->mutex);
|
||||
*global_event_dispatcher->event_tail = mb_event;
|
||||
global_event_dispatcher->event_tail = &mb_event->next;
|
||||
WakeAllConditionVariable(&global_event_dispatcher->cv_work);
|
||||
LeaveCriticalSection(&global_event_dispatcher->mutex);
|
||||
return false;
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace hooks {
|
||||
|
||||
this->wactive = true;
|
||||
this->set_wstatus(WorkerStatus::INITIALIZING);
|
||||
this->wthread = std::thread(std::bind(&Win32RawHook::wloop, this));
|
||||
this->window_thread = std::thread([this] { this->window_loop(); });
|
||||
|
||||
std::unique_lock ws_lock{this->wstatus_mutex};
|
||||
this->wstatus_changed_cv.wait(ws_lock, [&]{
|
||||
@ -27,12 +27,14 @@ namespace hooks {
|
||||
|
||||
void Win32RawHook::detach() {
|
||||
this->wactive = false;
|
||||
{
|
||||
//TODO trigger no message!
|
||||
|
||||
if(this->hwnd) {
|
||||
PostMessage(this->hwnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
if(this->wthread.joinable())
|
||||
this->wthread.join();
|
||||
if(this->window_thread.joinable())
|
||||
this->window_thread.join();
|
||||
|
||||
this->set_wstatus(WorkerStatus::STOPPED);
|
||||
|
||||
KeyboardHook::detach();
|
||||
@ -46,7 +48,7 @@ namespace hooks {
|
||||
}
|
||||
|
||||
#define WORKER_CLASS_NAME ("TeaClient - KeyHook worker")
|
||||
void Win32RawHook::wloop() {
|
||||
void Win32RawHook::window_loop() {
|
||||
this->set_wstatus(WorkerStatus::INITIALIZING);
|
||||
|
||||
/* setup */
|
||||
@ -55,12 +57,12 @@ namespace hooks {
|
||||
WNDCLASS wc = {0};
|
||||
wc.lpfnWndProc = window_proc;
|
||||
wc.cbWndExtra = sizeof(void*);
|
||||
wc.hInstance = 0;
|
||||
wc.hInstance = nullptr;
|
||||
wc.lpszClassName = WORKER_CLASS_NAME;
|
||||
RegisterClass(&wc);
|
||||
}
|
||||
|
||||
this->hwnd = CreateWindow(WORKER_CLASS_NAME, "TeaClient - KeyHook worker window", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, this);
|
||||
this->hwnd = CreateWindow(WORKER_CLASS_NAME, "TeaClient - KeyHook worker window", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, this);
|
||||
if(!this->hwnd) {
|
||||
this->worker_died_reason = "Failed to create window";
|
||||
this->set_wstatus(WorkerStatus::DIED);
|
||||
@ -70,12 +72,12 @@ namespace hooks {
|
||||
RAWINPUTDEVICE devices[2];
|
||||
devices[0].usUsagePage = 0x01; //HID_USAGE_PAGE_GENERIC;
|
||||
devices[0].usUsage = 0x02; //HID_USAGE_GENERIC_MOUSE;
|
||||
devices[0].dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
|
||||
devices[0].dwFlags = (uint32_t) RIDEV_NOLEGACY | (uint32_t) RIDEV_INPUTSINK;
|
||||
devices[0].hwndTarget = hwnd;
|
||||
|
||||
devices[1].usUsagePage = 0x01; //HID_USAGE_PAGE_GENERIC;
|
||||
devices[1].usUsage = 0x06; //HID_USAGE_GENERIC_KEYBOARD;
|
||||
devices[1].dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
|
||||
devices[1].dwFlags = (uint32_t) RIDEV_NOLEGACY | (uint32_t) RIDEV_INPUTSINK;
|
||||
devices[1].hwndTarget = hwnd;
|
||||
|
||||
if(!RegisterRawInputDevices(devices, 2, sizeof *devices)) {
|
||||
@ -86,18 +88,19 @@ namespace hooks {
|
||||
}
|
||||
|
||||
this->set_wstatus(WorkerStatus::RUNNING);
|
||||
|
||||
BOOL ret;
|
||||
MSG msg;
|
||||
while (this->wactive) {
|
||||
ret = GetMessage(&msg, this->hwnd, 0, 0);
|
||||
if(ret == 0)
|
||||
break;
|
||||
|
||||
if (ret == -1) {
|
||||
this->worker_died_reason = "GetMessage() threw an error";
|
||||
this->set_wstatus(WorkerStatus::DIED);
|
||||
goto cleanup;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
@ -105,10 +108,8 @@ namespace hooks {
|
||||
this->set_wstatus(WorkerStatus::STOPPED);
|
||||
|
||||
cleanup:
|
||||
if(this->hwnd > 0) {
|
||||
DestroyWindow(this->hwnd);
|
||||
this->hwnd = 0;
|
||||
}
|
||||
if(auto window{std::exchange(this->hwnd, nullptr)}; window)
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
LRESULT Win32RawHook::window_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
|
||||
@ -116,18 +117,17 @@ namespace hooks {
|
||||
|
||||
switch (msg) {
|
||||
case WM_CREATE: {
|
||||
CREATESTRUCT *s = reinterpret_cast<CREATESTRUCT *>(lp);
|
||||
auto s = reinterpret_cast<CREATESTRUCT *>(lp);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) s->lpCreateParams);
|
||||
return 0;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
PostQuitMessage(0);
|
||||
/* nothing to do here, the window will be cleaned up by the event dispatchers */
|
||||
return 0;
|
||||
|
||||
case WM_INPUT: {
|
||||
UINT target_size{0};
|
||||
GetRawInputData((HRAWINPUT) lp, RID_INPUT, NULL, &target_size, sizeof(RAWINPUTHEADER));
|
||||
GetRawInputData((HRAWINPUT) lp, RID_INPUT, nullptr, &target_size, sizeof(RAWINPUTHEADER));
|
||||
if(target_size > sizeof(RAWINPUT)) {
|
||||
std::cerr << "Failed to retrieve input (Target size is longer than expected)" << std::endl;
|
||||
return 0;
|
||||
|
190
package-lock.json
generated
190
package-lock.json
generated
@ -172,6 +172,11 @@
|
||||
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/color-name": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
|
||||
},
|
||||
"@types/ejs": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-2.7.0.tgz",
|
||||
@ -523,6 +528,11 @@
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
|
||||
"dev": true
|
||||
},
|
||||
"astral-regex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
|
||||
},
|
||||
"async-each": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
|
||||
@ -1102,6 +1112,50 @@
|
||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz",
|
||||
"integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w=="
|
||||
},
|
||||
"cli-truncate": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
|
||||
"integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
|
||||
"requires": {
|
||||
"slice-ansi": "^3.0.0",
|
||||
"string-width": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
|
||||
@ -1679,6 +1733,26 @@
|
||||
"extract-zip": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"electron-context-menu": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-2.3.0.tgz",
|
||||
"integrity": "sha512-XYsYkNY+jvX4C5o09qMuZoKL6e9frnQzBFehZSIiKp6zK0u3XYowJYDyK3vDKKZxYsOIGiE/Gbx40jERC03Ctw==",
|
||||
"requires": {
|
||||
"cli-truncate": "^2.0.0",
|
||||
"electron-dl": "^3.0.0",
|
||||
"electron-is-dev": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"electron-dl": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.0.2.tgz",
|
||||
"integrity": "sha512-pRgE9Jbhoo5z6Vk3qi+vIrfpMDlCp2oB1UeR96SMnsfz073jj0AZGQwp69EdIcEvlUlwBSGyJK8Jt6OB6JLn+g==",
|
||||
"requires": {
|
||||
"ext-name": "^5.0.0",
|
||||
"pupa": "^2.0.1",
|
||||
"unused-filename": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"electron-fetch": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.5.0.tgz",
|
||||
@ -1770,6 +1844,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"electron-is-dev": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz",
|
||||
"integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw=="
|
||||
},
|
||||
"electron-osx-sign": {
|
||||
"version": "0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.15.tgz",
|
||||
@ -2318,6 +2397,11 @@
|
||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||
"optional": true
|
||||
},
|
||||
"escape-goat": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
|
||||
"integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
@ -2397,6 +2481,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ext-list": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
|
||||
"integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
|
||||
"requires": {
|
||||
"mime-db": "^1.28.0"
|
||||
}
|
||||
},
|
||||
"ext-name": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
|
||||
"integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
|
||||
"requires": {
|
||||
"ext-list": "^2.0.0",
|
||||
"sort-keys-length": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
@ -3901,6 +4002,11 @@
|
||||
"path-is-inside": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"is-plain-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
@ -4518,6 +4624,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"modify-filename": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz",
|
||||
"integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
|
||||
@ -5313,6 +5424,14 @@
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"pupa": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz",
|
||||
"integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==",
|
||||
"requires": {
|
||||
"escape-goat": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pure-uuid": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pure-uuid/-/pure-uuid-1.6.0.tgz",
|
||||
@ -5842,6 +5961,45 @@
|
||||
"string-width": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
|
||||
"integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"astral-regex": "^2.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
@ -5970,6 +6128,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"sort-keys": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
|
||||
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
|
||||
"requires": {
|
||||
"is-plain-obj": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"sort-keys-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
|
||||
"integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
|
||||
"requires": {
|
||||
"sort-keys": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.1.32",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz",
|
||||
@ -6668,6 +6842,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"unused-filename": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz",
|
||||
"integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==",
|
||||
"requires": {
|
||||
"modify-filename": "^1.1.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"unzip-response": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
|
||||
|
@ -58,6 +58,7 @@
|
||||
"aws4": "^1.10.0",
|
||||
"color.js": "^0.1.3",
|
||||
"electron": "8.0.0",
|
||||
"electron-context-menu": "^2.3.0",
|
||||
"electron-installer-windows": "^1.1.0",
|
||||
"electron-rebuild": "^1.11.0",
|
||||
"electron-wix-msi": "^2.1.1",
|
||||
|
Loading…
Reference in New Issue
Block a user