X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/03a126c68c940c13a7a6c9ee183fa88e9b575a21..90df6033544b93f48573c6a5371fefc87f36e564:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 559fc2b744..18a1c409d5 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -19,16 +19,11 @@ #ifndef WX_PRECOMP #include "wx/log.h" #include "wx/app.h" - #include "wx/frame.h" + #include "wx/toplevel.h" #include "wx/dcclient.h" #include "wx/menu.h" #include "wx/settings.h" #include "wx/msgdlg.h" - #include "wx/textctrl.h" - #include "wx/radiobut.h" - #include "wx/toolbar.h" - #include "wx/combobox.h" - #include "wx/layout.h" #include "wx/math.h" #endif @@ -408,9 +403,9 @@ gtk_window_own_expose_callback( GtkWidget *widget, // make it extern because wxStaticText needs to disconnect this one extern "C" { -void wxgtk_window_size_request_callback(GtkWidget *widget, +void wxgtk_window_size_request_callback(GtkWidget * WXUNUSED(widget), GtkRequisition *requisition, - wxWindow *win) + wxWindow * win) { int w, h; win->GetSize( &w, &h ); @@ -428,9 +423,9 @@ void wxgtk_window_size_request_callback(GtkWidget *widget, extern "C" { static -void wxgtk_combo_size_request_callback(GtkWidget *widget, +void wxgtk_combo_size_request_callback(GtkWidget * WXUNUSED(widget), GtkRequisition *requisition, - wxComboBox *win) + wxWindow* win) { // This callback is actually hooked into the text entry // of the combo box, not the GtkHBox. @@ -1013,18 +1008,7 @@ gtk_window_key_press_callback( GtkWidget *widget, return_after_IM = true; } - // 2005.01.26 modified by Hong Jen Yee (hzysoft@sina.com.tw): - // When we get a key_press event here, it could be originate - // from the current widget or its child widgets. However, only the widget - // with the INPUT FOCUS can generate the INITIAL key_press event. That is, - // if the CURRENT widget doesn't have the FOCUS at all, this event definitely - // originated from its child widgets and shouldn't be passed to IM context. - // In fact, what a GTK+ IM should do is filtering keyEvents and convert them - // into text input ONLY WHEN THE WIDGET HAS INPUT FOCUS. Besides, when current - // widgets has both IM context and input focus, the event should be filtered - // by gtk_im_context_filter_keypress(). - // Then, we should, according to GTK+ 2.0 API doc, return whatever it returns. - if ((!ret) && (win->m_imData != NULL) && ( wxWindow::FindFocus() == win )) + if ((!ret) && (win->m_imData != NULL)) { // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API // docs, if IM filter returns true, no further processing should be done. @@ -1127,7 +1111,7 @@ gtk_window_key_press_callback( GtkWidget *widget, extern "C" { static void -gtk_wxwindow_commit_cb (GtkIMContext *context, +gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context), const gchar *str, wxWindow *window) { @@ -1205,7 +1189,7 @@ gtk_wxwindow_commit_cb (GtkIMContext *context, extern "C" { static gboolean -gtk_window_key_release_callback( GtkWidget *widget, +gtk_window_key_release_callback( GtkWidget * WXUNUSED(widget), GdkEventKey *gdk_event, wxWindowGTK *win ) { @@ -1575,7 +1559,7 @@ gtk_window_button_press_callback( GtkWidget *widget, if ( ret ) return TRUE; - if ((event_type == wxEVT_LEFT_DOWN) && !win->IsOfStandardClass() && + if ((event_type == wxEVT_LEFT_DOWN) && !win->IsOfStandardClass() && (g_focusWindow != win) /* && win->IsFocusable() */) { win->SetFocus(); @@ -1664,7 +1648,7 @@ gtk_window_button_release_callback( GtkWidget *widget, //----------------------------------------------------------------------------- static gboolean -gtk_window_motion_notify_callback( GtkWidget *widget, +gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget), GdkEventMotion *gdk_event, wxWindowGTK *win ) { @@ -1774,7 +1758,7 @@ static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win) //----------------------------------------------------------------------------- static gboolean -gtk_window_focus_in_callback( GtkWidget *widget, +gtk_window_focus_in_callback( GtkWidget * WXUNUSED(widget), GdkEventFocus *WXUNUSED(event), wxWindow *win ) { @@ -1824,8 +1808,8 @@ gtk_window_focus_in_callback( GtkWidget *widget, //----------------------------------------------------------------------------- static gboolean -gtk_window_focus_out_callback( GtkWidget *widget, - GdkEventFocus *gdk_event, +gtk_window_focus_out_callback( GtkWidget * WXUNUSED(widget), + GdkEventFocus * WXUNUSED(gdk_event), wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1870,9 +1854,7 @@ gtk_window_focus_out_callback( GtkWidget *widget, // Disable default focus handling for custom windows // since the default GTK+ handler issues a repaint if ( has_wxwindow ) - { return TRUE; - } } // continue with normal processing @@ -1881,7 +1863,7 @@ gtk_window_focus_out_callback( GtkWidget *widget, static gboolean wx_window_focus_callback(GtkWidget *widget, - GtkDirectionType direction, + GtkDirectionType WXUNUSED(direction), wxWindowGTK *win) { // the default handler for focus signal in GtkPizza (or, rather, in @@ -2016,9 +1998,10 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) const int orient = wxWindow::OrientFromScrollDir( win->ScrollDirFromRange(range)); - wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient); - event.SetEventObject(win); - win->GTKProcessEvent(event); + wxScrollWinEvent evt(wxEVT_SCROLLWIN_THUMBRELEASE, + win->GetScrollPos(orient), orient); + evt.SetEventObject(win); + win->GTKProcessEvent(evt); } } @@ -2078,58 +2061,60 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) } //----------------------------------------------------------------------------- -// "size_allocate" +// "size_allocate" from m_wxwindow or m_widget //----------------------------------------------------------------------------- -static -void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), - GtkAllocation *alloc, - wxWindow *win ) +static void +size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win) { - int client_width = 0; - int client_height = 0; - win->GetClientSize( &client_width, &client_height ); - if ((client_width == win->m_oldClientWidth) && (client_height == win->m_oldClientHeight)) - return; - - if ( !client_width && !client_height ) - { - // the window is currently unmapped, don't generate size events - return; - } - - win->m_oldClientWidth = client_width; - win->m_oldClientHeight = client_height; - - if (!win->m_nativeSizeEvent) + int w = alloc->width; + int h = alloc->height; + if (win->m_wxwindow) { - wxSizeEvent event( win->GetSize(), win->GetId() ); - event.SetEventObject( win ); - win->GTKProcessEvent( event ); + const int border = GTK_CONTAINER(win->m_wxwindow)->border_width; + w -= 2 * border; + h -= 2 * border; + if (w < 0) w = 0; + if (h < 0) h = 0; + } + if (win->m_oldClientWidth != w || win->m_oldClientHeight != h) + { + win->m_oldClientWidth = w; + win->m_oldClientHeight = h; + // this callback can be connected to m_wxwindow, + // so always get size from m_widget->allocation + win->m_width = win->m_widget->allocation.width; + win->m_height = win->m_widget->allocation.height; + if (!win->m_nativeSizeEvent) + { + wxSizeEvent event(win->GetSize(), win->GetId()); + event.SetEventObject(win); + win->GTKProcessEvent(event); + } } } //----------------------------------------------------------------------------- -// "grab_broken" +// "grab_broken" //----------------------------------------------------------------------------- -#ifdef __WXGTK210__ -static void -gtk_window_grab_broken( GtkWidget *m_widget, +#if GTK_CHECK_VERSION(2, 8, 0) +static gboolean +gtk_window_grab_broken( GtkWidget*, GdkEventGrabBroken *event, wxWindow *win ) { // Mouse capture has been lost involuntarily, notify the application - if( !event->keyboard && win && wxWindow::GetCapture() == win ) + if(!event->keyboard && wxWindow::GetCapture() == win) { wxMouseCaptureLostEvent evt( win->GetId() ); evt.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( evt ); } + return false; } #endif - } // extern "C" // ---------------------------------------------------------------------------- @@ -2253,8 +2238,6 @@ void wxWindowGTK::Init() m_oldClientWidth = m_oldClientHeight = 0; - m_resizing = false; - m_insertCallback = wxInsertChildInWindow; m_hasFocus = false; @@ -2538,12 +2521,15 @@ void wxWindowGTK::PostCreation() g_signal_connect (connect_widget, "realize", G_CALLBACK (gtk_window_realized_callback), this); + if (!IsTopLevel()) + { + g_signal_connect(m_wxwindow ? m_wxwindow : m_widget, "size_allocate", + G_CALLBACK(size_allocate), this); + } + if (m_wxwindow) { - // Catch native resize events - g_signal_connect (m_wxwindow, "size_allocate", - G_CALLBACK (gtk_window_size_callback), this); -#ifdef __WXGTK210__ +#if GTK_CHECK_VERSION(2, 8, 0) if (!gtk_check_version(2,8,0)) { // Make sure we can notify the app when mouse capture is lost @@ -2555,7 +2541,7 @@ void wxWindowGTK::PostCreation() if ( connect_widget != m_wxwindow ) { -#ifdef __WXGTK210__ +#if GTK_CHECK_VERSION(2, 8, 0) if (!gtk_check_version(2,8,0)) { // Make sure we can notify app code when mouse capture is lost @@ -2667,9 +2653,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") ); - if (m_resizing) return; /* I don't like recursions */ - m_resizing = true; - int currentX, currentY; GetPosition(¤tX, ¤tY); if (x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) @@ -2689,6 +2672,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags height = sizeBest.y; } + const wxSize oldSize(m_width, m_height); if (width != -1) m_width = width; if (height != -1) @@ -2696,36 +2680,11 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags ConstrainSize(); -#if wxUSE_TOOLBAR_NATIVE - if (wxDynamicCast(GetParent(), wxToolBar)) - { - // don't take the x,y values, they're wrong because toolbar sets them - GtkWidget *widget = m_widget; - gtk_widget_set_size_request (widget, m_width, m_height); - } - else -#endif - if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook - { - // don't set the size for children of wxNotebook, just take the values. - m_x = x; - m_y = y; - m_width = width; - m_height = height; - } - else + if (m_parent->m_wxwindow) { GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); - if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) - { - if (x != -1) m_x = x + gtk_pizza_get_xoffset( pizza ); - if (y != -1) m_y = y + gtk_pizza_get_yoffset( pizza ); - } - else - { - m_x = x + gtk_pizza_get_xoffset( pizza ); - m_y = y + gtk_pizza_get_yoffset( pizza ); - } + m_x = x + gtk_pizza_get_xoffset(pizza); + m_y = y + gtk_pizza_get_yoffset(pizza); int left_border = 0; int right_border = 0; @@ -2753,32 +2712,20 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags m_height+top_border+bottom_border ); } - if (m_hasScrolling) + if (m_width != oldSize.x || m_height != oldSize.y) { - /* Sometimes the client area changes size without the - whole windows's size changing, but if the whole - windows's size doesn't change, no wxSizeEvent will - normally be sent. Here we add an extra test if - the client test has been changed and this will - be used then. */ + // update these variables to keep size_allocate handler + // from sending another size event for this change GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); - } -/* - wxPrintf( "OnSize sent from " ); - if (GetClassInfo() && GetClassInfo()->GetClassName()) - wxPrintf( GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height ); -*/ - - if (!m_nativeSizeEvent) - { - wxSizeEvent event( wxSize(m_width,m_height), GetId() ); - event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); + gtk_widget_queue_resize(m_widget); + if (!m_nativeSizeEvent) + { + wxSizeEvent event( wxSize(m_width,m_height), GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + } } - - m_resizing = false; } bool wxWindowGTK::GtkShowFromOnIdle() @@ -2853,7 +2800,7 @@ void wxWindowGTK::OnInternalIdle() } } - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -2911,7 +2858,7 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const int dx = 0; int dy = 0; - if (m_parent && m_parent->m_wxwindow) + if (!IsTopLevel() && m_parent && m_parent->m_wxwindow) { GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); dx = gtk_pizza_get_xoffset( pizza ); @@ -3063,9 +3010,7 @@ int wxWindowGTK::GetCharHeight() const wxFont font = GetFont(); wxCHECK_MSG( font.Ok(), 12, wxT("invalid font") ); - PangoContext *context = NULL; - if (m_widget) - context = gtk_widget_get_pango_context( m_widget ); + PangoContext* context = gtk_widget_get_pango_context(m_widget); if (!context) return 0; @@ -3091,9 +3036,7 @@ int wxWindowGTK::GetCharWidth() const wxFont font = GetFont(); wxCHECK_MSG( font.Ok(), 8, wxT("invalid font") ); - PangoContext *context = NULL; - if (m_widget) - context = gtk_widget_get_pango_context( m_widget ); + PangoContext* context = gtk_widget_get_pango_context(m_widget); if (!context) return 0; @@ -3194,22 +3137,30 @@ void wxWindowGTK::SetFocus() if (m_wxwindow) { + // wxWindow::SetFocus() should really set the focus to + // this control, whatever the flags are + if (!GTK_WIDGET_CAN_FOCUS(m_wxwindow)) + GTK_WIDGET_SET_FLAGS(m_wxwindow, GTK_CAN_FOCUS); + if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow)) { gtk_widget_grab_focus (m_wxwindow); } } - else if (m_widget) + else { + // wxWindow::SetFocus() should really set the focus to + // this control, whatever the flags are + if (!GTK_WIDGET_CAN_FOCUS(m_widget)) + GTK_WIDGET_SET_FLAGS(m_widget, GTK_CAN_FOCUS); + if (GTK_IS_CONTAINER(m_widget)) { -#if wxUSE_RADIOBTN - if (IsKindOf(CLASSINFO(wxRadioButton))) + if (GTK_IS_RADIO_BUTTON(m_widget)) { gtk_widget_grab_focus (m_widget); return; } -#endif // wxUSE_RADIOBTN gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD ); } @@ -3619,7 +3570,8 @@ bool wxWindowGTK::ScrollPages(int pages) return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Page, pages); } -void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) +void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground), + const wxRect *rect) { if (!m_widget) return; @@ -3782,7 +3734,6 @@ void wxWindowGTK::GtkSendPaintEvents() nc_paint_event.SetEventObject( this ); GetEventHandler()->ProcessEvent( nc_paint_event ); - wxPaintEvent paint_event( GetId() ); paint_event.SetEventObject( this ); GetEventHandler()->ProcessEvent( paint_event ); @@ -4321,8 +4272,11 @@ void wxWindowGTK::GtkScrolledWindowSetBorder(GtkWidget* w, int wxstyle) gtkstyle = GTK_SHADOW_OUT; else if (wxstyle & wxBORDER_SUNKEN) gtkstyle = GTK_SHADOW_IN; +#if 0 + // Now obsolete else if (wxstyle & wxBORDER_DOUBLE) gtkstyle = GTK_SHADOW_ETCHED_IN; +#endif else //default gtkstyle = GTK_SHADOW_IN;