Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make tray not block main process #19036

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions atom/browser/ui/tray_icon_cocoa.h
Expand Up @@ -29,6 +29,7 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
void SetHighlightMode(TrayIcon::HighlightMode mode) override;
void SetIgnoreDoubleClickEvents(bool ignore) override;
bool GetIgnoreDoubleClickEvents() override;
void PopUpOnUI(AtomMenuModel* menu_model);
void PopUpContextMenu(const gfx::Point& pos,
AtomMenuModel* menu_model) override;
void SetContextMenu(AtomMenuModel* menu_model) override;
Expand All @@ -48,6 +49,8 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
// Used for unregistering observer.
AtomMenuModel* menu_model_ = nullptr; // weak ref.

base::WeakPtrFactory<TrayIconCocoa> weak_factory_;

DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa);
};

Expand Down
23 changes: 21 additions & 2 deletions atom/browser/ui/tray_icon_cocoa.mm
Expand Up @@ -8,7 +8,11 @@
#include "atom/browser/ui/cocoa/NSString+ANSI.h"
#include "atom/browser/ui/cocoa/atom_menu_controller.h"
#include "base/mac/sdk_forward_declarations.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ui/display/screen.h"
#include "ui/events/cocoa/cocoa_event_utils.h"
#include "ui/gfx/image/image.h"
Expand Down Expand Up @@ -326,22 +330,30 @@ - (void)mouseUp:(NSEvent*)event {
}

- (void)popUpContextMenu:(atom::AtomMenuModel*)menu_model {
// Make sure events can be pumped while the menu is up.
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;

// Show a custom menu.
if (menu_model) {
base::scoped_nsobject<AtomMenuController> menuController(
[[AtomMenuController alloc] initWithModel:menu_model
useDefaultAccelerator:NO]);
forceHighlight_ = YES; // Should highlight when showing menu.
[self setNeedsDisplay:YES];

[statusItem_ popUpStatusItemMenu:[menuController menu]];
forceHighlight_ = NO;
[self setNeedsDisplay:YES];
return;
}

if (menuController_ && ![menuController_ isMenuOpen]) {
// Ensure the UI can update while the menu is fading out.
base::ScopedPumpMessagesInPrivateModes pump_private;

// Redraw the tray icon to show highlight if it is enabled.
[self setNeedsDisplay:YES];

[statusItem_ popUpStatusItemMenu:[menuController_ menu]];
// The popUpStatusItemMenu returns only after the showing menu is closed.
// When it returns, we need to redraw the tray icon to not show highlight.
Expand Down Expand Up @@ -439,7 +451,7 @@ - (BOOL)shouldHighlight {

namespace atom {

TrayIconCocoa::TrayIconCocoa() {
TrayIconCocoa::TrayIconCocoa() : weak_factory_(this) {
status_item_view_.reset([[StatusItemView alloc] initWithIcon:this]);
}

Expand Down Expand Up @@ -477,9 +489,16 @@ - (BOOL)shouldHighlight {
return [status_item_view_ getIgnoreDoubleClickEvents];
}

void TrayIconCocoa::PopUpOnUI(AtomMenuModel* menu_model) {
[status_item_view_ popUpContextMenu:menu_model];
}

void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
AtomMenuModel* menu_model) {
[status_item_view_ popUpContextMenu:menu_model];
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&TrayIconCocoa::PopUpOnUI, weak_factory_.GetWeakPtr(),
base::Unretained(menu_model)));
}

void TrayIconCocoa::SetContextMenu(AtomMenuModel* menu_model) {
Expand Down