mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
chrome: Add cleanup when context menu isn't running (fixes #3711)
The menu may not be running in the following cases: - If the menu is empty (e.g. cleared in OnBeforeContextMenu). - If the menu is disabled (see e.g. RenderViewContextMenuViews::Show). - When the run call blocks until the menu is dismissed (macOS behavior). We explicitly clean up in these cases instead of waiting for OnMenuClosed which will otherwise never be called for the first 2 cases. Menu run status is exposed via new ContextMenuDelegate and RenderViewContextMenuBase methods.
This commit is contained in:
@@ -152,6 +152,12 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
|
||||
}
|
||||
|
||||
void OnMenuClosed() override {
|
||||
// May be called multiple times. For example, if the menu runs and is
|
||||
// additionally reset via MaybeResetContextMenu.
|
||||
if (!handler_) {
|
||||
return;
|
||||
}
|
||||
|
||||
handler_->OnContextMenuDismissed(browser_, GetFrame());
|
||||
model_->Detach();
|
||||
|
||||
@@ -203,17 +209,25 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
|
||||
base::BindOnce(&CefContextMenuObserver::ExecuteCommandCallback,
|
||||
weak_ptr_factory_.GetWeakPtr())));
|
||||
|
||||
bool handled = handler_->RunContextMenu(browser_, GetFrame(), params_,
|
||||
model_, callbackImpl.get());
|
||||
if (!handled && callbackImpl->IsDisconnected()) {
|
||||
is_handled_ = handler_->RunContextMenu(browser_, GetFrame(), params_,
|
||||
model_, callbackImpl.get());
|
||||
if (!is_handled_ && callbackImpl->IsDisconnected()) {
|
||||
LOG(ERROR) << "Should return true from RunContextMenu when executing the "
|
||||
"callback";
|
||||
handled = true;
|
||||
is_handled_ = true;
|
||||
}
|
||||
if (!handled) {
|
||||
if (!is_handled_) {
|
||||
callbackImpl->Disconnect();
|
||||
}
|
||||
return handled;
|
||||
return is_handled_;
|
||||
}
|
||||
|
||||
void MaybeResetContextMenu() {
|
||||
// Don't reset the menu when the client is using custom handling. It will be
|
||||
// reset via ExecuteCommandCallback instead.
|
||||
if (!is_handled_) {
|
||||
OnMenuClosed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -282,6 +296,8 @@ class CefContextMenuObserver : public RenderViewContextMenuObserver,
|
||||
using ItemInfoMap = std::map<int, ItemInfo>;
|
||||
ItemInfoMap iteminfomap_;
|
||||
|
||||
bool is_handled_ = false;
|
||||
|
||||
base::WeakPtrFactory<CefContextMenuObserver> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
@@ -336,4 +352,13 @@ bool HandleContextMenu(content::WebContents* opener,
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaybeResetContextMenu(content::WebContents* opener) {
|
||||
auto browser = CefBrowserHostBase::GetBrowserForContents(opener);
|
||||
if (browser && browser->context_menu_observer()) {
|
||||
return static_cast<CefContextMenuObserver*>(
|
||||
browser->context_menu_observer())
|
||||
->MaybeResetContextMenu();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace context_menu
|
||||
|
Reference in New Issue
Block a user