Applets
x11embedpainter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "x11embedpainter.h"
00023
00024 #include <QtCore/QSet>
00025 #include <QtCore/QTime>
00026 #include <QtCore/QTimer>
00027
00028 #include <KDebug>
00029 #include <KGlobal>
00030
00031
00032 #define MAX_PAINTS_PER_SEC 20
00033 #define MIN_TIME_BETWEEN_PAINTS (1000 / MAX_PAINTS_PER_SEC)
00034
00035
00036 namespace SystemTray
00037 {
00038
00039 class X11EmbedPainter::Private
00040 {
00041 public:
00042 Private(X11EmbedPainter *parent)
00043 : q(parent)
00044 {
00045 lastPaintTime = QTime::currentTime();
00046 lastPaintTime.addMSecs(-MIN_TIME_BETWEEN_PAINTS);
00047
00048 delayedPaintTimer.setSingleShot(true);
00049 connect(&delayedPaintTimer, SIGNAL(timeout()),
00050 q, SLOT(performUpdates()));
00051 }
00052
00053 X11EmbedPainter *q;
00054 QSet<X11EmbedContainer*> containers;
00055 QTime lastPaintTime;
00056 QTimer delayedPaintTimer;
00057 };
00058
00059
00060 X11EmbedPainter::X11EmbedPainter()
00061 : d(new Private(this))
00062 {
00063 }
00064
00065
00066 X11EmbedPainter::~X11EmbedPainter()
00067 {
00068 delete d;
00069 }
00070
00071
00072 void X11EmbedPainter::updateContainer(X11EmbedContainer *container)
00073 {
00074 if (d->containers.contains(container)) {
00075 return;
00076 }
00077
00078 d->containers.insert(container);
00079
00080 connect(container, SIGNAL(destroyed(QObject*)),
00081 this, SLOT(removeContainer(QObject*)));
00082
00083 if (!d->delayedPaintTimer.isActive()) {
00084 int msecsToNextPaint = MIN_TIME_BETWEEN_PAINTS - d->lastPaintTime.elapsed();
00085 if (msecsToNextPaint > 0 && msecsToNextPaint < MIN_TIME_BETWEEN_PAINTS) {
00086
00087 d->delayedPaintTimer.start(msecsToNextPaint);
00088 } else {
00089 d->delayedPaintTimer.start(0);
00090 }
00091 }
00092 }
00093
00094
00095 void X11EmbedPainter::removeContainer(QObject *container)
00096 {
00097 d->containers.remove(static_cast<X11EmbedContainer*>(container));
00098 }
00099
00100
00101 void X11EmbedPainter::performUpdates()
00102 {
00103 QMultiHash<QWidget*, X11EmbedContainer*> containersByParent;
00104
00105 foreach (X11EmbedContainer *container, d->containers) {
00106 QWidget *topWidget = container;
00107 while (topWidget->parentWidget()) {
00108 topWidget = topWidget->parentWidget();
00109 }
00110 containersByParent.insert(topWidget, container);
00111 container->setUpdatesEnabled(false);
00112 }
00113
00114 foreach (QWidget *parent, containersByParent.uniqueKeys()) {
00115 QList<X11EmbedContainer*> containers = containersByParent.values(parent);
00116 containersByParent.remove(parent);
00117
00118 QRegion paintRegion;
00119 foreach (X11EmbedContainer *container, containers) {
00120 QRect rect = QRect(container->mapTo(parent, QPoint(0, 0)), container->size());
00121 paintRegion = paintRegion.united(rect);
00122 }
00123
00124 QPixmap background = QPixmap(parent->size());
00125 parent->render(&background, paintRegion.boundingRect().topLeft(), paintRegion);
00126
00127 foreach (X11EmbedContainer *container, containers) {
00128 QRect rect = QRect(container->mapTo(parent, QPoint(0, 0)), container->size());
00129 container->setBackgroundPixmap(background.copy(rect));
00130 }
00131 }
00132
00133 foreach (X11EmbedContainer *container, d->containers) {
00134 container->setUpdatesEnabled(true);
00135 disconnect(container, SIGNAL(destroyed(QObject*)),
00136 this, SLOT(removeContainer(QObject*)));
00137 }
00138
00139 d->containers.clear();
00140 d->lastPaintTime.start();
00141 }
00142
00143 }
00144
00145 #include "x11embedpainter.moc"