From c9c33bd227f0199b368d92131a0ee566d2651061 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 20 Sep 2011 18:10:39 +0200 Subject: [PATCH] Fix support for drag pixmaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-add the support for drag pixmaps to qdnd. Use the new WindowTransparentForMouseEvents flag for the window that shows the drag pixmap. Change-Id: I4b594085c161475988b9be0ffdc02c75fcc37f66 Reviewed-on: http://codereview.qt-project.org/5261 Reviewed-by: Qt Sanity Bot Reviewed-by: Samuel Rødal --- src/gui/kernel/qdnd.cpp | 68 ++++++++++++++++++++++++++++------------- src/gui/kernel/qdnd_p.h | 42 +++++++------------------ 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index 4ed2515115..9a90c213cf 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -51,6 +51,7 @@ #include "qpoint.h" #include "qbuffer.h" #include "qimage.h" +#include "qpainter.h" #include "qregexp.h" #include "qdir.h" #include "qdnd_p.h" @@ -277,7 +278,6 @@ QObject *QDragManager::currentTarget() } -static QPixmap *defaultPm = 0; static const int default_pm_hotx = -2; static const int default_pm_hoty = -16; static const char *const default_pm[] = { @@ -297,39 +297,65 @@ static const char *const default_pm[] = { }; +QShapedPixmapWindow::QShapedPixmapWindow() + : QWindow() +{ + setSurfaceType(RasterSurface); + setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | + Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput); + create(); + backingStore = new QBackingStore(this); +} + +void QShapedPixmapWindow::render() +{ + QRect rect(QPoint(), geometry().size()); + backingStore->resize(rect.size()); + + backingStore->beginPaint(rect); + + QPaintDevice *device = backingStore->paintDevice(); + + { + QPainter p(device); + p.drawPixmap(0, 0, pixmap); + } + + backingStore->endPaint(); + backingStore->flush(rect); +} + + + + static Qt::KeyboardModifiers oldstate; void QDragManager::updatePixmap() { if (shapedPixmapWindow) { - QPixmap pm; - QPoint pm_hot(default_pm_hotx,default_pm_hoty); + shapedPixmapWindow->pixmap = QPixmap(); + shapedPixmapWindow->hotSpot = QPoint(default_pm_hotx,default_pm_hoty); if (object) { - pm = object->pixmap(); - if (!pm.isNull()) - pm_hot = object->hotSpot(); - } - if (pm.isNull()) { - if (!defaultPm) - defaultPm = new QPixmap(default_pm); - pm = *defaultPm; - } - shapedPixmapWindow->setPixmap(pm); - shapedPixmapWindow->move(QCursor::pos()-pm_hot); - if (willDrop) { - shapedPixmapWindow->show(); - } else { - shapedPixmapWindow->hide(); + shapedPixmapWindow->pixmap = object->pixmap(); + if (!shapedPixmapWindow->pixmap.isNull()) + shapedPixmapWindow->hotSpot = object->hotSpot(); } + if (shapedPixmapWindow->pixmap.isNull()) + shapedPixmapWindow->pixmap = QPixmap(default_pm); + shapedPixmapWindow->setGeometry(QRect(QCursor::pos() - shapedPixmapWindow->hotSpot, shapedPixmapWindow->pixmap.size())); + shapedPixmapWindow->show(); + shapedPixmapWindow->render(); } } void QDragManager::updateCursor() { + if (shapedPixmapWindow) { + shapedPixmapWindow->render(); // ### Hack + shapedPixmapWindow->move(QCursor::pos() - shapedPixmapWindow->hotSpot); + } #ifndef QT_NO_CURSOR if (willDrop) { - if (shapedPixmapWindow) - shapedPixmapWindow->show(); if (currentActionForOverrideCursor != global_accepted_action) { QGuiApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0)); currentActionForOverrideCursor = global_accepted_action; @@ -340,8 +366,6 @@ void QDragManager::updateCursor() QGuiApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor)); currentActionForOverrideCursor = Qt::IgnoreAction; } - if (shapedPixmapWindow) - shapedPixmapWindow->hide(); } #endif } diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 2a81de5c7f..a94d439811 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -62,7 +62,7 @@ #include "QtGui/qwindow.h" #include "QtCore/qpoint.h" #include "private/qobject_p.h" - +#include "QtGui/qbackingstore.h" QT_BEGIN_NAMESPACE class QEventLoop; @@ -109,41 +109,21 @@ public: Qt::DropAction defaultDropAction; }; -class QShapedPixmapWindow : public QWindow { - QPixmap pixmap; +class QShapedPixmapWindow : public QWindow +{ public: - QShapedPixmapWindow() : - QWindow() + QShapedPixmapWindow(); + + void exposeEvent(QExposeEvent *) { - setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); - // ### Should we set the surface type to raster? - // ### FIXME -// setAttribute(Qt::WA_TransparentForMouseEvents); + render(); } - void move(const QPoint &p) { - QRect g = geometry(); - g.setTopLeft(p); - setGeometry(g); - } - void setPixmap(QPixmap pm) - { - pixmap = pm; - // ### -// if (!pixmap.mask().isNull()) { -// setMask(pixmap.mask()); -// } else { -// clearMask(); -// } - setGeometry(QRect(geometry().topLeft(), pm.size())); - } + void render(); - // ### Get it painted again! -// void paintEvent(QPaintEvent*) -// { -// QPainter p(this); -// p.drawPixmap(0,0,pixmap); -// } + QBackingStore *backingStore; + QPixmap pixmap; + QPoint hotSpot; };