Add wxTaskBarIcon::GetPopupMenu()

This is similar to CreatePopupMenu(), but the menu pointer returned by
the new function won't be deleted by wxWidgets, allowing it to return
the same pointer every time it is called.

Closes #18886.
This commit is contained in:
Andreas Falkenhahn
2020-08-14 19:30:46 +02:00
committed by Vadim Zeitlin
parent 5a27ea9a86
commit c70a8261cb
4 changed files with 55 additions and 9 deletions

View File

@@ -62,6 +62,9 @@ protected:
// creates menu to be displayed when user clicks on the icon
virtual wxMenu *CreatePopupMenu() { return NULL; }
// same as CreatePopupMenu but won't destroy the menu
virtual wxMenu *GetPopupMenu() { return NULL; }
private:
// default events handling, calls CreatePopupMenu:
void OnRightButtonDown(wxTaskBarIconEvent& event);

View File

@@ -62,8 +62,9 @@ public:
@beginEventEmissionTable{wxTaskBarIconEvent}
Note that not all ports are required to send these events and so it's better
to override wxTaskBarIcon::CreatePopupMenu() if all that the application does
is that it shows a popup menu in reaction to mouse click.
to override wxTaskBarIcon::CreatePopupMenu() or wxTaskBarIcon::GetPopupMenu()
if all that the application does is that it shows a popup menu in reaction to
mouse click.
@event{EVT_TASKBAR_MOVE(func)}
Process a @c wxEVT_TASKBAR_MOVE event.
@event{EVT_TASKBAR_LEFT_DOWN(func)}
@@ -123,9 +124,10 @@ public:
The events can be handled by a class derived from wxTaskBarIcon.
@note
It is recommended to override CreatePopupMenu() callback instead of
calling this method from event handler, because some ports (e.g. wxCocoa)
may not implement PopupMenu() and mouse click events at all.
It is recommended to override the CreatePopupMenu() or GetPopupMenu()
callback instead of calling this method from event handler, because some
ports (e.g. wxCocoa) may not implement PopupMenu() and mouse click events
at all.
*/
virtual bool PopupMenu(wxMenu* menu);
@@ -172,11 +174,25 @@ protected:
Override this function in order to provide popup menu associated with the icon.
If CreatePopupMenu() returns @NULL (this happens by default), no menu is shown,
otherwise the menu is displayed and then deleted by the library as soon as the
user dismisses it.
user dismisses it. If you don't want the menu to get destroyed when it is dismissed,
override GetPopupMenu() instead.
The events can be handled by a class derived from wxTaskBarIcon.
*/
virtual wxMenu* CreatePopupMenu();
/**
This method is called by the library when the user requests popup menu
(on Windows and Unix platforms, this is when the user right-clicks the icon).
Override this function in order to provide popup menu associated with the icon.
If GetPopupMenu() returns @NULL (this happens by default), no menu is shown,
otherwise the menu is displayed. In contrast to CreatePopupMenu(), GetPopupMenu()
won't destroy the menu once the user dismisses it.
The events can be handled by a class derived from wxTaskBarIcon.
*/
virtual wxMenu* GetPopupMenu();
};

View File

@@ -53,6 +53,13 @@ void wxTaskBarIconBase::OnRightButtonDown(wxTaskBarIconEvent& WXUNUSED(event))
PopupMenu(menu);
delete menu;
}
else
{
menu = GetPopupMenu();
if (menu)
PopupMenu(menu);
}
}
void wxTaskBarIconBase::Destroy()

View File

@@ -68,6 +68,8 @@ public:
inline wxTaskBarIcon* GetTaskBarIcon() { return m_taskBarIcon; }
wxMenu * CreatePopupMenu()
{ return m_taskBarIcon->CreatePopupMenu(); }
wxMenu * GetPopupMenu()
{ return m_taskBarIcon->GetPopupMenu(); }
wxDECLARE_NO_COPY_CLASS(wxTaskBarIconImpl);
@@ -100,6 +102,7 @@ protected:
private:
wxTaskBarIconDockImpl();
wxMenu *m_pMenu;
bool m_keepMenu;
};
class wxTaskBarIconCustomStatusItemImpl;
@@ -228,6 +231,7 @@ wxTaskBarIconDockImpl::wxTaskBarIconDockImpl(wxTaskBarIcon *taskBarIcon)
wxASSERT_MSG(!sm_dockIcon, wxT("You should never have more than one dock icon!"));
sm_dockIcon = this;
m_pMenu = NULL;
m_keepMenu = false;
}
wxTaskBarIconDockImpl::~wxTaskBarIconDockImpl()
@@ -247,13 +251,27 @@ WX_NSMenu wxTaskBarIconDockImpl::OSXGetDockHMenu()
WX_NSMenu wxTaskBarIconDockImpl::OSXDoGetDockHMenu()
{
wxMenu *dockMenu = CreatePopupMenu();
bool keepMenu;
if(!dockMenu)
return nil;
{
dockMenu = GetPopupMenu();
wxDELETE(m_pMenu);
if(!dockMenu)
return nil;
keepMenu = true;
}
else
{
keepMenu = false;
}
if(!m_keepMenu)
wxDELETE(m_pMenu);
m_pMenu = dockMenu;
m_keepMenu = keepMenu;
m_pMenu->SetInvokingWindow(m_eventWindow);
@@ -271,7 +289,9 @@ bool wxTaskBarIconDockImpl::SetIcon(const wxIcon& icon, const wxString& WXUNUSED
bool wxTaskBarIconDockImpl::RemoveIcon()
{
wxDELETE(m_pMenu);
if(!m_keepMenu)
wxDELETE(m_pMenu);
m_icon = wxBitmap();
[[NSApplication sharedApplication] setApplicationIconImage:nil];
return true;