Fix handling display disconnection under wxMSW
Information about display cached in wxDisplayFactory::m_impls and in wxDisplayFactoryMSW::m_displays could get out of sync after removing a display from the system, resulting in failures when calling various wxDisplay functions later. To fix this, reuse InvalidateCache() to invalidate the cache in wxDisplayFactoryMSW too, making it virtual in order to allow overriding it there. Also call InvalidateCache() from wxDisplayFactoryMSW itself instead of doing it from wxWindow, as this works even when the application isn't showing any windows (and also keeps all display-related code together). Closes https://github.com/wxWidgets/wxWidgets/pull/1246
This commit is contained in:
@@ -49,7 +49,7 @@ public:
|
|||||||
virtual int GetFromWindow(const wxWindow *window);
|
virtual int GetFromWindow(const wxWindow *window);
|
||||||
|
|
||||||
// Trigger recreation of wxDisplayImpl when they're needed the next time.
|
// Trigger recreation of wxDisplayImpl when they're needed the next time.
|
||||||
void InvalidateCache() { ClearImpls(); }
|
virtual void InvalidateCache() { ClearImpls(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// create a new display object
|
// create a new display object
|
||||||
|
@@ -192,9 +192,15 @@ public:
|
|||||||
virtual int GetFromPoint(const wxPoint& pt) wxOVERRIDE;
|
virtual int GetFromPoint(const wxPoint& pt) wxOVERRIDE;
|
||||||
virtual int GetFromWindow(const wxWindow *window) wxOVERRIDE;
|
virtual int GetFromWindow(const wxWindow *window) wxOVERRIDE;
|
||||||
|
|
||||||
|
void InvalidateCache() wxOVERRIDE
|
||||||
|
{
|
||||||
|
wxDisplayFactory::InvalidateCache();
|
||||||
|
DoRefreshMonitors();
|
||||||
|
}
|
||||||
|
|
||||||
// Called when we receive WM_SETTINGCHANGE to refresh the list of monitor
|
// Called when we receive WM_SETTINGCHANGE to refresh the list of monitor
|
||||||
// handles.
|
// handles.
|
||||||
static void RefreshMonitors() { ms_factory->DoRefreshMonitors(); }
|
static void RefreshMonitors() { ms_factory->InvalidateCache(); }
|
||||||
|
|
||||||
// Declare the second argument as int to avoid problems with older SDKs not
|
// Declare the second argument as int to avoid problems with older SDKs not
|
||||||
// declaring MONITOR_DPI_TYPE enum.
|
// declaring MONITOR_DPI_TYPE enum.
|
||||||
@@ -529,9 +535,9 @@ bool wxDisplayMSW::ChangeMode(const wxVideoMode& mode)
|
|||||||
LRESULT APIENTRY
|
LRESULT APIENTRY
|
||||||
wxDisplayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
wxDisplayWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if ( msg == WM_SETTINGCHANGE )
|
if ( msg == WM_SETTINGCHANGE || msg == WM_DISPLAYCHANGE )
|
||||||
{
|
{
|
||||||
wxDisplayFactoryMSW::RefreshMonitors();
|
wxDisplay::InvalidateCache();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -4723,8 +4723,6 @@ bool wxWindowMSW::HandleSysColorChange()
|
|||||||
|
|
||||||
bool wxWindowMSW::HandleDisplayChange()
|
bool wxWindowMSW::HandleDisplayChange()
|
||||||
{
|
{
|
||||||
wxDisplay::InvalidateCache();
|
|
||||||
|
|
||||||
wxDisplayChangedEvent event;
|
wxDisplayChangedEvent event;
|
||||||
event.SetEventObject(this);
|
event.SetEventObject(this);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user