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/drag_drop_types.h" | 7 #include "app/drag_drop_types.h" |
8 #include "app/gfx/path.h" | 8 #include "app/gfx/path.h" |
9 #include "app/os_exchange_data.h" | 9 #include "app/os_exchange_data.h" |
10 #include "app/os_exchange_data_provider_gtk.h" | 10 #include "app/os_exchange_data_provider_gtk.h" |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 | 471 |
472 void WidgetGtk::DidProcessEvent(GdkEvent* event) { | 472 void WidgetGtk::DidProcessEvent(GdkEvent* event) { |
473 if (root_view_->NeedsPainting(true)) | 473 if (root_view_->NeedsPainting(true)) |
474 PaintNow(root_view_->GetScheduledPaintRect()); | 474 PaintNow(root_view_->GetScheduledPaintRect()); |
475 } | 475 } |
476 | 476 |
477 //////////////////////////////////////////////////////////////////////////////// | 477 //////////////////////////////////////////////////////////////////////////////// |
478 // TODO(beng): organize into sections: | 478 // TODO(beng): organize into sections: |
479 | 479 |
480 void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { | 480 void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) { |
| 481 // We turn off double buffering for two reasons: |
| 482 // 1. We draw to a canvas then composite to the screen, which means we're |
| 483 // doing our own double buffering already. |
| 484 // 2. GTKs double buffering clips to the dirty region. RootView occasionally |
| 485 // needs to expand the paint region (see RootView::OnPaint). This means |
| 486 // that if we use GTK's double buffering and we tried to expand the dirty |
| 487 // region, it wouldn't get painted. |
481 if (type_ == TYPE_CHILD) { | 488 if (type_ == TYPE_CHILD) { |
482 window_contents_ = widget_ = gtk_fixed_new(); | 489 window_contents_ = widget_ = gtk_fixed_new(); |
| 490 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); |
483 gtk_fixed_set_has_window(GTK_FIXED(widget_), true); | 491 gtk_fixed_set_has_window(GTK_FIXED(widget_), true); |
484 if (!parent && !null_parent_) { | 492 if (!parent && !null_parent_) { |
485 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); | 493 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); |
486 null_parent_ = gtk_fixed_new(); | 494 null_parent_ = gtk_fixed_new(); |
487 gtk_container_add(GTK_CONTAINER(popup), null_parent_); | 495 gtk_container_add(GTK_CONTAINER(popup), null_parent_); |
488 gtk_widget_realize(null_parent_); | 496 gtk_widget_realize(null_parent_); |
489 } | 497 } |
490 gtk_container_add(GTK_CONTAINER(parent ? parent : null_parent_), widget_); | 498 gtk_container_add(GTK_CONTAINER(parent ? parent : null_parent_), widget_); |
491 SetViewForNative(widget_, this); | 499 SetViewForNative(widget_, this); |
492 } else { | 500 } else { |
493 widget_ = gtk_window_new( | 501 widget_ = gtk_window_new( |
494 type_ == TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP); | 502 type_ == TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP); |
| 503 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); |
495 | 504 |
496 if (!bounds.size().IsEmpty()) { | 505 if (!bounds.size().IsEmpty()) { |
497 // When we realize the window, the window manager is given a size. If we | 506 // When we realize the window, the window manager is given a size. If we |
498 // don't specify a size before then GTK defaults to 200x200. Specify | 507 // don't specify a size before then GTK defaults to 200x200. Specify |
499 // a size now so that the window manager sees the requested size. | 508 // a size now so that the window manager sees the requested size. |
500 GtkAllocation alloc = { 0, 0, bounds.width(), bounds.height() }; | 509 GtkAllocation alloc = { 0, 0, bounds.width(), bounds.height() }; |
501 gtk_widget_size_allocate(widget_, &alloc); | 510 gtk_widget_size_allocate(widget_, &alloc); |
502 } | 511 } |
503 gtk_window_set_decorated(GTK_WINDOW(widget_), false); | 512 gtk_window_set_decorated(GTK_WINDOW(widget_), false); |
504 // We'll take care of positioning our window. | 513 // We'll take care of positioning our window. |
505 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); | 514 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); |
506 SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); | 515 SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); |
507 SetViewForNative(widget_, this); | 516 SetViewForNative(widget_, this); |
508 | 517 |
509 window_contents_ = gtk_fixed_new(); | 518 window_contents_ = gtk_fixed_new(); |
| 519 GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); |
510 gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); | 520 gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); |
511 gtk_container_add(GTK_CONTAINER(widget_), window_contents_); | 521 gtk_container_add(GTK_CONTAINER(widget_), window_contents_); |
512 gtk_widget_show(window_contents_); | 522 gtk_widget_show(window_contents_); |
513 SetViewForNative(window_contents_, this); | 523 SetViewForNative(window_contents_, this); |
514 | 524 |
515 if (transparent_) | 525 if (transparent_) |
516 ConfigureWidgetForTransparentBackground(); | 526 ConfigureWidgetForTransparentBackground(); |
517 } | 527 } |
518 // The widget needs to be realized before handlers like size-allocate can | 528 // The widget needs to be realized before handlers like size-allocate can |
519 // function properly. | 529 // function properly. |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 void WidgetGtk::ConfigureWidgetForTransparentBackground() { | 1039 void WidgetGtk::ConfigureWidgetForTransparentBackground() { |
1030 DCHECK(widget_ && window_contents_ && widget_ != window_contents_); | 1040 DCHECK(widget_ && window_contents_ && widget_ != window_contents_); |
1031 | 1041 |
1032 GdkColormap* rgba_colormap = | 1042 GdkColormap* rgba_colormap = |
1033 gdk_screen_get_rgba_colormap(gdk_screen_get_default()); | 1043 gdk_screen_get_rgba_colormap(gdk_screen_get_default()); |
1034 if (!rgba_colormap) { | 1044 if (!rgba_colormap) { |
1035 transparent_ = false; | 1045 transparent_ = false; |
1036 return; | 1046 return; |
1037 } | 1047 } |
1038 // To make the background transparent we need to install the RGBA colormap | 1048 // To make the background transparent we need to install the RGBA colormap |
1039 // on both the window and fixed. In addition we need to turn off double | 1049 // on both the window and fixed. In addition we need to make sure no |
1040 // buffering and make sure no decorations are drawn. The last bit is to make | 1050 // decorations are drawn. The last bit is to make sure the widget doesn't |
1041 // sure the widget doesn't attempt to draw a pixmap in it's background. | 1051 // attempt to draw a pixmap in it's background. |
1042 gtk_widget_set_colormap(widget_, rgba_colormap); | 1052 gtk_widget_set_colormap(widget_, rgba_colormap); |
1043 gtk_widget_set_app_paintable(widget_, true); | 1053 gtk_widget_set_app_paintable(widget_, true); |
1044 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); | |
1045 gtk_widget_realize(widget_); | 1054 gtk_widget_realize(widget_); |
1046 gdk_window_set_decorations(widget_->window, | 1055 gdk_window_set_decorations(widget_->window, |
1047 static_cast<GdkWMDecoration>(0)); | 1056 static_cast<GdkWMDecoration>(0)); |
1048 // Widget must be realized before setting pixmap. | 1057 // Widget must be realized before setting pixmap. |
1049 gdk_window_set_back_pixmap(widget_->window, NULL, FALSE); | 1058 gdk_window_set_back_pixmap(widget_->window, NULL, FALSE); |
1050 | 1059 |
1051 gtk_widget_set_colormap(window_contents_, rgba_colormap); | 1060 gtk_widget_set_colormap(window_contents_, rgba_colormap); |
1052 gtk_widget_set_app_paintable(window_contents_, true); | 1061 gtk_widget_set_app_paintable(window_contents_, true); |
1053 GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); | |
1054 gtk_widget_realize(window_contents_); | 1062 gtk_widget_realize(window_contents_); |
1055 // Widget must be realized before setting pixmap. | 1063 // Widget must be realized before setting pixmap. |
1056 gdk_window_set_back_pixmap(window_contents_->window, NULL, FALSE); | 1064 gdk_window_set_back_pixmap(window_contents_->window, NULL, FALSE); |
1057 } | 1065 } |
1058 | 1066 |
1059 void WidgetGtk::HandleGrabBroke() { | 1067 void WidgetGtk::HandleGrabBroke() { |
1060 if (has_capture_) { | 1068 if (has_capture_) { |
1061 if (is_mouse_down_) | 1069 if (is_mouse_down_) |
1062 root_view_->ProcessMouseDragCanceled(); | 1070 root_view_->ProcessMouseDragCanceled(); |
1063 is_mouse_down_ = false; | 1071 is_mouse_down_ = false; |
1064 has_capture_ = false; | 1072 has_capture_ = false; |
1065 } | 1073 } |
1066 } | 1074 } |
1067 | 1075 |
1068 | 1076 |
1069 //////////////////////////////////////////////////////////////////////////////// | 1077 //////////////////////////////////////////////////////////////////////////////// |
1070 // Widget, public: | 1078 // Widget, public: |
1071 | 1079 |
1072 // static | 1080 // static |
1073 Widget* Widget::CreateTransparentPopupWidget(bool delete_on_destroy) { | 1081 Widget* Widget::CreateTransparentPopupWidget(bool delete_on_destroy) { |
1074 WidgetGtk* popup = new WidgetGtk(WidgetGtk::TYPE_POPUP); | 1082 WidgetGtk* popup = new WidgetGtk(WidgetGtk::TYPE_POPUP); |
1075 popup->set_delete_on_destroy(delete_on_destroy); | 1083 popup->set_delete_on_destroy(delete_on_destroy); |
1076 popup->MakeTransparent(); | 1084 popup->MakeTransparent(); |
1077 return popup; | 1085 return popup; |
1078 } | 1086 } |
1079 | 1087 |
1080 } // namespace views | 1088 } // namespace views |
OLD | NEW |