From ace4710951ca5be3cb10bb631d8082e12e0b0b1c Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@nokia.com>
Date: Thu, 1 Jul 2010 11:22:23 +0200
Subject: Updated WebKit to 0eee8df53d1873669a9dda8f9c0340543258a316

Integrated changes:

|| <https://webkit.org/b/38597> || [Qt] QtTestBrowser does not have a "Load" button ; therefore, unable to load pages on touch only symbian devices (portrait mode). ||
|| <https://webkit.org/b/40846> || [Qt] GraphicsLayerQt delay seems unnecessary. ||
|| <https://webkit.org/b/41160> || Spatial Navigation: make elements in inner frames nested more than 1 level deep focusable ||
|| <https://webkit.org/b/39019> || [Qt] Combobox doesn't close when scrolling in graphicsbased mode ||
|| <https://webkit.org/b/41164> || [Qt] QtWebKit crashes if <select>'s render changes in its onchange event ||
|| <https://webkit.org/b/41198> || [QT][S60] build-webkit scripts picks wrong make spec for windows build ||
|| <https://webkit.org/b/41278> || [Qt] Replace single treat-as-space characters with normal space ||
|| <https://webkit.org/b/37303> || [Qt] Application crash on exit if NPPlugin is loaded ||
|| <https://webkit.org/b/40378> || [Qt] When any geometry change happens to a node it will resize the backing cache ||
|| <https://webkit.org/b/40795> || [Qt] Crash when uploading document to Google Docs ||
|| <https://webkit.org/b/40446> || [Qt] Only 10 websites can be loaded consecutively when using QtWebkit 2.0 ||
---
 src/3rdparty/webkit/.tag                           |   2 +-
 src/3rdparty/webkit/VERSION                        |   2 +-
 src/3rdparty/webkit/WebCore/ChangeLog              | 100 +++++++++++++++
 .../webkit/WebCore/page/FocusController.cpp        |   2 +-
 .../webkit/WebCore/page/SpatialNavigation.cpp      |  20 +++
 .../webkit/WebCore/page/SpatialNavigation.h        |   1 +
 .../webkit/WebCore/platform/graphics/qt/FontQt.cpp |   2 +-
 .../platform/graphics/qt/GraphicsLayerQt.cpp       | 134 ++++++++++++++++-----
 .../platform/network/qt/QNetworkReplyHandler.cpp   |   8 ++
 .../platform/network/qt/QNetworkReplyHandler.h     |   1 +
 .../WebCore/plugins/symbian/PluginViewSymbian.cpp  |   6 +-
 src/3rdparty/webkit/WebKit/qt/ChangeLog            |  34 ++++++
 .../qt/WebCoreSupport/QtFallbackWebPopup.cpp       |  20 ++-
 .../WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h  |   1 +
 14 files changed, 298 insertions(+), 35 deletions(-)

diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag
index aa30784..8be0498 100644
--- a/src/3rdparty/webkit/.tag
+++ b/src/3rdparty/webkit/.tag
@@ -1 +1 @@
-38d650efc92427cd6452f6685d3c40d22428cdb7
+0eee8df53d1873669a9dda8f9c0340543258a316
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index 980e01a..56e2c01 100644
--- a/src/3rdparty/webkit/VERSION
+++ b/src/3rdparty/webkit/VERSION
@@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from
 
 and has the sha1 checksum
 
-        38d650efc92427cd6452f6685d3c40d22428cdb7
+        0eee8df53d1873669a9dda8f9c0340543258a316
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index a84f177..5ba94de 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,103 @@
+2010-06-28  Sam Magnuson  <smagnuson@netflix.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] GraphicsLayerQt delay seems unnecessary.
+        https://bugs.webkit.org/show_bug.cgi?id=40846
+
+        Test: compositing/animation/busy-indicator.html
+
+        * platform/graphics/qt/GraphicsLayerQt.cpp:
+        (WebCore::GraphicsLayerQtImpl::recache):
+        (WebCore::GraphicsLayerQtImpl::flushChanges):
+        (WebCore::GraphicsLayerQt::setContentsToImage):
+        (WebCore::GraphicsLayerQt::addAnimation):
+
+2010-06-25  Sam Magnuson  <smagnuson@netflix.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] When any geometry change happens to a node it will resize the
+        backing cache
+        https://bugs.webkit.org/show_bug.cgi?id=40378
+
+        Continue to grow the cache, but never toss it. When the pixmap
+        cache gets too big it will be lost and created at the right size
+        next time.
+
+        No new tests: this is an optimization.
+
+        * platform/graphics/qt/GraphicsLayerQt.cpp:
+        (WebCore::GraphicsLayerQtImpl::recache):
+        (WebCore::GraphicsLayerQtImpl::paint):
+        (WebCore::GraphicsLayerQtImpl::flushChanges):
+
+2010-06-30  Antonio Gomes  <tonikitoo@webkit.org>
+
+        Reviewed by Simon Fraser.
+
+        Spatial Navigation: make elements in inner frames nested more than 1 level deep focusable
+        https://bugs.webkit.org/show_bug.cgi?id=41160
+
+        Patch addresses the problem of spatial navigation not work properly with nested
+        inner frames by adding the isNodeDeepDescendantOfDocument method. It recursively checks
+        if a give node is descendant of a given document or any parent of it.
+
+        Test: fast/events/spatial-navigation/snav-iframe-nested.html
+
+        * page/FocusController.cpp:
+        (WebCore::FocusController::deepFindFocusableNodeInDirection):
+        * page/SpatialNavigation.cpp:
+        (WebCore::isNodeDeepDescendantOfDocument):
+        * page/SpatialNavigation.h:
+
+2010-06-30  Andreas Kling  <andreas.kling@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] Crash when uploading document to Google Docs
+        https://bugs.webkit.org/show_bug.cgi?id=40795
+
+        Fix bug where the local file wasn't opened (for POSTing)
+        if it were the first element in the form.
+
+        * platform/network/qt/QNetworkReplyHandler.cpp:
+        (WebCore::FormDataIODevice::FormDataIODevice):
+        (WebCore::FormDataIODevice::moveToNextElement):
+        (WebCore::FormDataIODevice::openFileForCurrentElement):
+        * platform/network/qt/QNetworkReplyHandler.h:
+
+2010-06-29  Abhinav Mithal <abhinav.mithal@nokia.com>
+
+        Reviewed by Laszlo Gombos.
+
+        [Qt] [Symbian] Fix doube-deallocation while destroying PluginContainerSymbian
+        https://bugs.webkit.org/show_bug.cgi?id=37303
+
+        * plugins/symbian/PluginViewSymbian.cpp:
+        (WebCore::PluginView::platformDestroy):
+
+2010-06-29  Kristian Amlie  <kristian.amlie@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt/Symbian] Fixed deployment paths for WebKit declarative plugin.
+
+        * WebCore.pro:
+
+2010-06-28  Andreas Kling  <andreas.kling@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Replace single treat-as-space characters with normal space
+        https://bugs.webkit.org/show_bug.cgi?id=41278
+
+        This keeps Qt from attempting glyph substitution and loading a bunch
+        of extra fonts when encountering &nbsp; entities.
+
+        * platform/graphics/qt/FontQt.cpp:
+        (WebCore::Font::floatWidthForComplexText):
+
 2010-06-24  Simon Hausmann  <simon.hausmann@nokia.com>
 
         Unreviewed Symbian build fix.
diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.cpp b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
index a285e52..2bd00e8 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
@@ -503,7 +503,7 @@ void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* fo
         if (!innerDocument)
             return;
 
-        descendantOfContainer = innerDocument == focusedNode->document();
+        descendantOfContainer = isNodeDeepDescendantOfDocument(focusedNode, innerDocument);
         firstChild = innerDocument->firstChild();
 
     // Scrollable block elements (e.g. <div>, etc)
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
index 1ce61c3..a80626f 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
@@ -545,4 +545,24 @@ bool isScrollableContainerNode(Node* node)
     return false;
 }
 
+bool isNodeDeepDescendantOfDocument(Node* node, Document* baseDocument)
+{
+    if (!node || !baseDocument)
+        return false;
+
+    bool descendant = baseDocument == node->document();
+
+    Element* currentElement = static_cast<Element*>(node);
+    while (!descendant) {
+        Element* documentOwner = currentElement->document()->ownerElement();
+        if (!documentOwner)
+            break;
+
+        descendant = documentOwner->document() == baseDocument;
+        currentElement = documentOwner;
+    }
+
+    return descendant;
+}
+
 } // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
index 06389a3..5499ca7 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
@@ -133,6 +133,7 @@ void scrollIntoView(Element*);
 bool hasOffscreenRect(Node*);
 bool isInRootDocument(Node*);
 bool isScrollableContainerNode(Node*);
+bool isNodeDeepDescendantOfDocument(Node*, Document*);
 
 } // namspace WebCore
 
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp
index 06885ba..4ae70d0 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp
@@ -234,7 +234,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
         return 0;
 
     if (run.length() == 1 && treatAsSpace(run[0]))
-        return QFontMetrics(font()).width(run[0]) + run.padding();
+        return QFontMetrics(font()).width(space) + run.padding();
 
     String sanitized = Font::normalizeSpaces(String(run.characters(), run.length()));
     QString string = fromRawDataWithoutRef(sanitized);
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
index ad2ec9c..8a123b1 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp
@@ -41,6 +41,10 @@
 #include <QtGui/qpixmapcache.h>
 #include <QtGui/qstyleoption.h>
 
+
+#define QT_DEBUG_RECACHE 0
+#define QT_DEBUG_CACHEDUMP 0
+
 namespace WebCore {
 
 #ifndef QT_NO_GRAPHICSEFFECT
@@ -214,7 +218,10 @@ public:
     int m_changeMask;
 
     QSizeF m_size;
-    QPixmapCache::Key m_backingStoreKey;
+    struct {
+        QPixmapCache::Key key;
+        QSizeF size;
+    } m_backingStore;
 #ifndef QT_NO_ANIMATION
     QList<QWeakPointer<QAbstractAnimation> > m_animations;
 #endif
@@ -303,36 +310,109 @@ const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const
 
 QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate)
 {
-    if (!m_layer->drawsContent() || m_size.isEmpty() ||!m_size.isValid())
+    if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid())
         return QPixmap();
 
-    QRegion region = regionToUpdate;
     QPixmap pixmap;
+    QRegion region = regionToUpdate;
+    if (QPixmapCache::find(m_backingStore.key, &pixmap)) {
+        if (region.isEmpty())
+            return pixmap;
+        QPixmapCache::remove(m_backingStore.key); // Remove the reference to the pixmap in the cache to avoid a detach.
+    }
 
-    // We might be drawing into an existing cache.
-    if (!QPixmapCache::find(m_backingStoreKey, &pixmap))
-        region = QRegion(QRect(0, 0, m_size.width(), m_size.height()));
+    {
+        bool erased = false;
 
-    if (m_size != pixmap.size()) {
-        pixmap = QPixmap(m_size.toSize());
-        if (!m_layer->contentsOpaque())
-            pixmap.fill(Qt::transparent);
-        m_pendingContent.regionToUpdate = QRegion(QRect(QPoint(0, 0), m_size.toSize()));
-    }
+        // If the pixmap is not in the cache or the view has grown since last cached.
+        if (pixmap.isNull() || m_size != m_backingStore.size) {
+#if QT_DEBUG_RECACHE
+            if (pixmap.isNull())
+                qDebug() << "CacheMiss" << this << m_size;
+#endif
+            bool fill = true;
+            QRegion newRegion;
+            QPixmap oldPixmap = pixmap;
+
+            // If the pixmap is two small to hold the view contents we enlarge, otherwise just use the old (large) pixmap.
+            if (pixmap.width() < m_size.width() || pixmap.height() < m_size.height()) {
+#if QT_DEBUG_RECACHE
+                qDebug() << "CacheGrow" << this << m_size;
+#endif
+                pixmap = QPixmap(m_size.toSize());
+                pixmap.fill(Qt::transparent);
+                newRegion = QRegion(0, 0, m_size.width(), m_size.height());
+            }
+
+#if 1
+            // Blit the contents of oldPixmap back into the cached pixmap as we are just adding new pixels.
+            if (!oldPixmap.isNull()) {
+                const QRegion cleanRegion = (QRegion(0, 0, m_size.width(), m_size.height())
+                                             & QRegion(0, 0, m_backingStore.size.width(), m_backingStore.size.height())) - regionToUpdate;
+                if (!cleanRegion.isEmpty()) {
+#if QT_DEBUG_RECACHE
+                    qDebug() << "CacheBlit" << this << cleanRegion;
+#endif
+                    const QRect cleanBounds(cleanRegion.boundingRect());
+                    QPainter painter(&pixmap);
+                    painter.setCompositionMode(QPainter::CompositionMode_Source);
+                    painter.drawPixmap(cleanBounds.topLeft(), oldPixmap, cleanBounds);
+                    newRegion -= cleanRegion;
+                    fill = false; // We cannot just fill the pixmap.
+                }
+                oldPixmap = QPixmap();
+            }
+#endif
+            region += newRegion;
+            if (fill && !region.isEmpty()) { // Clear the entire pixmap with the background.
+#if QT_DEBUG_RECACHE
+                qDebug() << "CacheErase" << this << m_size << background;
+#endif
+                erased = true;
+                pixmap.fill(Qt::transparent);
+            }
+        }
+        region &= QRegion(0, 0, m_size.width(), m_size.height());
+
+        // If we have something to draw its time to erase it and render the contents.
+        if (!region.isEmpty()) {
+#if QT_DEBUG_CACHEDUMP
+            static int recacheCount = 0;
+            ++recacheCount;
+            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
+            pixmap.save(QString().sprintf("/tmp/%05d_A.png", recacheCount), "PNG");
+#endif
+
+            QPainter painter(&pixmap);
+            GraphicsContext gc(&painter);
+
+            painter.setClipRegion(region);
+
+            if (!erased) { // Erase the area in cache that we're drawing into.
+                painter.setCompositionMode(QPainter::CompositionMode_Clear);
+                painter.fillRect(region.boundingRect(), Qt::transparent);
 
-    QPainter painter(&pixmap);
-    GraphicsContext gc(&painter);
+#if QT_DEBUG_CACHEDUMP
+                qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
+                pixmap.save(QString().sprintf("/tmp/%05d_B.png", recacheCount), "PNG");
+#endif
+            }
 
-    // Clear the area in cache that we're drawing into
-    painter.setCompositionMode(QPainter::CompositionMode_Clear);
-    painter.fillRect(region.boundingRect(), Qt::transparent);
+            // Render the actual contents into the cache.
+            painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+            m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
+            painter.end();
 
-    // Render the actual contents into the cache
-    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-    m_layer->paintGraphicsLayerContents(gc, region.boundingRect());
-    painter.end();
+#if QT_DEBUG_CACHEDUMP
+            qDebug() << "**** CACHEDUMP" << recacheCount << this << m_layer << region << m_size;
+            pixmap.save(QString().sprintf("/tmp/%05d_C.png", recacheCount), "PNG");
+#endif
+        }
+        m_backingStore.size = m_size; // Store the used size of the pixmap.
+    }
 
-    m_backingStoreKey = QPixmapCache::insert(pixmap);    
+    // Finally insert into the cache and allow a reference there.
+    m_backingStore.key = QPixmapCache::insert(pixmap);
     return pixmap;
 }
 
@@ -447,8 +527,9 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte
         if (m_state.drawsContent) {
             QPixmap backingStore;
             // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full).
-            if (!QPixmapCache::find(m_backingStoreKey, &backingStore) || backingStore.size() != m_size.toSize())
+            if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize())
                 backingStore = recache(QRegion(m_state.contentsRect));
+            const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height());
             painter->drawPixmap(0, 0, backingStore);
         }
         break;
@@ -614,11 +695,13 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform
     else
 #endif
     if (m_changeMask & DisplayChange) {
+#ifndef QT_GRAPHICS_LAYER_NO_RECACHE_ON_DISPLAY_CHANGE
         // Recache now: all the content is ready and we don't want to wait until the paint event.
         // We only need to do this for HTML content, there's no point in caching directly composited
         // content like images or solid rectangles.
         if (m_pendingContent.contentType == HTMLContentType)
             recache(m_pendingContent.regionToUpdate);
+#endif
         update(m_pendingContent.regionToUpdate.boundingRect());
         m_pendingContent.regionToUpdate = QRegion();
     }
@@ -1319,10 +1402,7 @@ bool GraphicsLayerQt::addAnimation(const KeyframeValueList& values, const IntSiz
     if (anim->fillsBackwards())
         newAnim->setCurrentTime(0);
 
-    if (anim->delay())
-        QTimer::singleShot(anim->delay() * 1000, newAnim, SLOT(start()));
-    else
-        newAnim->start();
+    newAnim->start();
 
     // we synchronize the animation's clock to WebCore's timeOffset
     newAnim->setCurrentTime(timeOffset * 1000);
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index abeb895..7e08fd7 100644
--- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -60,6 +60,9 @@ FormDataIODevice::FormDataIODevice(FormData* data)
     , m_currentDelta(0)
 {
     setOpenMode(FormDataIODevice::ReadOnly);
+
+    if (!m_formElements.isEmpty() && m_formElements[0].m_type == FormDataElement::encodedFile)
+        openFileForCurrentElement();
 }
 
 FormDataIODevice::~FormDataIODevice()
@@ -78,6 +81,11 @@ void FormDataIODevice::moveToNextElement()
     if (m_formElements.isEmpty() || m_formElements[0].m_type == FormDataElement::data)
         return;
 
+    openFileForCurrentElement();
+}
+
+void FormDataIODevice::openFileForCurrentElement()
+{
     if (!m_currentFile)
         m_currentFile = new QFile;
 
diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.h b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.h
index 1abad4e..d35f4d8 100644
--- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -104,6 +104,7 @@ protected:
 
 private:
     void moveToNextElement();
+    void openFileForCurrentElement();
 
 private:
     Vector<FormDataElement> m_formElements;
diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
index 108fcca..c272647 100644
--- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
@@ -416,8 +416,10 @@ void PluginView::platformDestroy()
 {
     if (platformPluginWidget()) {
         PluginContainerSymbian* container = static_cast<PluginContainerSymbian*>(platformPluginWidget());
-        delete container->proxy();
-        delete container;
+        if (container && container->proxy())
+            delete container->proxy();
+        else
+            delete container;
     }
 }
 
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 8fb929e..acf1695 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,37 @@
+2010-06-30  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] Make sure we catch closed QComboBox popups.
+        https://bugs.webkit.org/show_bug.cgi?id=39019
+
+        The way it works currently is using the QComboBox::show/hidePopup
+        virtual method to catch popup requests in the middle. There is
+        some cases however that the popup widget gets closed without
+        going through the hidePopup method.
+
+        This patch adds an event filter to the popup's view to know when
+        it gets closed and calls hidePopup to call our handling code.
+        This may get hidePopup called twice but this shouldn't have any
+        effect.
+
+        * WebCoreSupport/QtFallbackWebPopup.cpp:
+        (WebCore::QtFallbackWebPopupCombo::QtFallbackWebPopupCombo):
+        (WebCore::QtFallbackWebPopupCombo::eventFilter):
+        * WebCoreSupport/QtFallbackWebPopup.h:
+
+2010-06-25  Luiz Agostini  <luiz.agostini@openbossa.org>
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        [Qt] QtWebKit crashes if <select>'s render changes in its onchange event
+        https://bugs.webkit.org/show_bug.cgi?id=41164
+
+        QtWebKit crashes if <select>'s renderer changes in its onchange event.
+
+        * WebCoreSupport/QtFallbackWebPopup.cpp:
+        (WebCore::QtFallbackWebPopup::~QtFallbackWebPopup):
+
 2010-06-28  Andreas Kling  <andreas.kling@nokia.com>
 
         Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp
index 26420e5..1a87463 100644
--- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp
@@ -47,6 +47,10 @@ namespace WebCore {
 QtFallbackWebPopupCombo::QtFallbackWebPopupCombo(QtFallbackWebPopup& ownerPopup)
     : m_ownerPopup(ownerPopup)
 {
+    // Install an event filter on the view inside the combo box popup to make sure we know
+    // when the popup got closed. E.g. QComboBox::hidePopup() won't be called when the popup
+    // is closed by a mouse wheel event outside its window.
+    view()->installEventFilter(this);
 }
 
 void QtFallbackWebPopupCombo::showPopup()
@@ -81,6 +85,18 @@ void QtFallbackWebPopupCombo::hidePopup()
     m_ownerPopup.popupDidHide();
 }
 
+bool QtFallbackWebPopupCombo::eventFilter(QObject* watched, QEvent* event)
+{
+    Q_ASSERT(watched == view());
+
+    if (event->type() == QEvent::Show && !m_ownerPopup.m_popupVisible)
+        showPopup();
+    else if (event->type() == QEvent::Hide && m_ownerPopup.m_popupVisible)
+        hidePopup();
+
+    return false;
+}
+
 // QtFallbackWebPopup
 
 QtFallbackWebPopup::QtFallbackWebPopup()
@@ -97,8 +113,8 @@ QtFallbackWebPopup::~QtFallbackWebPopup()
 {
     // If we create a proxy, then the deletion of the proxy and the
     // combo will be done by the proxy's parent (QGraphicsWebView)
-    if (!m_proxy)
-        delete m_combo;
+    if (!m_proxy && m_combo)
+        m_combo->deleteLater();
 }
 
 void QtFallbackWebPopup::show()
diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h
index 6d2e1ff..860e9fa 100644
--- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h
+++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h
@@ -62,6 +62,7 @@ public:
     QtFallbackWebPopupCombo(QtFallbackWebPopup& ownerPopup);
     virtual void showPopup();
     virtual void hidePopup();
+    virtual bool eventFilter(QObject* watched, QEvent* event);
 
 private:
     QtFallbackWebPopup& m_ownerPopup;
-- 
cgit v0.12

