#pragma once #include "autocorrect.h" #include "storage.h" #include "update.h" #include #include #include #include #include #include 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, Screenshot = 7, 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 layouts; Settings settings; std::unique_ptr history; AutoCorrector autoCorrector; std::atomic busy{false}, suspended{false}; std::atomic ownSequence{0}; std::atomic inputVersion{0}; std::atomic pauseUntil{0}; HWND pasteTarget{}; HWND hotkeyCapture{}; DWORD hotkeyCaptureProcess{}; HWND logWindow{}; std::mutex stateMutex; Run run; std::optional 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 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> 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> 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 showScreenshot(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