textinputv3: implement enableSurface() and disableSurface()
When enter() happens, it got enabled unconditionally. Then in QWaylandInputContext::setFocusObject(), we need to enable() or disable() it based on real situation.(If previous enter is not valid on the QObject, it will be disabled by disableSurface().) It fixes the issue for wayfire and kwin/plasma 6. Sway still has issues with input method events with popup menu, with and without this patch.(Sway doesn't make keyboard_leave/enter after surface_enter of popups.) See also https://github.com/swaywm/sway/issues/4406 Fixes: QTBUG-132196 Pick-to: 6.9 6.8 Done-with: Liang Qi <liang.qi@qt.io> Change-Id: I5b29a86e0256868c8bcbe48f936c09ee013728a6 Reviewed-by: Liang Qi <liang.qi@qt.io>
This commit is contained in:
parent
005927d089
commit
c57da9bb0a
@ -189,25 +189,30 @@ void QWaylandInputContext::setFocusObject(QObject *object)
|
||||
|
||||
QWindow *window = QGuiApplication::focusWindow();
|
||||
|
||||
if (mCurrentWindow && mCurrentWindow->handle()) {
|
||||
if (mCurrentWindow.data() != window || !inputMethodAccepted()) {
|
||||
auto *surface = static_cast<QWaylandWindow *>(mCurrentWindow->handle())->wlSurface();
|
||||
if (window && window->handle()) {
|
||||
if (mCurrentWindow.data() != window) {
|
||||
if (!inputMethodAccepted()) {
|
||||
auto *surface = static_cast<QWaylandWindow *>(window->handle())->wlSurface();
|
||||
if (surface)
|
||||
inputInterface->disableSurface(surface);
|
||||
mCurrentWindow.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (window && window->handle() && inputMethodAccepted()) {
|
||||
if (mCurrentWindow.data() != window) {
|
||||
} else {
|
||||
auto *surface = static_cast<QWaylandWindow *>(window->handle())->wlSurface();
|
||||
if (surface) {
|
||||
inputInterface->enableSurface(surface);
|
||||
mCurrentWindow = window;
|
||||
} else {
|
||||
mCurrentWindow.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mCurrentWindow)
|
||||
inputInterface->updateState(Qt::ImQueryAll, QWaylandTextInputInterface::update_state_enter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCurrentWindow)
|
||||
mCurrentWindow.clear();
|
||||
}
|
||||
|
||||
QWaylandTextInputInterface *QWaylandInputContext::textInput() const
|
||||
|
@ -40,12 +40,16 @@ const Qt::InputMethodQueries supportedQueries3 = Qt::ImEnabled |
|
||||
Qt::ImCursorRectangle;
|
||||
}
|
||||
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_enter(struct ::wl_surface *surface)
|
||||
void QWaylandTextInputv3::enableSurface(::wl_surface *surface)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << m_surface << surface;
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << surface;
|
||||
|
||||
if (m_surface == surface)
|
||||
return; // already enabled
|
||||
if (m_surface)
|
||||
qCWarning(qLcQpaWaylandTextInput()) << Q_FUNC_INFO << "Try to enable surface" << surface << "with focusing surface" << m_surface;
|
||||
|
||||
m_surface = surface;
|
||||
|
||||
m_pendingPreeditString.clear();
|
||||
m_pendingCommitString.clear();
|
||||
m_pendingDeleteBeforeText = 0;
|
||||
@ -55,27 +59,51 @@ void QWaylandTextInputv3::zwp_text_input_v3_enter(struct ::wl_surface *surface)
|
||||
updateState(supportedQueries3, update_state_enter);
|
||||
}
|
||||
|
||||
void QWaylandTextInputv3::disableSurface(::wl_surface *surface)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << surface;
|
||||
|
||||
if (!m_surface)
|
||||
return; // already disabled
|
||||
if (m_surface != surface)
|
||||
qCWarning(qLcQpaWaylandTextInput()) << Q_FUNC_INFO << "Try to disable surface" << surface << "with focusing surface" << m_surface;
|
||||
|
||||
m_currentPreeditString.clear();
|
||||
m_surface = nullptr;
|
||||
disable();
|
||||
commit();
|
||||
}
|
||||
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_enter(struct ::wl_surface *surface)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << m_surface << surface;
|
||||
|
||||
if (m_surface)
|
||||
qCWarning(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "Got enter event without leaving a surface " << m_surface;
|
||||
|
||||
enableSurface(surface);
|
||||
}
|
||||
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_leave(struct ::wl_surface *surface)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO;
|
||||
|
||||
if (m_surface != surface) {
|
||||
qCWarning(qLcQpaWaylandTextInput()) << Q_FUNC_INFO << "Got leave event for surface" << surface << "focused surface" << m_surface;
|
||||
return;
|
||||
}
|
||||
if (!m_surface)
|
||||
return; // Nothing to leave
|
||||
|
||||
m_currentPreeditString.clear();
|
||||
if (m_surface != surface)
|
||||
qCWarning(qLcQpaWaylandTextInput()) << Q_FUNC_INFO << "Got leave event for surface" << surface << "with focusing surface" << m_surface;
|
||||
|
||||
m_surface = nullptr;
|
||||
|
||||
disable();
|
||||
commit();
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "Done";
|
||||
disableSurface(surface);
|
||||
}
|
||||
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_preedit_string(const QString &text, int32_t cursorBegin, int32_t cursorEnd)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << text << cursorBegin << cursorEnd;
|
||||
if (!m_surface) {
|
||||
qCWarning(qLcQpaWaylandTextInput) << "Got preedit_string event without entering a surface";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QGuiApplication::focusObject())
|
||||
return;
|
||||
@ -88,6 +116,10 @@ void QWaylandTextInputv3::zwp_text_input_v3_preedit_string(const QString &text,
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_commit_string(const QString &text)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << text;
|
||||
if (!m_surface) {
|
||||
qCWarning(qLcQpaWaylandTextInput) << "Got commit_string event without entering a surface";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QGuiApplication::focusObject())
|
||||
return;
|
||||
@ -98,6 +130,10 @@ void QWaylandTextInputv3::zwp_text_input_v3_commit_string(const QString &text)
|
||||
void QWaylandTextInputv3::zwp_text_input_v3_delete_surrounding_text(uint32_t beforeText, uint32_t afterText)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << beforeText << afterText;
|
||||
if (!m_surface) {
|
||||
qCWarning(qLcQpaWaylandTextInput) << "Got delete_surrounding_text event without entering a surface";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!QGuiApplication::focusObject())
|
||||
return;
|
||||
@ -110,6 +146,9 @@ void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial)
|
||||
{
|
||||
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "with serial" << serial << m_currentSerial;
|
||||
|
||||
if (!m_surface)
|
||||
return;
|
||||
|
||||
// This is a case of double click.
|
||||
// text_input_v3 will ignore this done signal and just keep the selection of the clicked word.
|
||||
if (m_cursorPos != m_anchorPos && (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0)) {
|
||||
|
@ -48,10 +48,8 @@ public:
|
||||
QLocale locale() const override;
|
||||
Qt::LayoutDirection inputDirection() const override;
|
||||
|
||||
// doing nothing in zwp_text_input_v3.
|
||||
// enter() and leave() takes the role to enable/disable the surface
|
||||
void enableSurface(::wl_surface *) override {};
|
||||
void disableSurface(::wl_surface *) override {};
|
||||
void enableSurface(::wl_surface *) override;
|
||||
void disableSurface(::wl_surface *) override;
|
||||
|
||||
protected:
|
||||
void zwp_text_input_v3_enter(struct ::wl_surface *surface) override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user