Skip to content

Conversation

@CMurtagh-LGTM
Copy link
Contributor

@CMurtagh-LGTM CMurtagh-LGTM commented Aug 22, 2025

  • Popup surface This PR is already large, will add in future PR.
  • Handle surrounding_text, text_change_cause and content_type events somehow.
  • Key repeat
  • Documentation

Do we want to also expose the virtual keyboard so people can create their own clients?

Popup surface and qml virtual keyboard will be in future PRs.

@outfoxxed
Copy link
Member

outfoxxed commented Sep 3, 2025

Exposing virtual keyboard would be a good idea, but as a separate PR.
Oh I see it was added. Is this ready for review?

@CMurtagh-LGTM
Copy link
Contributor Author

CMurtagh-LGTM commented Sep 3, 2025

I still need to do a couple things - especially documentation. I'll add the popup screen and exposing virtual keyboard in future prs since this one is already quite large.

@CMurtagh-LGTM CMurtagh-LGTM force-pushed the cmurtagh/inputmethod branch 2 times, most recently from b265756 to 7054e2d Compare September 5, 2025 05:18
@CMurtagh-LGTM CMurtagh-LGTM marked this pull request as ready for review September 5, 2025 05:36
@outfoxxed outfoxxed force-pushed the master branch 3 times, most recently from a92879d to 9bb2c04 Compare October 4, 2025 20:00
@CMurtagh-LGTM
Copy link
Contributor Author

Sorry I haven't updated in a while.
This pull request is good to go.

I have a separate branch that I have been working on the adding the popup surface functionality however it looks like I need to use the private qt headers, which I have not yet been able to work out.

@outfoxxed
Copy link
Member

Looks like CI is broken here, can you rebase on master? For private qt headers you should just be able to import them if you add a dependency on the private qt module.

Copy link
Member

@outfoxxed outfoxxed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed most of it that didn't seem likely to greatly change. It would also be useful if you included a couple tests. They dont have to be complex or automatic, just some QML files we can run to make sure its still working.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this protocol included directly instead of from w-p?

Comment on lines +82 to +83
/// The @@Keyboard$ that will handle the grabbed keyboard.
/// Use @@KeyboardTextEdit$ for most cases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the $ if there's a space, period, or comma after the reference

Comment on lines +101 to +102
Q_INVOKABLE void
sendPreeditString(const QString& text, int32_t cursorBegin = -1, int32_t cursorEnd = -1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation generator doesn't properly support default args, so probably make two forms of this: sendPreeditString(text, begin, end), sendPreeditString(text)

Comment on lines +122 to +123
/// @@hasKeyboard$
Q_INVOKABLE [[nodiscard]] bool hasKeyboard() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property getters dont need to be invokable


key += WAYLAND_KEY_OFFSET;

#if INPUT_METHOD_PRINT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am glad you added logs but instead of ifdefing them, use logging categories (grep for QS_LOGGING_CATEGORY and qCDebug)

Comment on lines +17 to +21
InputMethodManager* InputMethodManager::instance() {
// The OS should free this memory when we exit
static auto* instance = new InputMethodManager();
return instance;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is unnnecessary.

Return nullptr when not initialized.

Comment on lines +25 to +44
void InputMethod::sendString(const QString& text) {
if (!this->isActive()) return;

this->handle->commitString(text);
this->handle->commit();
}

void InputMethod::sendPreeditString(const QString& text, int32_t cursorBegin, int32_t cursorEnd) {
if (!this->isActive()) return;

this->handle->sendPreeditString(text, cursorBegin, cursorEnd);
this->handle->commit();
}

void InputMethod::deleteText(int before, int after) {
if (!this->isActive()) return;

this->handle->deleteText(before, after);
this->handle->commit();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer commit to be separated for this one. The pre-edit string and cursor region may be better exposed as properties instead of a function as well.

Comment on lines +48 to +60
QQmlComponent* InputMethod::keyboardComponent() const { return this->mKeyboardComponent; }
void InputMethod::setKeyboardComponent(QQmlComponent* keyboardComponent) {
if (this->mKeyboardComponent == keyboardComponent) return;
this->mKeyboardComponent = keyboardComponent;
emit this->keyboardComponentChanged();

if (this->keyboard) {
this->keyboard->deleteLater();
this->keyboard = nullptr;
}

this->handleKeyboardActive();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are components even involved in this? Shouldn't we just expose the keyboard as a member of the inputmethod which is null if we haven't grabbed it?

Comment on lines +17 to +94
QString QMLContentHint::toString(Enum contentHint) {
QString string = "";

bool first = true;

if (contentHint & Completion) {
if (!first) {
string += " | ";
}
string += "Completion";
first = false;
}
if (contentHint & Spellcheck) {
if (!first) {
string += " | ";
}
string += "Spellcheck";
first = false;
}
if (contentHint & AutoCapitalization) {
if (!first) {
string += " | ";
}
string += "AutoCapitalization";
first = false;
}
if (contentHint & Lowercase) {
if (!first) {
string += " | ";
}
string += "Lowercase";
first = false;
}
if (contentHint & Uppercase) {
if (!first) {
string += " | ";
}
string += "Uppercase";
first = false;
}
if (contentHint & Titlecase) {
if (!first) {
string += " | ";
}
string += "Titlecase";
first = false;
}
if (contentHint & HiddenText) {
if (!first) {
string += " | ";
}
string += "HiddenText";
first = false;
}
if (contentHint & SensitiveData) {
if (!first) {
string += " | ";
}
string += "SensitiveData";
first = false;
}
if (contentHint & Latin) {
if (!first) {
string += " | ";
}
string += "Latin";
first = false;
}
if (contentHint & Multiline) {
if (!first) {
string += " | ";
}
string += "Multiline";
first = false;
}

if (string == "") string = "None";
return string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a list and join it instead of if (!first)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Might be better to split this
  2. Include from w-p instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants