diff options
Diffstat (limited to 'src/compositor/compositor_api/qwaylandseat.cpp')
-rw-r--r-- | src/compositor/compositor_api/qwaylandseat.cpp | 207 |
1 files changed, 162 insertions, 45 deletions
diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index 0be10f450..0e7df0ec0 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -1,31 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** 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 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "qwaylandseat.h" #include "qwaylandseat_p.h" @@ -41,6 +15,7 @@ #include <QtWaylandCompositor/QWaylandKeymap> #include <QtWaylandCompositor/private/qwaylandseat_p.h> #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwaylandkeyboard_p.h> #if QT_CONFIG(wayland_datadevice) #include <QtWaylandCompositor/private/qwldatadevice_p.h> #endif @@ -48,6 +23,8 @@ #include "extensions/qwlqtkey_p.h" #include "extensions/qwaylandtextinput.h" +#include "extensions/qwaylandtextinputv3.h" +#include "extensions/qwaylandqttextinputmethod.h" QT_BEGIN_NAMESPACE @@ -136,6 +113,7 @@ void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t i /*! * \qmltype WaylandSeat + * \instantiates QWaylandSeat * \inqmlmodule QtWayland.Compositor * \since 5.8 * \brief Provides access to keyboard, mouse, and touch input. @@ -177,6 +155,9 @@ QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capab d->capabilities = capabilityFlags; if (compositor->isCreated()) initialize(); + + // Support deprecated signal for backward compatibility + connect(this, &QWaylandSeat::cursorSurfaceRequested, this, &QWaylandSeat::cursorSurfaceRequest); } /*! @@ -296,7 +277,7 @@ uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface, int id, const Q } /*! - * \qmlmethod uint QtWaylandCompositor::WaylandSeat::sendTouchPointPressed(WaylandSurface surface, int id, point position) + * \qmlmethod uint QtWayland.Compositor::WaylandSeat::sendTouchPointPressed(WaylandSurface surface, int id, point position) * * Sends a touch pressed event for the touch point \a id on \a surface with * position \a position. @@ -330,7 +311,7 @@ uint QWaylandSeat::sendTouchPointPressed(QWaylandSurface *surface, int id, const } /*! - * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchPointReleased(WaylandSurface surface, int id, point position) + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendTouchPointReleased(WaylandSurface surface, int id, point position) * * Sends a touch released event for the touch point \a id on \a surface with * position \a position. @@ -364,7 +345,7 @@ uint QWaylandSeat::sendTouchPointReleased(QWaylandSurface *surface, int id, cons } /*! - * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchPointMoved(WaylandSurface surface, int id, point position) + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendTouchPointMoved(WaylandSurface surface, int id, point position) * * Sends a touch moved event for the touch point \a id on \a surface with * position \a position. @@ -398,7 +379,7 @@ uint QWaylandSeat::sendTouchPointMoved(QWaylandSurface *surface, int id, const Q } /*! - * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchFrameEvent(WaylandClient client) + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendTouchFrameEvent(WaylandClient client) * * Sends a frame event to the touch device of a \a client to indicate the end * of a series of touch up, down, and motion events. @@ -416,7 +397,7 @@ void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client) } /*! - * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchCancelEvent(WaylandClient client) + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendTouchCancelEvent(WaylandClient client) * * Sends a cancel event to the touch device of a \a client. */ @@ -434,7 +415,7 @@ void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client) /*! * Sends the \a event to the specified \a surface on the touch device. * - * \warning This API will automatically map \l QTouchEvent::TouchPoint::id to a + * \warning This API will automatically map \l QEventPoint::id() to a * sequential id before sending it to the client. It should therefore not be * used in combination with the other API using explicit ids, as collisions * might occur. @@ -451,6 +432,11 @@ void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *eve /*! * Sends the \a event to the keyboard device. + * + * \note The \a event should correspond to an actual keyboard key in the current mapping. + * For example, \c Qt::Key_Exclam is normally not a separate key: with most keyboards the + * exclamation mark is produced with Shift + 1. In that case, to send an exclamation mark + * key press event, use \c{QKeyEvent(QEvent::KeyPress, Qt::Key_1, Qt::ShiftModifier)}. */ void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) { @@ -464,10 +450,30 @@ void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) #if QT_CONFIG(im) if (keyboardFocus()->inputMethodControl()->enabled() && event->nativeScanCode() == 0) { - QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); - if (textInput) { - textInput->sendKeyEvent(event); - return; + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) { + QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); + if (textInput) { + textInput->sendKeyEvent(event); + return; + } + } + + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) { + QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(this); + if (textInputMethod) { + textInputMethod->sendKeyEvent(event); + return; + } + } + + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) { + QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(this); + if (textInputV3 && !event->text().isEmpty()) { + // it will just commit the text for text-input-unstable-v3 when keyPress + if (event->type() == QEvent::KeyPress) + textInputV3->sendKeyEvent(event); + return; + } } } #endif @@ -487,22 +493,29 @@ void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event) return; } - if (event->type() == QEvent::KeyPress) + if (event->type() == QEvent::KeyPress) { + QWaylandKeyboardPrivate::get(d->keyboard.data())->checkAndRepairModifierState(event); d->keyboard->sendKeyPressEvent(scanCode); - else if (event->type() == QEvent::KeyRelease) + } else if (event->type() == QEvent::KeyRelease) { d->keyboard->sendKeyReleaseEvent(scanCode); + } } } /*! - * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendKeyEvent(int qtKey, bool pressed) + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendKeyEvent(int qtKey, bool pressed) * \since 5.12 * - * Sends a key press or release to the keyboard device. + * Sends a key press (if \a pressed is \c true) or release (if \a pressed is \c false) + * event of a key \a qtKey to the keyboard device. */ /*! - * Sends a key press or release to the keyboard device. + * Sends a key press (if \a pressed is \c true) or release (if \a pressed is \c false) + * event of a key \a qtKey to the keyboard device. + * + * \note This function does not support key events that require modifiers, such as \c Qt::Key_Exclam. + * Use \l{sendFullKeyEvent} instead. * * \since 5.12 */ @@ -525,6 +538,104 @@ void QWaylandSeat::sendKeyEvent(int qtKey, bool pressed) } /*! + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendUnicodeKeyPressEvent(uint unicode) + * \since 6.7 + * + * Sends a key press event of a UCS4 \a unicode through a text-input protocol. + * + * \note This function will not work properly if the client does not support the + * text-input protocol that the compositor supports. + */ + +/*! + * Sends a key press event of a UCS4 \a unicode through a text-input protocol. + * + * \note This function will not work properly if the client does not support the + * text-input protocol that the compositor supports. + * + * \sa {sendFullKeyEvent} {sendKeyEvent} + * + * \since 6.7 + */ +void QWaylandSeat::sendUnicodeKeyPressEvent(uint unicode) +{ + sendUnicodeKeyEvent(unicode, QEvent::KeyPress); +} + +/*! + * \qmlmethod void QtWayland.Compositor::WaylandSeat::sendUnicodeKeyReleaseEvent(uint unicode) + * \since 6.7 + * + * Sends a key release event of a UCS4 \a unicode through a text-input protocol. + * + * \note This function will not work properly if the client does not support the + * text-input protocol that the compositor supports. + */ + +/*! + * Sends a key release event of a UCS4 \a unicode through a text-input protocol. + * + * \note This function will not work properly if the client does not support the + * text-input protocol that the compositor supports. + * + * \sa {sendFullKeyEvent} {sendKeyEvent} + * + * \since 6.7 + */ +void QWaylandSeat::sendUnicodeKeyReleaseEvent(uint unicode) +{ + sendUnicodeKeyEvent(unicode, QEvent::KeyRelease); +} + +/*! + * \internal + * + * Sends an \a eventType for the UCS4 \a unicode through a text-input protocol. + */ +void QWaylandSeat::sendUnicodeKeyEvent(uint unicode, QEvent::Type eventType) +{ + if (!keyboardFocus()) { + qWarning("Can't send a unicode key event, no keyboard focus, fix the compositor"); + return; + } +#if QT_CONFIG(im) + QString text; + text += QChar::fromUcs4(static_cast<char32_t>(unicode)); + + QKeyEvent event(eventType, Qt::Key_unknown, Qt::KeyboardModifiers{}, text); + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV2)) { + QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); + if (textInput) { + textInput->sendKeyEvent(&event); + return; + } + } + + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::QtTextInputMethodV1)) { + QWaylandQtTextInputMethod *textInputMethod = QWaylandQtTextInputMethod::findIn(this); + if (textInputMethod) { + textInputMethod->sendKeyEvent(&event); + return; + } + } + + if (keyboardFocus()->client()->textInputProtocols().testFlag(QWaylandClient::TextInputProtocol::TextInputV3)) { + QWaylandTextInputV3 *textInputV3 = QWaylandTextInputV3::findIn(this); + if (textInputV3 && !text.isEmpty()) { + // it will just commit the text for text-input-unstable-v3 when keyPress + if (eventType == QEvent::KeyPress) + textInputV3->sendKeyEvent(&event); + return; + } + } +#else + Q_UNUSED(unicode); + Q_UNUSED(eventType); + qWarning() << "Can't send a unicode key event: Unable to find a text-input protocol."; +#endif +} + +/*! * Returns the keyboard for this input device. */ QWaylandKeyboard *QWaylandSeat::keyboard() const @@ -696,7 +807,7 @@ void QWaylandSeat::handleMouseFocusDestroyed() } -/*! \qmlsignal void QtWaylandCompositor::QWaylandSeat::keyboardFocusChanged(QWaylandSurface newFocus, QWaylandSurface oldFocus) +/*! \qmlsignal void QtWayland.Compositor::WaylandSeat::keyboardFocusChanged(QWaylandSurface newFocus, QWaylandSurface oldFocus) * * This signal is emitted when setKeyboardFocus() is called or when a WaylandQuickItem has focus * and the user starts pressing keys. @@ -716,7 +827,7 @@ void QWaylandSeat::handleMouseFocusDestroyed() * \a oldFocus has the surface that lost keyboard focus; or \c nullptr if no surface had focus. */ -/*! \qmlsignal void QtWaylandCompositor::QWaylandSeat::cursorSurfaceRequest(QWaylandSurface surface, int hotspotX, int hotspotY) +/*! \qmlsignal void QtWayland.Compositor::WaylandSeat::cursorSurfaceRequest(QWaylandSurface surface, int hotspotX, int hotspotY) * * This signal is emitted when the client has requested for a specific \a surface to be the mouse * cursor. For example, when the user hovers over a particular surface, and you want the cursor @@ -734,6 +845,10 @@ void QWaylandSeat::handleMouseFocusDestroyed() * This signal is emitted when the client has requested for a specific \a surface to be the mouse * cursor. For example, when the user hovers over a particular surface, and you want the cursor * to change into a resize arrow. + * + * Both \a hotspotX and \a hotspotY are offsets from the top-left of a pointer surface, where a + * click should happen. For example, if the requested cursor surface is an arrow, the parameters + * indicate where the arrow's tip is, on that surface. */ /*! @@ -757,3 +872,5 @@ void QWaylandSeat::handleMouseFocusDestroyed() */ QT_END_NAMESPACE + +#include "moc_qwaylandseat.cpp" |