X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f68586e51b20dccee3fd5645aeaca7cc8ff298c2..122603f10fbec49df8de06bc2901758ac12c1baa:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index fb0fb302c4..befad324ff 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -36,15 +36,19 @@ #include "wx/settings.h" #include "wx/log.h" +#ifdef __WXDEBUG__ + #include "wx/thread.h" +#endif + #include -#include "gdk/gdk.h" -#include "gtk/gtk.h" -#include "gdk/gdkprivate.h" -#include "gdk/gdkkeysyms.h" -#include "wx/gtk/win_gtk.h" +#include +#include +#include +#include +#include -#include "gdk/gdkx.h" +#include //----------------------------------------------------------------------------- // documentation on internals @@ -198,12 +202,20 @@ static int g_sendActivateEvent = -1; the last click here */ static guint32 gs_timeLastClick = 0; +extern bool g_mainThreadLocked; + //----------------------------------------------------------------------------- // debug //----------------------------------------------------------------------------- #ifdef __WXDEBUG__ +#if wxUSE_THREADS +# define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance"); +#else +# define DEBUG_MAIN_THREAD +#endif + static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), const wxChar *WXUNUSED(name) ) @@ -223,18 +235,25 @@ static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget), void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window ) { - wxString tmp = name; - tmp += wxT(" FROM "); - tmp += window; + // suppress warnings about gtk_debug_focus_in_callback being unused with + // this "if ( 0 )" + if ( 0 ) + { + wxString tmp = name; + tmp += wxT(" FROM "); + tmp += window; - wxChar *s = new wxChar[tmp.Length()+1]; + wxChar *s = new wxChar[tmp.Length()+1]; - wxStrcpy( s, tmp ); + wxStrcpy( s, tmp ); - gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", - GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s ); + gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s ); + } } +#else +#define DEBUG_MAIN_THREAD #endif // Debug //----------------------------------------------------------------------------- @@ -282,29 +301,35 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) int dw = 0; int dh = 0; - if (win->HasScrolling()) + if (win->m_hasScrolling) { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass ); + GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget); -/* - GtkWidget *hscrollbar = scroll_window->hscrollbar; - GtkWidget *vscrollbar = scroll_window->vscrollbar; + GtkRequisition vscroll_req; + vscroll_req.width = 2; + vscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (scroll_window->vscrollbar, &vscroll_req ); - we use this instead: range.slider_width = 11 + 2*2pts edge -*/ + GtkRequisition hscroll_req; + hscroll_req.width = 2; + hscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (scroll_window->hscrollbar, &hscroll_req ); - if (scroll_window->vscrollbar_visible) - { - dw += 15; /* dw += vscrollbar->allocation.width; */ - dw += scroll_class->scrollbar_spacing; - } + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass ); - if (scroll_window->hscrollbar_visible) - { - dh += 15; /* dh += hscrollbar->allocation.height; */ - dh += scroll_class->scrollbar_spacing; - } + if (scroll_window->vscrollbar_visible) + { + dw += vscroll_req.width; + dw += scroll_class->scrollbar_spacing; + } + + if (scroll_window->hscrollbar_visible) + { + dh += hscroll_req.height; + dh += scroll_class->scrollbar_spacing; + } } int dx = 0; @@ -322,7 +347,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) GTK_STATE_NORMAL, GTK_SHADOW_OUT, dx, dy, - win->m_width-dw, win->m_height-dh ); + widget->allocation.width-dw, widget->allocation.height-dh ); return; } @@ -333,7 +358,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) GTK_STATE_NORMAL, GTK_SHADOW_IN, dx, dy, - win->m_width-dw, win->m_height-dh ); + widget->allocation.width-dw, widget->allocation.height-dh ); return; } @@ -344,7 +369,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) gdk_gc_set_foreground( gc, &widget->style->black ); gdk_draw_rectangle( widget->window, gc, FALSE, dx, dy, - win->m_width-dw-1, win->m_height-dh-1 ); + widget->allocation.width-dw-1, widget->allocation.height-dh-1 ); gdk_gc_unref( gc ); return; } @@ -585,26 +610,32 @@ static long map_to_wx_keysym( KeySym keysym ) static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win ) { - if (!win->m_hasVMT) - return; + DEBUG_MAIN_THREAD +/* + if (win->GetName() == wxT("grid window")) + { + wxPrintf( wxT("OnExpose from ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x, + (int)gdk_event->area.y, + (int)gdk_event->area.width, + (int)gdk_event->area.height ); + } +*/ + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, gdk_event->area.height ); + if (gdk_event->count > 0) return; -/* - wxPrintf( "OnExpose from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x, - (int)gdk_event->area.y, - (int)gdk_event->area.width, - (int)gdk_event->area.height ); -*/ + if (!win->m_hasVMT) + return; wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -624,24 +655,32 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); - - if (!win->m_hasVMT) + + if ((rect->x == 0) && (rect->y == 0) && (rect->width <= 1) && (rect->height <= 1)) return; +/* + if (win->GetName() == wxT("grid window")) + { + 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 ); + } +*/ + win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); -/* - wxPrintf( "OnDraw from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)rect->x, - (int)rect->y, - (int)rect->width, - (int)rect->height ); -*/ + if (!win->m_hasVMT) + return; wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -660,6 +699,8 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -667,17 +708,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e if (g_blockEventsOnDrag) return FALSE; /* + wxString tmp; + tmp += (char)gdk_event->keyval; + printf( "KeyDown-Code is: %s.\n", tmp.c_str() ); printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); - if (gdk_event->state & GDK_SHIFT_MASK) - printf( "ShiftDown.\n" ); - else - printf( "ShiftUp.\n" ); - if (gdk_event->state & GDK_CONTROL_MASK) - printf( "ControlDown.\n" ); - else - printf( "ControlUp.\n" ); - printf( "\n" ); */ + int x = 0; int y = 0; GdkModifierType state; @@ -752,13 +788,13 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) { wxNavigationKeyEvent new_event; - new_event.SetEventObject( win ); + 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->GetEventHandler()->ProcessEvent( new_event ); + ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); } /* generate wxID_CANCEL if has been pressed (typically in dialogs) */ @@ -817,6 +853,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -867,12 +905,46 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk return FALSE; } +// ---------------------------------------------------------------------------- +// mouse event processing helper +// ---------------------------------------------------------------------------- + +static void AdjustEventButtonState(wxMouseEvent& event) +{ + // GDK reports the old state of the button for a button press event, but + // for compatibility with MSW and common sense we want m_leftDown be TRUE + // for a LEFT_DOWN event, not FALSE, so we will invert + // left/right/middleDown for the corresponding click events + switch ( event.GetEventType() ) + { + case wxEVT_LEFT_DOWN: + case wxEVT_LEFT_DCLICK: + case wxEVT_LEFT_UP: + event.m_leftDown = !event.m_leftDown; + break; + + case wxEVT_MIDDLE_DOWN: + case wxEVT_MIDDLE_DCLICK: + case wxEVT_MIDDLE_UP: + event.m_middleDown = !event.m_middleDown; + break; + + case wxEVT_RIGHT_DOWN: + case wxEVT_RIGHT_DCLICK: + case wxEVT_RIGHT_UP: + event.m_rightDown = !event.m_rightDown; + break; + } +} + //----------------------------------------------------------------------------- // "button_press_event" //----------------------------------------------------------------------------- static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -904,7 +976,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton } } - wxEventType event_type = wxEVT_LEFT_DOWN; + wxEventType event_type = wxEVT_NULL; if (gdk_event->button == 1) { @@ -934,6 +1006,12 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton } } + if ( event_type == wxEVT_NULL ) + { + // unknown mouse button or click type + return FALSE; + } + wxMouseEvent event( event_type ); event.SetTimestamp( gdk_event->time ); event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); @@ -944,8 +1022,10 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); - event.m_x = (long)gdk_event->x; - event.m_y = (long)gdk_event->y; + event.m_x = (wxCoord)gdk_event->x; + event.m_y = (wxCoord)gdk_event->y; + + AdjustEventButtonState(event); // Some control don't have their own X window and thus cannot get // any events. @@ -1037,6 +1117,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1060,6 +1142,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto case 1: event_type = wxEVT_LEFT_UP; break; case 2: event_type = wxEVT_MIDDLE_UP; break; case 3: event_type = wxEVT_RIGHT_UP; break; + default: return FALSE; } wxMouseEvent event( event_type ); @@ -1071,8 +1154,10 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK); event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); - event.m_x = (long)gdk_event->x; - event.m_y = (long)gdk_event->y; + event.m_x = (wxCoord)gdk_event->x; + event.m_y = (wxCoord)gdk_event->y; + + AdjustEventButtonState(event); // Some control don't have their own X window and thus cannot get // any events. @@ -1155,6 +1240,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1191,8 +1278,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK); event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK); - event.m_x = (long)gdk_event->x; - event.m_y = (long)gdk_event->y; + event.m_x = (wxCoord)gdk_event->x; + event.m_y = (wxCoord)gdk_event->y; // Some control don't have their own X window and thus cannot get // any events. @@ -1275,6 +1362,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1312,6 +1401,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( panel->SetLastFocus(win); } +#ifdef HAVE_XIM + if (win->m_ic) + gdk_im_begin(win->m_ic, win->m_wxwindow->window); +#endif + wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1330,6 +1424,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1350,6 +1446,11 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED printf( ".\n" ); */ +#ifdef HAVE_XIM + if (win->m_ic) + gdk_im_end(); +#endif + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1368,6 +1469,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1396,8 +1499,8 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ event.m_middleDown = (state & GDK_BUTTON2_MASK); event.m_rightDown = (state & GDK_BUTTON3_MASK); - event.m_x = (long)x; - event.m_y = (long)y; + event.m_x = x; + event.m_y = y; if (win->GetEventHandler()->ProcessEvent( event )) { @@ -1414,6 +1517,8 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1442,8 +1547,8 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ event.m_middleDown = (state & GDK_BUTTON2_MASK); event.m_rightDown = (state & GDK_BUTTON3_MASK); - event.m_x = (long)x; - event.m_y = (long)y; + event.m_x = x; + event.m_y = y; if (win->GetEventHandler()->ProcessEvent( event )) { @@ -1460,6 +1565,8 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1494,6 +1601,8 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win ) static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); @@ -1522,81 +1631,65 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win ) } //----------------------------------------------------------------------------- -// "changed" from m_vAdjust +// "button_press_event" from scrollbar //----------------------------------------------------------------------------- -static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win ) +static gint gtk_scrollbar_button_press_callback( GtkRange *widget, + GdkEventButton *gdk_event, + wxWindow *win) { - if (g_isIdle) - wxapp_install_idle_handler(); + DEBUG_MAIN_THREAD - if (g_blockEventsOnDrag) return; - if (!win->m_hasVMT) return; - - wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK; - int value = (int)(win->m_vAdjust->value+0.5); - - wxScrollWinEvent event( command, value, wxVERTICAL ); - event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); -} - -//----------------------------------------------------------------------------- -// "changed" from m_hAdjust -//----------------------------------------------------------------------------- - -static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win ) -{ if (g_isIdle) wxapp_install_idle_handler(); - if (g_blockEventsOnDrag) return; - if (!win->m_hasVMT) return; - - wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK; - int value = (int)(win->m_hAdjust->value+0.5); + g_blockEventsOnScroll = TRUE; + win->m_isScrolling = (gdk_event->window == widget->slider); - wxScrollWinEvent event( command, value, wxHORIZONTAL ); - event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + return FALSE; } //----------------------------------------------------------------------------- -// "button_press_event" from scrollbar +// "button_release_event" from scrollbar //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), - GdkEventButton *WXUNUSED(gdk_event), - wxWindow *win ) +static gint gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindow *win) { - if (g_isIdle) - wxapp_install_idle_handler(); + DEBUG_MAIN_THREAD // don't test here as we can release the mouse while being over // a different window than the slider // // if (gdk_event->window != widget->slider) return FALSE; - win->SetScrolling( TRUE ); + g_blockEventsOnScroll = FALSE; - return FALSE; -} - -//----------------------------------------------------------------------------- -// "button_release_event" from scrollbar -//----------------------------------------------------------------------------- + if (win->m_isScrolling) + { + wxEventType command = wxEVT_SCROLL_THUMBRELEASE; + int value = -1; + int dir = -1; -static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget), - GdkEventButton *WXUNUSED(gdk_event), - wxWindow *win ) -{ + GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget); + if (widget == GTK_RANGE(scrolledWindow->hscrollbar)) + { + value = (int)(win->m_hAdjust->value+0.5); + dir = wxHORIZONTAL; + } + if (widget == GTK_RANGE(scrolledWindow->vscrollbar)) + { + value = (int)(win->m_vAdjust->value+0.5); + dir = wxVERTICAL; + } -// don't test here as we can release the mouse while being over -// a different window than the slider -// -// if (gdk_event->window != widget->slider) return FALSE; + wxScrollWinEvent event( command, value, dir ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + } - win->SetScrolling( FALSE ); + win->m_isScrolling = FALSE; return FALSE; } @@ -1615,18 +1708,17 @@ wxWindow *wxWindowBase::FindFocus() // "realize" from m_widget //----------------------------------------------------------------------------- -/* we cannot set colours and fonts before the widget has - been realized, so we do this directly after realization */ +/* We cannot set colours and fonts before the widget has + been realized, so we do this directly after realization. */ static gint -gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win ) +gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win ) { + DEBUG_MAIN_THREAD + if (g_isIdle) wxapp_install_idle_handler(); - if (win->m_delayedFont) - win->SetFont( win->GetFont() ); - if (win->m_delayedBackgroundColour) win->SetBackgroundColour( win->GetBackgroundColour() ); @@ -1636,6 +1728,163 @@ gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win ) wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "size_allocate" +//----------------------------------------------------------------------------- + +static +void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), + GtkAllocation *WXUNUSED(alloc), + wxWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + if (!win->m_hasScrolling) return; + + 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; + + win->m_oldClientWidth = client_width; + win->m_oldClientHeight = client_height; + + if (!win->m_nativeSizeEvent) + { + wxSizeEvent event( win->GetSize(), win->GetId() ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + } +} + + +#ifdef HAVE_XIM + #define WXUNUSED_UNLESS_XIM(param) param +#else + #define WXUNUSED_UNLESS_XIM(param) WXUNUSED(param) +#endif + +/* Resize XIM window */ + +static +void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), + GtkAllocation* WXUNUSED_UNLESS_XIM(alloc), + wxWindow* WXUNUSED_UNLESS_XIM(win) ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + +#ifdef HAVE_XIM + if (!win->m_ic) + return; + + if (gdk_ic_get_style (win->m_ic) & GDK_IM_PREEDIT_POSITION) + { + gint width, height; + + gdk_window_get_size (widget->window, &width, &height); + win->m_icattr->preedit_area.width = width; + win->m_icattr->preedit_area.height = height; + gdk_ic_set_attr (win->m_ic, win->m_icattr, GDK_IC_PREEDIT_AREA); + } +#endif // HAVE_XIM +} + +//----------------------------------------------------------------------------- +// "realize" from m_wxwindow +//----------------------------------------------------------------------------- + +/* Initialize XIM support */ + +static gint +gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), + wxWindow * WXUNUSED_UNLESS_XIM(win) ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + +#ifdef HAVE_XIM + if (win->m_ic) return FALSE; + if (!widget) return FALSE; + if (!gdk_im_ready()) return FALSE; + + win->m_icattr = gdk_ic_attr_new(); + if (!win->m_icattr) return FALSE; + + gint width, height; + GdkEventMask mask; + GdkColormap *colormap; + GdkICAttr *attr = win->m_icattr; + unsigned attrmask = GDK_IC_ALL_REQ; + GdkIMStyle style; + GdkIMStyle supported_style = (GdkIMStyle) + (GDK_IM_PREEDIT_NONE | + GDK_IM_PREEDIT_NOTHING | + GDK_IM_PREEDIT_POSITION | + GDK_IM_STATUS_NONE | + GDK_IM_STATUS_NOTHING); + + if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) + supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION); + + attr->style = style = gdk_im_decide_style (supported_style); + attr->client_window = widget->window; + + if ((colormap = gtk_widget_get_colormap (widget)) != + gtk_widget_get_default_colormap ()) + { + attrmask |= GDK_IC_PREEDIT_COLORMAP; + attr->preedit_colormap = colormap; + } + + attrmask |= GDK_IC_PREEDIT_FOREGROUND; + attrmask |= GDK_IC_PREEDIT_BACKGROUND; + attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL]; + attr->preedit_background = widget->style->base[GTK_STATE_NORMAL]; + + switch (style & GDK_IM_PREEDIT_MASK) + { + case GDK_IM_PREEDIT_POSITION: + if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) + { + g_warning ("over-the-spot style requires fontset"); + break; + } + + gdk_window_get_size (widget->window, &width, &height); + + attrmask |= GDK_IC_PREEDIT_POSITION_REQ; + attr->spot_location.x = 0; + attr->spot_location.y = height; + attr->preedit_area.x = 0; + attr->preedit_area.y = 0; + attr->preedit_area.width = width; + attr->preedit_area.height = height; + attr->preedit_fontset = widget->style->font; + + break; + } + + win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask); + + if (win->m_ic == NULL) + g_warning ("Can't create input context."); + else + { + mask = gdk_window_get_events (widget->window); + mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); + gdk_window_set_events (widget->window, mask); + + if (GTK_WIDGET_HAS_FOCUS(widget)) + gdk_im_begin (win->m_ic, widget->window); + } +#endif return FALSE; } @@ -1724,6 +1973,11 @@ void wxWindow::Init() m_acceptsFocus = FALSE; m_cursor = *wxSTANDARD_CURSOR; + +#ifdef HAVE_XIM + m_ic = (GdkIC*) NULL; + m_icattr = (GdkICAttr*) NULL; +#endif } wxWindow::wxWindow() @@ -1869,11 +2123,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed", - (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this ); - gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed", - (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this ); - gtk_widget_show( m_wxwindow ); if (m_parent) @@ -1899,9 +2148,19 @@ wxWindow::~wxWindow() if (m_parent) m_parent->RemoveChild( this ); +#ifdef HAVE_XIM + if (m_ic) + gdk_ic_destroy (m_ic); + if (m_icattr) + gdk_ic_attr_destroy (m_icattr); +#endif + if (m_widgetStyle) { - gtk_style_unref( m_widgetStyle ); + // don't delete if it's a pixmap theme style + if (!m_widgetStyle->engine_data) + gtk_style_unref( m_widgetStyle ); + m_widgetStyle = (GtkStyle*) NULL; } @@ -1976,15 +2235,50 @@ void wxWindow::PostCreation() #endif } + if (m_wxwindow && m_needParent) + { + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "focus_out_event", + GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this ); + } + else + { + // For dialogs and frames, we are interested mainly in + // m_widget's focus. + + gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_widget), "focus_out_event", + GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this ); + } + GtkWidget *connect_widget = GetConnectWidget(); ConnectWidget( connect_widget ); - /* we cannot set colours, fonts and cursors before the widget has + /* 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 ); + 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 ); + + /* Initialize XIM support. */ + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", + GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback), (gpointer) this ); + + /* And resize XIM window. */ + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate", + GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this ); + } + m_hasVMT = TRUE; } @@ -2005,12 +2299,6 @@ void wxWindow::ConnectWidget( GtkWidget *widget ) gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event", GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this ); - gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", - GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event", - GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this ); - gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event", GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this ); @@ -2027,6 +2315,11 @@ bool wxWindow::Destroy() return wxWindowBase::Destroy(); } +void wxWindow::DoMoveWindow(int x, int y, int width, int height) +{ + gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height ); +} + void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); @@ -2087,12 +2380,15 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) bottom_border = 5; } - gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), - m_widget, - m_x-border, - m_y-border, - m_width+2*border, - m_height+border+bottom_border ); + DoMoveWindow( m_x-border, + m_y-border, + m_width+2*border, + m_height+border+bottom_border ); + } + + if (m_hasScrolling) + { + GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); } /* @@ -2185,24 +2481,6 @@ void wxWindow::DoSetClientSize( int width, int height ) int dw = 0; int dh = 0; -#if (GTK_MINOR_VERSION == 0) - if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) - { - if (HasScrolling()) - { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); -#if 0 // unused - if this is ok, just remove this line (VZ) - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); -#endif // 0 - - GtkWidget *viewport = scroll_window->viewport; - GtkStyleClass *viewport_class = viewport->style->klass; - - dw += 2 * viewport_class->xthickness; - dh += 2 * viewport_class->ythickness; - } - } -#else if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2215,32 +2493,37 @@ void wxWindow::DoSetClientSize( int width, int height ) dw += 1 * 2; dh += 1 * 2; } -#endif - if (HasScrolling()) + if (m_hasScrolling) { -/* - GtkWidget *hscrollbar = scroll_window->hscrollbar; - GtkWidget *vscrollbar = scroll_window->vscrollbar; + GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); - we use this instead: range.slider_width = 11 + 2*2pts edge -*/ + GtkRequisition vscroll_req; + vscroll_req.width = 2; + vscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (scroll_window->vscrollbar, &vscroll_req ); + + GtkRequisition hscroll_req; + hscroll_req.width = 2; + hscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (scroll_window->hscrollbar, &hscroll_req ); - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); if (scroll_window->vscrollbar_visible) { - dw += 15; /* dw += vscrollbar->allocation.width; */ + dw += vscroll_req.width; dw += scroll_class->scrollbar_spacing; } if (scroll_window->hscrollbar_visible) { - dh += 15; /* dh += hscrollbar->allocation.height; */ + dh += hscroll_req.height; dh += scroll_class->scrollbar_spacing; } - } + } SetSize( width+dw, height+dh ); } @@ -2260,24 +2543,6 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const int dw = 0; int dh = 0; -#if (GTK_MINOR_VERSION == 0) - if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) - { - if (HasScrolling()) - { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); -#if 0 // unused - if this is ok, just remove this line (VZ) - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); -#endif // 0 - - GtkWidget *viewport = scroll_window->viewport; - GtkStyleClass *viewport_class = viewport->style->klass; - - dw += 2 * viewport_class->xthickness; - dh += 2 * viewport_class->ythickness; - } - } -#else if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { /* when using GTK 1.2 we set the shadow border size to 2 */ @@ -2290,28 +2555,34 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const dw += 1 * 2; dh += 1 * 2; } -#endif - if (HasScrolling()) + + if (m_hasScrolling) { -/* - GtkWidget *hscrollbar = scroll_window->hscrollbar; - GtkWidget *vscrollbar = scroll_window->vscrollbar; + GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); - we use this instead: range.slider_width = 11 + 2*2pts edge -*/ + GtkRequisition vscroll_req; + vscroll_req.width = 2; + vscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request ) + (scroll_window->vscrollbar, &vscroll_req ); + + GtkRequisition hscroll_req; + hscroll_req.width = 2; + hscroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request ) + (scroll_window->hscrollbar, &hscroll_req ); - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); if (scroll_window->vscrollbar_visible) { - dw += 15; /* dw += vscrollbar->allocation.width; */ + dw += vscroll_req.width; dw += scroll_class->scrollbar_spacing; } if (scroll_window->hscrollbar_visible) { - dh += 15; /* dh += hscrollbar->allocation.height; */ + dh += hscroll_req.height; dh += scroll_class->scrollbar_spacing; } } @@ -2600,8 +2871,7 @@ void wxWindow::WarpPointer( int x, int y ) void wxWindow::Refresh( bool eraseBackground, const wxRect *rect ) { - wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - + if (!m_widget) return; if (!m_widget->window) return; if (eraseBackground && m_wxwindow && m_wxwindow->window) @@ -2667,7 +2937,7 @@ void wxWindow::Clear() if (m_wxwindow && m_wxwindow->window) { - gdk_window_clear( m_wxwindow->window ); +// gdk_window_clear( m_wxwindow->window ); } } @@ -2709,12 +2979,11 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour ) // but it couldn't get applied as the // widget hasn't been realized yet. m_delayedBackgroundColour = TRUE; - - // pretend we have done something - return TRUE; } - if (m_wxwindow) + if ((m_wxwindow) && + (m_wxwindow->window) && + (m_backgroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE))) { /* wxMSW doesn't clear the window here. I don't do that either to provide compatibility. call Clear() to do the job. */ @@ -2723,17 +2992,7 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour ) gdk_window_set_background( window, m_backgroundColour.GetColor() ); } - wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ); - if (sysbg == m_backgroundColour) - { - m_backgroundColour = wxNullColour; - ApplyWidgetStyle(); - m_backgroundColour = sysbg; - } - else - { - ApplyWidgetStyle(); - } + ApplyWidgetStyle(); return TRUE; } @@ -2761,61 +3020,84 @@ bool wxWindow::SetForegroundColour( const wxColour &colour ) // but it couldn't get applied as the // widget hasn't been realized yet. m_delayedForegroundColour = TRUE; - - // pretend we have done something - return TRUE; } - wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ); - if ( sysbg == m_backgroundColour ) - { - m_backgroundColour = wxNullColour; - ApplyWidgetStyle(); - m_backgroundColour = sysbg; - } - else - { - ApplyWidgetStyle(); - } + ApplyWidgetStyle(); return TRUE; } GtkStyle *wxWindow::GetWidgetStyle() { - if (m_widgetStyle) gtk_style_unref( m_widgetStyle ); + if (m_widgetStyle) + { + GtkStyle *remake = gtk_style_copy( m_widgetStyle ); + remake->klass = m_widgetStyle->klass; + + gtk_style_unref( m_widgetStyle ); + m_widgetStyle = remake; + } + else + { + GtkStyle *def = gtk_rc_get_style( m_widget ); + + if (!def) + def = gtk_widget_get_default_style(); - m_widgetStyle = gtk_style_copy( gtk_widget_get_style( m_widget ) ); + m_widgetStyle = gtk_style_copy( def ); + m_widgetStyle->klass = def->klass; + } return m_widgetStyle; } void wxWindow::SetWidgetStyle() { + if (m_widget->style->engine_data) + { + static bool s_warningPrinted = FALSE; + if (!s_warningPrinted) + { + printf( "wxWindows warning: Widget styles disabled due to buggy GTK theme.\n" ); + s_warningPrinted = TRUE; + } + m_widgetStyle = m_widget->style; + return; + } + GtkStyle *style = GetWidgetStyle(); - gdk_font_unref( style->font ); - style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) ); + if (m_font != wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT )) + { + gdk_font_unref( style->font ); + style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) ); + } if (m_foregroundColour.Ok()) { m_foregroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) ); - style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor(); - style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); - style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); + if (m_foregroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT)) + { + style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); + } } if (m_backgroundColour.Ok()) { m_backgroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) ); - style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); - style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); - style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); - style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + if (m_backgroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE)) + { + style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + } } } @@ -3096,20 +3378,29 @@ void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) m_vAdjust->value = fpos; } -/* - if (!m_isScrolling) + if (m_wxwindow->window) { -*/ - if (m_wxwindow->window) + if (orient == wxHORIZONTAL) { - if (orient == wxHORIZONTAL) - gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" ); - else - gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" ); + gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust), + (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); + + gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" ); + + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", + (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); + } + else + { + gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust), + (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); + + gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" ); + + gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", + (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); } -/* } -*/ } int wxWindow::GetScrollThumb( int orient ) const @@ -3153,63 +3444,60 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); + + if ((dx == 0) && (dy == 0)) return; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); - -/* - if (!m_scrollGC) + +/* + if (m_children.GetCount() > 0) { - m_scrollGC = gdk_gc_new( m_wxwindow->window ); - gdk_gc_set_exposures( m_scrollGC, TRUE ); - } - - wxNode *node = m_children.First(); - while (node) - { - wxWindow *child = (wxWindow*) node->Data(); - int sx = 0; - int sy = 0; - child->GetSize( &sx, &sy ); - child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE ); - node = node->Next(); - } - - int cw = 0; - int ch = 0; - GetClientSize( &cw, &ch ); - int w = cw - abs(dx); - int h = ch - abs(dy); - - if ((h < 0) || (w < 0)) - { - Refresh(); + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); } else { - int s_x = 0; - int s_y = 0; - if (dx < 0) s_x = -dx; - if (dy < 0) s_y = -dy; - int d_x = 0; - int d_y = 0; - if (dx > 0) d_x = dx; - if (dy > 0) d_y = dy; - - gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y, - m_wxwindow->window, s_x, s_y, w, h ); + GtkPizza *pizza = GTK_PIZZA(m_wxwindow); + + pizza->xoffset -= dx; + pizza->yoffset -= dy; + + GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); + gdk_gc_set_exposures( m_scrollGC, TRUE ); - wxRect rect; - if (dx < 0) rect.x = cw+dx; else rect.x = 0; - if (dy < 0) rect.y = ch+dy; else rect.y = 0; - if (dy != 0) rect.width = cw; else rect.width = abs(dx); - if (dx != 0) rect.height = ch; else rect.height = abs(dy); + int cw = 0; + int ch = 0; + GetClientSize( &cw, &ch ); + int w = cw - abs(dx); + int h = ch - abs(dy); - Refresh( TRUE, &rect ); + if ((h < 0) || (w < 0)) + { + Refresh(); + } + else + { + int s_x = 0; + int s_y = 0; + if (dx < 0) s_x = -dx; + if (dy < 0) s_y = -dy; + int d_x = 0; + int d_y = 0; + if (dx > 0) d_x = dx; + if (dy > 0) d_y = dy; + + gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y, + pizza->bin_window, s_x, s_y, w, h ); + + wxRect rect; + if (dx < 0) rect.x = cw+dx; else rect.x = 0; + if (dy < 0) rect.y = ch+dy; else rect.y = 0; + if (dy != 0) rect.width = cw; else rect.width = abs(dx); + if (dx != 0) rect.height = ch; else rect.height = abs(dy); + + Refresh( TRUE, &rect ); + } + + gdk_gc_unref( m_scrollGC ); } */ } - -void wxWindow::SetScrolling(bool scroll) -{ - m_isScrolling = g_blockEventsOnScroll = scroll; -}