summaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/CMakeLists.txt3
-rw-r--r--src/client/qwaylandbuffer.cpp7
-rw-r--r--src/client/qwaylandbuffer_p.h3
-rw-r--r--src/client/qwaylanddatadevice.cpp8
-rw-r--r--src/client/qwaylanddisplay.cpp5
-rw-r--r--src/client/qwaylanddisplay_p.h6
-rw-r--r--src/client/qwaylandextendedsurface.cpp92
-rw-r--r--src/client/qwaylandextendedsurface_p.h59
-rw-r--r--src/client/qwaylandnativeinterface.cpp1
-rw-r--r--src/client/qwaylandshellsurface.cpp1
-rw-r--r--src/client/qwaylandsurface.cpp10
-rw-r--r--src/client/qwaylandtextinputv3.cpp97
-rw-r--r--src/client/qwaylandtextinputv3_p.h7
-rw-r--r--src/client/qwaylandwindow.cpp29
-rw-r--r--src/client/qwaylandwindow_p.h3
15 files changed, 100 insertions, 231 deletions
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
index 300fd4ffa..4d0a106f6 100644
--- a/src/client/CMakeLists.txt
+++ b/src/client/CMakeLists.txt
@@ -9,7 +9,6 @@
qt_internal_add_module(WaylandClient
PLUGIN_TYPES wayland-graphics-integration-client wayland-inputdevice-integration wayland-decoration-client wayland-shell-integration
- GENERATE_CPP_EXPORTS
SOURCES
../shared/qwaylandinputmethodeventbuilder.cpp ../shared/qwaylandinputmethodeventbuilder_p.h
../shared/qwaylandmimehelper.cpp ../shared/qwaylandmimehelper_p.h
@@ -31,7 +30,6 @@ qt_internal_add_module(WaylandClient
qwaylanddecorationfactory.cpp qwaylanddecorationfactory_p.h
qwaylanddecorationplugin.cpp qwaylanddecorationplugin_p.h
qwaylanddisplay.cpp qwaylanddisplay_p.h
- qwaylandextendedsurface.cpp qwaylandextendedsurface_p.h
qwaylandfractionalscale.cpp qwaylandfractionalscale_p.h
qwaylandinputcontext.cpp qwaylandinputcontext_p.h
qwaylandtextinputv1.cpp qwaylandtextinputv1_p.h
@@ -100,7 +98,6 @@ qt6_generate_wayland_protocol_client_sources(WaylandClient
${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-key-unstable-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-text-input-method-unstable-v1.xml
${CMAKE_CURRENT_SOURCE_DIR}/../extensions/qt-windowmanager.xml
- ${CMAKE_CURRENT_SOURCE_DIR}/../extensions/surface-extension.xml
${CMAKE_CURRENT_SOURCE_DIR}/../extensions/touch-extension.xml
${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/hardware-integration.xml
${CMAKE_CURRENT_SOURCE_DIR}/hardwareintegration/../../extensions/server-buffer-extension.xml
diff --git a/src/client/qwaylandbuffer.cpp b/src/client/qwaylandbuffer.cpp
index 1907d5864..dd99b702b 100644
--- a/src/client/qwaylandbuffer.cpp
+++ b/src/client/qwaylandbuffer.cpp
@@ -31,6 +31,13 @@ void QWaylandBuffer::release(void *data, wl_buffer *)
QWaylandBuffer *self = static_cast<QWaylandBuffer *>(data);
self->mBusy = false;
self->mCommitted = false;
+ if (self->mDeleteOnRelease)
+ delete self;
+}
+
+void QWaylandBuffer::setDeleteOnRelease(bool deleteOnRelease)
+{
+ mDeleteOnRelease = deleteOnRelease;
}
const wl_buffer_listener QWaylandBuffer::listener = {
diff --git a/src/client/qwaylandbuffer_p.h b/src/client/qwaylandbuffer_p.h
index 3798ef3eb..c96f213b9 100644
--- a/src/client/qwaylandbuffer_p.h
+++ b/src/client/qwaylandbuffer_p.h
@@ -43,12 +43,15 @@ public:
void setCommitted() { mCommitted = true; }
bool committed() const { return mCommitted; }
+ void setDeleteOnRelease(bool deleteOnRelease);
+
protected:
struct wl_buffer *mBuffer = nullptr;
private:
bool mBusy = false;
bool mCommitted = false;
+ bool mDeleteOnRelease = false;
static void release(void *data, wl_buffer *);
static const wl_buffer_listener listener;
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
index a59b201f6..30bfb86c5 100644
--- a/src/client/qwaylanddatadevice.cpp
+++ b/src/client/qwaylanddatadevice.cpp
@@ -195,7 +195,7 @@ void QWaylandDataDevice::data_device_drop()
QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_dragWindow, dragData, m_dragPoint, supportedActions,
QGuiApplication::mouseButtons(),
- QGuiApplication::keyboardModifiers());
+ m_inputDevice->modifiers());
if (drag) {
auto drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
drag->setDropResponse(response);
@@ -230,7 +230,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface,
const QPlatformDragQtResponse &response = QWindowSystemInterface::handleDrag(
m_dragWindow, dragData, m_dragPoint, supportedActions, QGuiApplication::mouseButtons(),
- QGuiApplication::keyboardModifiers());
+ m_inputDevice->modifiers());
if (drag) {
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
}
@@ -243,7 +243,7 @@ void QWaylandDataDevice::data_device_leave()
if (m_dragWindow)
QWindowSystemInterface::handleDrag(m_dragWindow, nullptr, QPoint(), Qt::IgnoreAction,
QGuiApplication::mouseButtons(),
- QGuiApplication::keyboardModifiers());
+ m_inputDevice->modifiers());
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
if (!drag) {
@@ -274,7 +274,7 @@ void QWaylandDataDevice::data_device_motion(uint32_t time, wl_fixed_t x, wl_fixe
const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint, supportedActions,
QGuiApplication::mouseButtons(),
- QGuiApplication::keyboardModifiers());
+ m_inputDevice->modifiers());
if (drag) {
static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index e6ed0772f..f78bf2dd2 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -34,7 +34,6 @@
#include "qwaylandshellintegration_p.h"
#include "qwaylandclientbufferintegration_p.h"
-#include "qwaylandextendedsurface_p.h"
#include "qwaylandpointergestures_p.h"
#include "qwaylandsubsurface_p.h"
#include "qwaylandtouch_p.h"
@@ -642,10 +641,6 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
} else if (interface == QLatin1String(QWaylandDataDeviceManager::interface()->name)) {
mGlobals.dndSelectionHandler.reset(new QWaylandDataDeviceManager(this, version, id));
#endif
- } else if (interface == QLatin1String(QtWayland::qt_surface_extension::interface()->name)) {
- mGlobals.surfaceExtension.reset(
- new WithDestructor<QtWayland::qt_surface_extension, qt_surface_extension_destroy>(
- registry, id, 1));
} else if (interface == QLatin1String(QtWayland::wl_subcompositor::interface()->name)) {
mGlobals.subCompositor.reset(
new WithDestructor<QtWayland::wl_subcompositor, wl_subcompositor_destroy>(registry,
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 2fd176d84..b93a2ecc0 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -48,7 +48,6 @@ class QPlatformScreen;
class QPlatformPlaceholderScreen;
namespace QtWayland {
- class qt_surface_extension;
class zwp_text_input_manager_v1;
class zwp_text_input_manager_v2;
class zwp_text_input_manager_v3;
@@ -153,10 +152,6 @@ public:
return mGlobals.primarySelectionManager.get();
}
#endif
- QtWayland::qt_surface_extension *windowExtension() const
- {
- return mGlobals.surfaceExtension.get();
- }
#if QT_CONFIG(tabletevent)
QWaylandTabletManagerV2 *tabletManager() const
{
@@ -323,7 +318,6 @@ private:
#if QT_CONFIG(wayland_datadevice)
std::unique_ptr<QWaylandDataDeviceManager> dndSelectionHandler;
#endif
- std::unique_ptr<QtWayland::qt_surface_extension> surfaceExtension;
std::unique_ptr<QtWayland::wl_subcompositor> subCompositor;
std::unique_ptr<QWaylandTouchExtension> touchExtension;
std::unique_ptr<QWaylandQtKeyExtension> qtKeyExtension;
diff --git a/src/client/qwaylandextendedsurface.cpp b/src/client/qwaylandextendedsurface.cpp
deleted file mode 100644
index a61612ce8..000000000
--- a/src/client/qwaylandextendedsurface.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "qwaylandextendedsurface_p.h"
-
-#include "qwaylandwindow_p.h"
-
-#include "qwaylanddisplay_p.h"
-
-#include "qwaylandnativeinterface_p.h"
-
-#include <QtGui/QGuiApplication>
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qwindowsysteminterface.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWaylandClient {
-
-QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window)
- : QtWayland::qt_extended_surface(window->display()->windowExtension()->get_extended_surface(window->wlSurface()))
- , m_window(window)
-{
-}
-
-QWaylandExtendedSurface::~QWaylandExtendedSurface()
-{
- qt_extended_surface_destroy(object());
-}
-
-void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value)
-{
- QByteArray byteValue;
- QDataStream ds(&byteValue, QIODevice::WriteOnly);
- ds << value;
-
- update_generic_property(name, byteValue);
-}
-
-void QWaylandExtendedSurface::setContentOrientationMask(Qt::ScreenOrientations mask)
-{
- int32_t wlmask = 0;
- if (mask & Qt::PrimaryOrientation)
- wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
- if (mask & Qt::PortraitOrientation)
- wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
- if (mask & Qt::LandscapeOrientation)
- wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
- if (mask & Qt::InvertedPortraitOrientation)
- wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
- if (mask & Qt::InvertedLandscapeOrientation)
- wlmask |= QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
- set_content_orientation_mask(wlmask);
-}
-
-void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility)
-{
- m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility));
-}
-
-void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value)
-{
- QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size);
-
- QVariant variantValue;
- QDataStream ds(data);
- ds >> variantValue;
-
- m_window->setProperty(name, variantValue);
-}
-
-void QWaylandExtendedSurface::extended_surface_close()
-{
- QWindowSystemInterface::handleCloseEvent(m_window->window());
-}
-
-Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags)
-{
- uint wlFlags = 0;
-
- if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP;
- if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES;
- if (flags & Qt::BypassWindowManagerHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER;
-
- set_window_flags(wlFlags);
-
- return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures | Qt::BypassWindowManagerHint);
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/client/qwaylandextendedsurface_p.h b/src/client/qwaylandextendedsurface_p.h
deleted file mode 100644
index 0a7c6e5ad..000000000
--- a/src/client/qwaylandextendedsurface_p.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef QWAYLANDEXTENDEDSURFACE_H
-#define QWAYLANDEXTENDEDSURFACE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QString>
-#include <QtCore/QVariant>
-#include <QtCore/QMap> // for QVariantMap
-
-#include <QtWaylandClient/qtwaylandclientglobal.h>
-
-#include <QtWaylandClient/private/qwayland-surface-extension.h>
-#include <QtCore/private/qglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWaylandClient {
-
-class QWaylandDisplay;
-class QWaylandWindow;
-
-class Q_WAYLANDCLIENT_EXPORT QWaylandExtendedSurface : public QtWayland::qt_extended_surface
-{
-public:
- QWaylandExtendedSurface(QWaylandWindow *window);
- ~QWaylandExtendedSurface() override;
-
- void setContentOrientationMask(Qt::ScreenOrientations mask);
-
- void updateGenericProperty(const QString &name, const QVariant &value);
-
- Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
-
-private:
- void extended_surface_onscreen_visibility(int32_t visibility) override;
- void extended_surface_set_generic_property(const QString &name, wl_array *value) override;
- void extended_surface_close() override;
-
- QWaylandWindow *m_window = nullptr;
- QVariantMap m_properties;
-};
-
-}
-
-QT_END_NAMESPACE
-
-#endif // QWAYLANDEXTENDEDSURFACE_H
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
index 601f833aa..e1586d244 100644
--- a/src/client/qwaylandnativeinterface.cpp
+++ b/src/client/qwaylandnativeinterface.cpp
@@ -6,7 +6,6 @@
#include "qwaylandwindow_p.h"
#include "qwaylandshellintegration_p.h"
#include "qwaylandsubsurface_p.h"
-#include "qwaylandextendedsurface_p.h"
#include "qwaylandintegration_p.h"
#include "qwaylanddisplay_p.h"
#include "qwaylandwindowmanagerintegration_p.h"
diff --git a/src/client/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp
index 77d6b97a9..fde1e1d3f 100644
--- a/src/client/qwaylandshellsurface.cpp
+++ b/src/client/qwaylandshellsurface.cpp
@@ -3,7 +3,6 @@
#include "qwaylandshellsurface_p.h"
#include "qwaylandwindow_p.h"
-#include "qwaylandextendedsurface_p.h"
#include "qwaylandinputdevice_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/client/qwaylandsurface.cpp b/src/client/qwaylandsurface.cpp
index 949d7b160..274fdda82 100644
--- a/src/client/qwaylandsurface.cpp
+++ b/src/client/qwaylandsurface.cpp
@@ -15,6 +15,7 @@ QWaylandSurface::QWaylandSurface(QWaylandDisplay *display)
: wl_surface(display->createSurface(this))
{
connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandSurface::handleScreenRemoved);
+ connect(qApp, &QGuiApplication::screenAdded, this, &QWaylandSurface::screensChanged);
}
QWaylandSurface::~QWaylandSurface()
@@ -24,7 +25,14 @@ QWaylandSurface::~QWaylandSurface()
QWaylandScreen *QWaylandSurface::oldestEnteredScreen()
{
- return m_screens.value(0, nullptr);
+ for (auto *screen : std::as_const(m_screens)) {
+ // only report valid screens
+ // we can have some ouptuts waiting for xdg output information
+ // that are valid QPlatformScreens, but not valid QScreens
+ if (screen->screen())
+ return screen;
+ }
+ return nullptr;
}
QWaylandSurface *QWaylandSurface::fromWlSurface(::wl_surface *surface)
diff --git a/src/client/qwaylandtextinputv3.cpp b/src/client/qwaylandtextinputv3.cpp
index 017456ac2..bb449c9d6 100644
--- a/src/client/qwaylandtextinputv3.cpp
+++ b/src/client/qwaylandtextinputv3.cpp
@@ -80,8 +80,8 @@ void QWaylandTextInputv3::zwp_text_input_v3_preedit_string(const QString &text,
return;
m_pendingPreeditString.text = text;
- m_pendingPreeditString.cursorBegin = cursorBegin;
- m_pendingPreeditString.cursorEnd = cursorEnd;
+ m_pendingPreeditString.cursorBegin = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursorBegin);
+ m_pendingPreeditString.cursorEnd = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursorEnd);
}
void QWaylandTextInputv3::zwp_text_input_v3_commit_string(const QString &text)
@@ -101,8 +101,8 @@ void QWaylandTextInputv3::zwp_text_input_v3_delete_surrounding_text(uint32_t bef
if (!QGuiApplication::focusObject())
return;
- m_pendingDeleteBeforeText = QWaylandInputMethodEventBuilder::indexFromWayland(m_surroundingText, beforeText);
- m_pendingDeleteAfterText = QWaylandInputMethodEventBuilder::indexFromWayland(m_surroundingText, afterText);
+ m_pendingDeleteBeforeText = beforeText;
+ m_pendingDeleteAfterText = afterText;
}
void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial)
@@ -157,14 +157,26 @@ void QWaylandTextInputv3::zwp_text_input_v3_done(uint32_t serial)
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "DELETE" << m_pendingDeleteBeforeText << m_pendingDeleteAfterText;
qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "COMMIT" << m_pendingCommitString;
- // A workaround for reselection
- // It will disable redundant commit after reselection
- if (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0)
+ int replaceFrom = 0;
+ int replaceLength = 0;
+ if (m_pendingDeleteBeforeText != 0 || m_pendingDeleteAfterText != 0) {
+ // A workaround for reselection
+ // It will disable redundant commit after reselection
m_condReselection = true;
+ const QByteArray &utf8 = QStringView{m_surroundingText}.toUtf8();
+ if (m_cursorPos < int(m_pendingDeleteBeforeText)) {
+ replaceFrom = -QString::fromUtf8(QByteArrayView{utf8}.first(m_pendingDeleteBeforeText)).size();
+ replaceLength = QString::fromUtf8(QByteArrayView{utf8}.first(m_pendingDeleteBeforeText + m_pendingDeleteAfterText)).size();
+ } else {
+ replaceFrom = -QString::fromUtf8(QByteArrayView{utf8}.sliced(m_cursorPos - m_pendingDeleteBeforeText, m_pendingDeleteBeforeText)).size();
+ replaceLength = QString::fromUtf8(QByteArrayView{utf8}.sliced(m_cursorPos - m_pendingDeleteBeforeText, m_pendingDeleteBeforeText + m_pendingDeleteAfterText)).size();
+ }
+ }
+ qCDebug(qLcQpaWaylandTextInput) << Q_FUNC_INFO << "DELETE from " << replaceFrom << " length " << replaceLength;
event.setCommitString(m_pendingCommitString,
- -m_pendingDeleteBeforeText,
- m_pendingDeleteBeforeText + m_pendingDeleteAfterText);
+ replaceFrom,
+ replaceLength);
m_currentPreeditString = m_pendingPreeditString;
m_pendingPreeditString.clear();
m_pendingCommitString.clear();
@@ -235,54 +247,63 @@ void QWaylandTextInputv3::updateState(Qt::InputMethodQueries queries, uint32_t f
int cursor = event.value(Qt::ImCursorPosition).toInt();
int anchor = event.value(Qt::ImAnchorPosition).toInt();
- qCDebug(qLcQpaWaylandTextInput) << "Orginal surrounding_text from InputMethodQuery: " << text << cursor << anchor;
+ qCDebug(qLcQpaWaylandTextInput) << "Original surrounding_text from InputMethodQuery: " << text << cursor << anchor;
// Make sure text is not too big
// surround_text cannot exceed 4000byte in wayland protocol
// The worst case will be supposed here.
const int MAX_MESSAGE_SIZE = 4000;
- if (text.toUtf8().size() > MAX_MESSAGE_SIZE) {
- const int selectionStart = QWaylandInputMethodEventBuilder::indexToWayland(text, qMin(cursor, anchor));
- const int selectionEnd = QWaylandInputMethodEventBuilder::indexToWayland(text, qMax(cursor, anchor));
+ const int textSize = text.toUtf8().size();
+ if (textSize > MAX_MESSAGE_SIZE) {
+ qCDebug(qLcQpaWaylandTextInput) << "SurroundText size is over "
+ << MAX_MESSAGE_SIZE
+ << " byte, some text will be clipped.";
+ const int selectionStart = qMin(cursor, anchor);
+ const int selectionEnd = qMax(cursor, anchor);
const int selectionLength = selectionEnd - selectionStart;
+ const int selectionSize = QStringView{text}.sliced(selectionStart, selectionLength).toUtf8().size();
// If selection is bigger than 4000 byte, it is fixed to 4000 byte.
// anchor will be moved in the 4000 byte boundary.
- if (selectionLength > MAX_MESSAGE_SIZE) {
+ if (selectionSize > MAX_MESSAGE_SIZE) {
if (anchor > cursor) {
- const int length = MAX_MESSAGE_SIZE;
- anchor = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, length, cursor);
- anchor -= cursor;
- text = text.mid(cursor, anchor);
cursor = 0;
+ anchor = MAX_MESSAGE_SIZE;
+ text = text.sliced(selectionStart, selectionLength);
} else {
- const int length = -MAX_MESSAGE_SIZE;
- anchor = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, length, cursor);
- cursor -= anchor;
- text = text.mid(anchor, cursor);
anchor = 0;
+ cursor = MAX_MESSAGE_SIZE;
+ text = text.sliced(selectionEnd - selectionLength, selectionLength);
}
} else {
- const int offset = (MAX_MESSAGE_SIZE - selectionLength) / 2;
-
- int textStart = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, -offset, qMin(cursor, anchor));
- int textEnd = QWaylandInputMethodEventBuilder::trimmedIndexFromWayland(text, MAX_MESSAGE_SIZE, textStart);
-
- anchor -= textStart;
- cursor -= textStart;
- text = text.mid(textStart, textEnd - textStart);
+ // This is not optimal in some cases.
+ // For examples, if the cursor position and
+ // the selectionEnd are close to the end of the surround text,
+ // the tail of the text might always be clipped.
+ // However all the cases of over 4000 byte are just exceptions.
+ int selEndSize = QStringView{text}.first(selectionEnd).toUtf8().size();
+ cursor = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor);
+ anchor = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor);
+ if (selEndSize < MAX_MESSAGE_SIZE) {
+ text = QString::fromUtf8(QByteArrayView{text.toUtf8()}.first(MAX_MESSAGE_SIZE));
+ } else {
+ const int startOffset = selEndSize - MAX_MESSAGE_SIZE;
+ text = QString::fromUtf8(QByteArrayView{text.toUtf8()}.sliced(startOffset, MAX_MESSAGE_SIZE));
+ cursor -= startOffset;
+ anchor -= startOffset;
+ }
}
+ } else {
+ cursor = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor);
+ anchor = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor);
}
qCDebug(qLcQpaWaylandTextInput) << "Modified surrounding_text: " << text << cursor << anchor;
- const int cursorPos = QWaylandInputMethodEventBuilder::indexToWayland(text, cursor);
- const int anchorPos = QWaylandInputMethodEventBuilder::indexToWayland(text, anchor);
-
- if (m_surroundingText != text || m_cursorPos != cursorPos || m_anchorPos != anchorPos) {
+ if (m_surroundingText != text || m_cursorPos != cursor || m_anchorPos != anchor) {
qCDebug(qLcQpaWaylandTextInput) << "Current surrounding_text: " << m_surroundingText << m_cursorPos << m_anchorPos;
- qCDebug(qLcQpaWaylandTextInput) << "New surrounding_text: " << text << cursorPos << anchorPos;
+ qCDebug(qLcQpaWaylandTextInput) << "New surrounding_text: " << text << cursor << anchor;
- set_surrounding_text(text, cursorPos, anchorPos);
+ set_surrounding_text(text, cursor, anchor);
// A workaround in the case of reselection
// It will work when re-clicking a preedit text
@@ -294,8 +315,8 @@ void QWaylandTextInputv3::updateState(Qt::InputMethodQueries queries, uint32_t f
}
m_surroundingText = text;
- m_cursorPos = cursorPos;
- m_anchorPos = anchorPos;
+ m_cursorPos = cursor;
+ m_anchorPos = anchor;
m_cursor = cursor;
}
}
diff --git a/src/client/qwaylandtextinputv3_p.h b/src/client/qwaylandtextinputv3_p.h
index e8b7aa027..8e32e514d 100644
--- a/src/client/qwaylandtextinputv3_p.h
+++ b/src/client/qwaylandtextinputv3_p.h
@@ -17,7 +17,6 @@
#include "qwaylandtextinputinterface_p.h"
#include <QtWaylandClient/private/qwayland-text-input-unstable-v3.h>
-#include <qwaylandinputmethodeventbuilder_p.h>
#include <QLoggingCategory>
struct wl_callback;
@@ -63,8 +62,6 @@ protected:
void zwp_text_input_v3_done(uint32_t serial) override;
private:
- QWaylandInputMethodEventBuilder m_builder;
-
::wl_surface *m_surface = nullptr; // ### Here for debugging purposes
struct PreeditInfo {
@@ -82,8 +79,8 @@ private:
PreeditInfo m_pendingPreeditString;
PreeditInfo m_currentPreeditString;
QString m_pendingCommitString;
- uint m_pendingDeleteBeforeText = 0;
- uint m_pendingDeleteAfterText = 0;
+ uint m_pendingDeleteBeforeText = 0; // byte length
+ uint m_pendingDeleteAfterText = 0; // byte length
QString m_surroundingText;
int m_cursor; // cursor position in QString
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 73fb331eb..e311b2eb4 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -60,8 +60,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
mFrameCallbackTimeout = frameCallbackTimeout;
}
- mScale = waylandScreen() ? waylandScreen()->scale() : 1; // fallback to 1 if we don't have a real screen
-
static WId id = 1;
mWindowId = id++;
initializeWlSurface();
@@ -327,6 +325,7 @@ void QWaylandWindow::reset()
mWaitingToApplyConfigure = false;
mCanResize = true;
mResizeDirty = false;
+ mScale = std::nullopt;
mOpaqueArea = QRegion();
mMask = QRegion();
@@ -463,7 +462,7 @@ void QWaylandWindow::setGeometry(const QRect &r)
if (mShellSurface) {
mShellSurface->setWindowGeometry(windowContentGeometry());
- if (!qt_window_private(window())->positionAutomatic)
+ if (!qt_window_private(window())->positionAutomatic && !mInResizeFromApplyConfigure)
mShellSurface->setWindowPosition(windowGeometry().topLeft());
}
@@ -558,7 +557,6 @@ QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
if (auto *screen = mSurface->oldestEnteredScreen())
return screen;
}
-
return QPlatformWindow::screen();
}
@@ -891,6 +889,7 @@ QMargins QWaylandWindow::clientSideMargins() const
void QWaylandWindow::setCustomMargins(const QMargins &margins) {
const QMargins oldMargins = mCustomMargins;
mCustomMargins = margins;
+ propagateSizeHints();
setGeometry(geometry().marginsRemoved(oldMargins).marginsAdded(margins));
}
@@ -1185,8 +1184,13 @@ QWaylandWindow *QWaylandWindow::guessTransientParent() const
if (auto transientParent = closestShellSurfaceWindow(window()->transientParent()))
return transientParent;
- if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup))
- return closestShellSurfaceWindow(QGuiApplication::focusWindow());
+ if (window()->type() == Qt::Popup) {
+ if (mTopPopup)
+ return mTopPopup;
+ }
+
+ if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup)
+ return display()->lastInputWindow();
return nullptr;
}
@@ -1433,14 +1437,11 @@ void QWaylandWindow::handleScreensChanged()
{
QPlatformScreen *newScreen = calculateScreenFromSurfaceEvents();
- if (newScreen == mLastReportedScreen)
+ if (newScreen->screen() == window()->screen())
return;
- if (!newScreen->isPlaceholder() && !newScreen->QPlatformScreen::screen())
- mDisplay->forceRoundTrip();
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
- mLastReportedScreen = newScreen;
if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
&& window()->type() != Qt::ToolTip
&& geometry().topLeft() != newScreen->geometry().topLeft()) {
@@ -1470,13 +1471,13 @@ void QWaylandWindow::updateScale()
return;
}
- int scale = mLastReportedScreen->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(mLastReportedScreen)->scale();
+ int scale = screen()->isPlaceholder() ? 1 : static_cast<QWaylandScreen *>(screen())->scale();
setScale(scale);
}
void QWaylandWindow::setScale(qreal newScale)
{
- if (qFuzzyCompare(mScale, newScale))
+ if (mScale.has_value() && qFuzzyCompare(mScale.value(), newScale))
return;
mScale = newScale;
@@ -1485,7 +1486,7 @@ void QWaylandWindow::setScale(qreal newScale)
if (mViewport)
updateViewport();
else if (mSurface->version() >= 3)
- mSurface->set_buffer_scale(std::ceil(mScale));
+ mSurface->set_buffer_scale(std::ceil(newScale));
}
ensureSize();
@@ -1547,7 +1548,7 @@ qreal QWaylandWindow::scale() const
qreal QWaylandWindow::devicePixelRatio() const
{
- return qreal(mScale);
+ return mScale.value_or(waylandScreen() ? waylandScreen()->scale() : 1);
}
bool QWaylandWindow::setMouseGrabEnabled(bool grab)
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index b78c8ce4e..c1b736c1e 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -310,8 +310,7 @@ protected:
bool mSentInitialResize = false;
QPoint mOffset;
- qreal mScale = 1;
- QPlatformScreen *mLastReportedScreen = nullptr;
+ std::optional<qreal> mScale = std::nullopt;
QString mWindowTitle;
QIcon mWindowIcon;