1// Copyright (c) 2012 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 "ui/aura/window.h"
6#include "ui/aura/window_observer.h"
7#include "ui/views/controls/menu/menu_runner.h"
8#include "ui/views/widget/widget.h"
9
10namespace views {
11namespace internal {
12
13// DisplayChangeListener implementation for aura. Cancels the menu any time the
14// root window bounds change.
15class AuraDisplayChangeListener
16    : public DisplayChangeListener,
17      public aura::WindowObserver {
18 public:
19  AuraDisplayChangeListener(Widget* widget, MenuRunner* menu_runner);
20  virtual ~AuraDisplayChangeListener();
21
22  // aura::WindowObserver overrides:
23  virtual void OnWindowBoundsChanged(aura::Window* window,
24                                     const gfx::Rect& old_bounds,
25                                     const gfx::Rect& new_bounds) OVERRIDE;
26  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
27
28 private:
29  MenuRunner* menu_runner_;
30  aura::Window* root_window_;
31
32  DISALLOW_COPY_AND_ASSIGN(AuraDisplayChangeListener);
33};
34
35AuraDisplayChangeListener::AuraDisplayChangeListener(Widget* widget,
36                                                     MenuRunner* menu_runner)
37    : menu_runner_(menu_runner),
38      root_window_(widget->GetNativeView()->GetRootWindow()) {
39  if (root_window_)
40    root_window_->AddObserver(this);
41}
42
43AuraDisplayChangeListener::~AuraDisplayChangeListener() {
44  if (root_window_)
45    root_window_->RemoveObserver(this);
46}
47
48void AuraDisplayChangeListener::OnWindowBoundsChanged(
49    aura::Window* window,
50    const gfx::Rect& old_bounds,
51    const gfx::Rect& new_bounds) {
52  menu_runner_->Cancel();
53}
54
55void AuraDisplayChangeListener::OnWindowDestroying(aura::Window* window) {
56  DCHECK_EQ(window, root_window_);
57  root_window_->RemoveObserver(this);
58  root_window_ = NULL;
59}
60
61// static
62DisplayChangeListener* DisplayChangeListener::Create(Widget* widget,
63                                                     MenuRunner* runner) {
64  return new AuraDisplayChangeListener(widget, runner);
65}
66
67}  // namespace internal
68}  // namespace views
69