diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 20:56:11 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 20:56:11 +0000 |
commit | 893160d54cb5b2c1c68d3b69ec8ebc9b25b68b82 (patch) | |
tree | 0f29c1776a2f34f06ba60ba53a20691d261b6366 /views/widget | |
parent | 22332192088e1e897d02a4bc7a2983e3864ab3b6 (diff) | |
download | chromium_src-893160d54cb5b2c1c68d3b69ec8ebc9b25b68b82.zip chromium_src-893160d54cb5b2c1c68d3b69ec8ebc9b25b68b82.tar.gz chromium_src-893160d54cb5b2c1c68d3b69ec8ebc9b25b68b82.tar.bz2 |
Minor gtk-views cleanup:
. Makes closing widget work.
. Makes clicking button send action.
. Fixes ownership of native controls.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/113657
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16532 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/widget')
-rw-r--r-- | views/widget/widget_gtk.cc | 78 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 19 |
2 files changed, 83 insertions, 14 deletions
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 0b24657..1f8790e 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -4,6 +4,7 @@ #include "views/widget/widget_gtk.h" +#include "base/compiler_specific.h" #include "views/fill_layout.h" #include "views/widget/root_view.h" #include "views/window/window_gtk.h" @@ -57,15 +58,12 @@ WidgetGtk::WidgetGtk(Type type) child_widget_parent_(NULL), is_mouse_down_(false), has_capture_(false), - last_mouse_event_was_move_(false) { + last_mouse_event_was_move_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), + delete_on_destroy_(true) { } WidgetGtk::~WidgetGtk() { - if (widget_) { - // TODO: make sure this is right. - gtk_widget_destroy(widget_); - child_widget_parent_ = widget_ = NULL; - } MessageLoopForUI::current()->RemoveObserver(this); } @@ -79,10 +77,10 @@ void WidgetGtk::Init(const gfx::Rect& bounds, // Make sure we receive our motion events. - // We register everything 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. + // 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(child_widget_parent_, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | @@ -114,10 +112,6 @@ void WidgetGtk::Init(const gfx::Rect& bounds, G_CALLBACK(CallButtonPress), NULL); g_signal_connect(G_OBJECT(child_widget_parent_), "button_release_event", G_CALLBACK(CallButtonRelease), NULL); - g_signal_connect(G_OBJECT(child_widget_parent_), "focus_in_event", - G_CALLBACK(CallFocusIn), NULL); - g_signal_connect(G_OBJECT(child_widget_parent_), "focus_out_event", - G_CALLBACK(CallFocusOut), NULL); g_signal_connect(G_OBJECT(child_widget_parent_), "grab_broke_event", G_CALLBACK(CallGrabBrokeEvent), NULL); g_signal_connect(G_OBJECT(child_widget_parent_), "grab_notify", @@ -133,6 +127,17 @@ void WidgetGtk::Init(const gfx::Rect& bounds, g_signal_connect(G_OBJECT(child_widget_parent_), "visibility_notify_event", G_CALLBACK(CallVisibilityNotify), NULL); + // 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(G_OBJECT(widget_), "focus_in_event", + G_CALLBACK(CallFocusIn), NULL); + g_signal_connect(G_OBJECT(widget_), "focus_out_event", + G_CALLBACK(CallFocusOut), NULL); + + g_signal_connect(G_OBJECT(widget_), "destroy", + G_CALLBACK(CallDestroy), NULL); + // TODO(erg): Ignore these signals for now because they're such a drag. // // g_signal_connect(G_OBJECT(widget_), "drag_motion", @@ -174,6 +179,35 @@ void WidgetGtk::SetContentsView(View* view) { OnSizeAllocate(widget_, &(widget_->allocation)); } +void WidgetGtk::Close() { + if (!widget_) + return; // No need to do anything. + + // Hide first. + Hide(); + if (close_widget_factory_.empty()) { + // And we delay the close just in case we're on the stack. + MessageLoop::current()->PostTask(FROM_HERE, + close_widget_factory_.NewRunnableMethod( + &WidgetGtk::CloseNow)); + } +} + +void WidgetGtk::CloseNow() { + if (widget_) + gtk_widget_destroy(widget_); +} + +void WidgetGtk::Show() { + if (widget_) + gtk_widget_show(widget_); +} + +void WidgetGtk::Hide() { + if (widget_) + gtk_widget_hide(widget_); +} + void WidgetGtk::GetBounds(gfx::Rect* out, bool including_frame) const { DCHECK(widget_); @@ -368,6 +402,13 @@ void WidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) { HandleGrabBroke(); } +void WidgetGtk::OnDestroy(GtkWidget* widget) { + widget_ = child_widget_parent_ = NULL; + root_view_->OnWidgetDestroyed(); + if (delete_on_destroy_) + delete this; +} + // static WindowGtk* WidgetGtk::GetWindowForNative(GtkWidget* widget) { gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-window"); @@ -572,6 +613,15 @@ void WidgetGtk::CallGrabNotify(GtkWidget* widget, gboolean was_grabbed) { } // static +void WidgetGtk::CallDestroy(GtkObject* object) { + WidgetGtk* widget_gtk = GetViewForNative(GTK_WIDGET(object)); + if (!widget_gtk) + return; + + return widget_gtk->OnDestroy(GTK_WIDGET(object)); +} + +// static Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { GtkWidget* parent = widget; while (parent) { diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index cebc686..e1a7468 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -39,6 +39,12 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { // Initializes this widget. void Init(const gfx::Rect& bounds, bool has_own_focus_manager); + // Sets whether or not we are deleted when the widget is destroyed. The + // default is true. + void set_delete_on_destroy(bool delete_on_destroy) { + delete_on_destroy_ = delete_on_destroy; + } + void AddChild(GtkWidget* child); void RemoveChild(GtkWidget* child); @@ -51,6 +57,11 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { virtual void SetContentsView(View* view); + virtual void Close(); + void CloseNow(); + virtual void Show(); + virtual void Hide(); + // Overridden from Widget: virtual void GetBounds(gfx::Rect* out, bool including_frame) const; virtual gfx::NativeView GetNativeView() const; @@ -93,6 +104,7 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { } virtual gboolean OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event); virtual void OnGrabNotify(GtkWidget* widget, gboolean was_grabbed); + virtual void OnDestroy(GtkWidget* widget); // Returns whether capture should be released on mouse release. The default // is true. @@ -136,6 +148,7 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { GdkEventVisibility* event); static gboolean CallGrabBrokeEvent(GtkWidget* widget, GdkEvent* event); static void CallGrabNotify(GtkWidget* widget, gboolean was_grabbed); + static void CallDestroy(GtkObject* object); // Returns the first ancestor of |widget| that is a window. static Window* GetWindowImpl(GtkWidget* widget); @@ -173,6 +186,12 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { int last_mouse_move_x_; int last_mouse_move_y_; + // The following factory is used to delay destruction. + ScopedRunnableMethodFactory<WidgetGtk> close_widget_factory_; + + // See description above setter. + bool delete_on_destroy_; + DISALLOW_COPY_AND_ASSIGN(WidgetGtk); }; |