1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/tab_contents/chrome_web_contents_view_focus_helper.h" 6 7 #include "base/memory/ptr_util.h" 8 #include "chrome/browser/ui/sad_tab_helper.h" 9 #include "chrome/browser/ui/views/sad_tab_view.h" 10 #include "components/web_modal/web_contents_modal_dialog_manager.h" 11 #include "content/public/browser/render_widget_host_view.h" 12 #include "content/public/browser/web_contents.h" 13 #include "ui/views/focus/focus_manager.h" 14 #include "ui/views/widget/widget.h" 15 16 // static CreateForWebContents(content::WebContents * web_contents)17void ChromeWebContentsViewFocusHelper::CreateForWebContents( 18 content::WebContents* web_contents) { 19 if (!ChromeWebContentsViewFocusHelper::FromWebContents(web_contents)) { 20 web_contents->SetUserData( 21 ChromeWebContentsViewFocusHelper::UserDataKey(), 22 base::WrapUnique(new ChromeWebContentsViewFocusHelper(web_contents))); 23 } 24 } 25 ChromeWebContentsViewFocusHelper(content::WebContents * web_contents)26ChromeWebContentsViewFocusHelper::ChromeWebContentsViewFocusHelper( 27 content::WebContents* web_contents) 28 : web_contents_(web_contents) {} 29 Focus()30bool ChromeWebContentsViewFocusHelper::Focus() { 31 SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents_); 32 if (sad_tab_helper) { 33 SadTabView* sad_tab = static_cast<SadTabView*>(sad_tab_helper->sad_tab()); 34 if (sad_tab) { 35 sad_tab->RequestFocus(); 36 return true; 37 } 38 } 39 40 const web_modal::WebContentsModalDialogManager* manager = 41 web_modal::WebContentsModalDialogManager::FromWebContents(web_contents_); 42 if (manager && manager->IsDialogActive()) { 43 manager->FocusTopmostDialog(); 44 return true; 45 } 46 47 return false; 48 } 49 TakeFocus(bool reverse)50bool ChromeWebContentsViewFocusHelper::TakeFocus(bool reverse) { 51 views::FocusManager* focus_manager = GetFocusManager(); 52 if (focus_manager) { 53 focus_manager->AdvanceFocus(reverse); 54 return true; 55 } 56 return false; 57 } 58 StoreFocus()59void ChromeWebContentsViewFocusHelper::StoreFocus() { 60 last_focused_view_tracker_.SetView(nullptr); 61 if (GetFocusManager()) 62 last_focused_view_tracker_.SetView(GetFocusManager()->GetFocusedView()); 63 } 64 RestoreFocus()65bool ChromeWebContentsViewFocusHelper::RestoreFocus() { 66 views::View* view_to_focus = GetStoredFocus(); 67 last_focused_view_tracker_.SetView(nullptr); 68 if (view_to_focus) { 69 view_to_focus->RequestFocus(); 70 return true; 71 } 72 return false; 73 } 74 ResetStoredFocus()75void ChromeWebContentsViewFocusHelper::ResetStoredFocus() { 76 last_focused_view_tracker_.SetView(nullptr); 77 } 78 GetStoredFocus()79views::View* ChromeWebContentsViewFocusHelper::GetStoredFocus() { 80 views::View* last_focused_view = last_focused_view_tracker_.view(); 81 if (last_focused_view && last_focused_view->IsFocusable() && 82 GetFocusManager()->ContainsView(last_focused_view)) { 83 return last_focused_view; 84 } 85 return nullptr; 86 } 87 GetActiveNativeView()88gfx::NativeView ChromeWebContentsViewFocusHelper::GetActiveNativeView() { 89 return web_contents_->GetNativeView(); 90 } 91 GetTopLevelWidget()92views::Widget* ChromeWebContentsViewFocusHelper::GetTopLevelWidget() { 93 return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView()); 94 } 95 GetFocusManager()96views::FocusManager* ChromeWebContentsViewFocusHelper::GetFocusManager() { 97 views::Widget* toplevel_widget = GetTopLevelWidget(); 98 return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL; 99 } 100 101 WEB_CONTENTS_USER_DATA_KEY_IMPL(ChromeWebContentsViewFocusHelper) 102