Applied patch, fixes #12090: wxGTK cursor handling revamp
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -217,8 +217,6 @@ private:
|
||||
|
||||
// For wxTE_AUTO_URL
|
||||
void OnUrlMouseEvent(wxMouseEvent&);
|
||||
GdkCursor *m_gdkHandCursor;
|
||||
GdkCursor *m_gdkXTermCursor;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS(wxTextCtrl)
|
||||
|
@@ -279,6 +279,10 @@ public:
|
||||
// find the direction of the given scrollbar (must be one of ours)
|
||||
ScrollDir ScrollDirFromRange(GtkRange *range) const;
|
||||
|
||||
// set the current cursor for all GdkWindows making part of this widget
|
||||
// (see GTKGetWindow)
|
||||
void GTKUpdateCursor(bool update_self = true, bool recurse = true);
|
||||
|
||||
// extra (wxGTK-specific) flags
|
||||
bool m_noExpose:1; // wxGLCanvas has its own redrawing
|
||||
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
|
||||
@@ -357,12 +361,6 @@ protected:
|
||||
// sets the border of a given GtkScrolledWindow from a wx style
|
||||
static void GTKScrolledWindowSetBorder(GtkWidget* w, int style);
|
||||
|
||||
// set the current cursor for all GdkWindows making part of this widget
|
||||
// (see GTKGetWindow)
|
||||
//
|
||||
// should be called from OnInternalIdle() if it's overridden
|
||||
void GTKUpdateCursor();
|
||||
|
||||
// Connect the given function to the specified signal on m_widget.
|
||||
//
|
||||
// This is just a wrapper for g_signal_connect() and returns the handler id
|
||||
|
@@ -323,11 +323,6 @@ void wxControl::OnInternalIdle()
|
||||
if ( GTKShowFromOnIdle() )
|
||||
return;
|
||||
|
||||
if ( GTK_WIDGET_REALIZED(m_widget) )
|
||||
{
|
||||
GTKUpdateCursor();
|
||||
}
|
||||
|
||||
if ( wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen() )
|
||||
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
|
||||
}
|
||||
|
@@ -374,7 +374,7 @@ const wxCursor wxBusyCursor::GetBusyCursor()
|
||||
return wxCursor(wxCURSOR_WATCH);
|
||||
}
|
||||
|
||||
static void InternalIdle(const wxWindowList& list, GdkDisplay*& display)
|
||||
static void UpdateCursors(const wxWindowList& list, GdkDisplay*& display)
|
||||
{
|
||||
wxWindowList::const_iterator i = list.begin();
|
||||
for (size_t n = list.size(); n--; ++i)
|
||||
@@ -382,8 +382,8 @@ static void InternalIdle(const wxWindowList& list, GdkDisplay*& display)
|
||||
wxWindow* win = *i;
|
||||
if (display == NULL && win->m_widget && win->m_widget->window)
|
||||
display = gdk_drawable_get_display(win->m_widget->window);
|
||||
win->OnInternalIdle();
|
||||
InternalIdle(win->GetChildren(), display);
|
||||
win->GTKUpdateCursor(true, false);
|
||||
UpdateCursors(win->GetChildren(), display);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ void wxEndBusyCursor()
|
||||
g_globalCursor = gs_savedCursor;
|
||||
gs_savedCursor = wxNullCursor;
|
||||
GdkDisplay* unused = NULL;
|
||||
InternalIdle(wxTopLevelWindows, unused);
|
||||
UpdateCursors(wxTopLevelWindows, unused);
|
||||
}
|
||||
|
||||
void wxBeginBusyCursor(const wxCursor* cursor)
|
||||
@@ -409,7 +409,7 @@ void wxBeginBusyCursor(const wxCursor* cursor)
|
||||
gs_savedCursor = g_globalCursor;
|
||||
g_globalCursor = *cursor;
|
||||
GdkDisplay* display = NULL;
|
||||
InternalIdle(wxTopLevelWindows, display);
|
||||
UpdateCursors(wxTopLevelWindows, display);
|
||||
if (display)
|
||||
gdk_display_flush(display);
|
||||
}
|
||||
@@ -422,5 +422,6 @@ bool wxIsBusy()
|
||||
void wxSetCursor( const wxCursor& cursor )
|
||||
{
|
||||
g_globalCursor = cursor;
|
||||
wxTheApp->WakeUpIdle();
|
||||
GdkDisplay* unused = NULL;
|
||||
UpdateCursors(wxTopLevelWindows, unused);
|
||||
}
|
||||
|
@@ -281,6 +281,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event,
|
||||
gdk_window_set_cursor( widget->window, gdk_cursor_new( GDK_BOTTOM_RIGHT_CORNER ) );
|
||||
else
|
||||
gdk_window_set_cursor( widget->window, NULL );
|
||||
win->GTKUpdateCursor(false);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -622,16 +622,10 @@ void wxTextCtrl::Init()
|
||||
|
||||
m_text = NULL;
|
||||
m_showPositionOnThaw = NULL;
|
||||
m_gdkHandCursor = NULL;
|
||||
m_gdkXTermCursor = NULL;
|
||||
}
|
||||
|
||||
wxTextCtrl::~wxTextCtrl()
|
||||
{
|
||||
if(m_gdkHandCursor)
|
||||
gdk_cursor_unref(m_gdkHandCursor);
|
||||
if(m_gdkXTermCursor)
|
||||
gdk_cursor_unref(m_gdkXTermCursor);
|
||||
}
|
||||
|
||||
wxTextCtrl::wxTextCtrl( wxWindow *parent,
|
||||
@@ -763,8 +757,6 @@ bool wxTextCtrl::Create( wxWindow *parent,
|
||||
if (style & wxTE_AUTO_URL)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
m_gdkHandCursor = gdk_cursor_new(GDK_HAND2);
|
||||
m_gdkXTermCursor = gdk_cursor_new(GDK_XTERM);
|
||||
|
||||
// We create our wxUrl tag here for slight efficiency gain - we
|
||||
// don't have to check for the tag existance in callbacks,
|
||||
@@ -1873,13 +1865,11 @@ void wxTextCtrl::OnUrlMouseEvent(wxMouseEvent& event)
|
||||
gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(m_text), &end, x, y);
|
||||
if (!gtk_text_iter_has_tag(&end, tag))
|
||||
{
|
||||
gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
|
||||
GTK_TEXT_WINDOW_TEXT), m_gdkXTermCursor);
|
||||
SetCursor(wxCursor(wxCURSOR_IBEAM));
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
|
||||
GTK_TEXT_WINDOW_TEXT), m_gdkHandCursor);
|
||||
SetCursor(wxCursor(wxCURSOR_HAND));
|
||||
|
||||
start = end;
|
||||
if(!gtk_text_iter_begins_tag(&start, tag))
|
||||
|
@@ -733,45 +733,6 @@ void wxToolBar::OnInternalIdle()
|
||||
// Check if we have to show window now
|
||||
if (GTKShowFromOnIdle()) return;
|
||||
|
||||
wxCursor cursor = m_cursor;
|
||||
if (g_globalCursor.Ok()) cursor = g_globalCursor;
|
||||
|
||||
if (cursor.Ok())
|
||||
{
|
||||
/* I now set the cursor the anew in every OnInternalIdle call
|
||||
as setting the cursor in a parent window also effects the
|
||||
windows above so that checking for the current cursor is
|
||||
not possible. */
|
||||
|
||||
if (HasFlag(wxTB_DOCKABLE) && (m_widget->window))
|
||||
{
|
||||
/* if the toolbar is dockable, then m_widget stands for the
|
||||
GtkHandleBox widget, which uses its own window so that we
|
||||
can set the cursor for it. if the toolbar is not dockable,
|
||||
m_widget comes from m_toolbar which uses its parent's
|
||||
window ("windowless windows") and thus we cannot set the
|
||||
cursor. */
|
||||
gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
|
||||
}
|
||||
|
||||
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
||||
while ( node )
|
||||
{
|
||||
wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
|
||||
node = node->GetNext();
|
||||
|
||||
if (tool->m_item)
|
||||
{
|
||||
GdkWindow* window = GTK_WIDGET(tool->m_item)->window;
|
||||
|
||||
if ( window )
|
||||
{
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
|
||||
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
|
||||
}
|
||||
|
@@ -183,14 +183,12 @@
|
||||
|
||||
Cursors, too, have been a constant source of pleasure. The main difficulty
|
||||
is that a GdkWindow inherits a cursor if the programmer sets a new cursor
|
||||
for the parent. To prevent this from doing too much harm, I use idle time
|
||||
to set the cursor over and over again, starting from the toplevel windows
|
||||
and ending with the youngest generation (speaking of parent and child windows).
|
||||
for the parent. To prevent this from doing too much harm, SetCursor calls
|
||||
GTKUpdateCursor, which will recursively re-set the cursors of all child windows.
|
||||
Also don't forget that cursors (like much else) are connected to GdkWindows,
|
||||
not GtkWidgets and that the "window" field of a GtkWidget might very well
|
||||
point to the GdkWindow of the parent widget (-> "window-less widget") and
|
||||
that the two obviously have very different meanings.
|
||||
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2565,38 +2563,6 @@ void wxWindowGTK::OnInternalIdle()
|
||||
m_needsStyleChange = false;
|
||||
}
|
||||
|
||||
wxCursor cursor = m_cursor;
|
||||
if (g_globalCursor.Ok()) cursor = g_globalCursor;
|
||||
|
||||
if (cursor.Ok())
|
||||
{
|
||||
/* I now set the cursor anew in every OnInternalIdle call
|
||||
as setting the cursor in a parent window also effects the
|
||||
windows above so that checking for the current cursor is
|
||||
not possible. */
|
||||
|
||||
if (m_wxwindow && (m_wxwindow != m_widget))
|
||||
{
|
||||
GdkWindow* window = GTKGetDrawingWindow();
|
||||
if (window)
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
|
||||
if (!g_globalCursor.Ok())
|
||||
cursor = *wxSTANDARD_CURSOR;
|
||||
|
||||
window = m_widget->window;
|
||||
if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
|
||||
}
|
||||
else if ( m_widget )
|
||||
{
|
||||
GdkWindow *window = m_widget->window;
|
||||
if ( window && !GTK_WIDGET_NO_WINDOW(m_widget) )
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
}
|
||||
}
|
||||
|
||||
if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
|
||||
UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
|
||||
}
|
||||
@@ -3429,17 +3395,19 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxWindowGTK::GTKUpdateCursor()
|
||||
void wxWindowGTK::GTKUpdateCursor(bool update_self /*=true*/, bool recurse /*=true*/)
|
||||
{
|
||||
if (update_self)
|
||||
{
|
||||
wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
|
||||
if ( cursor.Ok() )
|
||||
{
|
||||
wxArrayGdkWindows windowsThis;
|
||||
GdkWindow * const winThis = GTKGetWindow(windowsThis);
|
||||
if ( winThis )
|
||||
if (m_wxwindow && (m_wxwindow != m_widget))
|
||||
{
|
||||
gdk_window_set_cursor(winThis, cursor.GetCursor());
|
||||
}
|
||||
wxArrayGdkWindows windowsThis;
|
||||
GdkWindow* window = GTKGetDrawingWindow();
|
||||
if (window)
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
else
|
||||
{
|
||||
const size_t count = windowsThis.size();
|
||||
@@ -3451,10 +3419,30 @@ void wxWindowGTK::GTKUpdateCursor()
|
||||
wxFAIL_MSG(wxT("NULL window returned by GTKGetWindow()?"));
|
||||
continue;
|
||||
}
|
||||
|
||||
gdk_window_set_cursor(win, cursor.GetCursor());
|
||||
}
|
||||
}
|
||||
|
||||
window = m_widget->window;
|
||||
if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
|
||||
}
|
||||
else if ( m_widget )
|
||||
{
|
||||
GdkWindow *window = m_widget->window;
|
||||
if ( window && !GTK_WIDGET_NO_WINDOW(m_widget) )
|
||||
gdk_window_set_cursor( window, cursor.GetCursor() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse)
|
||||
{
|
||||
for (wxWindowList::iterator it = GetChildren().begin(); it != GetChildren().end(); ++it)
|
||||
{
|
||||
(*it)->GTKUpdateCursor( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user