Skip to content

Commit b265756

Browse files
committed
surrounding text
1 parent d172f95 commit b265756

File tree

8 files changed

+167
-64
lines changed

8 files changed

+167
-64
lines changed

src/wayland/input_method/input_method.cpp

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <qlogging.h>
66
#include <qobject.h>
77
#include <qpointer.h>
8+
#include <qstring.h>
89
#include <qtmetamacros.h>
910
#include <qwayland-input-method-unstable-v2.h>
1011
#include <wayland-input-method-unstable-v2-client-protocol.h>
@@ -53,32 +54,69 @@ void InputMethodHandle::releaseKeyboard() {
5354
bool InputMethodHandle::isActive() const { return this->mState.activated; }
5455
bool InputMethodHandle::isAvailable() const { return this->mAvailable; }
5556

57+
const QString& InputMethodHandle::surroundingText() const {
58+
return this->mState.surroundingText.text;
59+
}
60+
uint32_t InputMethodHandle::surroundingTextCursor() const {
61+
return this->mState.surroundingText.cursor;
62+
}
63+
uint32_t InputMethodHandle::surroundingTextAnchor() const {
64+
return this->mState.surroundingText.anchor;
65+
}
66+
67+
ContentHint InputMethodHandle::contentHint() const {
68+
return this->mState.contentHint;
69+
}
70+
ContentPurpose InputMethodHandle::contentPurpose() const {
71+
return this->mState.contentPurpose;
72+
}
73+
5674
void InputMethodHandle::zwp_input_method_v2_activate() { this->mNewState.activated = true; }
5775

5876
void InputMethodHandle::zwp_input_method_v2_deactivate() { this->mNewState.activated = false; }
5977

78+
void InputMethodHandle::zwp_input_method_v2_surrounding_text(
79+
const QString& text,
80+
uint32_t cursor,
81+
uint32_t anchor
82+
) {
83+
this->mNewState.surroundingText.text = text;
84+
this->mNewState.surroundingText.cursor = cursor;
85+
this->mNewState.surroundingText.anchor = anchor;
86+
}
87+
88+
void InputMethodHandle::zwp_input_method_v2_text_change_cause(uint32_t cause) {
89+
this->mNewState.surroundingText.textChangeCause = static_cast<TextChangeCause>(cause);
90+
}
6091

6192
void InputMethodHandle::zwp_input_method_v2_content_type(uint32_t hint, uint32_t purpose) {
6293
this->mNewState.contentHint = static_cast<ContentHint>(hint);
6394
this->mNewState.contentPurpose = static_cast<ContentPurpose>(purpose);
6495
};
6596

6697
void InputMethodHandle::zwp_input_method_v2_done() {
67-
if (this->mState.activated != this->mNewState.activated){
98+
auto oldState= mState;
99+
this->mState = this->mNewState;
100+
101+
102+
if (this->mState.activated != oldState.activated) {
68103
if (this->mNewState.activated) emit activated();
69104
else emit deactivated();
70105
}
71106

72-
if (this->mState.contentHint != this->mNewState.contentHint){
73-
emit contentHintChanged(this->mNewState.contentHint);
107+
if (this->mState.surroundingText != oldState.surroundingText) {
108+
emit surroundingTextChanged(
109+
this->mNewState.surroundingText.textChangeCause
110+
);
74111
}
75112

76-
77-
if (this->mState.contentPurpose != this->mNewState.contentPurpose){
78-
emit contentPurposeChanged(this->mNewState.contentPurpose);
113+
if (this->mState.contentHint != oldState.contentHint) {
114+
emit contentHintChanged();
79115
}
80116

81-
this->mState = this->mNewState;
117+
if (this->mState.contentPurpose != oldState.contentPurpose) {
118+
emit contentPurposeChanged();
119+
}
82120
}
83121

84122
void InputMethodHandle::zwp_input_method_v2_unavailable() {

src/wayland/input_method/input_method.hpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,27 @@ class InputMethodHandle
3535
[[nodiscard]] bool isActive() const;
3636
[[nodiscard]] bool isAvailable() const;
3737

38+
[[nodiscard]] const QString& surroundingText() const;
39+
[[nodiscard]] uint32_t surroundingTextCursor() const;
40+
[[nodiscard]] uint32_t surroundingTextAnchor() const;
41+
42+
[[nodiscard]] ContentHint contentHint() const;
43+
[[nodiscard]] ContentPurpose contentPurpose() const;
44+
3845
signals:
3946
void activated();
4047
void deactivated();
4148

42-
void contentHintChanged(ContentHint);
43-
void contentPurposeChanged(ContentPurpose);
49+
void surroundingTextChanged(TextChangeCause textChangeCause);
50+
51+
void contentHintChanged();
52+
void contentPurposeChanged();
4453

4554
private:
4655
void zwp_input_method_v2_activate() override;
4756
void zwp_input_method_v2_deactivate() override;
57+
void zwp_input_method_v2_surrounding_text(const QString& text, uint32_t cursor, uint32_t anchor) override;
58+
void zwp_input_method_v2_text_change_cause(uint32_t cause) override;
4859
void zwp_input_method_v2_content_type(uint32_t hint, uint32_t purpose) override;
4960
void zwp_input_method_v2_done() override;
5061
void zwp_input_method_v2_unavailable() override;
@@ -54,6 +65,15 @@ class InputMethodHandle
5465

5566
struct State {
5667
bool activated = false;
68+
69+
struct SurroundingText {
70+
QString text = "";
71+
uint32_t cursor = 0;
72+
uint32_t anchor = 0;
73+
TextChangeCause textChangeCause = TextChangeCause::INPUT_METHOD;
74+
bool operator==(const SurroundingText& other) const = default;
75+
} surroundingText;
76+
5777
ContentHint contentHint = ContentHint::NONE;
5878
ContentPurpose contentPurpose = ContentPurpose::NORMAL;
5979
};

src/wayland/input_method/qml.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,19 @@ void InputMethod::getInput() {
8181
this->handle.get(),
8282
&InputMethodHandle::contentHintChanged,
8383
this,
84-
&InputMethod::onContentHintChanged
84+
&InputMethod::contentHintChanged
8585
);
8686
QObject::connect(
8787
this->handle.get(),
8888
&InputMethodHandle::contentPurposeChanged,
8989
this,
90-
&InputMethod::onContentPurposeChanged
90+
&InputMethod::contentPurposeChanged
91+
);
92+
QObject::connect(
93+
this->handle.get(),
94+
&InputMethodHandle::surroundingTextChanged,
95+
this,
96+
&InputMethod::surroundingTextChanged
9197
);
9298

9399
emit hasInputChanged();
@@ -148,28 +154,28 @@ void InputMethod::handleKeyboardActive() {
148154
}
149155
}
150156

157+
const QString& InputMethod::surroundingText() const {
158+
return handle->surroundingText();
159+
}
160+
uint32_t InputMethod::surroundingTextCursor() const {
161+
return handle->surroundingTextCursor();
162+
}
163+
uint32_t InputMethod::surroundingTextAnchor() const {
164+
return handle->surroundingTextAnchor();
165+
}
166+
151167
QMLContentHint::Enum InputMethod::contentHint() const {
152-
return this->mContentHint;
168+
return this->handle->contentHint();
153169
}
154170
QMLContentPurpose::Enum InputMethod::contentPurpose() const {
155-
return this->mContentPurpose;
171+
return this->handle->contentPurpose();
156172
}
157173

158174
void InputMethod::onHandleActiveChanged() {
159175
this->handleKeyboardActive();
160176
emit activeChanged();
161177
}
162178

163-
void InputMethod::onContentHintChanged(QMLContentHint::Enum contentHint) {
164-
this->mContentHint = contentHint;
165-
emit contentHintChanged();
166-
}
167-
168-
void InputMethod::onContentPurposeChanged(QMLContentPurpose::Enum contentPurpose){
169-
this->mContentPurpose = contentPurpose;
170-
emit contentPurposeChanged();
171-
}
172-
173179
Keyboard::Keyboard(QObject* parent): QObject(parent) {}
174180

175181
void Keyboard::setKeyboard(QPointer<InputMethodKeyboardGrab> keyboard) {

src/wayland/input_method/qml.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class InputMethod: public QObject {
6666
Q_PROPERTY(bool hasInput READ hasInput NOTIFY hasInputChanged);
6767
/// If the input method has grabbed the keyboard
6868
Q_PROPERTY(bool hasKeyboard READ hasKeyboard NOTIFY hasKeyboardChanged);
69+
/// The text around the where we will insert
70+
Q_PROPERTY(QString surroundingText READ surroundingText NOTIFY surroundingTextChanged);
71+
Q_PROPERTY(uint32_t surroundingTextCurosr READ surroundingTextCursor NOTIFY surroundingTextChanged);
72+
Q_PROPERTY(uint32_t surroundingTextAnchor READ surroundingTextAnchor NOTIFY surroundingTextChanged);
6973
/// The content_hint of the text input see https://wayland.app/protocols/text-input-unstable-v3#zwp_text_input_v3:enum:content_hint
7074
Q_PROPERTY(QMLContentHint::Enum contentHint READ contentHint NOTIFY contentHintChanged);
7175
/// The content_purpose of the text input see https://wayland.app/protocols/text-input-unstable-v3#zwp_text_input_v3:enum:content_purpose
@@ -122,6 +126,10 @@ class InputMethod: public QObject {
122126
/// Releases the grabbed keyboard so it can be used normally.
123127
Q_INVOKABLE void releaseKeyboard();
124128

129+
Q_INVOKABLE [[nodiscard]] const QString& surroundingText() const;
130+
Q_INVOKABLE [[nodiscard]] uint32_t surroundingTextCursor() const;
131+
Q_INVOKABLE [[nodiscard]] uint32_t surroundingTextAnchor() const;
132+
125133
Q_INVOKABLE [[nodiscard]] QMLContentHint::Enum contentHint() const;
126134
Q_INVOKABLE [[nodiscard]] QMLContentPurpose::Enum contentPurpose() const;
127135

@@ -134,22 +142,18 @@ class InputMethod: public QObject {
134142
void contentHintChanged();
135143
void contentPurposeChanged();
136144

145+
void surroundingTextChanged(QMLTextChangeCause::Enum textChangeCause);
146+
137147
private slots:
138148
void onHandleActiveChanged();
139149

140-
void onContentHintChanged(QMLContentHint::Enum contentHint);
141-
void onContentPurposeChanged(QMLContentPurpose::Enum contentPurpose);
142-
143150
private:
144151
void handleKeyboardActive();
145152

146153
QPointer<impl::InputMethodHandle> handle;
147154
Keyboard* keyboard = nullptr;
148155
QQmlComponent* mKeyboardComponent = nullptr;
149156

150-
QMLContentHint::Enum mContentHint;
151-
QMLContentPurpose::Enum mContentPurpose;
152-
153157
bool mClearPreeditOnKeyboardRelease = true;
154158
};
155159

src/wayland/input_method/qml_helpers.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ KeyboardTextEdit::KeyboardTextEdit(QObject* parent): Keyboard(parent) {
1414
QObject::connect(this, &Keyboard::directionPress, this, &KeyboardTextEdit::onDirectionPress);
1515
QObject::connect(this, &Keyboard::backspacePress, this, &KeyboardTextEdit::onBackspacePress);
1616
QObject::connect(this, &Keyboard::deletePress, this, &KeyboardTextEdit::onDeletePress);
17+
18+
auto* inputMethod = dynamic_cast<InputMethod*>(parent);
19+
if (inputMethod)
20+
QObject::connect(inputMethod, &InputMethod::surroundingTextChanged, this, &KeyboardTextEdit::onSurroundingTextChanged);
1721
}
1822

1923
QJSValue KeyboardTextEdit::transform() const { return this->mTransform; }
@@ -97,4 +101,10 @@ void KeyboardTextEdit::onReturnPress() {
97101
inputMethod->releaseKeyboard();
98102
}
99103

104+
void KeyboardTextEdit::onSurroundingTextChanged(QMLTextChangeCause::Enum textChangeCause) {
105+
if (textChangeCause == QMLTextChangeCause::OTHER) {
106+
this->setEditText("");
107+
}
108+
}
109+
100110
} // namespace qs::wayland::input_method

src/wayland/input_method/qml_helpers.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ private slots:
6969
void onDirectionPress(QMLDirectionKey::Enum direction);
7070
void onBackspacePress();
7171
void onDeletePress();
72+
void onSurroundingTextChanged(QMLTextChangeCause::Enum textChangeCause);
7273

7374
private:
7475
void updatePreedit();

0 commit comments

Comments
 (0)