Accepting request 561009 from KDE:Qt5

- 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

OBS-URL: https://build.opensuse.org/request/show/561009
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtwayland?expand=0&rev=18
This commit is contained in:
Dominique Leuenberger 2018-01-09 13:46:54 +00:00 committed by Git OBS Bridge
parent 9560f8538a
commit 5f056bb474
4 changed files with 328 additions and 0 deletions

View File

@ -0,0 +1,176 @@
From 867cf6e37a657fea1bd847494d80b9b65678f5d8 Mon Sep 17 00:00:00 2001
From: Giulio Camuffo <giulio.camuffo@jollamobile.com>
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 <paul.tvete@qt.io>
---
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 <QtGui/QGuiApplication>
+#if QT_CONFIG(xkbcommon_evdev)
+#include <xkbcommon/xkbcommon-compose.h>
+#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<char, 32> 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

View File

@ -0,0 +1,139 @@
From ae858fe3d5a81b8ce5ab1d6ce7e2e6a65a11cc14 Mon Sep 17 00:00:00 2001
From: Johan Klokkhammer Helsing <johan.helsing@qt.io>
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 <pierluigi.fiorini@liri.io>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
---
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

View File

@ -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

View File

@ -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