From ef5c70f96f5e06e1c8f8119f51b99dd019583d2b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 25 Aug 2006 12:59:28 +0000 Subject: [PATCH] Many changes: - Introduced GTKGetWindow() which returns all GdkWindows associated with the given wxWindow - Renamed IsOwnGtkWindow() to GTKIsOwnWindow() to avoid confusion with the old virtual function (the new one is non-virtual and is implemented in terms of GTKGetWindow()) - Refactored/simplified event handlers code in gtk/window.cpp - Fixed some header guards names (__GTKFOO__ -> _WX_GTK_FOO_H_) - Added GTKUpdateCursor() which sets the current cursor for all windows returned by GTKGetWindow() - Factored out code from many different classes in wxControl::OnInternalIdle() which now updates the cursor, checks for internal focus and sends update UI events git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40815 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/gtk/button.h | 6 +- include/wx/gtk/checkbox.h | 6 +- include/wx/gtk/choice.h | 9 +- include/wx/gtk/combobox.h | 4 +- include/wx/gtk/control.h | 2 + include/wx/gtk/listbox.h | 7 +- include/wx/gtk/notebook.h | 5 +- include/wx/gtk/radiobox.h | 4 +- include/wx/gtk/radiobut.h | 12 +- include/wx/gtk/scrolbar.h | 13 +- include/wx/gtk/slider.h | 5 +- include/wx/gtk/spinbutt.h | 3 +- include/wx/gtk/spinctrl.h | 2 +- include/wx/gtk/textctrl.h | 5 +- include/wx/gtk/tglbtn.h | 13 +- include/wx/gtk/window.h | 40 +++++- src/gtk/button.cpp | 2 +- src/gtk/checkbox.cpp | 38 +----- src/gtk/choice.cpp | 2 +- src/gtk/combobox.cpp | 18 +-- src/gtk/control.cpp | 15 +++ src/gtk/notebook.cpp | 8 +- src/gtk/radiobox.cpp | 28 +--- src/gtk/radiobut.cpp | 36 +---- src/gtk/scrolbar.cpp | 5 +- src/gtk/slider.cpp | 5 +- src/gtk/spinbutt.cpp | 4 +- src/gtk/spinctrl.cpp | 10 +- src/gtk/textctrl.cpp | 31 +---- src/gtk/tglbtn.cpp | 60 +-------- src/gtk/window.cpp | 270 ++++++++++++++++++-------------------- 32 files changed, 275 insertions(+), 394 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 9d6364fac0..e1c9b38d65 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -67,6 +67,7 @@ wxMac: wxGTK: - Automatically use stock items for the menu items with standard ids +- Setting cursor now works for all controls 2.7.0 diff --git a/include/wx/gtk/button.h b/include/wx/gtk/button.h index a395a617ca..919c528c22 100644 --- a/include/wx/gtk/button.h +++ b/include/wx/gtk/button.h @@ -61,8 +61,6 @@ public: // implementation // -------------- - bool IsOwnGtkWindow( GdkWindow *window ); - // Since this wxButton doesn't derive from wxButtonBase (why?) we need // to override this here too... virtual bool ShouldInheritColours() const { return false; } @@ -75,7 +73,9 @@ public: protected: virtual wxSize DoGetBestSize() const; - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_DYNAMIC_CLASS(wxButton) diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h index a1ed20538c..c4639026ff 100644 --- a/include/wx/gtk/checkbox.h +++ b/include/wx/gtk/checkbox.h @@ -47,9 +47,6 @@ public: // implementation // -------------- - bool IsOwnGtkWindow( GdkWindow *window ); - void OnInternalIdle(); - GtkWidget *m_widgetCheckbox; GtkWidget *m_widgetLabel; @@ -57,7 +54,8 @@ public: protected: virtual wxSize DoGetBestSize() const; - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; void DoSet3StateValue(wxCheckBoxState state); wxCheckBoxState DoGet3StateValue() const; diff --git a/include/wx/gtk/choice.h b/include/wx/gtk/choice.h index 12d9a3a5fb..4a3527f52c 100644 --- a/include/wx/gtk/choice.h +++ b/include/wx/gtk/choice.h @@ -77,12 +77,13 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); - virtual bool IsOwnGtkWindow( GdkWindow *window ); - protected: wxList m_clientList; // contains the client data for the items - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual wxSize DoGetBestSize() const; + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; + virtual int DoAppend(const wxString& item); virtual int DoInsert(const wxString& item, unsigned int pos); @@ -91,8 +92,6 @@ protected: virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData); virtual wxClientData* DoGetItemClientObject(unsigned int n) const; - virtual wxSize DoGetBestSize() const; - private: // common part of Create() and DoAppend() int GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item); diff --git a/include/wx/gtk/combobox.h b/include/wx/gtk/combobox.h index 4d2e419530..206e729896 100644 --- a/include/wx/gtk/combobox.h +++ b/include/wx/gtk/combobox.h @@ -152,7 +152,6 @@ public: void DisableEvents(); void EnableEvents(); GtkWidget* GetConnectWidget(); - bool IsOwnGtkWindow( GdkWindow *window ); wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST @@ -161,7 +160,8 @@ public: protected: // From wxWindowGTK: - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; // From wxItemContainer: virtual int DoAppend(const wxString& item); diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h index f2e5c6dc04..d2cfee5cd8 100644 --- a/include/wx/gtk/control.h +++ b/include/wx/gtk/control.h @@ -59,6 +59,8 @@ public: virtual wxVisualAttributes GetDefaultAttributes() const; + virtual void OnInternalIdle(); + protected: virtual wxSize DoGetBestSize() const; void PostCreation(const wxSize& size); diff --git a/include/wx/gtk/listbox.h b/include/wx/gtk/listbox.h index c5c28a4e78..5332a01f0c 100644 --- a/include/wx/gtk/listbox.h +++ b/include/wx/gtk/listbox.h @@ -80,8 +80,6 @@ public: // implementation from now on GtkWidget *GetConnectWidget(); - bool IsOwnGtkWindow( GdkWindow *window ); - void OnInternalIdle(); #if wxUSE_TOOLTIPS void ApplyToolTip( GtkTooltips *tips, const wxChar *tip ); @@ -105,6 +103,9 @@ public: protected: virtual wxSize DoGetBestSize() const; + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; + virtual void DoSetSelection(int n, bool select); virtual int DoAppend(const wxString& item); virtual void DoInsertItems(const wxArrayString& items, unsigned int pos); @@ -116,8 +117,6 @@ protected: virtual wxClientData* DoGetItemClientObject(unsigned int n) const; virtual int DoListHitTest(const wxPoint& point) const; - void DoApplyWidgetStyle(GtkRcStyle *style); - private: void Init(); //common construction diff --git a/include/wx/gtk/notebook.h b/include/wx/gtk/notebook.h index 9724afdb11..8965c2d2f6 100644 --- a/include/wx/gtk/notebook.h +++ b/include/wx/gtk/notebook.h @@ -103,8 +103,6 @@ public: void SetConstraintSizes(bool recurse); bool DoPhase(int phase); #endif - // report if window belongs to notebook - bool IsOwnGtkWindow( GdkWindow *window ); // common part of all ctors void Init(); @@ -124,7 +122,8 @@ public: protected: // set all page's attributes - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; // remove one page from the notebook but do not destroy it virtual wxNotebookPage *DoRemovePage(size_t nPage); diff --git a/include/wx/gtk/radiobox.h b/include/wx/gtk/radiobox.h index bd74401b39..77bbb3a066 100644 --- a/include/wx/gtk/radiobox.h +++ b/include/wx/gtk/radiobox.h @@ -131,7 +131,6 @@ public: void SetFocus(); void GtkDisableEvents(); void GtkEnableEvents(); - bool IsOwnGtkWindow( GdkWindow *window ); #if wxUSE_TOOLTIPS void ApplyToolTip( GtkTooltips *tips, const wxChar *tip ); #endif // wxUSE_TOOLTIPS @@ -147,7 +146,8 @@ protected: virtual void DoSetItemToolTip(unsigned int n, wxToolTip *tooltip); #endif - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; virtual bool GTKWidgetNeedsMnemonic() const; virtual void GTKWidgetDoSetMnemonic(GtkWidget* w); diff --git a/include/wx/gtk/radiobut.h b/include/wx/gtk/radiobut.h index d9eea34fdb..bb4f5d869c 100644 --- a/include/wx/gtk/radiobut.h +++ b/include/wx/gtk/radiobut.h @@ -7,8 +7,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __GTKRADIOBUTTONH__ -#define __GTKRADIOBUTTONH__ +#ifndef _WX_GTK_RADIOBUT_H_ +#define _WX_GTK_RADIOBUT_H_ //----------------------------------------------------------------------------- // wxRadioButton @@ -51,17 +51,15 @@ public: virtual bool IsRadioButton() const { return TRUE; } - bool IsOwnGtkWindow( GdkWindow *window ); - void OnInternalIdle(); - bool m_blockEvent; protected: - void DoApplyWidgetStyle(GtkRcStyle *style); virtual wxSize DoGetBestSize() const; + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_DYNAMIC_CLASS(wxRadioButton) }; -#endif // __GTKRADIOBUTTONH__ +#endif // _WX_GTK_RADIOBUT_H_ diff --git a/include/wx/gtk/scrolbar.h b/include/wx/gtk/scrolbar.h index 37d64dbae6..3f94c5c062 100644 --- a/include/wx/gtk/scrolbar.h +++ b/include/wx/gtk/scrolbar.h @@ -7,8 +7,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __GTKSCROLLBARH__ -#define __GTKSCROLLBARH__ +#ifndef _WX_GTK_SCROLLBAR_H_ +#define _WX_GTK_SCROLLBAR_H_ #include "wx/defs.h" @@ -57,14 +57,11 @@ public: static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); - // implementation - // -------------- - - bool IsOwnGtkWindow( GdkWindow *window ); +protected: + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_DYNAMIC_CLASS(wxScrollBar) }; -#endif - // __GTKSCROLLBARH__ +#endif // _WX_GTK_SCROLLBAR_H_ diff --git a/include/wx/gtk/slider.h b/include/wx/gtk/slider.h index 8322bf66a9..76f6dae280 100644 --- a/include/wx/gtk/slider.h +++ b/include/wx/gtk/slider.h @@ -60,12 +60,13 @@ public: GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); // implementation - bool IsOwnGtkWindow( GdkWindow *window ); - double m_pos; int m_scrollEventType; bool m_needThumbRelease; +protected: + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; + private: DECLARE_DYNAMIC_CLASS(wxSlider) }; diff --git a/include/wx/gtk/spinbutt.h b/include/wx/gtk/spinbutt.h index f70abfcee0..4daf12bb37 100644 --- a/include/wx/gtk/spinbutt.h +++ b/include/wx/gtk/spinbutt.h @@ -48,12 +48,11 @@ public: // implementation void OnSize( wxSizeEvent &event ); - bool IsOwnGtkWindow( GdkWindow *window ); - int m_pos; protected: virtual wxSize DoGetBestSize() const; + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_EVENT_TABLE() diff --git a/include/wx/gtk/spinctrl.h b/include/wx/gtk/spinctrl.h index 426a01f4b0..77e2ae5fec 100644 --- a/include/wx/gtk/spinctrl.h +++ b/include/wx/gtk/spinctrl.h @@ -61,7 +61,6 @@ public: // implementation void OnChar( wxKeyEvent &event ); - bool IsOwnGtkWindow( GdkWindow *window ); void GtkDisableEvents(); void GtkEnableEvents(); @@ -69,6 +68,7 @@ public: protected: virtual wxSize DoGetBestSize() const; + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; // Widgets that use the style->base colour for the BG colour should // override this and return true. diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h index 19c3ca9010..9f1c6eddd2 100644 --- a/include/wx/gtk/textctrl.h +++ b/include/wx/gtk/textctrl.h @@ -138,9 +138,7 @@ public: bool SetBackgroundColour(const wxColour& colour); GtkWidget* GetConnectWidget(); - bool IsOwnGtkWindow( GdkWindow *window ); void CalculateScrollbar(); - void OnInternalIdle(); void SetUpdateFont(bool WXUNUSED(update)) { } @@ -175,7 +173,8 @@ public: protected: virtual wxSize DoGetBestSize() const; - void DoApplyWidgetStyle(GtkRcStyle *style); + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; // common part of all ctors void Init(); diff --git a/include/wx/gtk/tglbtn.h b/include/wx/gtk/tglbtn.h index 0c542ac0c9..4964591aa1 100644 --- a/include/wx/gtk/tglbtn.h +++ b/include/wx/gtk/tglbtn.h @@ -75,13 +75,11 @@ public: wxBitmap m_bitmap; void OnSetBitmap(); - bool IsOwnGtkWindow(GdkWindow *window); - - virtual void OnInternalIdle(); protected: - void DoApplyWidgetStyle(GtkRcStyle *style); virtual wxSize DoGetBestSize() const; + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_DYNAMIC_CLASS(wxToggleBitmapButton) @@ -131,13 +129,10 @@ public: // implementation bool m_blockEvent; - bool IsOwnGtkWindow(GdkWindow *window); - - virtual void OnInternalIdle(); - protected: - void DoApplyWidgetStyle(GtkRcStyle *style); virtual wxSize DoGetBestSize() const; + virtual void DoApplyWidgetStyle(GtkRcStyle *style); + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; private: DECLARE_DYNAMIC_CLASS(wxToggleButton) diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index fb02d8304f..8106f545cd 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -7,13 +7,17 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __GTKWINDOWH__ -#define __GTKWINDOWH__ +#ifndef _WX_GTK_WINDOW_H_ +#define _WX_GTK_WINDOW_H_ + +#include "wx/dynarray.h" // helper structure that holds class that holds GtkIMContext object and // some additional data needed for key events processing struct wxGtkIMData; +WX_DEFINE_EXPORTED_ARRAY_PTR(GdkWindow *, wxArrayGdkWindows); + //----------------------------------------------------------------------------- // callback definition for inserting a window (internal) //----------------------------------------------------------------------------- @@ -117,6 +121,8 @@ public: virtual WXWidget GetHandle() const { return m_widget; } + // many important things are done here, this function must be called + // regularly virtual void OnInternalIdle(); // Internal represention of Update() @@ -153,9 +159,11 @@ public: // widget where (most of) the input goes. even tooltips have // to be applied to all subwidgets. virtual GtkWidget* GetConnectWidget(); - virtual bool IsOwnGtkWindow( GdkWindow *window ); void ConnectWidget( GtkWidget *widget ); + // Called from several event handlers + bool GTKCallbackCommonPrologue(struct _GdkEventAny *event) const; + protected: // Override GTKWidgetNeedsMnemonic and return true if your // needs to set its mnemonic widget, such as for a @@ -164,6 +172,24 @@ protected: virtual bool GTKWidgetNeedsMnemonic() const; virtual void GTKWidgetDoSetMnemonic(GtkWidget* w); + // Get the GdkWindows making part of this window: usually there will be + // only one of them in which case it should be returned directly by this + // function. If there is more than one GdkWindow (can be the case for + // composite widgets), return NULL and fill in the provided array + // + // This is not pure virtual for backwards compatibility but almost + // certainly must be overridden in any wxControl-derived class! + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const; + + // Check if the given window makes part of this widget + bool GTKIsOwnWindow(GdkWindow *window) const; + + // Set the focus to this window if its setting was delayed because the + // widget hadn't been realized when SetFocus() was called + // + // Return true if focus was set to us, false if nothing was done + bool GTKSetDelayedFocusIfNeeded(); + public: // Returns the default context which usually is anti-aliased PangoContext *GtkGetPangoDefaultContext(); @@ -323,6 +349,12 @@ 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(); + private: enum ScrollUnit { ScrollUnit_Line, ScrollUnit_Page, ScrollUnit_Max }; @@ -340,4 +372,4 @@ private: extern WXDLLIMPEXP_CORE wxWindow *wxFindFocusedChild(wxWindowGTK *win); -#endif // __GTKWINDOWH__ +#endif // _WX_GTK_WINDOW_H_ diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp index efcfb9626f..35e0b4f537 100644 --- a/src/gtk/button.cpp +++ b/src/gtk/button.cpp @@ -257,7 +257,7 @@ bool wxButton::Enable( bool enable ) return true; } -bool wxButton::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { return GTK_BUTTON(m_widget)->event_window; } diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index c03eefa9c3..7dcc25d78f 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -21,8 +21,6 @@ //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; -extern wxCursor g_globalCursor; -extern wxWindowGTK *g_delayedFocus; //----------------------------------------------------------------------------- // "clicked" @@ -225,41 +223,9 @@ void wxCheckBox::DoApplyWidgetStyle(GtkRcStyle *style) gtk_widget_modify_style(m_widgetLabel, style); } -bool wxCheckBox::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxCheckBox::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - return window == GTK_BUTTON(m_widget)->event_window; -} - -void wxCheckBox::OnInternalIdle() -{ - // Check if we have to show window now - if (GtkShowFromOnIdle()) return; - - wxCursor cursor = m_cursor; - if (g_globalCursor.Ok()) cursor = g_globalCursor; - - GdkWindow *event_window = GTK_BUTTON(m_widgetCheckbox)->event_window; - if ( event_window && 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. */ - - gdk_window_set_cursor( event_window, cursor.GetCursor() ); - } - - if (g_delayedFocus == this) - { - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_grab_focus( m_widget ); - g_delayedFocus = NULL; - } - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); + return GTK_BUTTON(m_widgetCheckbox)->event_window; } wxSize wxCheckBox::DoGetBestSize() const diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index a7f05f679a..737522f7ad 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -599,7 +599,7 @@ wxSize wxChoice::DoGetBestSize() const return ret; } -bool wxChoice::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxChoice::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { return GTK_BUTTON(m_widget)->event_window; } diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp index 6549733c33..32123f67cc 100644 --- a/src/gtk/combobox.cpp +++ b/src/gtk/combobox.cpp @@ -1325,21 +1325,23 @@ GtkWidget* wxComboBox::GetConnectWidget() return GTK_WIDGET( entry ); } -bool wxComboBox::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const { - GtkEntry *entry = NULL; #ifdef __WXGTK24__ if (!gtk_check_version(2,4,0)) { - entry = GTK_ENTRY( GTK_BIN(m_widget)->child ); - return (window == entry->text_area); + wxUnusedVar(windows); + + return GTK_ENTRY(GTK_BIN(m_widget)->child)->text_area; } else -#endif +#endif // GTK+ 2.4 { - entry = GTK_ENTRY( GTK_COMBO(m_widget)->entry ); - return ( (window == entry->text_area) || - (window == GTK_COMBO(m_widget)->button->window ) ); + windows.push_back(GTK_ENTRY(GTK_COMBO(m_widget)->entry)->text_area); + windows.push_back(GTK_COMBO(m_widget)->button->window); + + // indicate that we return multiple windows in the windows array + return NULL; } } diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index 613ed139fa..21e35fd0d2 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -366,4 +366,19 @@ wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new, return attr; } +// ---------------------------------------------------------------------------- +// idle handling +// ---------------------------------------------------------------------------- + +void wxControl::OnInternalIdle() +{ + if ( GtkShowFromOnIdle() ) + return; + + GTKUpdateCursor(); + + if ( wxUpdateUIEvent::CanUpdate(this) ) + UpdateWindowUI(wxUPDATE_UI_FROMIDLE); +} + #endif // wxUSE_CONTROLS diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp index b8dfb49c81..756cd7f21b 100644 --- a/src/gtk/notebook.cpp +++ b/src/gtk/notebook.cpp @@ -847,10 +847,12 @@ void wxNotebook::DoApplyWidgetStyle(GtkRcStyle *style) gtk_widget_modify_style(GTK_WIDGET(GetNotebookPage(i)->m_label), style); } -bool wxNotebook::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const { - return ((m_widget->window == window) || - GTK_NOTEBOOK(m_widget)->event_window == window); + windows.push_back(m_widget->window); + windows.push_back(GTK_NOTEBOOK(m_widget)->event_window); + + return NULL; } // static diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp index 7af0bde3dd..9117e587ac 100644 --- a/src/gtk/radiobox.cpp +++ b/src/gtk/radiobox.cpp @@ -52,7 +52,6 @@ public: WX_DEFINE_LIST( wxRadioBoxButtonsInfoList ); extern bool g_blockEventsOnDrag; -extern wxWindowGTK *g_delayedFocus; //----------------------------------------------------------------------------- // "clicked" @@ -638,30 +637,27 @@ void wxRadioBox::DoSetItemToolTip(unsigned int n, wxToolTip *tooltip) #endif // wxUSE_TOOLTIPS -bool wxRadioBox::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const { - if (window == m_widget->window) - return true; + windows.push_back(m_widget->window); wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst(); while (node) { GtkWidget *button = GTK_WIDGET( node->GetData()->button ); - if (window == button->window) - return true; + windows.push_back(button->window); node = node->GetNext(); } - return false; + return NULL; } void wxRadioBox::OnInternalIdle() { - // Check if we have to show window now - if (GtkShowFromOnIdle()) return; - + wxControl::OnInternalIdle(); + if ( m_lostFocus ) { m_hasFocus = false; @@ -672,18 +668,6 @@ void wxRadioBox::OnInternalIdle() (void)GetEventHandler()->ProcessEvent( event ); } - - if (g_delayedFocus == this) - { - if (GTK_WIDGET_REALIZED(m_widget)) - { - g_delayedFocus = NULL; - SetFocus(); - } - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } // static diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp index cf56a75187..400b101454 100644 --- a/src/gtk/radiobut.cpp +++ b/src/gtk/radiobut.cpp @@ -21,8 +21,6 @@ //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; -extern wxCursor g_globalCursor; -extern wxWindowGTK *g_delayedFocus; //----------------------------------------------------------------------------- // "clicked" @@ -167,38 +165,10 @@ void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style) gtk_widget_modify_style(GTK_BIN(m_widget)->child, style); } -bool wxRadioButton::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow * +wxRadioButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - return window == GTK_BUTTON(m_widget)->event_window; -} - -void wxRadioButton::OnInternalIdle() -{ - wxCursor cursor = m_cursor; - if (g_globalCursor.Ok()) cursor = g_globalCursor; - - GdkWindow *win = GTK_BUTTON(m_widget)->event_window; - if ( win && 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. */ - - gdk_window_set_cursor( win, cursor.GetCursor() ); - } - - if (g_delayedFocus == this) - { - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_grab_focus( m_widget ); - g_delayedFocus = NULL; - } - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); + return GTK_BUTTON(m_widget)->event_window; } wxSize wxRadioButton::DoGetBestSize() const diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp index d0a691baea..f1d1efc384 100644 --- a/src/gtk/scrolbar.cpp +++ b/src/gtk/scrolbar.cpp @@ -248,10 +248,9 @@ void wxScrollBar::SetRange(int range) SetScrollbar(GetThumbPosition(), GetThumbSize(), range, GetPageSize()); } -bool wxScrollBar::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxScrollBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - GtkRange *range = GTK_RANGE(m_widget); - return ( (window == GTK_WIDGET(range)->window) ); + return GTK_WIDGET(GTK_RANGE(m_widget))->window; } // static diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp index 5e8098e47c..5cde6b19f6 100644 --- a/src/gtk/slider.cpp +++ b/src/gtk/slider.cpp @@ -401,10 +401,9 @@ int wxSlider::GetLineSize() const return int(gtk_range_get_adjustment (GTK_RANGE (m_widget))->step_increment); } -bool wxSlider::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxSlider::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - GtkRange *range = GTK_RANGE(m_widget); - return (range->event_window == window); + return GTK_RANGE(m_widget)->event_window; } // static diff --git a/src/gtk/spinbutt.cpp b/src/gtk/spinbutt.cpp index 6dbfe5b107..25c26b63a0 100644 --- a/src/gtk/spinbutt.cpp +++ b/src/gtk/spinbutt.cpp @@ -176,9 +176,9 @@ void wxSpinButton::OnSize( wxSizeEvent &WXUNUSED(event) ) gtk_widget_set_size_request( m_widget, m_width, m_height ); } -bool wxSpinButton::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxSpinButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - return GTK_SPIN_BUTTON(m_widget)->panel == window; + return GTK_SPIN_BUTTON(m_widget)->panel; } wxSize wxSpinButton::DoGetBestSize() const diff --git a/src/gtk/spinctrl.cpp b/src/gtk/spinctrl.cpp index 0e91452d8c..2cea9634f5 100644 --- a/src/gtk/spinctrl.cpp +++ b/src/gtk/spinctrl.cpp @@ -249,16 +249,20 @@ void wxSpinCtrl::OnChar( wxKeyEvent &event ) event.Skip(); } -bool wxSpinCtrl::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxSpinCtrl::GTKGetWindow(wxArrayGdkWindows& windows) const { GtkSpinButton* spinbutton = GTK_SPIN_BUTTON(m_widget); - return window == spinbutton->entry.text_area || window == spinbutton->panel; + + windows.push_back(spinbutton->entry.text_area); + windows.push_back(spinbutton->panel); + + return NULL; } wxSize wxSpinCtrl::DoGetBestSize() const { wxSize ret( wxControl::DoGetBestSize() ); - wxSize best(95, ret.y); + wxSize best(95, ret.y); // FIXME: 95? CacheBestSize(best); return best; } diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 64a6796cb5..59ff4e0486 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -31,12 +31,6 @@ #include "wx/gtk/private.h" #include -//----------------------------------------------------------------------------- -// data -//----------------------------------------------------------------------------- - -extern wxWindowGTK *g_delayedFocus; - // ---------------------------------------------------------------------------- // helpers // ---------------------------------------------------------------------------- @@ -1547,15 +1541,16 @@ GtkWidget* wxTextCtrl::GetConnectWidget() return GTK_WIDGET(m_text); } -bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window ) +GdkWindow *wxTextCtrl::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { if ( IsMultiLine() ) { - return window == gtk_text_view_get_window( GTK_TEXT_VIEW( m_text ), GTK_TEXT_WINDOW_TEXT ); // pure guesswork + return gtk_text_view_get_window(GTK_TEXT_VIEW(m_text), + GTK_TEXT_WINDOW_TEXT ); } else { - return (window == GTK_ENTRY(m_text)->text_area); + return GTK_ENTRY(m_text)->text_area; } } @@ -1717,24 +1712,6 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) event.Enable( CanRedo() ); } -void wxTextCtrl::OnInternalIdle() -{ - // Check if we have to show window now - if (GtkShowFromOnIdle()) return; - - if (g_delayedFocus == this) - { - if (GTK_WIDGET_REALIZED(m_widget)) - { - gtk_widget_grab_focus( m_widget ); - g_delayedFocus = NULL; - } - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - wxSize wxTextCtrl::DoGetBestSize() const { // FIXME should be different for multi-line controls... diff --git a/src/gtk/tglbtn.cpp b/src/gtk/tglbtn.cpp index a7a7b47926..cc2f7db78d 100644 --- a/src/gtk/tglbtn.cpp +++ b/src/gtk/tglbtn.cpp @@ -30,7 +30,6 @@ #include "wx/gtk/private.h" extern bool g_blockEventsOnDrag; -extern wxCursor g_globalCursor; extern "C" { static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb) @@ -174,37 +173,12 @@ void wxToggleBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style) gtk_widget_modify_style(GTK_BIN(m_widget)->child, style); } -bool wxToggleBitmapButton::IsOwnGtkWindow(GdkWindow *window) +GdkWindow * +wxToggleBitmapButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - return window == GTK_BUTTON(m_widget)->event_window; + return GTK_BUTTON(m_widget)->event_window; } -void wxToggleBitmapButton::OnInternalIdle() -{ - // Check if we have to show window now - if (GtkShowFromOnIdle()) return; - - wxCursor cursor = m_cursor; - - if (g_globalCursor.Ok()) - cursor = g_globalCursor; - - GdkWindow *win = GTK_BUTTON(m_widget)->event_window; - if ( win && 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. */ - - gdk_window_set_cursor(win, cursor.GetCursor()); - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - - // Get the "best" size for this control. wxSize wxToggleBitmapButton::DoGetBestSize() const { @@ -318,34 +292,12 @@ void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style) gtk_widget_modify_style(GTK_BIN(m_widget)->child, style); } -bool wxToggleButton::IsOwnGtkWindow(GdkWindow *window) +GdkWindow * +wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { - return window == GTK_BUTTON(m_widget)->event_window; + return GTK_BUTTON(m_widget)->event_window; } -void wxToggleButton::OnInternalIdle() -{ - wxCursor cursor = m_cursor; - - if (g_globalCursor.Ok()) - cursor = g_globalCursor; - - GdkWindow *win = GTK_BUTTON(m_widget)->event_window; - if ( win && 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. */ - - gdk_window_set_cursor(win, cursor.GetCursor()); - } - - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - - // Get the "best" size for this control. wxSize wxToggleButton::DoGetBestSize() const { diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index d94f9f2b0a..b5ebaaea80 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1406,42 +1406,79 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) return win; } +// ---------------------------------------------------------------------------- +// common event handlers helpers +// ---------------------------------------------------------------------------- + +bool wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const +{ + DEBUG_MAIN_THREAD + + if (g_isIdle) + wxapp_install_idle_handler(); + + if (!m_hasVMT) + return false; + if (g_blockEventsOnDrag) + return true; + if (g_blockEventsOnScroll) + return true; + + if (!GTKIsOwnWindow(event->window)) + return false; + + return true; +} + +// overloads for all GDK event types we use here: we need to have this as +// GdkEventXXX can't be implicitly cast to GdkEventAny even if it, in fact, +// derives from it in the sense that the structs have the same layout +#define wxDEFINE_COMMON_PROLOGUE_OVERLOAD(T) \ + static bool wxGtkCallbackCommonPrologue(T *event, wxWindowGTK *win) \ + { \ + return win->GTKCallbackCommonPrologue((GdkEventAny *)event); \ + } + +wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventButton) +wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventMotion) +wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventCrossing) + +#undef wxDEFINE_COMMON_PROLOGUE_OVERLOAD + +// send the wxChildFocusEvent and wxFocusEvent, common code of +// gtk_window_focus_in_callback() and SetFocus() +static bool DoSendFocusEvents(wxWindow *win) +{ + // Notify the parent keeping track of focus for the kbd navigation + // purposes that we got it. + wxChildFocusEvent eventChildFocus(win); + (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); + + wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); + eventFocus.SetEventObject(win); + + return win->GetEventHandler()->ProcessEvent(eventFocus); +} + +// all event handlers must have C linkage as they're called from GTK+ C code +extern "C" +{ + //----------------------------------------------------------------------------- // "button_press_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindowGTK *win ) { - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - -/* - wxPrintf( wxT("1) OnButtonPress from ") ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( wxT(".\n") ); -*/ - if (!win->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return TRUE; - if (g_blockEventsOnScroll) return TRUE; - - if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; + if ( !wxGtkCallbackCommonPrologue(gdk_event, win) ) + return FALSE; if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus()) { gtk_widget_grab_focus( win->m_wxwindow ); -/* - wxPrintf( wxT("GrabFocus from ") ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( wxT(".\n") ); -*/ } // GDK sends surplus button down events @@ -1599,28 +1636,18 @@ gtk_window_button_press_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "button_release_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindowGTK *win ) { - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - - if (!win->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return FALSE; - if (g_blockEventsOnScroll) return FALSE; - - if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; + if ( !wxGtkCallbackCommonPrologue(gdk_event, win) ) + return FALSE; wxEventType event_type = wxEVT_NULL; @@ -1666,28 +1693,18 @@ gtk_window_button_release_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "motion_notify_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindowGTK *win ) { - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - - if (!win->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return FALSE; - if (g_blockEventsOnScroll) return FALSE; - - if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; + if ( !wxGtkCallbackCommonPrologue(gdk_event, win) ) + return FALSE; if (gdk_event->is_hint) { @@ -1699,13 +1716,6 @@ gtk_window_motion_notify_callback( GtkWidget *widget, gdk_event->y = y; } -/* - printf( "OnMotion from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - printf( ".\n" ); -*/ - wxMouseEvent event( wxEVT_MOTION ); InitMouseEvent(win, event, gdk_event); @@ -1756,13 +1766,11 @@ gtk_window_motion_notify_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "scroll_event", (mouse wheel event) //----------------------------------------------------------------------------- -extern "C" { static gboolean window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win) { @@ -1804,43 +1812,22 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win) return win->GetEventHandler()->ProcessEvent(event); } -} //----------------------------------------------------------------------------- // "popup-menu" //----------------------------------------------------------------------------- -extern "C" { + static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win) { - wxContextMenuEvent event( - wxEVT_CONTEXT_MENU, - win->GetId(), - wxPoint(-1, -1)); + wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1)); event.SetEventObject(win); return win->GetEventHandler()->ProcessEvent(event); } -} //----------------------------------------------------------------------------- // "focus_in_event" //----------------------------------------------------------------------------- -// send the wxChildFocusEvent and wxFocusEvent, common code of -// gtk_window_focus_in_callback() and SetFocus() -static bool DoSendFocusEvents(wxWindow *win) -{ - // Notify the parent keeping track of focus for the kbd navigation - // purposes that we got it. - wxChildFocusEvent eventChildFocus(win); - (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); - - wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); - eventFocus.SetEventObject(win); - - return win->GetEventHandler()->ProcessEvent(eventFocus); -} - -extern "C" { static gboolean gtk_window_focus_in_callback( GtkWidget *widget, GdkEventFocus *WXUNUSED(event), @@ -1894,13 +1881,11 @@ gtk_window_focus_in_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "focus_out_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, @@ -1961,31 +1946,22 @@ gtk_window_focus_out_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "enter_notify_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindowGTK *win ) { - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - - if (!win->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return FALSE; + if ( !wxGtkCallbackCommonPrologue(gdk_event, win) ) + return FALSE; // Event was emitted after a grab if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE; - if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; - int x = 0; int y = 0; GdkModifierType state = (GdkModifierType)0; @@ -2015,31 +1991,22 @@ gtk_window_enter_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "leave_notify_event" //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindowGTK *win ) { - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - - if (!win->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return FALSE; + if ( !wxGtkCallbackCommonPrologue(gdk_event, win) ) + return FALSE; // Event was emitted after an ungrab if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE; - if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; - wxMouseEvent event( wxEVT_LEAVE_WINDOW ); event.SetTimestamp( gdk_event->time ); event.SetEventObject( win ); @@ -2070,13 +2037,11 @@ gtk_window_leave_callback( GtkWidget *widget, return FALSE; } -} //----------------------------------------------------------------------------- // "value_changed" from scrollbar //----------------------------------------------------------------------------- -extern "C" { static void gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win) { @@ -2099,13 +2064,11 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win) win->m_blockValueChanged[dir] = false; } } -} //----------------------------------------------------------------------------- // "button_press_event" from scrollbar //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win) { @@ -2119,13 +2082,11 @@ gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win) return false; } -} //----------------------------------------------------------------------------- // "event_after" from scrollbar //----------------------------------------------------------------------------- -extern "C" { static void gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) { @@ -2140,13 +2101,11 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) win->GetEventHandler()->ProcessEvent(event); } } -} //----------------------------------------------------------------------------- // "button_release_event" from scrollbar //----------------------------------------------------------------------------- -extern "C" { static gboolean gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* win) { @@ -2166,18 +2125,6 @@ gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* w return false; } -} - -// ---------------------------------------------------------------------------- -// this wxWindowBase function is implemented here (in platform-specific file) -// because it is static and so couldn't be made virtual -// ---------------------------------------------------------------------------- - -wxWindow *wxWindowBase::DoFindFocus() -{ - // the cast is necessary when we compile in wxUniversal mode - return (wxWindow *)g_focusWindow; -} //----------------------------------------------------------------------------- // "realize" from m_widget @@ -2186,7 +2133,6 @@ wxWindow *wxWindowBase::DoFindFocus() /* We cannot set colours and fonts before the widget has been realized, so we do this directly after realization. */ -extern "C" { static void gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) { @@ -2206,13 +2152,11 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); } -} //----------------------------------------------------------------------------- // "size_allocate" //----------------------------------------------------------------------------- -extern "C" { static void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation *WXUNUSED(alloc), @@ -2237,7 +2181,6 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), win->GetEventHandler()->ProcessEvent( event ); } } -} #ifdef HAVE_XIM @@ -2247,8 +2190,6 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), #endif /* Resize XIM window */ - -extern "C" { static void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), GtkAllocation* WXUNUSED_UNLESS_XIM(alloc), @@ -2272,7 +2213,6 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), } #endif // HAVE_XIM } -} //----------------------------------------------------------------------------- // "realize" from m_wxwindow @@ -2280,7 +2220,6 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), /* Initialize XIM support */ -extern "C" { static void gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), wxWindowGTK * WXUNUSED_UNLESS_XIM(win) ) @@ -2365,6 +2304,18 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), } #endif // HAVE_XIM } + +} // extern "C" + +// ---------------------------------------------------------------------------- +// this wxWindowBase function is implemented here (in platform-specific file) +// because it is static and so couldn't be made virtual +// ---------------------------------------------------------------------------- + +wxWindow *wxWindowBase::DoFindFocus() +{ + // the cast is necessary when we compile in wxUniversal mode + return (wxWindow *)g_focusWindow; } //----------------------------------------------------------------------------- @@ -3375,6 +3326,22 @@ void wxWindowGTK::GetTextExtent( const wxString& string, g_object_unref (layout); } +bool wxWindowGTK::GTKSetDelayedFocusIfNeeded() +{ + if ( g_delayedFocus == this ) + { + if ( GTK_WIDGET_REALIZED(m_widget) ) + { + gtk_widget_grab_focus(m_widget); + g_delayedFocus = NULL; + + return true; + } + } + + return false; +} + void wxWindowGTK::SetFocus() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); @@ -3626,10 +3593,29 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor ) if (g_isIdle) wxapp_install_idle_handler(); - if (cursor == wxNullCursor) - return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); - else - return wxWindowBase::SetCursor( cursor ); + return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR ); +} + +void wxWindowGTK::GTKUpdateCursor() +{ + wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor()); + if ( cursor.Ok() ) + { + wxArrayGdkWindows windowsThis; + GdkWindow * const winThis = GTKGetWindow(windowsThis); + if ( winThis ) + { + gdk_window_set_cursor(winThis, cursor.GetCursor()); + } + else + { + const size_t count = windowsThis.size(); + for ( size_t n = 0; n < count; n++ ) + { + gdk_window_set_cursor(windowsThis[n], cursor.GetCursor()); + } + } + } } void wxWindowGTK::WarpPointer( int x, int y ) @@ -4043,12 +4029,18 @@ GtkWidget* wxWindowGTK::GetConnectWidget() return connect_widget; } -bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window ) +bool wxWindowGTK::GTKIsOwnWindow(GdkWindow *window) const { - if (m_wxwindow) - return (window == GTK_PIZZA(m_wxwindow)->bin_window); + wxArrayGdkWindows windowsThis; + GdkWindow * const winThis = GTKGetWindow(windowsThis); - return (window == m_widget->window); + return winThis ? window == winThis + : windowsThis.Index(window) != wxNOT_FOUND; +} + +GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const +{ + return m_wxwindow ? GTK_PIZZA(m_wxwindow)->bin_window : m_widget->window; } bool wxWindowGTK::SetFont( const wxFont &font ) -- 2.45.2