X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3d257b8db10b5f464d896ff0d4249237d8f587a1..637b7e4f3a0fd1c6bdfc21d28e37bcf760e3b364:/src/gtk/window.cpp?ds=sidebyside diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 36ac106b20..95dd20fbcb 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -24,6 +24,9 @@ #include "wx/msgdlg.h" #include "wx/module.h" #include "wx/combobox.h" +#if wxUSE_TOOLBAR_NATIVE +#include "wx/toolbar.h" +#endif #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -55,6 +58,12 @@ #include "wx/math.h" #include +// FIXME: Due to a hack we use GtkCombo in here, which is deprecated since gtk2.3.0 +#include +#if defined(GTK_DISABLE_DEPRECATED) && GTK_CHECK_VERSION(2,3,0) +#undef GTK_DISABLE_DEPRECATED +#endif + #include "wx/gtk/private.h" #include #include @@ -65,20 +74,13 @@ #include "wx/gtk/win_gtk.h" -#ifdef __WXGTK20__ #include -#endif - -#ifdef __WXGTK20__ - #ifdef HAVE_XIM - #undef HAVE_XIM - #endif +#ifdef HAVE_XIM + #undef HAVE_XIM #endif -#ifdef __WXGTK20__ extern GtkContainerClass *pizza_parent_class; -#endif //----------------------------------------------------------------------------- // documentation on internals @@ -237,12 +239,6 @@ wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL; // yet, defer setting the focus to idle time. wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL; -// hack: we need something to pass to gtk_menu_popup, so we store the time of -// the last click here (extern: used from gtk/menu.cpp) -#ifndef __WXGTK20__ -guint32 wxGtkTimeLastClick = 0; -#endif - extern bool g_mainThreadLocked; //----------------------------------------------------------------------------- @@ -272,14 +268,9 @@ gdk_window_warp_pointer (GdkWindow *window, gint x, gint y) { -#ifndef __WXGTK20__ - GdkWindowPrivate *priv; -#endif - if (!window) window = GDK_ROOT_PARENT(); -#ifdef __WXGTK20__ if (!GDK_WINDOW_DESTROYED(window)) { XWarpPointer (GDK_WINDOW_XDISPLAY(window), @@ -288,27 +279,8 @@ gdk_window_warp_pointer (GdkWindow *window, 0, 0, 0, 0, /* not source window -> move from anywhere */ x, y ); } -#else - priv = (GdkWindowPrivate*) window; - - if (!priv->destroyed) - { - XWarpPointer (priv->xdisplay, - None, /* not source window -> move from anywhere */ - priv->xwindow, /* dest window */ - 0, 0, 0, 0, /* not source window -> move from anywhere */ - x, y ); - } -#endif } -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; - //----------------------------------------------------------------------------- // local code (see below) //----------------------------------------------------------------------------- @@ -388,23 +360,25 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) if (win->HasFlag(wxRAISED_BORDER)) { - gtk_draw_shadow( widget->style, - widget->window, - GTK_STATE_NORMAL, - GTK_SHADOW_OUT, - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + gtk_paint_shadow (widget->style, + widget->window, + GTK_STATE_NORMAL, + GTK_SHADOW_OUT, + NULL, NULL, NULL, // FIXME: No clipping? + dx, dy, + widget->allocation.width-dw, widget->allocation.height-dh ); return; } if (win->HasFlag(wxSUNKEN_BORDER)) { - gtk_draw_shadow( widget->style, - widget->window, - GTK_STATE_NORMAL, - GTK_SHADOW_IN, - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + gtk_paint_shadow (widget->style, + widget->window, + GTK_STATE_NORMAL, + GTK_SHADOW_IN, + NULL, NULL, NULL, // FIXME: No clipping? + dx, dy, + widget->allocation.width-dw, widget->allocation.height-dh ); return; } @@ -427,36 +401,21 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_own_expose_callback( GtkWidget *widget, + GdkEventExpose *gdk_event, + wxWindowGTK *win ) { if (gdk_event->count > 0) return FALSE; draw_frame( widget, win ); -#ifdef __WXGTK20__ - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); -#endif return TRUE; } } -//----------------------------------------------------------------------------- -// "draw" of m_widget -//----------------------------------------------------------------------------- - -#ifndef __WXGTK20__ - -extern "C" { -static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win ) -{ - draw_frame( widget, win ); -} -} - -#endif // GTK+ < 2.0 - //----------------------------------------------------------------------------- // "size_request" of m_widget //----------------------------------------------------------------------------- @@ -513,16 +472,16 @@ void wxgtk_combo_size_request_callback(GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static int gtk_window_expose_callback( GtkWidget *widget, - GdkEventExpose *gdk_event, - wxWindow *win ) +static gboolean +gtk_window_expose_callback( GtkWidget *widget, + GdkEventExpose *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); -#ifdef __WXGTK20__ // This callback gets called in drawing-idle time under // GTK 2.0, so we don't need to defer anything to idle // time anymore. @@ -562,147 +521,11 @@ static int gtk_window_expose_callback( GtkWidget *widget, // Let parent window draw window-less widgets (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); -#else - // This gets called immediately after an expose event - // under GTK 1.2 so we collect the calls and wait for - // the idle handler to pick things up. - - win->GetUpdateRegion().Union( gdk_event->area.x, - gdk_event->area.y, - gdk_event->area.width, - gdk_event->area.height ); - win->m_clearRegion.Union( gdk_event->area.x, - gdk_event->area.y, - gdk_event->area.width, - gdk_event->area.height ); - - // Actual redrawing takes place in idle time. - // win->GtkUpdate(); -#endif return FALSE; } } -//----------------------------------------------------------------------------- -// "event" of m_wxwindow -//----------------------------------------------------------------------------- - -#ifndef __WXGTK20__ - -// GTK thinks it is clever and filters out a certain amount of "unneeded" -// expose events. We need them, of course, so we override the main event -// procedure in GtkWidget by giving our own handler for all system events. -// There, we look for expose events ourselves whereas all other events are -// handled normally. - -extern "C" { -static -gint gtk_window_event_event_callback( GtkWidget *widget, - GdkEventExpose *event, - wxWindow *win ) -{ - if (event->type == GDK_EXPOSE) - { - gint ret = gtk_window_expose_callback( widget, event, win ); - return ret; - } - - return FALSE; -} -} - -#endif // !GTK+ 2 - -//----------------------------------------------------------------------------- -// "draw" of m_wxwindow -//----------------------------------------------------------------------------- - -#ifndef __WXGTK20__ - -// This callback is a complete replacement of the gtk_pizza_draw() function, -// which is disabled. - -extern "C" { -static void gtk_window_draw_callback( GtkWidget *widget, - GdkRectangle *rect, - wxWindow *win ) -{ - DEBUG_MAIN_THREAD - - if (g_isIdle) - wxapp_install_idle_handler(); - - // if there are any children we must refresh everything - // - // VZ: why? - if ( !win->HasFlag(wxFULL_REPAINT_ON_RESIZE) && - win->GetChildren().IsEmpty() ) - { - return; - } - -#if 0 - if (win->GetName()) - { - wxPrintf( wxT("OnDraw from ") ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x, - (int)rect->y, - (int)rect->width, - (int)rect->height ); - } -#endif - -#ifndef __WXUNIVERSAL__ - GtkPizza *pizza = GTK_PIZZA (widget); - - if (win->GetThemeEnabled() && win->GetBackgroundStyle() == wxBG_STYLE_SYSTEM) - { - wxWindow *parent = win->GetParent(); - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - if (!parent) - parent = win; - - gtk_paint_flat_box (parent->m_widget->style, - pizza->bin_window, - GTK_STATE_NORMAL, - GTK_SHADOW_NONE, - rect, - parent->m_widget, - (char *)"base", - 0, 0, -1, -1); - } -#endif - - win->m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height ); - win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); - - // Update immediately, not in idle time. - win->GtkUpdate(); - -#ifndef __WXUNIVERSAL__ - // Redraw child widgets - GList *children = pizza->children; - while (children) - { - GtkPizzaChild *child = (GtkPizzaChild*) children->data; - children = children->next; - - GdkRectangle child_area; - if (gtk_widget_intersect (child->widget, rect, &child_area)) - { - gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ ); - } - } -#endif -} -} - -#endif - //----------------------------------------------------------------------------- // "key_press_event" from any window //----------------------------------------------------------------------------- @@ -1120,12 +943,17 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, wxFillOtherKeyEventFields(event, win, gdk_event); event.m_keyCode = key_code; +#if wxUSE_UNICODE + if ( gdk_event->type == GDK_KEY_PRESS || gdk_event->type == GDK_KEY_RELEASE ) + { + event.m_uniChar = key_code; + } +#endif return true; } -#ifdef __WXGTK20__ struct wxGtkIMData { GtkIMContext *context; @@ -1141,12 +969,12 @@ struct wxGtkIMData g_object_unref(context); } }; -#endif extern "C" { -static gint gtk_window_key_press_callback( GtkWidget *widget, - GdkEventKey *gdk_event, - wxWindow *win ) +static gboolean +gtk_window_key_press_callback( GtkWidget *widget, + GdkEventKey *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -1175,7 +1003,6 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, return_after_IM = true; } -#ifdef __WXGTK20__ // 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 @@ -1197,73 +1024,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (intercepted_by_IM) { wxLogTrace(TRACE_KEYS, _T("Key event intercepted by IM")); - return true; + return TRUE; } } -#endif - if (return_after_IM) - return 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 - // composed of more than one character, which means gdk_event->length will always - // greater than one. When gtk_event->length == 1, this may be an ASCII character - // and can be translated by wx. However, when MBCS characters are sent by IM, - // gdk_event->length will >= 2. So neither should we pass it to accelerator table, - // nor should we pass it to controls. The following explanation was excerpted - // from GDK documentation. - // gint length : the length of string. - // gchar *string : a null-terminated multi-byte string containing the composed - // characters resulting from the key press. When text is being input, in a GtkEntry - // for example, it is these characters which should be added to the input buffer. - // When using Input Methods to support internationalized text input, the composed - // characters appear here after the pre-editing has been completed. - - 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. - #if wxUSE_UNICODE // GTK+ 1.2 is not UTF-8 based. - const wxWCharBuffer string = wxConvLocal.cMB2WC( gdk_event->string ); - if( !string ) - return false; - #else - const char* string = gdk_event->string; - #endif - - // Implement OnCharHook by checking ancestor top level windows - wxWindow *parent = win; - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - - for( const wxChar* pstr = string; *pstr; pstr++ ) - { - #if wxUSE_UNICODE - event.m_uniChar = *pstr; - // Backward compatible for ISO-8859-1 - event.m_keyCode = *pstr < 256 ? event.m_uniChar : 0; - #else - event.m_keyCode = *pstr; - #endif - if (parent) - { - event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->GetEventHandler()->ProcessEvent( event ); - } - if (!ret) - { - event.SetEventType(wxEVT_CHAR); - win->GetEventHandler()->ProcessEvent( event ); - } - } - return true; - } - -#endif // #ifndef __WXGTK20__ + if (return_after_IM) + return FALSE; #if wxUSE_ACCEL if (!ret) @@ -1313,6 +1079,16 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, event.m_keyCode = key_code; + // To conform to the docs we need to translate Ctrl-alpha + // characters to values in the range 1-26. + if (event.ControlDown() && key_code >= 'a' && key_code <= 'z' ) + { + event.m_keyCode = key_code - 'a' + 1; +#if wxUSE_UNICODE + event.m_uniChar = event.m_keyCode; +#endif + } + // Implement OnCharHook by checking ancestor top level windows wxWindow *parent = win; while (parent && !parent->IsTopLevel()) @@ -1398,7 +1174,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (ret) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + g_signal_stop_emission_by_name (widget, "key_press_event"); return TRUE; } @@ -1406,11 +1182,11 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, } } -#ifdef __WXGTK20__ extern "C" { -static void gtk_wxwindow_commit_cb (GtkIMContext *context, - const gchar *str, - wxWindow *window) +static void +gtk_wxwindow_commit_cb (GtkIMContext *context, + const gchar *str, + wxWindow *window) { wxKeyEvent event( wxEVT_KEY_DOWN ); @@ -1448,6 +1224,17 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, #else event.m_keyCode = *pstr; #endif // wxUSE_UNICODE + + // To conform to the docs we need to translate Ctrl-alpha + // characters to values in the range 1-26. + if (event.ControlDown() && *pstr >= 'a' && *pstr <= 'z' ) + { + event.m_keyCode = *pstr - 'a' + 1; +#if wxUSE_UNICODE + event.m_uniChar = event.m_keyCode; +#endif + } + if (parent) { event.SetEventType( wxEVT_CHAR_HOOK ); @@ -1462,7 +1249,6 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, } } } -#endif //----------------------------------------------------------------------------- @@ -1470,9 +1256,10 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_key_release_callback( GtkWidget *widget, - GdkEventKey *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_key_release_callback( GtkWidget *widget, + GdkEventKey *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1495,7 +1282,7 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, if ( !win->GetEventHandler()->ProcessEvent( event ) ) return FALSE; - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" ); + g_signal_stop_emission_by_name (widget, "key_release_event"); return TRUE; } } @@ -1643,9 +1430,10 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_button_press_callback( GtkWidget *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_button_press_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1801,25 +1589,9 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, if ( !g_captureWindow ) win = FindWindowForMouseEvent(win, event.m_x, event.m_y); -#ifndef __WXGTK20__ - wxGtkTimeLastClick = gdk_event->time; - - if (event_type == wxEVT_LEFT_DCLICK) - { - // GTK 1.2 crashes when intercepting double - // click events from both wxSpinButton and - // wxSpinCtrl - if (GTK_IS_SPIN_BUTTON(win->m_widget)) - { - // Just disable this event for now. - return FALSE; - } - } -#endif // !__WXGTK20__ - if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" ); + g_signal_stop_emission_by_name (widget, "button_press_event"); return TRUE; } @@ -1849,9 +1621,10 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_button_release_callback( GtkWidget *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_button_release_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1898,7 +1671,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" ); + g_signal_stop_emission_by_name (widget, "button_release_event"); return TRUE; } @@ -1911,9 +1684,10 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_motion_notify_callback( GtkWidget *widget, - GdkEventMotion *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_motion_notify_callback( GtkWidget *widget, + GdkEventMotion *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1972,9 +1746,18 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, win = FindWindowForMouseEvent(win, event.m_x, event.m_y); } + if ( !g_captureWindow ) + { + wxSetCursorEvent cevent( event.m_x, event.m_y ); + if (win->GetEventHandler()->ProcessEvent( cevent )) + { + // Rewrite cursor handling here (away from idle). + } + } + if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" ); + g_signal_stop_emission_by_name (widget, "motion_notify_event"); return TRUE; } @@ -1982,15 +1765,15 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, } } -#ifdef __WXGTK20__ //----------------------------------------------------------------------------- // "mouse_wheel_event" //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_wheel_callback (GtkWidget * widget, - GdkEventScroll * gdk_event, - wxWindowGTK * win) +static gboolean +gtk_window_wheel_callback (GtkWidget * widget, + GdkEventScroll * gdk_event, + wxWindowGTK * win) { DEBUG_MAIN_THREAD @@ -2032,7 +1815,7 @@ static gint gtk_window_wheel_callback (GtkWidget * widget, if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "scroll_event" ); + g_signal_stop_emission_by_name (widget, "scroll_event"); return TRUE; } @@ -2054,7 +1837,6 @@ static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win) return win->GetEventHandler()->ProcessEvent(event); } } -#endif // __WXGTK20__ //----------------------------------------------------------------------------- // "focus_in_event" @@ -2076,19 +1858,18 @@ static bool DoSendFocusEvents(wxWindow *win) } extern "C" { -static gint gtk_window_focus_in_callback( GtkWidget *widget, - GdkEvent *WXUNUSED(event), - wxWindow *win ) +static gboolean +gtk_window_focus_in_callback( GtkWidget *widget, + GdkEventFocus *WXUNUSED(event), + wxWindow *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); -#ifdef __WXGTK20__ if (win->m_imData) gtk_im_context_focus_in(win->m_imData->context); -#endif g_focusWindowLast = g_focusWindow = win; @@ -2110,19 +1891,24 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, } #endif // wxUSE_CARET + gboolean ret = FALSE; + // does the window itself think that it has the focus? if ( !win->m_hasFocus ) { // not yet, notify it win->m_hasFocus = true; - if ( DoSendFocusEvents(win) ) - { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); - return TRUE; - } + (void)DoSendFocusEvents(win); + + ret = TRUE; } + // Disable default focus handling for custom windows + // since the default GTK+ handler issues a repaint + if (win->m_wxwindow) + return ret; + return FALSE; } } @@ -2132,17 +1918,18 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_focus_out_callback( GtkWidget *widget, + GdkEventFocus *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); -#ifdef __WXGTK20__ if (win->m_imData) gtk_im_context_focus_out(win->m_imData->context); -#endif wxLogTrace( TRACE_FOCUS, _T("%s: focus out"), win->GetName().c_str() ); @@ -2168,6 +1955,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk } #endif // wxUSE_CARET + gboolean ret = FALSE; + // don't send the window a kill focus event if it thinks that it doesn't // have focus already if ( win->m_hasFocus ) @@ -2177,13 +1966,16 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); event.SetEventObject( win ); - // even if we did process the event in wx code, still let GTK itself - // process it too as otherwise bad things happen, especially in GTK2 - // where the text control simply aborts the program if it doesn't get - // the matching focus out event (void)win->GetEventHandler()->ProcessEvent( event ); + + ret = TRUE; } + // Disable default focus handling for custom windows + // since the default GTK+ handler issues a repaint + if (win->m_wxwindow) + return ret; + return FALSE; } } @@ -2193,10 +1985,10 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk //----------------------------------------------------------------------------- extern "C" { -static -gint gtk_window_enter_callback( GtkWidget *widget, - GdkEventCrossing *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_enter_callback( GtkWidget *widget, + GdkEventCrossing *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2223,9 +2015,18 @@ gint gtk_window_enter_callback( GtkWidget *widget, event.m_x = x + pt.x; event.m_y = y + pt.y; + if ( !g_captureWindow ) + { + wxSetCursorEvent cevent( event.m_x, event.m_y ); + if (win->GetEventHandler()->ProcessEvent( cevent )) + { + // Rewrite cursor handling here (away from idle). + } + } + if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" ); + g_signal_stop_emission_by_name (widget, "enter_notify_event"); return TRUE; } @@ -2238,7 +2039,10 @@ gint gtk_window_enter_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_leave_callback( GtkWidget *widget, + GdkEventCrossing *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2277,7 +2081,7 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" ); + g_signal_stop_emission_by_name (widget, "leave_notify_event"); return TRUE; } @@ -2291,7 +2095,6 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ extern "C" { static void gtk_window_vscroll_callback( GtkAdjustment *adjust, - SCROLLBAR_CBACK_ARG wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2308,10 +2111,7 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, win->m_oldVerticalPos = adjust->value; -#ifndef __WXGTK20__ - GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(win->m_widget); -#endif - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->vscrollbar)); + wxEventType command = GtkScrollWinTypeToWx(GTK_SCROLL_JUMP); int value = (int)(adjust->value+0.5); @@ -2327,7 +2127,6 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, extern "C" { static void gtk_window_hscroll_callback( GtkAdjustment *adjust, - SCROLLBAR_CBACK_ARG wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2341,10 +2140,7 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, float diff = adjust->value - win->m_oldHorizontalPos; if (fabs(diff) < 0.2) return; -#ifndef __WXGTK20__ - GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW(win->m_widget); -#endif - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->hscrollbar)); + wxEventType command = GtkScrollWinTypeToWx(GTK_SCROLL_JUMP); win->m_oldHorizontalPos = adjust->value; @@ -2361,9 +2157,10 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win) +static gboolean +gtk_scrollbar_button_press_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win) { DEBUG_MAIN_THREAD @@ -2373,8 +2170,8 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, g_blockEventsOnScroll = true; - // FIXME: there is no 'slider' field in GTK+ 2.0 any more -#ifndef __WXGTK20__ +// FIXME: there is no 'slider' field in GTK+ 2.0 any more +#if 0 win->m_isScrolling = (gdk_event->window == widget->slider); #endif @@ -2387,9 +2184,10 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, - GdkEventButton *WXUNUSED(gdk_event), - wxWindowGTK *win) +static gboolean +gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindowGTK *win) { DEBUG_MAIN_THREAD @@ -2448,7 +2246,7 @@ wxWindow *wxWindowBase::DoFindFocus() been realized, so we do this directly after realization. */ extern "C" { -static gint +static void gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) { DEBUG_MAIN_THREAD @@ -2456,20 +2254,16 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) if (g_isIdle) wxapp_install_idle_handler(); -#ifdef __WXGTK20__ if (win->m_imData) { GtkPizza *pizza = GTK_PIZZA( m_widget ); gtk_im_context_set_client_window( win->m_imData->context, pizza->bin_window ); } -#endif wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - - return FALSE; } } @@ -2548,7 +2342,7 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), /* Initialize XIM support */ extern "C" { -static gint +static void gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), wxWindowGTK * WXUNUSED_UNLESS_XIM(win) ) { @@ -2556,12 +2350,12 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), wxapp_install_idle_handler(); #ifdef HAVE_XIM - if (win->m_ic) return FALSE; - if (!widget) return FALSE; - if (!gdk_im_ready()) return FALSE; + if (win->m_ic) return; + if (!widget) return; + if (!gdk_im_ready()) return; win->m_icattr = gdk_ic_attr_new(); - if (!win->m_icattr) return FALSE; + if (!win->m_icattr) return; gint width, height; GdkEventMask mask; @@ -2631,8 +2425,6 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), gdk_im_begin (win->m_ic, widget->window); } #endif // HAVE_XIM - - return FALSE; } } @@ -2753,15 +2545,8 @@ void wxWindowGTK::Init() m_cursor = *wxSTANDARD_CURSOR; -#ifdef __WXGTK20__ m_imData = NULL; m_dirtyTabOrder = false; -#else -#ifdef HAVE_XIM - m_ic = (GdkIC*) NULL; - m_icattr = (GdkICAttr*) NULL; -#endif -#endif } wxWindowGTK::wxWindowGTK() @@ -2845,39 +2630,35 @@ bool wxWindowGTK::Create( wxWindow *parent, m_vAdjust->step_increment = 1.0; m_vAdjust->page_increment = 1.0; m_vAdjust->page_size = 5.0; - gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + g_signal_emit_by_name (m_vAdjust, "changed"); m_hAdjust->lower = 0.0; m_hAdjust->upper = 1.0; m_hAdjust->value = 0.0; m_hAdjust->step_increment = 1.0; m_hAdjust->page_increment = 1.0; m_hAdjust->page_size = 5.0; - gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + g_signal_emit_by_name (m_hAdjust, "changed"); // these handlers block mouse events to any window during scrolling such as // motion events and prevent GTK and wxWidgets from fighting over where the // slider should be - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + g_signal_connect (scrolledWindow->vscrollbar, "button_press_event", + G_CALLBACK (gtk_scrollbar_button_press_callback), this); + g_signal_connect (scrolledWindow->hscrollbar, "button_press_event", + G_CALLBACK (gtk_scrollbar_button_press_callback), this); + g_signal_connect (scrolledWindow->vscrollbar, "button_release_event", + G_CALLBACK (gtk_scrollbar_button_release_callback), this); + g_signal_connect (scrolledWindow->hscrollbar, "button_release_event", + G_CALLBACK (gtk_scrollbar_button_release_callback), this); // these handlers get notified when screen updates are required either when // scrolling or when the window size (and therefore scrollbar configuration) // has changed - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", - (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); - gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", - (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); + g_signal_connect (m_hAdjust, "value_changed", + G_CALLBACK (gtk_window_hscroll_callback), this); + g_signal_connect (m_vAdjust, "value_changed", + G_CALLBACK (gtk_window_vscroll_callback), this); gtk_widget_show( m_wxwindow ); @@ -2911,10 +2692,12 @@ wxWindowGTK::~wxWindowGTK() // propagated to this (soon to be) dead object if (m_focusWidget != NULL) { - gtk_signal_disconnect_by_func( GTK_OBJECT(m_focusWidget), - (GtkSignalFunc) gtk_window_focus_in_callback, (gpointer) this ); - gtk_signal_disconnect_by_func( GTK_OBJECT(m_focusWidget), - (GtkSignalFunc) gtk_window_focus_out_callback, (gpointer) this ); + g_signal_handlers_disconnect_by_func (m_focusWidget, + (gpointer) gtk_window_focus_in_callback, + this); + g_signal_handlers_disconnect_by_func (m_focusWidget, + (gpointer) gtk_window_focus_out_callback, + this); } if (m_widget) @@ -2927,10 +2710,8 @@ wxWindowGTK::~wxWindowGTK() gdk_ic_attr_destroy (m_icattr); #endif -#ifdef __WXGTK20__ // delete before the widgets to avoid a crash on solaris delete m_imData; -#endif if (m_wxwindow) { @@ -2972,42 +2753,24 @@ void wxWindowGTK::PostCreation() gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", - GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); - -#ifndef __WXGTK20__ - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", - GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "expose_event", + G_CALLBACK (gtk_window_expose_callback), this); - if (!HasFlag(wxFULL_REPAINT_ON_RESIZE)) - { - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", - GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this ); - } -#else - // gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), !HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); -#endif + gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); } -#ifdef __WXGTK20__ // Create input method handler m_imData = new wxGtkIMData; // Cannot handle drawing preedited text yet gtk_im_context_set_use_preedit( m_imData->context, FALSE ); - g_signal_connect (G_OBJECT (m_imData->context), "commit", + g_signal_connect (m_imData->context, "commit", G_CALLBACK (gtk_wxwindow_commit_cb), this); -#endif // these are called when the "sunken" or "raised" borders are drawn - gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event", - GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this ); - -#ifndef __WXGTK20__ - gtk_signal_connect( GTK_OBJECT(m_widget), "draw", - GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this ); -#endif + g_signal_connect (m_widget, "expose_event", + G_CALLBACK (gtk_window_own_expose_callback), this); } // focus handling @@ -3017,11 +2780,20 @@ void wxWindowGTK::PostCreation() if (m_focusWidget == NULL) m_focusWidget = m_widget; - gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event", - GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); - - gtk_signal_connect_after( GTK_OBJECT(m_focusWidget), "focus_out_event", - GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this ); + if (m_wxwindow) + { + g_signal_connect (m_focusWidget, "focus_in_event", + G_CALLBACK (gtk_window_focus_in_callback), this); + g_signal_connect (m_focusWidget, "focus_out_event", + G_CALLBACK (gtk_window_focus_out_callback), this); + } + else + { + g_signal_connect_after (m_focusWidget, "focus_in_event", + G_CALLBACK (gtk_window_focus_in_callback), this); + g_signal_connect_after (m_focusWidget, "focus_out_event", + G_CALLBACK (gtk_window_focus_out_callback), this); + } } // connect to the various key and mouse handlers @@ -3032,31 +2804,31 @@ void wxWindowGTK::PostCreation() /* We cannot set colours, fonts and cursors before the widget has been realized, so we do this directly after realization */ - gtk_signal_connect( GTK_OBJECT(connect_widget), "realize", - GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this ); + g_signal_connect (connect_widget, "realize", + G_CALLBACK (gtk_window_realized_callback), this); if (m_wxwindow) { // Catch native resize events - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate", - GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "size_allocate", + G_CALLBACK (gtk_window_size_callback), this); // Initialize XIM support - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", - GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback), (gpointer) this ); + g_signal_connect (m_wxwindow, "realize", + G_CALLBACK (gtk_wxwindow_realized_callback), this); // And resize XIM window - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate", - GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "size_allocate", + G_CALLBACK (gtk_wxwindow_size_callback), this); } 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 ); + g_signal_connect (gcombo->entry, "size_request", + G_CALLBACK (wxgtk_combo_size_request_callback), + this); } else { @@ -3064,9 +2836,9 @@ void wxWindowGTK::PostCreation() // 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. - gtk_signal_connect( GTK_OBJECT(m_widget), "size_request", - GTK_SIGNAL_FUNC(wxgtk_window_size_request_callback), - (gpointer) this ); + g_signal_connect (m_widget, "size_request", + G_CALLBACK (wxgtk_window_size_request_callback), + this); } InheritAttributes(); @@ -3081,33 +2853,24 @@ void wxWindowGTK::PostCreation() void wxWindowGTK::ConnectWidget( GtkWidget *widget ) { - gtk_signal_connect( GTK_OBJECT(widget), "key_press_event", - GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "key_release_event", - GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "button_press_event", - GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "button_release_event", - GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event", - GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this ); - -#ifdef __WXGTK20__ - gtk_signal_connect( GTK_OBJECT(widget), "scroll_event", - GTK_SIGNAL_FUNC(gtk_window_wheel_callback), (gpointer)this ); - g_signal_connect(widget, "popup_menu", - G_CALLBACK(wxgtk_window_popup_menu_callback), this); -#endif - - gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event", - GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event", - GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this ); + g_signal_connect (widget, "key_press_event", + G_CALLBACK (gtk_window_key_press_callback), this); + g_signal_connect (widget, "key_release_event", + G_CALLBACK (gtk_window_key_release_callback), this); + g_signal_connect (widget, "button_press_event", + G_CALLBACK (gtk_window_button_press_callback), this); + g_signal_connect (widget, "button_release_event", + G_CALLBACK (gtk_window_button_release_callback), this); + g_signal_connect (widget, "motion_notify_event", + G_CALLBACK (gtk_window_motion_notify_callback), this); + g_signal_connect (widget, "scroll_event", + G_CALLBACK (gtk_window_wheel_callback), this); + g_signal_connect (widget, "popup_menu", + G_CALLBACK (wxgtk_window_popup_menu_callback), this); + g_signal_connect (widget, "enter_notify_event", + G_CALLBACK (gtk_window_enter_callback), this); + g_signal_connect (widget, "leave_notify_event", + G_CALLBACK (gtk_window_leave_callback), this); } bool wxWindowGTK::Destroy() @@ -3144,9 +2907,46 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags y = currentY; AdjustForParentClientOrigin(x, y, sizeFlags); - if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ + // calculate the best size if we should auto size the window + if ( ((sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1) || + ((sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1) ) { - /* don't set the size for children of wxNotebook, just take the values. */ + const wxSize sizeBest = GetBestSize(); + if ( (sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1 ) + width = sizeBest.x; + if ( (sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1 ) + height = sizeBest.y; + } + + if (width != -1) + m_width = width; + if (height != -1) + m_height = height; + + int minWidth = GetMinWidth(), + minHeight = GetMinHeight(), + maxWidth = GetMaxWidth(), + maxHeight = GetMaxHeight(); + + if ((minWidth != -1) && (m_width < minWidth )) m_width = minWidth; + if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; + if ((maxWidth != -1) && (m_width > maxWidth )) m_width = maxWidth; + if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; + +#if wxUSE_TOOLBAR_NATIVE + if (wxDynamicCast(GetParent(), wxToolBar)) + { + // don't take the x,y values, they're wrong because toolbar sets them + GtkWidget *widget = GTK_WIDGET(m_widget); + gtk_widget_set_size_request (widget, m_width, m_height); + if (GTK_WIDGET_VISIBLE (widget)) + gtk_widget_queue_resize (widget); + } + 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; @@ -3166,32 +2966,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags m_y = y + pizza->yoffset; } - // calculate the best size if we should auto size the window - if ( ((sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1) || - ((sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1) ) - { - const wxSize sizeBest = GetBestSize(); - if ( (sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1 ) - width = sizeBest.x; - if ( (sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1 ) - height = sizeBest.y; - } - - if (width != -1) - m_width = width; - if (height != -1) - m_height = height; - - int minWidth = GetMinWidth(), - minHeight = GetMinHeight(), - maxWidth = GetMaxWidth(), - maxHeight = GetMaxHeight(); - - if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; - if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; - if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; - if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; - int left_border = 0; int right_border = 0; int top_border = 0; @@ -3200,7 +2974,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags /* the default button has a border around it */ if (GTK_WIDGET_CAN_DEFAULT(m_widget)) { -#ifdef __WXGTK20__ GtkBorder *default_border = NULL; gtk_widget_style_get( m_widget, "default_border", &default_border, NULL ); if (default_border) @@ -3211,12 +2984,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags bottom_border += default_border->bottom; g_free( default_border ); } -#else - left_border = 6; - right_border = 6; - top_border = 6; - bottom_border = 5; -#endif } DoMoveWindow( m_x-top_border, @@ -3255,10 +3022,12 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags void wxWindowGTK::OnInternalIdle() { -#ifdef __WXGTK20__ if ( m_dirtyTabOrder ) + { + m_dirtyTabOrder = false; RealizeTabOrder(); -#endif + } + // Update style if the window was not yet realized // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called if (m_needsStyleChange) @@ -3592,7 +3361,6 @@ int wxWindowGTK::GetCharHeight() const wxFont font = GetFont(); wxCHECK_MSG( font.Ok(), 12, wxT("invalid font") ); -#ifdef __WXGTK20__ PangoContext *context = NULL; if (m_widget) context = gtk_widget_get_pango_context( m_widget ); @@ -3612,11 +3380,6 @@ int wxWindowGTK::GetCharHeight() const g_object_unref( G_OBJECT( layout ) ); return (int) PANGO_PIXELS(rect.height); -#else - GdkFont *gfont = font.GetInternalFont( 1.0 ); - - return gfont->ascent + gfont->descent; -#endif } int wxWindowGTK::GetCharWidth() const @@ -3626,7 +3389,6 @@ int wxWindowGTK::GetCharWidth() const wxFont font = GetFont(); wxCHECK_MSG( font.Ok(), 8, wxT("invalid font") ); -#ifdef __WXGTK20__ PangoContext *context = NULL; if (m_widget) context = gtk_widget_get_pango_context( m_widget ); @@ -3646,11 +3408,6 @@ int wxWindowGTK::GetCharWidth() const g_object_unref( G_OBJECT( layout ) ); return (int) PANGO_PIXELS(rect.width); -#else - GdkFont *gfont = font.GetInternalFont( 1.0 ); - - return gdk_string_width( gfont, "g" ); -#endif } void wxWindowGTK::GetTextExtent( const wxString& string, @@ -3671,7 +3428,6 @@ void wxWindowGTK::GetTextExtent( const wxString& string, return; } -#ifdef __WXGTK20__ PangoContext *context = NULL; if (m_widget) context = gtk_widget_get_pango_context( m_widget ); @@ -3712,13 +3468,6 @@ void wxWindowGTK::GetTextExtent( const wxString& string, if (externalLeading) (*externalLeading) = 0; // ?? g_object_unref( G_OBJECT( layout ) ); -#else - GdkFont *font = fontToUse.GetInternalFont( 1.0 ); - if (x) (*x) = gdk_string_width( font, wxGTK_CONV( string ) ); - if (y) (*y) = font->ascent + font->descent; - if (descent) (*descent) = font->descent; - if (externalLeading) (*externalLeading) = 0; // ?? -#endif } void wxWindowGTK::SetFocus() @@ -3739,13 +3488,11 @@ void wxWindowGTK::SetFocus() } else if (m_widget) { -#ifdef __WXGTK20__ if (GTK_IS_CONTAINER(m_widget)) { gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD ); } else -#endif if (GTK_WIDGET_CAN_FOCUS(m_widget) && !GTK_WIDGET_HAS_FOCUS (m_widget) ) { @@ -3770,13 +3517,6 @@ void wxWindowGTK::SetFocus() } } else -#ifndef __WXGTK20__ - if (GTK_IS_CONTAINER(m_widget)) - { - gtk_container_focus( GTK_CONTAINER(m_widget), GTK_DIR_TAB_FORWARD ); - } - else -#endif { wxLogTrace(TRACE_FOCUS, _T("Can't set focus to %s(%s)"), @@ -3841,8 +3581,6 @@ void wxWindowGTK::DoAddChild(wxWindowGTK *child) (*m_insertCallback)(this, child); } -#ifdef __WXGTK20__ - void wxWindowGTK::AddChild(wxWindowBase *child) { wxWindowBase::AddChild(child); @@ -3867,18 +3605,64 @@ void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move) wxapp_install_idle_handler(); } +bool wxWindowGTK::GTKWidgetNeedsMnemonic() const +{ + // none needed by default + return false; +} + +void wxWindowGTK::GTKWidgetDoSetMnemonic(GtkWidget* WXUNUSED(w)) +{ + // nothing to do by default since none is needed +} + void wxWindowGTK::RealizeTabOrder() { if (m_wxwindow) { - if (m_children.size() > 0) + if ( !m_children.empty() ) { + // we don't only construct the correct focus chain but also use + // this opportunity to update the mnemonic widgets for the widgets + // that need them + GList *chain = NULL; + wxWindowGTK* mnemonicWindow = NULL; - for (wxWindowList::const_iterator i = m_children.begin(); - i != m_children.end(); ++i) + for ( wxWindowList::const_iterator i = m_children.begin(); + i != m_children.end(); + ++i ) { - chain = g_list_prepend(chain, (*i)->m_widget); + wxWindowGTK *win = *i; + + if ( mnemonicWindow ) + { + if ( win->AcceptsFocusFromKeyboard() ) + { + // wxComboBox et al. needs to focus on on a different + // widget than m_widget, so if the main widget isn't + // focusable try the connect widget + GtkWidget* w = win->m_widget; + if ( !GTK_WIDGET_CAN_FOCUS(w) ) + { + w = win->GetConnectWidget(); + if ( !GTK_WIDGET_CAN_FOCUS(w) ) + w = NULL; + } + + if ( w ) + { + mnemonicWindow->GTKWidgetDoSetMnemonic(w); + mnemonicWindow = NULL; + } + } + } + else if ( win->GTKWidgetNeedsMnemonic() ) + { + mnemonicWindow = win; + } + + chain = g_list_prepend(chain, win->m_widget); } chain = g_list_reverse(chain); @@ -3886,17 +3670,13 @@ void wxWindowGTK::RealizeTabOrder() gtk_container_set_focus_chain(GTK_CONTAINER(m_wxwindow), chain); g_list_free(chain); } - else + else // no children { gtk_container_unset_focus_chain(GTK_CONTAINER(m_wxwindow)); } } - - m_dirtyTabOrder = false; } -#endif // __WXGTK20__ - void wxWindowGTK::Raise() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); @@ -3958,6 +3738,39 @@ void wxWindowGTK::WarpPointer( int x, int y ) gdk_window_warp_pointer( window, x, y ); } +static bool wxScrollAdjust(GtkAdjustment* adj, double change) +{ + double value_start = adj->value; + double value = value_start + change; + double upper = adj->upper - adj->page_size; + if (value > upper) + { + value = upper; + } + // Lower bound will be checked by gtk_adjustment_set_value + gtk_adjustment_set_value(adj, value); + return adj->value != value_start; +} + +bool wxWindowGTK::ScrollLines(int lines) +{ + return + m_vAdjust != NULL && + wxScrollAdjust(m_vAdjust, lines * m_vAdjust->step_increment); +} + +bool wxWindowGTK::ScrollPages(int pages) +{ + return + m_vAdjust != NULL && + wxScrollAdjust(m_vAdjust, pages * m_vAdjust->page_increment); +} + +void wxWindowGTK::SetVScrollAdjustment(GtkAdjustment* adj) +{ + wxASSERT(m_vAdjust == NULL); + m_vAdjust = adj; +} void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { @@ -3966,67 +3779,6 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (!m_widget->window) return; -#ifndef __WXGTK20__ - if (g_isIdle) - wxapp_install_idle_handler(); - - wxRect myRect; - if (m_wxwindow && rect) - { - myRect.SetSize(wxSize( m_wxwindow->allocation.width, - m_wxwindow->allocation.height)); - if ( myRect.Intersect(*rect).IsEmpty() ) - { - // nothing to do, rectangle is empty - return; - } - - rect = &myRect; - } - - // schedule the area for later updating in GtkUpdate() - if (eraseBackground && m_wxwindow && m_wxwindow->window) - { - if (rect) - { - m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height ); - } - else - { - m_clearRegion.Clear(); - m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); - } - } - - if (rect) - { - if (m_wxwindow) - { - m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height ); - } - else - { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - gtk_widget_draw( m_widget, &gdk_rect ); - } - } - else - { - if (m_wxwindow) - { - m_updateRegion.Clear(); - m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height ); - } - else - { - gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); - } - } -#else // GTK+ 2 if (m_wxwindow) { GdkRectangle gdk_rect, @@ -4046,7 +3798,6 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE ); } -#endif // GTK+ 1/2 } void wxWindowGTK::Update() @@ -4062,13 +3813,8 @@ void wxWindowGTK::Update() void wxWindowGTK::GtkUpdate() { -#ifdef __WXGTK20__ if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE ); -#else - if (!m_updateRegion.IsEmpty()) - GtkSendPaintEvents(); -#endif // for consistency with other platforms (and also because it's convenient // to be able to update an entire TLW by calling Update() only once), we @@ -4085,9 +3831,6 @@ void wxWindowGTK::GtkSendPaintEvents() { if (!m_wxwindow) { -#ifndef __WXGTK20__ - m_clearRegion.Clear(); -#endif m_updateRegion.Clear(); return; } @@ -4131,7 +3874,6 @@ void wxWindowGTK::GtkSendPaintEvents() } else -#ifdef __WXGTK20__ { wxWindowDC dc( (wxWindow*)this ); dc.SetClippingRegion( m_updateRegion ); @@ -4141,38 +3883,6 @@ void wxWindowGTK::GtkSendPaintEvents() GetEventHandler()->ProcessEvent(erase_event); } -#else - // if (!m_clearRegion.IsEmpty()) // Always send an erase event under GTK 1.2 - { - wxWindowDC dc( (wxWindow*)this ); - if (m_clearRegion.IsEmpty()) - dc.SetClippingRegion( m_updateRegion ); - else - dc.SetClippingRegion( m_clearRegion ); - - wxEraseEvent erase_event( GetId(), &dc ); - erase_event.SetEventObject( this ); - - if (!GetEventHandler()->ProcessEvent(erase_event) && GetBackgroundStyle() != wxBG_STYLE_CUSTOM) - { - if (!g_eraseGC) - { - g_eraseGC = gdk_gc_new( pizza->bin_window ); - gdk_gc_set_fill( g_eraseGC, GDK_SOLID ); - } - gdk_gc_set_foreground( g_eraseGC, GetBackgroundColour().GetColor() ); - - wxRegionIterator upd( m_clearRegion ); - while (upd) - { - gdk_draw_rectangle( pizza->bin_window, g_eraseGC, 1, - upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); - upd ++; - } - } - m_clearRegion.Clear(); - } -#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); @@ -4184,67 +3894,12 @@ void wxWindowGTK::GtkSendPaintEvents() m_clipPaintRegion = false; -#if !defined(__WXUNIVERSAL__) && !defined(__WXGTK20__) - // The following code will result in all window-less widgets - // being redrawn because the wxWidgets class is allowed to - // paint over the window-less widgets. - - GList *children = pizza->children; - while (children) - { - GtkPizzaChild *child = (GtkPizzaChild*) children->data; - children = children->next; - - if (GTK_WIDGET_NO_WINDOW (child->widget) && - GTK_WIDGET_DRAWABLE (child->widget)) - { - // Get intersection of widget area and update region - wxRegion region( m_updateRegion ); - - GdkEventExpose gdk_event; - gdk_event.type = GDK_EXPOSE; - gdk_event.window = pizza->bin_window; - gdk_event.count = 0; - gdk_event.send_event = TRUE; - - wxRegionIterator upd( m_updateRegion ); - while (upd) - { - GdkRectangle rect; - rect.x = upd.GetX(); - rect.y = upd.GetY(); - rect.width = upd.GetWidth(); - rect.height = upd.GetHeight(); - - if (gtk_widget_intersect (child->widget, &rect, &gdk_event.area)) - { - gtk_widget_event (child->widget, (GdkEvent*) &gdk_event); - } - - upd ++; - } - } - } -#endif // native GTK 1 - m_updateRegion.Clear(); } void wxWindowGTK::ClearBackground() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); - -#ifndef __WXGTK20__ - if (m_wxwindow && m_wxwindow->window) - { - m_clearRegion.Clear(); - wxSize size( GetClientSize() ); - m_clearRegion.Union( 0,0,size.x,size.y ); - - // Better do this in idle? - GtkUpdate(); - } -#endif } #if wxUSE_TOOLTIPS @@ -4306,12 +3961,10 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour ) return true; } -#ifdef __WXGTK20__ PangoContext *wxWindowGTK::GtkGetPangoDefaultContext() { return gtk_widget_get_pango_context( m_widget ); } -#endif GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle) { @@ -4327,13 +3980,8 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle) if ( m_font.Ok() ) { -#ifdef __WXGTK20__ style->font_desc = pango_font_description_copy( m_font.GetNativeFontInfo()->description ); -#else - wxString xfontname = m_font.GetNativeFontInfo()->GetXFontName(); - style->fontset_name = g_strdup(xfontname.c_str()); -#endif } if ( m_foregroundColour.Ok() ) @@ -4604,21 +4252,21 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, } if (orient == wxHORIZONTAL) - gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + g_signal_emit_by_name (m_hAdjust, "changed"); else - gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + g_signal_emit_by_name (m_vAdjust, "changed"); } void wxWindowGTK::GtkUpdateScrollbar(int orient) { GtkAdjustment *adj = orient == wxHORIZONTAL ? m_hAdjust : m_vAdjust; - GtkSignalFunc fn = orient == wxHORIZONTAL - ? (GtkSignalFunc)gtk_window_hscroll_callback - : (GtkSignalFunc)gtk_window_vscroll_callback; + gpointer fn = orient == wxHORIZONTAL + ? (gpointer) gtk_window_hscroll_callback + : (gpointer) gtk_window_vscroll_callback; - gtk_signal_disconnect_by_func(GTK_OBJECT(adj), fn, (gpointer)this); - gtk_signal_emit_by_name(GTK_OBJECT(adj), "value_changed"); - gtk_signal_connect(GTK_OBJECT(adj), "value_changed", fn, (gpointer)this); + g_signal_handlers_disconnect_by_func (adj, fn, this); + g_signal_emit_by_name (adj, "value_changed"); + g_signal_connect (adj, "value_changed", G_CALLBACK (fn), this); } void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) @@ -4689,28 +4337,6 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) // No scrolling requested. if ((dx == 0) && (dy == 0)) return; -#ifndef __WXGTK20__ - if (!m_updateRegion.IsEmpty()) - { - m_updateRegion.Offset( dx, dy ); - - int cw = 0; - int ch = 0; - GetClientSize( &cw, &ch ); - m_updateRegion.Intersect( 0, 0, cw, ch ); - } - - if (!m_clearRegion.IsEmpty()) - { - m_clearRegion.Offset( dx, dy ); - - int cw = 0; - int ch = 0; - GetClientSize( &cw, &ch ); - m_clearRegion.Intersect( 0, 0, cw, ch ); - } -#endif - m_clipPaintRegion = true; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );