• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/browser_bubble.h"
6 
7 #include "chrome/browser/ui/views/bubble/border_contents.h"
8 #include "chrome/browser/ui/views/bubble/border_widget_win.h"
9 #include "chrome/browser/ui/views/frame/browser_view.h"
10 #include "views/widget/root_view.h"
11 #include "views/widget/widget_win.h"
12 #include "views/window/window.h"
13 
14 class BubbleWidget : public views::WidgetWin {
15  public:
BubbleWidget(BrowserBubble * bubble)16   explicit BubbleWidget(BrowserBubble* bubble)
17       : bubble_(bubble),
18         border_widget_(new BorderWidgetWin) {
19     set_window_style(WS_POPUP | WS_CLIPCHILDREN);
20     set_window_ex_style(WS_EX_TOOLWINDOW);
21   }
22 
ShowAndActivate(bool activate)23   void ShowAndActivate(bool activate) {
24     // Show the border first, then the popup overlaid on top.
25     border_widget_->Show();
26     if (activate)
27       ShowWindow(SW_SHOW);
28     else
29       views::WidgetWin::Show();
30   }
31 
Close()32   void Close() {
33     if (!bubble_)
34       return;  // We have already been closed.
35     if (IsActive()) {
36       BrowserBubble::Delegate* delegate = bubble_->delegate();
37       if (delegate)
38         delegate->BubbleLostFocus(bubble_, NULL);
39     }
40     border_widget_->Close();
41     views::WidgetWin::Close();
42     bubble_ = NULL;
43   }
44 
Hide()45   void Hide() {
46     if (IsActive() && bubble_) {
47       BrowserBubble::Delegate* delegate = bubble_->delegate();
48       if (delegate)
49         delegate->BubbleLostFocus(bubble_, NULL);
50     }
51     views::WidgetWin::Hide();
52     border_widget_->Hide();
53   }
54 
OnActivate(UINT action,BOOL minimized,HWND window)55   void OnActivate(UINT action, BOOL minimized, HWND window) {
56     WidgetWin::OnActivate(action, minimized, window);
57     if (!bubble_)
58       return;
59 
60     BrowserBubble::Delegate* delegate = bubble_->delegate();
61     if (!delegate) {
62       if (action == WA_INACTIVE) {
63         bubble_->DetachFromBrowser();
64         delete bubble_;
65       }
66       return;
67     }
68 
69     if (action == WA_INACTIVE) {
70       bool lost_focus_to_child = false;
71 
72       // Are we a parent of this window?
73       gfx::NativeView parent = window;
74       while (parent = ::GetParent(parent)) {
75         if (window == GetNativeView()) {
76           lost_focus_to_child = true;
77           break;
78         }
79       }
80 
81       // Do we own this window?
82       if (!lost_focus_to_child &&
83           ::GetWindow(window, GW_OWNER) == GetNativeView()) {
84         lost_focus_to_child = true;
85       }
86 
87       delegate->BubbleLostFocus(bubble_, lost_focus_to_child);
88     }
89   }
90 
OnSetFocus(HWND focused_window)91   virtual void OnSetFocus(HWND focused_window) {
92     WidgetWin::OnSetFocus(focused_window);
93     if (bubble_ && bubble_->delegate())
94       bubble_->delegate()->BubbleGotFocus(bubble_);
95   }
96 
border_widget()97   BorderWidgetWin* border_widget() {
98     return border_widget_;
99   }
100 
101  private:
102   BrowserBubble* bubble_;
103   BorderWidgetWin* border_widget_;
104 
105   DISALLOW_COPY_AND_ASSIGN(BubbleWidget);
106 };
107 
InitPopup()108 void BrowserBubble::InitPopup() {
109   // popup_ is a Widget, but we need to do some WidgetWin stuff first, then
110   // we'll assign it into popup_.
111   BubbleWidget* pop = new BubbleWidget(this);
112 
113   BorderWidgetWin* border_widget = pop->border_widget();
114   border_widget->Init(new BorderContents, frame_->GetNativeView());
115 
116   // We make the BorderWidgetWin the owner of the Bubble HWND, so that the
117   // latter is displayed on top of the former.
118   pop->Init(border_widget->GetNativeView(), gfx::Rect());
119   pop->SetContentsView(view_);
120 
121   popup_ = pop;
122 
123   ResizeToView();
124   Reposition();
125   AttachToBrowser();
126 }
127 
MovePopup(int x,int y,int w,int h)128 void BrowserBubble::MovePopup(int x, int y, int w, int h) {
129   views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_);
130   pop->SetBounds(gfx::Rect(x, y, w, h));
131 }
132 
Show(bool activate)133 void BrowserBubble::Show(bool activate) {
134   if (visible_)
135     return;
136   BubbleWidget* pop = static_cast<BubbleWidget*>(popup_);
137   pop->ShowAndActivate(activate);
138   visible_ = true;
139 }
140 
Hide()141 void BrowserBubble::Hide() {
142   if (!visible_)
143     return;
144   views::WidgetWin* pop = static_cast<views::WidgetWin*>(popup_);
145   pop->Hide();
146   visible_ = false;
147 }
148 
ResizeToView()149 void BrowserBubble::ResizeToView() {
150   BorderWidgetWin* border_widget =
151       static_cast<BubbleWidget*>(popup_)->border_widget();
152 
153   gfx::Rect window_bounds;
154   window_bounds = border_widget->SizeAndGetBounds(GetAbsoluteRelativeTo(),
155       arrow_location_, view_->size());
156 
157   SetAbsoluteBounds(window_bounds);
158 }
159