Index: ash/system/logout_button/logout_button_tray.cc |
diff --git a/ash/system/logout_button/logout_button_tray.cc b/ash/system/logout_button/logout_button_tray.cc |
index c06073040c5c26822b641ecb479f29c65cae088f..4d62ae48cf83d2b078915060986e813198149af2 100644 |
--- a/ash/system/logout_button/logout_button_tray.cc |
+++ b/ash/system/logout_button/logout_button_tray.cc |
@@ -6,12 +6,14 @@ |
#include "ash/shelf/shelf_types.h" |
#include "ash/shell.h" |
+#include "ash/system/logout_button/logout_confirmation_dialog_view.h" |
#include "ash/system/status_area_widget.h" |
#include "ash/system/tray/system_tray_delegate.h" |
#include "ash/system/tray/system_tray_notifier.h" |
#include "ash/system/tray/tray_constants.h" |
#include "ash/system/tray/tray_utils.h" |
#include "base/logging.h" |
+#include "base/message_loop/message_loop.h" |
#include "grit/ash_resources.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "ui/events/event.h" |
@@ -96,7 +98,6 @@ LogoutButton::~LogoutButton() { |
LogoutButtonTray::LogoutButtonTray(StatusAreaWidget* status_area_widget) |
: TrayBackgroundView(status_area_widget), |
- button_(NULL), |
login_status_(user::LOGGED_IN_NONE), |
show_logout_button_in_tray_(false) { |
button_ = new LogoutButton(this); |
@@ -106,10 +107,27 @@ LogoutButtonTray::LogoutButtonTray(StatusAreaWidget* status_area_widget) |
} |
LogoutButtonTray::~LogoutButtonTray() { |
+ EnsureConfirmationDialogIsClosed(); |
Shell::GetInstance()->system_tray_notifier()-> |
RemoveLogoutButtonObserver(this); |
} |
+void LogoutButtonTray::EnsureConfirmationDialogIsShowing() { |
+ if (!confirmation_dialog_) { |
+ confirmation_dialog_.reset(new LogoutConfirmationDialogView(this)); |
+ confirmation_dialog_->Show(dialog_duration_); |
+ } |
+} |
+ |
+void LogoutButtonTray::EnsureConfirmationDialogIsClosed() { |
+ if (confirmation_dialog_) { |
+ confirmation_dialog_->GetWidget()->Close(); |
bartfab (slow)
2013/11/20 18:00:44
Are you sure that closing the widget will not dest
|
+ LogoutConfirmationDialogView* dialog = UnbindWithConfirmationDialog(); |
+ if (dialog) |
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, dialog); |
+ } |
+} |
+ |
void LogoutButtonTray::SetShelfAlignment(ShelfAlignment alignment) { |
TrayBackgroundView::SetShelfAlignment(alignment); |
tray_container()->set_border(NULL); |
@@ -132,10 +150,20 @@ void LogoutButtonTray::OnShowLogoutButtonInTrayChanged(bool show) { |
UpdateVisibility(); |
} |
+void LogoutButtonTray::OnLogoutDialogDurationChanged(base::TimeDelta duration) { |
+ dialog_duration_ = duration; |
+ if (confirmation_dialog_) |
+ confirmation_dialog_->UpdateDialogDuration(dialog_duration_); |
+} |
+ |
void LogoutButtonTray::ButtonPressed(views::Button* sender, |
const ui::Event& event) { |
DCHECK_EQ(sender, button_); |
- Shell::GetInstance()->system_tray_delegate()->SignOut(); |
+ // Sign out immediately if kLogoutDialogDurationMs is non-positive. |
+ if (dialog_duration_ <= base::TimeDelta::FromSeconds(0)) |
+ Shell::GetInstance()->system_tray_delegate()->SignOut(); |
+ else |
+ EnsureConfirmationDialogIsShowing(); |
} |
void LogoutButtonTray::UpdateAfterLoginStatusChange( |
@@ -148,10 +176,25 @@ void LogoutButtonTray::UpdateAfterLoginStatusChange( |
UpdateVisibility(); |
} |
+LogoutConfirmationDialogView* LogoutButtonTray::UnbindWithConfirmationDialog() { |
+ // Use atomic operation to nullify two pointers. This function can be called |
+ // from both LogoutButtonTray and LogoutConfirmationDialogView, and the |
+ // destroy order of these two class doesn't matter now. Be careful this |
+ // function is not thread safe, and the dialog might not be destroyed yet. |
+ if (confirmation_dialog_) { |
+ LogoutConfirmationDialogView *dialog = confirmation_dialog_.release(); |
+ dialog->ClearOwner(); |
+ return dialog; |
+ } |
+ return NULL; |
+} |
+ |
void LogoutButtonTray::UpdateVisibility() { |
SetVisible(show_logout_button_in_tray_ && |
login_status_ != user::LOGGED_IN_NONE && |
login_status_ != user::LOGGED_IN_LOCKED); |
+ if (!show_logout_button_in_tray_) |
+ EnsureConfirmationDialogIsClosed(); |
} |
} // namespace internal |