Closed GoogleCodeExporter closed 9 years ago
A few problems with your patch:
1. UIT_CloseView(UIT_GetMainWndHandle()) in
CefBrowserImpl::UIT_DestroyBrowser() will close the parent window instead of
the browser window.
2. ShowWindow(root, SW_SHOWNORMAL) in BrowserWebViewDelegate::show() won't
behave as expected if m_hWndParent isn't a root window.
Original comment by magreenb...@gmail.com
on 11 Jul 2011 at 4:47
Correct, my solution is not ideal. Yeah, so this limits the functionality to
just one browser per parent window where the parent must be the root rather
than leaving open the possibility of having multiple browsers, possibly in a
container window,
somewhere in a root window.
Let me try again...
I am trying to solve the "window.close()" problem for any contained browser
window that is a child of another window. This is not working right in the most
recent couple of builds. (modal dialog support changed the miss-behavior a bit).
How about something like this:
* Add a bool CefLifeSpanHandler::QueryCanClose() in the browser's WM_CLOSE call
so that clients can override which window gets closed by denying the close and
handling it from a higher level, allowing it to proceed as is, or denying it
for some other reason. Return true to allow it to close, false otherwise.
* Move the re-enabling of the opener window for modal dialogs to a method that
clients can call (rather than forwarding the WM_CLOSE call from the parent
window to the browser.)
// This must be called if the browser is modal and the modal window is
// handled by CEF's modal loop.
void CefBrowser::PrepareToCloseModalWindow()
{
// We must re-enable the opener (owner of the modal window)
// before we close the popup to avoid focus/activation/z-order issues.
if (browser->opener_ && browser->opener_was_disabled_by_modal_loop_) {
HWND owner = ::GetAncestor(browser->opener_, GA_ROOT);
::EnableWindow(owner, TRUE);
}
}
* CefBrowser::PrepareToCloseModalWindow() and
CefLifeSpanHandler::OnBeforeClose()
would get called if QueryCanClose() returned true.
* If the contained browser window is allowed to close, it will be removed
from its parent window. Clients can use the OnBeforeClose() callback to
cleanup the parent window's layout.
Thoughts?
I have a test case for window.close() at
http://www.gusverdun.com/cef/modal/close.html
Original comment by gusver...@gmail.com
on 12 Jul 2011 at 9:51
Attached is a patch that reworks the solution to handle the window.close() case
when the browser is contained while allowing for multiple contained browser
windows.
I added the proposed bool CefLifeSpanHandler::QueryCanClose() and moved the
CefLifeSpanHandler::OnBeforeClose() call back to the UIT_DestroyBrowser() where
it was before the modal window support changed it.
I changed the name of the proposed PrepareToCloseModalWindow() to just
PrepareToCloseBrowser() which only needs to be called when closing the parent
window of a contained browser window.
Thanks for taking a look at this patch.
Original comment by gusver...@gmail.com
on 14 Jul 2011 at 7:17
Attachments:
Perhaps we're make this too complicated. These are the close steps as I
understand them for modal windows:
1. Re-enable the parent window in WM_CLOSE. WM_CLOSE messages are currently
sent directly by the client or indirectly by calling CefBrowser::CloseBrowser().
2. Quit the modal loop in WM_DESTROY. WM_DESTROY messages are sent when a
parent window is destroyed or when the WM_CLOSE message is allowed to
propagate. WM_DESTROY calls UIT_DestroyBrowser().
We need to give the client an opportunity to handle both of these events. If
the client doesn't handle them then we need to do so internally.
This is what I think should happen:
1. Add a new DoClose() callback that will be executed first thing when a
WM_CLOSE message is received. If the client returns false from DoClose() then
the WM_CLOSE message will be allowed to propagate resulting in a WM_DESTROY
message. If the client returns true from DoClose() then CEF will return
immediately without propagating the WM_CLOSE message and the client can either
cancel the close (by doing nothing) or perform some other action (like
destroying a parent window) that eventually results in the browser window
receiving a WM_DESTROY message. Eliminate the current OnBeforeClose() callback
in WM_CLOSE. If the user provided their own modal loop implementation they
would re-enable the parent window in DoClose().
2. Always call OnBeforeClose() in UIT_DestroyBrowser(). Eliminate the current
QuitModal() callback in UIT_DestroyBrowser(). If the user provided their own
modal loop implementation they would exit that loop in OnBeforeClose().
What do you think?
Original comment by magreenb...@gmail.com
on 14 Jul 2011 at 8:47
[deleted comment]
Sorry for the delay in my response... I was on a much needed vacation. :)
Attached is an updated patch with your suggestions. I still need a way execute
the cleanup code that re-enables the opener window when I close the parent
window of a browser window. I am calling this method
CefBrowser::ParentWindowWillClose() rather than PrepareToCloseBrowser() to make
it clear that this only matters to clients when the browser window is contained
in some other window they own.
Thanks for your suggestions.
Original comment by gusver...@gmail.com
on 26 Jul 2011 at 4:42
Attachments:
Looks great, thank you. Committed with minor documentation and style changes as
revision 271.
Original comment by magreenb...@gmail.com
on 3 Aug 2011 at 3:36
Original issue reported on code.google.com by
gusver...@gmail.com
on 7 Jul 2011 at 9:41Attachments: