Skip to content

Commit 3d16287

Browse files
committed
Make more reliable
1 parent 67a1e68 commit 3d16287

File tree

15 files changed

+491
-271
lines changed

15 files changed

+491
-271
lines changed

src/wayland/input_method/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
qt_add_library(quickshell-wayland-input-method STATIC
22
input_method.cpp
3+
keyboard_grab.cpp
34
virtual_keyboard.cpp
5+
key_map_state.cpp
46
manager.cpp
57
qml.cpp
68
)
Lines changed: 9 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
#include "input_method.hpp"
22

33
#include <qtmetamacros.h>
4-
#include <sys/mman.h>
54
#include <wayland-input-method-unstable-v2-client-protocol.h>
6-
#include <xkbcommon/xkbcommon.h>
75

8-
#include "manager.hpp"
9-
#include "virtual_keyboard.hpp"
6+
#include "keyboard_grab.hpp"
107

118
namespace qs::wayland::input_method::impl {
129

@@ -20,7 +17,13 @@ InputMethodHandle::~InputMethodHandle() {
2017
}
2118

2219
void InputMethodHandle::commitString(const QString& text) { commit_string(text); }
23-
void InputMethodHandle::sendPreeditString(const QString& text, int32_t cursorBegin, int32_t cursorEnd) { set_preedit_string(text, cursorBegin, cursorEnd); }
20+
void InputMethodHandle::sendPreeditString(
21+
const QString& text,
22+
int32_t cursorBegin,
23+
int32_t cursorEnd
24+
) {
25+
set_preedit_string(text, cursorBegin, cursorEnd);
26+
}
2427
void InputMethodHandle::deleteText(int before, int after) {
2528
zwp_input_method_v2::delete_surrounding_text(before, after);
2629
}
@@ -33,7 +36,7 @@ QPointer<InputMethodKeyboardGrab> InputMethodHandle::grabKeyboard() {
3336

3437
return keyboard;
3538
}
36-
void InputMethodHandle::releaseKeyboard(){
39+
void InputMethodHandle::releaseKeyboard() {
3740
if (!keyboard) return;
3841
keyboard->deleteLater();
3942
keyboard = nullptr;
@@ -61,117 +64,4 @@ void InputMethodHandle::zwp_input_method_v2_unavailable() {
6164
) << "Compositor denied input method request, likely due to one already existing elsewhere";
6265
}
6366

64-
InputMethodKeyboardGrab::InputMethodKeyboardGrab(
65-
QObject* parent,
66-
::zwp_input_method_keyboard_grab_v2* keyboard
67-
)
68-
: QObject(parent)
69-
, zwp_input_method_keyboard_grab_v2(keyboard) {}
70-
71-
InputMethodKeyboardGrab::~InputMethodKeyboardGrab() {
72-
this->release();
73-
}
74-
75-
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_keymap(
76-
uint32_t format,
77-
int32_t fd,
78-
uint32_t size
79-
) {
80-
// https://wayland-book.com/seat/keyboard.html
81-
assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);
82-
83-
char* mapShm = static_cast<char*>(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0));
84-
assert(mapShm != MAP_FAILED);
85-
86-
xkb_keymap_unref(xkbKeymap);
87-
this->xkbKeymap = xkb_keymap_new_from_string(
88-
this->xkbContext,
89-
mapShm,
90-
XKB_KEYMAP_FORMAT_TEXT_V1,
91-
XKB_KEYMAP_COMPILE_NO_FLAGS
92-
);
93-
94-
munmap(mapShm, size);
95-
close(fd);
96-
97-
xkb_state_unref(xkbState);
98-
this->xkbState = xkb_state_new(this->xkbKeymap);
99-
100-
// a hack to reset the keyboard on the client that has focus
101-
auto vk = VirtualKeyboardManager::instance()->createVirtualKeyboard(xkbKeymap);
102-
vk->sendKey(vk->toKey('\r'), WL_KEYBOARD_KEY_STATE_RELEASED);
103-
}
104-
105-
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_key(
106-
uint32_t serial,
107-
uint32_t /*time*/, // TODO key repeat
108-
uint32_t key,
109-
uint32_t state
110-
) {
111-
112-
if (serial <= mSerial) return;
113-
mSerial = serial;
114-
115-
xkb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, key + 8);
116-
if (sym == XKB_KEY_Escape) {
117-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit escapePress();
118-
return;
119-
}
120-
if (sym == XKB_KEY_Return) {
121-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit returnPress();
122-
return;
123-
}
124-
if (sym == XKB_KEY_Up) {
125-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(UP);
126-
return;
127-
}
128-
if (sym == XKB_KEY_Down) {
129-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(DOWN);
130-
return;
131-
}
132-
if (sym == XKB_KEY_Left) {
133-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(LEFT);
134-
return;
135-
}
136-
if (sym == XKB_KEY_Right) {
137-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit directionPress(RIGHT);
138-
return;
139-
}
140-
if (sym == XKB_KEY_BackSpace) {
141-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit backspacePress();
142-
return;
143-
}
144-
if (sym == XKB_KEY_Delete) {
145-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit deletePress();
146-
return;
147-
}
148-
if (sym >= XKB_KEY_space && sym <= XKB_KEY_ydiaeresis)
149-
{ // Should we limit the keyboard like this?
150-
char buf[128]; // NOLINT
151-
xkb_state_key_get_utf8(xkbState, key + 8, buf, sizeof(buf));
152-
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) emit keyPress(buf);
153-
return;
154-
}
155-
}
156-
157-
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_modifiers(
158-
uint32_t serial,
159-
uint32_t modsDepressed,
160-
uint32_t modsLatched,
161-
uint32_t modsLocked,
162-
uint32_t group
163-
) {
164-
if (serial <= mSerial) return;
165-
mSerial = serial;
166-
xkb_state_update_mask(xkbState, modsDepressed, modsLatched, modsLocked, group, group, group);
167-
}
168-
169-
void InputMethodKeyboardGrab::zwp_input_method_keyboard_grab_v2_repeat_info(
170-
int32_t rate,
171-
int32_t delay
172-
) {
173-
mRate = rate;
174-
mDelay = delay;
175-
}
176-
17767
} // namespace qs::wayland::input_method::impl

src/wayland/input_method/input_method.hpp

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,10 @@
44
#include <qpointer.h>
55
#include <qtclasshelpermacros.h>
66
#include <qwayland-input-method-unstable-v2.h>
7-
#include <xkbcommon/xkbcommon.h>
8-
#include "types.hpp"
97

108
namespace qs::wayland::input_method::impl {
119

12-
class InputMethodHandle;
13-
14-
class InputMethodPopupSurface: QObject {
15-
Q_OBJECT;
16-
};
17-
18-
class InputMethodKeyboardGrab
19-
: public QObject
20-
, private QtWayland::zwp_input_method_keyboard_grab_v2 {
21-
Q_OBJECT;
22-
23-
public:
24-
explicit InputMethodKeyboardGrab(QObject* parent, ::zwp_input_method_keyboard_grab_v2* keyboard);
25-
~InputMethodKeyboardGrab() override;
26-
Q_DISABLE_COPY_MOVE(InputMethodKeyboardGrab);
27-
28-
signals:
29-
void keyPress(const QString& text);
30-
void escapePress();
31-
void returnPress();
32-
void directionPress(DirectionKey);
33-
void backspacePress();
34-
void deletePress();
35-
36-
private:
37-
void
38-
zwp_input_method_keyboard_grab_v2_keymap(uint32_t format, int32_t fd, uint32_t size) override;
39-
void zwp_input_method_keyboard_grab_v2_key(
40-
uint32_t serial,
41-
uint32_t time,
42-
uint32_t key,
43-
uint32_t state
44-
) override;
45-
void zwp_input_method_keyboard_grab_v2_modifiers(
46-
uint32_t serial,
47-
uint32_t modsDepressed,
48-
uint32_t modsLatched,
49-
uint32_t modsLocked,
50-
uint32_t group
51-
) override;
52-
void zwp_input_method_keyboard_grab_v2_repeat_info(int32_t rate, int32_t delay) override;
53-
54-
uint32_t mSerial = 0;
55-
int32_t mRate = 0;
56-
int32_t mDelay = 0;
57-
58-
xkb_context* xkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
59-
xkb_keymap* xkbKeymap = nullptr;
60-
xkb_state *xkbState = nullptr;
61-
};
10+
class InputMethodKeyboardGrab;
6211

6312
class InputMethodHandle
6413
: public QObject

0 commit comments

Comments
 (0)