Merge pull request #3660 from atom/tray-custom-menu
Add `menu` parameter for Tray.popUpContextMenu
This commit is contained in:
commit
4252c17db0
9 changed files with 53 additions and 27 deletions
|
@ -137,9 +137,11 @@ void Tray::DisplayBalloon(mate::Arguments* args,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tray::PopUpContextMenu(mate::Arguments* args) {
|
void Tray::PopUpContextMenu(mate::Arguments* args) {
|
||||||
|
mate::Handle<Menu> menu;
|
||||||
|
args->GetNext(&menu);
|
||||||
gfx::Point pos;
|
gfx::Point pos;
|
||||||
args->GetNext(&pos);
|
args->GetNext(&pos);
|
||||||
tray_icon_->PopUpContextMenu(pos);
|
tray_icon_->PopUpContextMenu(pos, menu.IsEmpty() ? nullptr : menu->model());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
|
void Tray::SetContextMenu(mate::Arguments* args, Menu* menu) {
|
||||||
|
|
|
@ -26,7 +26,8 @@ void TrayIcon::DisplayBalloon(const gfx::Image& icon,
|
||||||
const base::string16& contents) {
|
const base::string16& contents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::PopUpContextMenu(const gfx::Point& pos) {
|
void TrayIcon::PopUpContextMenu(const gfx::Point& pos,
|
||||||
|
ui::SimpleMenuModel* menu_model) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) {
|
void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) {
|
||||||
|
|
|
@ -47,7 +47,9 @@ class TrayIcon {
|
||||||
const base::string16& title,
|
const base::string16& title,
|
||||||
const base::string16& contents);
|
const base::string16& contents);
|
||||||
|
|
||||||
virtual void PopUpContextMenu(const gfx::Point& pos);
|
// Popups the menu.
|
||||||
|
virtual void PopUpContextMenu(const gfx::Point& pos,
|
||||||
|
ui::SimpleMenuModel* menu_model);
|
||||||
|
|
||||||
// Set the context menu for this icon.
|
// Set the context menu for this icon.
|
||||||
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0;
|
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0;
|
||||||
|
|
|
@ -29,7 +29,8 @@ class TrayIconCocoa : public TrayIcon,
|
||||||
void SetToolTip(const std::string& tool_tip) override;
|
void SetToolTip(const std::string& tool_tip) override;
|
||||||
void SetTitle(const std::string& title) override;
|
void SetTitle(const std::string& title) override;
|
||||||
void SetHighlightMode(bool highlight) override;
|
void SetHighlightMode(bool highlight) override;
|
||||||
void PopUpContextMenu(const gfx::Point& pos) override;
|
void PopUpContextMenu(const gfx::Point& pos,
|
||||||
|
ui::SimpleMenuModel* menu_model) override;
|
||||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -23,6 +23,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
atom::TrayIconCocoa* trayIcon_; // weak
|
atom::TrayIconCocoa* trayIcon_; // weak
|
||||||
AtomMenuController* menuController_; // weak
|
AtomMenuController* menuController_; // weak
|
||||||
BOOL isHighlightEnable_;
|
BOOL isHighlightEnable_;
|
||||||
|
BOOL forceHighlight_;
|
||||||
BOOL inMouseEventSequence_;
|
BOOL inMouseEventSequence_;
|
||||||
base::scoped_nsobject<NSImage> image_;
|
base::scoped_nsobject<NSImage> image_;
|
||||||
base::scoped_nsobject<NSImage> alternateImage_;
|
base::scoped_nsobject<NSImage> alternateImage_;
|
||||||
|
@ -39,6 +40,8 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
image_.reset([image copy]);
|
image_.reset([image copy]);
|
||||||
trayIcon_ = icon;
|
trayIcon_ = icon;
|
||||||
isHighlightEnable_ = YES;
|
isHighlightEnable_ = YES;
|
||||||
|
forceHighlight_ = NO;
|
||||||
|
inMouseEventSequence_ = NO;
|
||||||
|
|
||||||
if ((self = [super initWithFrame: CGRectZero])) {
|
if ((self = [super initWithFrame: CGRectZero])) {
|
||||||
// Setup the image view.
|
// Setup the image view.
|
||||||
|
@ -238,7 +241,19 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)popUpContextMenu {
|
- (void)popUpContextMenu:(ui::SimpleMenuModel*)menu_model {
|
||||||
|
// Show a custom menu.
|
||||||
|
if (menu_model) {
|
||||||
|
base::scoped_nsobject<AtomMenuController> menuController(
|
||||||
|
[[AtomMenuController alloc] initWithModel:menu_model]);
|
||||||
|
forceHighlight_ = YES; // Should highlight when showing menu.
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
[statusItem_ popUpStatusItemMenu:[menuController menu]];
|
||||||
|
forceHighlight_ = NO;
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (menuController_ && ![menuController_ isMenuOpen]) {
|
if (menuController_ && ![menuController_ isMenuOpen]) {
|
||||||
// Redraw the dray icon to show highlight if it is enabled.
|
// Redraw the dray icon to show highlight if it is enabled.
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
|
@ -288,6 +303,8 @@ const CGFloat kVerticalTitleMargin = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)shouldHighlight {
|
- (BOOL)shouldHighlight {
|
||||||
|
if (isHighlightEnable_ && forceHighlight_)
|
||||||
|
return true;
|
||||||
BOOL isMenuOpen = menuController_ && [menuController_ isMenuOpen];
|
BOOL isMenuOpen = menuController_ && [menuController_ isMenuOpen];
|
||||||
return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen);
|
return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen);
|
||||||
}
|
}
|
||||||
|
@ -338,8 +355,9 @@ void TrayIconCocoa::SetHighlightMode(bool highlight) {
|
||||||
[status_item_view_ setHighlight:highlight];
|
[status_item_view_ setHighlight:highlight];
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos) {
|
void TrayIconCocoa::PopUpContextMenu(const gfx::Point& pos,
|
||||||
[status_item_view_ popUpContextMenu];
|
ui::SimpleMenuModel* menu_model) {
|
||||||
|
[status_item_view_ popUpContextMenu:menu_model];
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "ui/gfx/image/image.h"
|
#include "ui/gfx/image/image.h"
|
||||||
#include "ui/gfx/geometry/point.h"
|
#include "ui/gfx/geometry/point.h"
|
||||||
#include "ui/gfx/geometry/rect.h"
|
#include "ui/gfx/geometry/rect.h"
|
||||||
|
#include "ui/gfx/screen.h"
|
||||||
#include "ui/views/controls/menu/menu_runner.h"
|
#include "ui/views/controls/menu/menu_runner.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -45,8 +46,7 @@ NotifyIcon::~NotifyIcon() {
|
||||||
Shell_NotifyIcon(NIM_DELETE, &icon_data);
|
Shell_NotifyIcon(NIM_DELETE, &icon_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
|
void NotifyIcon::HandleClickEvent(int modifiers,
|
||||||
int modifiers,
|
|
||||||
bool left_mouse_click,
|
bool left_mouse_click,
|
||||||
bool double_button_click) {
|
bool double_button_click) {
|
||||||
NOTIFYICONIDENTIFIER icon_id;
|
NOTIFYICONIDENTIFIER icon_id;
|
||||||
|
@ -66,7 +66,7 @@ void NotifyIcon::HandleClickEvent(const gfx::Point& cursor_pos,
|
||||||
return;
|
return;
|
||||||
} else if (!double_button_click) { // single right click
|
} else if (!double_button_click) { // single right click
|
||||||
if (menu_model_)
|
if (menu_model_)
|
||||||
PopUpContextMenu(cursor_pos);
|
PopUpContextMenu(gfx::Point(), menu_model_);
|
||||||
else
|
else
|
||||||
NotifyRightClicked(gfx::Rect(rect), modifiers);
|
NotifyRightClicked(gfx::Rect(rect), modifiers);
|
||||||
}
|
}
|
||||||
|
@ -142,24 +142,26 @@ void NotifyIcon::DisplayBalloon(const gfx::Image& icon,
|
||||||
LOG(WARNING) << "Unable to create status tray balloon.";
|
LOG(WARNING) << "Unable to create status tray balloon.";
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos) {
|
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
|
||||||
|
ui::SimpleMenuModel* menu_model) {
|
||||||
// Returns if context menu isn't set.
|
// Returns if context menu isn't set.
|
||||||
if (!menu_model_)
|
if (!menu_model)
|
||||||
return;
|
return;
|
||||||
// Set our window as the foreground window, so the context menu closes when
|
// Set our window as the foreground window, so the context menu closes when
|
||||||
// we click away from it.
|
// we click away from it.
|
||||||
if (!SetForegroundWindow(window_))
|
if (!SetForegroundWindow(window_))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Show menu at mouse's position by default.
|
||||||
|
gfx::Rect rect(pos, gfx::Size());
|
||||||
|
if (pos.IsOrigin())
|
||||||
|
rect.set_origin(gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
|
||||||
|
|
||||||
views::MenuRunner menu_runner(
|
views::MenuRunner menu_runner(
|
||||||
menu_model_,
|
menu_model,
|
||||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||||
ignore_result(menu_runner.RunMenuAt(
|
ignore_result(menu_runner.RunMenuAt(
|
||||||
NULL,
|
NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
|
||||||
NULL,
|
|
||||||
gfx::Rect(pos, gfx::Size()),
|
|
||||||
views::MENU_ANCHOR_TOPLEFT,
|
|
||||||
ui::MENU_SOURCE_MOUSE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
||||||
|
|
|
@ -33,8 +33,7 @@ class NotifyIcon : public TrayIcon {
|
||||||
// Handles a click event from the user - if |left_button_click| is true and
|
// Handles a click event from the user - if |left_button_click| is true and
|
||||||
// there is a registered observer, passes the click event to the observer,
|
// there is a registered observer, passes the click event to the observer,
|
||||||
// otherwise displays the context menu if there is one.
|
// otherwise displays the context menu if there is one.
|
||||||
void HandleClickEvent(const gfx::Point& cursor_pos,
|
void HandleClickEvent(int modifiers,
|
||||||
int modifiers,
|
|
||||||
bool left_button_click,
|
bool left_button_click,
|
||||||
bool double_button_click);
|
bool double_button_click);
|
||||||
|
|
||||||
|
@ -52,7 +51,8 @@ class NotifyIcon : public TrayIcon {
|
||||||
void DisplayBalloon(const gfx::Image& icon,
|
void DisplayBalloon(const gfx::Image& icon,
|
||||||
const base::string16& title,
|
const base::string16& title,
|
||||||
const base::string16& contents) override;
|
const base::string16& contents) override;
|
||||||
void PopUpContextMenu(const gfx::Point& pos) override;
|
void PopUpContextMenu(const gfx::Point& pos,
|
||||||
|
ui::SimpleMenuModel* menu_model) override;
|
||||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "base/win/win_util.h"
|
#include "base/win/win_util.h"
|
||||||
#include "base/win/wrapped_window_proc.h"
|
#include "base/win/wrapped_window_proc.h"
|
||||||
#include "ui/events/event_constants.h"
|
#include "ui/events/event_constants.h"
|
||||||
#include "ui/gfx/screen.h"
|
|
||||||
#include "ui/gfx/win/hwnd_util.h"
|
#include "ui/gfx/win/hwnd_util.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -172,10 +171,7 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd,
|
||||||
case WM_CONTEXTMENU:
|
case WM_CONTEXTMENU:
|
||||||
// Walk our icons, find which one was clicked on, and invoke its
|
// Walk our icons, find which one was clicked on, and invoke its
|
||||||
// HandleClickEvent() method.
|
// HandleClickEvent() method.
|
||||||
gfx::Point cursor_pos(
|
|
||||||
gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
|
|
||||||
win_icon->HandleClickEvent(
|
win_icon->HandleClickEvent(
|
||||||
cursor_pos,
|
|
||||||
GetKeyboardModifers(),
|
GetKeyboardModifers(),
|
||||||
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
|
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
|
||||||
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK));
|
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK));
|
||||||
|
|
|
@ -187,12 +187,16 @@ when the tray icon is clicked. Defaults to true.
|
||||||
|
|
||||||
Displays a tray balloon.
|
Displays a tray balloon.
|
||||||
|
|
||||||
### `Tray.popUpContextMenu([position])` _OS X_ _Windows_
|
### `Tray.popUpContextMenu([menu, position])` _OS X_ _Windows_
|
||||||
|
|
||||||
* `position` Object (optional)- The pop up position.
|
* `menu` Menu (optional)
|
||||||
|
* `position` Object (optional) - The pop up position.
|
||||||
* `x` Integer
|
* `x` Integer
|
||||||
* `y` Integer
|
* `y` Integer
|
||||||
|
|
||||||
|
Popups the context menu of tray icon. When `menu` is passed, the `menu` will
|
||||||
|
showed instead of the tray's context menu.
|
||||||
|
|
||||||
The `position` is only available on Windows, and it is (0, 0) by default.
|
The `position` is only available on Windows, and it is (0, 0) by default.
|
||||||
|
|
||||||
### `Tray.setContextMenu(menu)`
|
### `Tray.setContextMenu(menu)`
|
||||||
|
|
Loading…
Reference in a new issue