Optional PC key blocks: function row, navigation, numeric keypad
- Template sections placed above or to the right of the typing keys; the user picks any mix in settings, typing keys included - keysym keys send XKB keysyms on press, optionally repeating - Geometry lays blocks side by side with one key unit; stretch keys are resolved at layout time so composed blocks line up - Toggling a block resizes the window so keys keep their size Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,14 +14,18 @@ static_assert(int(KeyboardController::ShiftMode::Locked) == int(ShiftState::Mode
|
||||
namespace {
|
||||
// Enough history for the text rules; fields may report megabytes.
|
||||
constexpr qsizetype MaxTextBefore = 256;
|
||||
// Like a hardware key: no word mode, a faster rate than Backspace.
|
||||
constexpr KeyRepeater::Timing KeysymRepeat{.intervalMs = 50, .wordModeAfterMs = std::numeric_limits<int>::max()};
|
||||
}
|
||||
|
||||
KeyboardController::KeyboardController(InputEngine &engine, LayoutModel &model, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_engine(engine)
|
||||
, m_model(model)
|
||||
, m_keysymRepeater(KeysymRepeat)
|
||||
{
|
||||
connect(&m_backspaceRepeater, &KeyRepeater::repeat, this, &KeyboardController::deleteBackward);
|
||||
connect(&m_keysymRepeater, &KeyRepeater::repeat, this, &KeyboardController::sendRepeatedKeysym);
|
||||
}
|
||||
|
||||
KeyboardController::ShiftMode KeyboardController::shiftMode() const
|
||||
@@ -43,6 +47,13 @@ void KeyboardController::keyDown(const KeyDef &key, qint64 timeMs)
|
||||
m_layerBeforeSwitch = m_model.layerName();
|
||||
m_model.setLayer(key.target);
|
||||
break;
|
||||
case KeyType::Keysym:
|
||||
m_engine.sendKeysym(key.keysym);
|
||||
if (key.repeat) {
|
||||
m_repeatingKeysym = key.keysym;
|
||||
m_keysymRepeater.start();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break; // everything else acts on release
|
||||
}
|
||||
@@ -57,6 +68,9 @@ void KeyboardController::keyUp(const KeyDef &key, KeyOutput output, const QStrin
|
||||
case KeyType::Backspace:
|
||||
m_backspaceRepeater.stop();
|
||||
break;
|
||||
case KeyType::Keysym:
|
||||
stopRepeating(key);
|
||||
break;
|
||||
case KeyType::Character:
|
||||
if (output == KeyOutput::Alternate && !alternate.isEmpty())
|
||||
typeText(alternate);
|
||||
@@ -90,6 +104,8 @@ void KeyboardController::keyCancelled(const KeyDef &key)
|
||||
changeShift([&] { m_shift.release(); });
|
||||
else if (key.type == KeyType::Backspace)
|
||||
m_backspaceRepeater.stop();
|
||||
else if (key.type == KeyType::Keysym)
|
||||
stopRepeating(key);
|
||||
}
|
||||
|
||||
void KeyboardController::slideReleased(const KeyDef &target, qint64 timeMs)
|
||||
@@ -156,6 +172,18 @@ void KeyboardController::deleteBackward(bool wholeWord)
|
||||
autoCapitalize();
|
||||
}
|
||||
|
||||
// Only the key that started the repeat stops it; another finger's key doesn't.
|
||||
void KeyboardController::stopRepeating(const KeyDef &key)
|
||||
{
|
||||
if (key.keysym == m_repeatingKeysym)
|
||||
m_keysymRepeater.stop();
|
||||
}
|
||||
|
||||
void KeyboardController::sendRepeatedKeysym()
|
||||
{
|
||||
m_engine.sendKeysym(m_repeatingKeysym);
|
||||
}
|
||||
|
||||
void KeyboardController::autoCapitalize()
|
||||
{
|
||||
const bool capitalize = m_options.autoCapitalize && m_context.allowsAutoCapitalization()
|
||||
|
||||
Reference in New Issue
Block a user