Invalidate wxDisplay cache under MSW when the displays change
The cache added in 990c8bfd73
was not
invalidated properly, meaning that wrong information was returned when
displays were [dis]connected after the application startup.
Fix this at least for MSW by invalidating the cache on receiving
WM_DISPLAYCHANGE (which means that sometimes we will do it
unnecessarily, as the change in resolution of an existing display
doesn't require cache invalidation, but this shouldn't be a big problem
in practice as the speed with which the user can change the display
resolution is not very high).
Closes https://github.com/wxWidgets/wxWidgets/pull/1090
This commit is contained in:
@@ -115,6 +115,11 @@ public:
|
||||
void ResetMode() { (void)ChangeMode(); }
|
||||
#endif // wxUSE_DISPLAY
|
||||
|
||||
// If the implementation caches any information about the displays, calling
|
||||
// this function clears it -- this should be done e.g. after a display
|
||||
// [dis]connection.
|
||||
static void InvalidateCache();
|
||||
|
||||
private:
|
||||
// returns the factory used to implement our static methods and create new
|
||||
// displays
|
||||
|
@@ -22,7 +22,7 @@ class wxDisplayFactory
|
||||
{
|
||||
public:
|
||||
wxDisplayFactory() { }
|
||||
virtual ~wxDisplayFactory();
|
||||
virtual ~wxDisplayFactory() { ClearImpls(); }
|
||||
|
||||
// Create the display if necessary using CreateDisplay(), otherwise just
|
||||
// get it from cache.
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
// the window pointer must not be NULL (i.e. caller should check it)
|
||||
virtual int GetFromWindow(const wxWindow *window);
|
||||
|
||||
// Trigger recreation of wxDisplayImpl when they're needed the next time.
|
||||
void InvalidateCache() { ClearImpls(); }
|
||||
|
||||
protected:
|
||||
// create a new display object
|
||||
//
|
||||
@@ -55,6 +58,9 @@ protected:
|
||||
virtual wxDisplayImpl *CreateDisplay(unsigned n) = 0;
|
||||
|
||||
private:
|
||||
// Delete all the elements of m_impls vector and clear it.
|
||||
void ClearImpls();
|
||||
|
||||
// On-demand populated vector of wxDisplayImpl objects.
|
||||
wxVector<wxDisplayImpl*> m_impls;
|
||||
|
||||
|
@@ -113,6 +113,11 @@ wxDisplay::wxDisplay(const wxWindow* window)
|
||||
return Factory().GetFromWindow(window);
|
||||
}
|
||||
|
||||
/* static */ void wxDisplay::InvalidateCache()
|
||||
{
|
||||
Factory().InvalidateCache();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// functions forwarded to wxDisplayImpl
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -229,13 +234,15 @@ wxSize wxDisplayImpl::GetPPI() const
|
||||
// wxDisplayFactory implementation
|
||||
// ============================================================================
|
||||
|
||||
wxDisplayFactory::~wxDisplayFactory()
|
||||
void wxDisplayFactory::ClearImpls()
|
||||
{
|
||||
for ( size_t n = 0; n < m_impls.size(); ++n )
|
||||
{
|
||||
// It can be null, that's ok.
|
||||
delete m_impls[n];
|
||||
}
|
||||
|
||||
m_impls.clear();
|
||||
}
|
||||
|
||||
int wxDisplayFactory::GetFromWindow(const wxWindow *window)
|
||||
|
@@ -58,8 +58,9 @@
|
||||
#include "wx/ownerdrw.h"
|
||||
#endif
|
||||
|
||||
#include "wx/hashmap.h"
|
||||
#include "wx/display.h"
|
||||
#include "wx/evtloop.h"
|
||||
#include "wx/hashmap.h"
|
||||
#include "wx/popupwin.h"
|
||||
#include "wx/power.h"
|
||||
#include "wx/scopeguard.h"
|
||||
@@ -4692,6 +4693,8 @@ bool wxWindowMSW::HandleSysColorChange()
|
||||
|
||||
bool wxWindowMSW::HandleDisplayChange()
|
||||
{
|
||||
wxDisplay::InvalidateCache();
|
||||
|
||||
wxDisplayChangedEvent event;
|
||||
event.SetEventObject(this);
|
||||
|
||||
|
Reference in New Issue
Block a user