Skip to content

Commit c627f93

Browse files
committed
key repeat
1 parent 402093b commit c627f93

File tree

5 files changed

+66
-22
lines changed

5 files changed

+66
-22
lines changed

src/wayland/input_method/key_map_state.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ std::string_view KeyMapState::keyStateName(wl_keyboard_key_state state) {
9797
}
9898
}
9999

100+
bool KeyMapState::keyRepeats(xkb_keycode_t key) const {
101+
return xkb_keymap_key_repeats(this->xkbKeymap, key);
102+
}
103+
100104
xkb_context* KeyMapState::xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
101105

102106
} // namespace qs::wayland::input_method::impl

src/wayland/input_method/key_map_state.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class KeyMapState {
5050

5151
static std::string_view keyStateName(wl_keyboard_key_state state);
5252

53+
[[nodiscard]] bool keyRepeats(xkb_keycode_t key) const;
54+
5355
private:
5456
static xkb_context* xkbContext;
5557
xkb_keymap* xkbKeymap = nullptr;

src/wayland/input_method/keyboard_grab.cpp

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <cstddef>
44
#include <vector>
55

6-
#include <qlogging.h>
6+
#include <qdebug.h>
77
#include <qobject.h>
88
#include <qtmetamacros.h>
99
#include <qwayland-input-method-unstable-v2.h>
@@ -25,7 +25,12 @@ InputMethodKeyboardGrab::InputMethodKeyboardGrab(
2525
::zwp_input_method_keyboard_grab_v2* keyboard
2626
)
2727
: QObject(parent)
28-
, zwp_input_method_keyboard_grab_v2(keyboard) {}
28+
, zwp_input_method_keyboard_grab_v2(keyboard) {
29+
this->mRepeatTimer.callOnTimeout(this, [&](){
30+
this->mRepeatTimer.setInterval(1000 / this->mRepeatRate);
31+
handleKey(mRepeatKey);
32+
});
33+
}
2934

3035
InputMethodKeyboardGrab::~InputMethodKeyboardGrab() {
3136
this->release();
@@ -108,38 +113,58 @@ void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_key(
108113
this->mKeyState[key - this->mKeyMapState.minKeycode()] = KeyState::RELEASED;
109114
}
110115

116+
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
117+
bool keyHandled = handleKey(key);
118+
if (keyHandled){
119+
if (this->mKeyMapState.keyRepeats(key) && this->mRepeatRate > 0) {
120+
this->mRepeatKey = key;
121+
this->mRepeatTimer.setInterval(this->mRepeatDelay);
122+
this->mRepeatTimer.start();
123+
}
124+
return;
125+
}
126+
}
127+
128+
if (this->mRepeatKey == key) {
129+
this->mRepeatTimer.stop();
130+
}
131+
132+
this->mVirturalKeyboard->sendKey(key, static_cast<wl_keyboard_key_state>(state));
133+
}
134+
135+
bool InputMethodKeyboardGrab::handleKey(xkb_keycode_t key){
136+
const xkb_keysym_t sym = this->mKeyMapState.getOneSym(key);
111137
if (sym == XKB_KEY_Up) {
112-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(DirectionKey::UP);
113-
return;
138+
emit directionPress(DirectionKey::UP);
139+
return true;
114140
}
115141
if (sym == XKB_KEY_Down) {
116-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(DirectionKey::DOWN);
117-
return;
142+
emit directionPress(DirectionKey::DOWN);
143+
return true;
118144
}
119145
if (sym == XKB_KEY_Left) {
120-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(DirectionKey::LEFT);
121-
return;
146+
emit directionPress(DirectionKey::LEFT);
147+
return true;
122148
}
123149
if (sym == XKB_KEY_Right) {
124-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(DirectionKey::RIGHT);
125-
return;
150+
emit directionPress(DirectionKey::RIGHT);
151+
return true;
126152
}
127153
if (sym == XKB_KEY_BackSpace) {
128-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit backspacePress();
129-
return;
154+
emit backspacePress();
155+
return true;
130156
}
131157
if (sym == XKB_KEY_Delete) {
132-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit deletePress();
133-
return;
158+
emit deletePress();
159+
return true;
134160
}
135161

136162
const QChar character = this->mKeyMapState.getChar(key);
137163
if (character != '\0') {
138-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit keyPress(character);
139-
return;
140-
} else {
141-
this->mVirturalKeyboard->sendKey(key, static_cast<wl_keyboard_key_state>(state));
164+
emit keyPress(character);
165+
return true;
142166
}
167+
return false;
143168
}
144169

145170
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_modifiers(
@@ -158,8 +183,11 @@ void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_modifiers(
158183
}
159184

160185
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_repeat_info(
161-
int32_t /*rate*/,
162-
int32_t /*delay*/
163-
) {}
186+
int32_t rate,
187+
int32_t delay
188+
) {
189+
mRepeatRate = rate;
190+
mRepeatDelay = delay;
191+
}
164192

165193
} // namespace qs::wayland::input_method::impl

src/wayland/input_method/keyboard_grab.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <qobject.h>
44
#include <qtclasshelpermacros.h>
55
#include <qwayland-input-method-unstable-v2.h>
6+
#include <qtimer.h>
67

78
#include "key_map_state.hpp"
89
#include "types.hpp"
@@ -55,6 +56,8 @@ class InputMethodKeyboardGrab
5556
) override;
5657
void zwp_input_method_keyboard_grab_v2_repeat_info(int32_t rate, int32_t delay) override;
5758

59+
bool handleKey(xkb_keycode_t key);
60+
5861
uint32_t mSerial = 0;
5962

6063
enum class KeyState : bool {
@@ -64,6 +67,13 @@ class InputMethodKeyboardGrab
6467
std::vector<KeyState> mKeyState;
6568
KeyMapState mKeyMapState;
6669

70+
QTimer mRepeatTimer;
71+
// Keys per second
72+
int32_t mRepeatRate = 25;
73+
// milliseconds before first repeat
74+
int32_t mRepeatDelay = 400;
75+
xkb_keycode_t mRepeatKey = 0;
76+
6777
std::unique_ptr<VirtualKeyboardHandle> mVirturalKeyboard;
6878
};
6979

src/wayland/input_method/qml_helpers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void KeyboardTextEdit::setTransform(const QJSValue& callback) {
2929
int KeyboardTextEdit::cursor() const { return this->mCursor; }
3030
void KeyboardTextEdit::setCursor(int value) {
3131
value = std::max(value, 0);
32-
value = std::min(value, static_cast<int>(this->mEditText.size() - 1));
32+
value = std::min(value, static_cast<int>(this->mEditText.size()));
3333
if (this->mCursor == value) return;
3434
this->mCursor = value;
3535
this->updatePreedit();

0 commit comments

Comments
 (0)