OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/widget/widget_gtk.h" | 5 #include "views/widget/widget_gtk.h" |
6 | 6 |
7 #include "app/gfx/path.h" | 7 #include "app/gfx/path.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "views/fill_layout.h" | |
10 #include "views/widget/default_theme_provider.h" | 9 #include "views/widget/default_theme_provider.h" |
11 #include "views/widget/root_view.h" | 10 #include "views/widget/root_view.h" |
12 #include "views/widget/tooltip_manager_gtk.h" | 11 #include "views/widget/tooltip_manager_gtk.h" |
13 #include "views/window/window_gtk.h" | 12 #include "views/window/window_gtk.h" |
14 | 13 |
15 namespace views { | 14 namespace views { |
16 | 15 |
17 // Returns the position of a widget on screen. | 16 // Returns the position of a widget on screen. |
18 static void GetWidgetPositionOnScreen(GtkWidget* widget, int* x, int *y) { | 17 static void GetWidgetPositionOnScreen(GtkWidget* widget, int* x, int *y) { |
19 while (widget) { | 18 while (widget) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 last_mouse_event_was_move_(false), | 68 last_mouse_event_was_move_(false), |
70 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 69 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
71 delete_on_destroy_(true), | 70 delete_on_destroy_(true), |
72 transparent_(false) { | 71 transparent_(false) { |
73 } | 72 } |
74 | 73 |
75 WidgetGtk::~WidgetGtk() { | 74 WidgetGtk::~WidgetGtk() { |
76 MessageLoopForUI::current()->RemoveObserver(this); | 75 MessageLoopForUI::current()->RemoveObserver(this); |
77 } | 76 } |
78 | 77 |
| 78 bool WidgetGtk::MakeTransparent() { |
| 79 // Transparency can only be enabled for windows/popups and only if we haven't |
| 80 // realized the widget. |
| 81 DCHECK(!widget_ && type_ != TYPE_CHILD); |
| 82 |
| 83 if (!gdk_screen_is_composited(gdk_screen_get_default())) { |
| 84 // Transparency is only supported for compositing window managers. |
| 85 DLOG(WARNING) << "compsiting not supported"; |
| 86 return false; |
| 87 } |
| 88 |
| 89 if (!gdk_screen_get_rgba_colormap(gdk_screen_get_default())) { |
| 90 // We need rgba to make the window transparent. |
| 91 return false; |
| 92 } |
| 93 |
| 94 transparent_ = true; |
| 95 return true; |
| 96 } |
| 97 |
| 98 void WidgetGtk::AddChild(GtkWidget* child) { |
| 99 gtk_container_add(GTK_CONTAINER(window_contents_), child); |
| 100 } |
| 101 |
| 102 void WidgetGtk::RemoveChild(GtkWidget* child) { |
| 103 // We can be called after the contents widget has been destroyed, e.g. any |
| 104 // NativeViewHost not removed from the view hierarchy before the window is |
| 105 // closed. |
| 106 if (GTK_IS_CONTAINER(window_contents_)) |
| 107 gtk_container_remove(GTK_CONTAINER(window_contents_), child); |
| 108 } |
| 109 |
| 110 void WidgetGtk::ReparentChild(GtkWidget* child) { |
| 111 gtk_widget_reparent(child, window_contents_); |
| 112 } |
| 113 |
| 114 void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) { |
| 115 GtkAllocation alloc = { x, y, w, h }; |
| 116 // For some reason we need to do both of these to size a widget. |
| 117 gtk_widget_size_allocate(child, &alloc); |
| 118 gtk_widget_set_size_request(child, w, h); |
| 119 gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y); |
| 120 } |
| 121 |
| 122 //////////////////////////////////////////////////////////////////////////////// |
| 123 // WidgetGtk, Widget implementation: |
| 124 |
79 void WidgetGtk::Init(GtkWidget* parent, | 125 void WidgetGtk::Init(GtkWidget* parent, |
80 const gfx::Rect& bounds) { | 126 const gfx::Rect& bounds) { |
81 // Force creation of the RootView if it hasn't been created yet. | 127 // Force creation of the RootView if it hasn't been created yet. |
82 GetRootView(); | 128 GetRootView(); |
83 | 129 |
84 #if !defined(OS_CHROMEOS) | 130 #if !defined(OS_CHROMEOS) |
85 default_theme_provider_.reset(new DefaultThemeProvider()); | 131 default_theme_provider_.reset(new DefaultThemeProvider()); |
86 #endif | 132 #endif |
87 | 133 |
88 // Make container here. | 134 // Make container here. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), | 220 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), |
175 bounds.width(), bounds.height()); | 221 bounds.width(), bounds.height()); |
176 } | 222 } |
177 } else { | 223 } else { |
178 if (bounds.width() > 0 && bounds.height() > 0) | 224 if (bounds.width() > 0 && bounds.height() > 0) |
179 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); | 225 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); |
180 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); | 226 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); |
181 } | 227 } |
182 } | 228 } |
183 | 229 |
184 bool WidgetGtk::MakeTransparent() { | 230 void WidgetGtk::SetContentsView(View* view) { |
185 // Transparency can only be enabled for windows/popups and only if we haven't | 231 root_view_->SetContentsView(view); |
186 // realized the widget. | |
187 DCHECK(!widget_ && type_ != TYPE_CHILD); | |
188 | |
189 if (!gdk_screen_is_composited(gdk_screen_get_default())) { | |
190 // Transparency is only supported for compositing window managers. | |
191 DLOG(WARNING) << "compsiting not supported"; | |
192 return false; | |
193 } | |
194 | |
195 if (!gdk_screen_get_rgba_colormap(gdk_screen_get_default())) { | |
196 // We need rgba to make the window transparent. | |
197 return false; | |
198 } | |
199 | |
200 transparent_ = true; | |
201 return true; | |
202 } | 232 } |
203 | 233 |
204 void WidgetGtk::AddChild(GtkWidget* child) { | |
205 gtk_container_add(GTK_CONTAINER(window_contents_), child); | |
206 } | |
207 | |
208 void WidgetGtk::RemoveChild(GtkWidget* child) { | |
209 // We can be called after the contents widget has been destroyed, e.g. any | |
210 // NativeViewHost not removed from the view hierarchy before the window is | |
211 // closed. | |
212 if (GTK_IS_CONTAINER(window_contents_)) | |
213 gtk_container_remove(GTK_CONTAINER(window_contents_), child); | |
214 } | |
215 | |
216 void WidgetGtk::ReparentChild(GtkWidget* child) { | |
217 gtk_widget_reparent(child, window_contents_); | |
218 } | |
219 | |
220 void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) { | |
221 GtkAllocation alloc = { x, y, w, h }; | |
222 // For some reason we need to do both of these to size a widget. | |
223 gtk_widget_size_allocate(child, &alloc); | |
224 gtk_widget_set_size_request(child, w, h); | |
225 gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y); | |
226 } | |
227 | |
228 void WidgetGtk::SetContentsView(View* view) { | |
229 DCHECK(view && widget_) | |
230 << "Can't be called until after the HWND is created!"; | |
231 // The ContentsView must be set up _after_ the window is created so that its | |
232 // Widget pointer is valid. | |
233 root_view_->SetLayoutManager(new FillLayout); | |
234 if (root_view_->GetChildViewCount() != 0) | |
235 root_view_->RemoveAllChildViews(true); | |
236 root_view_->AddChildView(view); | |
237 | |
238 DCHECK(widget_); // Widget must have been created by now. | |
239 | |
240 // Force a layout now, since the attached hierarchy won't be ready for the | |
241 // containing window's bounds. Note that we call Layout directly rather than | |
242 // calling OnSizeAllocate, since the RootView's bounds may not have changed, | |
243 // which will cause the Layout not to be done otherwise. | |
244 root_view_->Layout(); | |
245 } | |
246 | |
247 //////////////////////////////////////////////////////////////////////////////// | |
248 // WidgetGtk, Widget implementation: | |
249 | |
250 void WidgetGtk::GetBounds(gfx::Rect* out, bool including_frame) const { | 234 void WidgetGtk::GetBounds(gfx::Rect* out, bool including_frame) const { |
251 DCHECK(widget_); | 235 DCHECK(widget_); |
252 | 236 |
253 int x = 0, y = 0, w, h; | 237 int x = 0, y = 0, w, h; |
254 if (GTK_IS_WINDOW(widget_)) { | 238 if (GTK_IS_WINDOW(widget_)) { |
255 gtk_window_get_position(GTK_WINDOW(widget_), &x, &y); | 239 gtk_window_get_position(GTK_WINDOW(widget_), &x, &y); |
256 gtk_window_get_size(GTK_WINDOW(widget_), &w, &h); | 240 gtk_window_get_size(GTK_WINDOW(widget_), &w, &h); |
257 } else { | 241 } else { |
258 // TODO: make sure this is right. Docs indicate gtk_window_get_position | 242 // TODO: make sure this is right. Docs indicate gtk_window_get_position |
259 // returns a value useful to the window manager, which may not be the same | 243 // returns a value useful to the window manager, which may not be the same |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 | 809 |
826 void WidgetGtk::HandleGrabBroke() { | 810 void WidgetGtk::HandleGrabBroke() { |
827 if (has_capture_) { | 811 if (has_capture_) { |
828 if (is_mouse_down_) | 812 if (is_mouse_down_) |
829 root_view_->ProcessMouseDragCanceled(); | 813 root_view_->ProcessMouseDragCanceled(); |
830 is_mouse_down_ = false; | 814 is_mouse_down_ = false; |
831 has_capture_ = false; | 815 has_capture_ = false; |
832 } | 816 } |
833 } | 817 } |
834 | 818 |
| 819 |
| 820 //////////////////////////////////////////////////////////////////////////////// |
| 821 // Widget, public: |
| 822 |
| 823 // static |
| 824 Widget* Widget::CreateTransparentPopupWidget(bool delete_on_destroy) { |
| 825 WidgetGtk* popup = new WidgetGtk(WidgetGtk::TYPE_POPUP); |
| 826 popup->set_delete_on_destroy(delete_on_destroy); |
| 827 popup->MakeTransparent(); |
| 828 return popup; |
| 829 } |
| 830 |
835 } // namespace views | 831 } // namespace views |
OLD | NEW |