Skip to content

Commit

Permalink
Don't close menu(s) on certain operations
Browse files Browse the repository at this point in the history
In several cases we don't want menu(s) to close when an action on menu was
done. For example on drag-n-drop or menu item deletion (where confirmation
dialog is shown).

In such situations `s_bPreventClosing` was set to true (and then back to
false when closing was allowed again).
Though original code honored this variable only in certain situations and
typically (at least on Win10) menus were hidden/closed despite of it.

This patch changes the behavior and menus(s) are not closed when
`s_bPreventClosing` is set to true.
Basically now menu(s) stay visible until there is an action that changes
active window.

Following functionality was also removed because it is not needed now:

* CMenuContainer::HideTemp
* COwnerWindow::OnClear
  WM_CLEAR was sent to the window only by already removed `HideTemp`
  • Loading branch information
ge0rdi committed Oct 26, 2019
1 parent f33cd60 commit fe47f84
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 68 deletions.
4 changes: 0 additions & 4 deletions Src/StartMenu/StartMenuDLL/DragDrop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ bool CMenuContainer::DragOutApps( const CItemManager::ItemInfo *pInfo )
s_bDragFromTree=false;
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
HideTemp(false);
s_bPreventClosing=false;

if (s_bDragClosed)
Expand Down Expand Up @@ -343,7 +342,6 @@ bool CMenuContainer::DragOut( int index, bool bApp )
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
s_bDragMovable=false;
HideTemp(false);
s_bPreventClosing=false;

if (s_bDragClosed)
Expand Down Expand Up @@ -863,8 +861,6 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
s_bPreventClosing=true;
AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
if (!bOld)
HideTemp(false);
s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
Expand Down
7 changes: 1 addition & 6 deletions Src/StartMenu/StartMenuDLL/MenuCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2396,7 +2396,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
}
}
DestroyMenu(menu2);
HideTemp(false);
s_bPreventClosing=false;

PITEMID_CHILD newPidl=NULL;
Expand Down Expand Up @@ -2485,7 +2484,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
Invalidate();
if (m_HotItem<0) SetHotItem(index);
}
HideTemp(false);
s_bPreventClosing=false;
}
SetContextItem(-1);
Expand Down Expand Up @@ -2742,7 +2740,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
else
SetFocus();
}
HideTemp(false);
s_bPreventClosing=false;
s_HotPos=GetMessagePos();
res=CMD_RENAME;
Expand Down Expand Up @@ -2802,8 +2799,7 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
if (bRefresh || bRefreshMain)
info.fMask|=CMIC_MASK_NOASYNC; // wait for delete/link commands to finish so we can refresh the menu

if ((type!=ACTIVATE_MENU && type!=ACTIVATE_DELETE) || GetWinVersion()<WIN_VER_WIN8)
s_bPreventClosing=true;
s_bPreventClosing=true;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
(*it)->EnableWindow(FALSE); // disable all menus
bool bAllPrograms=s_bAllPrograms;
Expand Down Expand Up @@ -2880,7 +2876,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
else
SetFocus();
}
HideTemp(false);
s_bPreventClosing=false;

if (!bKeepOpen && !bRefresh && !bRefreshMain)
Expand Down
31 changes: 10 additions & 21 deletions Src/StartMenu/StartMenuDLL/MenuContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6365,11 +6365,6 @@ LRESULT CMenuContainer::OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
return 0;
}

void CMenuContainer::HideTemp( bool bHide )
{
::PostMessage(g_OwnerWindow,WM_CLEAR,bHide,0);
}

LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if (LOWORD(wParam)!=WA_INACTIVE)
Expand All @@ -6379,6 +6374,9 @@ LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
return 0;
}
#ifndef PREVENT_CLOSING
if (s_bPreventClosing)
return 0;

if (lParam)
{
// check if another menu window is being activated
Expand All @@ -6389,24 +6387,15 @@ LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO

if ((HWND)lParam==g_OwnerWindow || (HWND)lParam==g_TopWin7Menu)
return 0;

if (s_bPreventClosing && (::GetWindowLong((HWND)lParam,GWL_EXSTYLE)&WS_EX_TOPMOST))
return 0;
}

// a non-top-most window tries to activate while we are still here
if (s_bPreventClosing && (!g_TopWin7Menu || !s_bAllPrograms))
HideTemp(true);
else
{
for (std::vector<CMenuContainer*>::reverse_iterator it=s_Menus.rbegin();it!=s_Menus.rend();++it)
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->PostMessage(WM_CLOSE);
(*it)->m_bClosing=true;
}
if (g_TopWin7Menu && s_bAllPrograms) ::PostMessage(g_TopWin7Menu,WM_CLOSE,0,0);
}
for (std::vector<CMenuContainer*>::reverse_iterator it=s_Menus.rbegin();it!=s_Menus.rend();++it)
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->PostMessage(WM_CLOSE);
(*it)->m_bClosing=true;
}
if (g_TopWin7Menu && s_bAllPrograms) ::PostMessage(g_TopWin7Menu,WM_CLOSE,0,0);
#endif

return 0;
Expand Down
1 change: 0 additions & 1 deletion Src/StartMenu/StartMenuDLL/MenuContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,6 @@ class CMenuContainer: public IDropTarget, public IFrameworkInputPaneHandler, pub
friend LRESULT CALLBACK SubclassTopMenuProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData );
friend HRESULT CreatePinLink( PCIDLIST_ABSOLUTE sourcePidl, const wchar_t *name, const wchar_t *iconPath, int iconIndex );

static void HideTemp( bool bHide );
static void AddMRUShortcut( const wchar_t *path );
static void AddMRUAppId( const wchar_t *appid );
static void DeleteMRUShortcut( const wchar_t *path );
Expand Down
2 changes: 0 additions & 2 deletions Src/StartMenu/StartMenuDLL/ProgramsTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1601,8 +1601,6 @@ HRESULT CProgramsTree::Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt
CMenuContainer::s_bPreventClosing=true;
m_pOwner->AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
if (!bOld)
CMenuContainer::HideTemp(false);
CMenuContainer::s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=CMenuContainer::s_Menus.begin();it!=CMenuContainer::s_Menus.end();++it)
if (!(*it)->m_bDestroyed)
Expand Down
39 changes: 5 additions & 34 deletions Src/StartMenu/StartMenuDLL/StartMenuDLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ class COwnerWindow: public CWindowImpl<COwnerWindow>
// message handlers
BEGIN_MSG_MAP( COwnerWindow )
MESSAGE_HANDLER( WM_ACTIVATE, OnActivate )
MESSAGE_HANDLER( WM_CLEAR, OnClear )
MESSAGE_HANDLER( WM_SYSCOLORCHANGE, OnColorChange )
MESSAGE_HANDLER( WM_SETTINGCHANGE, OnSettingChange )
MESSAGE_HANDLER( WM_DISPLAYCHANGE, OnDisplayChange )
Expand All @@ -304,7 +303,7 @@ class COwnerWindow: public CWindowImpl<COwnerWindow>
if (LOWORD(wParam)!=WA_INACTIVE)
return 0;

if (CMenuContainer::s_bPreventClosing && lParam && (::GetWindowLongPtr((HWND)lParam,GWL_EXSTYLE)&WS_EX_TOPMOST))
if (CMenuContainer::s_bPreventClosing)
return 0;

// check if another menu window is being activated
Expand All @@ -313,42 +312,14 @@ class COwnerWindow: public CWindowImpl<COwnerWindow>
if ((*it)->m_hWnd==(HWND)lParam)
return 0;

if (CMenuContainer::s_bPreventClosing)
{
CMenuContainer::HideTemp(true);
}
else
{
for (std::vector<CMenuContainer*>::reverse_iterator it=CMenuContainer::s_Menus.rbegin();it!=CMenuContainer::s_Menus.rend();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);
}
return 0;
}
for (std::vector<CMenuContainer*>::reverse_iterator it=CMenuContainer::s_Menus.rbegin();it!=CMenuContainer::s_Menus.rend();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);

LRESULT OnClear( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
bool bHide=(wParam!=0); // hide or destroy
if (CMenuContainer::s_bTempHidden!=bHide)
{
CMenuContainer::s_bTempHidden=bHide;
if (bHide && CMenuContainer::s_UserPicture.m_hWnd)
CMenuContainer::s_UserPicture.ShowWindow(SW_HIDE);
for (std::vector<CMenuContainer*>::iterator it=CMenuContainer::s_Menus.begin();it!=CMenuContainer::s_Menus.end();++it)
{
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->m_bClosing=true;
if (!bHide)
(*it)->PostMessage(WM_CLOSE);
else
(*it)->ShowWindow(SW_HIDE);
}
}
}
return 0;
}


LRESULT OnColorChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
CMenuContainer::s_Skin.Hash=0;
Expand Down

0 comments on commit fe47f84

Please sign in to comment.