summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rosca <[email protected]>2016-12-10 23:27:09 +0100
committerDavid Rosca <[email protected]>2016-12-15 14:55:24 +0100
commitc5f1504d7ce23f4adfd9f8914b726ffd24fc24d2 (patch)
treea4e725e5341b3c8acd30240a2a73c4e983bda954
parent234ff11c993c2e5e9204b209ed96922e8d7bab05 (diff)
Implement drag from free space also for QtQuickControls
Use window manager to handle window move when dragging from free space also with QtQuickControls. Registering QQuickItems is hacky, because there is no Style::polish for QtQuickControls, so those items are now registered from ::isQtQuickControl. Adaptation of the same patch from Breeze. Differential Revision: https://phabricator.kde.org/D3638
-rw-r--r--CMakeLists.txt2
-rw-r--r--kstyle/CMakeLists.txt2
-rw-r--r--kstyle/oxygenstyle.cpp4
-rw-r--r--kstyle/oxygenwindowmanager.cpp91
-rw-r--r--kstyle/oxygenwindowmanager.h25
5 files changed, 95 insertions, 29 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 066fb8b..5ebb7fe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,7 +46,7 @@ else()
find_package(ECM 0.0.9 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
- find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets DBus)
+ find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets DBus Quick)
find_package(KF5 REQUIRED COMPONENTS
I18n
Config
diff --git a/kstyle/CMakeLists.txt b/kstyle/CMakeLists.txt
index 22a64b0..12db970 100644
--- a/kstyle/CMakeLists.txt
+++ b/kstyle/CMakeLists.txt
@@ -85,7 +85,7 @@ else()
kconfig_add_kcfg_files(oxygen_PART_SRCS oxygenstyleconfigdata.kcfgc)
add_library(oxygen MODULE ${oxygen_PART_SRCS})
- target_link_libraries(oxygen Qt5::Core Qt5::Gui Qt5::Widgets Qt5::DBus)
+ target_link_libraries(oxygen Qt5::Core Qt5::Gui Qt5::Widgets Qt5::DBus Qt5::Quick)
target_link_libraries(oxygen KF5::GuiAddons KF5::Style KF5::WindowSystem)
target_link_libraries(oxygen oxygenstyle5)
diff --git a/kstyle/oxygenstyle.cpp b/kstyle/oxygenstyle.cpp
index 7785d08..2fbef95 100644
--- a/kstyle/oxygenstyle.cpp
+++ b/kstyle/oxygenstyle.cpp
@@ -8607,7 +8607,9 @@ namespace Oxygen
bool Style::isQtQuickControl( const QStyleOption* option, const QWidget* widget ) const
{
#if QT_VERSION >= 0x050000
- return (widget == nullptr) && option && option->styleObject && option->styleObject->inherits( "QQuickItem" );
+ const bool is = (widget == nullptr) && option && option->styleObject && option->styleObject->inherits( "QQuickItem" );
+ if ( is ) _windowManager->registerQuickItem( static_cast<QQuickItem*>( option->styleObject ) );
+ return is;
#else
Q_UNUSED( widget );
Q_UNUSED( option );
diff --git a/kstyle/oxygenwindowmanager.cpp b/kstyle/oxygenwindowmanager.cpp
index fd73f8b..015ac75 100644
--- a/kstyle/oxygenwindowmanager.cpp
+++ b/kstyle/oxygenwindowmanager.cpp
@@ -89,6 +89,8 @@
#include <NETRootInfo>
#else
#include <NETWM>
+#include <QQuickItem>
+#include <QQuickWindow>
#endif
#endif
@@ -315,6 +317,22 @@ namespace Oxygen
}
+#if !OXYGEN_USE_KDE4
+ void WindowManager::registerQuickItem( QQuickItem* item )
+ {
+ if ( !item ) return;
+
+ QQuickWindow *window = item->window();
+ if (window) {
+ QQuickItem *contentItem = window->contentItem();
+ contentItem->setAcceptedMouseButtons( Qt::LeftButton );
+ contentItem->removeEventFilter( this );
+ contentItem->installEventFilter( this );
+ }
+
+ }
+#endif
+
//_____________________________________________________________
void WindowManager::unregisterWidget( QWidget* widget )
{
@@ -370,11 +388,20 @@ namespace Oxygen
break;
case QEvent::MouseMove:
- if ( object == _target.data() ) return mouseMoveEvent( object, event );
+ if ( object == _target.data()
+#if !OXYGEN_USE_KDE4
+ || object == _quickTarget.data()
+#endif
+ ) return mouseMoveEvent( object, event );
break;
case QEvent::MouseButtonRelease:
- if ( _target ) return mouseReleaseEvent( object, event );
+ if ( _target
+#if !OXYGEN_USE_KDE4
+ || _quickTarget
+#endif
+ ) return mouseReleaseEvent( object, event );
+
break;
default:
@@ -394,8 +421,16 @@ namespace Oxygen
{
_dragTimer.stop();
+#if OXYGEN_USE_KDE4
+ if( _target )
+ { startDrag( _target.data()->window(), _globalDragPoint ); }
+#else
if( _target )
- { startDrag( _target.data(), _globalDragPoint ); }
+ { startDrag( _target.data()->window()->windowHandle(), _globalDragPoint ); }
+ else if( _quickTarget )
+ { startDrag( _quickTarget.data()->window(), _globalDragPoint ); }
+#endif
+
} else {
@@ -418,6 +453,21 @@ namespace Oxygen
if( isLocked() ) return false;
else setLocked( true );
+#if !OXYGEN_USE_KDE4
+ // check QQuickItem - we can immediately start drag, because QQuickWindow's contentItem
+ // only receives mouse events that weren't handled by children
+ if ( QQuickItem *item = qobject_cast<QQuickItem*>( object ) ) {
+ _quickTarget = item;
+ _dragPoint = mouseEvent->pos();
+ _globalDragPoint = mouseEvent->globalPos();
+
+ if( _dragTimer.isActive() ) _dragTimer.stop();
+ _dragTimer.start( _dragDelay, this );
+
+ return true;
+ }
+#endif
+
// cast to widget
QWidget *widget = static_cast<QWidget*>( object );
@@ -481,7 +531,7 @@ namespace Oxygen
return true;
- } else if( !useWMMoveResize() ) {
+ } else if( !useWMMoveResize() && _target ) {
// use QWidget::move for the grabbing
/* this works only if the sending object and the target are identical */
@@ -789,6 +839,9 @@ namespace Oxygen
}
_target.clear();
+#if !OXYGEN_USE_KDE4
+ _quickTarget.clear();
+#endif
if( _dragTimer.isActive() ) _dragTimer.stop();
_dragPoint = QPoint();
_globalDragPoint = QPoint();
@@ -798,19 +851,19 @@ namespace Oxygen
}
//____________________________________________________________
- void WindowManager::startDrag( QWidget* widget, const QPoint& position )
+ void WindowManager::startDrag( Window* window, const QPoint& position )
{
- if( !( enabled() && widget ) ) return;
+ if( !( enabled() && window ) ) return;
if( QWidget::mouseGrabber() ) return;
// ungrab pointer
if( useWMMoveResize() )
{
if( Helper::isX11() ) {
- startDragX11( widget, position );
+ startDragX11( window, position );
} else if( Helper::isWayland() ) {
- startDragWayland( widget, position );
+ startDragWayland( window, position );
}
} else if( !_cursorOverride ) {
@@ -827,21 +880,14 @@ namespace Oxygen
}
//_______________________________________________________
- void WindowManager::startDragX11( QWidget* widget, const QPoint& position )
+ void WindowManager::startDragX11( Window* window, const QPoint& position )
{
#if OXYGEN_HAVE_X11
// connection
xcb_connection_t* connection( Helper::connection() );
- // window
- const WId window( widget->window()->winId() );
-
#if QT_VERSION >= 0x050300
- qreal dpiRatio = 1;
- QWindow* windowHandle = widget->window()->windowHandle();
- if( windowHandle ) dpiRatio = windowHandle->devicePixelRatio();
- else dpiRatio = qApp->devicePixelRatio();
- dpiRatio = qApp->devicePixelRatio();
+ const qreal dpiRatio = qApp->devicePixelRatio();
#else
const qreal dpiRatio = 1;
#endif
@@ -854,28 +900,27 @@ namespace Oxygen
xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME );
NETRootInfo( net_connection, NET::WMMoveResize ).moveResizeRequest(
- window, position.x() * dpiRatio,
+ window->winId(), position.x() * dpiRatio,
position.y() * dpiRatio,
NET::Move );
#else
- Q_UNUSED( widget );
+ Q_UNUSED( window );
Q_UNUSED( position );
#endif
}
//_______________________________________________________
- void WindowManager::startDragWayland( QWidget* widget, const QPoint& position )
+ void WindowManager::startDragWayland( Window* window, const QPoint& position )
{
#if OXYGEN_HAVE_KWAYLAND
if( !_seat ) {
return;
}
- QWindow* windowHandle = widget->window()->windowHandle();
- auto shellSurface = KWayland::Client::ShellSurface::fromWindow(windowHandle);
+ auto shellSurface = KWayland::Client::ShellSurface::fromWindow(window);
if( !shellSurface ) {
// TODO: also check for xdg-shell in future
return;
@@ -884,7 +929,7 @@ namespace Oxygen
shellSurface->requestMove( _seat, _waylandSerial );
#else
- Q_UNUSED( widget );
+ Q_UNUSED( window );
Q_UNUSED( position );
#endif
diff --git a/kstyle/oxygenwindowmanager.h b/kstyle/oxygenwindowmanager.h
index 5630d1e..bc90532 100644
--- a/kstyle/oxygenwindowmanager.h
+++ b/kstyle/oxygenwindowmanager.h
@@ -31,6 +31,10 @@
#include <QString>
#include <QWidget>
+#if !OXYGEN_USE_KDE4
+#include <QQuickItem>
+#endif
+
#if OXYGEN_HAVE_KWAYLAND
namespace KWayland
{
@@ -66,6 +70,11 @@ namespace Oxygen
//* register widget
void registerWidget( QWidget* );
+#if !OXYGEN_USE_KDE4
+ //* register quick item
+ void registerQuickItem( QQuickItem* );
+#endif
+
//* unregister widget
void unregisterWidget( QWidget* );
@@ -163,14 +172,20 @@ namespace Oxygen
//* reset drag
void resetDrag( void );
+#if QT_VERSION >= 0x050000
+ using Window = QWindow;
+#else
+ using Window = QWidget;
+#endif
+
//* start drag
- void startDrag( QWidget*, const QPoint& );
+ void startDrag( Window*, const QPoint& );
//* X11 specific implementation for startDrag
- void startDragX11( QWidget*, const QPoint& );
+ void startDragX11( Window*, const QPoint& );
//* Wayland specific implementation for startDrag
- void startDragWayland( QWidget*, const QPoint& );
+ void startDragWayland( Window*, const QPoint& );
//* returns true if window manager is used for moving
/** right now this is true only for X11 */
@@ -263,6 +278,10 @@ namespace Oxygen
/** Weak pointer is used in case the target gets deleted while drag is in progress */
WeakPointer<QWidget> _target;
+#if !OXYGEN_USE_KDE4
+ WeakPointer<QQuickItem> _quickTarget;
+#endif
+
//* true if drag is about to start
bool _dragAboutToStart;