This source file includes following definitions.
- is_persistent_
- InitView
- bubble
- bubble_type
- bubble_view
- is_persistent
- tray_date_
- InitializeTrayItems
- CreateItems
- AddTrayItem
- RemoveTrayItem
- GetTrayItems
- ShowDefaultView
- ShowPersistentDefaultView
- ShowDetailedView
- SetDetailedViewCloseDelay
- HideDetailedView
- ShowNotificationView
- HideNotificationView
- UpdateAfterLoginStatusChange
- UpdateAfterShelfAlignmentChange
- SetHideNotifications
- ShouldShowShelf
- HasSystemBubble
- HasNotificationBubble
- GetSystemBubble
- IsAnyBubbleVisible
- IsMouseInNotificationBubble
- CloseSystemBubble
- GetHelpButtonView
- CloseNotificationBubbleForTest
- HasSystemBubbleType
- DestroySystemBubble
- DestroyNotificationBubble
- GetTrayXOffset
- ShowDefaultViewWithOffset
- ShowItems
- UpdateNotificationBubble
- UpdateWebNotifications
- SetShelfAlignment
- AnchorUpdated
- GetAccessibleNameForTray
- BubbleResized
- HideBubbleWithView
- ClickedOutsideBubble
- BubbleViewDestroyed
- OnMouseEnteredView
- OnMouseExitedView
- GetAccessibleNameForBubble
- GetAnchorRect
- HideBubble
- GetTrayItemViewForTest
- GetTrayDateForTesting
- PerformAction
- CloseSystemBubbleAndDeactivateSystemTray
#include "ash/system/tray/system_tray.h"
#include "ash/ash_switches.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/shell/panel_window.h"
#include "ash/shell_window_ids.h"
#include "ash/system/audio/tray_audio.h"
#include "ash/system/bluetooth/tray_bluetooth.h"
#include "ash/system/date/tray_date.h"
#include "ash/system/drive/tray_drive.h"
#include "ash/system/ime/tray_ime.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray_item.h"
#include "ash/system/tray/tray_bubble_wrapper.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray_accessibility.h"
#include "ash/system/tray_update.h"
#include "ash/system/user/login_status.h"
#include "ash/system/user/tray_user.h"
#include "ash/system/user/tray_user_separator.h"
#include "ash/system/web_notification/web_notification_tray.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/timer/timer.h"
#include "grit/ash_strings.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#if defined(OS_CHROMEOS)
#include "ash/system/chromeos/audio/tray_audio_chromeos.h"
#include "ash/system/chromeos/brightness/tray_brightness.h"
#include "ash/system/chromeos/enterprise/tray_enterprise.h"
#include "ash/system/chromeos/managed/tray_locally_managed_user.h"
#include "ash/system/chromeos/network/tray_network.h"
#include "ash/system/chromeos/network/tray_sms.h"
#include "ash/system/chromeos/network/tray_vpn.h"
#include "ash/system/chromeos/power/tray_power.h"
#include "ash/system/chromeos/screen_security/screen_capture_tray_item.h"
#include "ash/system/chromeos/screen_security/screen_share_tray_item.h"
#include "ash/system/chromeos/session/tray_session_length_limit.h"
#include "ash/system/chromeos/settings/tray_settings.h"
#include "ash/system/chromeos/tray_caps_lock.h"
#include "ash/system/chromeos/tray_display.h"
#include "ash/system/chromeos/tray_tracing.h"
#include "ui/message_center/message_center.h"
#elif defined(OS_WIN)
#include "ash/system/win/audio/tray_audio_win.h"
#include "media/audio/win/core_audio_util_win.h"
#endif
using views::TrayBubbleView;
namespace ash {
const int kMinimumSystemTrayMenuWidth = 300;
class SystemBubbleWrapper {
public:
explicit SystemBubbleWrapper(SystemTrayBubble* bubble)
: bubble_(bubble), is_persistent_(false) {}
void InitView(TrayBackgroundView* tray,
views::View* anchor,
TrayBubbleView::InitParams* init_params,
bool is_persistent) {
DCHECK(anchor);
user::LoginStatus login_status =
Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus();
bubble_->InitView(anchor, login_status, init_params);
bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_->bubble_view()));
if (ash::switches::UseAlternateShelfLayout()) {
bubble_->bubble_view()->SetArrowPaintType(
views::BubbleBorder::PAINT_NONE);
}
is_persistent_ = is_persistent;
if (Shell::GetInstance()->accessibility_delegate()->
IsSpokenFeedbackEnabled()) {
bubble_->FocusDefaultIfNeeded();
}
}
SystemTrayBubble* bubble() const { return bubble_.get(); }
SystemTrayBubble::BubbleType bubble_type() const {
return bubble_->bubble_type();
}
TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); }
bool is_persistent() const { return is_persistent_; }
private:
scoped_ptr<SystemTrayBubble> bubble_;
scoped_ptr<TrayBubbleWrapper> bubble_wrapper_;
bool is_persistent_;
DISALLOW_COPY_AND_ASSIGN(SystemBubbleWrapper);
};
SystemTray::SystemTray(StatusAreaWidget* status_area_widget)
: TrayBackgroundView(status_area_widget),
items_(),
default_bubble_height_(0),
hide_notifications_(false),
full_system_tray_menu_(false),
tray_accessibility_(NULL),
tray_date_(NULL) {
SetContentsBackground();
}
SystemTray::~SystemTray() {
system_bubble_.reset();
notification_bubble_.reset();
for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
it != items_.end();
++it) {
(*it)->DestroyTrayView();
}
}
void SystemTray::InitializeTrayItems(SystemTrayDelegate* delegate) {
TrayBackgroundView::Initialize();
CreateItems(delegate);
}
void SystemTray::CreateItems(SystemTrayDelegate* delegate) {
#if defined(OS_CHROMEOS)
AddTrayItem(new TraySessionLengthLimit(this));
#endif
#if !defined(OS_WIN)
ash::Shell* shell = ash::Shell::GetInstance();
int maximum_user_profiles =
shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers();
for (int i = 0; i < maximum_user_profiles; i++)
AddTrayItem(new TrayUser(this, i));
if (maximum_user_profiles > 1) {
AddTrayItem(new TrayUserSeparator(this));
}
#endif
tray_accessibility_ = new TrayAccessibility(this);
tray_date_ = new TrayDate(this);
#if defined(OS_CHROMEOS)
AddTrayItem(new TrayEnterprise(this));
AddTrayItem(new TrayLocallyManagedUser(this));
AddTrayItem(new TrayIME(this));
AddTrayItem(tray_accessibility_);
AddTrayItem(new TrayTracing(this));
AddTrayItem(new TrayPower(this, message_center::MessageCenter::Get()));
AddTrayItem(new TrayNetwork(this));
AddTrayItem(new TrayVPN(this));
AddTrayItem(new TraySms(this));
AddTrayItem(new TrayBluetooth(this));
AddTrayItem(new TrayDrive(this));
AddTrayItem(new TrayDisplay(this));
AddTrayItem(new ScreenCaptureTrayItem(this));
AddTrayItem(new ScreenShareTrayItem(this));
AddTrayItem(new TrayAudioChromeOs(this));
AddTrayItem(new TrayBrightness(this));
AddTrayItem(new TrayCapsLock(this));
AddTrayItem(new TraySettings(this));
AddTrayItem(new TrayUpdate(this));
AddTrayItem(tray_date_);
#elif defined(OS_WIN)
AddTrayItem(tray_accessibility_);
if (media::CoreAudioUtil::IsSupported())
AddTrayItem(new TrayAudioWin(this));
AddTrayItem(new TrayUpdate(this));
AddTrayItem(tray_date_);
#elif defined(OS_LINUX)
AddTrayItem(new TrayIME(this));
AddTrayItem(tray_accessibility_);
AddTrayItem(new TrayBluetooth(this));
AddTrayItem(new TrayDrive(this));
AddTrayItem(new TrayUpdate(this));
AddTrayItem(tray_date_);
#endif
SetVisible(ash::Shell::GetInstance()->system_tray_delegate()->
GetTrayVisibilityOnStartup());
}
void SystemTray::AddTrayItem(SystemTrayItem* item) {
items_.push_back(item);
SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
views::View* tray_item = item->CreateTrayView(delegate->GetUserLoginStatus());
item->UpdateAfterShelfAlignmentChange(shelf_alignment());
if (tray_item) {
tray_container()->AddChildViewAt(tray_item, 0);
PreferredSizeChanged();
tray_item_map_[item] = tray_item;
}
}
void SystemTray::RemoveTrayItem(SystemTrayItem* item) {
NOTIMPLEMENTED();
}
const std::vector<SystemTrayItem*>& SystemTray::GetTrayItems() const {
return items_.get();
}
void SystemTray::ShowDefaultView(BubbleCreationType creation_type) {
ShowDefaultViewWithOffset(
creation_type,
TrayBubbleView::InitParams::kArrowDefaultOffset,
false);
}
void SystemTray::ShowPersistentDefaultView() {
ShowItems(items_.get(),
false,
false,
BUBBLE_CREATE_NEW,
TrayBubbleView::InitParams::kArrowDefaultOffset,
true);
}
void SystemTray::ShowDetailedView(SystemTrayItem* item,
int close_delay,
bool activate,
BubbleCreationType creation_type) {
std::vector<SystemTrayItem*> items;
items.push_back(item);
ShowItems(items, true, activate, creation_type, GetTrayXOffset(item), false);
if (system_bubble_)
system_bubble_->bubble()->StartAutoCloseTimer(close_delay);
}
void SystemTray::SetDetailedViewCloseDelay(int close_delay) {
if (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DETAILED))
system_bubble_->bubble()->StartAutoCloseTimer(close_delay);
}
void SystemTray::HideDetailedView(SystemTrayItem* item) {
if (item != detailed_item_)
return;
DestroySystemBubble();
UpdateNotificationBubble();
}
void SystemTray::ShowNotificationView(SystemTrayItem* item) {
if (std::find(notification_items_.begin(), notification_items_.end(), item)
!= notification_items_.end())
return;
notification_items_.push_back(item);
UpdateNotificationBubble();
}
void SystemTray::HideNotificationView(SystemTrayItem* item) {
std::vector<SystemTrayItem*>::iterator found_iter =
std::find(notification_items_.begin(), notification_items_.end(), item);
if (found_iter == notification_items_.end())
return;
notification_items_.erase(found_iter);
if (notification_bubble_)
UpdateNotificationBubble();
}
void SystemTray::UpdateAfterLoginStatusChange(user::LoginStatus login_status) {
DestroySystemBubble();
UpdateNotificationBubble();
for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
it != items_.end();
++it) {
(*it)->UpdateAfterLoginStatusChange(login_status);
}
if (shelf_alignment() != SHELF_ALIGNMENT_BOTTOM)
UpdateAfterShelfAlignmentChange(shelf_alignment());
SetVisible(true);
PreferredSizeChanged();
}
void SystemTray::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
for (std::vector<SystemTrayItem*>::iterator it = items_.begin();
it != items_.end();
++it) {
(*it)->UpdateAfterShelfAlignmentChange(alignment);
}
}
void SystemTray::SetHideNotifications(bool hide_notifications) {
if (notification_bubble_)
notification_bubble_->bubble()->SetVisible(!hide_notifications);
hide_notifications_ = hide_notifications;
}
bool SystemTray::ShouldShowShelf() const {
return system_bubble_.get() && system_bubble_->bubble()->ShouldShowShelf();
}
bool SystemTray::HasSystemBubble() const {
return system_bubble_.get() != NULL;
}
bool SystemTray::HasNotificationBubble() const {
return notification_bubble_.get() != NULL;
}
SystemTrayBubble* SystemTray::GetSystemBubble() {
if (!system_bubble_)
return NULL;
return system_bubble_->bubble();
}
bool SystemTray::IsAnyBubbleVisible() const {
return ((system_bubble_.get() &&
system_bubble_->bubble()->IsVisible()) ||
(notification_bubble_.get() &&
notification_bubble_->bubble()->IsVisible()));
}
bool SystemTray::IsMouseInNotificationBubble() const {
if (!notification_bubble_)
return false;
return notification_bubble_->bubble_view()->GetBoundsInScreen().Contains(
Shell::GetScreen()->GetCursorScreenPoint());
}
bool SystemTray::CloseSystemBubble() const {
if (!system_bubble_)
return false;
system_bubble_->bubble()->Close();
return true;
}
views::View* SystemTray::GetHelpButtonView() const {
return tray_date_->GetHelpButtonView();
}
bool SystemTray::CloseNotificationBubbleForTest() const {
if (!notification_bubble_)
return false;
notification_bubble_->bubble()->Close();
return true;
}
bool SystemTray::HasSystemBubbleType(SystemTrayBubble::BubbleType type) {
DCHECK(type != SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION);
return system_bubble_.get() && system_bubble_->bubble_type() == type;
}
void SystemTray::DestroySystemBubble() {
CloseSystemBubbleAndDeactivateSystemTray();
detailed_item_ = NULL;
UpdateWebNotifications();
}
void SystemTray::DestroyNotificationBubble() {
if (notification_bubble_) {
notification_bubble_.reset();
UpdateWebNotifications();
}
}
int SystemTray::GetTrayXOffset(SystemTrayItem* item) const {
if (shelf_alignment() != SHELF_ALIGNMENT_BOTTOM &&
shelf_alignment() != SHELF_ALIGNMENT_TOP)
return TrayBubbleView::InitParams::kArrowDefaultOffset;
std::map<SystemTrayItem*, views::View*>::const_iterator it =
tray_item_map_.find(item);
if (it == tray_item_map_.end())
return TrayBubbleView::InitParams::kArrowDefaultOffset;
const views::View* item_view = it->second;
if (item_view->bounds().IsEmpty()) {
return TrayBubbleView::InitParams::kArrowDefaultOffset;
}
gfx::Point point(item_view->width() / 2, 0);
ConvertPointToWidget(item_view, &point);
return point.x();
}
void SystemTray::ShowDefaultViewWithOffset(BubbleCreationType creation_type,
int arrow_offset,
bool persistent) {
if (creation_type != BUBBLE_USE_EXISTING) {
Shell::GetInstance()->metrics()->RecordUserMetricsAction(
ash::UMA_STATUS_AREA_MENU_OPENED);
}
ShowItems(items_.get(), false, true, creation_type, arrow_offset, persistent);
}
void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
bool detailed,
bool can_activate,
BubbleCreationType creation_type,
int arrow_offset,
bool persistent) {
if (Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() ==
ash::user::LOGGED_IN_KIOSK_APP) {
return;
}
SystemTrayBubble::BubbleType bubble_type = detailed ?
SystemTrayBubble::BUBBLE_TYPE_DETAILED :
SystemTrayBubble::BUBBLE_TYPE_DEFAULT;
notification_bubble_.reset();
if (system_bubble_.get() && creation_type == BUBBLE_USE_EXISTING) {
system_bubble_->bubble()->UpdateView(items, bubble_type);
if (Shell::GetInstance()->accessibility_delegate()->
IsSpokenFeedbackEnabled()) {
system_bubble_->bubble()->FocusDefaultIfNeeded();
}
} else {
full_system_tray_menu_ = items.size() > 1;
int menu_width = std::max(kMinimumSystemTrayMenuWidth,
Shell::GetInstance()->system_tray_delegate()->GetSystemTrayMenuWidth());
TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY,
GetAnchorAlignment(),
menu_width,
kTrayPopupMaxWidth);
init_params.can_activate = can_activate;
init_params.first_item_has_no_margin =
ash::switches::UseAlternateShelfLayout();
if (detailed) {
init_params.max_height = default_bubble_height_;
init_params.arrow_color = kBackgroundColor;
} else {
init_params.arrow_color = kHeaderBackgroundColor;
}
init_params.arrow_offset = arrow_offset;
if (bubble_type == SystemTrayBubble::BUBBLE_TYPE_DEFAULT)
init_params.close_on_deactivate = !persistent;
init_params.arrow_paint_type = views::BubbleBorder::PAINT_NORMAL;
if (items.size() == 1 && items[0]->ShouldHideArrow())
init_params.arrow_paint_type = views::BubbleBorder::PAINT_TRANSPARENT;
SystemTrayBubble* bubble = new SystemTrayBubble(this, items, bubble_type);
system_bubble_.reset(new SystemBubbleWrapper(bubble));
system_bubble_->InitView(this, tray_container(), &init_params, persistent);
}
if (!detailed)
default_bubble_height_ = system_bubble_->bubble_view()->height();
if (detailed && items.size() > 0)
detailed_item_ = items[0];
else
detailed_item_ = NULL;
UpdateNotificationBubble();
if (!notification_bubble_)
UpdateWebNotifications();
GetShelfLayoutManager()->UpdateAutoHideState();
if (full_system_tray_menu_)
SetDrawBackgroundAsActive(true);
}
void SystemTray::UpdateNotificationBubble() {
if (notification_items_.empty()) {
DestroyNotificationBubble();
return;
}
notification_bubble_.reset();
SystemTrayBubble* notification_bubble;
notification_bubble = new SystemTrayBubble(
this, notification_items_, SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION);
views::View* anchor;
TrayBubbleView::AnchorType anchor_type;
if (system_bubble_.get() &&
system_bubble_->bubble_view() &&
system_bubble_->bubble_view()->GetWidget()) {
anchor = system_bubble_->bubble_view();
anchor_type = TrayBubbleView::ANCHOR_TYPE_BUBBLE;
} else {
anchor = tray_container();
anchor_type = TrayBubbleView::ANCHOR_TYPE_TRAY;
}
TrayBubbleView::InitParams init_params(anchor_type,
GetAnchorAlignment(),
kTrayPopupMinWidth,
kTrayPopupMaxWidth);
init_params.first_item_has_no_margin =
ash::switches::UseAlternateShelfLayout();
init_params.arrow_color = kBackgroundColor;
init_params.arrow_offset = GetTrayXOffset(notification_items_[0]);
notification_bubble_.reset(new SystemBubbleWrapper(notification_bubble));
notification_bubble_->InitView(this, anchor, &init_params, false);
if (notification_bubble->bubble_view()->child_count() == 0) {
DestroyNotificationBubble();
return;
}
if (hide_notifications_)
notification_bubble->SetVisible(false);
else
UpdateWebNotifications();
}
void SystemTray::UpdateWebNotifications() {
TrayBubbleView* bubble_view = NULL;
if (notification_bubble_)
bubble_view = notification_bubble_->bubble_view();
else if (system_bubble_)
bubble_view = system_bubble_->bubble_view();
int height = 0;
if (bubble_view) {
gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
bubble_view->GetWidget()->GetNativeView()).work_area();
if (GetShelfLayoutManager()->GetAlignment() != SHELF_ALIGNMENT_TOP) {
height = std::max(
0, work_area.height() - bubble_view->GetBoundsInScreen().y());
} else {
height = std::max(
0, bubble_view->GetBoundsInScreen().bottom() - work_area.y());
}
}
status_area_widget()->web_notification_tray()->SetSystemTrayHeight(height);
}
void SystemTray::SetShelfAlignment(ShelfAlignment alignment) {
if (alignment == shelf_alignment())
return;
TrayBackgroundView::SetShelfAlignment(alignment);
UpdateAfterShelfAlignmentChange(alignment);
CloseSystemBubbleAndDeactivateSystemTray();
if (notification_bubble_) {
notification_bubble_.reset();
UpdateNotificationBubble();
}
}
void SystemTray::AnchorUpdated() {
if (notification_bubble_) {
notification_bubble_->bubble_view()->UpdateBubble();
notification_bubble_->bubble_view()->GetWidget()->StackAtTop();
UpdateBubbleViewArrow(notification_bubble_->bubble_view());
}
if (system_bubble_) {
system_bubble_->bubble_view()->UpdateBubble();
UpdateBubbleViewArrow(system_bubble_->bubble_view());
}
}
base::string16 SystemTray::GetAccessibleNameForTray() {
return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
}
void SystemTray::BubbleResized(const TrayBubbleView* bubble_view) {
UpdateWebNotifications();
}
void SystemTray::HideBubbleWithView(const TrayBubbleView* bubble_view) {
if (system_bubble_.get() && bubble_view == system_bubble_->bubble_view()) {
DestroySystemBubble();
UpdateNotificationBubble();
GetShelfLayoutManager()->UpdateAutoHideState();
} else if (notification_bubble_.get() &&
bubble_view == notification_bubble_->bubble_view()) {
DestroyNotificationBubble();
}
}
bool SystemTray::ClickedOutsideBubble() {
if (!system_bubble_ || system_bubble_->is_persistent())
return false;
HideBubbleWithView(system_bubble_->bubble_view());
return true;
}
void SystemTray::BubbleViewDestroyed() {
if (system_bubble_) {
system_bubble_->bubble()->DestroyItemViews();
system_bubble_->bubble()->BubbleViewDestroyed();
}
}
void SystemTray::OnMouseEnteredView() {
if (system_bubble_)
system_bubble_->bubble()->StopAutoCloseTimer();
}
void SystemTray::OnMouseExitedView() {
if (system_bubble_)
system_bubble_->bubble()->RestartAutoCloseTimer();
}
base::string16 SystemTray::GetAccessibleNameForBubble() {
return GetAccessibleNameForTray();
}
gfx::Rect SystemTray::GetAnchorRect(
views::Widget* anchor_widget,
TrayBubbleView::AnchorType anchor_type,
TrayBubbleView::AnchorAlignment anchor_alignment) {
return GetBubbleAnchorRect(anchor_widget, anchor_type, anchor_alignment);
}
void SystemTray::HideBubble(const TrayBubbleView* bubble_view) {
HideBubbleWithView(bubble_view);
}
views::View* SystemTray::GetTrayItemViewForTest(SystemTrayItem* item) {
std::map<SystemTrayItem*, views::View*>::iterator it =
tray_item_map_.find(item);
return it == tray_item_map_.end() ? NULL : it->second;
}
TrayDate* SystemTray::GetTrayDateForTesting() const { return tray_date_; }
bool SystemTray::PerformAction(const ui::Event& event) {
if (HasSystemBubbleType(SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) {
system_bubble_->bubble()->Close();
} else {
int arrow_offset = TrayBubbleView::InitParams::kArrowDefaultOffset;
if (event.IsMouseEvent() || event.type() == ui::ET_GESTURE_TAP) {
const ui::LocatedEvent& located_event =
static_cast<const ui::LocatedEvent&>(event);
if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM ||
shelf_alignment() == SHELF_ALIGNMENT_TOP) {
gfx::Point point(located_event.x(), 0);
ConvertPointToWidget(this, &point);
arrow_offset = point.x();
}
}
ShowDefaultViewWithOffset(BUBBLE_CREATE_NEW, arrow_offset, false);
}
return true;
}
void SystemTray::CloseSystemBubbleAndDeactivateSystemTray() {
system_bubble_.reset();
if (full_system_tray_menu_) {
SetDrawBackgroundAsActive(false);
full_system_tray_menu_ = false;
}
}
}