OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/window/window_gtk.h" | 5 #include "views/window/window_gtk.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
9 #include "ui/gfx/gtk_util.h" | 9 #include "ui/gfx/gtk_util.h" |
10 #include "ui/gfx/path.h" | 10 #include "ui/gfx/path.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 break; | 72 break; |
73 } | 73 } |
74 // Default to something defaultish. | 74 // Default to something defaultish. |
75 return GDK_LEFT_PTR; | 75 return GDK_LEFT_PTR; |
76 } | 76 } |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
80 namespace views { | 80 namespace views { |
81 | 81 |
82 WindowGtk::WindowGtk() | 82 WindowGtk::WindowGtk(internal::NativeWindowDelegate* delegate) |
83 : ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), | 83 : WidgetGtk(delegate->AsNativeWidgetDelegate()), |
| 84 delegate_(delegate), |
84 window_state_(GDK_WINDOW_STATE_WITHDRAWN), | 85 window_state_(GDK_WINDOW_STATE_WITHDRAWN), |
85 window_closed_(false) { | 86 window_closed_(false) { |
86 SetNativeWindow(this); | |
87 is_window_ = true; | 87 is_window_ = true; |
88 } | 88 } |
89 | 89 |
90 WindowGtk::~WindowGtk() { | 90 WindowGtk::~WindowGtk() { |
91 } | 91 } |
92 | 92 |
93 // static | |
94 void Window::CloseAllSecondaryWindows() { | |
95 GList* windows = gtk_window_list_toplevels(); | |
96 for (GList* window = windows; window; | |
97 window = g_list_next(window)) { | |
98 Window::CloseSecondaryWidget( | |
99 NativeWidget::GetNativeWidgetForNativeView( | |
100 GTK_WIDGET(window->data))->GetWidget()); | |
101 } | |
102 g_list_free(windows); | |
103 } | |
104 | |
105 Window* WindowGtk::AsWindow() { | |
106 return this; | |
107 } | |
108 | |
109 const Window* WindowGtk::AsWindow() const { | |
110 return this; | |
111 } | |
112 | |
113 //////////////////////////////////////////////////////////////////////////////// | 93 //////////////////////////////////////////////////////////////////////////////// |
114 // WindowGtk, WidgetGtk overrides: | 94 // WindowGtk, WidgetGtk overrides: |
115 | 95 |
116 gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { | 96 gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { |
117 GdkEventButton transformed_event = *event; | 97 GdkEventButton transformed_event = *event; |
118 MouseEvent mouse_event(TransformEvent(&transformed_event)); | 98 MouseEvent mouse_event(TransformEvent(&transformed_event)); |
119 | 99 |
120 int hittest_code = | 100 int hittest_code = |
121 GetWindow()->non_client_view()->NonClientHitTest(mouse_event.location()); | 101 GetWindow()->non_client_view()->NonClientHitTest(mouse_event.location()); |
122 switch (hittest_code) { | 102 switch (hittest_code) { |
123 case HTCAPTION: { | 103 case HTCAPTION: { |
124 // Start dragging if the mouse event is a single click and *not* a right | 104 // Start dragging if the mouse event is a single click and *not* a right |
125 // click. If it is a right click, then pass it through to | 105 // click. If it is a right click, then pass it through to |
126 // WidgetGtk::OnButtonPress so that View class can show ContextMenu upon a | 106 // WidgetGtk::OnButtonPress so that View class can show ContextMenu upon a |
127 // mouse release event. We only start drag on single clicks as we get a | 107 // mouse release event. We only start drag on single clicks as we get a |
128 // crash in Gtk on double/triple clicks. | 108 // crash in Gtk on double/triple clicks. |
129 if (event->type == GDK_BUTTON_PRESS && | 109 if (event->type == GDK_BUTTON_PRESS && |
130 !mouse_event.IsOnlyRightMouseButton()) { | 110 !mouse_event.IsOnlyRightMouseButton()) { |
131 gfx::Point screen_point(event->x, event->y); | 111 gfx::Point screen_point(event->x, event->y); |
132 View::ConvertPointToScreen(GetRootView(), &screen_point); | 112 View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); |
133 gtk_window_begin_move_drag(GetNativeWindow(), event->button, | 113 gtk_window_begin_move_drag(GetNativeWindow(), event->button, |
134 screen_point.x(), screen_point.y(), | 114 screen_point.x(), screen_point.y(), |
135 event->time); | 115 event->time); |
136 return TRUE; | 116 return TRUE; |
137 } | 117 } |
138 break; | 118 break; |
139 } | 119 } |
140 case HTBOTTOM: | 120 case HTBOTTOM: |
141 case HTBOTTOMLEFT: | 121 case HTBOTTOMLEFT: |
142 case HTBOTTOMRIGHT: | 122 case HTBOTTOMRIGHT: |
143 case HTGROWBOX: | 123 case HTGROWBOX: |
144 case HTLEFT: | 124 case HTLEFT: |
145 case HTRIGHT: | 125 case HTRIGHT: |
146 case HTTOP: | 126 case HTTOP: |
147 case HTTOPLEFT: | 127 case HTTOPLEFT: |
148 case HTTOPRIGHT: { | 128 case HTTOPRIGHT: { |
149 gfx::Point screen_point(event->x, event->y); | 129 gfx::Point screen_point(event->x, event->y); |
150 View::ConvertPointToScreen(GetRootView(), &screen_point); | 130 View::ConvertPointToScreen(GetWindow()->GetRootView(), &screen_point); |
151 // TODO(beng): figure out how to get a good minimum size. | 131 // TODO(beng): figure out how to get a good minimum size. |
152 gtk_widget_set_size_request(GetNativeView(), 100, 100); | 132 gtk_widget_set_size_request(GetNativeView(), 100, 100); |
153 gtk_window_begin_resize_drag(GetNativeWindow(), | 133 gtk_window_begin_resize_drag(GetNativeWindow(), |
154 HitTestCodeToGDKWindowEdge(hittest_code), | 134 HitTestCodeToGDKWindowEdge(hittest_code), |
155 event->button, screen_point.x(), | 135 event->button, screen_point.x(), |
156 screen_point.y(), event->time); | 136 screen_point.y(), event->time); |
157 return TRUE; | 137 return TRUE; |
158 } | 138 } |
159 default: | 139 default: |
160 // Everything else falls into standard client event handling... | 140 // Everything else falls into standard client event handling... |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 194 |
215 return WidgetGtk::OnLeaveNotify(widget, event); | 195 return WidgetGtk::OnLeaveNotify(widget, event); |
216 } | 196 } |
217 | 197 |
218 void WindowGtk::IsActiveChanged() { | 198 void WindowGtk::IsActiveChanged() { |
219 WidgetGtk::IsActiveChanged(); | 199 WidgetGtk::IsActiveChanged(); |
220 delegate_->OnNativeWindowActivationChanged(IsActive()); | 200 delegate_->OnNativeWindowActivationChanged(IsActive()); |
221 } | 201 } |
222 | 202 |
223 void WindowGtk::InitNativeWidget(const Widget::InitParams& params) { | 203 void WindowGtk::InitNativeWidget(const Widget::InitParams& params) { |
224 if (params.parent) | |
225 make_transient_to_parent(); | |
226 | |
227 WidgetGtk::InitNativeWidget(params); | 204 WidgetGtk::InitNativeWidget(params); |
228 | 205 |
229 g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event", | 206 g_signal_connect(G_OBJECT(GetNativeWindow()), "configure-event", |
230 G_CALLBACK(CallConfigureEvent), this); | 207 G_CALLBACK(CallConfigureEvent), this); |
231 g_signal_connect(G_OBJECT(GetNativeWindow()), "window-state-event", | 208 g_signal_connect(G_OBJECT(GetNativeWindow()), "window-state-event", |
232 G_CALLBACK(CallWindowStateEvent), this); | 209 G_CALLBACK(CallWindowStateEvent), this); |
233 } | 210 } |
234 | 211 |
235 //////////////////////////////////////////////////////////////////////////////// | 212 //////////////////////////////////////////////////////////////////////////////// |
236 // WindowGtk, NativeWindow implementation: | 213 // WindowGtk, NativeWindow implementation: |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 void WindowGtk::SetAccessibleName(const std::wstring& name) { | 280 void WindowGtk::SetAccessibleName(const std::wstring& name) { |
304 } | 281 } |
305 | 282 |
306 void WindowGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { | 283 void WindowGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { |
307 } | 284 } |
308 | 285 |
309 void WindowGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { | 286 void WindowGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { |
310 } | 287 } |
311 | 288 |
312 Window* WindowGtk::GetWindow() { | 289 Window* WindowGtk::GetWindow() { |
313 return this; | 290 return delegate_->AsWindow(); |
| 291 } |
| 292 |
| 293 const Window* WindowGtk::GetWindow() const { |
| 294 return delegate_->AsWindow(); |
314 } | 295 } |
315 | 296 |
316 void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, | 297 void WindowGtk::SetWindowBounds(const gfx::Rect& bounds, |
317 gfx::NativeWindow other_window) { | 298 gfx::NativeWindow other_window) { |
318 // TODO: need to deal with other_window. | 299 // TODO: need to deal with other_window. |
319 WidgetGtk::SetBounds(bounds); | 300 WidgetGtk::SetBounds(bounds); |
320 } | 301 } |
321 | 302 |
322 void WindowGtk::HideWindow() { | 303 void WindowGtk::HideWindow() { |
323 Hide(); | 304 GetWindow()->Hide(); |
324 } | 305 } |
325 | 306 |
326 void WindowGtk::Activate() { | 307 void WindowGtk::Activate() { |
327 gtk_window_present(GTK_WINDOW(GetNativeView())); | 308 gtk_window_present(GTK_WINDOW(GetNativeView())); |
328 } | 309 } |
329 | 310 |
330 void WindowGtk::Deactivate() { | 311 void WindowGtk::Deactivate() { |
331 gdk_window_lower(GTK_WIDGET(GetNativeView())->window); | 312 gdk_window_lower(GTK_WIDGET(GetNativeView())->window); |
332 } | 313 } |
333 | 314 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 353 } |
373 | 354 |
374 bool WindowGtk::IsFullscreen() const { | 355 bool WindowGtk::IsFullscreen() const { |
375 return window_state_ & GDK_WINDOW_STATE_FULLSCREEN; | 356 return window_state_ & GDK_WINDOW_STATE_FULLSCREEN; |
376 } | 357 } |
377 | 358 |
378 void WindowGtk::SetUseDragFrame(bool use_drag_frame) { | 359 void WindowGtk::SetUseDragFrame(bool use_drag_frame) { |
379 NOTIMPLEMENTED(); | 360 NOTIMPLEMENTED(); |
380 } | 361 } |
381 | 362 |
| 363 NonClientFrameView* WindowGtk::CreateFrameViewForWindow() { |
| 364 return new CustomFrameView(delegate_->AsWindow()); |
| 365 } |
| 366 |
382 void WindowGtk::SetAlwaysOnTop(bool always_on_top) { | 367 void WindowGtk::SetAlwaysOnTop(bool always_on_top) { |
383 gtk_window_set_keep_above(GetNativeWindow(), always_on_top); | 368 gtk_window_set_keep_above(GetNativeWindow(), always_on_top); |
384 } | 369 } |
385 | 370 |
386 bool WindowGtk::IsAppWindow() const { | |
387 return false; | |
388 } | |
389 | |
390 NonClientFrameView* WindowGtk::CreateFrameViewForWindow() { | |
391 // TODO(erg): Always use a custom frame view? Are there cases where we let | |
392 // the window manager deal with the X11 equivalent of the "non-client" area? | |
393 return new CustomFrameView(this); | |
394 } | |
395 | |
396 void WindowGtk::UpdateFrameAfterFrameChange() { | 371 void WindowGtk::UpdateFrameAfterFrameChange() { |
397 // We currently don't support different frame types on Gtk, so we don't | 372 // We currently don't support different frame types on Gtk, so we don't |
398 // need to implement this. | 373 // need to implement this. |
399 NOTIMPLEMENTED(); | 374 NOTIMPLEMENTED(); |
400 } | 375 } |
401 | 376 |
402 gfx::NativeWindow WindowGtk::GetNativeWindow() const { | 377 gfx::NativeWindow WindowGtk::GetNativeWindow() const { |
403 return GTK_WINDOW(GetNativeView()); | 378 return GTK_WINDOW(GetNativeView()); |
404 } | 379 } |
405 | 380 |
406 bool WindowGtk::ShouldUseNativeFrame() const { | 381 bool WindowGtk::ShouldUseNativeFrame() const { |
407 return false; | 382 return false; |
408 } | 383 } |
409 | 384 |
410 void WindowGtk::FrameTypeChanged() { | 385 void WindowGtk::FrameTypeChanged() { |
411 // This is called when the Theme has changed, so forward the event to the root | 386 // This is called when the Theme has changed, so forward the event to the root |
412 // widget. | 387 // widget. |
413 ThemeChanged(); | 388 GetWidget()->ThemeChanged(); |
414 GetRootView()->SchedulePaint(); | 389 GetWidget()->GetRootView()->SchedulePaint(); |
415 } | 390 } |
416 | 391 |
417 //////////////////////////////////////////////////////////////////////////////// | 392 //////////////////////////////////////////////////////////////////////////////// |
418 // WindowGtk, private: | 393 // WindowGtk, private: |
419 | 394 |
420 // static | 395 // static |
421 gboolean WindowGtk::CallConfigureEvent(GtkWidget* widget, | 396 gboolean WindowGtk::CallConfigureEvent(GtkWidget* widget, |
422 GdkEventConfigure* event, | 397 GdkEventConfigure* event, |
423 WindowGtk* window_gtk) { | 398 WindowGtk* window_gtk) { |
424 return window_gtk->OnConfigureEvent(widget, event); | 399 return window_gtk->OnConfigureEvent(widget, event); |
425 } | 400 } |
426 | 401 |
427 // static | 402 // static |
428 gboolean WindowGtk::CallWindowStateEvent(GtkWidget* widget, | 403 gboolean WindowGtk::CallWindowStateEvent(GtkWidget* widget, |
429 GdkEventWindowState* event, | 404 GdkEventWindowState* event, |
430 WindowGtk* window_gtk) { | 405 WindowGtk* window_gtk) { |
431 return window_gtk->OnWindowStateEvent(widget, event); | 406 return window_gtk->OnWindowStateEvent(widget, event); |
432 } | 407 } |
433 | 408 |
434 void WindowGtk::SaveWindowPosition() { | 409 void WindowGtk::SaveWindowPosition() { |
435 // The delegate may have gone away on us. | 410 // The delegate may have gone away on us. |
436 if (!GetWindow()->window_delegate()) | 411 if (!GetWindow()->window_delegate()) |
437 return; | 412 return; |
438 | 413 |
439 bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; | 414 bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; |
440 GetWindow()->window_delegate()->SaveWindowPlacement(GetBounds(), maximized); | 415 GetWindow()->window_delegate()->SaveWindowPlacement( |
| 416 GetWidget()->GetWindowScreenBounds(), |
| 417 maximized); |
441 } | 418 } |
442 | 419 |
443 void WindowGtk::OnDestroy(GtkWidget* widget) { | 420 void WindowGtk::OnDestroy(GtkWidget* widget) { |
444 delegate_->OnNativeWindowDestroying(); | 421 delegate_->OnNativeWindowDestroying(); |
445 WidgetGtk::OnDestroy(widget); | 422 WidgetGtk::OnDestroy(widget); |
446 delegate_->OnNativeWindowDestroyed(); | 423 delegate_->OnNativeWindowDestroyed(); |
447 } | 424 } |
448 | 425 |
449 //////////////////////////////////////////////////////////////////////////////// | 426 //////////////////////////////////////////////////////////////////////////////// |
450 // NativeWindow, public: | 427 // NativeWindow, public: |
451 | 428 |
452 // static | 429 // static |
453 Window* NativeWindow::CreateNativeWindow() { | 430 NativeWindow* NativeWindow::CreateNativeWindow( |
454 return new WindowGtk; | 431 internal::NativeWindowDelegate* delegate) { |
| 432 return new WindowGtk(delegate); |
455 } | 433 } |
456 | 434 |
457 } // namespace views | 435 } // namespace views |
| 436 |
OLD | NEW |