diff --git a/include/wx/containr.h b/include/wx/containr.h index e6750713bc..af248caf73 100644 --- a/include/wx/containr.h +++ b/include/wx/containr.h @@ -14,7 +14,7 @@ #define _WX_CONTAINR_H_ // use native tab traversal logic under GTK+ 2 (doesn't work yet) -#if 0 // def __WXGTK20__ +#ifdef __WXGTK20__ #define wxHAS_NATIVE_TAB_TRAVERSAL #endif diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 9c92179ca3..e8d0e60fe3 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -68,7 +68,6 @@ public: virtual bool IsRetained() const; virtual void SetFocus(); - virtual bool AcceptsFocus() const; virtual bool Reparent( wxWindowBase *newParent ); @@ -183,7 +182,7 @@ public: protected: // Override GTKWidgetNeedsMnemonic and return true if your - // needs to set its mnemonic widget, such as for a + // needs to set its mnemonic widget, such as for a // GtkLabel for wxStaticText, then do the actual // setting of the widget inside GTKWidgetDoSetMnemonic virtual bool GTKWidgetNeedsMnemonic() const; @@ -219,13 +218,13 @@ public: // the layouting functions have to be called later on // (i.e. in idle time, implemented in OnInternalIdle() ). void GtkUpdateSize() { m_sizeSet = false; } - - + + // Called when a window should delay showing itself // until idle time. This partly mimmicks defered // sizing under MSW. void GtkShowOnIdle() { m_showOnIdle = true; } - + // This is called from the various OnInternalIdle methods bool GtkShowFromOnIdle(); @@ -299,7 +298,6 @@ public: bool m_hasVMT:1; bool m_sizeSet:1; bool m_resizing:1; - bool m_acceptsFocus:1; // true if not static bool m_hasFocus:1; // true if == FindFocus() bool m_isScrolling:1; // dragging scrollbar thumb? bool m_clipPaintRegion:1; // true after ScrollWindow() @@ -310,7 +308,7 @@ public: // background style until OnIdle bool m_mouseButtonDown:1; bool m_blockScrollEvent:1; - + bool m_showOnIdle:1; // postpone showing the window until idle // C++ has no virtual methods in the constrcutor of any class but we need diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp index e6e6b8b0f9..2999905883 100644 --- a/src/gtk/animate.cpp +++ b/src/gtk/animate.cpp @@ -200,7 +200,6 @@ bool wxAnimationCtrl::Create( wxWindow *parent, wxWindowID id, const wxString& name) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !base_type::CreateBase(parent, id, pos, size, style & wxWINDOW_STYLE_MASK, diff --git a/src/gtk/bmpbuttn.cpp b/src/gtk/bmpbuttn.cpp index cc9f6d14e7..6ec496ea1a 100644 --- a/src/gtk/bmpbuttn.cpp +++ b/src/gtk/bmpbuttn.cpp @@ -125,7 +125,6 @@ bool wxBitmapButton::Create( wxWindow *parent, const wxString &name ) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp index 35e0b4f537..3e4e83feeb 100644 --- a/src/gtk/button.cpp +++ b/src/gtk/button.cpp @@ -111,7 +111,6 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label, long style, const wxValidator& validator, const wxString &name ) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index 7dcc25d78f..f3352a1397 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -110,7 +110,6 @@ bool wxCheckBox::Create(wxWindow *parent, const wxString &name ) { m_needParent = true; - m_acceptsFocus = true; m_blockEvent = false; if (!PreCreation( parent, pos, size ) || diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp index 02b6c41b2a..b159c5e984 100644 --- a/src/gtk/choice.cpp +++ b/src/gtk/choice.cpp @@ -98,9 +98,6 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString &name ) { m_needParent = true; -#if (GTK_MINOR_VERSION > 0) - m_acceptsFocus = true; -#endif if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) diff --git a/src/gtk/clrpicker.cpp b/src/gtk/clrpicker.cpp index a8ed5ef927..a710f9fa33 100644 --- a/src/gtk/clrpicker.cpp +++ b/src/gtk/clrpicker.cpp @@ -62,7 +62,6 @@ bool wxColourButton::Create( wxWindow *parent, wxWindowID id, if (!gtk_check_version(2,4,0)) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !wxControl::CreateBase(parent, id, pos, size, style, validator, name)) diff --git a/src/gtk/collpane.cpp b/src/gtk/collpane.cpp index 93b0be56e1..3ba9f7e25f 100644 --- a/src/gtk/collpane.cpp +++ b/src/gtk/collpane.cpp @@ -199,7 +199,6 @@ bool wxCollapsiblePane::Create(wxWindow *parent, pos, size, style, val, name); m_needParent = true; - m_acceptsFocus = true; m_bIgnoreNextChange = false; if ( !PreCreation( parent, pos, size ) || diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp index d4c88afb03..1a4e40ce0f 100644 --- a/src/gtk/combobox.cpp +++ b/src/gtk/combobox.cpp @@ -251,7 +251,6 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, { m_ignoreNextUpdate = false; m_needParent = true; - m_acceptsFocus = true; m_prevSelection = 0; if (!PreCreation( parent, pos, size ) || diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index c075c1dfe4..a7c4bc7c72 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -1882,7 +1882,6 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, Init(); m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator )) diff --git a/src/gtk/filepicker.cpp b/src/gtk/filepicker.cpp index c79eb51426..32d0c62808 100644 --- a/src/gtk/filepicker.cpp +++ b/src/gtk/filepicker.cpp @@ -47,7 +47,6 @@ bool wxFileButton::Create( wxWindow *parent, wxWindowID id, // if you find a problem here, fix it also in wxDirButton ! m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !wxControl::CreateBase(parent, id, pos, size, style & wxWINDOW_STYLE_MASK, @@ -197,7 +196,6 @@ bool wxDirButton::Create( wxWindow *parent, wxWindowID id, // if you find a problem here, fix it also in wxFileButton ! m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !wxControl::CreateBase(parent, id, pos, size, style & wxWINDOW_STYLE_MASK, diff --git a/src/gtk/fontpicker.cpp b/src/gtk/fontpicker.cpp index bc24c2e8d8..97102051c8 100644 --- a/src/gtk/fontpicker.cpp +++ b/src/gtk/fontpicker.cpp @@ -61,7 +61,6 @@ bool wxFontButton::Create( wxWindow *parent, wxWindowID id, if (!gtk_check_version(2,4,0)) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !wxControl::CreateBase(parent, id, pos, size, style, validator, name)) diff --git a/src/gtk/hyperlink.cpp b/src/gtk/hyperlink.cpp index 697d7e358b..046c601aeb 100644 --- a/src/gtk/hyperlink.cpp +++ b/src/gtk/hyperlink.cpp @@ -77,7 +77,6 @@ bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id, CheckParams(label, url, style); m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index e4bbf51aae..1502a4f4f7 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -335,7 +335,6 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, const wxString &name ) { m_needParent = true; - m_acceptsFocus = true; m_blockEvent = false; if (!PreCreation( parent, pos, size ) || diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp index 172bc4b120..14ce6bfac3 100644 --- a/src/gtk/notebook.cpp +++ b/src/gtk/notebook.cpp @@ -162,77 +162,6 @@ gtk_notebook_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win ) } } -//----------------------------------------------------------------------------- -// "key_press_event" -//----------------------------------------------------------------------------- - -extern "C" { -static gboolean -gtk_notebook_key_press_callback( GtkWidget *widget, - GdkEventKey *gdk_event, - wxNotebook *notebook ) -{ - // don't need to install idle handler, its done from "event" signal - - if (!notebook->m_hasVMT) return FALSE; - if (g_blockEventsOnDrag) return FALSE; - - /* win is a control: tab can be propagated up */ - if ((gdk_event->keyval == GDK_Left) || (gdk_event->keyval == GDK_Right)) - { - int page; - int nMax = notebook->GetPageCount(); - if ( nMax-- ) // decrement it to get the last valid index - { - int nSel = notebook->GetSelection(); - - // change selection wrapping if it becomes invalid - page = (gdk_event->keyval != GDK_Left) ? nSel == nMax ? 0 - : nSel + 1 - : nSel == 0 ? nMax - : nSel - 1; - } - else // notebook is empty, no next page - { - return FALSE; - } - - gtk_notebook_set_current_page( GTK_NOTEBOOK(widget), page ); - - return TRUE; - } - - /* win is a control: tab can be propagated up */ - if ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) - { - int sel = notebook->GetSelection(); - if (sel == -1) - return TRUE; - wxGtkNotebookPage *nb_page = notebook->GetNotebookPage(sel); - wxCHECK_MSG( nb_page, FALSE, _T("invalid selection in wxNotebook") ); - - wxNavigationKeyEvent event; - event.SetEventObject( notebook ); - /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ - event.SetDirection( (gdk_event->keyval == GDK_Tab) ); - /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ - event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) || - (gdk_event->keyval == GDK_Left) || (gdk_event->keyval == GDK_Right) ); - event.SetCurrentFocus( notebook ); - - wxNotebookPage *client = notebook->GetPage(sel); - if ( !client->GetEventHandler()->ProcessEvent( event ) ) - { - client->SetFocus(); - } - - return TRUE; - } - - return FALSE; -} -} - //----------------------------------------------------------------------------- // InsertChild callback for wxNotebook //----------------------------------------------------------------------------- @@ -296,7 +225,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name ) { m_needParent = true; - m_acceptsFocus = true; m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook; if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT ) @@ -329,9 +257,6 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id, if (m_windowStyle & wxBK_BOTTOM) gtk_notebook_set_tab_pos( GTK_NOTEBOOK(m_widget), GTK_POS_BOTTOM ); - g_signal_connect (m_widget, "key_press_event", - G_CALLBACK (gtk_notebook_key_press_callback), this); - PostCreation(size); g_signal_connect (m_widget, "realize", diff --git a/src/gtk/popupwin.cpp b/src/gtk/popupwin.cpp index 8d1a10b4f9..2de47c76c0 100644 --- a/src/gtk/popupwin.cpp +++ b/src/gtk/popupwin.cpp @@ -65,21 +65,6 @@ static gint gtk_popup_button_press (GtkWidget *widget, GdkEvent *gdk_event, wxPo } } -//----------------------------------------------------------------------------- -// "focus" from m_window -//----------------------------------------------------------------------------- - -extern "C" { -static gint gtk_dialog_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) ) -{ - if (g_isIdle) - wxapp_install_idle_handler(); - - /* This disables GTK's tab traversal */ - return TRUE; -} -} - //----------------------------------------------------------------------------- // "delete_event" //----------------------------------------------------------------------------- @@ -209,10 +194,6 @@ bool wxPopupWindow::Create( wxWindow *parent, int style ) g_signal_connect (m_widget, "realize", G_CALLBACK (gtk_dialog_realized_callback), this); - // disable native tab traversal - g_signal_connect (m_widget, "focus", - G_CALLBACK (gtk_dialog_focus_callback), this); - m_time = gtk_get_current_event_time(); g_signal_connect (m_widget, "button_press_event", diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp index e84d215469..911aa6ccab 100644 --- a/src/gtk/radiobox.cpp +++ b/src/gtk/radiobox.cpp @@ -219,7 +219,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl) void wxRadioBox::Init() { m_needParent = true; - m_acceptsFocus = true; m_hasFocus = m_lostFocus = false; diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp index 400b101454..f52faff09e 100644 --- a/src/gtk/radiobut.cpp +++ b/src/gtk/radiobut.cpp @@ -62,7 +62,6 @@ bool wxRadioButton::Create( wxWindow *parent, const wxValidator& validator, const wxString& name ) { - m_acceptsFocus = TRUE; m_needParent = TRUE; m_blockEvent = FALSE; diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp index 00ea880973..492678bd88 100644 --- a/src/gtk/scrolbar.cpp +++ b/src/gtk/scrolbar.cpp @@ -134,7 +134,6 @@ bool wxScrollBar::Create(wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString& name ) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp index 269d2c4921..a8c1451100 100644 --- a/src/gtk/slider.cpp +++ b/src/gtk/slider.cpp @@ -288,7 +288,6 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name ) { - m_acceptsFocus = true; m_needParent = true; if (!PreCreation( parent, pos, size ) || diff --git a/src/gtk/spinctrl.cpp b/src/gtk/spinctrl.cpp index 2cea9634f5..1c0a9fcfa0 100644 --- a/src/gtk/spinctrl.cpp +++ b/src/gtk/spinctrl.cpp @@ -102,7 +102,6 @@ bool wxSpinCtrl::Create(wxWindow *parent, wxWindowID id, const wxString& name) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index caa6405299..4fc49796fb 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -685,7 +685,6 @@ bool wxTextCtrl::Create( wxWindow *parent, const wxString &name ) { m_needParent = true; - m_acceptsFocus = true; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) diff --git a/src/gtk/tglbtn.cpp b/src/gtk/tglbtn.cpp index c90a09ec6d..134fa7a9d5 100644 --- a/src/gtk/tglbtn.cpp +++ b/src/gtk/tglbtn.cpp @@ -59,7 +59,6 @@ bool wxToggleBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxString &name) { m_needParent = true; - m_acceptsFocus = true; m_blockEvent = false; @@ -202,7 +201,6 @@ bool wxToggleButton::Create(wxWindow *parent, wxWindowID id, const wxString &name) { m_needParent = true; - m_acceptsFocus = true; m_blockEvent = false; diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index e3e320f77e..7227e4887f 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -197,23 +197,6 @@ static gboolean gtk_frame_focus_out_callback( GtkWidget *widget, } } -//----------------------------------------------------------------------------- -// "focus" from m_window -//----------------------------------------------------------------------------- - -extern "C" { -static gboolean gtk_frame_focus_callback( GtkWidget *WXUNUSED(widget), - GtkDirectionType WXUNUSED(d), - wxWindow *WXUNUSED(win) ) -{ - if (g_isIdle) - wxapp_install_idle_handler(); - - // This disables GTK's tab traversal - return TRUE; -} -} - //----------------------------------------------------------------------------- // "size_allocate" //----------------------------------------------------------------------------- @@ -628,10 +611,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, g_signal_connect (m_widget, "configure_event", G_CALLBACK (gtk_frame_configure_callback), this); - // disable native tab traversal - g_signal_connect (m_widget, "focus", - G_CALLBACK (gtk_frame_focus_callback), this); - // activation g_signal_connect_after (m_widget, "focus_in_event", G_CALLBACK (gtk_frame_focus_in_callback), this); diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c index 2b6944fb3e..caa1b5f497 100644 --- a/src/gtk/win_gtk.c +++ b/src/gtk/win_gtk.c @@ -198,6 +198,7 @@ gtk_pizza_child_type (GtkContainer *container) static void gtk_pizza_init (GtkPizza *pizza) { + GTK_WIDGET_SET_FLAGS (pizza, GTK_CAN_FOCUS); GTK_WIDGET_UNSET_FLAGS (pizza, GTK_NO_WINDOW); pizza->children = NULL; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 3d372237ed..291b13c614 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1114,30 +1114,6 @@ gtk_window_key_press_callback( GtkWidget *widget, } } - // win is a control: tab can be propagated up - if ( !ret && - ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && -// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here - the control may -// have this style, yet choose not to process this particular TAB in which -// case TAB must still work as a navigational character -// JS: enabling again to make consistent with other platforms -// (with wxTE_PROCESS_TAB you have to call Navigate to get default -// navigation behaviour) -#if wxUSE_TEXTCTRL - (! (win->HasFlag(wxTE_PROCESS_TAB) && win->IsKindOf(CLASSINFO(wxTextCtrl)) )) && -#endif - win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) - { - wxNavigationKeyEvent new_event; - new_event.SetEventObject( win->GetParent() ); - // GDK reports GDK_ISO_Left_Tab for SHIFT-TAB - new_event.SetDirection( (gdk_event->keyval == GDK_Tab) ); - // CTRL-TAB changes the (parent) window, i.e. switch notebook page - new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); - new_event.SetCurrentFocus( win ); - ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); - } - return ret; } } @@ -1928,6 +1904,25 @@ gtk_window_focus_out_callback( GtkWidget *widget, return FALSE; } +static gboolean +wx_window_focus_callback(GtkWidget *widget, + GtkDirectionType direction, + wxWindowGTK *win) +{ + // the default handler for focus signal in GtkPizza (or, rather, in + // GtkScrolledWindow from which GtkPizza inherits this behaviour) sets + // focus to the window itself even if it doesn't accept focus, i.e. has no + // GTK_CAN_FOCUS in its style -- work around this by forcibly preventing + // the signal from reaching gtk_scrolled_window_focus() if we don't have + // any children which might accept focus (we know we don't accept the focus + // ourselves as this signal is only connected in this case) + if ( win->GetChildren().empty() ) + g_signal_stop_emission_by_name(widget, "focus"); + + // we didn't change the focus + return FALSE; +} + //----------------------------------------------------------------------------- // "enter_notify_event" //----------------------------------------------------------------------------- @@ -2283,7 +2278,6 @@ void wxWindowGTK::Init() m_insertCallback = (wxInsertChildFunction) NULL; - m_acceptsFocus = false; m_hasFocus = false; m_clipPaintRegion = false; @@ -2330,7 +2324,6 @@ bool wxWindowGTK::Create( wxWindow *parent, m_insertCallback = wxInsertChildInWindow; m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); - GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); @@ -2365,9 +2358,6 @@ bool wxWindowGTK::Create( wxWindow *parent, gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); - GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); - m_acceptsFocus = true; - // connect various scroll-related events for ( int dir = 0; dir < ScrollDir_Max; dir++ ) { @@ -2516,6 +2506,16 @@ void wxWindowGTK::PostCreation() } } + if ( !AcceptsFocusFromKeyboard() ) + { + GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + if ( m_wxwindow ) + GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + + g_signal_connect(m_widget, "focus", + G_CALLBACK(wx_window_focus_callback), this); + } + // connect to the various key and mouse handlers GtkWidget *connect_widget = GetConnectWidget(); @@ -3218,11 +3218,6 @@ void wxWindowGTK::SetFocus() } } -bool wxWindowGTK::AcceptsFocus() const -{ - return m_acceptsFocus && wxWindowBase::AcceptsFocus(); -} - bool wxWindowGTK::Reparent( wxWindowBase *newParentBase ) { wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") );