| Index: views/widget/widget_gtk.cc
|
| ===================================================================
|
| --- views/widget/widget_gtk.cc (revision 83020)
|
| +++ views/widget/widget_gtk.cc (working copy)
|
| @@ -283,12 +283,12 @@
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // WidgetGtk, public:
|
|
|
| -WidgetGtk::WidgetGtk(Type type)
|
| +WidgetGtk::WidgetGtk()
|
| : is_window_(false),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)),
|
| - type_(type),
|
| widget_(NULL),
|
| window_contents_(NULL),
|
| + child_(false),
|
| ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)),
|
| delete_on_destroy_(true),
|
| transparent_(false),
|
| @@ -326,12 +326,10 @@
|
| input_method_.reset();
|
| DestroyRootView();
|
| DCHECK(delete_on_destroy_ || widget_ == NULL);
|
| - if (type_ != TYPE_CHILD)
|
| - ActiveWindowWatcherX::RemoveObserver(this);
|
| }
|
|
|
| GtkWindow* WidgetGtk::GetTransientParent() const {
|
| - return (type_ != TYPE_CHILD && widget_) ?
|
| + return (!child_ && widget_) ?
|
| gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL;
|
| }
|
|
|
| @@ -366,15 +364,6 @@
|
| }
|
| }
|
|
|
| -bool WidgetGtk::MakeIgnoreEvents() {
|
| - // Transparency can only be enabled for windows/popups and only if we haven't
|
| - // realized the widget.
|
| - DCHECK(!widget_ && type_ != TYPE_CHILD);
|
| -
|
| - ignore_events_ = true;
|
| - return true;
|
| -}
|
| -
|
| void WidgetGtk::AddChild(GtkWidget* child) {
|
| gtk_container_add(GTK_CONTAINER(window_contents_), child);
|
| }
|
| @@ -490,7 +479,7 @@
|
|
|
| bool was_active = IsActive();
|
| is_active_ = (active_window == GTK_WIDGET(GetNativeView())->window);
|
| - if (!is_active_ && active_window && type_ != TYPE_CHILD) {
|
| + if (!is_active_ && active_window && !child_) {
|
| // We're not active, but the force the window to be rendered as active if
|
| // a child window is transient to us.
|
| gpointer data = NULL;
|
| @@ -510,151 +499,6 @@
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // WidgetGtk, Widget implementation:
|
|
|
| -void WidgetGtk::InitWithWidget(Widget* parent,
|
| - const gfx::Rect& bounds) {
|
| - WidgetGtk* parent_gtk = static_cast<WidgetGtk*>(parent);
|
| - GtkWidget* native_parent = NULL;
|
| - if (parent != NULL) {
|
| - if (type_ != TYPE_CHILD) {
|
| - // window's parent has to be window.
|
| - native_parent = parent_gtk->GetNativeView();
|
| - } else {
|
| - native_parent = parent_gtk->window_contents();
|
| - }
|
| - }
|
| - Init(native_parent, bounds);
|
| -}
|
| -
|
| -void WidgetGtk::Init(GtkWidget* parent,
|
| - const gfx::Rect& bounds) {
|
| - Widget::Init(parent, bounds);
|
| - if (type_ != TYPE_CHILD)
|
| - ActiveWindowWatcherX::AddObserver(this);
|
| -
|
| - // Make container here.
|
| - CreateGtkWidget(parent, bounds);
|
| - delegate_->OnNativeWidgetCreated();
|
| -
|
| - // Creates input method for toplevel widget after calling
|
| - // delegate_->OnNativeWidgetCreated(), to make sure that focus manager is
|
| - // already created at this point.
|
| - // TODO(suzhe): Always enable input method when we start to use
|
| - // RenderWidgetHostViewViews in normal ChromeOS.
|
| -#if defined(TOUCH_UI) && defined(HAVE_IBUS)
|
| - if (type_ != TYPE_CHILD) {
|
| - input_method_.reset(new InputMethodIBus(this));
|
| -#else
|
| - if (type_ != TYPE_CHILD && NativeTextfieldViews::IsTextfieldViewsEnabled()) {
|
| - input_method_.reset(new InputMethodGtk(this));
|
| -#endif
|
| - input_method_->Init(GetWidget());
|
| - }
|
| -
|
| - if (opacity_ != 255)
|
| - SetOpacity(opacity_);
|
| -
|
| - // Make sure we receive our motion events.
|
| -
|
| - // In general we register most events on the parent of all widgets. At a
|
| - // minimum we need painting to happen on the parent (otherwise painting
|
| - // doesn't work at all), and similarly we need mouse release events on the
|
| - // parent as windows don't get mouse releases.
|
| - gtk_widget_add_events(window_contents_,
|
| - GDK_ENTER_NOTIFY_MASK |
|
| - GDK_LEAVE_NOTIFY_MASK |
|
| - GDK_BUTTON_PRESS_MASK |
|
| - GDK_BUTTON_RELEASE_MASK |
|
| - GDK_POINTER_MOTION_MASK |
|
| - GDK_KEY_PRESS_MASK |
|
| - GDK_KEY_RELEASE_MASK);
|
| -
|
| - g_signal_connect_after(G_OBJECT(window_contents_), "size_request",
|
| - G_CALLBACK(&OnSizeRequestThunk), this);
|
| - g_signal_connect_after(G_OBJECT(window_contents_), "size_allocate",
|
| - G_CALLBACK(&OnSizeAllocateThunk), this);
|
| - gtk_widget_set_app_paintable(window_contents_, true);
|
| - g_signal_connect(window_contents_, "expose_event",
|
| - G_CALLBACK(&OnPaintThunk), this);
|
| - g_signal_connect(window_contents_, "enter_notify_event",
|
| - G_CALLBACK(&OnEnterNotifyThunk), this);
|
| - g_signal_connect(window_contents_, "leave_notify_event",
|
| - G_CALLBACK(&OnLeaveNotifyThunk), this);
|
| - g_signal_connect(window_contents_, "motion_notify_event",
|
| - G_CALLBACK(&OnMotionNotifyThunk), this);
|
| - g_signal_connect(window_contents_, "button_press_event",
|
| - G_CALLBACK(&OnButtonPressThunk), this);
|
| - g_signal_connect(window_contents_, "button_release_event",
|
| - G_CALLBACK(&OnButtonReleaseThunk), this);
|
| - g_signal_connect(window_contents_, "grab_broken_event",
|
| - G_CALLBACK(&OnGrabBrokeEventThunk), this);
|
| - g_signal_connect(window_contents_, "grab_notify",
|
| - G_CALLBACK(&OnGrabNotifyThunk), this);
|
| - g_signal_connect(window_contents_, "scroll_event",
|
| - G_CALLBACK(&OnScrollThunk), this);
|
| - g_signal_connect(window_contents_, "visibility_notify_event",
|
| - G_CALLBACK(&OnVisibilityNotifyThunk), this);
|
| -
|
| - // In order to receive notification when the window is no longer the front
|
| - // window, we need to install these on the widget.
|
| - // NOTE: this doesn't work with focus follows mouse.
|
| - g_signal_connect(widget_, "focus_in_event",
|
| - G_CALLBACK(&OnFocusInThunk), this);
|
| - g_signal_connect(widget_, "focus_out_event",
|
| - G_CALLBACK(&OnFocusOutThunk), this);
|
| - g_signal_connect(widget_, "destroy",
|
| - G_CALLBACK(&OnDestroyThunk), this);
|
| - g_signal_connect(widget_, "show",
|
| - G_CALLBACK(&OnShowThunk), this);
|
| - g_signal_connect(widget_, "map",
|
| - G_CALLBACK(&OnMapThunk), this);
|
| - g_signal_connect(widget_, "hide",
|
| - G_CALLBACK(&OnHideThunk), this);
|
| -
|
| - // Views/FocusManager (re)sets the focus to the root window,
|
| - // so we need to connect signal handlers to the gtk window.
|
| - // See views::Views::Focus and views::FocusManager::ClearNativeFocus
|
| - // for more details.
|
| - g_signal_connect(widget_, "key_press_event",
|
| - G_CALLBACK(&OnEventKeyThunk), this);
|
| - g_signal_connect(widget_, "key_release_event",
|
| - G_CALLBACK(&OnEventKeyThunk), this);
|
| -
|
| - // Drag and drop.
|
| - gtk_drag_dest_set(window_contents_, static_cast<GtkDestDefaults>(0),
|
| - NULL, 0, GDK_ACTION_COPY);
|
| - g_signal_connect(window_contents_, "drag_motion",
|
| - G_CALLBACK(&OnDragMotionThunk), this);
|
| - g_signal_connect(window_contents_, "drag_data_received",
|
| - G_CALLBACK(&OnDragDataReceivedThunk), this);
|
| - g_signal_connect(window_contents_, "drag_drop",
|
| - G_CALLBACK(&OnDragDropThunk), this);
|
| - g_signal_connect(window_contents_, "drag_leave",
|
| - G_CALLBACK(&OnDragLeaveThunk), this);
|
| - g_signal_connect(window_contents_, "drag_data_get",
|
| - G_CALLBACK(&OnDragDataGetThunk), this);
|
| - g_signal_connect(window_contents_, "drag_end",
|
| - G_CALLBACK(&OnDragEndThunk), this);
|
| - g_signal_connect(window_contents_, "drag_failed",
|
| - G_CALLBACK(&OnDragFailedThunk), this);
|
| -
|
| - tooltip_manager_.reset(new TooltipManagerGtk(this));
|
| -
|
| - // Register for tooltips.
|
| - g_object_set(G_OBJECT(window_contents_), "has-tooltip", TRUE, NULL);
|
| - g_signal_connect(window_contents_, "query_tooltip",
|
| - G_CALLBACK(&OnQueryTooltipThunk), this);
|
| -
|
| - if (type_ == TYPE_CHILD) {
|
| - if (parent) {
|
| - SetBounds(bounds);
|
| - }
|
| - } else {
|
| - if (bounds.width() > 0 && bounds.height() > 0)
|
| - gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height());
|
| - gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y());
|
| - }
|
| -}
|
| -
|
| gfx::NativeView WidgetGtk::GetNativeView() const {
|
| return widget_;
|
| }
|
| @@ -691,7 +535,7 @@
|
| }
|
|
|
| void WidgetGtk::ClearNativeFocus() {
|
| - DCHECK(type_ != TYPE_CHILD);
|
| + DCHECK(!child_);
|
| if (!GetNativeView()) {
|
| NOTREACHED();
|
| return;
|
| @@ -774,26 +618,143 @@
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // WidgetGtk, NativeWidget implementation:
|
|
|
| -void WidgetGtk::SetCreateParams(const CreateParams& params) {
|
| - DCHECK(!GetNativeView());
|
| +void WidgetGtk::InitNativeWidget(const CreateParams& params) {
|
| + SetCreateParams(params);
|
|
|
| - // Set non-style attributes.
|
| - set_delete_on_destroy(params.delete_on_destroy);
|
| + CreateParams modified_params = params;
|
| + gfx::NativeView parent = params.parent;
|
| + if (params.parent_widget) {
|
| + WidgetGtk* parent_gtk =
|
| + static_cast<WidgetGtk*>(params.parent_widget->native_widget());
|
| + modified_params.parent = child_ ? parent_gtk->window_contents()
|
| + : params.parent_widget->GetNativeView();
|
| + }
|
|
|
| - if (params.transparent)
|
| - MakeTransparent();
|
| - if (!params.accept_events)
|
| - MakeIgnoreEvents();
|
| + if (!child_)
|
| + ActiveWindowWatcherX::AddObserver(this);
|
|
|
| - if (params.type == CreateParams::TYPE_MENU) {
|
| - GdkEvent* event = gtk_get_current_event();
|
| - if (event) {
|
| - is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS ||
|
| - event->type == GDK_2BUTTON_PRESS ||
|
| - event->type == GDK_3BUTTON_PRESS;
|
| - gdk_event_free(event);
|
| - }
|
| + // Make container here.
|
| + CreateGtkWidget(modified_params);
|
| + delegate_->OnNativeWidgetCreated();
|
| +
|
| + // Creates input method for toplevel widget after calling
|
| + // delegate_->OnNativeWidgetCreated(), to make sure that focus manager is
|
| + // already created at this point.
|
| + // TODO(suzhe): Always enable input method when we start to use
|
| + // RenderWidgetHostViewViews in normal ChromeOS.
|
| +#if defined(TOUCH_UI) && defined(HAVE_IBUS)
|
| + if (!child_) {
|
| + input_method_.reset(new InputMethodIBus(this));
|
| +#else
|
| + if (!child_ && NativeTextfieldViews::IsTextfieldViewsEnabled()) {
|
| + input_method_.reset(new InputMethodGtk(this));
|
| +#endif
|
| + input_method_->Init(GetWidget());
|
| }
|
| +
|
| + if (opacity_ != 255)
|
| + SetOpacity(opacity_);
|
| +
|
| + // Make sure we receive our motion events.
|
| +
|
| + // In general we register most events on the parent of all widgets. At a
|
| + // minimum we need painting to happen on the parent (otherwise painting
|
| + // doesn't work at all), and similarly we need mouse release events on the
|
| + // parent as windows don't get mouse releases.
|
| + gtk_widget_add_events(window_contents_,
|
| + GDK_ENTER_NOTIFY_MASK |
|
| + GDK_LEAVE_NOTIFY_MASK |
|
| + GDK_BUTTON_PRESS_MASK |
|
| + GDK_BUTTON_RELEASE_MASK |
|
| + GDK_POINTER_MOTION_MASK |
|
| + GDK_KEY_PRESS_MASK |
|
| + GDK_KEY_RELEASE_MASK);
|
| +
|
| + g_signal_connect_after(G_OBJECT(window_contents_), "size_request",
|
| + G_CALLBACK(&OnSizeRequestThunk), this);
|
| + g_signal_connect_after(G_OBJECT(window_contents_), "size_allocate",
|
| + G_CALLBACK(&OnSizeAllocateThunk), this);
|
| + gtk_widget_set_app_paintable(window_contents_, true);
|
| + g_signal_connect(window_contents_, "expose_event",
|
| + G_CALLBACK(&OnPaintThunk), this);
|
| + g_signal_connect(window_contents_, "enter_notify_event",
|
| + G_CALLBACK(&OnEnterNotifyThunk), this);
|
| + g_signal_connect(window_contents_, "leave_notify_event",
|
| + G_CALLBACK(&OnLeaveNotifyThunk), this);
|
| + g_signal_connect(window_contents_, "motion_notify_event",
|
| + G_CALLBACK(&OnMotionNotifyThunk), this);
|
| + g_signal_connect(window_contents_, "button_press_event",
|
| + G_CALLBACK(&OnButtonPressThunk), this);
|
| + g_signal_connect(window_contents_, "button_release_event",
|
| + G_CALLBACK(&OnButtonReleaseThunk), this);
|
| + g_signal_connect(window_contents_, "grab_broken_event",
|
| + G_CALLBACK(&OnGrabBrokeEventThunk), this);
|
| + g_signal_connect(window_contents_, "grab_notify",
|
| + G_CALLBACK(&OnGrabNotifyThunk), this);
|
| + g_signal_connect(window_contents_, "scroll_event",
|
| + G_CALLBACK(&OnScrollThunk), this);
|
| + g_signal_connect(window_contents_, "visibility_notify_event",
|
| + G_CALLBACK(&OnVisibilityNotifyThunk), this);
|
| +
|
| + // In order to receive notification when the window is no longer the front
|
| + // window, we need to install these on the widget.
|
| + // NOTE: this doesn't work with focus follows mouse.
|
| + g_signal_connect(widget_, "focus_in_event",
|
| + G_CALLBACK(&OnFocusInThunk), this);
|
| + g_signal_connect(widget_, "focus_out_event",
|
| + G_CALLBACK(&OnFocusOutThunk), this);
|
| + g_signal_connect(widget_, "destroy",
|
| + G_CALLBACK(&OnDestroyThunk), this);
|
| + g_signal_connect(widget_, "show",
|
| + G_CALLBACK(&OnShowThunk), this);
|
| + g_signal_connect(widget_, "map",
|
| + G_CALLBACK(&OnMapThunk), this);
|
| + g_signal_connect(widget_, "hide",
|
| + G_CALLBACK(&OnHideThunk), this);
|
| +
|
| + // Views/FocusManager (re)sets the focus to the root window,
|
| + // so we need to connect signal handlers to the gtk window.
|
| + // See views::Views::Focus and views::FocusManager::ClearNativeFocus
|
| + // for more details.
|
| + g_signal_connect(widget_, "key_press_event",
|
| + G_CALLBACK(&OnEventKeyThunk), this);
|
| + g_signal_connect(widget_, "key_release_event",
|
| + G_CALLBACK(&OnEventKeyThunk), this);
|
| +
|
| + // Drag and drop.
|
| + gtk_drag_dest_set(window_contents_, static_cast<GtkDestDefaults>(0),
|
| + NULL, 0, GDK_ACTION_COPY);
|
| + g_signal_connect(window_contents_, "drag_motion",
|
| + G_CALLBACK(&OnDragMotionThunk), this);
|
| + g_signal_connect(window_contents_, "drag_data_received",
|
| + G_CALLBACK(&OnDragDataReceivedThunk), this);
|
| + g_signal_connect(window_contents_, "drag_drop",
|
| + G_CALLBACK(&OnDragDropThunk), this);
|
| + g_signal_connect(window_contents_, "drag_leave",
|
| + G_CALLBACK(&OnDragLeaveThunk), this);
|
| + g_signal_connect(window_contents_, "drag_data_get",
|
| + G_CALLBACK(&OnDragDataGetThunk), this);
|
| + g_signal_connect(window_contents_, "drag_end",
|
| + G_CALLBACK(&OnDragEndThunk), this);
|
| + g_signal_connect(window_contents_, "drag_failed",
|
| + G_CALLBACK(&OnDragFailedThunk), this);
|
| +
|
| + tooltip_manager_.reset(new TooltipManagerGtk(this));
|
| +
|
| + // Register for tooltips.
|
| + g_object_set(G_OBJECT(window_contents_), "has-tooltip", TRUE, NULL);
|
| + g_signal_connect(window_contents_, "query_tooltip",
|
| + G_CALLBACK(&OnQueryTooltipThunk), this);
|
| +
|
| + if (child_) {
|
| + if (parent)
|
| + SetBounds(params.bounds);
|
| + } else {
|
| + if (params.bounds.width() > 0 && params.bounds.height() > 0)
|
| + gtk_window_resize(GTK_WINDOW(widget_), params.bounds.width(),
|
| + params.bounds.height());
|
| + gtk_window_move(GTK_WINDOW(widget_), params.bounds.x(), params.bounds.y());
|
| + }
|
| }
|
|
|
| Widget* WidgetGtk::GetWidget() {
|
| @@ -870,7 +831,7 @@
|
| }
|
|
|
| void WidgetGtk::SetBounds(const gfx::Rect& bounds) {
|
| - if (type_ == TYPE_CHILD) {
|
| + if (child_) {
|
| GtkWidget* parent = gtk_widget_get_parent(widget_);
|
| if (GTK_IS_VIEWS_FIXED(parent)) {
|
| WidgetGtk* parent_widget = static_cast<WidgetGtk*>(
|
| @@ -908,7 +869,7 @@
|
| }
|
|
|
| void WidgetGtk::SetSize(const gfx::Size& size) {
|
| - if (type_ == TYPE_CHILD) {
|
| + if (child_) {
|
| GtkWidget* parent = gtk_widget_get_parent(widget_);
|
| if (GTK_IS_VIEWS_FIXED(parent)) {
|
| gtk_views_fixed_set_widget_size(widget_, size.width(), size.height());
|
| @@ -984,7 +945,7 @@
|
| }
|
|
|
| void WidgetGtk::SetAlwaysOnTop(bool on_top) {
|
| - DCHECK(type_ != TYPE_CHILD);
|
| + DCHECK(!child_);
|
| always_on_top_ = on_top;
|
| if (widget_)
|
| gtk_window_set_keep_above(GTK_WINDOW(widget_), on_top);
|
| @@ -995,7 +956,7 @@
|
| }
|
|
|
| bool WidgetGtk::IsActive() const {
|
| - DCHECK(type_ != TYPE_CHILD);
|
| + DCHECK(!child_);
|
| return is_active_;
|
| }
|
|
|
| @@ -1048,7 +1009,7 @@
|
| // the requisition as a minimum size for top level windows, returning a
|
| // preferred size for these would prevents us from setting smaller window
|
| // sizes.
|
| - if (type_ == TYPE_CHILD) {
|
| + if (child_) {
|
| gfx::Size size(GetRootView()->GetPreferredSize());
|
| requisition->width = size.width();
|
| requisition->height = size.height();
|
| @@ -1068,7 +1029,7 @@
|
| }
|
|
|
| gboolean WidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) {
|
| - if (transparent_ && type_ == TYPE_CHILD) {
|
| + if (transparent_ && child_) {
|
| // Clear the background before drawing any view and native components.
|
| DrawTransparentBackground(widget, event);
|
| if (!CompositePainter::IsComposited(widget_) &&
|
| @@ -1101,7 +1062,7 @@
|
|
|
| if (!painted_) {
|
| painted_ = true;
|
| - if (type_ != TYPE_CHILD)
|
| + if (!child_)
|
| UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */);
|
| }
|
| return false; // False indicates other widgets should get the event as well.
|
| @@ -1262,7 +1223,7 @@
|
|
|
| should_handle_menu_key_release_ = false;
|
|
|
| - if (type_ == TYPE_CHILD)
|
| + if (child_)
|
| return false;
|
|
|
| // Only top-level Widget should have an InputMethod instance.
|
| @@ -1282,7 +1243,7 @@
|
| return false; // This is the second focus-out event in a row, ignore it.
|
| has_focus_ = false;
|
|
|
| - if (type_ == TYPE_CHILD)
|
| + if (child_)
|
| return false;
|
|
|
| // Only top-level Widget should have an InputMethod instance.
|
| @@ -1328,6 +1289,8 @@
|
| }
|
|
|
| void WidgetGtk::OnDestroy(GtkWidget* object) {
|
| + if (!child_)
|
| + ActiveWindowWatcherX::RemoveObserver(this);
|
| // Note that this handler is hooked to GtkObject::destroy.
|
| // NULL out pointers here since we might still be in an observerer list
|
| // until delstion happens.
|
| @@ -1414,6 +1377,28 @@
|
| gtk_bindings_activate_event(GTK_OBJECT(widget_), event);
|
| }
|
|
|
| +void WidgetGtk::SetCreateParams(const CreateParams& params) {
|
| + DCHECK(!GetNativeView());
|
| +
|
| + delete_on_destroy_ = params.delete_on_destroy;
|
| + child_ = params.child;
|
| +
|
| + if (params.transparent)
|
| + MakeTransparent();
|
| + if (!params.accept_events && !child_)
|
| + ignore_events_ = true;
|
| +
|
| + if (params.type == CreateParams::TYPE_MENU) {
|
| + GdkEvent* event = gtk_get_current_event();
|
| + if (event) {
|
| + is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS ||
|
| + event->type == GDK_2BUTTON_PRESS ||
|
| + event->type == GDK_3BUTTON_PRESS;
|
| + gdk_event_free(event);
|
| + }
|
| + }
|
| +}
|
| +
|
| gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) {
|
| // Clear the background to be totally transparent. We don't need to
|
| // paint the root view here as that is done by OnPaint.
|
| @@ -1430,7 +1415,7 @@
|
| }
|
|
|
| void WidgetGtk::OnChildExpose(GtkWidget* child) {
|
| - DCHECK(type_ != TYPE_CHILD);
|
| + DCHECK(!child_);
|
| if (!painted_) {
|
| painted_ = true;
|
| UpdateFreezeUpdatesProperty(GTK_WINDOW(widget_), false /* remove */);
|
| @@ -1464,7 +1449,7 @@
|
| return NULL;
|
| }
|
|
|
| -void WidgetGtk::CreateGtkWidget(GtkWidget* parent, const gfx::Rect& bounds) {
|
| +void WidgetGtk::CreateGtkWidget(const CreateParams& params) {
|
| // We turn off double buffering for two reasons:
|
| // 1. We draw to a canvas then composite to the screen, which means we're
|
| // doing our own double buffering already.
|
| @@ -1472,13 +1457,13 @@
|
| // needs to expand the paint region (see RootView::OnPaint). This means
|
| // that if we use GTK's double buffering and we tried to expand the dirty
|
| // region, it wouldn't get painted.
|
| - if (type_ == TYPE_CHILD) {
|
| + if (child_) {
|
| window_contents_ = widget_ = gtk_views_fixed_new();
|
| gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed");
|
| if (!is_double_buffered_)
|
| GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED);
|
| gtk_fixed_set_has_window(GTK_FIXED(widget_), true);
|
| - if (!parent && !null_parent_) {
|
| + if (!params.parent && !null_parent_) {
|
| GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP);
|
| null_parent_ = gtk_fixed_new();
|
| gtk_widget_set_name(widget_, "views-gtkwidget-null-parent");
|
| @@ -1487,10 +1472,12 @@
|
| }
|
| if (transparent_) {
|
| // transparency has to be configured before widget is realized.
|
| - DCHECK(parent) << "Transparent widget must have parent when initialized";
|
| - ConfigureWidgetForTransparentBackground(parent);
|
| + DCHECK(params.parent) <<
|
| + "Transparent widget must have parent when initialized";
|
| + ConfigureWidgetForTransparentBackground(params.parent);
|
| }
|
| - gtk_container_add(GTK_CONTAINER(parent ? parent : null_parent_), widget_);
|
| + gtk_container_add(
|
| + GTK_CONTAINER(params.parent ? params.parent : null_parent_), widget_);
|
| gtk_widget_realize(widget_);
|
| if (transparent_) {
|
| // The widget has to be realized to set composited flag.
|
| @@ -1499,7 +1486,7 @@
|
| DCHECK(GTK_WIDGET_REALIZED(widget_));
|
| gdk_window_set_composited(widget_->window, true);
|
| }
|
| - if (parent && !bounds.size().IsEmpty()) {
|
| + if (params.parent && !params.bounds.size().IsEmpty()) {
|
| // Make sure that an widget is given it's initial size before
|
| // we're done initializing, to take care of some potential
|
| // corner cases when programmatically arranging hierarchies as
|
| @@ -1509,17 +1496,20 @@
|
| // This can't be done without a parent present, or stale data
|
| // might show up on the screen as seen in
|
| // http://code.google.com/p/chromium/issues/detail?id=53870
|
| - GtkAllocation alloc = { 0, 0, bounds.width(), bounds.height() };
|
| + GtkAllocation alloc =
|
| + { 0, 0, params.bounds.width(), params.bounds.height() };
|
| gtk_widget_size_allocate(widget_, &alloc);
|
| }
|
| } else {
|
| // Use our own window class to override GtkWindow's move_focus method.
|
| widget_ = gtk_views_window_new(
|
| - (type_ == TYPE_WINDOW || type_ == TYPE_DECORATED_WINDOW) ?
|
| - GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP);
|
| + params.type == CreateParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL
|
| + : GTK_WINDOW_POPUP);
|
| gtk_widget_set_name(widget_, "views-gtkwidget-window");
|
| - if (transient_to_parent_)
|
| - gtk_window_set_transient_for(GTK_WINDOW(widget_), GTK_WINDOW(parent));
|
| + if (transient_to_parent_) {
|
| + gtk_window_set_transient_for(GTK_WINDOW(widget_),
|
| + GTK_WINDOW(params.parent));
|
| + }
|
| GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED);
|
|
|
| // Gtk determines the size for windows based on the requested size of the
|
| @@ -1533,18 +1523,17 @@
|
| // time.
|
| gtk_widget_set_size_request(widget_, 1, 1);
|
|
|
| - if (!bounds.size().IsEmpty()) {
|
| + if (!params.bounds.size().IsEmpty()) {
|
| // When we realize the window, the window manager is given a size. If we
|
| // don't specify a size before then GTK defaults to 200x200. Specify
|
| // a size now so that the window manager sees the requested size.
|
| - GtkAllocation alloc = { 0, 0, bounds.width(), bounds.height() };
|
| + GtkAllocation alloc =
|
| + { 0, 0, params.bounds.width(), params.bounds.height() };
|
| gtk_widget_size_allocate(widget_, &alloc);
|
| }
|
| - if (type_ != TYPE_DECORATED_WINDOW) {
|
| - gtk_window_set_decorated(GTK_WINDOW(widget_), false);
|
| - // We'll take care of positioning our window.
|
| - gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE);
|
| - }
|
| + gtk_window_set_decorated(GTK_WINDOW(widget_), false);
|
| + // We'll take care of positioning our window.
|
| + gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE);
|
|
|
| window_contents_ = gtk_views_fixed_new();
|
| gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed");
|
| @@ -1582,7 +1571,7 @@
|
| // on both the window and fixed. In addition we need to make sure no
|
| // decorations are drawn. The last bit is to make sure the widget doesn't
|
| // attempt to draw a pixmap in it's background.
|
| - if (type_ != TYPE_CHILD) {
|
| + if (!child_) {
|
| DCHECK(parent == NULL);
|
| gtk_widget_set_colormap(widget_, rgba_colormap);
|
| gtk_widget_set_app_paintable(widget_, true);
|
| @@ -1632,30 +1621,8 @@
|
| // Widget, public:
|
|
|
| // static
|
| -Widget* Widget::CreateWidget(const CreateParams& params) {
|
| - // TODO(beng): coalesce with CreateParams::Type.
|
| - WidgetGtk::Type widget_gtk_type = WidgetGtk::TYPE_DECORATED_WINDOW;
|
| - switch (params.type) {
|
| - case CreateParams::TYPE_CONTROL:
|
| - widget_gtk_type = WidgetGtk::TYPE_CHILD;
|
| - break;
|
| - case CreateParams::TYPE_MENU:
|
| - widget_gtk_type = WidgetGtk::TYPE_POPUP;
|
| - break;
|
| - case CreateParams::TYPE_POPUP:
|
| - widget_gtk_type = WidgetGtk::TYPE_POPUP;
|
| - break;
|
| - case CreateParams::TYPE_WINDOW:
|
| - widget_gtk_type = WidgetGtk::TYPE_DECORATED_WINDOW;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -
|
| - WidgetGtk* widget = new WidgetGtk(widget_gtk_type);
|
| - widget->SetCreateParams(params);
|
| - return widget;
|
| +Widget* Widget::CreateWidget() {
|
| + return new WidgetGtk();
|
| }
|
|
|
| // static
|
|
|