Qt 4.8
qbackingstore.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
43 #include "qplatformdefs.h"
44 
45 #include "qbackingstore_p.h"
46 
47 #include <QtCore/qglobal.h>
48 #include <QtCore/qdebug.h>
49 #include <QtCore/qvarlengtharray.h>
50 #include <QtGui/qevent.h>
51 #include <QtGui/qapplication.h>
52 #include <QtGui/qpaintengine.h>
53 #include <QtGui/qgraphicsproxywidget.h>
54 
55 #include <private/qwidget_p.h>
56 #include <private/qwindowsurface_raster_p.h>
57 #include <private/qapplication_p.h>
58 #include <private/qpaintengine_raster_p.h>
59 #include <private/qgraphicseffect_p.h>
60 
61 #include "qgraphicssystem_p.h"
62 
63 #ifdef Q_WS_QWS
64 #include <QtGui/qwsmanager_qws.h>
65 #include <private/qwsmanager_p.h>
66 #endif
67 
69 
71 
72 /*
73  A version of QRect::intersects() that does not normalize the rects.
74 */
75 static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
76 {
77  return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right())
78  && qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
79 }
80 
86 static inline void qt_flush(QWidget *widget, const QRegion &region, QWindowSurface *windowSurface,
87  QWidget *tlw, const QPoint &tlwOffset)
88 {
89  Q_ASSERT(widget);
90  Q_ASSERT(!region.isEmpty());
91  Q_ASSERT(windowSurface);
92  Q_ASSERT(tlw);
93 
94 #if !defined(QT_NO_PAINT_DEBUG) && !defined(Q_WS_QWS)
95  // QWS does flush update in QWindowSurface::flush (because it needs to lock the surface etc).
96  static int flushUpdate = qgetenv("QT_FLUSH_UPDATE").toInt();
97  if (flushUpdate > 0)
98  QWidgetBackingStore::showYellowThing(widget, region, flushUpdate * 10, false);
99 #endif
100 
101  //The performance hit by doing this should be negligible. However, be aware that
102  //using this FPS when you have > 1 windowsurface can give you inaccurate FPS
103  static bool fpsDebug = qgetenv("QT_DEBUG_FPS").toInt();
104  if (fpsDebug) {
105  static QTime time = QTime::currentTime();
106  static int frames = 0;
107 
108  frames++;
109 
110  if(time.elapsed() > 5000) {
111  double fps = double(frames * 1000) /time.restart();
112  fprintf(stderr,"FPS: %.1f\n",fps);
113  frames = 0;
114  }
115  }
116  if (widget != tlw)
117  windowSurface->flush(widget, region, tlwOffset + widget->mapTo(tlw, QPoint()));
118  else
119  windowSurface->flush(widget, region, tlwOffset);
120 }
121 
122 #ifndef QT_NO_PAINT_DEBUG
123 #ifdef Q_WS_WIN
124 static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
125 {
126  HBRUSH brush;
127  static int i = 0;
128  switch (i) {
129  case 0:
130  brush = CreateSolidBrush(RGB(255, 255, 0));
131  break;
132  case 1:
133  brush = CreateSolidBrush(RGB(255, 200, 55));
134  break;
135  case 2:
136  brush = CreateSolidBrush(RGB(200, 255, 55));
137  break;
138  case 3:
139  brush = CreateSolidBrush(RGB(200, 200, 0));
140  break;
141  }
142  i = (i + 1) & 3;
143 
144  HDC hdc = widget->getDC();
145 
146  const QVector<QRect> &rects = region.rects();
147  foreach (QRect rect, rects) {
148  RECT winRect;
149  SetRect(&winRect, rect.left(), rect.top(), rect.right(), rect.bottom());
150  FillRect(hdc, &winRect, brush);
151  }
152 
153  widget->releaseDC(hdc);
154  ::Sleep(msec);
155 }
156 #endif
157 
158 void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped)
159 {
160 #ifdef Q_WS_QWS
161  Q_UNUSED(widget);
162  Q_UNUSED(unclipped);
163  static QWSYellowSurface surface(true);
164  surface.setDelay(msec);
165  surface.flush(widget, toBePainted, QPoint());
166 #else
167  QRegion paintRegion = toBePainted;
168  QRect widgetRect = widget->rect();
169 
170  if (!widget->internalWinId()) {
171  QWidget *nativeParent = widget->nativeParentWidget();
172  const QPoint offset = widget->mapTo(nativeParent, QPoint(0, 0));
173  paintRegion.translate(offset);
174  widgetRect.translate(offset);
175  widget = nativeParent;
176  }
177 
178 #ifdef Q_WS_WIN
179  Q_UNUSED(unclipped);
180  showYellowThing_win(widget, paintRegion, msec);
181 #else
182  //flags to fool painter
183  bool paintUnclipped = widget->testAttribute(Qt::WA_PaintUnclipped);
184  if (unclipped && !widget->d_func()->paintOnScreen())
186 
187  const bool setFlag = !widget->testAttribute(Qt::WA_WState_InPaintEvent);
188  if (setFlag)
190 
191  //setup the engine
192  QPaintEngine *pe = widget->paintEngine();
193  if (pe) {
194  pe->setSystemClip(paintRegion);
195  {
196  QPainter p(widget);
197  p.setClipRegion(paintRegion);
198  static int i = 0;
199  switch (i) {
200  case 0:
201  p.fillRect(widgetRect, QColor(255,255,0));
202  break;
203  case 1:
204  p.fillRect(widgetRect, QColor(255,200,55));
205  break;
206  case 2:
207  p.fillRect(widgetRect, QColor(200,255,55));
208  break;
209  case 3:
210  p.fillRect(widgetRect, QColor(200,200,0));
211  break;
212  }
213  i = (i+1) & 3;
214  p.end();
215  }
216  }
217 
218  if (setFlag)
220 
221  //restore
222  widget->setAttribute(Qt::WA_PaintUnclipped, paintUnclipped);
223 
224  if (pe)
225  pe->setSystemClip(QRegion());
226 
228 
229 #if defined(Q_OS_UNIX)
230  ::usleep(1000 * msec);
231 #endif
232 #endif // Q_WS_WIN
233 #endif // Q_WS_QWS
234 }
235 
237 {
238  if (!widget)
239  return false;
240 
241  int delay = 0;
243  static int flushPaintEvent = qgetenv("QT_FLUSH_PAINT_EVENT").toInt();
244  if (!flushPaintEvent)
245  return false;
246  delay = flushPaintEvent;
247  } else {
248  static int flushPaint = qgetenv("QT_FLUSH_PAINT").toInt();
249  if (!flushPaint)
250  return false;
251  delay = flushPaint;
252  }
253 
254  QWidgetBackingStore::showYellowThing(widget, rgn, delay * 10, true);
255  return true;
256 }
257 
259 {
260  if (widget->d_func()->paintOnScreen() || rgn.isEmpty())
261  return;
262 
263  QWidget *tlw = widget->window();
264  QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
265  if (!tlwExtra)
266  return;
267 
268  const QPoint offset = widget->mapTo(tlw, QPoint());
269  qt_flush(widget, rgn, tlwExtra->backingStore->windowSurface, tlw, offset);
270 }
271 #endif // QT_NO_PAINT_DEBUG
272 
273 /*
274  Moves the whole rect by (dx, dy) in widget's coordinate system.
275  Doesn't generate any updates.
276 */
277 bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
278 {
279  const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft()));
280  const QRect tlwRect(QRect(pos, rect.size()));
281  if (fullUpdatePending || dirty.intersects(tlwRect))
282  return false; // We don't want to scroll junk.
283  return windowSurface->scroll(tlwRect, dx, dy);
284 }
285 
287 {
288  if (windowSurface)
289 #if defined(Q_WS_QPA)
290  windowSurface->resize(QSize());
291 #else
293 #endif
294 #ifdef Q_BACKINGSTORE_SUBSURFACES
295  for (int i = 0; i < subSurfaces.size(); ++i)
296  subSurfaces.at(i)->setGeometry(QRect());
297 #endif
298 }
299 
307  BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates)
308 {
309 #ifdef Q_WS_QWS
311  QWidget *surfaceWidget = surface->window();
312 
313  if (!surface->isValid()) {
314  // this looks strange but it really just releases the surface
315  surface->releaseSurface();
316  // the old window surface is deleted in setWindowSurface, which is
317  // called from QWindowSurface constructor.
318  windowSurface = tlw->d_func()->createDefaultWindowSurface();
319  surface = static_cast<QWSWindowSurface *>(windowSurface);
320  // createDefaultWindowSurface() will set topdata->windowSurface on the
321  // widget to zero. However, if this is a sub-surface, it should point
322  // to the widget's sub windowSurface, so we set that here:
323  if (!surfaceWidget->isWindow())
324  surfaceWidget->d_func()->topData()->windowSurface = windowSurface;
325  surface->setGeometry(topLevelRect());
326  returnInfo->windowSurfaceRecreated = true;
327  }
328 
329  const QRegion toCleanUnclipped(toClean);
330 
331  if (surfaceWidget->isWindow())
332  tlwOffset = surface->painterOffset();
333 #ifdef Q_BACKINGSTORE_SUBSURFACES
334  else if (toCleanIsInTopLevelCoordinates)
335  toClean &= surface->clipRegion().translated(surfaceWidget->mapTo(tlw, QPoint()));
336  if (!toCleanIsInTopLevelCoordinates && windowSurface == this->windowSurface)
337  toClean &= surface->clipRegion().translated(-widget->mapTo(surfaceWidget, QPoint()));
338 #else
339  toClean &= surface->clipRegion();
340 #endif
341 
342  if (toClean.isEmpty()) {
343  if (surfaceWidget->isWindow()) {
344  dirtyFromPreviousSync += toCleanUnclipped;
346  }
347 
348  returnInfo->nothingToPaint = true;
349  // Nothing to repaint. However, we might have newly exposed areas on the
350  // screen, so we have to make sure those are flushed.
351  flush();
352  return;
353  }
354 
355  if (surfaceWidget->isWindow()) {
356  if (toCleanUnclipped != toClean) {
357  dirtyFromPreviousSync += (toCleanUnclipped - surface->clipRegion());
359  }
361  dirtyFromPreviousSync -= toClean;
363  }
364  }
365 
366 #endif // Q_WS_QWS
367 
368  Q_UNUSED(widget);
369  Q_UNUSED(toCleanIsInTopLevelCoordinates);
370 
371  // Always flush repainted areas.
372  dirtyOnScreen += toClean;
373 
374 #if defined(Q_WS_QWS) && !defined(Q_BACKINGSTORE_SUBSURFACES)
375  toClean.translate(tlwOffset);
376 #endif
377 
378 #ifdef QT_NO_PAINT_DEBUG
379  windowSurface->beginPaint(toClean);
380 #else
381  returnInfo->wasFlushed = QWidgetBackingStore::flushPaint(tlw, toClean);
382  // Avoid deadlock with QT_FLUSH_PAINT: the server will wait for
383  // the BackingStore lock, so if we hold that, the server will
384  // never release the Communication lock that we are waiting for in
385  // sendSynchronousCommand
386  if (!returnInfo->wasFlushed)
387  windowSurface->beginPaint(toClean);
388 #endif
389 
390  Q_UNUSED(returnInfo);
391 }
392 
394  BeginPaintInfo *beginPaintInfo)
395 {
396 #ifndef QT_NO_PAINT_DEBUG
397  if (!beginPaintInfo->wasFlushed)
398  windowSurface->endPaint(cleaned);
399  else
401 #else
402  Q_UNUSED(beginPaintInfo);
403  windowSurface->endPaint(cleaned);
404 #endif
405 
406 #ifdef Q_BACKINGSTORE_SUBSURFACES
407  flush(static_cast<QWSWindowSurface *>(windowSurface)->window(), windowSurface);
408 #else
409  flush();
410 #endif
411 }
412 
420 {
421  const bool widgetDirty = widget && widget != tlw;
422  const QRect tlwRect(topLevelRect());
423 #if defined(Q_WS_QPA)
424  const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size());
425 #else
426  const QRect surfaceGeometry(windowSurface->geometry());
427 #endif
428  if (fullUpdatePending || (surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size())) {
429  if (widgetDirty) {
430  const QRect dirtyTlwRect = QRect(QPoint(), tlwRect.size());
431  const QPoint offset(widget->mapTo(tlw, QPoint()));
432  const QRect dirtyWidgetRect(dirtyTlwRect & widget->rect().translated(offset));
433  return dirtyWidgetRect.translated(-offset);
434  }
435  return QRect(QPoint(), tlwRect.size());
436  }
437 
438  // Calculate the region that needs repaint.
439  QRegion r(dirty);
440  for (int i = 0; i < dirtyWidgets.size(); ++i) {
441  QWidget *w = dirtyWidgets.at(i);
442  if (widgetDirty && w != widget && !widget->isAncestorOf(w))
443  continue;
444  r += w->d_func()->dirty.translated(w->mapTo(tlw, QPoint()));
445  }
446 
447  // Append the region that needs flush.
448  r += dirtyOnScreen;
449 
450  if (dirtyOnScreenWidgets) { // Only in use with native child widgets.
451  for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
453  if (widgetDirty && w != widget && !widget->isAncestorOf(w))
454  continue;
455  QWidgetPrivate *wd = w->d_func();
456  Q_ASSERT(wd->needsFlush);
457  r += wd->needsFlush->translated(w->mapTo(tlw, QPoint()));
458  }
459  }
460 
461  if (widgetDirty) {
462  // Intersect with the widget geometry and translate to its coordinates.
463  const QPoint offset(widget->mapTo(tlw, QPoint()));
464  r &= widget->rect().translated(offset);
465  r.translate(-offset);
466  }
467  return r;
468 }
469 
475 QRegion QWidgetBackingStore::staticContents(QWidget *parent, const QRect &withinClipRect) const
476 {
477  if (!parent && tlw->testAttribute(Qt::WA_StaticContents)) {
478 #if defined(Q_WS_QPA)
479  const QSize surfaceGeometry(windowSurface->size());
480 #else
481  const QRect surfaceGeometry(windowSurface->geometry());
482 #endif
483  QRect surfaceRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
484  if (!withinClipRect.isEmpty())
485  surfaceRect &= withinClipRect;
486  return QRegion(surfaceRect);
487  }
488 
489  QRegion region;
490  if (parent && parent->d_func()->children.isEmpty())
491  return region;
492 
493  const bool clipToRect = !withinClipRect.isEmpty();
494  const int count = staticWidgets.count();
495  for (int i = 0; i < count; ++i) {
496  QWidget *w = staticWidgets.at(i);
497  QWidgetPrivate *wd = w->d_func();
498  if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty()
499  || !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
500  continue;
501  }
502 
504  const QPoint offset = w->mapTo(parent ? parent : tlw, QPoint());
505  if (clipToRect)
506  rect &= withinClipRect.translated(-offset);
507  if (rect.isEmpty())
508  continue;
509 
510  rect &= wd->clipRect();
511  if (rect.isEmpty())
512  continue;
513 
514  QRegion visible(rect);
515  wd->clipToEffectiveMask(visible);
516  if (visible.isEmpty())
517  continue;
518  wd->subtractOpaqueSiblings(visible, 0, /*alsoNonOpaque=*/true);
519 
520  visible.translate(offset);
521  region += visible;
522  }
523 
524  return region;
525 }
526 
527 static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
528 {
529  if (!widget)
530  return;
531 
532  if (updateImmediately) {
534  QApplication::sendEvent(widget, &event);
535  } else {
537  }
538 }
539 
553 void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately,
554  bool invalidateBuffer)
555 {
556  Q_ASSERT(tlw->d_func()->extra);
557  Q_ASSERT(tlw->d_func()->extra->topextra);
558  Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
559  Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
560  Q_ASSERT(widget->window() == tlw);
561  Q_ASSERT(!rgn.isEmpty());
562 
563 #ifndef QT_NO_GRAPHICSEFFECT
564  widget->d_func()->invalidateGraphicsEffectsRecursively();
565 #endif //QT_NO_GRAPHICSEFFECT
566 
567  if (widget->d_func()->paintOnScreen()) {
568  if (widget->d_func()->dirty.isEmpty()) {
569  widget->d_func()->dirty = rgn;
570  sendUpdateRequest(widget, updateImmediately);
571  return;
572  } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) {
573  if (updateImmediately)
574  sendUpdateRequest(widget, updateImmediately);
575  return; // Already dirty.
576  }
577 
578  const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
579  widget->d_func()->dirty += rgn;
580  if (!eventAlreadyPosted || updateImmediately)
581  sendUpdateRequest(widget, updateImmediately);
582  return;
583  }
584 
585  if (fullUpdatePending) {
586  if (updateImmediately)
587  sendUpdateRequest(tlw, updateImmediately);
588  return;
589  }
590 
592  fullUpdatePending = true;
593  sendUpdateRequest(tlw, updateImmediately);
594  return;
595  }
596 
597  const QPoint offset = widget->mapTo(tlw, QPoint());
598  const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
599  if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
600  if (updateImmediately)
601  sendUpdateRequest(tlw, updateImmediately);
602  return; // Already dirty.
603  }
604 
605  if (invalidateBuffer) {
606  const bool eventAlreadyPosted = !dirty.isEmpty();
607 #ifndef QT_NO_GRAPHICSEFFECT
608  if (widget->d_func()->graphicsEffect)
609  dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
610  else
611 #endif //QT_NO_GRAPHICSEFFECT
612  dirty += rgn.translated(offset);
613  if (!eventAlreadyPosted || updateImmediately)
614  sendUpdateRequest(tlw, updateImmediately);
615  return;
616  }
617 
618  if (dirtyWidgets.isEmpty()) {
619  addDirtyWidget(widget, rgn);
620  sendUpdateRequest(tlw, updateImmediately);
621  return;
622  }
623 
624  if (widget->d_func()->inDirtyList) {
625  if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
626 #ifndef QT_NO_GRAPHICSEFFECT
627  if (widget->d_func()->graphicsEffect)
628  widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
629  else
630 #endif //QT_NO_GRAPHICSEFFECT
631  widget->d_func()->dirty += rgn;
632  }
633  } else {
634  addDirtyWidget(widget, rgn);
635  }
636 
637  if (updateImmediately)
638  sendUpdateRequest(tlw, updateImmediately);
639 }
640 
648 void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool updateImmediately,
649  bool invalidateBuffer)
650 {
651  Q_ASSERT(tlw->d_func()->extra);
652  Q_ASSERT(tlw->d_func()->extra->topextra);
653  Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
654  Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
655  Q_ASSERT(widget->window() == tlw);
656  Q_ASSERT(!rect.isEmpty());
657 
658 #ifndef QT_NO_GRAPHICSEFFECT
659  widget->d_func()->invalidateGraphicsEffectsRecursively();
660 #endif //QT_NO_GRAPHICSEFFECT
661 
662  if (widget->d_func()->paintOnScreen()) {
663  if (widget->d_func()->dirty.isEmpty()) {
664  widget->d_func()->dirty = QRegion(rect);
665  sendUpdateRequest(widget, updateImmediately);
666  return;
667  } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) {
668  if (updateImmediately)
669  sendUpdateRequest(widget, updateImmediately);
670  return; // Already dirty.
671  }
672 
673  const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
674  widget->d_func()->dirty += rect;
675  if (!eventAlreadyPosted || updateImmediately)
676  sendUpdateRequest(widget, updateImmediately);
677  return;
678  }
679 
680  if (fullUpdatePending) {
681  if (updateImmediately)
682  sendUpdateRequest(tlw, updateImmediately);
683  return;
684  }
685 
687  fullUpdatePending = true;
688  sendUpdateRequest(tlw, updateImmediately);
689  return;
690  }
691 
692  const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
693  const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));
694  if (qt_region_strictContains(dirty, translatedRect)) {
695  if (updateImmediately)
696  sendUpdateRequest(tlw, updateImmediately);
697  return; // Already dirty
698  }
699 
700  if (invalidateBuffer) {
701  const bool eventAlreadyPosted = !dirty.isEmpty();
702  dirty += translatedRect;
703  if (!eventAlreadyPosted || updateImmediately)
704  sendUpdateRequest(tlw, updateImmediately);
705  return;
706  }
707 
708  if (dirtyWidgets.isEmpty()) {
709  addDirtyWidget(widget, rect);
710  sendUpdateRequest(tlw, updateImmediately);
711  return;
712  }
713 
714  if (widget->d_func()->inDirtyList) {
715  if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect))
716  widget->d_func()->dirty += widgetRect;
717  } else {
718  addDirtyWidget(widget, rect);
719  }
720 
721  if (updateImmediately)
722  sendUpdateRequest(tlw, updateImmediately);
723 }
724 
732 {
733  if (!widget || widget->d_func()->paintOnScreen() || region.isEmpty())
734  return;
735 
736 #if defined(Q_WS_QWS) || defined(Q_WS_MAC)
738  dirtyOnScreen += region.translated(topLevelOffset);
739  return;
740 #endif
741 
742  // Top-level.
743  if (widget == tlw) {
745  dirtyOnScreen += region;
746  return;
747  }
748 
749  // Alien widgets.
750  if (!widget->internalWinId() && !widget->isWindow()) {
751  QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case).
752  if (nativeParent == tlw) {
754  dirtyOnScreen += region.translated(topLevelOffset);
755  return;
756  }
757 
758  // Alien widgets with native parent != tlw.
759  QWidgetPrivate *nativeParentPrivate = nativeParent->d_func();
760  if (!nativeParentPrivate->needsFlush)
761  nativeParentPrivate->needsFlush = new QRegion;
762  const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint());
763  *nativeParentPrivate->needsFlush += region.translated(nativeParentOffset);
764  appendDirtyOnScreenWidget(nativeParent);
765  return;
766  }
767 
768  // Native child widgets.
769  QWidgetPrivate *widgetPrivate = widget->d_func();
770  if (!widgetPrivate->needsFlush)
771  widgetPrivate->needsFlush = new QRegion;
772  *widgetPrivate->needsFlush += region;
774 }
775 
777 {
778  if (!w)
779  return;
780 
783  resetWidget(w);
784 
785  QWidgetPrivate *wd = w->d_func();
786  const int n = wd->children.count();
787  for (int i = 0; i < n; ++i) {
788  if (QWidget *child = qobject_cast<QWidget*>(wd->children.at(i)))
789  removeDirtyWidget(child);
790  }
791 }
792 
793 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
794 bool QWidgetBackingStore::hasDirtyWindowDecoration() const
795 {
796  QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
797  if (tlwExtra && tlwExtra->qwsManager)
798  return !tlwExtra->qwsManager->d_func()->dirtyRegions.isEmpty();
799  return false;
800 }
801 
802 void QWidgetBackingStore::paintWindowDecoration()
803 {
804  if (!hasDirtyWindowDecoration())
805  return;
806 
807  QDecoration &decoration = QApplication::qwsDecoration();
808  const QRect decorationRect = tlw->rect();
809  QRegion decorationRegion = decoration.region(tlw, decorationRect);
810 
811  QWSManagerPrivate *managerPrivate = tlw->d_func()->topData()->qwsManager->d_func();
812  const bool doClipping = !managerPrivate->entireDecorationNeedsRepaint
813  && !managerPrivate->dirtyClip.isEmpty();
814 
815  if (doClipping) {
816  decorationRegion &= static_cast<QWSWindowSurface *>(windowSurface)->clipRegion();
817  decorationRegion &= managerPrivate->dirtyClip;
818  }
819 
820  if (decorationRegion.isEmpty())
821  return;
822 
823  //### The QWS decorations do not always paint the pixels they promise to paint.
824  // This causes painting problems with QWSMemorySurface. Since none of the other
825  // window surfaces actually use the region, passing an empty region is a safe
826  // workaround.
827 
829 
831  Q_ASSERT(engine);
832  const QRegion oldSystemClip(engine->systemClip());
833  engine->setSystemClip(decorationRegion.translated(tlwOffset));
834 
835  QPainter painter(windowSurface->paintDevice());
836  painter.setFont(QApplication::font());
837  painter.translate(tlwOffset);
838 
839  const int numDirty = managerPrivate->dirtyRegions.size();
840  for (int i = 0; i < numDirty; ++i) {
841  const int area = managerPrivate->dirtyRegions.at(i);
842 
843  QRegion clipRegion = decoration.region(tlw, decorationRect, area);
844  if (!clipRegion.isEmpty()) {
845  // Decoration styles changes the clip and assumes the old clip is non-empty,
846  // so we have to set it, but in theory it shouldn't be required.
847  painter.setClipRegion(clipRegion);
848  decoration.paint(&painter, tlw, area, managerPrivate->dirtyStates.at(i));
849  }
850  }
851  markDirtyOnScreen(decorationRegion, tlw, QPoint());
852 
853  painter.end();
854  windowSurface->endPaint(decorationRegion);
855  managerPrivate->clearDirtyRegions();
856  engine->setSystemClip(oldSystemClip);
857 }
858 #endif
859 
861 {
862  if (!cur)
863  return;
864 
865  QList<QObject*> children = cur->children();
866  for (int i = 0; i < children.size(); ++i) {
867  QWidget *child = qobject_cast<QWidget*>(children.at(i));
868  if (!child)
869  continue;
870 
871  updateLists(child);
872  }
873 
875  addStaticWidget(cur);
876 
877 #ifdef Q_BACKINGSTORE_SUBSURFACES
878  QTLWExtra *extra = cur->d_func()->maybeTopData();
879  if (extra && extra->windowSurface && cur != tlw)
880  subSurfaces.append(extra->windowSurface);
881 #endif
882 }
883 
885  : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false)
886  , fullUpdatePending(0)
887 {
889  if (!windowSurface)
890  windowSurface = topLevel->d_func()->createDefaultWindowSurface();
891 
892  // The QWindowSurface constructor will call QWidget::setWindowSurface(),
893  // but automatically created surfaces should not be added to the topdata.
894 #ifdef Q_BACKINGSTORE_SUBSURFACES
895  Q_ASSERT(topLevel->d_func()->topData()->windowSurface == windowSurface);
896 #endif
897  topLevel->d_func()->topData()->windowSurface = 0;
898 
899  // Ensure all existing subsurfaces and static widgets are added to their respective lists.
900  updateLists(topLevel);
901 }
902 
904 {
905  for (int c = 0; c < dirtyWidgets.size(); ++c) {
907  }
908 
909  delete windowSurface;
910  windowSurface = 0;
911  delete dirtyOnScreenWidgets;
913 }
914 
915 //parent's coordinates; move whole rect; update parent and widget
916 //assume the screen blt has already been done, so we don't need to refresh that part
917 void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
918 {
919  Q_Q(QWidget);
920  if (!q->isVisible() || (dx == 0 && dy == 0))
921  return;
922 
923  QWidget *tlw = q->window();
924  QTLWExtra* x = tlw->d_func()->topData();
925  if (x->inTopLevelResize)
926  return;
927 
928  static int accelEnv = -1;
929  if (accelEnv == -1) {
930  accelEnv = qgetenv("QT_NO_FAST_MOVE").toInt() == 0;
931  }
932 
933  QWidget *pw = q->parentWidget();
934  QPoint toplevelOffset = pw->mapTo(tlw, QPoint());
935  QWidgetPrivate *pd = pw->d_func();
936  QRect clipR(pd->clipRect());
937 #ifdef Q_WS_QWS
939  QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
940  clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect());
941 #endif
942  const QRect newRect(rect.translated(dx, dy));
943  QRect destRect = rect.intersected(clipR);
944  if (destRect.isValid())
945  destRect = destRect.translated(dx, dy).intersected(clipR);
946  const QRect sourceRect(destRect.translated(-dx, -dy));
947  const QRect parentRect(rect & clipR);
948 
949  bool accelerateMove = accelEnv && isOpaque
950 #ifndef QT_NO_GRAPHICSVIEW
951  // No accelerate move for proxy widgets.
952  && !tlw->d_func()->extra->proxyWidget
953 #endif
954  && !isOverlapped(sourceRect) && !isOverlapped(destRect);
955 
956  if (!accelerateMove) {
957  QRegion parentR(effectiveRectFor(parentRect));
958  if (!extra || !extra->hasMask) {
959  parentR -= newRect;
960  } else {
961  // invalidateBuffer() excludes anything outside the mask
962  parentR += newRect & clipR;
963  }
964  pd->invalidateBuffer(parentR);
965  invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft()));
966  } else {
967 
969  QRegion childExpose(newRect & clipR);
970 
971  if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw))
972  childExpose -= destRect;
973 
974  if (!pw->updatesEnabled())
975  return;
976 
977  const bool childUpdatesEnabled = q->updatesEnabled();
978  if (childUpdatesEnabled && !childExpose.isEmpty()) {
979  childExpose.translate(-data.crect.topLeft());
980  wbs->markDirty(childExpose, q);
981  isMoved = true;
982  }
983 
984  QRegion parentExpose(parentRect);
985  parentExpose -= newRect;
986  if (extra && extra->hasMask)
987  parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft());
988 
989  if (!parentExpose.isEmpty()) {
990  wbs->markDirty(parentExpose, pw);
991  pd->isMoved = true;
992  }
993 
994  if (childUpdatesEnabled) {
995  QRegion needsFlush(sourceRect);
996  needsFlush += destRect;
997  wbs->markDirtyOnScreen(needsFlush, pw, toplevelOffset);
998  }
999  }
1000 }
1001 
1002 //widget's coordinates; scroll within rect; only update widget
1003 void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
1004 {
1005  Q_Q(QWidget);
1006  QWidget *tlw = q->window();
1007  QTLWExtra* x = tlw->d_func()->topData();
1008  if (x->inTopLevelResize)
1009  return;
1010 
1012  if (!wbs)
1013  return;
1014 
1015  static int accelEnv = -1;
1016  if (accelEnv == -1) {
1017  accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0;
1018  }
1019 
1020  QRect scrollRect = rect & clipRect();
1021  bool overlapped = false;
1022  bool accelerateScroll = accelEnv && isOpaque
1023  && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
1024 
1025 #if defined(Q_WS_QWS)
1027  surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
1028 
1029  if (accelerateScroll && !surface->isBuffered()) {
1030  const QRegion surfaceClip = surface->clipRegion();
1031  const QRegion outsideClip = QRegion(rect) - surfaceClip;
1032  if (!outsideClip.isEmpty()) {
1033  const QVector<QRect> clipped = (surfaceClip & rect).rects();
1034  if (clipped.size() < 8) {
1035  for (int i = 0; i < clipped.size(); ++i)
1036  this->scrollRect(clipped.at(i), dx, dy);
1037  return;
1038  } else {
1039  accelerateScroll = false;
1040  }
1041  }
1042  }
1043 #endif // Q_WS_QWS
1044 
1045  if (!accelerateScroll) {
1046  if (overlapped) {
1047  QRegion region(scrollRect);
1048  subtractOpaqueSiblings(region);
1049  invalidateBuffer(region);
1050  }else {
1051  invalidateBuffer(scrollRect);
1052  }
1053  } else {
1054  const QPoint toplevelOffset = q->mapTo(tlw, QPoint());
1055 #ifdef Q_WS_QWS
1056  QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
1057  const QRegion clip = surface->clipRegion().translated(-toplevelOffset) & scrollRect;
1058  const QRect clipBoundingRect = clip.boundingRect();
1059  scrollRect &= clipBoundingRect;
1060 #endif
1061  const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
1062  const QRect sourceRect = destRect.translated(-dx, -dy);
1063 
1064  QRegion childExpose(scrollRect);
1065  if (sourceRect.isValid()) {
1066  if (wbs->bltRect(sourceRect, dx, dy, q))
1067  childExpose -= destRect;
1068  }
1069 
1070  if (inDirtyList) {
1071  if (rect == q->rect()) {
1072  dirty.translate(dx, dy);
1073  } else {
1074  QRegion dirtyScrollRegion = dirty.intersected(scrollRect);
1075  if (!dirtyScrollRegion.isEmpty()) {
1076  dirty -= dirtyScrollRegion;
1077  dirtyScrollRegion.translate(dx, dy);
1078  dirty += dirtyScrollRegion;
1079  }
1080  }
1081  }
1082 
1083  if (!q->updatesEnabled())
1084  return;
1085 
1086  if (!childExpose.isEmpty()) {
1087  wbs->markDirty(childExpose, q);
1088  isScrolled = true;
1089  }
1090 
1091  // Instead of using native scroll-on-screen, we copy from
1092  // backingstore, giving only one screen update for each
1093  // scroll, and a solid appearance
1094  wbs->markDirtyOnScreen(destRect, q, toplevelOffset);
1095  }
1096 }
1097 
1098 static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
1099 {
1100  if (!tlw || !tlwExtra)
1101  return true;
1102 
1103 #ifdef Q_WS_X11
1104  // Delay the sync until we get an Expose event from X11 (initial show).
1105  // Qt::WA_Mapped is set to true, but the actual mapping has not yet occurred.
1106  // However, we must repaint immediately regardless of the state if someone calls repaint().
1107  if (tlwExtra->waitingForMapNotify && !tlwExtra->inRepaint)
1108  return true;
1109 #endif
1110 
1111  if (!tlw->testAttribute(Qt::WA_Mapped))
1112  return true;
1113 
1114  if (!tlw->isVisible()
1115 #ifndef Q_WS_X11
1116  // If we're minimized on X11, WA_Mapped will be false and we
1117  // will return in the case above. Some window managers on X11
1118  // sends us the PropertyNotify to change the minimized state
1119  // *AFTER* we've received the expose event, which is baaad.
1120  || tlw->isMinimized()
1121 #endif
1122  )
1123  return true;
1124 
1125  return false;
1126 }
1127 
1135 void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedRegion)
1136 {
1137  QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
1138  if (discardSyncRequest(tlw, tlwExtra) || tlwExtra->inTopLevelResize)
1139  return;
1140 
1141  if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible()
1142  || !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) {
1143  return;
1144  }
1145 
1146  // If there's no preserved contents support we always need
1147  // to do a full repaint before flushing
1149  fullUpdatePending = true;
1150 
1151  // Nothing to repaint.
1152  if (!isDirty()) {
1153  qt_flush(exposedWidget, exposedRegion, windowSurface, tlw, tlwOffset);
1154  return;
1155  }
1156 
1157  if (exposedWidget != tlw)
1158  markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint()));
1159  else
1160  markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
1161  sync();
1162 }
1163 
1168 {
1169  QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
1170  if (discardSyncRequest(tlw, tlwExtra)) {
1171  // If the top-level is minimized, it's not visible on the screen so we can delay the
1172  // update until it's shown again. In order to do that we must keep the dirty states.
1173  // These will be cleared when we receive the first expose after showNormal().
1174  // However, if the widget is not visible (isVisible() returns false), everything will
1175  // be invalidated once the widget is shown again, so clear all dirty states.
1176  if (!tlw->isVisible()) {
1177  dirty = QRegion();
1178  for (int i = 0; i < dirtyWidgets.size(); ++i)
1180  dirtyWidgets.clear();
1181  fullUpdatePending = false;
1182  }
1183  return;
1184  }
1185 
1186  const bool updatesDisabled = !tlw->updatesEnabled();
1187  bool repaintAllWidgets = false;
1188 
1189  const bool inTopLevelResize = tlwExtra->inTopLevelResize;
1190  const QRect tlwRect(topLevelRect());
1191 #ifdef Q_WS_QPA
1192  const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size());
1193 #else
1194  const QRect surfaceGeometry(windowSurface->geometry());
1195 #endif
1196  if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
1197  if (hasStaticContents()) {
1198  // Repaint existing dirty area and newly visible area.
1199  const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
1200  const QRegion staticRegion(staticContents(0, clipRect));
1201  QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height());
1202  newVisible -= staticRegion;
1203  dirty += newVisible;
1204  windowSurface->setStaticContents(staticRegion);
1205  } else {
1206  // Repaint everything.
1207  dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height());
1208  for (int i = 0; i < dirtyWidgets.size(); ++i)
1210  dirtyWidgets.clear();
1211  repaintAllWidgets = true;
1212  }
1213  }
1214 
1215 #ifdef Q_WS_QPA
1216  if (inTopLevelResize || surfaceGeometry.size() != tlwRect.size())
1217  windowSurface->resize(tlwRect.size());
1218 #else
1219  if (inTopLevelResize || surfaceGeometry != tlwRect)
1220  windowSurface->setGeometry(tlwRect);
1221 #endif
1222 
1223  if (updatesDisabled)
1224  return;
1225 
1228 
1229  // Contains everything that needs repaint.
1230  QRegion toClean(dirty);
1231 
1232  // Loop through all update() widgets and remove them from the list before they are
1233  // painted (in case someone calls update() in paintEvent). If the widget is opaque
1234  // and does not have transparent overlapping siblings, append it to the
1235  // opaqueNonOverlappedWidgets list and paint it directly without composition.
1236  QVarLengthArray<QWidget *, 32> opaqueNonOverlappedWidgets;
1237  for (int i = 0; i < dirtyWidgets.size(); ++i) {
1238  QWidget *w = dirtyWidgets.at(i);
1239  QWidgetPrivate *wd = w->d_func();
1240  if (wd->data.in_destructor)
1241  continue;
1242 
1243  // Clip with mask() and clipRect().
1244  wd->dirty &= wd->clipRect();
1245  wd->clipToEffectiveMask(wd->dirty);
1246 
1247  // Subtract opaque siblings and children.
1248  bool hasDirtySiblingsAbove = false;
1249  // We know for sure that the widget isn't overlapped if 'isMoved' is true.
1250  if (!wd->isMoved)
1251  wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove);
1252  // Scrolled and moved widgets must draw all children.
1253  if (!wd->isScrolled && !wd->isMoved)
1254  wd->subtractOpaqueChildren(wd->dirty, w->rect());
1255 
1256  if (wd->dirty.isEmpty()) {
1257  resetWidget(w);
1258  continue;
1259  }
1260 
1261  const QRegion widgetDirty(w != tlw ? wd->dirty.translated(w->mapTo(tlw, QPoint()))
1262  : wd->dirty);
1263  toClean += widgetDirty;
1264 
1265 #ifndef QT_NO_GRAPHICSVIEW
1266  if (tlw->d_func()->extra->proxyWidget) {
1267  resetWidget(w);
1268  continue;
1269  }
1270 #endif
1271 
1272  if (!hasDirtySiblingsAbove && wd->isOpaque && !dirty.intersects(widgetDirty.boundingRect())) {
1273  opaqueNonOverlappedWidgets.append(w);
1274  } else {
1275  resetWidget(w);
1276  dirty += widgetDirty;
1277  }
1278  }
1279  dirtyWidgets.clear();
1280 
1281  fullUpdatePending = false;
1282 
1283  if (toClean.isEmpty()) {
1284  // Nothing to repaint. However, we might have newly exposed areas on the
1285  // screen if this function was called from sync(QWidget *, QRegion)), so
1286  // we have to make sure those are flushed.
1287  flush();
1288  return;
1289  }
1290 
1291 #ifndef QT_NO_GRAPHICSVIEW
1292  if (tlw->d_func()->extra->proxyWidget) {
1294  dirty = QRegion();
1295  const QVector<QRect> rects(toClean.rects());
1296  for (int i = 0; i < rects.size(); ++i)
1297  tlw->d_func()->extra->proxyWidget->update(rects.at(i));
1298  return;
1299  }
1300 #endif
1301 
1302 #ifndef Q_BACKINGSTORE_SUBSURFACES
1303  BeginPaintInfo beginPaintInfo;
1304  beginPaint(toClean, tlw, windowSurface, &beginPaintInfo);
1305  if (beginPaintInfo.nothingToPaint) {
1306  for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i)
1307  resetWidget(opaqueNonOverlappedWidgets[i]);
1308  dirty = QRegion();
1309  return;
1310  }
1311 #endif
1312 
1313  // Must do this before sending any paint events because
1314  // the size may change in the paint event.
1316  const QRegion dirtyCopy(dirty);
1317  dirty = QRegion();
1318 
1319  // Paint opaque non overlapped widgets.
1320  for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) {
1321  QWidget *w = opaqueNonOverlappedWidgets[i];
1322  QWidgetPrivate *wd = w->d_func();
1323 
1324  int flags = QWidgetPrivate::DrawRecursive;
1325  // Scrolled and moved widgets must draw all children.
1326  if (!wd->isScrolled && !wd->isMoved)
1328  if (w == tlw)
1329  flags |= QWidgetPrivate::DrawAsRoot;
1330 
1331  QRegion toBePainted(wd->dirty);
1332  resetWidget(w);
1333 
1334 #ifdef Q_BACKINGSTORE_SUBSURFACES
1335  QWindowSurface *subSurface = w->windowSurface();
1336  BeginPaintInfo beginPaintInfo;
1337 
1338  QPoint off = w->mapTo(tlw, QPoint());
1339  toBePainted.translate(off);
1340  beginPaint(toBePainted, w, subSurface, &beginPaintInfo, true);
1341  toBePainted.translate(-off);
1342 
1343  if (beginPaintInfo.nothingToPaint)
1344  continue;
1345 
1346  if (beginPaintInfo.windowSurfaceRecreated) {
1347  // Eep the window surface has changed. The old one may have been
1348  // deleted, in which case we will segfault on the call to
1349  // painterOffset() below. Use the new window surface instead.
1350  subSurface = w->windowSurface();
1351  }
1352 
1353  QPoint offset(tlwOffset);
1354  if (subSurface == windowSurface)
1355  offset += w->mapTo(tlw, QPoint());
1356  else
1357  offset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset();
1358  wd->drawWidget(subSurface->paintDevice(), toBePainted, offset, flags, 0, this);
1359 
1360  endPaint(toBePainted, subSurface, &beginPaintInfo);
1361 #else
1362  QPoint offset(tlwOffset);
1363  if (w != tlw)
1364  offset += w->mapTo(tlw, QPoint());
1365  wd->drawWidget(windowSurface->paintDevice(), toBePainted, offset, flags, 0, this);
1366 #endif
1367  }
1368 
1369  // Paint the rest with composition.
1370 #ifndef Q_BACKINGSTORE_SUBSURFACES
1371  if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
1373  tlw->d_func()->drawWidget(windowSurface->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this);
1374  }
1375 
1376  endPaint(toClean, windowSurface, &beginPaintInfo);
1377 #else
1378  if (!repaintAllWidgets && dirtyCopy.isEmpty())
1379  return; // Nothing more to paint.
1380 
1381  QList<QWindowSurface *> surfaceList(subSurfaces);
1382  surfaceList.prepend(windowSurface);
1383  const QRect dirtyBoundingRect(dirtyCopy.boundingRect());
1384 
1385  // Loop through all window surfaces (incl. the top-level surface) and
1386  // repaint those intersecting with the bounding rect of the dirty region.
1387  for (int i = 0; i < surfaceList.size(); ++i) {
1388  QWindowSurface *subSurface = surfaceList.at(i);
1389  QWidget *w = subSurface->window();
1390  QWidgetPrivate *wd = w->d_func();
1391 
1392  const QRect clipRect = wd->clipRect().translated(w->mapTo(tlw, QPoint()));
1393  if (!qRectIntersects(dirtyBoundingRect, clipRect))
1394  continue;
1395 
1396  toClean = dirtyCopy;
1397  BeginPaintInfo beginPaintInfo;
1398  beginPaint(toClean, w, subSurface, &beginPaintInfo);
1399  if (beginPaintInfo.nothingToPaint)
1400  continue;
1401 
1402  if (beginPaintInfo.windowSurfaceRecreated) {
1403  // Eep the window surface has changed. The old one may have been
1404  // deleted, in which case we will segfault on the call to
1405  // painterOffset() below. Use the new window surface instead.
1406  subSurface = w->windowSurface();
1407  }
1408 
1409  int flags = QWidgetPrivate::DrawRecursive;
1410  if (w == tlw)
1411  flags |= QWidgetPrivate::DrawAsRoot;
1412  const QPoint painterOffset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset();
1413  wd->drawWidget(subSurface->paintDevice(), toClean, painterOffset, flags, 0, this);
1414 
1415  endPaint(toClean, subSurface, &beginPaintInfo);
1416  }
1417 #endif
1418 }
1419 
1426 {
1427 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
1428  paintWindowDecoration();
1429 #endif
1430 
1431  if (!dirtyOnScreen.isEmpty()) {
1432  QWidget *target = widget ? widget : tlw;
1433  QWindowSurface *source = surface ? surface : windowSurface;
1434  qt_flush(target, dirtyOnScreen, source, tlw, tlwOffset);
1435  dirtyOnScreen = QRegion();
1436  }
1437 
1439  return;
1440 
1441  for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
1442  QWidget *w = dirtyOnScreenWidgets->at(i);
1443  QWidgetPrivate *wd = w->d_func();
1444  Q_ASSERT(wd->needsFlush);
1446  *wd->needsFlush = QRegion();
1447  }
1449 }
1450 
1452 {
1453  Q_ASSERT(widget);
1455  return true;
1456 
1457  if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
1458  return true;
1459 
1460  if (!widget->isVisible() || !widget->updatesEnabled())
1461  return true;
1462 
1463  return false;
1464 }
1465 
1471 {
1472  Q_Q(QWidget);
1473  Q_ASSERT(!q->isWindow());
1474  Q_ASSERT(q->parentWidget());
1475 
1476  const bool staticContents = q->testAttribute(Qt::WA_StaticContents);
1477  const bool sizeDecreased = (data.crect.width() < oldSize.width())
1478  || (data.crect.height() < oldSize.height());
1479 
1480  const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y());
1481  const bool parentAreaExposed = !offset.isNull() || sizeDecreased;
1482  const QRect newWidgetRect(q->rect());
1483  const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.height());
1484 
1485  if (!staticContents || graphicsEffect) {
1486  QRegion staticChildren;
1487  QWidgetBackingStore *bs = 0;
1488  if (offset.isNull() && (bs = maybeBackingStore()))
1489  staticChildren = bs->staticContents(q, oldWidgetRect);
1490  const bool hasStaticChildren = !staticChildren.isEmpty();
1491 
1492  if (hasStaticChildren) {
1493  QRegion dirty(newWidgetRect);
1494  dirty -= staticChildren;
1495  invalidateBuffer(dirty);
1496  } else {
1497  // Entire widget needs repaint.
1498  invalidateBuffer(newWidgetRect);
1499  }
1500 
1501  if (!parentAreaExposed)
1502  return;
1503 
1504  // Invalidate newly exposed area of the parent.
1505  if (!graphicsEffect && extra && extra->hasMask) {
1506  QRegion parentExpose(extra->mask.translated(oldPos));
1507  parentExpose &= QRect(oldPos, oldSize);
1508  if (hasStaticChildren)
1509  parentExpose -= data.crect; // Offset is unchanged, safe to do this.
1510  q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
1511  } else {
1512  if (hasStaticChildren && !graphicsEffect) {
1513  QRegion parentExpose(QRect(oldPos, oldSize));
1514  parentExpose -= data.crect; // Offset is unchanged, safe to do this.
1515  q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
1516  } else {
1517  q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize)));
1518  }
1519  }
1520  return;
1521  }
1522 
1523  // Move static content to its new position.
1524  if (!offset.isNull()) {
1525  if (sizeDecreased) {
1526  const QSize minSize(qMin(oldSize.width(), data.crect.width()),
1527  qMin(oldSize.height(), data.crect.height()));
1528  moveRect(QRect(oldPos, minSize), offset.x(), offset.y());
1529  } else {
1530  moveRect(QRect(oldPos, oldSize), offset.x(), offset.y());
1531  }
1532  }
1533 
1534  // Invalidate newly visible area of the widget.
1535  if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) {
1536  QRegion newVisible(newWidgetRect);
1537  newVisible -= oldWidgetRect;
1538  invalidateBuffer(newVisible);
1539  }
1540 
1541  if (!parentAreaExposed)
1542  return;
1543 
1544  // Invalidate newly exposed area of the parent.
1545  const QRect oldRect(oldPos, oldSize);
1546  if (extra && extra->hasMask) {
1547  QRegion parentExpose(oldRect);
1548  parentExpose &= extra->mask.translated(oldPos);
1549  parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect);
1550  q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
1551  } else {
1552  QRegion parentExpose(oldRect);
1553  parentExpose -= data.crect;
1554  q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
1555  }
1556 }
1557 
1566 {
1567  Q_Q(QWidget);
1568 
1569  QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
1570  if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty())
1571  return;
1572 
1573  QRegion wrgn(rgn);
1574  wrgn &= clipRect();
1575  if (!graphicsEffect && extra && extra->hasMask)
1576  wrgn &= extra->mask;
1577  if (wrgn.isEmpty())
1578  return;
1579 
1580  tlwExtra->backingStore->markDirty(wrgn, q, false, true);
1581 }
1582 
1591 {
1592  Q_Q(QWidget);
1593 
1594  QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
1595  if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty())
1596  return;
1597 
1598  QRect wRect(rect);
1599  wRect &= clipRect();
1600  if (wRect.isEmpty())
1601  return;
1602 
1603  if (graphicsEffect || !extra || !extra->hasMask) {
1604  tlwExtra->backingStore->markDirty(wRect, q, false, true);
1605  return;
1606  }
1607 
1608  QRegion wRgn(extra->mask);
1609  wRgn &= wRect;
1610  if (wRgn.isEmpty())
1611  return;
1612 
1613  tlwExtra->backingStore->markDirty(wRgn, q, false, true);
1614 }
1615 
1617 {
1618  if (data.in_destructor)
1619  return;
1620 
1621  Q_Q(QWidget);
1622  if (q->testAttribute(Qt::WA_StaticContents)) {
1623  if (!extra)
1624  createExtra();
1625  extra->staticContentsSize = data.crect.size();
1626  }
1627 
1628 #ifdef Q_WS_QPA //Don't even call q->p
1629  QPaintEngine *engine = 0;
1630 #else
1631  QPaintEngine *engine = q->paintEngine();
1632 #endif
1633  // QGLWidget does not support partial updates if:
1634  // 1) The context is double buffered
1635  // 2) The context is single buffered and auto-fill background is enabled.
1636  const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL
1637  || engine->type() == QPaintEngine::OpenGL2))
1638  && (usesDoubleBufferedGLContext || q->autoFillBackground());
1639  QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
1640 
1641 #ifdef Q_WS_MAC
1642  // No difference between update() and repaint() on the Mac.
1643  update_sys(toBePainted);
1644  return;
1645 #endif
1646 
1647  toBePainted &= clipRect();
1648  clipToEffectiveMask(toBePainted);
1649  if (toBePainted.isEmpty())
1650  return; // Nothing to repaint.
1651 
1652 #ifndef QT_NO_PAINT_DEBUG
1653  bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted);
1654 #endif
1655 
1656  drawWidget(q, toBePainted, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, 0);
1657 
1658 #ifndef QT_NO_PAINT_DEBUG
1659  if (flushed)
1660  QWidgetBackingStore::unflushPaint(q, toBePainted);
1661 #endif
1662 
1663  if (!q->testAttribute(Qt::WA_PaintOutsidePaintEvent) && q->paintingActive())
1664  qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
1665 }
1666 
1667 
T qobject_cast(QObject *object)
Definition: qobject.h:375
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
QRect geometry() const
Returns the currently allocated area on the screen.
The QWSWindowSurface class provides the drawing area for top-level windows in Qt for Embedded Linux...
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
virtual bool paint(QPainter *p, const QWidget *w, int decorationRegion=All, DecorationState state=Normal)=0
Implement this function to paint the border and title decoration for the specified top level widget u...
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QRegion intersected(const QRegion &r) const
Returns a region which is the intersection of this region and r.
Definition: qregion.h:112
unsigned char c[8]
Definition: qnumeric_p.h:62
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QRegion clipRegion() const
Returns the region currently visible on the screen.
EventRef event
QPointer< QWidget > widget
QRegion dirty
Definition: qwidget_p.h:726
QPoint mapTo(QWidget *, const QPoint &) const
Translates the widget coordinate pos to the coordinate system of parent.
Definition: qwidget.cpp:4409
QWindowSurface * windowSurface
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
void releaseDC(HDC) const
Releases the HDC hdc acquired by a previous call to getDC().
Definition: qwidget.cpp:11862
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
bool isVisible() const
Definition: qwidget.h:1005
QRegion qt_dirtyRegion(QWidget *)
Definition: qwidget.cpp:1111
QWindowSurface * windowSurface
Definition: qwidget_p.h:167
QRect clipRect() const
Definition: qwidget.cpp:1997
bool isDirty() const
void moveRect(const QRect &, int dx, int dy)
QRegion staticContents(QWidget *widget=0, const QRect &withinClipRect=QRect()) const
Returns the static content inside the parent if non-zero; otherwise the static content for the entire...
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
uint inTopLevelResize
Definition: qwidget_p.h:188
QRect translated(int dx, int dy) const
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis...
Definition: qrect.h:328
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset)
Marks the region of the widget as dirty on screen.
void removeDirtyWidget(QWidget *w)
void sync()
Synchronizes the backing store, i.e.
void addStaticWidget(QWidget *widget)
friend class QWSManagerPrivate
void resetWidget(QWidget *widget)
void flush(QWidget *widget, const QRegion &region, const QPoint &offset)
Flushes the given region from the specified widget onto the screen.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static void qt_flush(QWidget *widget, const QRegion &region, QWindowSurface *windowSurface, QWidget *tlw, const QPoint &tlwOffset)
QRect intersected(const QRect &other) const
Returns the intersection of this rectangle and the given rectangle.
Definition: qrect.h:481
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
bool isBuffered() const
Returns true if the QWSWindowSurface::Buffered is set; otherwise returns false.
qreal x() const
Returns the x coordinate of this point.
Definition: qvector3d.h:161
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QObjectList children
Definition: qobject.h:93
void append(const T &t)
QList< QWidget * > staticWidgets
QRect topLevelRect() const
virtual QRegion region(const QWidget *w, const QRect &rect, int decorationRegion=All)=0
Implement this function to return the region specified by decorationRegion for the given top level wi...
virtual void beginPaint(const QRegion &)
This function is called before painting onto the surface begins, with the region in which the paintin...
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
int restart()
Sets this time to the current time and returns the number of milliseconds that have elapsed since the...
Definition: qdatetime.cpp:2095
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
virtual void releaseSurface()
#define Q_Q(Class)
Definition: qglobal.h:2483
static QFont font()
Returns the default application font.
The QDecoration class is a base class for window decorations in Qt for Embedded Linux.
QWidgetData data
Definition: qwidget_p.h:755
void update()
Updates the widget unless updates are disabled or the widget is hidden.
Definition: qwidget.cpp:10883
QVector< QWidget * > dirtyWidgets
void markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately=false, bool invalidateBuffer=false)
Marks the region of the widget as dirty (if not already marked as dirty) and posts an UpdateRequest e...
QWindowSurface * surface() const
NSWindow * window
int width() const
Returns the width.
Definition: qsize.h:126
The QTime class provides clock time functions.
Definition: qdatetime.h:148
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void setDelay(int msec)
QWidget * nativeParentWidget() const
Returns the native parent for this widget, i.
Definition: qwidget.cpp:4514
uint windowSurfaceRecreated
bool updatesEnabled
whether updates are enabled
Definition: qwidget.h:190
virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset)=0
Flushes the given region from the specified widget onto the screen.
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition: qwidget.h:1041
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
Definition: qregion.cpp:4098
static void showYellowThing(QWidget *widget, const QRegion &rgn, int msec, bool)
QSize staticContentsSize
Definition: qwidget_p.h:270
void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, QPainter *sharedPainter=0, QWidgetBackingStore *backingStore=0)
Definition: qwidget.cpp:5679
void prepend(const T &t)
Inserts value at the beginning of the list.
Definition: qlist.h:541
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual Type type() const =0
Reimplement this function to return the paint engine Type.
bool isNull() const
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
Definition: qpoint.h:125
Q_CORE_EXPORT void qWarning(const char *,...)
void repaint_sys(const QRegion &rgn)
static const char * data(const QByteArray &arr)
static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
uint inRepaint
Definition: qwidget_p.h:189
void updateLists(QWidget *widget)
QWindowSurface * windowSurface() const
Returns the QWindowSurface this widget will be drawn into.
Definition: qwidget.cpp:12819
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
static bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra)
bool hasStaticContents() const
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
void setSystemClip(const QRegion &baseClip)
Sets the system clip for this engine.
void appendDirtyOnScreenWidget(QWidget *widget)
The QWindowSurface class provides the drawing area for top-level windows.
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QGraphicsEffect * graphicsEffect() const
The graphicsEffect function returns a pointer to the widget&#39;s graphics effect.
Definition: qwidget.cpp:5484
virtual bool isValid() const =0
Implement this function to return true if the surface is a valid surface for the given top-level wind...
void invalidateBuffer(const QRegion &)
Invalidates the rgn (in widget&#39;s coordinates) of the backing store, i.e.
QWidgetBackingStore(QWidget *t)
QPoint topLevelOffset() const
void flush(QWidget *widget=0, QWindowSurface *surface=0)
Flushes the contents of the backing store into the top-level widget.
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
int elapsed() const
Returns the number of milliseconds that have elapsed since the last time start() or restart() was cal...
Definition: qdatetime.cpp:2123
static bool qRectIntersects(const QRect &r1, const QRect &r2)
virtual QPaintEngine * paintEngine() const =0
QRegion * needsFlush
Definition: qwidget_p.h:705
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
virtual QPoint painterOffset() const
Returns the offset to be used when painting.
void setStaticContents(const QRegion &region)
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
Definition: qpainter.cpp:2917
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
virtual void endPaint(const QRegion &)
This function is called after painting onto the surface has ended, with the region in which the paint...
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:168
QPaintEngine * paintEngine() const
Returns the widget&#39;s paint engine.
void beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface, BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates=true)
Prepares the window surface to paint a\ toClean region of the widget and updates the BeginPaintInfo s...
static QTime currentTime()
Returns the current time as reported by the system clock.
Definition: qdatetime.cpp:3125
static void syncX()
Synchronizes with the X server in the X11 implementation.
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
QWidgetBackingStore * data()
Definition: qwidget_p.h:132
Q_GUI_EXPORT bool qt_region_strictContains(const QRegion &region, const QRect &rect)
Returns true if rect is guaranteed to be fully contained in region.
Definition: qregion.cpp:4380
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
QRegion dirtyRegion(QWidget *widget=0) const
Returns the region (in top-level coordinates) that needs repaint and/or flush.
void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const
Definition: qwidget.cpp:2128
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool isAncestorOf(const QWidget *child) const
Returns true if this widget is a parent, (or grandparent and so on to any level), of the given child...
Definition: qwidget.cpp:8573
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QWExtra * extra
Definition: qwidget_p.h:700
static bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
void dirtyOnScreenWidgetsRemoveAll(QWidget *widget)
WId internalWinId() const
Returns the window system identifier of the widget, or 0 if the widget is not created yet...
Definition: qwidget.h:244
void scrollRect(const QRect &, int dx, int dy)
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
Definition: qwidget.cpp:11087
bool hasFeature(WindowSurfaceFeature feature) const
bool isMinimized() const
Definition: qwidget.cpp:3027
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
bool intersects(const QRegion &r) const
Returns true if this region intersects with region, otherwise returns false.
Definition: qregion.cpp:766
void translate(int dx, int dy)
Translates (moves) the region dx along the X axis and dy along the Y axis.
Definition: qregion.cpp:4116
HDC getDC() const
Returns the window system handle of the widget, for low-level access.
Definition: qwidget.cpp:11849
uint in_destructor
Definition: qwidget.h:129
void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove=0, bool alsoNonOpaque=false) const
Definition: qwidget.cpp:2139
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
void setFont(const QFont &f)
Sets the painter&#39;s font to the given font.
Definition: qpainter.cpp:4288
QRegion translated(int dx, int dy) const
Returns a copy of the region that is translated dx along the x axis and dy along the y axis...
Definition: qregion.cpp:743
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
static void flushUpdate(QWidget *widget, const QRegion &region, const QPoint &offset)
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
Invalidates the buffer when the widget is resized.
bool isEmpty() const
Returns true if either of the width and height is less than or equal to 0; otherwise returns false...
Definition: qsize.h:120
static void sendUpdateRequest(QWidget *widget, bool updateImmediately)
QWidgetBackingStoreTracker backingStore
Definition: qwidget_p.h:166
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
void dirtyWidgetsRemoveAll(QWidget *widget)
void clipToEffectiveMask(QRegion &region) const
Definition: qwidget.cpp:2230
QVector< QWidget * > * dirtyOnScreenWidgets
QRegion systemClip() const
Returns the system clip.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void addDirtyWidget(QWidget *widget, const QRegion &rgn)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
virtual bool scroll(const QRegion &area, int dx, int dy)
Scrolls the given area dx pixels to the right and dy downward; both dx and dy may be negative...
QWidget * window() const
Returns a pointer to the top-level window associated with this surface.
static bool flushPaint(QWidget *widget, const QRegion &rgn)
void endPaint(const QRegion &cleaned, QWindowSurface *windowSurface, BeginPaintInfo *beginPaintInfo)
static void unflushPaint(QWidget *widget, const QRegion &rgn)
uint waitingForMapNotify
Definition: qwidget_p.h:197
bool end()
Ends painting.
Definition: qpainter.cpp:1929
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
Definition: qpainter.cpp:7420
int size() const
virtual QPaintDevice * paintDevice()=0
Implement this function to return the appropriate paint device.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static int area(const QSize &s)
Definition: qicon.cpp:155
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288