mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 09:41:41 +00:00
mshtml: Grab refs to windows upfront before sending pagehide events.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
3c2b417151
commit
6bd162d9d2
|
@ -414,45 +414,73 @@ HRESULT call_set_active_object(IOleInPlaceUIWindow *window, IOleInPlaceActiveObj
|
|||
return IOleInPlaceUIWindow_SetActiveObject(window, act_obj, act_obj ? html_documentW : NULL);
|
||||
}
|
||||
|
||||
static void send_unload_events_impl(HTMLInnerWindow *window)
|
||||
static unsigned get_window_list_num(HTMLInnerWindow *window)
|
||||
{
|
||||
HTMLOuterWindow *child;
|
||||
unsigned ret = 1;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry)
|
||||
ret += get_window_list_num(child->base.inner_window);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HTMLInnerWindow **get_window_list(HTMLInnerWindow *window, HTMLInnerWindow **output)
|
||||
{
|
||||
HTMLOuterWindow *child;
|
||||
|
||||
*output++ = window;
|
||||
IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry)
|
||||
output = get_window_list(child->base.inner_window, output);
|
||||
return output;
|
||||
}
|
||||
|
||||
static void send_unload_events(HTMLDocumentObj *doc)
|
||||
{
|
||||
HTMLInnerWindow **windows, *window;
|
||||
DOMEvent *event;
|
||||
unsigned i, num;
|
||||
HRESULT hres;
|
||||
|
||||
if(!window)
|
||||
if(!doc->window || !doc->doc_node->content_ready)
|
||||
return;
|
||||
window = doc->window->base.inner_window;
|
||||
|
||||
if(window->doc && !window->doc->unload_sent) {
|
||||
window->doc->unload_sent = TRUE;
|
||||
/* Grab list of all windows ahead, and keep refs,
|
||||
since it can be detached from under our feet. */
|
||||
num = get_window_list_num(window);
|
||||
if(!(windows = malloc(num * sizeof(*windows))))
|
||||
return;
|
||||
get_window_list(window, windows);
|
||||
|
||||
/* Native sends pagehide events prior to unload on the same window
|
||||
before it moves on to the next window, so they're interleaved. */
|
||||
if(window->doc->document_mode >= COMPAT_MODE_IE11) {
|
||||
hres = create_document_event(window->doc, EVENTID_PAGEHIDE, &event);
|
||||
for(i = 0; i < num; i++) {
|
||||
window = windows[i];
|
||||
|
||||
if(window->doc && !window->doc->unload_sent) {
|
||||
window->doc->unload_sent = TRUE;
|
||||
|
||||
/* Native sends pagehide events prior to unload on the same window
|
||||
before it moves on to the next window, so they're interleaved. */
|
||||
if(window->doc->document_mode >= COMPAT_MODE_IE11) {
|
||||
hres = create_document_event(window->doc, EVENTID_PAGEHIDE, &event);
|
||||
if(SUCCEEDED(hres)) {
|
||||
dispatch_event(&window->event_target, event);
|
||||
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||
}
|
||||
}
|
||||
|
||||
hres = create_document_event(window->doc, EVENTID_UNLOAD, &event);
|
||||
if(SUCCEEDED(hres)) {
|
||||
dispatch_event(&window->event_target, event);
|
||||
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||
}
|
||||
}
|
||||
|
||||
hres = create_document_event(window->doc, EVENTID_UNLOAD, &event);
|
||||
if(SUCCEEDED(hres)) {
|
||||
dispatch_event(&window->event_target, event);
|
||||
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||
}
|
||||
IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(child, &window->children, HTMLOuterWindow, sibling_entry)
|
||||
send_unload_events_impl(child->base.inner_window);
|
||||
}
|
||||
|
||||
static void send_unload_events(HTMLDocumentObj *doc)
|
||||
{
|
||||
if(!doc->window || !doc->doc_node->content_ready)
|
||||
return;
|
||||
|
||||
send_unload_events_impl(doc->window->base.inner_window);
|
||||
free(windows);
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
|
Loading…
Reference in a new issue