#pragma once #include "core.h" #include #include #include #include #include namespace ks { inline std::wstring localBuildTitle(const std::wstring &title) { static const bool development=[] { wchar_t path[32768]{}; if(!GetModuleFileNameW(nullptr,path,std::size(path))) return false; std::error_code error; return std::filesystem::exists(std::filesystem::path(path).parent_path()/L".local-dev",error); }(); return development?title+L" [LOCAL DEV]":title; } using Bytes = std::vector; struct Format { UINT id{}; std::wstring name; Bytes data; }; struct Clip { std::vector formats; std::wstring text() const; size_t size() const; }; std::vector readLayouts(); const Layout &physicalLayout(); wchar_t physicalKey(DWORD scan, bool shift); HKL windowLayout(HWND); bool switchWindowLayout(HWND, HKL, const std::function &valid); bool activateWindow(HWND); void showRequestedWindow(HWND); void showMenuAccessKeys(HMENU); bool ownsClipboard(HWND); bool webViewDescendant(DWORD owner, DWORD host, const std::function>(DWORD)> &read); std::wstring processName(HWND); enum class ClipboardRead { All, Selection, WithoutImages }; Clip readClipboard(HWND, size_t limit = 32 * 1024 * 1024, ClipboardRead = ClipboardRead::All, std::optional expected = {}); DWORD writeClipboard(HWND, const Clip &); DWORD writeClipboardGuarded(HWND, const Clip &, std::optional expected); Clip textClip(const std::wstring &); bool chord(WORD key, UINT modifiers = 0); // Process-local marker, shared by every KSwitcher input producer (not an authentication token). ULONG_PTR inputMarker(); bool ownKeyboardInput(const KBDLLHOOKSTRUCT &); INPUT keyboardInput(WORD key, DWORD flags = 0); bool needsSelectionDelay(HWND); bool selectPrevious(size_t count, const std::function &valid); bool modifiersReleased(); void releaseModifiers(); std::filesystem::path dataDirectory(); void atomicWrite(const std::filesystem::path &, const Bytes &); Bytes readFile(const std::filesystem::path &, size_t limit); Bytes protect(const Bytes &); Bytes unprotect(const Bytes &); void setAutostart(bool, bool elevated = false); std::wstring currentUserSid(); void configureAutostart(int mode); std::wstring executable(); std::wstring lastError(const std::wstring &context); void log(const std::wstring &message); std::wstring diagnosticText(const std::wstring &text); // A bounded, short-lived context. A problem drains it, so old incidents are not repeated. class DiagnosticBuffer { std::deque> entries; public: size_t expire(ULONGLONG now); std::wstring record(const std::wstring &message, bool problem, ULONGLONG now); void clear() { entries.clear(); } }; void setLoggingEnabled(bool enabled); void expireDiagnostics(ULONGLONG now); void diagnosticEvent(const std::wstring &message, bool problem = false); void diagnosticOperation(const std::string &json); std::wstring readDiagnosticLog(bool previous); void clearDiagnosticLog(bool previous); } // namespace ks