Index: ui/views/bubble/tray_bubble_view.cc |
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc |
index a7657e9ceaf7cf0bbde4274c7963eeded7865489..7a592ea8cbae3ef1fca5c741b3cc8c001a603bcf 100644 |
--- a/ui/views/bubble/tray_bubble_view.cc |
+++ b/ui/views/bubble/tray_bubble_view.cc |
@@ -196,7 +196,7 @@ TrayBubbleView::TrayBubbleView(const InitParams& init_params) |
bubble_border_->set_alignment(BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
bubble_border_->set_paint_arrow(BubbleBorder::PAINT_NONE); |
set_parent_window(params_.parent_window); |
- set_can_activate(params_.can_activate); |
James Cook
2017/06/09 16:06:13
Is TrayBubbleView::InitParams::can_activate still
|
+ set_can_activate(false); |
set_notify_enter_exit_on_child(true); |
set_close_on_deactivate(init_params.close_on_deactivate); |
set_margins(gfx::Insets()); |
@@ -211,9 +211,12 @@ TrayBubbleView::TrayBubbleView(const InitParams& init_params) |
TrayBubbleView::~TrayBubbleView() { |
mouse_watcher_.reset(); |
- // Inform host items (models) that their views are being destroyed. |
- if (delegate_) |
+ if (delegate_) { |
+ delegate_->UnregisterAllAccelerators(this); |
+ |
+ // Inform host items (models) that their views are being destroyed. |
delegate_->BubbleViewDestroyed(); |
+ } |
} |
// static |
@@ -230,6 +233,16 @@ void TrayBubbleView::InitializeAndShowBubble() { |
UpdateBubble(); |
++g_current_tray_bubble_showing_count_; |
+ |
+ // If TrayBubbleView cannot be activated, register accelerators to activate |
James Cook
2017/06/09 16:06:13
Comment says "activate it" but list contains Escap
yawano
2017/06/12 09:11:04
Done.
|
+ // it by keyboard. |
+ if (delegate_ && !CanActivate()) { |
+ delegate_->RegisterAccelerators( |
+ {ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE), |
+ ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE), |
+ ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN)}, |
+ this); |
+ } |
} |
void TrayBubbleView::UpdateBubble() { |
@@ -237,6 +250,11 @@ void TrayBubbleView::UpdateBubble() { |
SizeToContents(); |
bubble_content_mask_->layer()->SetBounds(layer()->bounds()); |
GetWidget()->GetRootView()->SchedulePaint(); |
+ |
+ // When extra keyboard accessibility is enabled, focus the default item if |
+ // no item is focused. |
+ if (delegate_ && delegate_->ShouldEnableExtraKeyboardAccessibility()) |
+ FocusDefaultIfNeeded(); |
} |
} |
@@ -263,6 +281,13 @@ gfx::Insets TrayBubbleView::GetBorderInsets() const { |
return bubble_border_->GetInsets(); |
} |
+void TrayBubbleView::ResetDelegate() { |
+ if (delegate_) |
+ delegate_->UnregisterAllAccelerators(this); |
+ |
+ delegate_ = nullptr; |
+} |
+ |
int TrayBubbleView::GetDialogButtons() const { |
return ui::DIALOG_BUTTON_NONE; |
} |
@@ -373,6 +398,24 @@ void TrayBubbleView::MouseMovedOutOfHost() { |
mouse_watcher_->Stop(); |
} |
+bool TrayBubbleView::AcceleratorPressed(const ui::Accelerator& accelerator) { |
+ if (accelerator == ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)) { |
+ CloseBubbleView(); |
+ return true; |
+ } else if (accelerator == ui::Accelerator(ui::VKEY_TAB, ui::EF_NONE) || |
James Cook
2017/06/09 16:06:13
nit: no "else" after return
yawano
2017/06/12 09:11:04
Done.
|
+ accelerator == ui::Accelerator(ui::VKEY_TAB, ui::EF_SHIFT_DOWN)) { |
+ ui::KeyEvent key_event( |
+ accelerator.key_state() == ui::Accelerator::KeyState::PRESSED |
+ ? ui::EventType::ET_KEY_PRESSED |
+ : ui::EventType::ET_KEY_RELEASED, |
+ accelerator.key_code(), accelerator.modifiers()); |
+ ActivateAndStartNavigation(key_event); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
void TrayBubbleView::ChildPreferredSizeChanged(View* child) { |
SizeToContents(); |
} |
@@ -385,4 +428,39 @@ void TrayBubbleView::ViewHierarchyChanged( |
} |
} |
+void TrayBubbleView::CloseBubbleView() { |
+ if (!delegate_) |
+ return; |
+ |
+ delegate_->UnregisterAllAccelerators(this); |
+ delegate_->HideBubble(this); |
+} |
+ |
+void TrayBubbleView::ActivateAndStartNavigation(const ui::KeyEvent& key_event) { |
+ set_can_activate(true); |
+ GetWidget()->Activate(); |
+ if (!GetWidget()->GetFocusManager()->OnKeyEvent(key_event) && delegate_) { |
+ // No need to handle accelerators by TrayBubbleView after focus has moved to |
+ // the widget. The focused view will handle focus traversal. |
+ // FocusManager::OnKeyEvent returns false when it consumes a key event. |
+ delegate_->UnregisterAllAccelerators(this); |
+ } |
+} |
+ |
+void TrayBubbleView::FocusDefaultIfNeeded() { |
+ views::FocusManager* manager = GetFocusManager(); |
+ if (!manager || manager->GetFocusedView()) |
+ return; |
+ |
+ views::View* view = |
+ manager->GetNextFocusableView(nullptr, nullptr, false, false); |
+ if (!view) |
+ return; |
+ |
+ set_can_activate(true); |
+ GetWidget()->Activate(); |
+ |
+ view->RequestFocus(); |
+} |
+ |
} // namespace views |