diff --git a/0001-Implement-basic-key-composition-support.patch b/0001-Implement-basic-key-composition-support.patch new file mode 100644 index 0000000..98e417c --- /dev/null +++ b/0001-Implement-basic-key-composition-support.patch @@ -0,0 +1,176 @@ +From 867cf6e37a657fea1bd847494d80b9b65678f5d8 Mon Sep 17 00:00:00 2001 +From: Giulio Camuffo +Date: Fri, 1 May 2015 17:12:22 +0300 +Subject: [PATCH 1/2] Implement basic key composition support + +Use xkbcommon-compose to handle basic compose key support. We should expand on +it in the future to handle things like resetting the compose state on text +field switching. + +Task-number: QTBUG-54792 +Task-number: QTBUG-64572 +Change-Id: I9d1d5ca4c9991928e12979f69eaa477e0cb28ada +Reviewed-by: Paul Olav Tvete +--- + src/client/qwaylandinputdevice.cpp | 65 +++++++++++++++++++++++++++++++++++++- + src/client/qwaylandinputdevice_p.h | 9 ++++++ + 2 files changed, 73 insertions(+), 1 deletion(-) + +diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp +index 4def0de8..90b27769 100644 +--- a/src/client/qwaylandinputdevice.cpp ++++ b/src/client/qwaylandinputdevice.cpp +@@ -70,6 +70,10 @@ + + #include + ++#if QT_CONFIG(xkbcommon_evdev) ++#include ++#endif ++ + QT_BEGIN_NAMESPACE + + namespace QtWaylandClient { +@@ -113,6 +117,7 @@ bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() + qWarning() << "xkb_map_new_from_names failed, no key input"; + return false; + } ++ createComposeState(); + return true; + } + +@@ -125,11 +130,41 @@ void QWaylandInputDevice::Keyboard::releaseKeyMap() + if (mXkbContext) + xkb_context_unref(mXkbContext); + } ++ ++void QWaylandInputDevice::Keyboard::createComposeState() ++{ ++ static const char *locale = nullptr; ++ if (!locale) { ++ locale = getenv("LC_ALL"); ++ if (!locale) ++ locale = getenv("LC_CTYPE"); ++ if (!locale) ++ locale = getenv("LANG"); ++ if (!locale) ++ locale = "C"; ++ } ++ ++ mXkbComposeTable = xkb_compose_table_new_from_locale(mXkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); ++ if (mXkbComposeTable) ++ mXkbComposeState = xkb_compose_state_new(mXkbComposeTable, XKB_COMPOSE_STATE_NO_FLAGS); ++} ++ ++void QWaylandInputDevice::Keyboard::releaseComposeState() ++{ ++ if (mXkbComposeState) ++ xkb_compose_state_unref(mXkbComposeState); ++ if (mXkbComposeTable) ++ xkb_compose_table_unref(mXkbComposeTable); ++ mXkbComposeState = nullptr; ++ mXkbComposeTable = nullptr; ++} ++ + #endif + + QWaylandInputDevice::Keyboard::~Keyboard() + { + #if QT_CONFIG(xkbcommon_evdev) ++ releaseComposeState(); + releaseKeyMap(); + #endif + if (mFocus) +@@ -632,6 +667,7 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, + + // Release the old keymap resources in the case they were already created in + // the key event or when the compositor issues a new map ++ releaseComposeState(); + releaseKeyMap(); + + mXkbContext = xkb_context_new(xkb_context_flags(0)); +@@ -640,6 +676,8 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, + close(fd); + + mXkbState = xkb_state_new(mXkbMap); ++ createComposeState(); ++ + #else + Q_UNUSED(format); + Q_UNUSED(fd); +@@ -723,12 +761,37 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, + return; + } + +- const xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); ++ QString composedText; ++ xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); ++ if (mXkbComposeState) { ++ if (isDown) ++ xkb_compose_state_feed(mXkbComposeState, sym); ++ xkb_compose_status status = xkb_compose_state_get_status(mXkbComposeState); ++ ++ switch (status) { ++ case XKB_COMPOSE_COMPOSED: { ++ int size = xkb_compose_state_get_utf8(mXkbComposeState, nullptr, 0); ++ QVarLengthArray buffer(size + 1); ++ xkb_compose_state_get_utf8(mXkbComposeState, buffer.data(), buffer.size()); ++ composedText = QString::fromUtf8(buffer.constData()); ++ sym = xkb_compose_state_get_one_sym(mXkbComposeState); ++ xkb_compose_state_reset(mXkbComposeState); ++ } break; ++ case XKB_COMPOSE_COMPOSING: ++ case XKB_COMPOSE_CANCELLED: ++ return; ++ case XKB_COMPOSE_NOTHING: ++ break; ++ } ++ } + + Qt::KeyboardModifiers modifiers = mParent->modifiers(); + + std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers); + ++ if (!composedText.isNull()) ++ text = composedText; ++ + sendKey(window->window(), time, type, qtkey, modifiers, code, sym, mNativeModifiers, text); + #else + // Generic fallback for single hard keys: Assume 'key' is a Qt key code. +diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h +index 9e3d1d1f..b1424981 100644 +--- a/src/client/qwaylandinputdevice_p.h ++++ b/src/client/qwaylandinputdevice_p.h +@@ -76,6 +76,11 @@ + struct wl_cursor_image; + #endif + ++#if QT_CONFIG(xkbcommon_evdev) ++struct xkb_compose_state; ++struct xkb_compose_table; ++#endif ++ + QT_BEGIN_NAMESPACE + + namespace QtWaylandClient { +@@ -207,6 +212,8 @@ public: + xkb_context *mXkbContext; + xkb_keymap *mXkbMap; + xkb_state *mXkbState; ++ xkb_compose_table *mXkbComposeTable = nullptr; ++ xkb_compose_state *mXkbComposeState = nullptr; + #endif + uint32_t mNativeModifiers; + +@@ -228,6 +235,8 @@ private: + #if QT_CONFIG(xkbcommon_evdev) + bool createDefaultKeyMap(); + void releaseKeyMap(); ++ void createComposeState(); ++ void releaseComposeState(); + #endif + + }; +-- +2.15.0 + diff --git a/0002-Automatically-change-scale-when-entering-a-new-outpu.patch b/0002-Automatically-change-scale-when-entering-a-new-outpu.patch new file mode 100644 index 0000000..1844e72 --- /dev/null +++ b/0002-Automatically-change-scale-when-entering-a-new-outpu.patch @@ -0,0 +1,139 @@ +From ae858fe3d5a81b8ce5ab1d6ce7e2e6a65a11cc14 Mon Sep 17 00:00:00 2001 +From: Johan Klokkhammer Helsing +Date: Fri, 18 Aug 2017 13:08:50 +0200 +Subject: [PATCH 2/2] Automatically change scale when entering a new output + +Change-Id: I99198d47eac5b2091fe2bfd8fc24646be9c9890a +Reviewed-by: Pier Luigi Fiorini +Reviewed-by: David Edmundson +--- + src/client/qwaylandwindow.cpp | 27 ++++++++++++++++++---- + src/client/qwaylandwindow_p.h | 2 ++ + .../client/wayland-egl/qwaylandeglwindow.cpp | 5 ++++ + .../client/wayland-egl/qwaylandeglwindow.h | 1 + + 4 files changed, 31 insertions(+), 4 deletions(-) + +diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp +index 6d7c0885..c7490532 100644 +--- a/src/client/qwaylandwindow.cpp ++++ b/src/client/qwaylandwindow.cpp +@@ -128,6 +128,12 @@ QWaylandWindow::~QWaylandWindow() + } + } + ++void QWaylandWindow::ensureSize() ++{ ++ if (mBackingStore) ++ mBackingStore->ensureSize(); ++} ++ + void QWaylandWindow::initWindow() + { + if (window()->type() == Qt::Desktop) +@@ -196,7 +202,6 @@ void QWaylandWindow::initWindow() + // Enable high-dpi rendering. Scale() returns the screen scale factor and will + // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() + // to inform the compositor that high-resolution buffers will be provided. +- //FIXME this needs to be changed when the screen changes along with a resized backing store + if (mDisplay->compositorVersion() >= 3) + set_buffer_scale(scale()); + +@@ -516,7 +521,7 @@ void QWaylandWindow::surface_enter(wl_output *output) + + QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); + if (oldScreen != newScreen) //currently this will only happen if the first wl_surface.enter is for a non-primary screen +- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); ++ handleScreenChanged(); + } + + void QWaylandWindow::surface_leave(wl_output *output) +@@ -533,7 +538,7 @@ void QWaylandWindow::surface_leave(wl_output *output) + + QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); + if (oldScreen != newScreen) +- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); ++ handleScreenChanged(); + } + + void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) +@@ -543,7 +548,7 @@ void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) + if (wasRemoved) { + QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); + if (oldScreen != newScreen) +- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); ++ handleScreenChanged(); + } + } + +@@ -906,6 +911,20 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe + } + } + ++void QWaylandWindow::handleScreenChanged() ++{ ++ QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); ++ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); ++ ++ int scale = newScreen->scale(); ++ if (scale != mScale) { ++ mScale = scale; ++ if (isInitialized() && mDisplay->compositorVersion() >= 3) ++ set_buffer_scale(mScale); ++ ensureSize(); ++ } ++} ++ + #if QT_CONFIG(cursor) + void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor) + { +diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h +index bd4a3590..5457d655 100644 +--- a/src/client/qwaylandwindow_p.h ++++ b/src/client/qwaylandwindow_p.h +@@ -110,6 +110,7 @@ public: + ~QWaylandWindow(); + + virtual WindowType windowType() const = 0; ++ virtual void ensureSize(); + WId winId() const override; + void setVisible(bool visible) override; + void setParent(const QPlatformWindow *parent) override; +@@ -263,6 +264,7 @@ private: + QWaylandScreen *calculateScreenFromSurfaceEvents() const; + + void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); ++ void handleScreenChanged(); + + bool mUpdateRequested; + +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +index 6b5c5326..87f3e2d4 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +@@ -92,6 +92,11 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const + return QWaylandWindow::Egl; + } + ++void QWaylandEglWindow::ensureSize() ++{ ++ updateSurface(false); ++} ++ + void QWaylandEglWindow::setGeometry(const QRect &rect) + { + QWaylandWindow::setGeometry(rect); +diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +index e471a8f7..77aee56d 100644 +--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h ++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +@@ -59,6 +59,7 @@ public: + QWaylandEglWindow(QWindow *window); + ~QWaylandEglWindow(); + WindowType windowType() const override; ++ void ensureSize() override; + + void updateSurface(bool create); + virtual void setGeometry(const QRect &rect) override; +-- +2.15.0 + diff --git a/libqt5-qtwayland.changes b/libqt5-qtwayland.changes index 5bbb7cc..c0147a2 100644 --- a/libqt5-qtwayland.changes +++ b/libqt5-qtwayland.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Mon Jan 1 01:03:04 UTC 2018 - fabian@ritter-vogt.de + +- Add patch from upstream dev branch for compose key support: + * 0001-Implement-basic-key-composition-support.patch +- Add fix from upstream dev branch: + * 0002-Automatically-change-scale-when-entering-a-new-outpu.patch + ------------------------------------------------------------------- Fri Dec 8 23:14:19 UTC 2017 - christophe@krop.fr diff --git a/libqt5-qtwayland.spec b/libqt5-qtwayland.spec index 5286043..d09cba4 100644 --- a/libqt5-qtwayland.spec +++ b/libqt5-qtwayland.spec @@ -33,6 +33,9 @@ Source: https://download.qt.io/official_releases/qt/5.10/%{real_version} Source1: baselibs.conf # PATCH-FIX-OPENSUSE Patch1: workaround-null-object.patch +# Patches from upstream dev branch +Patch2000: 0001-Implement-basic-key-composition-support.patch +Patch2001: 0002-Automatically-change-scale-when-entering-a-new-outpu.patch BuildRequires: fdupes BuildRequires: libqt5-qtbase-private-headers-devel >= %{version} BuildRequires: libqt5-qtdeclarative-private-headers-devel >= %{version} @@ -104,6 +107,8 @@ Examples for libqt5-qtwayland module. %prep %setup -q -n %{tar_version} %patch1 -p1 +%patch2000 -p1 +%patch2001 -p1 %post -n libQt5WaylandCompositor5 -p /sbin/ldconfig