diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ include(KDECMakeSettings) set(REQUIRED_QT_VERSION 5.5.0) -find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets DBus) +find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets DBus X11Extras) set(KF5_VERSION "5.18.0") # handled by release scripts set(KF5_DEP_VERSION "5.17.0") # handled by release scripts @@ -35,6 +35,7 @@ find_package(KF5KIO ${KF5_DEP_VERSION} REQUIRED) find_package(KF5Notifications ${KF5_DEP_VERSION} REQUIRED) find_package(KF5WidgetsAddons ${KF5_DEP_VERSION} REQUIRED) +find_package(KF5WindowSystem ${KF5_DEP_VERSION} REQUIRED) find_package(KF5Wayland 5.5 CONFIG REQUIRED) add_definitions(-DTRANSLATION_DOMAIN=\"plasmaintegration5\") diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -27,7 +27,7 @@ add_test(frameworkintegration-${_testname} ${_testname}) ecm_mark_as_test(${_testname}) ecm_mark_nongui_executable(${_testname}) - target_link_libraries(${_testname} Qt5::Test Qt5::DBus KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets KF5::I18n KF5::Notifications KF5::WaylandClient) + target_link_libraries(${_testname} Qt5::Test Qt5::DBus Qt5::X11Extras KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets KF5::I18n KF5::Notifications KF5::WindowSystem KF5::WaylandClient) endmacro() set(platformThemeSRCS @@ -40,6 +40,7 @@ ../src/platformtheme/kdirselectdialog.cpp ../src/platformtheme/kfiletreeview.cpp ../src/platformtheme/kwaylandintegration.cpp + ../src/platformtheme/x11integration.cpp ) frameworkintegration_tests( diff --git a/autotests/kdeplatformtheme_unittest.cpp b/autotests/kdeplatformtheme_unittest.cpp --- a/autotests/kdeplatformtheme_unittest.cpp +++ b/autotests/kdeplatformtheme_unittest.cpp @@ -25,10 +25,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -38,8 +40,11 @@ #include #include #include +#include +#include #include +#include static void prepareEnvironment() { @@ -293,6 +298,30 @@ QCOMPARE(palette->brush(states[i], QPalette::LinkVisited), redBrush); } } + + void dndWindowFlagsTest() + { + if (!QX11Info::isPlatformX11()) { + QSKIP("This test requires xcb platform."); + } + + QDrag *drag = new QDrag(this); + QMimeData *data = new QMimeData; + data->setData("Text/Plain", "drag data"); + drag->setMimeData(data); + bool succeeded = false; + QTimer::singleShot(1000, [&succeeded] { + auto windows = QGuiApplication::allWindows(); + auto it = std::find_if(windows.constBegin(), windows.constEnd(), [] (QWindow *w) { return w->inherits("QShapedPixmapWindow"); }); + if (it != windows.constEnd()) { + KWindowInfo info((*it)->winId(), NET::WMWindowType); + succeeded = info.windowType(NET::DNDIconMask) == NET::DNDIcon; + } + QTest::keyClick(windows.first(), Qt::Key_Escape); + }); + drag->exec(); + QVERIFY(succeeded); + } }; QTEST_MAIN(KdePlatformTheme_UnitTest) diff --git a/src/platformtheme/CMakeLists.txt b/src/platformtheme/CMakeLists.txt --- a/src/platformtheme/CMakeLists.txt +++ b/src/platformtheme/CMakeLists.txt @@ -20,6 +20,7 @@ kfiletreeview.cpp kdirselectdialog.cpp kwaylandintegration.cpp + x11integration.cpp main.cpp ) @@ -31,14 +32,16 @@ target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::DBus + Qt5::X11Extras KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets # KFileFilterCombo, KDirSortFilterProxyModel, KRecentDirs KF5::KIOWidgets KF5::XmlGui KF5::I18n KF5::Notifications + KF5::WindowSystem KF5::WaylandClient ) diff --git a/src/platformtheme/kdeplatformtheme.h b/src/platformtheme/kdeplatformtheme.h --- a/src/platformtheme/kdeplatformtheme.h +++ b/src/platformtheme/kdeplatformtheme.h @@ -30,6 +30,7 @@ class KHintsSettings; class KFontSettingsData; class KWaylandIntegration; +class X11Integration; class QIconEngine; class KdePlatformTheme : public QPlatformTheme @@ -57,6 +58,7 @@ KHintsSettings *m_hints; KFontSettingsData *m_fontsData; QScopedPointer m_kwaylandIntegration; + QScopedPointer m_x11Integration; }; #endif // KDEPLATFORMTHEME_H diff --git a/src/platformtheme/kdeplatformtheme.cpp b/src/platformtheme/kdeplatformtheme.cpp --- a/src/platformtheme/kdeplatformtheme.cpp +++ b/src/platformtheme/kdeplatformtheme.cpp @@ -26,6 +26,7 @@ #include "kdeplatformfiledialoghelper.h" #include "kdeplatformsystemtrayicon.h" #include "kwaylandintegration.h" +#include "x11integration.h" #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include #include @@ -48,6 +50,9 @@ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"))) { m_kwaylandIntegration.reset(new KWaylandIntegration()); m_kwaylandIntegration->init(); + } else if (QX11Info::isPlatformX11()) { + m_x11Integration.reset(new X11Integration()); + m_x11Integration->init(); } } diff --git a/src/platformtheme/x11integration.h b/src/platformtheme/x11integration.h new file mode 100644 --- /dev/null +++ b/src/platformtheme/x11integration.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE libraries + * Copyright 2015 Martin Gräßlin + * Copyright 2016 Marco Martin + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License or ( at + * your option ) version 3 or, at the discretion of KDE e.V. ( which shall + * act as a proxy as in section 14 of the GPLv3 ), any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef X11INTEGRATION_H +#define X11INTEGRATION_H + +#include + +class X11Integration : public QObject +{ + Q_OBJECT +public: + explicit X11Integration(); + virtual ~X11Integration(); + void init(); + + bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; + +private: + +}; + +#endif diff --git a/src/platformtheme/x11integration.cpp b/src/platformtheme/x11integration.cpp new file mode 100644 --- /dev/null +++ b/src/platformtheme/x11integration.cpp @@ -0,0 +1,53 @@ +/* This file is part of the KDE libraries + * Copyright 2015 Martin Gräßlin + * Copyright 2016 Marco Martin + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License or ( at + * your option ) version 3 or, at the discretion of KDE e.V. ( which shall + * act as a proxy as in section 14 of the GPLv3 ), any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "x11integration.h" + +#include +#include +#include +#include + +X11Integration::X11Integration() + : QObject() +{ +} + +X11Integration::~X11Integration() = default; + +void X11Integration::init() +{ + QCoreApplication::instance()->installEventFilter(this); +} + +bool X11Integration::eventFilter(QObject *watched, QEvent *event) +{ + //the drag and drop window should NOT be a tooltip + //https://bugreports.qt.io/browse/QTBUG-52560 + if (event->type() == QEvent::Show && watched->inherits("QShapedPixmapWindow")) { + //static cast should be safe there + QWindow *w = static_cast(watched); + NETWinInfo info(QX11Info::connection(), w->winId(), QX11Info::appRootWindow(), NET::WMWindowType, NET::Properties2()); + info.setWindowType(NET::DNDIcon); + // TODO: does this flash the xcb connection? + } + return false; +} +