Hold Keys mode: keys stay down while touched, like a hardware keyboard
- HardwareKeys presses a key's unshifted keysym on touch and releases it on lift, through fake input; held keys repeat and combine as on a physical keyboard (games, Shift+click) - Shift/Ctrl/Alt/Super are plain held keys, caps lock is the system's, dead keys compose in the app - No long-press, flick, trackpad or rollover in this mode; nothing is left held when the mode is turned off or touches are cancelled - Settings switch; default stays the touch (virtual keyboard) mode Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ KeyboardController::KeyboardController(InputEngine &engine, LayoutModel &model,
|
||||
: QObject(parent)
|
||||
, m_engine(engine)
|
||||
, m_model(model)
|
||||
, m_hardware(engine)
|
||||
, m_keysymRepeater(KeysymRepeat)
|
||||
{
|
||||
connect(&m_backspaceRepeater, &KeyRepeater::repeat, this, &KeyboardController::deleteBackward);
|
||||
@@ -30,11 +31,34 @@ KeyboardController::KeyboardController(InputEngine &engine, LayoutModel &model,
|
||||
|
||||
KeyboardController::ShiftMode KeyboardController::shiftMode() const
|
||||
{
|
||||
if (m_options.holdKeys) {
|
||||
if (m_hardware.isCapsLockOn())
|
||||
return ShiftMode::Locked;
|
||||
return m_hardware.isShiftHeld() ? ShiftMode::Once : ShiftMode::Off;
|
||||
}
|
||||
return ShiftMode(m_shift.mode());
|
||||
}
|
||||
|
||||
QVariantMap KeyboardController::modifierModes() const
|
||||
{
|
||||
return m_options.holdKeys ? m_hardware.modifierModes() : m_modifiers.modes();
|
||||
}
|
||||
|
||||
bool KeyboardController::holdKey(const KeyDef &key, bool pressed)
|
||||
{
|
||||
if (!m_options.holdKeys || !HardwareKeys::handles(key))
|
||||
return false;
|
||||
pressed ? m_hardware.press(key) : m_hardware.release(key);
|
||||
m_model.setShiftLevel(shiftLevel());
|
||||
Q_EMIT shiftChanged();
|
||||
Q_EMIT modifiersChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
void KeyboardController::keyDown(const KeyDef &key, qint64 timeMs)
|
||||
{
|
||||
if (holdKey(key, true))
|
||||
return;
|
||||
switch (key.type) {
|
||||
case KeyType::Shift:
|
||||
changeShift([&] { m_shift.press(timeMs); });
|
||||
@@ -72,6 +96,8 @@ void KeyboardController::keyDown(const KeyDef &key, qint64 timeMs)
|
||||
|
||||
void KeyboardController::keyUp(const KeyDef &key, KeyOutput output, const QString &alternate, qint64)
|
||||
{
|
||||
if (holdKey(key, false))
|
||||
return;
|
||||
switch (key.type) {
|
||||
case KeyType::Shift:
|
||||
changeShift([&] { m_shift.release(); });
|
||||
@@ -112,6 +138,8 @@ void KeyboardController::keyUp(const KeyDef &key, KeyOutput output, const QStrin
|
||||
|
||||
void KeyboardController::keyCancelled(const KeyDef &key)
|
||||
{
|
||||
if (holdKey(key, false))
|
||||
return;
|
||||
if (key.type == KeyType::Shift)
|
||||
changeShift([&] { m_shift.release(); });
|
||||
else if (key.type == KeyType::Modifier) {
|
||||
@@ -125,6 +153,7 @@ void KeyboardController::keyCancelled(const KeyDef &key)
|
||||
|
||||
void KeyboardController::slideReleased(const KeyDef &target, qint64 timeMs)
|
||||
{
|
||||
holdKey(target, true); // only in hold-keys mode: the slide never pressed it
|
||||
keyUp(target, KeyOutput::Primary, {}, timeMs);
|
||||
m_model.setLayer(m_layerBeforeSwitch);
|
||||
}
|
||||
@@ -158,7 +187,12 @@ void KeyboardController::setContext(const TextContext &context)
|
||||
|
||||
void KeyboardController::setOptions(const TypingOptions &options)
|
||||
{
|
||||
if (m_options.holdKeys && !options.holdKeys)
|
||||
m_hardware.releaseAll();
|
||||
m_options = options;
|
||||
m_model.setShiftLevel(shiftLevel());
|
||||
Q_EMIT shiftChanged();
|
||||
Q_EMIT modifiersChanged();
|
||||
autoCapitalize();
|
||||
}
|
||||
|
||||
@@ -254,6 +288,8 @@ void KeyboardController::autoCapitalize()
|
||||
|
||||
ShiftLevel KeyboardController::shiftLevel() const
|
||||
{
|
||||
if (m_options.holdKeys)
|
||||
return m_hardware.shiftLevel();
|
||||
if (m_shift.appliesToShortcuts())
|
||||
return ShiftLevel::Shifted;
|
||||
return m_shift.isActive() ? ShiftLevel::Capitals : ShiftLevel::None;
|
||||
|
||||
Reference in New Issue
Block a user