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