fix: delay emitting NotifyIcon events on Windows (#26668)
* wip? * attempt to use weakptr * apply posttask change to other balloon events * chore: add clarifying comment on weakptr * refactor: move weakptr include to implementation (it's not needed in the header file) * refactor: use default initializer for weak factory * refactor: move weakptr usage outside of loop * fix: convert mouse events as well * refactor: use member function for balloon events * fix: check if wicon is truthy in callback * refactor: bind mouse events with member function * refactor: inline lparams * refactor: inline getkeyboardmodifiers() * chore: correct GetKeyboardModifiers typo
This commit is contained in:
parent
14c8e000cb
commit
36af8022ca
2 changed files with 33 additions and 9 deletions
|
@ -71,6 +71,8 @@ class NotifyIcon : public TrayIcon {
|
||||||
void SetContextMenu(ElectronMenuModel* menu_model) override;
|
void SetContextMenu(ElectronMenuModel* menu_model) override;
|
||||||
gfx::Rect GetBounds() override;
|
gfx::Rect GetBounds() override;
|
||||||
|
|
||||||
|
base::WeakPtr<NotifyIcon> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitIconData(NOTIFYICONDATA* icon_data);
|
void InitIconData(NOTIFYICONDATA* icon_data);
|
||||||
|
|
||||||
|
@ -101,6 +103,8 @@ class NotifyIcon : public TrayIcon {
|
||||||
// Context menu associated with this icon (if any).
|
// Context menu associated with this icon (if any).
|
||||||
std::unique_ptr<views::MenuRunner> menu_runner_;
|
std::unique_ptr<views::MenuRunner> menu_runner_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<NotifyIcon> weak_factory_{this};
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
|
DISALLOW_COPY_AND_ASSIGN(NotifyIcon);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "base/win/win_util.h"
|
#include "base/win/win_util.h"
|
||||||
#include "base/win/windows_types.h"
|
#include "base/win/windows_types.h"
|
||||||
#include "base/win/wrapped_window_proc.h"
|
#include "base/win/wrapped_window_proc.h"
|
||||||
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
#include "shell/browser/ui/win/notify_icon.h"
|
#include "shell/browser/ui/win/notify_icon.h"
|
||||||
#include "ui/events/event_constants.h"
|
#include "ui/events/event_constants.h"
|
||||||
#include "ui/events/win/system_event_state_lookup.h"
|
#include "ui/events/win/system_event_state_lookup.h"
|
||||||
|
@ -34,7 +36,7 @@ bool IsWinPressed() {
|
||||||
((::GetKeyState(VK_RWIN) & 0x8000) == 0x8000);
|
((::GetKeyState(VK_RWIN) & 0x8000) == 0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetKeyboardModifers() {
|
int GetKeyboardModifiers() {
|
||||||
int modifiers = ui::EF_NONE;
|
int modifiers = ui::EF_NONE;
|
||||||
if (ui::win::IsShiftPressed())
|
if (ui::win::IsShiftPressed())
|
||||||
modifiers |= ui::EF_SHIFT_DOWN;
|
modifiers |= ui::EF_SHIFT_DOWN;
|
||||||
|
@ -160,17 +162,29 @@ LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd,
|
||||||
if (!win_icon)
|
if (!win_icon)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
// We use a WeakPtr factory for NotifyIcons here so
|
||||||
|
// that the callback is aware if the NotifyIcon gets
|
||||||
|
// garbage-collected. This occurs when the tray gets
|
||||||
|
// GC'd, and the BALLOON events below will not emit.
|
||||||
|
base::WeakPtr<NotifyIcon> win_icon_weak = win_icon->GetWeakPtr();
|
||||||
|
|
||||||
switch (lparam) {
|
switch (lparam) {
|
||||||
case NIN_BALLOONSHOW:
|
case NIN_BALLOONSHOW:
|
||||||
win_icon->NotifyBalloonShow();
|
content::GetUIThreadTaskRunner({})->PostTask(
|
||||||
|
FROM_HERE,
|
||||||
|
base::BindOnce(&NotifyIcon::NotifyBalloonShow, win_icon_weak));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case NIN_BALLOONUSERCLICK:
|
case NIN_BALLOONUSERCLICK:
|
||||||
win_icon->NotifyBalloonClicked();
|
content::GetUIThreadTaskRunner({})->PostTask(
|
||||||
|
FROM_HERE,
|
||||||
|
base::BindOnce(&NotifyIcon::NotifyBalloonClicked, win_icon_weak));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case NIN_BALLOONTIMEOUT:
|
case NIN_BALLOONTIMEOUT:
|
||||||
win_icon->NotifyBalloonClosed();
|
content::GetUIThreadTaskRunner({})->PostTask(
|
||||||
|
FROM_HERE,
|
||||||
|
base::BindOnce(&NotifyIcon::NotifyBalloonClosed, win_icon_weak));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
@ -180,14 +194,20 @@ 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.
|
||||||
win_icon->HandleClickEvent(
|
content::GetUIThreadTaskRunner({})->PostTask(
|
||||||
GetKeyboardModifers(),
|
FROM_HERE,
|
||||||
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
|
base::BindOnce(
|
||||||
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK));
|
&NotifyIcon::HandleClickEvent, win_icon_weak,
|
||||||
|
GetKeyboardModifiers(),
|
||||||
|
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
|
||||||
|
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
win_icon->HandleMouseMoveEvent(GetKeyboardModifers());
|
content::GetUIThreadTaskRunner({})->PostTask(
|
||||||
|
FROM_HERE, base::BindOnce(&NotifyIcon::HandleMouseMoveEvent,
|
||||||
|
win_icon_weak, GetKeyboardModifiers()));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue