• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be found
3 // in the LICENSE file.
4 
5 #include "libcef/browser/views/window_impl.h"
6 
7 #include "libcef/browser/browser_util.h"
8 #include "libcef/browser/thread_util.h"
9 #include "libcef/browser/views/display_impl.h"
10 #include "libcef/browser/views/fill_layout_impl.h"
11 #include "libcef/browser/views/layout_util.h"
12 #include "libcef/browser/views/view_util.h"
13 #include "libcef/browser/views/window_view.h"
14 
15 #include "base/i18n/rtl.h"
16 #include "ui/base/test/ui_controls.h"
17 #include "ui/compositor/compositor.h"
18 #include "ui/gfx/geometry/rect.h"
19 #include "ui/views/controls/button/menu_button.h"
20 #include "ui/views/controls/menu/menu_runner.h"
21 
22 #if defined(USE_AURA)
23 #include "ui/aura/test/ui_controls_factory_aura.h"
24 #include "ui/aura/window.h"
25 #include "ui/base/test/ui_controls_aura.h"
26 #if defined(USE_OZONE)
27 #include "ui/ozone/public/ozone_ui_controls_test_helper.h"
28 #include "ui/views/test/ui_controls_factory_desktop_aura_ozone.h"
29 #endif
30 #endif  // defined(USE_AURA)
31 
32 #if BUILDFLAG(IS_WIN)
33 #include "ui/display/win/screen_win.h"
34 #endif
35 
36 #if defined(USE_AURA) && defined(USE_OZONE)
37 // Stub implementation for function called from
38 // $root_gen_dir/ui/ozone/test_constructor_list.cc to avoid
39 // //ui/ozone/platform/wayland:ui_test_support dependencies.
40 namespace ui {
CreateOzoneUIControlsTestHelperWayland()41 OzoneUIControlsTestHelper* CreateOzoneUIControlsTestHelperWayland() {
42   NOTREACHED();
43   return nullptr;
44 }
45 }  // namespace ui
46 #endif
47 
48 namespace {
49 
50 // Based on chrome/test/base/interactive_ui_tests_main.cc.
InitializeUITesting()51 void InitializeUITesting() {
52   static bool initialized = false;
53   if (!initialized) {
54     ui_controls::EnableUIControls();
55 
56 #if defined(USE_AURA)
57 #if BUILDFLAG(IS_WIN)
58     ui_controls::InstallUIControlsAura(
59         aura::test::CreateUIControlsAura(nullptr));
60 #elif defined(USE_OZONE)
61     ui_controls::InstallUIControlsAura(
62         views::test::CreateUIControlsDesktopAuraOzone());
63 #endif
64 #endif  // defined(USE_AURA)
65 
66     initialized = true;
67   }
68 }
69 
70 #if defined(USE_AURA)
71 
72 // This class forwards KeyEvents to the CefWindowImpl associated with a widget.
73 // This allows KeyEvents to be processed after all other targets.
74 // Events originating from CefBrowserView will instead be delivered via
75 // CefBrowserViewImpl::HandleKeyboardEvent.
76 class CefUnhandledKeyEventHandler : public ui::EventHandler {
77  public:
CefUnhandledKeyEventHandler(CefWindowImpl * window_impl,views::Widget * widget)78   CefUnhandledKeyEventHandler(CefWindowImpl* window_impl, views::Widget* widget)
79       : window_impl_(window_impl),
80         widget_(widget),
81         window_(widget->GetNativeWindow()) {
82     DCHECK(window_);
83     window_->AddPostTargetHandler(this);
84   }
85 
86   CefUnhandledKeyEventHandler(const CefUnhandledKeyEventHandler&) = delete;
87   CefUnhandledKeyEventHandler& operator=(const CefUnhandledKeyEventHandler&) =
88       delete;
89 
~CefUnhandledKeyEventHandler()90   ~CefUnhandledKeyEventHandler() override {
91     window_->RemovePostTargetHandler(this);
92   }
93 
94   // Implementation of ui::EventHandler:
OnKeyEvent(ui::KeyEvent * event)95   void OnKeyEvent(ui::KeyEvent* event) override {
96     // Give the FocusManager a chance to handle accelerators first.
97     // Widget::OnKeyEvent would normally call this after all EventHandlers have
98     // had a shot but we don't want to wait.
99     if (widget_->GetFocusManager() &&
100         !widget_->GetFocusManager()->OnKeyEvent(*event)) {
101       event->StopPropagation();
102       return;
103     }
104 
105     CefKeyEvent cef_event;
106     if (browser_util::GetCefKeyEvent(*event, cef_event) &&
107         window_impl_->OnKeyEvent(cef_event)) {
108       event->StopPropagation();
109     }
110   }
111 
112  private:
113   // Members are guaranteed to outlive this object.
114   CefWindowImpl* window_impl_;
115   views::Widget* widget_;
116 
117   // |window_| is the event target that is associated with this class.
118   aura::Window* window_;
119 };
120 
121 #endif  // defined(USE_AURA)
122 
123 }  // namespace
124 
125 // static
CreateTopLevelWindow(CefRefPtr<CefWindowDelegate> delegate)126 CefRefPtr<CefWindow> CefWindow::CreateTopLevelWindow(
127     CefRefPtr<CefWindowDelegate> delegate) {
128   return CefWindowImpl::Create(delegate);
129 }
130 
131 // static
Create(CefRefPtr<CefWindowDelegate> delegate)132 CefRefPtr<CefWindowImpl> CefWindowImpl::Create(
133     CefRefPtr<CefWindowDelegate> delegate) {
134   CEF_REQUIRE_UIT_RETURN(nullptr);
135   CefRefPtr<CefWindowImpl> window = new CefWindowImpl(delegate);
136   window->Initialize();
137   window->CreateWidget();
138   if (delegate)
139     delegate->OnWindowCreated(window.get());
140   return window;
141 }
142 
Show()143 void CefWindowImpl::Show() {
144   CEF_REQUIRE_VALID_RETURN_VOID();
145   if (widget_)
146     widget_->Show();
147 }
148 
Hide()149 void CefWindowImpl::Hide() {
150   CEF_REQUIRE_VALID_RETURN_VOID();
151   if (widget_)
152     widget_->Hide();
153 }
154 
CenterWindow(const CefSize & size)155 void CefWindowImpl::CenterWindow(const CefSize& size) {
156   CEF_REQUIRE_VALID_RETURN_VOID();
157   if (widget_)
158     widget_->CenterWindow(gfx::Size(size.width, size.height));
159 }
160 
Close()161 void CefWindowImpl::Close() {
162   CEF_REQUIRE_VALID_RETURN_VOID();
163   if (widget_ && !widget_->IsClosed())
164     widget_->Close();
165 }
166 
IsClosed()167 bool CefWindowImpl::IsClosed() {
168   CEF_REQUIRE_UIT_RETURN(false);
169   return destroyed_ || (widget_ && widget_->IsClosed());
170 }
171 
Activate()172 void CefWindowImpl::Activate() {
173   CEF_REQUIRE_VALID_RETURN_VOID();
174   if (widget_ && widget_->CanActivate() && !widget_->IsActive())
175     widget_->Activate();
176 }
177 
Deactivate()178 void CefWindowImpl::Deactivate() {
179   CEF_REQUIRE_VALID_RETURN_VOID();
180   if (widget_ && widget_->CanActivate() && widget_->IsActive())
181     widget_->Deactivate();
182 }
183 
IsActive()184 bool CefWindowImpl::IsActive() {
185   CEF_REQUIRE_VALID_RETURN(false);
186   if (widget_)
187     return widget_->IsActive();
188   return false;
189 }
190 
BringToTop()191 void CefWindowImpl::BringToTop() {
192   CEF_REQUIRE_VALID_RETURN_VOID();
193   if (widget_)
194     widget_->StackAtTop();
195 }
196 
SetAlwaysOnTop(bool on_top)197 void CefWindowImpl::SetAlwaysOnTop(bool on_top) {
198   CEF_REQUIRE_VALID_RETURN_VOID();
199   if (widget_ && on_top != (widget_->GetZOrderLevel() ==
200                             ui::ZOrderLevel::kFloatingWindow)) {
201     widget_->SetZOrderLevel(on_top ? ui::ZOrderLevel::kFloatingWindow
202                                    : ui::ZOrderLevel::kNormal);
203   }
204 }
205 
IsAlwaysOnTop()206 bool CefWindowImpl::IsAlwaysOnTop() {
207   CEF_REQUIRE_VALID_RETURN(false);
208   if (widget_)
209     return widget_->GetZOrderLevel() == ui::ZOrderLevel::kFloatingWindow;
210   return false;
211 }
212 
Maximize()213 void CefWindowImpl::Maximize() {
214   CEF_REQUIRE_VALID_RETURN_VOID();
215   if (widget_ && !widget_->IsMaximized())
216     widget_->Maximize();
217 }
218 
Minimize()219 void CefWindowImpl::Minimize() {
220   CEF_REQUIRE_VALID_RETURN_VOID();
221   if (widget_ && !widget_->IsMinimized())
222     widget_->Minimize();
223 }
224 
Restore()225 void CefWindowImpl::Restore() {
226   CEF_REQUIRE_VALID_RETURN_VOID();
227   if (widget_ && (widget_->IsMaximized() || widget_->IsMinimized()))
228     widget_->Restore();
229 }
230 
SetFullscreen(bool fullscreen)231 void CefWindowImpl::SetFullscreen(bool fullscreen) {
232   CEF_REQUIRE_VALID_RETURN_VOID();
233   if (widget_ && fullscreen != widget_->IsFullscreen())
234     widget_->SetFullscreen(fullscreen);
235 }
236 
IsMaximized()237 bool CefWindowImpl::IsMaximized() {
238   CEF_REQUIRE_VALID_RETURN(false);
239   if (widget_)
240     return widget_->IsMaximized();
241   return false;
242 }
243 
IsMinimized()244 bool CefWindowImpl::IsMinimized() {
245   CEF_REQUIRE_VALID_RETURN(false);
246   if (widget_)
247     return widget_->IsMinimized();
248   return false;
249 }
250 
IsFullscreen()251 bool CefWindowImpl::IsFullscreen() {
252   CEF_REQUIRE_VALID_RETURN(false);
253   if (widget_)
254     return widget_->IsFullscreen();
255   return false;
256 }
257 
SetTitle(const CefString & title)258 void CefWindowImpl::SetTitle(const CefString& title) {
259   CEF_REQUIRE_VALID_RETURN_VOID();
260   if (root_view())
261     root_view()->SetTitle(title);
262 }
263 
GetTitle()264 CefString CefWindowImpl::GetTitle() {
265   CEF_REQUIRE_VALID_RETURN(CefString());
266   if (root_view())
267     return root_view()->title();
268   return CefString();
269 }
270 
SetWindowIcon(CefRefPtr<CefImage> image)271 void CefWindowImpl::SetWindowIcon(CefRefPtr<CefImage> image) {
272   CEF_REQUIRE_VALID_RETURN_VOID();
273   if (root_view())
274     root_view()->SetWindowIcon(image);
275 }
276 
GetWindowIcon()277 CefRefPtr<CefImage> CefWindowImpl::GetWindowIcon() {
278   CEF_REQUIRE_VALID_RETURN(nullptr);
279   if (root_view())
280     return root_view()->window_icon();
281   return nullptr;
282 }
283 
SetWindowAppIcon(CefRefPtr<CefImage> image)284 void CefWindowImpl::SetWindowAppIcon(CefRefPtr<CefImage> image) {
285   CEF_REQUIRE_VALID_RETURN_VOID();
286   if (root_view())
287     root_view()->SetWindowAppIcon(image);
288 }
289 
GetWindowAppIcon()290 CefRefPtr<CefImage> CefWindowImpl::GetWindowAppIcon() {
291   CEF_REQUIRE_VALID_RETURN(nullptr);
292   if (root_view())
293     return root_view()->window_app_icon();
294   return nullptr;
295 }
296 
AddOverlayView(CefRefPtr<CefView> view,cef_docking_mode_t docking_mode)297 CefRefPtr<CefOverlayController> CefWindowImpl::AddOverlayView(
298     CefRefPtr<CefView> view,
299     cef_docking_mode_t docking_mode) {
300   CEF_REQUIRE_VALID_RETURN(nullptr);
301   if (root_view())
302     return root_view()->AddOverlayView(view, docking_mode);
303   return nullptr;
304 }
305 
GetDebugInfo(base::DictionaryValue * info,bool include_children)306 void CefWindowImpl::GetDebugInfo(base::DictionaryValue* info,
307                                  bool include_children) {
308   ParentClass::GetDebugInfo(info, include_children);
309   if (root_view())
310     info->SetString("title", root_view()->title());
311 }
312 
ShowMenu(CefRefPtr<CefMenuModel> menu_model,const CefPoint & screen_point,cef_menu_anchor_position_t anchor_position)313 void CefWindowImpl::ShowMenu(CefRefPtr<CefMenuModel> menu_model,
314                              const CefPoint& screen_point,
315                              cef_menu_anchor_position_t anchor_position) {
316   ShowMenu(nullptr, menu_model, screen_point, anchor_position);
317 }
318 
Detach()319 void CefWindowImpl::Detach() {
320   // OnDeleteDelegate should always be called before Detach().
321   DCHECK(!widget_);
322 
323   ParentClass::Detach();
324 }
325 
SetBounds(const CefRect & bounds)326 void CefWindowImpl::SetBounds(const CefRect& bounds) {
327   CEF_REQUIRE_VALID_RETURN_VOID();
328   if (widget_) {
329     widget_->SetBounds(
330         gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
331   }
332 }
333 
GetBounds()334 CefRect CefWindowImpl::GetBounds() {
335   CEF_REQUIRE_VALID_RETURN(CefRect());
336   gfx::Rect bounds;
337   if (widget_)
338     bounds = widget_->GetWindowBoundsInScreen();
339   return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
340 }
341 
GetBoundsInScreen()342 CefRect CefWindowImpl::GetBoundsInScreen() {
343   return GetBounds();
344 }
345 
SetSize(const CefSize & size)346 void CefWindowImpl::SetSize(const CefSize& size) {
347   CEF_REQUIRE_VALID_RETURN_VOID();
348   if (widget_)
349     widget_->SetSize(gfx::Size(size.width, size.height));
350 }
351 
SetPosition(const CefPoint & position)352 void CefWindowImpl::SetPosition(const CefPoint& position) {
353   CEF_REQUIRE_VALID_RETURN_VOID();
354   if (widget_) {
355     gfx::Rect bounds = widget_->GetWindowBoundsInScreen();
356     bounds.set_origin(gfx::Point(position.x, position.y));
357     widget_->SetBounds(bounds);
358   }
359 }
360 
SizeToPreferredSize()361 void CefWindowImpl::SizeToPreferredSize() {
362   CEF_REQUIRE_VALID_RETURN_VOID();
363   if (widget_) {
364     if (widget_->non_client_view())
365       widget_->SetSize(widget_->non_client_view()->GetPreferredSize());
366     else
367       widget_->SetSize(root_view()->GetPreferredSize());
368   }
369 }
370 
SetVisible(bool visible)371 void CefWindowImpl::SetVisible(bool visible) {
372   if (visible)
373     Show();
374   else
375     Hide();
376 }
377 
IsVisible()378 bool CefWindowImpl::IsVisible() {
379   CEF_REQUIRE_VALID_RETURN(false);
380   if (widget_)
381     return widget_->IsVisible();
382   return false;
383 }
384 
IsDrawn()385 bool CefWindowImpl::IsDrawn() {
386   return IsVisible();
387 }
388 
SetBackgroundColor(cef_color_t color)389 void CefWindowImpl::SetBackgroundColor(cef_color_t color) {
390   CEF_REQUIRE_VALID_RETURN_VOID();
391   ParentClass::SetBackgroundColor(color);
392   if (widget_ && widget_->GetCompositor())
393     widget_->GetCompositor()->SetBackgroundColor(color);
394 }
395 
CanWidgetClose()396 bool CefWindowImpl::CanWidgetClose() {
397   if (delegate())
398     return delegate()->CanClose(this);
399   return true;
400 }
401 
OnWindowClosing()402 void CefWindowImpl::OnWindowClosing() {
403 #if defined(USE_AURA)
404   unhandled_key_event_handler_.reset();
405 #endif
406 }
407 
OnWindowViewDeleted()408 void CefWindowImpl::OnWindowViewDeleted() {
409   CancelMenu();
410 
411   destroyed_ = true;
412   widget_ = nullptr;
413 
414   if (delegate())
415     delegate()->OnWindowDestroyed(this);
416 
417   // Call Detach() here instead of waiting for the root View to be deleted so
418   // that any following attempts to call CefWindow methods from the delegate
419   // will fail.
420   Detach();
421 }
422 
423 // Will only be called if CanHandleAccelerators() returns true.
AcceleratorPressed(const ui::Accelerator & accelerator)424 bool CefWindowImpl::AcceleratorPressed(const ui::Accelerator& accelerator) {
425   for (const auto& entry : accelerator_map_) {
426     if (entry.second == accelerator)
427       return delegate()->OnAccelerator(this, entry.first);
428   }
429   return false;
430 }
431 
CanHandleAccelerators() const432 bool CefWindowImpl::CanHandleAccelerators() const {
433   if (delegate() && widget_)
434     return widget_->IsActive();
435   return false;
436 }
437 
OnKeyEvent(const CefKeyEvent & event)438 bool CefWindowImpl::OnKeyEvent(const CefKeyEvent& event) {
439   if (delegate())
440     return delegate()->OnKeyEvent(this, event);
441   return false;
442 }
443 
ShowMenu(views::MenuButton * menu_button,CefRefPtr<CefMenuModel> menu_model,const CefPoint & screen_point,cef_menu_anchor_position_t anchor_position)444 void CefWindowImpl::ShowMenu(views::MenuButton* menu_button,
445                              CefRefPtr<CefMenuModel> menu_model,
446                              const CefPoint& screen_point,
447                              cef_menu_anchor_position_t anchor_position) {
448   CancelMenu();
449 
450   if (!widget_)
451     return;
452 
453   CefMenuModelImpl* menu_model_impl =
454       static_cast<CefMenuModelImpl*>(menu_model.get());
455   if (!menu_model_impl || !menu_model_impl->model())
456     return;
457 
458   menu_model_ = menu_model_impl;
459 
460   // We'll send the MenuClosed notification manually for better accuracy.
461   menu_model_->set_auto_notify_menu_closed(false);
462 
463   menu_runner_.reset(new views::MenuRunner(
464       menu_model_impl->model(),
465       menu_button ? views::MenuRunner::HAS_MNEMONICS
466                   : views::MenuRunner::CONTEXT_MENU,
467       base::BindRepeating(&CefWindowImpl::MenuClosed, this)));
468 
469   menu_runner_->RunMenuAt(
470       widget_, menu_button ? menu_button->button_controller() : nullptr,
471       gfx::Rect(gfx::Point(screen_point.x, screen_point.y), gfx::Size()),
472       static_cast<views::MenuAnchorPosition>(anchor_position),
473       ui::MENU_SOURCE_NONE);
474 }
475 
MenuClosed()476 void CefWindowImpl::MenuClosed() {
477   menu_model_->NotifyMenuClosed();
478   menu_model_ = nullptr;
479   menu_runner_.reset(nullptr);
480 }
481 
CancelMenu()482 void CefWindowImpl::CancelMenu() {
483   CEF_REQUIRE_VALID_RETURN_VOID();
484   if (menu_runner_)
485     menu_runner_->Cancel();
486   DCHECK(!menu_model_);
487   DCHECK(!menu_runner_);
488 }
489 
GetDisplay()490 CefRefPtr<CefDisplay> CefWindowImpl::GetDisplay() {
491   CEF_REQUIRE_VALID_RETURN(nullptr);
492   if (widget_ && root_view()) {
493     const display::Display& display = root_view()->GetDisplay();
494     if (display.is_valid())
495       return new CefDisplayImpl(display);
496   }
497   return nullptr;
498 }
499 
GetClientAreaBoundsInScreen()500 CefRect CefWindowImpl::GetClientAreaBoundsInScreen() {
501   CEF_REQUIRE_VALID_RETURN(CefRect());
502   if (widget_) {
503     gfx::Rect bounds = widget_->GetClientAreaBoundsInScreen();
504 
505     views::NonClientFrameView* non_client_frame_view =
506         root_view()->GetNonClientFrameView();
507     if (non_client_frame_view) {
508       // When using a custom drawn NonClientFrameView the native Window will not
509       // know the actual client bounds. Adjust the native Window bounds for the
510       // reported client bounds.
511       const gfx::Rect& client_bounds =
512           non_client_frame_view->GetBoundsForClientView();
513       bounds.set_origin(bounds.origin() + client_bounds.OffsetFromOrigin());
514       bounds.set_size(client_bounds.size());
515     }
516 
517     return CefRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
518   }
519   return CefRect();
520 }
521 
SetDraggableRegions(const std::vector<CefDraggableRegion> & regions)522 void CefWindowImpl::SetDraggableRegions(
523     const std::vector<CefDraggableRegion>& regions) {
524   CEF_REQUIRE_VALID_RETURN_VOID();
525   if (root_view())
526     root_view()->SetDraggableRegions(regions);
527 }
528 
GetWindowHandle()529 CefWindowHandle CefWindowImpl::GetWindowHandle() {
530   CEF_REQUIRE_VALID_RETURN(kNullWindowHandle);
531   return view_util::GetWindowHandle(widget_);
532 }
533 
SendKeyPress(int key_code,uint32 event_flags)534 void CefWindowImpl::SendKeyPress(int key_code, uint32 event_flags) {
535   CEF_REQUIRE_VALID_RETURN_VOID();
536   InitializeUITesting();
537 
538   gfx::NativeWindow native_window = view_util::GetNativeWindow(widget_);
539   if (!native_window)
540     return;
541 
542   ui_controls::SendKeyPress(native_window,
543                             static_cast<ui::KeyboardCode>(key_code),
544                             !!(event_flags & EVENTFLAG_CONTROL_DOWN),
545                             !!(event_flags & EVENTFLAG_SHIFT_DOWN),
546                             !!(event_flags & EVENTFLAG_ALT_DOWN),
547                             false);  // Command key is not supported by Aura.
548 }
549 
SendMouseMove(int screen_x,int screen_y)550 void CefWindowImpl::SendMouseMove(int screen_x, int screen_y) {
551   CEF_REQUIRE_VALID_RETURN_VOID();
552   InitializeUITesting();
553 
554   gfx::Point point(screen_x, screen_y);
555 #if BUILDFLAG(IS_WIN)
556   // Windows expects pixel coordinates.
557   point = display::win::ScreenWin::DIPToScreenPoint(point);
558 #endif
559 
560   ui_controls::SendMouseMove(point.x(), point.y());
561 }
562 
SendMouseEvents(cef_mouse_button_type_t button,bool mouse_down,bool mouse_up)563 void CefWindowImpl::SendMouseEvents(cef_mouse_button_type_t button,
564                                     bool mouse_down,
565                                     bool mouse_up) {
566   CEF_REQUIRE_VALID_RETURN_VOID();
567   if (!mouse_down && !mouse_up)
568     return;
569 
570   InitializeUITesting();
571 
572   ui_controls::MouseButton type = ui_controls::LEFT;
573   if (button == MBT_MIDDLE)
574     type = ui_controls::MIDDLE;
575   else if (button == MBT_RIGHT)
576     type = ui_controls::RIGHT;
577 
578   int state = 0;
579   if (mouse_down)
580     state |= ui_controls::DOWN;
581   if (mouse_up)
582     state |= ui_controls::UP;
583 
584   ui_controls::SendMouseEvents(type, state);
585 }
586 
SetAccelerator(int command_id,int key_code,bool shift_pressed,bool ctrl_pressed,bool alt_pressed)587 void CefWindowImpl::SetAccelerator(int command_id,
588                                    int key_code,
589                                    bool shift_pressed,
590                                    bool ctrl_pressed,
591                                    bool alt_pressed) {
592   CEF_REQUIRE_VALID_RETURN_VOID();
593   if (!widget_)
594     return;
595 
596   AcceleratorMap::const_iterator it = accelerator_map_.find(command_id);
597   if (it != accelerator_map_.end())
598     RemoveAccelerator(command_id);
599 
600   int modifiers = 0;
601   if (shift_pressed)
602     modifiers |= ui::EF_SHIFT_DOWN;
603   if (ctrl_pressed)
604     modifiers |= ui::EF_CONTROL_DOWN;
605   if (alt_pressed)
606     modifiers |= ui::EF_ALT_DOWN;
607   ui::Accelerator accelerator(static_cast<ui::KeyboardCode>(key_code),
608                               modifiers);
609 
610   accelerator_map_.insert(std::make_pair(command_id, accelerator));
611 
612   views::FocusManager* focus_manager = widget_->GetFocusManager();
613   DCHECK(focus_manager);
614   focus_manager->RegisterAccelerator(
615       accelerator, ui::AcceleratorManager::kNormalPriority, this);
616 }
617 
RemoveAccelerator(int command_id)618 void CefWindowImpl::RemoveAccelerator(int command_id) {
619   CEF_REQUIRE_VALID_RETURN_VOID();
620   if (!widget_)
621     return;
622 
623   AcceleratorMap::iterator it = accelerator_map_.find(command_id);
624   if (it == accelerator_map_.end())
625     return;
626 
627   ui::Accelerator accelerator = it->second;
628 
629   accelerator_map_.erase(it);
630 
631   views::FocusManager* focus_manager = widget_->GetFocusManager();
632   DCHECK(focus_manager);
633   focus_manager->UnregisterAccelerator(accelerator, this);
634 }
635 
RemoveAllAccelerators()636 void CefWindowImpl::RemoveAllAccelerators() {
637   CEF_REQUIRE_VALID_RETURN_VOID();
638   if (!widget_)
639     return;
640 
641   accelerator_map_.clear();
642 
643   views::FocusManager* focus_manager = widget_->GetFocusManager();
644   DCHECK(focus_manager);
645   focus_manager->UnregisterAccelerators(this);
646 }
647 
CefWindowImpl(CefRefPtr<CefWindowDelegate> delegate)648 CefWindowImpl::CefWindowImpl(CefRefPtr<CefWindowDelegate> delegate)
649     : ParentClass(delegate), widget_(nullptr), destroyed_(false) {}
650 
CreateRootView()651 CefWindowView* CefWindowImpl::CreateRootView() {
652   return new CefWindowView(delegate(), this);
653 }
654 
InitializeRootView()655 void CefWindowImpl::InitializeRootView() {
656   static_cast<CefWindowView*>(root_view())->Initialize();
657 }
658 
CreateWidget()659 void CefWindowImpl::CreateWidget() {
660   DCHECK(!widget_);
661 
662   root_view()->CreateWidget();
663   widget_ = root_view()->GetWidget();
664   DCHECK(widget_);
665 
666 #if defined(USE_AURA)
667   unhandled_key_event_handler_ =
668       std::make_unique<CefUnhandledKeyEventHandler>(this, widget_);
669 #endif
670 
671   // The Widget and root View are owned by the native window. Therefore don't
672   // keep an owned reference.
673   std::unique_ptr<views::View> view_ptr = view_util::PassOwnership(this);
674   views::View* view = view_ptr.release();
675   ALLOW_UNUSED_LOCAL(view);
676 }
677