• 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 <vector>
8 
9 #include "chrome/browser/ui/views/bubble/border_contents.h"
10 #include "chrome/browser/ui/views/frame/browser_view.h"
11 #include "views/widget/root_view.h"
12 #include "views/widget/widget_gtk.h"
13 
14 #if defined(OS_CHROMEOS)
15 #include "chrome/browser/chromeos/wm_ipc.h"
16 #include "third_party/cros/chromeos_wm_ipc_enums.h"
17 #endif
18 
19 using std::vector;
20 
21 namespace {
22 
23 class BubbleWidget : public views::WidgetGtk {
24  public:
BubbleWidget(BrowserBubble * bubble)25   explicit BubbleWidget(BrowserBubble* bubble)
26       : views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW),
27         bubble_(bubble),
28         border_contents_(new BorderContents) {
29     border_contents_->Init();
30   }
31 
ShowAndActivate(bool activate)32   void ShowAndActivate(bool activate) {
33     // TODO: honor activate.
34     views::WidgetGtk::Show();
35   }
36 
Close()37   virtual void Close() {
38     if (!bubble_)
39       return;  // We have already been closed.
40     if (IsActive()) {
41       BrowserBubble::Delegate* delegate = bubble_->delegate();
42       if (delegate)
43         delegate->BubbleLostFocus(bubble_, false);
44     }
45     views::WidgetGtk::Close();
46     bubble_ = NULL;
47   }
48 
Hide()49   virtual void Hide() {
50     if (IsActive()&& bubble_) {
51       BrowserBubble::Delegate* delegate = bubble_->delegate();
52       if (delegate)
53         delegate->BubbleLostFocus(bubble_, false);
54     }
55     views::WidgetGtk::Hide();
56   }
57 
IsActiveChanged()58   virtual void IsActiveChanged() {
59     if (IsActive() || !bubble_)
60       return;
61     BrowserBubble::Delegate* delegate = bubble_->delegate();
62     if (!delegate) {
63       bubble_->DetachFromBrowser();
64       delete bubble_;
65       return;
66     }
67 
68     // TODO(jcampan): http://crbugs.com/29131 Check if the window we are losing
69     //                focus to is a child window and pass that to the call
70     //                below.
71     delegate->BubbleLostFocus(bubble_, false);
72   }
73 
OnFocusIn(GtkWidget * widget,GdkEventFocus * event)74   virtual gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event) {
75     if (bubble_ && bubble_->delegate())
76       bubble_->delegate()->BubbleGotFocus(bubble_);
77     return views::WidgetGtk::OnFocusIn(widget, event);
78   }
79 
border_contents()80   BorderContents* border_contents() {
81     return border_contents_;
82   }
83 
84  private:
85   BrowserBubble* bubble_;
86   BorderContents* border_contents_;  // Owned by root view of this widget.
87 
88   DISALLOW_COPY_AND_ASSIGN(BubbleWidget);
89 };
90 
91 }  // namespace
92 
InitPopup()93 void BrowserBubble::InitPopup() {
94   // TODO(port)
95   BubbleWidget* pop = new BubbleWidget(this);
96   pop->MakeTransparent();
97   pop->make_transient_to_parent();
98   pop->Init(frame_->GetNativeView(), gfx::Rect());
99 #if defined(OS_CHROMEOS)
100   {
101     vector<int> params;
102     params.push_back(0);  // don't show while screen is locked
103     chromeos::WmIpc::instance()->SetWindowType(
104         pop->GetNativeView(),
105         chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE,
106         &params);
107   }
108 #endif
109 
110   views::View* contents_view = new views::View;
111 
112   // We add |contents_view| to ourselves before the AddChildView() call below so
113   // that when |contents| gets added, it will already have a widget, and thus
114   // any NativeButtons it creates in ViewHierarchyChanged() will be functional
115   // (e.g. calling SetChecked() on checkboxes is safe).
116   pop->SetContentsView(contents_view);
117 
118   // Added border_contents before |view_| so it will paint under it.
119   contents_view->AddChildView(pop->border_contents());
120   contents_view->AddChildView(view_);
121 
122   popup_ = pop;
123 
124   ResizeToView();
125   Reposition();
126   AttachToBrowser();
127 }
128 
MovePopup(int x,int y,int w,int h)129 void BrowserBubble::MovePopup(int x, int y, int w, int h) {
130   views::WidgetGtk* pop = static_cast<views::WidgetGtk*>(popup_);
131   pop->SetBounds(gfx::Rect(x, y, w, h));
132 }
133 
Show(bool activate)134 void BrowserBubble::Show(bool activate) {
135   if (visible_)
136     return;
137   static_cast<BubbleWidget*>(popup_)->ShowAndActivate(activate);
138   visible_ = true;
139 }
140 
Hide()141 void BrowserBubble::Hide() {
142   if (!visible_)
143     return;
144   views::WidgetGtk* pop = static_cast<views::WidgetGtk*>(popup_);
145   pop->Hide();
146   visible_ = false;
147 }
148 
ResizeToView()149 void BrowserBubble::ResizeToView() {
150   BorderContents* border_contents =
151       static_cast<BubbleWidget*>(popup_)->border_contents();
152 
153   // Calculate and set the bounds for all windows and views.
154   gfx::Rect window_bounds;
155   gfx::Rect contents_bounds;
156   border_contents->SizeAndGetBounds(GetAbsoluteRelativeTo(),
157       arrow_location_, false, view_->size(),
158       &contents_bounds, &window_bounds);
159 
160   border_contents->SetBoundsRect(gfx::Rect(gfx::Point(), window_bounds.size()));
161   view_->SetBoundsRect(contents_bounds);
162 
163   SetAbsoluteBounds(window_bounds);
164 }
165