summaryrefslogtreecommitdiffstats
path: root/src/compositor/extensions/qwaylandtextinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/extensions/qwaylandtextinput.cpp')
-rw-r--r--src/compositor/extensions/qwaylandtextinput.cpp105
1 files changed, 69 insertions, 36 deletions
diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp
index 6be9c0cde..933f31208 100644
--- a/src/compositor/extensions/qwaylandtextinput.cpp
+++ b/src/compositor/extensions/qwaylandtextinput.cpp
@@ -1,31 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwaylandtextinput.h"
#include "qwaylandtextinput_p.h"
@@ -36,6 +10,7 @@
#include "qwaylandsurface.h"
#include "qwaylandview.h"
#include "qwaylandinputmethodeventbuilder_p.h"
+#include "qwaylandinputmethodcontrol.h"
#include <QGuiApplication>
#include <QInputMethodEvent>
@@ -130,10 +105,10 @@ void QWaylandTextInputPrivate::sendInputMethodEvent(QInputMethodEvent *event)
if (event->replacementLength() > 0 || event->replacementStart() != 0) {
// Remove replacement
- afterCommit.cursorPosition = qBound(0, afterCommit.cursorPosition + event->replacementStart(), afterCommit.surroundingText.length());
+ afterCommit.cursorPosition = qBound(0, afterCommit.cursorPosition + event->replacementStart(), afterCommit.surroundingText.size());
afterCommit.surroundingText.remove(afterCommit.cursorPosition,
qMin(event->replacementLength(),
- afterCommit.surroundingText.length() - afterCommit.cursorPosition));
+ afterCommit.surroundingText.size() - afterCommit.cursorPosition));
if (event->replacementStart() <= 0 && (event->replacementLength() >= -event->replacementStart())) {
const int selectionStart = qMin(currentState->cursorPosition, currentState->anchorPosition);
@@ -149,7 +124,7 @@ void QWaylandTextInputPrivate::sendInputMethodEvent(QInputMethodEvent *event)
// Insert commit string
afterCommit.surroundingText.insert(afterCommit.cursorPosition, event->commitString());
- afterCommit.cursorPosition += event->commitString().length();
+ afterCommit.cursorPosition += event->commitString().size();
afterCommit.anchorPosition = afterCommit.cursorPosition;
for (const QInputMethodEvent::Attribute &attribute : event->attributes()) {
@@ -194,13 +169,22 @@ void QWaylandTextInputPrivate::sendKeyEvent(QKeyEvent *event)
if (!focusResource || !focusResource->handle)
return;
- // TODO add support for modifiers
+ uint mods = 0;
+ const auto &qtMods = event->modifiers();
+ if (qtMods & Qt::ShiftModifier)
+ mods |= shiftModifierMask;
+ if (qtMods & Qt::ControlModifier)
+ mods |= controlModifierMask;
+ if (qtMods & Qt::AltModifier)
+ mods |= altModifierMask;
+ if (qtMods & Qt::MetaModifier)
+ mods |= metaModifierMask;
#if QT_CONFIG(xkbcommon)
for (xkb_keysym_t keysym : QXkbCommon::toKeysym(event)) {
send_keysym(focusResource->handle, event->timestamp(), keysym,
event->type() == QEvent::KeyPress ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED,
- 0);
+ mods);
}
#else
Q_UNUSED(event);
@@ -313,9 +297,24 @@ void QWaylandTextInputPrivate::setFocus(QWaylandSurface *surface)
focus = surface;
}
+void QWaylandTextInputPrivate::sendModifiersMap(const QByteArray &modifiersMap)
+{
+ send_modifiers_map(focusResource->handle, modifiersMap);
+}
+
+#if !QT_CONFIG(xkbcommon)
+#define XKB_MOD_NAME_SHIFT "Shift"
+#define XKB_MOD_NAME_CTRL "Control"
+#define XKB_MOD_NAME_ALT "Mod1"
+#define XKB_MOD_NAME_LOGO "Mod4"
+#endif
void QWaylandTextInputPrivate::zwp_text_input_v2_bind_resource(Resource *resource)
{
- send_modifiers_map(resource->handle, QByteArray(""));
+ QByteArray modifiers = XKB_MOD_NAME_SHIFT + QByteArray(1, '\0');
+ modifiers += XKB_MOD_NAME_CTRL + QByteArray(1, '\0');
+ modifiers += XKB_MOD_NAME_ALT + QByteArray(1, '\0');
+ modifiers += XKB_MOD_NAME_LOGO + QByteArray(1, '\0');
+ send_modifiers_map(resource->handle, modifiers);
}
void QWaylandTextInputPrivate::zwp_text_input_v2_destroy_resource(Resource *resource)
@@ -335,6 +334,11 @@ void QWaylandTextInputPrivate::zwp_text_input_v2_enable(Resource *resource, wl_r
QWaylandSurface *s = QWaylandSurface::fromResource(surface);
enabledSurfaces.insert(resource, s);
+
+ QWaylandInputMethodControl *control = s->inputMethodControl();
+ if (control)
+ control->updateTextInput();
+
emit q->surfaceEnabled(s);
}
@@ -388,9 +392,9 @@ void QWaylandTextInputPrivate::zwp_text_input_v2_update_state(Resource *resource
Qt::InputMethodQueries queries;
if (flags == update_state_change) {
- queries = currentState->mergeChanged(*pendingState.data());
+ queries = currentState->mergeChanged(*pendingState);
} else {
- queries = pendingState->updatedQueries(*currentState.data());
+ queries = pendingState->updatedQueries(*currentState);
currentState.swap(pendingState);
}
@@ -601,4 +605,33 @@ QByteArray QWaylandTextInput::interfaceName()
return QWaylandTextInputPrivate::interfaceName();
}
+
+void QWaylandTextInput::sendModifiersMap(const QByteArray &modifiersMap)
+{
+ Q_D(QWaylandTextInput);
+
+ const QList<QByteArray> modifiers = modifiersMap.split('\0');
+
+ int numModifiers = modifiers.size();
+ if (modifiers.last().isEmpty())
+ numModifiers--;
+
+ for (int i = 0; i < numModifiers; ++i) {
+ const auto modString = modifiers.at(i);
+ if (modString == XKB_MOD_NAME_SHIFT)
+ d->shiftModifierMask = 1 << i;
+ else if (modString == XKB_MOD_NAME_CTRL)
+ d->controlModifierMask = 1 << i;
+ else if (modString == XKB_MOD_NAME_ALT)
+ d->altModifierMask = 1 << i;
+ else if (modString == XKB_MOD_NAME_LOGO)
+ d->metaModifierMask = 1 << i;
+ else
+ qCDebug(qLcWaylandCompositorInputMethods) << "unsupported modifier name " << modString;
+ }
+ d->sendModifiersMap(modifiersMap);
+}
+
QT_END_NAMESPACE
+
+#include "moc_qwaylandtextinput.cpp"