X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ad975781ebc03425a72d3956bd5ef82b6d892fb7..cd9a8d40c9a7380f7fefe676cbe01089833cdd60:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 00c74805d1..e6a12132c2 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -28,6 +28,7 @@ #include "wx/dialog.h" #include "wx/msgdlg.h" #include "wx/module.h" +#include "wx/combobox.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -476,6 +477,34 @@ void wxgtk_window_size_request_callback(GtkWidget *widget, requisition->width = w; } + +extern "C" +void wxgtk_combo_size_request_callback(GtkWidget *widget, + GtkRequisition *requisition, + wxComboBox *win) +{ + // This callback is actually hooked into the text entry + // of the combo box, not the GtkHBox. + + int w, h; + win->GetSize( &w, &h ); + if (w < 2) + w = 2; + if (h < 2) + h = 2; + + GtkCombo *gcombo = GTK_COMBO(win->m_widget); + + GtkRequisition entry_req; + entry_req.width = 2; + entry_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request ) + (gcombo->button, &entry_req ); + + requisition->width = w - entry_req.width; + requisition->height = entry_req.height+4; // TODO: why +4? +} + //----------------------------------------------------------------------------- // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- @@ -971,6 +1000,8 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event, #if wxUSE_UNICODE event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval); #endif + wxGetMousePosition( &x, &y ); + win->ScreenToClient( &x, &y ); event.m_x = x; event.m_y = y; event.SetEventObject( win ); @@ -1111,29 +1142,27 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, return FALSE; if (g_blockEventsOnDrag) return FALSE; - + + + wxKeyEvent event( wxEVT_KEY_DOWN ); + bool ret = false; + bool return_after_IM = false; + + if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) + { + // Emit KEY_DOWN event + ret = win->GetEventHandler()->ProcessEvent( event ); + } + else + { + // Return after IM processing as we cannot do + // anything with it anyhow. + return_after_IM = true; + } + #ifdef __WXGTK20__ -#if 0 - // We have to pass key press events through GTK+'s Input Method context - // object in order to get correct characters. By doing so, we lose the - // ability to let other GTK+'s handlers (namely, widgets' default signal - // handlers) handle the signal by returning false from this callback. - // Because GTK+ sends the events to parent widgets as well, we can't - // afford losing it, otherwise native widgets inserted into wxPanel - // would break in subtle ways (e.g. spacebar would no longer toggle - // wxCheckButton's state). Therefore, we only pass the event to IM if it - // originated in this window's widget, which we detect by checking if we've - // seen the same event before (no events from children are lost this way, - // because gtk_window_key_press_callback is installed for native controls - // as well and the wxKeyEvent it creates propagates upwards). - static GdkEventKey s_lastEvent; - bool useIM = (win->m_imData != NULL) && - memcmp(gdk_event, &s_lastEvent, sizeof(GdkEventKey)) != 0; - s_lastEvent = *gdk_event; -#else // 2005.01.26 modified by Hong Jen Yee (hzysoft@sina.com.tw): - // There is no need to store lastEvent. The original code makes GTK+ IM - // dysfunction. When we get a key_press event here, it could be originate + // 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 @@ -1143,30 +1172,27 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, // 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. - bool useIM = (win->m_imData != NULL) && ( wxWindow::FindFocus() == win ); -#endif - -#endif - - bool IM_ret = FALSE; -#ifdef __WXGTK20__ - // 2005.01.26 modified by Hong Jen Yee (hzysoft@sina.com.tw): - // 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. - // wWe should send the key_down event anyway. - if (useIM) + if ((!ret) && (win->m_imData != NULL) && ( wxWindow::FindFocus() == win )) { - // it may be useful for the input method, though: - IM_ret = gtk_im_context_filter_keypress(win->m_imData->context, gdk_event); + // 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. + // we should send the key_down event anyway. + bool intercepted_by_IM = gtk_im_context_filter_keypress(win->m_imData->context, gdk_event); win->m_imData->lastKeyEvent = NULL; - if (IM_ret) + if (intercepted_by_IM) + { wxLogTrace(TRACE_KEYS, _T("Key event intercepted by IM")); + return true; + } } #endif + if (return_after_IM) + return true; - wxKeyEvent event( wxEVT_KEY_DOWN ); - bool ret = FALSE; - +#ifndef __WXGTK20__ + // This is for GTK+ 1.2 only. The char event generatation for GTK+ 2.0 is done + // in the "commit" handler. + // 2005.02.02 modified by Hong Jen Yee (hzysoft@sina.com.tw). // In GTK+ 1.2, strings sent by IMs are also regarded as key_press events whose // keyCodes cannot be recognized by wxWidgets. These MBCS strings, however, are @@ -1183,10 +1209,6 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, // When using Input Methods to support internationalized text input, the composed // characters appear here after the pre-editing has been completed. -#ifndef __WXGTK20__ - // This is for GTK+ 1.2 only. The char event generatation for - // GTK+ 2.0 is done in the emit handler. - if ( (!ret) && (gdk_event->length > 1) ) // If this event contains a pre-edited string from IM. { // We should translate this key event into wxEVT_CHAR not wxEVT_KEY_DOWN. @@ -1199,11 +1221,11 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, #endif // Implement OnCharHook by checking ancesteror top level windows - wxWindow *parent = window; + wxWindow *parent = win; while (parent && !parent->IsTopLevel()) parent = parent->GetParent(); - for( wxChar* pstr = string; *pstr; pstr++ ) + for( const wxChar* pstr = string; *pstr; pstr++ ) { #if wxUSE_UNICODE event.m_uniChar = *pstr; @@ -1220,28 +1242,14 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (!ret) { event.SetEventType(wxEVT_CHAR); - window->GetEventHandler()->ProcessEvent( event ); + win->GetEventHandler()->ProcessEvent( event ); } } return true; } - // Only translate the key event when it's not sent with a pre-edited string. - else + #endif // #ifndef __WXGTK20__ - if( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) - { - // unknown key pressed, ignore (the event would be useless anyhow) - return false; - } - else // This event doesn't contain a pre-edited string and is not an invalid key either. - { - // Emit KEY_DOWN event - ret = win->GetEventHandler()->ProcessEvent( event ); - } - if (IM_ret) - return false; - #if wxUSE_ACCEL if (!ret) { @@ -1308,6 +1316,10 @@ static gint 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)) && @@ -2948,13 +2960,20 @@ void wxWindowGTK::PostCreation() GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this ); } - if ( !GTK_IS_COMBO(m_widget)) + if (GTK_IS_COMBO(m_widget)) + { + GtkCombo *gcombo = GTK_COMBO(m_widget); + + gtk_signal_connect( GTK_OBJECT(gcombo->entry), "size_request", + GTK_SIGNAL_FUNC(wxgtk_combo_size_request_callback), + (gpointer) this ); + } + else { // This is needed if we want to add our windows into native - // GTK control, such as the toolbar. With this callback, the + // GTK controls, such as the toolbar. With this callback, the // toolbar gets to know the correct size (the one set by the - // programmer). Sadly, it misbehaves for wxComboBox. FIXME - // when moving to GTK 2.0. + // programmer). Sadly, it misbehaves for wxComboBox. gtk_signal_connect( GTK_OBJECT(m_widget), "size_request", GTK_SIGNAL_FUNC(wxgtk_window_size_request_callback), (gpointer) this ); @@ -3083,22 +3102,37 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; - int border = 0; + int left_border = 0; + int right_border = 0; + int top_border = 0; int bottom_border = 0; -#ifndef __WXGTK20__ + /* the default button has a border around it */ if (GTK_WIDGET_CAN_DEFAULT(m_widget)) { - /* the default button has a border around it */ - border = 6; +#ifdef __WXGTK20__ + GtkBorder *default_outside_border = NULL; + gtk_widget_style_get( m_widget, "default_outside_border", &default_outside_border, NULL ); + if (default_outside_border) + { + left_border += default_outside_border->left; + right_border += default_outside_border->right; + top_border += default_outside_border->top; + bottom_border += default_outside_border->bottom; + g_free( default_outside_border ); + } +#else + left_border = 6; + right_border = 6; + top_border = 6; bottom_border = 5; - } #endif + } - DoMoveWindow( m_x-border, - m_y-border, - m_width+2*border, - m_height+border+bottom_border ); + DoMoveWindow( m_x-top_border, + m_y-left_border, + m_width+left_border+right_border, + m_height+top_border+bottom_border ); } if (m_hasScrolling) @@ -3924,6 +3958,12 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) void wxWindowGTK::Update() { GtkUpdate(); + + // when we call Update() we really want to update the window immediately on + // screen, even if itmeans flushing the entire queue and hence slowing down + // everything -- but it should still be done, it's just that Update() should + // be called very rarely + gdk_flush(); } void wxWindowGTK::GtkUpdate() @@ -3954,12 +3994,10 @@ void wxWindowGTK::GtkSendPaintEvents() // widget to draw on GtkPizza *pizza = GTK_PIZZA (m_wxwindow); - if (GetThemeEnabled() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM) + if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM)) { // find ancestor from which to steal background - wxWindow *parent = GetParent(); - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); + wxWindow *parent = wxGetTopLevelParent((wxWindow *)this); if (!parent) parent = (wxWindow*)this;