diff options
-rw-r--r-- | ash/system/tray/system_tray_bubble.cc | 31 | ||||
-rw-r--r-- | ash/system/tray/system_tray_bubble.h | 10 | ||||
-rw-r--r-- | ui/views/bubble/bubble_delegate.cc | 7 | ||||
-rw-r--r-- | ui/views/bubble/bubble_delegate.h | 1 | ||||
-rw-r--r-- | ui/views/widget/widget.cc | 25 | ||||
-rw-r--r-- | ui/views/widget/widget.h | 9 |
6 files changed, 49 insertions, 34 deletions
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc index 38596dc..07e064a 100644 --- a/ash/system/tray/system_tray_bubble.cc +++ b/ash/system/tray/system_tray_bubble.cc @@ -12,6 +12,7 @@ #include "ash/system/tray/tray_constants.h" #include "ash/wm/shelf_layout_manager.h" #include "ash/wm/window_animations.h" +#include "base/message_loop.h" #include "grit/ash_strings.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" @@ -356,6 +357,10 @@ SystemTrayBubble::SystemTrayBubble( } SystemTrayBubble::~SystemTrayBubble() { + // The bubble may be closing without having been hidden first. So it may still + // be in the message-loop's observer list. + MessageLoopForUI::current()->RemoveObserver(this); + DestroyItemViews(); // Reset the host pointer in bubble_view_ in case its destruction is deferred. if (bubble_view_) @@ -509,11 +514,37 @@ void SystemTrayBubble::CreateItemViews(user::LoginStatus login_status) { } } +base::EventStatus SystemTrayBubble::WillProcessEvent( + const base::NativeEvent& event) { + // Check if the user clicked outside of the bubble and close it if they did. + if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION && + ui::EventTypeFromNative(event) == ui::ET_MOUSE_PRESSED) { + gfx::Point cursor_in_view = ui::EventLocationFromNative(event); + views::View::ConvertPointFromScreen(bubble_view_, &cursor_in_view); + if (!bubble_view_->HitTest(cursor_in_view)) { + bubble_widget_->Close(); + } + } + return base::EVENT_CONTINUE; +} + +void SystemTrayBubble::DidProcessEvent(const base::NativeEvent& event) { +} + void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) { CHECK_EQ(bubble_widget_, widget); + MessageLoopForUI::current()->RemoveObserver(this); bubble_widget_ = NULL; tray_->RemoveBubble(this); } +void SystemTrayBubble::OnWidgetVisibilityChanged(views::Widget* widget, + bool visible) { + if (!visible) + MessageLoopForUI::current()->RemoveObserver(this); + else + MessageLoopForUI::current()->AddObserver(this); +} + } // namespace internal } // namespace ash diff --git a/ash/system/tray/system_tray_bubble.h b/ash/system/tray/system_tray_bubble.h index 63b749f..ed397b3 100644 --- a/ash/system/tray/system_tray_bubble.h +++ b/ash/system/tray/system_tray_bubble.h @@ -8,6 +8,7 @@ #include "ash/system/user/login_status.h" #include "base/base_export.h" +#include "base/message_pump_observer.h" #include "base/timer.h" #include "ui/views/bubble/bubble_delegate.h" #include "ui/views/widget/widget.h" @@ -57,7 +58,8 @@ class SystemTrayBubbleView : public views::BubbleDelegateView { DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleView); }; -class SystemTrayBubble : public views::Widget::Observer { +class SystemTrayBubble : public base::MessagePumpObserver, + public views::Widget::Observer { public: enum BubbleType { BUBBLE_TYPE_DEFAULT, @@ -107,8 +109,14 @@ class SystemTrayBubble : public views::Widget::Observer { private: void CreateItemViews(user::LoginStatus login_status); + // Overridden from base::MessagePumpObserver. + virtual base::EventStatus WillProcessEvent( + const base::NativeEvent& event) OVERRIDE; + virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE; // Overridden from views::Widget::Observer. virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; + virtual void OnWidgetVisibilityChanged(views::Widget* widget, + bool visible) OVERRIDE; ash::SystemTray* tray_; SystemTrayBubbleView* bubble_view_; diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc index 072f355..92645a8 100644 --- a/ui/views/bubble/bubble_delegate.cc +++ b/ui/views/bubble/bubble_delegate.cc @@ -25,7 +25,6 @@ Widget* CreateBubbleWidget(BubbleDelegateView* bubble) { Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE); bubble_params.delegate = bubble; bubble_params.transparent = true; - bubble_params.close_on_deactivate = bubble->close_on_deactivate(); if (bubble->parent_window()) bubble_params.parent = bubble->parent_window(); else @@ -213,6 +212,12 @@ void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget, } } +void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget, + bool active) { + if (close_on_deactivate() && widget == GetWidget() && !active) + GetWidget()->Close(); +} + void BubbleDelegateView::OnWidgetMoved(Widget* widget) { if (move_with_anchor() && anchor_widget() == widget) SizeToContents(); diff --git a/ui/views/bubble/bubble_delegate.h b/ui/views/bubble/bubble_delegate.h index 25d13f8..be66f80 100644 --- a/ui/views/bubble/bubble_delegate.h +++ b/ui/views/bubble/bubble_delegate.h @@ -50,6 +50,7 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView, // Widget::Observer overrides: virtual void OnWidgetClosing(Widget* widget) OVERRIDE; virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) OVERRIDE; + virtual void OnWidgetActivationChanged(Widget* widget, bool active) OVERRIDE; virtual void OnWidgetMoved(Widget* widget) OVERRIDE; bool close_on_esc() const { return close_on_esc_; } diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index e5f3072..e238c67 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc @@ -4,7 +4,6 @@ #include "ui/views/widget/widget.h" -#include "base/bind.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" @@ -108,7 +107,6 @@ Widget::InitParams::InitParams() ViewsDelegate::views_delegate->UseTransparentWindows()), accept_events(true), can_activate(true), - close_on_deactivate(false), keep_on_top(false), ownership(NATIVE_WIDGET_OWNS_WIDGET), mirror_origin_in_rtl(false), @@ -133,7 +131,6 @@ Widget::InitParams::InitParams(Type type) ViewsDelegate::views_delegate->UseTransparentWindows()), accept_events(true), can_activate(type != TYPE_POPUP && type != TYPE_MENU), - close_on_deactivate(false), keep_on_top(type == TYPE_MENU), ownership(NATIVE_WIDGET_OWNS_WIDGET), mirror_origin_in_rtl(false), @@ -156,8 +153,7 @@ gfx::NativeView Widget::InitParams::GetParent() const { // Widget, public: Widget::Widget() - : ALLOW_THIS_IN_INITIALIZER_LIST(set_capture_factory_(this)), - native_widget_(NULL), + : native_widget_(NULL), widget_delegate_(NULL), non_client_view_(NULL), dragged_view_(NULL), @@ -169,7 +165,6 @@ Widget::Widget() widget_closed_(false), saved_show_state_(ui::SHOW_STATE_DEFAULT), focus_on_creation_(true), - close_on_deactivate_(false), is_top_level_(false), native_widget_initialized_(false), native_widget_destroyed_(false), @@ -321,7 +316,6 @@ void Widget::Init(const InitParams& params) { SetContentsView(params.delegate->GetContentsView()); SetInitialBoundsForFramelessWindow(params.bounds); } - close_on_deactivate_ = params.close_on_deactivate; native_widget_initialized_ = true; } @@ -517,14 +511,6 @@ void Widget::Show() { } else { native_widget_->Show(); } - - if (CanActivate() && close_on_deactivate_) { - // Set mouse capture on timeout in case this is called from a - // mouse pressed handler. - MessageLoopForUI::current()->PostTask(FROM_HERE, base::Bind( - &Widget::SetMouseCapture, set_capture_factory_.GetWeakPtr(), - static_cast<View*>(NULL))); - } } void Widget::Hide() { @@ -1064,8 +1050,6 @@ bool Widget::OnMouseEvent(const MouseEvent& event) { native_widget_->SetCapture(); return true; } - if (close_on_deactivate_ && !GetRootView()->HitTest(event.location())) - Close(); return false; case ui::ET_MOUSE_RELEASED: last_mouse_event_was_move_ = false; @@ -1106,11 +1090,6 @@ void Widget::OnMouseCaptureLost() { if (is_mouse_button_pressed_) GetRootView()->OnMouseCaptureLost(); is_mouse_button_pressed_ = false; - - // Without mouse capture, the widget doesn't process all events so can miss - // the user clicking outside the root view's bounds. - if (close_on_deactivate_) - Close(); } ui::TouchStatus Widget::OnTouchEvent(const TouchEvent& event) { @@ -1178,7 +1157,7 @@ void Widget::DestroyRootView() { // Widget, private: bool Widget::ShouldReleaseCaptureOnMouseReleased() const { - return !close_on_deactivate_; + return true; } void Widget::SetInactiveRenderingDisabled(bool value) { diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h index 82ab276..c754e95 100644 --- a/ui/views/widget/widget.h +++ b/ui/views/widget/widget.h @@ -11,7 +11,6 @@ #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "ui/base/accessibility/accessibility_types.h" #include "ui/base/ui_base_types.h" @@ -164,7 +163,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, bool transparent; bool accept_events; bool can_activate; - bool close_on_deactivate; bool keep_on_top; Ownership ownership; bool mirror_origin_in_rtl; @@ -695,8 +693,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // It's only for testing purpose. void ReplaceInputMethod(InputMethod* input_method); - base::WeakPtrFactory<Widget> set_capture_factory_; - internal::NativeWidgetPrivate* native_widget_; ObserverList<Observer> observers_; @@ -762,11 +758,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // initial focus for the widget. bool focus_on_creation_; - // If true, the widget is closed when the user clicks outside the root view's - // bounds. This intentionally encompasses some situations where deactivation - // does not happen. - bool close_on_deactivate_; - scoped_ptr<InputMethod> input_method_; // See |is_top_level()| accessor. |