Force close browsers and handle bigpicture exit
Call CloseBrowser(true) for chrome, popup and tab browsers to force shutdown. Immediately destroy the top-level window and call MaybeFinishShutdown() to avoid hangs when WM_CLOSE is not resent by Alloy child-window paths. Route "close" and new "exit-bigpicture" chrome commands through OnWindowCloseRequested so they trigger the same shutdown flow. Add IsBigPictureFrame and permit the "exit-bigpicture" process message from bigpicture internal frames.
This commit is contained in:
@@ -162,10 +162,6 @@ void NebulaController::OnWindowCloseRequested() {
|
||||
}
|
||||
|
||||
if (closing_) {
|
||||
// CEF re-sends WM_CLOSE to the top-level window after each Alloy
|
||||
// child browser finishes its JS unload + DoClose phase. Destroy the
|
||||
// Nebula window now so CEF can tear down the child browser HWNDs and
|
||||
// fire OnBeforeClose; MaybeFinishShutdown will then quit the loop.
|
||||
if (window_ && window_->native_handle()) {
|
||||
nebula::platform::DestroyTopLevelWindow(window_->native_handle());
|
||||
}
|
||||
@@ -180,16 +176,24 @@ void NebulaController::OnWindowCloseRequested() {
|
||||
}
|
||||
|
||||
if (chrome_browser_) {
|
||||
chrome_browser_->GetHost()->CloseBrowser(false);
|
||||
chrome_browser_->GetHost()->CloseBrowser(true);
|
||||
}
|
||||
if (menu_popup_browser_) {
|
||||
menu_popup_browser_->GetHost()->CloseBrowser(false);
|
||||
menu_popup_browser_->GetHost()->CloseBrowser(true);
|
||||
}
|
||||
for (const auto& tab : tabs_.Tabs()) {
|
||||
if (tab.browser) {
|
||||
tab.browser->GetHost()->CloseBrowser(false);
|
||||
tab.browser->GetHost()->CloseBrowser(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not wait for CEF to re-send WM_CLOSE to the host window. On some
|
||||
// Alloy child-window paths that message never arrives, leaving the app
|
||||
// alive with all close affordances disabled until the process is killed.
|
||||
if (window_ && window_->native_handle()) {
|
||||
nebula::platform::DestroyTopLevelWindow(window_->native_handle());
|
||||
}
|
||||
MaybeFinishShutdown();
|
||||
}
|
||||
|
||||
void NebulaController::OnActiveTabChanged(const nebula::browser::NebulaTab& tab) {
|
||||
@@ -307,7 +311,9 @@ void NebulaController::OnChromeCommand(const std::string& command, const std::st
|
||||
} else if (command == "maximize" && window_) {
|
||||
window_->ToggleMaximize();
|
||||
} else if (command == "close" && window_) {
|
||||
window_->Close();
|
||||
OnWindowCloseRequested();
|
||||
} else if (command == "exit-bigpicture" && window_) {
|
||||
OnWindowCloseRequested();
|
||||
} else if (command == "drag" && window_) {
|
||||
window_->BeginDrag();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@ bool IsSettingsFrame(CefRefPtr<CefFrame> frame) {
|
||||
return nebula::ui::ToInternalUrl(frame->GetURL().ToString()).starts_with("nebula://settings");
|
||||
}
|
||||
|
||||
bool IsBigPictureFrame(CefRefPtr<CefFrame> frame) {
|
||||
if (!frame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string url = nebula::ui::ToInternalUrl(frame->GetURL().ToString());
|
||||
return url.starts_with("nebula://bigpicture") ||
|
||||
url.starts_with("nebula://big-picture");
|
||||
}
|
||||
|
||||
std::vector<std::string> ToStringVector(const std::vector<CefString>& values) {
|
||||
std::vector<std::string> result;
|
||||
result.reserve(values.size());
|
||||
@@ -67,7 +77,10 @@ bool NebulaBrowserClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser
|
||||
command == "new-tab" ||
|
||||
command == "clear-site-history" ||
|
||||
command == "clear-search-history");
|
||||
if (!allowed_insecure_command && !allowed_settings_command) {
|
||||
const bool allowed_big_picture_command =
|
||||
IsBigPictureFrame(frame) && command == "exit-bigpicture";
|
||||
if (!allowed_insecure_command && !allowed_settings_command &&
|
||||
!allowed_big_picture_command) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user