Index: /trunk/src/gui/painting/qwindowsurface_pm.cpp
===================================================================
--- /trunk/src/gui/painting/qwindowsurface_pm.cpp	(revision 1034)
+++ /trunk/src/gui/painting/qwindowsurface_pm.cpp	(revision 1035)
@@ -338,5 +338,4 @@
     ULONG bufNum;
     bool posDirty;
-    bool vrnDisabled;
     bool inDrag;
     SETUP_BLITTER setup;
@@ -353,5 +352,6 @@
     {
         int widgetHeight;
-        bool vrnDirty;
+        bool vrnDirty : 1;
+        bool vrnDisabled : 1;
         size_t rclCount;
         QVector<RECTL> rcls;
@@ -393,14 +393,9 @@
     wd->rclCount = 0;
 
-    if (widget == that->window()) {
-        // receive visible region change messages (note that we don't do this
-        // for sub-widgets as it causes some strange PM freezes if these widgets
-        // are embedded windows manipulated by other processes). We also want
-        // to handle other PM messages
-        widget->addPmEventFilter(this);
-        WinSetVisibleRegionNotify(widget->internalWinId(), TRUE);
-    } else {
-        // receive various PM messages
-        widget->addPmEventFilter(this);
+    // receive visible region change messages and other PM messages
+    widget->addPmEventFilter(this);
+    WinSetVisibleRegionNotify(widget->internalWinId(), TRUE);
+
+    if (widget != that->window()) {
         // receive reparent messages from children to cleanup the map
         widget->installEventFilter(this);
@@ -410,12 +405,11 @@
 void QPMDiveWindowSurfacePrivate::removeWidget(QWidget *widget)
 {
-    if (widget == that->window()) {
-        WinSetVisibleRegionNotify(widget->internalWinId(), FALSE);
-        widget->removePmEventFilter(this);
-    } else {
+    if (widget != that->window()) {
         widget->removeEventFilter(this);
-        widget->removePmEventFilter(this);
         subWidgets->remove(widget);
     }
+
+    WinSetVisibleRegionNotify(widget->internalWinId(), FALSE);
+    widget->removePmEventFilter(this);
 }
 
@@ -435,7 +429,14 @@
     switch (msg->msg) {
         case WM_VRNDISABLED: {
-            if (!useFB)
-                DiveSetupBlitter(hDive, NULL);
-            vrnDisabled = true;
+            if (msg->hwnd == that->window()->internalWinId()) {
+                if (!useFB)
+                    DiveSetupBlitter(hDive, NULL);
+                data.vrnDisabled = true;
+            } else {
+                WidgetData *wd = widgetData(QWidget::find(msg->hwnd));
+                Q_ASSERT(wd);
+                if (wd)
+                    wd->vrnDisabled = true;
+            }
             *result = 0;
             return true;
@@ -451,5 +452,9 @@
         }
         case WM_VRNENABLED: {
-            vrnDisabled = false;
+            QWidget *widget = msg->hwnd == that->window()->internalWinId() ?
+                              that->window() : QWidget::find(msg->hwnd);
+            WidgetData *wd = widgetData(widget);
+            Q_ASSERT(wd);
+            wd->vrnDisabled = false;
             // Note that when an overlapping window of *other* process is moved
             // over this window, PM still sends WM_VRNENABLED to it but with
@@ -461,34 +466,22 @@
             if (LONGFROMMP(msg->mp1)) // window's visible region changed
 #endif
-            {
-                // mark all widgets' visible regions as dirty
-                data.vrnDirty = true;
-                if (subWidgets) {
-                    foreach(QWidget *w, subWidgets->keys())
-                        (*subWidgets)[w].vrnDirty = true;
+                wd->vrnDirty = true;
+
+            if (widget == that->window())
+                posDirty = true;
+
+            // process pending flush events for this widget
+            for (QList<QPMDiveWindowSurfacePrivate::FlushArgs>::iterator
+                 it = pending.begin(); it != pending.end();) {
+                if (it->widget == widget) {
+                    that->doFlush(it->widget, it->from, it->to);
+                    it = pending.erase(it);
+                } else {
+                    ++it;
                 }
             }
-            posDirty = true;
-
-            // process pending flush events
-            foreach(const QPMDiveWindowSurfacePrivate::FlushArgs &args, pending)
-                that->doFlush(args.widget, args.from, args.to);
-            pending.clear();
 
             *result = 0;
             return true;
-        }
-        case WM_SIZE: {
-            if (msg->hwnd != that->window()->internalWinId()) {
-                // sometimes PM doesn't send WM_VRNENABLED to the main widget
-                // when the sub-widget (its descendant) gets resized within it;
-                // fix it here by invalidating all visible regions
-                data.vrnDirty = true;
-                if (subWidgets) {
-                    foreach(QWidget *w, subWidgets->keys())
-                        (*subWidgets)[w].vrnDirty = true;
-                }
-            }
-            break;
         }
         default:
@@ -508,5 +501,4 @@
     d->bufNum = 0;
     d->posDirty = true;
-    d->vrnDisabled = false;
     d->inDrag = false;
     d->subWidgets = 0;
@@ -651,5 +643,8 @@
     QRect wbr = br.translated(-wOffset);
 
-    if (d->vrnDisabled) {
+    QPMDiveWindowSurfacePrivate::WidgetData *wd = d->widgetData(widget);
+    Q_ASSERT(wd);
+
+    if (wd->vrnDisabled) {
         // defer the flush
         QPMDiveWindowSurfacePrivate::FlushArgs args = { widget,
