125 lines
3.0 KiB
C++
125 lines
3.0 KiB
C++
/*******************************************************************************
|
|
* StellarX native keyboard, text, IME, and activation event model.
|
|
* Stage 1 only captures, normalizes, queues, and observes these events.
|
|
* Focus, routing, and control behavior are intentionally out of scope.
|
|
******************************************************************************/
|
|
#pragma once
|
|
|
|
#include <windows.h>
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
namespace StellarX
|
|
{
|
|
enum class KeyAction : std::uint8_t
|
|
{
|
|
Down,
|
|
Up
|
|
};
|
|
|
|
// Snapshot modifiers in WndProc; delayed consumers must not reread global state.
|
|
struct KeyModifiers
|
|
{
|
|
bool leftControl = false;
|
|
bool rightControl = false;
|
|
bool leftShift = false;
|
|
bool rightShift = false;
|
|
bool leftAlt = false;
|
|
bool rightAlt = false;
|
|
|
|
bool control() const noexcept { return leftControl || rightControl; }
|
|
bool shift() const noexcept { return leftShift || rightShift; }
|
|
bool alt() const noexcept { return leftAlt || rightAlt; }
|
|
};
|
|
|
|
struct KeyEvent
|
|
{
|
|
KeyAction action = KeyAction::Down;
|
|
|
|
UINT virtualKey = 0; // Raw WndProc VK; VK_PROCESSKEY is never rewritten.
|
|
UINT physicalVirtualKey = 0; // Left/right-normalized modifier VK.
|
|
UINT scanCode = 0;
|
|
|
|
std::uint16_t repeatCount = 0;
|
|
bool extended = false;
|
|
bool wasDown = false;
|
|
bool altContext = false; // Raw lParam bit 29; modifiers.alt() is the semantic snapshot.
|
|
bool systemKey = false;
|
|
|
|
// Snapshot of the standard IME lifecycle axis at capture time.
|
|
// It never overrides the per-key ownership expressed by VK_PROCESSKEY.
|
|
bool imeComposingAtCapture = false;
|
|
|
|
KeyModifiers modifiers{};
|
|
|
|
bool isAutoRepeat() const noexcept
|
|
{
|
|
return action == KeyAction::Down && wasDown;
|
|
}
|
|
|
|
bool isImeOwnedAtCapture() const noexcept
|
|
{
|
|
// Per-key ownership and IME lifecycle are intentionally independent axes.
|
|
// A normal key captured during a standard composition remains a normal key;
|
|
// routing may suppress it because of the lifecycle snapshot, but must not
|
|
// rewrite its ownership.
|
|
return virtualKey == VK_PROCESSKEY;
|
|
}
|
|
};
|
|
|
|
enum class TextSource : std::uint8_t
|
|
{
|
|
ImeResult,
|
|
UnicodeChar,
|
|
UnicodeScalar,
|
|
AnsiCharFallback,
|
|
Clipboard
|
|
};
|
|
|
|
struct TextInputEvent
|
|
{
|
|
std::wstring text;
|
|
TextSource source = TextSource::UnicodeChar;
|
|
std::uint64_t compositionId = 0; // Zero for non-IME input.
|
|
};
|
|
|
|
enum class CompositionStage : std::uint8_t
|
|
{
|
|
Start,
|
|
Update,
|
|
Commit,
|
|
Cancel,
|
|
End
|
|
};
|
|
|
|
struct CompositionEvent
|
|
{
|
|
CompositionStage stage = CompositionStage::Start;
|
|
std::uint64_t compositionId = 0;
|
|
std::wstring compositionText;
|
|
std::uint32_t caretOffset = 0;
|
|
};
|
|
|
|
struct WindowActivationEvent
|
|
{
|
|
bool keyboardFocusActive = false;
|
|
HWND otherWindow = nullptr;
|
|
};
|
|
|
|
using NativeInputPayload = std::variant<
|
|
KeyEvent,
|
|
TextInputEvent,
|
|
CompositionEvent,
|
|
WindowActivationEvent>;
|
|
|
|
struct NativeInputEvent
|
|
{
|
|
std::uint64_t sequence = 0;
|
|
DWORD messageTime = 0;
|
|
HWND hwnd = nullptr;
|
|
NativeInputPayload payload{};
|
|
};
|
|
}
|