From 73724d91a2496197657ee5467a15990bc0eabc84edcb9041446349562a702010 Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Sun, 1 Jun 2014 16:55:54 +0000 Subject: [PATCH] Accepting request 235520 from KDE:Qt5 ------------------------------------------------------------------- - Build with pkgconfig(libudev), not pkgconfig(udev) ------------------------------------------------------------------- - Fix the modal dialogs can go behind other process windows (QTBUG-35302) * libqt5-fix-the-modal-dialogs-can-go-behind.patch ------------------------------------------------------------------- - Fix broken Gujarati rendering (bnc#878292): libqt5-Fix-Gujarati-font.patch OBS-URL: https://build.opensuse.org/request/show/235520 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtbase?expand=0&rev=20 --- libqt5-Fix-Gujarati-font.patch | 14 + ...-fix-the-modal-dialogs-can-go-behind.patch | 372 ++++++++++++++++++ libqt5-qtbase.changes | 17 + libqt5-qtbase.spec | 10 +- 4 files changed, 411 insertions(+), 2 deletions(-) create mode 100644 libqt5-Fix-Gujarati-font.patch create mode 100644 libqt5-fix-the-modal-dialogs-can-go-behind.patch diff --git a/libqt5-Fix-Gujarati-font.patch b/libqt5-Fix-Gujarati-font.patch new file mode 100644 index 0000000..2f5b899 --- /dev/null +++ b/libqt5-Fix-Gujarati-font.patch @@ -0,0 +1,14 @@ +--- + src/gui/text/qtextengine.cpp | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/gui/text/qtextengine.cpp ++++ b/src/gui/text/qtextengine.cpp +@@ -1549,6 +1549,7 @@ void QTextEngine::itemize() const + case QChar::Script_Hiragana: + case QChar::Script_Katakana: + case QChar::Script_Bopomofo: ++ case QChar::Script_Gujarati: + analysis[i].script = QChar::Script_Common; + break; + default: diff --git a/libqt5-fix-the-modal-dialogs-can-go-behind.patch b/libqt5-fix-the-modal-dialogs-can-go-behind.patch new file mode 100644 index 0000000..0de4dd5 --- /dev/null +++ b/libqt5-fix-the-modal-dialogs-can-go-behind.patch @@ -0,0 +1,372 @@ +From 50b8506eaccc3c9bc3d717b241193bc8be9708b0 Mon Sep 17 00:00:00 2001 +From: Jorgen Lind +Date: Thu, 3 Apr 2014 13:11:59 +0200 +Subject: [PATCH] XCB: fix that modal dialogs can go behind other process + windows + +Task-number: QTBUG-35302 +Change-Id: I1ad7a66e530710d5338a15057254360dae676451 +Reviewed-by: Friedemann Kleint +Reviewed-by: Laszlo Agocs +--- + src/plugins/platforms/windows/qwindowscontext.cpp | 8 + + src/plugins/platforms/windows/qwindowswindow.cpp | 22 ++-- + src/plugins/platforms/xcb/qxcbwindow.cpp | 104 +++++++++++++------- + src/plugins/platforms/xcb/qxcbwindow.h | 4 + tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 113 ++++++++++++++++++++++ + 5 files changed, 206 insertions(+), 45 deletions(-) + +--- a/src/plugins/platforms/windows/qwindowscontext.cpp ++++ b/src/plugins/platforms/windows/qwindowscontext.cpp +@@ -49,11 +49,11 @@ + #include "qwindowsmime.h" + #include "qwindowsinputcontext.h" + #include "qwindowstabletsupport.h" ++#include + #ifndef QT_NO_ACCESSIBILITY + # include "accessible/qwindowsaccessibility.h" + #endif + #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) +-# include + # include + # include "qwindowssessionmanager.h" + #endif +@@ -1025,6 +1025,12 @@ void QWindowsContext::handleFocusEvent(Q + { + QWindow *nextActiveWindow = 0; + if (et == QtWindows::FocusInEvent) { ++ QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window()); ++ QWindow *modalWindow = 0; ++ if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) { ++ modalWindow->requestActivate(); ++ return; ++ } + nextActiveWindow = platformWindow->window(); + } else { + // Focus out: Is the next window known and different +--- a/src/plugins/platforms/windows/qwindowswindow.cpp ++++ b/src/plugins/platforms/windows/qwindowswindow.cpp +@@ -1016,17 +1016,17 @@ QWindow *QWindowsWindow::topLevelOf(QWin + while (QWindow *parent = w->parent()) + w = parent; + +- const QWindowsWindow *ww = static_cast(w->handle()); +- +- // In case the topmost parent is embedded, find next ancestor using native methods +- if (ww->isEmbedded(0)) { +- HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); +- const HWND desktopHwnd = GetDesktopWindow(); +- const QWindowsContext *ctx = QWindowsContext::instance(); +- while (parentHWND && parentHWND != desktopHwnd) { +- if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND)) +- return topLevelOf(ancestor->window()); +- parentHWND = GetAncestor(parentHWND, GA_PARENT); ++ if (const QPlatformWindow *handle = w->handle()) { ++ const QWindowsWindow *ww = static_cast(handle); ++ if (ww->isEmbedded(0)) { ++ HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); ++ const HWND desktopHwnd = GetDesktopWindow(); ++ const QWindowsContext *ctx = QWindowsContext::instance(); ++ while (parentHWND && parentHWND != desktopHwnd) { ++ if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND)) ++ return topLevelOf(ancestor->window()); ++ parentHWND = GetAncestor(parentHWND, GA_PARENT); ++ } + } + } + return w; +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -485,7 +485,7 @@ QXcbWindow::~QXcbWindow() + void QXcbWindow::destroy() + { + if (connection()->focusWindow() == this) +- connection()->setFocusWindow(0); ++ doFocusOut(); + + if (m_syncCounter && m_usingSyncProtocol) + Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); +@@ -671,6 +671,9 @@ void QXcbWindow::show() + + Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); + ++ if (QGuiApplication::modalWindow() == window()) ++ requestActivateWindow(); ++ + m_screen->windowShown(this); + + connection()->sync(); +@@ -694,6 +697,68 @@ void QXcbWindow::hide() + m_mapped = false; + } + ++static QWindow *tlWindow(QWindow *window) ++{ ++ if (window && window->parent()) ++ return tlWindow(window->parent()); ++ return window; ++} ++ ++bool QXcbWindow::relayFocusToModalWindow() const ++{ ++ QWindow *w = tlWindow(static_cast(QObjectPrivate::get(window()))->eventReceiver()); ++ QWindow *modal_window = 0; ++ if (QGuiApplicationPrivate::instance()->isWindowBlocked(w,&modal_window) && modal_window != w) { ++ modal_window->requestActivate(); ++ connection()->flush(); ++ return true; ++ } ++ ++ return false; ++} ++ ++void QXcbWindow::doFocusIn() ++{ ++ if (relayFocusToModalWindow()) ++ return; ++ QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); ++ connection()->setFocusWindow(static_cast(w->handle())); ++ QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); ++} ++ ++static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) ++{ ++ if (!event) { ++ // FocusIn event is not in the queue, proceed with FocusOut normally. ++ QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason); ++ return true; ++ } ++ uint response_type = event->response_type & ~0x80; ++ if (response_type == XCB_FOCUS_IN) ++ return true; ++ ++ /* We are also interested in XEMBED_FOCUS_IN events */ ++ if (response_type == XCB_CLIENT_MESSAGE) { ++ xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; ++ if (cme->type == connection->atom(QXcbAtom::_XEMBED) ++ && cme->data.data32[1] == XEMBED_FOCUS_IN) ++ return true; ++ } ++ ++ return false; ++} ++ ++void QXcbWindow::doFocusOut() ++{ ++ if (relayFocusToModalWindow()) ++ return; ++ connection()->setFocusWindow(0); ++ // Do not set the active window to 0 if there is a FocusIn coming. ++ // There is however no equivalent for XPutBackEvent so register a ++ // callback for QXcbConnection instead. ++ connection()->addPeekFunc(focusInPeeker); ++} ++ + struct QtMotifWmHints { + quint32 flags, functions, decorations; + qint32 input_mode; +@@ -1514,6 +1579,8 @@ void QXcbWindow::handleClientMessageEven + QWindowSystemInterface::handleCloseEvent(window()); + } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) { + connection()->setTime(event->data.data32[1]); ++ relayFocusToModalWindow(); ++ return; + } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) { + if (event->window == m_screen->root()) + return; +@@ -1549,8 +1616,7 @@ void QXcbWindow::handleClientMessageEven + } else if (event->type == atom(QXcbAtom::_XEMBED)) { + handleXEmbedMessage(event); + } else if (event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) { +- connection()->setFocusWindow(this); +- QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason); ++ doFocusIn(); + } else if (event->type == atom(QXcbAtom::MANAGER) + || event->type == atom(QXcbAtom::_NET_WM_STATE) + || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) { +@@ -1868,41 +1934,13 @@ void QXcbWindow::handlePropertyNotifyEve + + void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) + { +- QWindow *w = window(); +- w = static_cast(QObjectPrivate::get(w))->eventReceiver(); +- connection()->setFocusWindow(static_cast(w->handle())); +- QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); ++ doFocusIn(); + } + +-static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) +-{ +- if (!event) { +- // FocusIn event is not in the queue, proceed with FocusOut normally. +- QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason); +- return true; +- } +- uint response_type = event->response_type & ~0x80; +- if (response_type == XCB_FOCUS_IN) +- return true; +- +- /* We are also interested in XEMBED_FOCUS_IN events */ +- if (response_type == XCB_CLIENT_MESSAGE) { +- xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; +- if (cme->type == connection->atom(QXcbAtom::_XEMBED) +- && cme->data.data32[1] == XEMBED_FOCUS_IN) +- return true; +- } +- +- return false; +-} + + void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) + { +- connection()->setFocusWindow(0); +- // Do not set the active window to 0 if there is a FocusIn coming. +- // There is however no equivalent for XPutBackEvent so register a +- // callback for QXcbConnection instead. +- connection()->addPeekFunc(focusInPeeker); ++ doFocusOut(); + } + + void QXcbWindow::updateSyncRequestCounter() +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -176,6 +176,10 @@ private: + void show(); + void hide(); + ++ bool relayFocusToModalWindow() const; ++ void doFocusIn(); ++ void doFocusOut(); ++ + QXcbScreen *m_screen; + + xcb_window_t m_window; +--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp ++++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +@@ -88,6 +88,10 @@ private slots: + void visibility(); + void mask(); + void initialSize(); ++ void modalDialog(); ++ void modalDialogClosingOneOfTwoModal(); ++ void modalWithChildWindow(); ++ void modalWindowModallity(); + + void initTestCase() + { +@@ -1316,6 +1320,115 @@ void tst_QWindow::initialSize() + } + } + ++void tst_QWindow::modalDialog() ++{ ++ QWindow normalWindow; ++ normalWindow.resize(400, 400); ++ normalWindow.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); ++ ++ QWindow dialog; ++ dialog.resize(200,200); ++ dialog.setModality(Qt::ApplicationModal); ++ dialog.setFlags(Qt::Dialog); ++ dialog.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&dialog)); ++ ++ normalWindow.requestActivate(); ++ ++ QGuiApplication::sync(); ++ QGuiApplication::processEvents(); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog); ++} ++ ++void tst_QWindow::modalDialogClosingOneOfTwoModal() ++{ ++ QWindow normalWindow; ++ normalWindow.resize(400, 400); ++ normalWindow.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); ++ ++ QWindow first_dialog; ++ first_dialog.resize(200,200); ++ first_dialog.setModality(Qt::ApplicationModal); ++ first_dialog.setFlags(Qt::Dialog); ++ first_dialog.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&first_dialog)); ++ ++ { ++ QWindow second_dialog; ++ second_dialog.resize(200,200); ++ second_dialog.setModality(Qt::ApplicationModal); ++ second_dialog.setFlags(Qt::Dialog); ++ second_dialog.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&second_dialog)); ++ ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &second_dialog); ++ ++ second_dialog.close(); ++ } ++ ++ QGuiApplication::sync(); ++ QGuiApplication::processEvents(); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &first_dialog); ++} ++ ++void tst_QWindow::modalWithChildWindow() ++{ ++ QWindow normalWindow; ++ normalWindow.resize(400, 400); ++ normalWindow.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); ++ ++ QWindow tlw_dialog; ++ tlw_dialog.resize(400,200); ++ tlw_dialog.setModality(Qt::ApplicationModal); ++ tlw_dialog.setFlags(Qt::Dialog); ++ tlw_dialog.create(); ++ ++ QWindow sub_window(&tlw_dialog); ++ sub_window.resize(200,300); ++ sub_window.show(); ++ ++ tlw_dialog.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&tlw_dialog)); ++ QVERIFY(QTest::qWaitForWindowExposed(&sub_window)); ++ ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &tlw_dialog); ++ ++ sub_window.requestActivate(); ++ QGuiApplication::sync(); ++ QGuiApplication::processEvents(); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &sub_window); ++} ++ ++void tst_QWindow::modalWindowModallity() ++{ ++ QWindow normal_window; ++ normal_window.resize(400, 400); ++ normal_window.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&normal_window)); ++ ++ QWindow parent_to_modal; ++ parent_to_modal.resize(400, 400); ++ parent_to_modal.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&parent_to_modal)); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &parent_to_modal); ++ ++ QWindow modal_dialog; ++ modal_dialog.resize(400,200); ++ modal_dialog.setModality(Qt::WindowModal); ++ modal_dialog.setFlags(Qt::Dialog); ++ modal_dialog.setTransientParent(&parent_to_modal); ++ modal_dialog.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&modal_dialog)); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &modal_dialog); ++ ++ normal_window.requestActivate(); ++ QTRY_COMPARE(QGuiApplication::focusWindow(), &normal_window); ++ ++} ++ + #include + QTEST_MAIN(tst_QWindow) + diff --git a/libqt5-qtbase.changes b/libqt5-qtbase.changes index 6e7eb29..0d289bd 100644 --- a/libqt5-qtbase.changes +++ b/libqt5-qtbase.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Tue May 27 09:52:05 UTC 2014 - hrvoje.senjan@gmail.com + +- Build with pkgconfig(libudev), not pkgconfig(udev) + +------------------------------------------------------------------- +Fri May 23 08:55:44 UTC 2014 - mlin@suse.com + +- Fix the modal dialogs can go behind other process windows (QTBUG-35302) + * libqt5-fix-the-modal-dialogs-can-go-behind.patch + +------------------------------------------------------------------- +Thu May 22 12:57:48 CEST 2014 - tiwai@suse.de + +- Fix broken Gujarati rendering (bnc#878292): + libqt5-Fix-Gujarati-font.patch + ------------------------------------------------------------------- Wed May 21 00:32:51 UTC 2014 - hrvoje.senjan@gmail.com diff --git a/libqt5-qtbase.spec b/libqt5-qtbase.spec index 5cb14a4..ec85e05 100644 --- a/libqt5-qtbase.spec +++ b/libqt5-qtbase.spec @@ -51,6 +51,10 @@ Patch133: f1ee10f81ac18789e9a7dc715b464415ba2bc2b8.patch Patch134: libqt5-add-support-for-byte-swapping.patch # PATCH-FIX-UPSTREAM libqt5-byte-order-byte-is-address0.patch -- the byte order byte is at address 0(bnc#866709), currently it's at the upstream dev branch Patch135: libqt5-byte-order-byte-is-address0.patch +# PATCH-FIX-SUSE libqt5-Fix-Gujarati-font.patch bnc#878292 fix broken Gujarati font rendering +Patch136: libqt5-Fix-Gujarati-font.patch +# PATCH-FIX-UPSTREAM libqt5-fix-the-modal-dialogs-can-go-behind.patch -- fix that modal dialogs can go behind other process window +Patch137: libqt5-fix-the-modal-dialogs-can-go-behind.patch BuildRequires: alsa-devel BuildRequires: cups-devel BuildRequires: fdupes @@ -82,7 +86,6 @@ BuildRequires: pkgconfig(glesv2) %endif BuildRequires: libicu-devel BuildRequires: libpulse-devel -BuildRequires: libudev-devel BuildRequires: xcb-util-image-devel BuildRequires: xcb-util-keysyms-devel BuildRequires: xcb-util-renderutil-devel @@ -91,6 +94,7 @@ BuildRequires: xorg-x11-devel BuildRequires: xz BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gtk+-2.0) +BuildRequires: pkgconfig(libudev) %if 0%{?suse_version} >= 1310 BuildRequires: pkgconfig(harfbuzz) %endif @@ -139,6 +143,8 @@ handling. %patch133 -p1 %patch134 -p1 %patch135 -p1 +%patch136 -p1 +%patch137 -p1 # be sure not to use them rm -r src/3rdparty/{libjpeg,freetype,libpng,zlib} @@ -574,8 +580,8 @@ Requires: pkgconfig(fontconfig) Requires: pkgconfig(freetype2) Requires: pkgconfig(gl) Requires: pkgconfig(glib-2.0) +Requires: pkgconfig(libudev) Requires: pkgconfig(mtdev) -Requires: pkgconfig(udev) Requires: pkgconfig(x11) Requires: pkgconfig(xext) Requires: pkgconfig(xrender)