Files
hrynco-kswitcher/src/app.h
T

110 lines
3.5 KiB
C++

#pragma once
#include "autocorrect.h"
#include "storage.h"
#include "update.h"
#include <atomic>
#include <condition_variable>
#include <deque>
#include <memory>
#include <shellapi.h>
#include <thread>
namespace ks
{
inline constexpr UINT TrayMessage = WM_APP + 1, ErrorMessage = WM_APP + 2, HistoryMessage = WM_APP + 3,
SnippetMessage = WM_APP + 4;
inline constexpr int Toggle = 1, Case = 2, Translit = 3, Undo = 4, ShowHistory = 5, AutoCorrect = 6,
Direct = 100;
inline constexpr UINT AutoCorrectMessage = WM_APP + 6;
inline constexpr UINT CaptureHotkeyMessage = WM_APP + 5;
struct LastTransform
{
HWND window{};
std::wstring original, result;
int layout = -1;
ULONGLONG at{};
uint64_t version{};
int sourceLayout = -1;
bool autoCorrected = false;
};
class App
{
public:
HWND window{}, historyWindow{}, settingsWindow{}, snippetsWindow{};
HINSTANCE instance{};
std::filesystem::path data;
std::vector<Layout> layouts;
Settings settings;
std::unique_ptr<History> history;
AutoCorrector autoCorrector;
std::atomic<bool> busy{false}, suspended{false};
std::atomic<DWORD> ownSequence{0};
std::atomic<uint64_t> inputVersion{0};
std::atomic<ULONGLONG> pauseUntil{0};
HWND pasteTarget{};
HWND hotkeyCapture{};
DWORD hotkeyCaptureProcess{};
HWND logWindow{};
std::mutex stateMutex;
Run run;
std::optional<LastTransform> last;
std::wstring registrationWarning;
bool smoke{};
int startCommand{};
std::wstring updateStartupEvent;
App(HINSTANCE, bool = false, const std::filesystem::path &dataRoot = {});
~App();
int execute();
void dispatch(int);
void transform(int, int snippet = -1);
void pasteEntry(std::wstring, bool plain);
void recognizeEntry(std::wstring);
void captureHistory();
void enqueue(std::function<void()>);
void report(const std::wstring &);
void trayMenu();
void addTray();
bool registerHotkeys(const Settings &, bool rollback = false);
void applySettings(const Settings &);
void reloadLayouts();
void clearHistory();
void setHotkeyCapture(HWND);
bool isHotkey(DWORD, UINT);
void keyboard(const KBDLLHOOKSTRUCT &, UINT modifiers);
bool handleKeyboard(const KBDLLHOOKSTRUCT &, bool down, UINT modifiers);
void resetInput();
void checkUpdate(bool interactive, bool install = false, const std::wstring &version = {});
static App *current;
private:
friend struct InputRegressionAccess;
HHOOK keyboardHook{}, mouseHook{};
std::mutex jobsMutex;
std::condition_variable jobsReady;
std::deque<std::function<void()>> jobs;
std::thread worker;
std::thread updateWorker;
bool updateRunning{}, installingUpdate{};
std::wstring availableUpdate;
bool stop{};
UINT taskbarCreated{};
uint64_t pendingAutoVersion{};
uint64_t transformAttempt{}, previousAttemptVersion{};
ULONGLONG previousAttemptAt{};
HWND previousAttemptWindow{};
int previousAttemptCommand{}, repeatAttempts{};
std::vector<std::pair<int, Hotkey>> hookBindings;
HotkeyHook hotkeyHook;
static LRESULT CALLBACK windowProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK keyProc(int, WPARAM, LPARAM);
static LRESULT CALLBACK mouseProc(int, WPARAM, LPARAM);
};
void showHistory(App &);
void refreshHistory(App &);
void showSettings(App &, bool visible = true);
void showLogs(App &);
void showSnippets(App &);
void showShortcuts(App &);
void showEntry(App &, const std::wstring &);
} // namespace ks