Changeset 52830 in webkit


Ignore:
Timestamp:
Jan 5, 2010 3:07:33 PM (14 years ago)
Author:
Adam Roben
Message:

Make IWebView::close and destroying a WebView's HWND optional for WebKit clients

WebView will now take care of these operations itself when its last
reference is released, if they haven't already been done.

IWebView::close now also destroys the WebView's HWND. All WebKit
clients were already performing these operations in succession anyway,
or were attempting to by calling IWebView::close then destroying the
WebView's host window (which actually resulted in the WebView's HWND
leaking, and the crash in the below bug).

Fixes <http://webkit.org/b/32827> Crash when calling IWebView::close,
then releasing the WebView, without calling DestroyWindow

Fixes a few WebViewDestruction tests, too.

Reviewed by Steve Falkenburg.

  • WebView.cpp:

(WebView::~WebView): Don't try to destroy m_viewWindow here. That
should already have happened. Assert that this is the case.
(WebView::close): If m_viewWindow isn't already being destroyed,
destroy it now. Moved the call to revokeDragDrop() here from our
WM_DESTROY handler because it needs to be done before m_viewWindow is
nulled out.
(WebView::WebViewWndProc): Removed call to revokeDragDrop() that
close() now performs.
(WebView::Release): If our last reference is being released, call
close() so that clients don't have to. (It's harmless to call close()
multiple times.) We do this here instead of in the destructor because
close() can cause AddRef() and Release() to be called, and calling
those from within the destructor leads to double-destruction.
(WebView::setHostWindow): Removed an unnecessary (and now harmful)
null-check.
(WebView::revokeDragDrop): Changed an assertion into a run-time check,
since this will now sometimes be called when m_viewWindow hasn't been
created yet. Changed the IsWindow call to a null-check because we
never hold onto a destroyed m_viewWindow.
(WebView::windowAncestryDidChange): If we don't have a view window,
stop tracking changes to our parent's active state.

Location:
trunk/WebKit/win
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit/win/ChangeLog

    r52829 r52830  
     12010-01-05  Adam Roben  <aroben@apple.com>
     2
     3        Make IWebView::close and destroying a WebView's HWND optional for
     4        WebKit clients
     5
     6        WebView will now take care of these operations itself when its last
     7        reference is released, if they haven't already been done.
     8
     9        IWebView::close now also destroys the WebView's HWND. All WebKit
     10        clients were already performing these operations in succession anyway,
     11        or were attempting to by calling IWebView::close then destroying the
     12        WebView's host window (which actually resulted in the WebView's HWND
     13        leaking, and the crash in the below bug).
     14
     15        Fixes <http://webkit.org/b/32827> Crash when calling IWebView::close,
     16        then releasing the WebView, without calling DestroyWindow
     17
     18        Fixes a few WebViewDestruction tests, too.
     19
     20        Reviewed by Steve Falkenburg.
     21
     22        * WebView.cpp:
     23        (WebView::~WebView): Don't try to destroy m_viewWindow here. That
     24        should already have happened. Assert that this is the case.
     25        (WebView::close): If m_viewWindow isn't already being destroyed,
     26        destroy it now. Moved the call to revokeDragDrop() here from our
     27        WM_DESTROY handler because it needs to be done before m_viewWindow is
     28        nulled out.
     29        (WebView::WebViewWndProc): Removed call to revokeDragDrop() that
     30        close() now performs.
     31        (WebView::Release): If our last reference is being released, call
     32        close() so that clients don't have to. (It's harmless to call close()
     33        multiple times.) We do this here instead of in the destructor because
     34        close() can cause AddRef() and Release() to be called, and calling
     35        those from within the destructor leads to double-destruction.
     36        (WebView::setHostWindow): Removed an unnecessary (and now harmful)
     37        null-check.
     38        (WebView::revokeDragDrop): Changed an assertion into a run-time check,
     39        since this will now sometimes be called when m_viewWindow hasn't been
     40        created yet. Changed the IsWindow call to a null-check because we
     41        never hold onto a destroyed m_viewWindow.
     42        (WebView::windowAncestryDidChange): If we don't have a view window,
     43        stop tracking changes to our parent's active state.
     44
    1452010-01-05  Adam Roben  <aroben@apple.com>
    246
  • trunk/WebKit/win/WebView.cpp

    r52829 r52830  
    355355    deleteBackingStore();
    356356
    357     // <rdar://4958382> m_viewWindow will be destroyed when m_hostWindow is destroyed, but if
    358     // setHostWindow was never called we will leak our HWND. If we still have a valid HWND at
    359     // this point, we should just destroy it ourselves.
    360     if (!isBeingDestroyed() && ::IsWindow(m_viewWindow))
    361         ::DestroyWindow(m_viewWindow);
    362 
    363357    // the tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD
    364358    if (::IsWindow(m_toolTipHwnd))
     
    367361    ASSERT(!m_page);
    368362    ASSERT(!m_preferences);
     363    ASSERT(!m_viewWindow);
    369364
    370365    WebViewCount--;
     
    647642    }
    648643   
     644    revokeDragDrop();
     645
     646    if (m_viewWindow) {
     647        // We can't check IsWindow(m_viewWindow) here, because that will return true even while
     648        // we're already handling WM_DESTROY. So we check !isBeingDestroyed() instead.
     649        if (!isBeingDestroyed())
     650            DestroyWindow(m_viewWindow);
     651        // Either we just destroyed m_viewWindow, or it's in the process of being destroyed. Either
     652        // way, we clear it out to make sure we don't try to use it later.
     653        m_viewWindow = 0;
     654    }
     655
    649656    setHostWindow(0);
    650657
     
    19111918            webView->setIsBeingDestroyed();
    19121919            webView->close();
    1913             webView->revokeDragDrop();
    19141920            break;
    19151921        case WM_GESTURENOTIFY:
     
    22812287    ASSERT(!m_deletionHasBegun);
    22822288
     2289    if (m_refCount == 1) {
     2290        // Call close() now so that clients don't have to. (It's harmless to call close() multiple
     2291        // times.) We do this here instead of in our destructor because close() can cause AddRef()
     2292        // and Release() to be called, and if that happened in our destructor we would be destroyed
     2293        // more than once.
     2294        close();
     2295    }
     2296
    22832297    ULONG newRef = --m_refCount;
    22842298    if (!newRef) {
     
    30613075    m_hostWindow = window;
    30623076
    3063     if (m_viewWindow)
    3064         windowAncestryDidChange();
     3077    windowAncestryDidChange();
    30653078
    30663079    return S_OK;
     
    49424955HRESULT WebView::revokeDragDrop()
    49434956{
    4944     ASSERT(::IsWindow(m_viewWindow));
     4957    if (!m_viewWindow)
     4958        return S_OK;
     4959
    49454960    return ::RevokeDragDrop(m_viewWindow);
    49464961}
     
    53705385HRESULT STDMETHODCALLTYPE WebView::windowAncestryDidChange()
    53715386{
    5372     HWND newParent = findTopLevelParent(m_hostWindow);
     5387    HWND newParent;
     5388    if (m_viewWindow)
     5389        newParent = findTopLevelParent(m_hostWindow);
     5390    else {
     5391        // There's no point in tracking active state changes of our parent window if we don't have
     5392        // a window ourselves.
     5393        newParent = 0;
     5394    }
     5395
    53735396    if (newParent == m_topLevelParent)
    53745397        return S_OK;
Note: See TracChangeset for help on using the changeset viewer.