1 /***************************************************************************
4 * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
20 ***************************************************************************/
22 #include "x11embedpainter.h"
24 #include <QtCore/QSet>
25 #include <QtCore/QTime>
26 #include <QtCore/QTimer>
32 #define MAX_PAINTS_PER_SEC 20
33 #define MIN_TIME_BETWEEN_PAINTS (1000 / MAX_PAINTS_PER_SEC)
39 class X11EmbedPainter::Private
42 Private(X11EmbedPainter
*parent
)
45 lastPaintTime
= QTime::currentTime();
46 lastPaintTime
.addMSecs(-MIN_TIME_BETWEEN_PAINTS
);
48 delayedPaintTimer
.setSingleShot(true);
49 connect(&delayedPaintTimer
, SIGNAL(timeout()),
50 q
, SLOT(performUpdates()));
54 QSet
<X11EmbedContainer
*> containers
;
56 QTimer delayedPaintTimer
;
60 X11EmbedPainter::X11EmbedPainter()
61 : d(new Private(this))
66 X11EmbedPainter::~X11EmbedPainter()
72 void X11EmbedPainter::updateContainer(X11EmbedContainer
*container
)
74 if (d
->containers
.contains(container
)) {
78 d
->containers
.insert(container
);
80 connect(container
, SIGNAL(destroyed(QObject
*)),
81 this, SLOT(removeContainer(QObject
*)));
83 if (!d
->delayedPaintTimer
.isActive()) {
84 int msecsToNextPaint
= MIN_TIME_BETWEEN_PAINTS
- d
->lastPaintTime
.elapsed();
85 if (msecsToNextPaint
> 0 && msecsToNextPaint
< MIN_TIME_BETWEEN_PAINTS
) {
86 //kDebug() << "Delaying paint by" << msecsToNextPaint << "msecs";
87 d
->delayedPaintTimer
.start(msecsToNextPaint
);
89 d
->delayedPaintTimer
.start(0);
95 void X11EmbedPainter::removeContainer(QObject
*container
)
97 d
->containers
.remove(static_cast<X11EmbedContainer
*>(container
));
101 void X11EmbedPainter::performUpdates()
103 QMultiHash
<QWidget
*, X11EmbedContainer
*> containersByParent
;
105 foreach (X11EmbedContainer
*container
, d
->containers
) {
106 QWidget
*topWidget
= container
;
107 while (topWidget
->parentWidget()) {
108 topWidget
= topWidget
->parentWidget();
110 containersByParent
.insert(topWidget
, container
);
111 container
->setUpdatesEnabled(false);
114 foreach (QWidget
*parent
, containersByParent
.uniqueKeys()) {
115 QList
<X11EmbedContainer
*> containers
= containersByParent
.values(parent
);
116 containersByParent
.remove(parent
);
119 foreach (X11EmbedContainer
*container
, containers
) {
120 QRect rect
= QRect(container
->mapTo(parent
, QPoint(0, 0)), container
->size());
121 paintRegion
= paintRegion
.united(rect
);
124 QPixmap background
= QPixmap(parent
->size());
125 parent
->render(&background
, paintRegion
.boundingRect().topLeft(), paintRegion
);
127 foreach (X11EmbedContainer
*container
, containers
) {
128 QRect rect
= QRect(container
->mapTo(parent
, QPoint(0, 0)), container
->size());
129 container
->setBackgroundPixmap(background
.copy(rect
));
133 foreach (X11EmbedContainer
*container
, d
->containers
) {
134 container
->setUpdatesEnabled(true);
135 disconnect(container
, SIGNAL(destroyed(QObject
*)),
136 this, SLOT(removeContainer(QObject
*)));
139 d
->containers
.clear();
140 d
->lastPaintTime
.start();
145 #include "x11embedpainter.moc"