Implement dismissal for unfocused wxPopupTransientWindow
Popups not using wxPU_CONTAINS_CONTROLS were not automatically dismissed at all any longer, as the only auto-dismissal mechanism related on getting WM_ACTIVATE, which they never did, so implement a different logic for dismissing them: do it on any change of focus and also any mouse press (but not move and not key press neither). This will allow not using wxPU_CONTAINS_CONTROLS for popups that don't need focus, but still must disappear on their own.
This commit is contained in:
@@ -40,6 +40,10 @@ public:
|
||||
// Return the top level window parent of this popup or null.
|
||||
wxWindow* MSWGetOwner() const { return m_owner; }
|
||||
|
||||
// This is a way to notify non-wxPU_CONTAINS_CONTROLS windows about the
|
||||
// events that should result in their dismissal.
|
||||
virtual void MSWDismissUnfocusedPopup() { }
|
||||
|
||||
private:
|
||||
wxWindow* m_owner;
|
||||
|
||||
|
@@ -151,6 +151,9 @@ public:
|
||||
WXWPARAM wParam,
|
||||
WXLPARAM lParam) wxOVERRIDE;
|
||||
|
||||
// Override to dismiss the popup.
|
||||
virtual void MSWDismissUnfocusedPopup() wxOVERRIDE;
|
||||
|
||||
private:
|
||||
void DismissOnDeactivate();
|
||||
|
||||
|
@@ -210,6 +210,19 @@ void wxPopupTransientWindow::DismissOnDeactivate()
|
||||
}
|
||||
}
|
||||
|
||||
void wxPopupTransientWindow::MSWDismissUnfocusedPopup()
|
||||
{
|
||||
// When we use wxPU_CONTAINS_CONTROLS, we can react to the popup
|
||||
// deactivation in MSWHandleMessage(), but if we don't have focus, we don't
|
||||
// get any events ourselves, so we rely on wxWindow to forward them to us.
|
||||
if ( !HasFlag(wxPU_CONTAINS_CONTROLS) )
|
||||
{
|
||||
// It doesn't seem necessary to use CallAfter() here, as dismissing
|
||||
// this window shouldn't affect the focus, as it never has it anyhow.
|
||||
DismissAndNotify();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
wxPopupTransientWindow::MSWHandleMessage(WXLRESULT *result,
|
||||
WXUINT message,
|
||||
|
@@ -3844,6 +3844,42 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result,
|
||||
}
|
||||
}
|
||||
|
||||
// Special hook for dismissing the current popup if it's active. It's a bit
|
||||
// ugly to have to do this here, but the only alternatives seem to be
|
||||
// installing a WH_CBT hook in wxPopupTransientWindow code, which is not
|
||||
// really much better.
|
||||
#if wxUSE_POPUPWIN
|
||||
if ( wxCurrentPopupWindow )
|
||||
{
|
||||
switch ( message )
|
||||
{
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCLBUTTONUP:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_NCRBUTTONUP:
|
||||
case WM_NCRBUTTONDBLCLK:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
case WM_NCMBUTTONUP:
|
||||
case WM_NCMBUTTONDBLCLK:
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS:
|
||||
wxCurrentPopupWindow->MSWDismissUnfocusedPopup();
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_POPUPWIN
|
||||
|
||||
if ( !processed )
|
||||
return false;
|
||||
|
||||
|
Reference in New Issue
Block a user