Different fix for cursor inheritance and busy cursor/global cursor.
Previous work was not compatible with GTK < 2.18 and did not properly handle some cases see #15801 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75807 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -283,7 +283,10 @@ void wxCursor::InitFromImage( const wxImage & image )
|
||||
|
||||
GdkCursor *wxCursor::GetCursor() const
|
||||
{
|
||||
return M_CURSORDATA->m_cursor;
|
||||
GdkCursor* cursor = NULL;
|
||||
if (m_refData)
|
||||
cursor = M_CURSORDATA->m_cursor;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
wxGDIRefData *wxCursor::CreateGDIRefData() const
|
||||
@@ -308,108 +311,43 @@ wxCursor::CloneGDIRefData(const wxGDIRefData * WXUNUSED(data)) const
|
||||
// busy cursor routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wxCursor g_globalCursor;
|
||||
wxCursor g_busyCursor;
|
||||
static wxCursor gs_storedCursor;
|
||||
static int gs_busyCount = 0;
|
||||
|
||||
void wxBeginBusyCursor(const wxCursor* cursor)
|
||||
const wxCursor& wxBusyCursor::GetStoredCursor()
|
||||
{
|
||||
if (gs_busyCount++ == 0)
|
||||
wxSetCursor(*cursor);
|
||||
return gs_storedCursor;
|
||||
}
|
||||
|
||||
void wxEndBusyCursor()
|
||||
const wxCursor wxBusyCursor::GetBusyCursor()
|
||||
{
|
||||
if (gs_busyCount && --gs_busyCount == 0)
|
||||
wxSetCursor(wxCursor());
|
||||
return g_busyCursor;
|
||||
}
|
||||
|
||||
bool wxIsBusy()
|
||||
static void UpdateCursors(wxWindow* win, bool isBusyOrGlobalCursor)
|
||||
{
|
||||
return gs_busyCount > 0;
|
||||
win->GTKUpdateCursor(isBusyOrGlobalCursor);
|
||||
const wxWindowList& children = win->GetChildren();
|
||||
wxWindowList::const_iterator i = children.begin();
|
||||
for (size_t n = children.size(); n--; ++i)
|
||||
UpdateCursors(*i, isBusyOrGlobalCursor);
|
||||
}
|
||||
|
||||
// Table holding non-default cursors to be restored when global cursor is unset
|
||||
WX_DECLARE_HASH_MAP(GdkWindow*, GdkCursor*, wxPointerHash, wxPointerEqual, wxGdkWindowGdkCursorMapBase);
|
||||
class wxGdkWindowGdkCursorMap: public wxGdkWindowGdkCursorMapBase
|
||||
{
|
||||
public:
|
||||
~wxGdkWindowGdkCursorMap();
|
||||
};
|
||||
static wxGdkWindowGdkCursorMap* gs_windowCursorMap;
|
||||
|
||||
wxGdkWindowGdkCursorMap::~wxGdkWindowGdkCursorMap()
|
||||
{
|
||||
const_iterator i = begin();
|
||||
for (size_t n = size(); n--; ++i)
|
||||
{
|
||||
#ifdef __WXGTK3__
|
||||
g_object_unref(i->second);
|
||||
#else
|
||||
gdk_cursor_unref(i->second);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Set cursor to default for window and all its children,
|
||||
// recording non-default cursors in gs_windowCursorMap
|
||||
static void clearCursors(GdkWindow* window)
|
||||
{
|
||||
GdkCursor* cursor = gdk_window_get_cursor(window);
|
||||
if (cursor)
|
||||
{
|
||||
#ifdef __WXGTK3__
|
||||
g_object_ref(cursor);
|
||||
#else
|
||||
gdk_cursor_ref(cursor);
|
||||
#endif
|
||||
(*gs_windowCursorMap)[window] = cursor;
|
||||
gdk_window_set_cursor(window, NULL);
|
||||
}
|
||||
for (const GList* p = gdk_window_peek_children(window); p; p = p->next)
|
||||
clearCursors(static_cast<GdkWindow*>(p->data));
|
||||
}
|
||||
|
||||
// Restore non-default cursors
|
||||
static void restoreCursors(GdkWindow* window)
|
||||
{
|
||||
wxGdkWindowGdkCursorMap::const_iterator i = gs_windowCursorMap->find(window);
|
||||
if (i != gs_windowCursorMap->end())
|
||||
gdk_window_set_cursor(window, i->second);
|
||||
for (const GList* p = gdk_window_peek_children(window); p; p = p->next)
|
||||
restoreCursors(static_cast<GdkWindow*>(p->data));
|
||||
}
|
||||
|
||||
void wxSetCursor( const wxCursor& cursor )
|
||||
static void SetGlobalCursor(const wxCursor& cursor)
|
||||
{
|
||||
GdkCursor* gdk_cursor = cursor.GetCursor();
|
||||
GdkDisplay* display = NULL;
|
||||
wxWindowList::const_iterator i = wxTopLevelWindows.begin();
|
||||
for (size_t n = wxTopLevelWindows.size(); n--; ++i)
|
||||
{
|
||||
GtkWidget* widget = (*i)->m_widget;
|
||||
wxWindow* win = *i;
|
||||
GdkWindow* window;
|
||||
if (widget && (window = gtk_widget_get_window(widget)))
|
||||
if (win->m_widget && (window = gtk_widget_get_window(win->m_widget)))
|
||||
{
|
||||
// if setting global cursor
|
||||
if (cursor.IsOk())
|
||||
{
|
||||
delete gs_windowCursorMap;
|
||||
gs_windowCursorMap = new wxGdkWindowGdkCursorMap;
|
||||
// clear all cursors, saving non-default ones for later
|
||||
clearCursors(window);
|
||||
// set global cursor
|
||||
gdk_window_set_cursor(window, cursor.GetCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove global cursor
|
||||
gdk_window_set_cursor(window, NULL);
|
||||
if (gs_windowCursorMap)
|
||||
{
|
||||
// restore non-default cursors
|
||||
restoreCursors(window);
|
||||
delete gs_windowCursorMap;
|
||||
gs_windowCursorMap = NULL;
|
||||
}
|
||||
}
|
||||
gdk_window_set_cursor(window, gdk_cursor);
|
||||
UpdateCursors(win, gdk_cursor != NULL);
|
||||
if (display == NULL)
|
||||
display = gdk_window_get_display(window);
|
||||
}
|
||||
@@ -417,3 +355,35 @@ void wxSetCursor( const wxCursor& cursor )
|
||||
if (display)
|
||||
gdk_display_flush(display);
|
||||
}
|
||||
|
||||
void wxBeginBusyCursor(const wxCursor* cursor)
|
||||
{
|
||||
if (gs_busyCount++ == 0)
|
||||
{
|
||||
g_busyCursor = *cursor;
|
||||
gs_storedCursor = g_globalCursor;
|
||||
SetGlobalCursor(*cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void wxEndBusyCursor()
|
||||
{
|
||||
if (gs_busyCount && --gs_busyCount == 0)
|
||||
{
|
||||
g_globalCursor = gs_storedCursor;
|
||||
gs_storedCursor =
|
||||
g_busyCursor = wxCursor();
|
||||
SetGlobalCursor(g_globalCursor);
|
||||
}
|
||||
}
|
||||
|
||||
bool wxIsBusy()
|
||||
{
|
||||
return gs_busyCount > 0;
|
||||
}
|
||||
|
||||
void wxSetCursor( const wxCursor& cursor )
|
||||
{
|
||||
g_globalCursor = cursor;
|
||||
SetGlobalCursor(cursor);
|
||||
}
|
||||
|
Reference in New Issue
Block a user