Reimplement QShapedPixmapWindow using QRasterWindow.

The current implementation makes the window too big when
a QPixmap with a DPR != 1 is set. Circumvent the problem
by using a QRasterWindow.

Task-number: QTBUG-46068
Task-number: QTBUG-50938
Change-Id: I0fca91f571937250c740f1400bd60286330fb595
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
Reviewed-by: Alexander Volkov <a.volkov@rusbitech.ru>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
bb10
Friedemann Kleint 2016-01-29 14:03:41 +01:00
parent d3744eff86
commit abe3217bac
2 changed files with 33 additions and 49 deletions

View File

@ -42,52 +42,31 @@
QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
: QWindow(screen),
m_backingStore(0),
m_useCompositing(true)
: m_useCompositing(true)
{
setScreen(screen);
QSurfaceFormat format;
format.setAlphaBufferSize(8);
setFormat(format);
setSurfaceType(RasterSurface);
setFlags(Qt::ToolTip | Qt::FramelessWindowHint |
Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
create();
m_backingStore = new QBackingStore(this);
setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint
| Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
}
QShapedPixmapWindow::~QShapedPixmapWindow()
{
delete m_backingStore;
m_backingStore = 0;
}
void QShapedPixmapWindow::render()
{
QRect rect(QPoint(), geometry().size());
m_backingStore->beginPaint(rect);
QPaintDevice *device = m_backingStore->paintDevice();
{
QPainter p(device);
if (m_useCompositing)
p.setCompositionMode(QPainter::CompositionMode_Source);
else
p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
m_backingStore->endPaint();
m_backingStore->flush(rect);
}
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
if (!m_useCompositing)
setMask(m_pixmap.mask());
if (!m_useCompositing) {
const QBitmap mask = m_pixmap.mask();
if (!mask.isNull()) {
if (!handle())
create();
setMask(mask);
}
}
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
@ -95,19 +74,28 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
m_hotSpot = hotspot;
}
void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
void QShapedPixmapWindow::paintEvent(QPaintEvent *)
{
if (m_pixmap.isNull())
m_backingStore->resize(QSize(1,1));
else if (m_backingStore->size() != m_pixmap.size())
m_backingStore->resize(m_pixmap.size());
setGeometry(QRect(pos - m_hotSpot, m_backingStore->size()));
if (!m_pixmap.isNull()) {
const QRect rect(QPoint(0, 0), size());
QPainter painter(this);
if (m_useCompositing)
painter.setCompositionMode(QPainter::CompositionMode_Source);
else
painter.fillRect(rect, QGuiApplication::palette().base());
painter.drawPixmap(rect, m_pixmap);
}
}
void QShapedPixmapWindow::exposeEvent(QExposeEvent *)
void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
{
render();
QSize size(1, 1);
if (!m_pixmap.isNull()) {
size = qFuzzyCompare(m_pixmap.devicePixelRatio(), 1.0)
? m_pixmap.size()
: (QSizeF(m_pixmap.size()) / m_pixmap.devicePixelRatio()).toSize();
}
setGeometry(QRect(pos - m_hotSpot, size));
}
QT_END_NAMESPACE

View File

@ -45,21 +45,18 @@
// We mean it.
//
#include <QtGui/QWindow>
#include <QtGui/QRasterWindow>
#include <QtGui/QPixmap>
#include <QtGui/QBackingStore>
QT_BEGIN_NAMESPACE
class QShapedPixmapWindow : public QWindow
class QShapedPixmapWindow : public QRasterWindow
{
Q_OBJECT
public:
explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow();
void render();
void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@ -67,10 +64,9 @@ public:
void updateGeometry(const QPoint &pos);
protected:
void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
bool m_useCompositing;