summaryrefslogtreecommitdiff
path: root/chromium/ui/views/focus/focus_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/focus/focus_manager.cc')
-rw-r--r--chromium/ui/views/focus/focus_manager.cc38
1 files changed, 30 insertions, 8 deletions
diff --git a/chromium/ui/views/focus/focus_manager.cc b/chromium/ui/views/focus/focus_manager.cc
index 0b634e3f151..536755394f4 100644
--- a/chromium/ui/views/focus/focus_manager.cc
+++ b/chromium/ui/views/focus/focus_manager.cc
@@ -206,7 +206,9 @@ bool FocusManager::RotatePaneFocus(Direction direction,
continue;
pane->RequestFocus();
- focused_view = GetFocusedView();
+ // |pane| may be in a different widget, so don't assume its focus manager
+ // is |this|.
+ focused_view = pane->GetWidget()->GetFocusManager()->GetFocusedView();
if (pane == focused_view || pane->Contains(focused_view))
return true;
}
@@ -609,7 +611,10 @@ void FocusManager::OnViewIsDeleting(View* view) {
bool FocusManager::RedirectAcceleratorToBubbleAnchorWidget(
const ui::Accelerator& accelerator) {
- Widget* anchor_widget = GetBubbleAnchorWidget();
+ views::BubbleDialogDelegate* widget_delegate =
+ widget_->widget_delegate()->AsBubbleDialogDelegate();
+ Widget* anchor_widget =
+ widget_delegate ? widget_delegate->anchor_widget() : nullptr;
if (!anchor_widget)
return false;
@@ -617,15 +622,32 @@ bool FocusManager::RedirectAcceleratorToBubbleAnchorWidget(
if (!focus_manager->IsAcceleratorRegistered(accelerator))
return false;
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // Processing an accelerator can delete things. Because we
+ // need these objects afterwards on Linux, save widget_ as weak pointer and
+ // save the close_on_deactivate property value of widget_delegate in a
+ // variable.
+ base::WeakPtr<Widget> widget_weak_ptr = widget_->GetWeakPtr();
+ const bool close_widget_on_deactivate =
+ widget_delegate->close_on_deactivate();
+#endif
+
// The parent view must be focused for it to process events.
focus_manager->SetFocusedView(anchor_widget->GetRootView());
- return focus_manager->ProcessAccelerator(accelerator);
-}
+ const bool accelerator_processed =
+ focus_manager->ProcessAccelerator(accelerator);
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // Need to manually close the bubble widget on Linux. On Linux when the
+ // bubble is shown, the main widget remains active. Because of that when
+ // focus is set to the main widget to process accelerator, the main widget
+ // isn't activated and the bubble widget isn't deactivated and closed.
+ if (accelerator_processed && close_widget_on_deactivate) {
+ widget_weak_ptr->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
+ }
+#endif
-Widget* FocusManager::GetBubbleAnchorWidget() {
- BubbleDialogDelegateView* widget_delegate =
- widget_->widget_delegate()->AsBubbleDialogDelegate();
- return widget_delegate ? widget_delegate->anchor_widget() : nullptr;
+ return accelerator_processed;
}
} // namespace views