summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/system/tray/system_tray_bubble.cc31
-rw-r--r--ash/system/tray/system_tray_bubble.h10
-rw-r--r--ui/views/bubble/bubble_delegate.cc7
-rw-r--r--ui/views/bubble/bubble_delegate.h1
-rw-r--r--ui/views/widget/widget.cc25
-rw-r--r--ui/views/widget/widget.h9
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.