Skip to content

Commit 5464050

Browse files
committed
Send modifiers over virtual keyboard
1 parent 3d16287 commit 5464050

File tree

5 files changed

+87
-74
lines changed

5 files changed

+87
-74
lines changed

src/wayland/input_method/key_map_state.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,47 +56,49 @@ xkb_keycode_t KeyMapState::toKey(QChar character) const {
5656
return keycode;
5757
}
5858

59-
6059
const char* KeyMapState::keyName(xkb_keycode_t key) const {
6160
return xkb_keymap_key_get_name(xkbKeymap, key);
6261
}
6362

6463
xkb_keycode_t KeyMapState::maxKeycode() const { return xkb_keymap_max_keycode(xkbKeymap); }
6564

66-
xkb_keysym_t KeyMapState::getOneSym(xkb_keycode_t key) const{
65+
xkb_keysym_t KeyMapState::getOneSym(xkb_keycode_t key) const {
6766
return xkb_state_key_get_one_sym(xkbState, key);
6867
}
69-
QChar KeyMapState::getChar(xkb_keycode_t key) const{
68+
QChar KeyMapState::getChar(xkb_keycode_t key) const {
7069
return QChar(xkb_state_key_get_utf32(xkbState, key));
7170
}
7271

73-
void KeyMapState::setModifiers(
74-
xkb_mod_mask_t depressedMods,
75-
xkb_mod_mask_t latchedMods,
76-
xkb_mod_mask_t lockedMods,
77-
xkb_layout_index_t depressedLayout,
78-
xkb_layout_index_t latchedLayout,
79-
xkb_layout_index_t lockedLayout
80-
) {
72+
void KeyMapState::setModifiers(ModifierState modifierState) {
8173
if (!*this) return;
8274
xkb_state_update_mask(
8375
xkbState,
84-
depressedMods,
85-
latchedMods,
86-
lockedMods,
87-
depressedLayout,
88-
latchedLayout,
89-
lockedLayout
76+
modifierState.depressed,
77+
modifierState.latched,
78+
modifierState.locked,
79+
modifierState.depressedLayout,
80+
modifierState.latchedLayout,
81+
modifierState.lockedLayout
9082
);
9183
}
9284

85+
KeyMapState::ModifierState KeyMapState::serialiseMods() const {
86+
return {
87+
xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED),
88+
xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED),
89+
xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LOCKED),
90+
xkb_state_serialize_mods(xkbState, XKB_STATE_LAYOUT_DEPRESSED),
91+
xkb_state_serialize_mods(xkbState, XKB_STATE_LAYOUT_LATCHED),
92+
xkb_state_serialize_mods(xkbState, XKB_STATE_LAYOUT_LOCKED),
93+
};
94+
}
9395

9496
std::string_view KeyMapState::keyStateName(wl_keyboard_key_state state) {
9597
switch (state) {
96-
case WL_KEYBOARD_KEY_STATE_RELEASED: return "released";
97-
case WL_KEYBOARD_KEY_STATE_PRESSED: return "pressed";
98-
case WL_KEYBOARD_KEY_STATE_REPEATED: return "repeated";
99-
default: return "unknown state";
98+
case WL_KEYBOARD_KEY_STATE_RELEASED: return "released";
99+
case WL_KEYBOARD_KEY_STATE_PRESSED: return "pressed";
100+
case WL_KEYBOARD_KEY_STATE_REPEATED: return "repeated";
101+
default: return "unknown state";
100102
}
101103
}
102104

src/wayland/input_method/key_map_state.hpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,18 @@ class KeyMapState {
3434
[[nodiscard]] xkb_keysym_t getOneSym(xkb_keycode_t key) const;
3535
[[nodiscard]] QChar getChar(xkb_keycode_t key) const;
3636

37-
void setModifiers(
38-
xkb_mod_mask_t depressedMods,
39-
xkb_mod_mask_t latchedMods,
40-
xkb_mod_mask_t lockedMods,
41-
xkb_layout_index_t depressedLayout,
42-
xkb_layout_index_t latchedLayout,
43-
xkb_layout_index_t lockedLayout
44-
);
37+
struct ModifierState {
38+
xkb_mod_mask_t depressed;
39+
xkb_mod_mask_t latched;
40+
xkb_mod_mask_t locked;
41+
xkb_layout_index_t depressedLayout;
42+
xkb_layout_index_t latchedLayout;
43+
xkb_layout_index_t lockedLayout;
44+
};
45+
// This is the server version
46+
// if we want to expand virtual keyboard support
47+
void setModifiers(ModifierState modifierState);
48+
[[nodiscard]] ModifierState serialiseMods() const;
4549

4650
static std::string_view keyStateName(wl_keyboard_key_state state);
4751

src/wayland/input_method/keyboard_grab.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ InputMethodKeyboardGrab::~InputMethodKeyboardGrab() {
2929
}
3030

3131
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_keymap(
32-
uint32_t format,
32+
uint32_t [[maybe_unused]] format,
3333
int32_t fd,
3434
uint32_t size
3535
) {
@@ -64,7 +64,7 @@ void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_key(
6464

6565
key += 8;
6666

67-
qDebug() << KeyMapState::keyStateName(static_cast<wl_keyboard_key_state>(state))
67+
qInfo() << KeyMapState::keyStateName(static_cast<wl_keyboard_key_state>(state))
6868
<< this->mKeyMapState.keyName(key) << "[" << key << "]"
6969
<< this->mKeyMapState.getChar(key);
7070

@@ -75,10 +75,6 @@ void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_key(
7575
}
7676

7777
xkb_keysym_t sym = this->mKeyMapState.getOneSym(key);
78-
79-
char buf[16]; // NOLINT
80-
xkb_keysym_get_name(sym, buf, sizeof(buf));
81-
qDebug() << buf;
8278

8379
if (sym == XKB_KEY_Escape) {
8480
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit escapePress();
@@ -128,7 +124,10 @@ void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_modifiers(
128124
) {
129125
if (serial <= this->mSerial) return;
130126
this->mSerial = serial;
131-
this->mKeyMapState.setModifiers(modsDepressed, modsLatched, modsLocked, group, group, group);
127+
this->mKeyMapState.setModifiers(
128+
KeyMapState::ModifierState(modsDepressed, modsLatched, modsLocked, group, group, group)
129+
);
130+
this->mVirturalKeyboard->sendModifiers();
132131
}
133132

134133
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_repeat_info(

src/wayland/input_method/virtual_keyboard.cpp

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,75 @@
11
#include "virtual_keyboard.hpp"
22
#include <chrono>
33

4-
#include <sys/mman.h>
54
#include <fcntl.h>
5+
#include <sys/mman.h>
66

77
namespace qs::wayland::input_method::impl {
88

99
namespace {
1010
using namespace std::chrono;
1111
uint32_t now() {
12-
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
12+
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1313
}
1414
} // namespace
1515

16-
VirtualKeyboardHandle::VirtualKeyboardHandle(::zwp_virtual_keyboard_v1* keyboard, const KeyMapState& keymap)
16+
VirtualKeyboardHandle::VirtualKeyboardHandle(
17+
::zwp_virtual_keyboard_v1* keyboard,
18+
const KeyMapState& keymap
19+
)
1720
: QtWayland::zwp_virtual_keyboard_v1(keyboard) {
18-
setKeymapState(keymap);
21+
setKeymapState(keymap);
1922
}
2023

2124
VirtualKeyboardHandle::~VirtualKeyboardHandle() { this->destroy(); }
2225

2326
void VirtualKeyboardHandle::setKeymapState(const KeyMapState& keymap) {
24-
if (this->mKeyMapState == keymap) return;
25-
if (!keymap) return;
26-
this->mKeyMapState = keymap;
27+
if (this->mKeyMapState == keymap) return;
28+
if (!keymap) return;
29+
this->mKeyMapState = keymap;
2730

28-
static const char* shmName = "/quickshellvirtualkeyboardformat";
29-
if(shm_unlink(shmName) == -1 && errno != ENOENT){
30-
perror("");
31-
qDebug() << "Virtual keyboard failed to unlink shared memory";
32-
}
33-
int fd = shm_open(shmName, O_CREAT | O_RDWR, 0);
34-
if(fd == -1) {
35-
perror("");
36-
qDebug() << "Virtual keyboard failed to open shared memory";
37-
return;
38-
}
39-
auto keymapString = keymap.keyMapAsString();
40-
size_t size = strlen(keymapString.get()) + 1;
41-
if(ftruncate(fd, static_cast<int>(size)) == -1) {
42-
perror("");
43-
qDebug() << "Virtual keyboard failed to resize shared memory to" << size;
44-
return;
45-
}
31+
static const char* shmName = "/quickshellvirtualkeyboardformat";
32+
if (shm_unlink(shmName) == -1 && errno != ENOENT) {
33+
perror("");
34+
qDebug() << "Virtual keyboard failed to unlink shared memory";
35+
}
36+
int fd = shm_open(shmName, O_CREAT | O_RDWR, 0);
37+
if (fd == -1) {
38+
perror("");
39+
qDebug() << "Virtual keyboard failed to open shared memory";
40+
return;
41+
}
42+
auto keymapString = keymap.keyMapAsString();
43+
size_t size = strlen(keymapString.get()) + 1;
44+
if (ftruncate(fd, static_cast<int>(size)) == -1) {
45+
perror("");
46+
qDebug() << "Virtual keyboard failed to resize shared memory to" << size;
47+
return;
48+
}
4649

47-
char* mapShm = static_cast<char*>(mmap(nullptr, size, PROT_WRITE, MAP_SHARED, fd, 0));
48-
if(mapShm == MAP_FAILED) {
49-
perror("");
50-
qDebug() << "Virtual keyboard failed to open shared memory";
51-
return;
52-
}
53-
strcpy(mapShm, keymapString.get());
50+
char* mapShm = static_cast<char*>(mmap(nullptr, size, PROT_WRITE, MAP_SHARED, fd, 0));
51+
if (mapShm == MAP_FAILED) {
52+
perror("");
53+
qDebug() << "Virtual keyboard failed to open shared memory";
54+
return;
55+
}
56+
strcpy(mapShm, keymapString.get());
5457

55-
this->zwp_virtual_keyboard_v1::keymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, size);
58+
this->zwp_virtual_keyboard_v1::keymap(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, size);
5659

57-
good = true;
60+
good = true;
5861
}
5962

60-
6163
void VirtualKeyboardHandle::sendKey(xkb_keycode_t keycode, wl_keyboard_key_state state) {
62-
if (!good) return;
63-
if(keycode == XKB_KEYCODE_INVALID) return;
64+
if (!good) return;
65+
if (keycode == XKB_KEYCODE_INVALID) return;
66+
67+
this->zwp_virtual_keyboard_v1::key(now(), keycode - 8, state);
68+
}
6469

65-
this->zwp_virtual_keyboard_v1::key(now(), keycode - 8, state);
70+
void VirtualKeyboardHandle::sendModifiers() {
71+
auto mods = mKeyMapState.serialiseMods();
72+
modifiers(mods.depressed, mods.latched, mods.locked, mods.depressedLayout);
6673
}
6774

6875
bool VirtualKeyboardHandle::getGood() const { return good; }

src/wayland/input_method/virtual_keyboard.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class VirtualKeyboardHandle: private QtWayland::zwp_virtual_keyboard_v1 {
2020
void setKeymapState(const KeyMapState& keymap);
2121

2222
void sendKey(xkb_keycode_t keycode, wl_keyboard_key_state state);
23+
void sendModifiers();
2324

2425
[[nodiscard]] bool getGood() const;
2526

0 commit comments

Comments
 (0)