X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/defdd888002f2dabf2228a4e4b58d4e7a0b56eda..7282b0678a879077a109495cb3cd20b28ea9cf45:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 2cfd697af3..2618e11b8c 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: gtk/window.cpp +// Name: src/gtk1/window.cpp // Purpose: // Author: Robert Roebling // Id: $Id$ @@ -15,15 +15,25 @@ #endif #include "wx/window.h" -#include "wx/dcclient.h" -#include "wx/frame.h" -#include "wx/app.h" -#include "wx/layout.h" -#include "wx/utils.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" -#include "wx/module.h" -#include "wx/combobox.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/frame.h" + #include "wx/dcclient.h" + #include "wx/menu.h" + #include "wx/dialog.h" + #include "wx/settings.h" + #include "wx/msgdlg.h" + #include "wx/textctrl.h" + #include "wx/combobox.h" + #include "wx/layout.h" + #include "wx/statusbr.h" + #include "wx/math.h" + #include "wx/module.h" +#endif #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -37,25 +47,15 @@ #include "wx/caret.h" #endif // wxUSE_CARET -#if wxUSE_TEXTCTRL - #include "wx/textctrl.h" -#endif - -#include "wx/menu.h" -#include "wx/statusbr.h" -#include "wx/intl.h" -#include "wx/settings.h" -#include "wx/log.h" #include "wx/fontutil.h" -#ifdef __WXDEBUG__ +#if wxDEBUG_LEVEL #include "wx/thread.h" #endif -#include "wx/math.h" #include -#include "wx/gtk/private.h" +#include "wx/gtk1/private.h" #include #include #include @@ -63,22 +63,7 @@ #include #include -#include "wx/gtk/win_gtk.h" - -#ifdef __WXGTK20__ -#include -#endif - - -#ifdef __WXGTK20__ - #ifdef HAVE_XIM - #undef HAVE_XIM - #endif -#endif - -#ifdef __WXGTK20__ -extern GtkContainerClass *pizza_parent_class; -#endif +#include "wx/gtk1/win_gtk.h" //----------------------------------------------------------------------------- // documentation on internals @@ -214,7 +199,6 @@ extern GtkContainerClass *pizza_parent_class; // data //----------------------------------------------------------------------------- -extern wxList wxPendingDelete; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; @@ -223,25 +207,28 @@ static GdkGC *g_eraseGC = NULL; // mouse capture state: the window which has it and if the mouse is currently // inside it -static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL; +static wxWindowGTK *g_captureWindow = NULL; static bool g_captureWindowHasMouse = false; -wxWindowGTK *g_focusWindow = (wxWindowGTK*) NULL; +wxWindowGTK *g_focusWindow = NULL; // the last window which had the focus - this is normally never NULL (except // if we never had focus at all) as even when g_focusWindow is NULL it still // keeps its previous value -wxWindowGTK *g_focusWindowLast = (wxWindowGTK*) NULL; +wxWindowGTK *g_focusWindowLast = NULL; // If a window get the focus set but has not been realized // yet, defer setting the focus to idle time. -wxWindowGTK *g_delayedFocus = (wxWindowGTK*) NULL; +wxWindowGTK *g_delayedFocus = 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 + +// global variables because GTK+ DnD want to have the +// mouse event that caused it +GdkEvent *g_lastMouseEvent = NULL; +int g_lastButtonNumber = 0; extern bool g_mainThreadLocked; @@ -249,19 +236,16 @@ extern bool g_mainThreadLocked; // debug //----------------------------------------------------------------------------- -#ifdef __WXDEBUG__ - #if wxUSE_THREADS -# define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance"); +# define DEBUG_MAIN_THREAD \ + wxASSERT_MSG( !g_mainThreadLocked || !wxThread::IsMain(), \ + "GUI reentrancy detected" ); #else # define DEBUG_MAIN_THREAD #endif -#else -#define DEBUG_MAIN_THREAD -#endif // Debug // the trace mask used for the focus debugging messages -#define TRACE_FOCUS _T("focus") +#define TRACE_FOCUS wxT("focus") //----------------------------------------------------------------------------- // missing gdk functions @@ -272,23 +256,11 @@ 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), - None, /* not source window -> move from anywhere */ - GDK_WINDOW_XID(window), /* dest window */ - 0, 0, 0, 0, /* not source window -> move from anywhere */ - x, y ); - } -#else priv = (GdkWindowPrivate*) window; if (!priv->destroyed) @@ -299,7 +271,6 @@ gdk_window_warp_pointer (GdkWindow *window, 0, 0, 0, 0, /* not source window -> move from anywhere */ x, y ); } -#endif } //----------------------------------------------------------------------------- @@ -320,7 +291,7 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win) { wxWindow *winFocus = wxWindowGTK::FindFocus(); if ( !winFocus ) - return (wxWindow *)NULL; + return NULL; if ( winFocus == win ) return (wxWindow *)win; @@ -334,7 +305,7 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win) return child; } - return (wxWindow *)NULL; + return NULL; } static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) @@ -397,7 +368,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) return; } - if (win->HasFlag(wxSUNKEN_BORDER)) + if (win->HasFlag(wxSUNKEN_BORDER) || win->HasFlag(wxBORDER_THEME)) { gtk_draw_shadow( widget->style, widget->window, @@ -433,11 +404,6 @@ static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *g draw_frame( widget, win ); -#ifdef __WXGTK20__ - - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); - -#endif return TRUE; } } @@ -446,8 +412,6 @@ static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *g // "draw" of m_widget //----------------------------------------------------------------------------- -#ifndef __WXGTK20__ - extern "C" { static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win ) { @@ -455,15 +419,13 @@ static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNU } } -#endif // GTK+ < 2.0 - //----------------------------------------------------------------------------- // "size_request" of m_widget //----------------------------------------------------------------------------- // make it extern because wxStaticText needs to disconnect this one extern "C" { -void wxgtk_window_size_request_callback(GtkWidget *widget, +void wxgtk_window_size_request_callback(GtkWidget *WXUNUSED(widget), GtkRequisition *requisition, wxWindow *win) { @@ -481,7 +443,7 @@ void wxgtk_window_size_request_callback(GtkWidget *widget, extern "C" { static -void wxgtk_combo_size_request_callback(GtkWidget *widget, +void wxgtk_combo_size_request_callback(GtkWidget *WXUNUSED(widget), GtkRequisition *requisition, wxComboBox *win) { @@ -513,7 +475,7 @@ void wxgtk_combo_size_request_callback(GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static int gtk_window_expose_callback( GtkWidget *widget, +static int gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win ) { @@ -522,47 +484,6 @@ static int gtk_window_expose_callback( GtkWidget *widget, 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. - - GtkPizza *pizza = GTK_PIZZA( widget ); - if (gdk_event->window != pizza->bin_window) return FALSE; - -#if 0 - if (win->GetName()) - { - 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 ); - } - - gtk_paint_box - ( - win->m_wxwindow->style, - pizza->bin_window, - GTK_STATE_NORMAL, - GTK_SHADOW_OUT, - (GdkRectangle*) NULL, - win->m_wxwindow, - (char *)"button", // const_cast - 20,20,24,24 - ); -#endif - - win->GetUpdateRegion() = wxRegion( gdk_event->region ); - - win->GtkSendPaintEvents(); - - - // 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. @@ -578,7 +499,6 @@ static int gtk_window_expose_callback( GtkWidget *widget, // Actual redrawing takes place in idle time. // win->GtkUpdate(); -#endif return FALSE; } @@ -588,8 +508,6 @@ static int gtk_window_expose_callback( GtkWidget *widget, // "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. @@ -612,14 +530,10 @@ gint gtk_window_event_event_callback( GtkWidget *widget, } } -#endif // !GTK+ 2 - //----------------------------------------------------------------------------- // "draw" of m_wxwindow //----------------------------------------------------------------------------- -#ifndef __WXGTK20__ - // This callback is a complete replacement of the gtk_pizza_draw() function, // which is disabled. @@ -694,21 +608,19 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle child_area; if (gtk_widget_intersect (child->widget, rect, &child_area)) { - gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ ); + gtk_widget_draw (child->widget, &child_area /* NULL*/ ); } } #endif } } -#endif - //----------------------------------------------------------------------------- // "key_press_event" from any window //----------------------------------------------------------------------------- // set WXTRACE to this to see the key event codes on the console -#define TRACE_KEYS _T("keyevent") +#define TRACE_KEYS wxT("keyevent") // translates an X key symbol to WXK_XXX value // @@ -828,11 +740,11 @@ static long wxTranslateKeySymToWXKey(KeySym keysym, bool isChar) break; case GDK_Prior: // == GDK_Page_Up - key_code = WXK_PRIOR; + key_code = WXK_PAGEUP; break; case GDK_Next: // == GDK_Page_Down - key_code = WXK_NEXT; + key_code = WXK_PAGEDOWN; break; case GDK_End: @@ -911,11 +823,11 @@ static long wxTranslateKeySymToWXKey(KeySym keysym, bool isChar) break; case GDK_KP_Prior: // == GDK_KP_Page_Up - key_code = isChar ? WXK_PRIOR : WXK_NUMPAD_PRIOR; + key_code = isChar ? WXK_PAGEUP : WXK_NUMPAD_PAGEUP; break; case GDK_KP_Next: // == GDK_KP_Page_Down - key_code = isChar ? WXK_NEXT : WXK_NUMPAD_NEXT; + key_code = isChar ? WXK_PAGEDOWN : WXK_NUMPAD_PAGEDOWN; break; case GDK_KP_End: @@ -1008,11 +920,13 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event, event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0; event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0; event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK) != 0; - event.m_scanCode = gdk_event->keyval; event.m_rawCode = (wxUint32) gdk_event->keyval; event.m_rawFlags = 0; #if wxUSE_UNICODE - event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval); +#if 0 + // this is not gtk1.x + event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval); +#endif #endif wxGetMousePosition( &x, &y ); win->ScreenToClient( &x, &y ); @@ -1040,9 +954,9 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, KeySym keysym = gdk_event->keyval; - wxLogTrace(TRACE_KEYS, _T("Key %s event: keysym = %ld"), - event.GetEventType() == wxEVT_KEY_UP ? _T("release") - : _T("press"), + wxLogTrace(TRACE_KEYS, wxT("Key %s event: keysym = %ld"), + event.GetEventType() == wxEVT_KEY_UP ? wxT("release") + : wxT("press"), keysym); long key_code = wxTranslateKeySymToWXKey(keysym, false /* !isChar */); @@ -1071,7 +985,7 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, Display *dpy = (Display *)wxGetDisplay(); KeyCode keycode = XKeysymToKeycode(dpy, keysym); - wxLogTrace(TRACE_KEYS, _T("\t-> keycode %d"), keycode); + wxLogTrace(TRACE_KEYS, wxT("\t-> keycode %d"), keycode); KeySym keysymNormalized = XKeycodeToKeysym(dpy, keycode, 0); @@ -1110,7 +1024,7 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, } } - wxLogTrace(TRACE_KEYS, _T("\t-> wxKeyCode %ld"), key_code); + wxLogTrace(TRACE_KEYS, wxT("\t-> wxKeyCode %ld"), key_code); // sending unknown key events doesn't really make sense if ( !key_code ) @@ -1125,24 +1039,6 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, } -#ifdef __WXGTK20__ -struct wxGtkIMData -{ - GtkIMContext *context; - GdkEventKey *lastKeyEvent; - - wxGtkIMData() - { - context = gtk_im_multicontext_new(); - lastKeyEvent = NULL; - } - ~wxGtkIMData() - { - g_object_unref(context); - } -}; -#endif - extern "C" { static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, @@ -1163,10 +1059,10 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, bool ret = false; bool return_after_IM = false; - if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) + if ( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) { // Emit KEY_DOWN event - ret = win->GetEventHandler()->ProcessEvent( event ); + ret = win->HandleWindowEvent( event ); } else { @@ -1175,36 +1071,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 - // with the INPUT FOCUS can generate the INITIAL key_press event. That is, - // if the CURRENT widget doesn't have the FOCUS at all, this event definitely - // originated from its child widgets and shouldn't be passed to IM context. - // In fact, what a GTK+ IM should do is filtering keyEvents and convert them - // into text input ONLY WHEN THE WIDGET HAS INPUT FOCUS. Besides, when current - // widgets has both IM context and input focus, the event should be filtered - // by gtk_im_context_filter_keypress(). - // Then, we should, according to GTK+ 2.0 API doc, return whatever it returns. - if ((!ret) && (win->m_imData != NULL) && ( wxWindow::FindFocus() == win )) - { - // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API - // docs, if IM filter returns true, no further processing should be done. - // we should send the key_down event anyway. - bool intercepted_by_IM = gtk_im_context_filter_keypress(win->m_imData->context, gdk_event); - win->m_imData->lastKeyEvent = NULL; - if (intercepted_by_IM) - { - wxLogTrace(TRACE_KEYS, _T("Key event intercepted by IM")); - 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. @@ -1252,18 +1118,19 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (parent) { event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->GetEventHandler()->ProcessEvent( event ); + ret = parent->HandleWindowEvent( event ); } if (!ret) { event.SetEventType(wxEVT_CHAR); - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } } return true; } -#endif // #ifndef __WXGTK20__ + if (return_after_IM) + return false; #if wxUSE_ACCEL if (!ret) @@ -1275,7 +1142,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (command != -1) { wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); - ret = ancestor->GetEventHandler()->ProcessEvent( command_event ); + ret = ancestor->HandleWindowEvent( command_event ); break; } if (ancestor->IsTopLevel()) @@ -1309,7 +1176,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if ( key_code ) { - wxLogTrace(TRACE_KEYS, _T("Char event: %ld"), key_code); + wxLogTrace(TRACE_KEYS, wxT("Char event: %ld"), key_code); event.m_keyCode = key_code; @@ -1320,13 +1187,13 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (parent) { event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->GetEventHandler()->ProcessEvent( event ); + ret = parent->HandleWindowEvent( event ); } if (!ret) { event.SetEventType(wxEVT_CHAR); - ret = win->GetEventHandler()->ProcessEvent( event ); + ret = win->HandleWindowEvent( event ); } } } @@ -1356,7 +1223,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, // CTRL-TAB changes the (parent) window, i.e. switch notebook page new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); new_event.SetCurrentFocus( win ); - ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); + ret = win->GetParent()->HandleWindowEvent( new_event ); } // generate wxID_CANCEL if has been pressed (typically in dialogs) @@ -1392,7 +1259,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, { wxCommandEvent eventClick(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); eventClick.SetEventObject(btnCancel); - ret = btnCancel->GetEventHandler()->ProcessEvent(eventClick); + ret = btnCancel->HandleWindowEvent(eventClick); } } @@ -1406,65 +1273,6 @@ 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) -{ - wxKeyEvent event( wxEVT_KEY_DOWN ); - - // take modifiers, cursor position, timestamp etc. from the last - // key_press_event that was fed into Input Method: - if (window->m_imData->lastKeyEvent) - { - wxFillOtherKeyEventFields(event, - window, window->m_imData->lastKeyEvent); - } - -#if wxUSE_UNICODE - const wxWCharBuffer data = wxConvUTF8.cMB2WC( (char*)str ); -#else - const wxWCharBuffer wdata = wxConvUTF8.cMB2WC( (char*)str ); - const wxCharBuffer data = wxConvLocal.cWC2MB( wdata ); -#endif // wxUSE_UNICODE - if( !(const wxChar*)data ) - return; - - bool ret = false; - - // Implement OnCharHook by checking ancestor top level windows - wxWindow *parent = window; - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - - for( const wxChar* pstr = data; *pstr; pstr++ ) - { -#if wxUSE_UNICODE - event.m_uniChar = *pstr; - // Backward compatible for ISO-8859-1 - event.m_keyCode = *pstr < 256 ? event.m_uniChar : 0; - wxLogTrace(TRACE_KEYS, _T("IM sent character '%c'"), event.m_uniChar); -#else - event.m_keyCode = *pstr; -#endif // wxUSE_UNICODE - if (parent) - { - event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->GetEventHandler()->ProcessEvent( event ); - } - - if (!ret) - { - event.SetEventType(wxEVT_CHAR); - ret = window->GetEventHandler()->ProcessEvent( event ); - } - } -} -} -#endif - - //----------------------------------------------------------------------------- // "key_release_event" from any window //----------------------------------------------------------------------------- @@ -1492,7 +1300,7 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, return FALSE; } - if ( !win->GetEventHandler()->ProcessEvent( event ) ) + if ( !win->HandleWindowEvent( event ) ) return FALSE; gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" ); @@ -1543,7 +1351,7 @@ template void InitMouseEvent(wxWindowGTK *win, 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 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 @@ -1621,7 +1429,7 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) } else { - if ((child->m_wxwindow == (GtkWidget*) NULL) && + if ((child->m_wxwindow == NULL) && (child->m_x <= xx) && (child->m_y <= yy) && (child->m_x+child->m_width >= xx) && @@ -1664,7 +1472,9 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; - if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus()) + g_lastButtonNumber = gdk_event->button; + + if (win->m_wxwindow && (g_focusWindow != win) && win->IsFocusable()) { gtk_widget_grab_focus( win->m_wxwindow ); /* @@ -1698,21 +1508,6 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, wxEventType event_type = wxEVT_NULL; - // GdkDisplay is a GTK+ 2.2.0 thing -#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 2, 0) - if ( gdk_event->type == GDK_2BUTTON_PRESS && - !gtk_check_version(2,2,0) && - gdk_event->button >= 1 && gdk_event->button <= 3 ) - { - // Reset GDK internal timestamp variables in order to disable GDK - // triple click events. GDK will then next time believe no button has - // been clicked just before, and send a normal button click event. - GdkDisplay* display = gtk_widget_get_display (widget); - display->button_click_time[1] = 0; - display->button_click_time[0] = 0; - } -#endif // GTK 2+ - if (gdk_event->button == 1) { // note that GDK generates triple click events which are not supported @@ -1786,6 +1581,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, return FALSE; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + wxMouseEvent event( event_type ); InitMouseEvent( win, event, gdk_event ); @@ -1801,7 +1598,6 @@ 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) @@ -1815,13 +1611,14 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, return FALSE; } } -#endif // !__WXGTK20__ - if (win->GetEventHandler()->ProcessEvent( event )) + if (win->HandleWindowEvent( event )) { gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" ); + g_lastMouseEvent = NULL; return TRUE; } + g_lastMouseEvent = NULL; if (event_type == wxEVT_RIGHT_DOWN) { @@ -1837,7 +1634,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, win->GetId(), win->ClientToScreen(event.GetPosition())); evtCtx.SetEventObject(win); - return win->GetEventHandler()->ProcessEvent(evtCtx); + return win->HandleWindowEvent(evtCtx); } return FALSE; @@ -1864,6 +1661,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE; + g_lastButtonNumber = 0; + wxEventType event_type = wxEVT_NULL; switch (gdk_event->button) @@ -1885,6 +1684,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, return FALSE; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + wxMouseEvent event( event_type ); InitMouseEvent( win, event, gdk_event ); @@ -1896,7 +1697,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, if ( !g_captureWindow ) win = FindWindowForMouseEvent(win, event.m_x, event.m_y); - if (win->GetEventHandler()->ProcessEvent( event )) + if (win->HandleWindowEvent( event )) { gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" ); return TRUE; @@ -1936,6 +1737,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, gdk_event->y = y; } + g_lastMouseEvent = (GdkEvent*) gdk_event; + /* printf( "OnMotion from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -1964,7 +1767,7 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, : wxEVT_LEAVE_WINDOW); InitMouseEvent(win, eventM, gdk_event); eventM.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(eventM); + win->HandleWindowEvent(eventM); } } else // no capture @@ -1972,90 +1775,18 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, win = FindWindowForMouseEvent(win, event.m_x, event.m_y); } - if (win->GetEventHandler()->ProcessEvent( event )) - { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" ); - return TRUE; - } - - return FALSE; -} -} - -#ifdef __WXGTK20__ -//----------------------------------------------------------------------------- -// "mouse_wheel_event" -//----------------------------------------------------------------------------- - -extern "C" { -static gint gtk_window_wheel_callback (GtkWidget * widget, - GdkEventScroll * gdk_event, - wxWindowGTK * win) -{ - DEBUG_MAIN_THREAD + bool ret = win->HandleWindowEvent( event ); + g_lastMouseEvent = NULL; - if (g_isIdle) - wxapp_install_idle_handler(); - - wxEventType event_type = wxEVT_NULL; - if (gdk_event->direction == GDK_SCROLL_UP) - event_type = wxEVT_MOUSEWHEEL; - else if (gdk_event->direction == GDK_SCROLL_DOWN) - event_type = wxEVT_MOUSEWHEEL; - else - return FALSE; - - wxMouseEvent event( event_type ); - // Can't use InitMouse macro because scroll events don't have button - event.SetTimestamp( gdk_event->time ); - event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK); - event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK); - event.m_altDown = (gdk_event->state & GDK_MOD1_MASK); - event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); - 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_linesPerAction = 3; - event.m_wheelDelta = 120; - if (gdk_event->direction == GDK_SCROLL_UP) - event.m_wheelRotation = 120; - else - event.m_wheelRotation = -120; - - wxPoint pt = win->GetClientAreaOrigin(); - event.m_x = (wxCoord)gdk_event->x - pt.x; - event.m_y = (wxCoord)gdk_event->y - pt.y; - - event.SetEventObject( win ); - event.SetId( win->GetId() ); - event.SetTimestamp( gdk_event->time ); - - if (win->GetEventHandler()->ProcessEvent( event )) + if ( ret ) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "scroll_event" ); - return TRUE; + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" ); } - return FALSE; + return ret ? TRUE : FALSE; } } -//----------------------------------------------------------------------------- -// "popup-menu" -//----------------------------------------------------------------------------- -extern "C" { -static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win) -{ - wxContextMenuEvent event( - wxEVT_CONTEXT_MENU, - win->GetId(), - wxPoint(-1, -1)); - event.SetEventObject(win); - return win->GetEventHandler()->ProcessEvent(event); -} -} -#endif // __WXGTK20__ - //----------------------------------------------------------------------------- // "focus_in_event" //----------------------------------------------------------------------------- @@ -2067,12 +1798,12 @@ static bool DoSendFocusEvents(wxWindow *win) // Notify the parent keeping track of focus for the kbd navigation // purposes that we got it. wxChildFocusEvent eventChildFocus(win); - (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); + (void)win->HandleWindowEvent(eventChildFocus); wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); eventFocus.SetEventObject(win); - return win->GetEventHandler()->ProcessEvent(eventFocus); + return win->HandleWindowEvent(eventFocus); } extern "C" { @@ -2085,16 +1816,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, 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; wxLogTrace(TRACE_FOCUS, - _T("%s: focus in"), win->GetName().c_str()); + wxT("%s: focus in"), win->GetName().c_str()); #ifdef HAVE_XIM if (win->m_ic) @@ -2132,27 +1858,24 @@ 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 gint gtk_window_focus_out_callback( GtkWidget *WXUNUSED(widget), + GdkEventFocus *WXUNUSED(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() ); + wxT("%s: focus out"), win->GetName().c_str() ); wxWindowGTK *winFocus = wxFindFocusedChild(win); if ( winFocus ) win = winFocus; - g_focusWindow = (wxWindowGTK *)NULL; + g_focusWindow = NULL; #ifdef HAVE_XIM if (win->m_ic) @@ -2181,7 +1904,7 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk // 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 ); + (void)win->HandleWindowEvent( event ); } return FALSE; @@ -2223,7 +1946,7 @@ gint gtk_window_enter_callback( GtkWidget *widget, event.m_x = x + pt.x; event.m_y = y + pt.y; - if (win->GetEventHandler()->ProcessEvent( event )) + if (win->HandleWindowEvent( event )) { gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" ); return TRUE; @@ -2275,7 +1998,7 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ event.m_x = x + pt.x; event.m_y = y + pt.y; - if (win->GetEventHandler()->ProcessEvent( event )) + if (win->HandleWindowEvent( event )) { gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" ); return TRUE; @@ -2308,16 +2031,14 @@ 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)); int value = (int)(adjust->value+0.5); wxScrollWinEvent event( command, value, wxVERTICAL ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } } @@ -2341,9 +2062,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)); win->m_oldHorizontalPos = adjust->value; @@ -2352,7 +2071,7 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxScrollWinEvent event( command, value, wxHORIZONTAL ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } } @@ -2374,9 +2093,7 @@ 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__ win->m_isScrolling = (gdk_event->window == widget->slider); -#endif return FALSE; } @@ -2420,7 +2137,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, wxScrollWinEvent event( command, value, dir ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } win->m_isScrolling = false; @@ -2449,25 +2166,16 @@ wxWindow *wxWindowBase::DoFindFocus() extern "C" { static gint -gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) +gtk_window_realized_callback( GtkWidget *WXUNUSED(widget), wxWindow *win ) { DEBUG_MAIN_THREAD 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 ); + win->HandleWindowEvent( event ); return FALSE; } @@ -2501,7 +2209,7 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), { wxSizeEvent event( win->GetSize(), win->GetId() ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } } } @@ -2518,7 +2226,7 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), extern "C" { static void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), - GtkAllocation* WXUNUSED_UNLESS_XIM(alloc), + GtkAllocation* WXUNUSED(alloc), wxWindowGTK* WXUNUSED_UNLESS_XIM(win) ) { if (g_isIdle) @@ -2672,6 +2380,31 @@ wxWindow *wxGetActiveWindow() return wxWindow::FindFocus(); } + +wxMouseState wxGetMouseState() +{ + wxMouseState ms; + + gint x; + gint y; + GdkModifierType mask; + + gdk_window_get_pointer(NULL, &x, &y, &mask); + + ms.SetX(x); + ms.SetY(y); + ms.SetLeftDown(mask & GDK_BUTTON1_MASK); + ms.SetMiddleDown(mask & GDK_BUTTON2_MASK); + ms.SetRightDown(mask & GDK_BUTTON3_MASK); + + ms.SetControlDown(mask & GDK_CONTROL_MASK); + ms.SetShiftDown(mask & GDK_SHIFT_MASK); + ms.SetAltDown(mask & GDK_MOD1_MASK); + ms.SetMetaDown(mask & GDK_MOD2_MASK); + + return ms; +} + //----------------------------------------------------------------------------- // wxWindowGTK //----------------------------------------------------------------------------- @@ -2687,9 +2420,9 @@ wxWindow *wxGetActiveWindow() void wxWindowGTK::Init() { // GTK specific - m_widget = (GtkWidget *) NULL; - m_wxwindow = (GtkWidget *) NULL; - m_focusWidget = (GtkWidget *) NULL; + m_widget = NULL; + m_wxwindow = NULL; + m_focusWidget = NULL; // position/size m_x = 0; @@ -2700,7 +2433,6 @@ void wxWindowGTK::Init() m_sizeSet = false; m_hasVMT = false; m_needParent = true; - m_isBeingDeleted = false; m_noExpose = false; m_nativeSizeEvent = false; @@ -2708,8 +2440,8 @@ void wxWindowGTK::Init() m_hasScrolling = false; m_isScrolling = false; - m_hAdjust = (GtkAdjustment*) NULL; - m_vAdjust = (GtkAdjustment*) NULL; + m_hAdjust = NULL; + m_vAdjust = NULL; m_oldHorizontalPos = m_oldVerticalPos = 0.0; m_oldClientWidth = @@ -2728,14 +2460,9 @@ 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 + m_ic = NULL; + m_icattr = NULL; #endif } @@ -2763,6 +2490,11 @@ bool wxWindowGTK::Create( wxWindow *parent, long style, const wxString &name ) { + // Get default border + wxBorder border = GetBorder(style); + style &= ~wxBORDER_MASK; + style |= border; + if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { @@ -2772,7 +2504,7 @@ bool wxWindowGTK::Create( wxWindow *parent, m_insertCallback = wxInsertChildInWindow; - m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); + m_widget = gtk_scrolled_window_new( NULL, NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); @@ -2794,7 +2526,7 @@ bool wxWindowGTK::Create( wxWindow *parent, { gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT ); } - else if (HasFlag(wxSUNKEN_BORDER)) + else if (HasFlag(wxSUNKEN_BORDER) || HasFlag(wxBORDER_THEME)) { gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN ); } @@ -2876,7 +2608,6 @@ wxWindowGTK::~wxWindowGTK() if ( g_delayedFocus == this ) g_delayedFocus = NULL; - m_isBeingDeleted = true; m_hasVMT = false; // destroy children before destroying this window itself @@ -2902,21 +2633,16 @@ 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) { gtk_widget_destroy( m_wxwindow ); - m_wxwindow = (GtkWidget*) NULL; + m_wxwindow = NULL; } if (m_widget) { gtk_widget_destroy( m_widget ); - m_widget = (GtkWidget*) NULL; + m_widget = NULL; } } @@ -2950,7 +2676,6 @@ void wxWindowGTK::PostCreation() 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 ); @@ -2959,30 +2684,14 @@ void wxWindowGTK::PostCreation() 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 } -#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_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 } // focus handling @@ -3071,13 +2780,6 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget ) 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 ); @@ -3175,23 +2877,10 @@ 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) - { - left_border += default_border->left; - right_border += default_border->right; - top_border += default_border->top; - 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, @@ -3222,7 +2911,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags { wxSizeEvent event( wxSize(m_width,m_height), GetId() ); event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( event ); + HandleWindowEvent( event ); } m_resizing = false; @@ -3230,10 +2919,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags void wxWindowGTK::OnInternalIdle() { -#ifdef __WXGTK20__ - if ( m_dirtyTabOrder ) - RealizeTabOrder(); -#endif // Update style if the window was not yet realized // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called if (m_needsStyleChange) @@ -3269,17 +2954,15 @@ void wxWindowGTK::OnInternalIdle() gdk_window_set_cursor( window, cursor.GetCursor() ); } - else + else if ( m_widget ) { - GdkWindow *window = m_widget->window; - if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget))) + if ( window && !GTK_WIDGET_NO_WINDOW(m_widget) ) gdk_window_set_cursor( window, cursor.GetCursor() ); - } } - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -3305,7 +2988,7 @@ void wxWindowGTK::DoSetClientSize( int width, int height ) int dh = 0; #ifndef __WXUNIVERSAL__ - if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) + if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxBORDER_THEME)) { /* when using GTK 1.2 we set the shadow border size to 2 */ dw += 2 * 2; @@ -3369,7 +3052,7 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const int dh = 0; #ifndef __WXUNIVERSAL__ - if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) + if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxBORDER_THEME)) { /* when using GTK 1.2 we set the shadow border size to 2 */ dw += 2 * 2; @@ -3449,7 +3132,7 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const if (!m_widget->window) return; - GdkWindow *source = (GdkWindow *) NULL; + GdkWindow *source = NULL; if (m_wxwindow) source = GTK_PIZZA(m_wxwindow)->bin_window; else @@ -3478,7 +3161,7 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const if (!m_widget->window) return; - GdkWindow *source = (GdkWindow *) NULL; + GdkWindow *source = NULL; if (m_wxwindow) source = GTK_PIZZA(m_wxwindow)->bin_window; else @@ -3519,45 +3202,18 @@ bool wxWindowGTK::Show( bool show ) wxShowEvent eventShow(GetId(), show); eventShow.SetEventObject(this); - GetEventHandler()->ProcessEvent(eventShow); + HandleWindowEvent(eventShow); return true; } -static void wxWindowNotifyEnable(wxWindowGTK* win, bool enable) -{ - win->OnParentEnable(enable); - - // Recurse, so that children have the opportunity to Do The Right Thing - // and reset colours that have been messed up by a parent's (really ancestor's) - // Enable call - for ( wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if (!child->IsKindOf(CLASSINFO(wxDialog)) && !child->IsKindOf(CLASSINFO(wxFrame))) - wxWindowNotifyEnable(child, enable); - } -} - -bool wxWindowGTK::Enable( bool enable ) +void wxWindowGTK::DoEnable( bool enable ) { - wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); - - if (!wxWindowBase::Enable(enable)) - { - // nothing to do - return false; - } + wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); gtk_widget_set_sensitive( m_widget, enable ); if ( m_wxwindow ) gtk_widget_set_sensitive( m_wxwindow, enable ); - - wxWindowNotifyEnable(this, enable); - - return true; } int wxWindowGTK::GetCharHeight() const @@ -3567,31 +3223,9 @@ 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 ); - - if (!context) - return 0; - - PangoFontDescription *desc = font.GetNativeFontInfo()->description; - PangoLayout *layout = pango_layout_new(context); - pango_layout_set_font_description(layout, desc); - pango_layout_set_text(layout, "H", 1); - PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data; - - PangoRectangle rect; - pango_layout_line_get_extents(line, NULL, &rect); - - 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 @@ -3601,39 +3235,17 @@ 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 ); - - if (!context) - return 0; - - PangoFontDescription *desc = font.GetNativeFontInfo()->description; - PangoLayout *layout = pango_layout_new(context); - pango_layout_set_font_description(layout, desc); - pango_layout_set_text(layout, "g", 1); - PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data; - - PangoRectangle rect; - pango_layout_line_get_extents(line, NULL, &rect); - - 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, - int *x, - int *y, - int *descent, - int *externalLeading, - const wxFont *theFont ) const +void wxWindowGTK::DoGetTextExtent(const wxString& string, + int *x, + int *y, + int *descent, + int *externalLeading, + const wxFont *theFont) const { wxFont fontToUse = theFont ? *theFont : GetFont(); @@ -3646,54 +3258,11 @@ void wxWindowGTK::GetTextExtent( const wxString& string, return; } -#ifdef __WXGTK20__ - PangoContext *context = NULL; - if (m_widget) - context = gtk_widget_get_pango_context( m_widget ); - - if (!context) - { - if (x) (*x) = 0; - if (y) (*y) = 0; - return; - } - - PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description; - PangoLayout *layout = pango_layout_new(context); - pango_layout_set_font_description(layout, desc); - { -#if wxUSE_UNICODE - const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); -#else - const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string ); - const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); -#endif - } - - PangoRectangle rect; - pango_layout_get_extents(layout, NULL, &rect); - - if (x) (*x) = (wxCoord) PANGO_PIXELS(rect.width); - if (y) (*y) = (wxCoord) PANGO_PIXELS(rect.height); - if (descent) - { - PangoLayoutIter *iter = pango_layout_get_iter(layout); - int baseline = pango_layout_iter_get_baseline(iter); - pango_layout_iter_free(iter); - *descent = *y - PANGO_PIXELS(baseline); - } - 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() @@ -3714,13 +3283,6 @@ 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) ) { @@ -3730,7 +3292,7 @@ void wxWindowGTK::SetFocus() // it should be focused and will do it later, during the idle // time, as soon as we can wxLogTrace(TRACE_FOCUS, - _T("Delaying setting focus to %s(%s)"), + wxT("Delaying setting focus to %s(%s)"), GetClassInfo()->GetClassName(), GetLabel().c_str()); g_delayedFocus = this; @@ -3738,23 +3300,21 @@ void wxWindowGTK::SetFocus() else { wxLogTrace(TRACE_FOCUS, - _T("Setting focus to %s(%s)"), + wxT("Setting focus to %s(%s)"), GetClassInfo()->GetClassName(), GetLabel().c_str()); gtk_widget_grab_focus (m_widget); } } 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)"), + wxT("Can't set focus to %s(%s)"), GetClassInfo()->GetClassName(), GetLabel().c_str()); } } @@ -3816,62 +3376,6 @@ void wxWindowGTK::DoAddChild(wxWindowGTK *child) (*m_insertCallback)(this, child); } -#ifdef __WXGTK20__ - -void wxWindowGTK::AddChild(wxWindowBase *child) -{ - wxWindowBase::AddChild(child); - m_dirtyTabOrder = true; - if (g_isIdle) - wxapp_install_idle_handler(); -} - -void wxWindowGTK::RemoveChild(wxWindowBase *child) -{ - wxWindowBase::RemoveChild(child); - m_dirtyTabOrder = true; - if (g_isIdle) - wxapp_install_idle_handler(); -} - -void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move) -{ - wxWindowBase::DoMoveInTabOrder(win, move); - m_dirtyTabOrder = true; - if (g_isIdle) - wxapp_install_idle_handler(); -} - -void wxWindowGTK::RealizeTabOrder() -{ - if (m_wxwindow) - { - if (m_children.size() > 0) - { - GList *chain = NULL; - - for (wxWindowList::const_iterator i = m_children.begin(); - i != m_children.end(); ++i) - { - chain = g_list_prepend(chain, (*i)->m_widget); - } - - chain = g_list_reverse(chain); - - gtk_container_set_focus_chain(GTK_CONTAINER(m_wxwindow), chain); - g_list_free(chain); - } - else - { - 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") ); @@ -3904,16 +3408,14 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor ) { wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); - if (cursor == m_cursor) + if ( cursor.IsSameAs(m_cursor) ) return false; if (g_isIdle) wxapp_install_idle_handler(); - if (cursor == wxNullCursor) - return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); - else - return wxWindowBase::SetCursor( cursor ); + return wxWindowBase::SetCursor( cursor.IsOk() ? cursor + : *wxSTANDARD_CURSOR ); } void wxWindowGTK::WarpPointer( int x, int y ) @@ -3923,7 +3425,7 @@ void wxWindowGTK::WarpPointer( int x, int y ) // We provide this function ourselves as it is // missing in GDK (top of this file). - GdkWindow *window = (GdkWindow*) NULL; + GdkWindow *window = NULL; if (m_wxwindow) window = GTK_PIZZA(m_wxwindow)->bin_window; else @@ -3941,7 +3443,6 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (!m_widget->window) return; -#ifndef __WXGTK20__ if (g_isIdle) wxapp_install_idle_handler(); @@ -3998,30 +3499,9 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) } else { - gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); - } - } -#else // GTK+ 2 - if (m_wxwindow) - { - GdkRectangle gdk_rect, - *p; - if (rect) - { - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; - p = &gdk_rect; - } - else // invalidate everything - { - p = NULL; + gtk_widget_draw( m_widget, NULL ); } - - gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE ); } -#endif // GTK+ 1/2 } void wxWindowGTK::Update() @@ -4037,13 +3517,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 @@ -4060,9 +3535,7 @@ void wxWindowGTK::GtkSendPaintEvents() { if (!m_wxwindow) { -#ifndef __WXGTK20__ m_clearRegion.Clear(); -#endif m_updateRegion.Clear(); return; } @@ -4104,31 +3577,16 @@ void wxWindowGTK::GtkSendPaintEvents() } } } - else - -#ifdef __WXGTK20__ + else // Always send an erase event under GTK 1.2 { wxWindowDC dc( (wxWindow*)this ); - dc.SetClippingRegion( m_updateRegion ); + dc.SetDeviceClippingRegion( m_clearRegion.IsEmpty() ? m_updateRegion + : m_clearRegion ); wxEraseEvent erase_event( GetId(), &dc ); erase_event.SetEventObject( this ); - 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 (!HandleWindowEvent(erase_event) && GetBackgroundStyle() != wxBG_STYLE_CUSTOM) { if (!g_eraseGC) { @@ -4147,19 +3605,18 @@ void wxWindowGTK::GtkSendPaintEvents() } m_clearRegion.Clear(); } -#endif wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( nc_paint_event ); + HandleWindowEvent( nc_paint_event ); wxPaintEvent paint_event( GetId() ); paint_event.SetEventObject( this ); - GetEventHandler()->ProcessEvent( paint_event ); + HandleWindowEvent( paint_event ); m_clipPaintRegion = false; -#if !defined(__WXUNIVERSAL__) && !defined(__WXGTK20__) +#if !defined(__WXUNIVERSAL__) // 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. @@ -4209,7 +3666,6 @@ void wxWindowGTK::ClearBackground() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); -#ifndef __WXGTK20__ if (m_wxwindow && m_wxwindow->window) { m_clearRegion.Clear(); @@ -4219,7 +3675,6 @@ void wxWindowGTK::ClearBackground() // Better do this in idle? GtkUpdate(); } -#endif } #if wxUSE_TOOLTIPS @@ -4234,7 +3689,7 @@ void wxWindowGTK::DoSetToolTip( wxToolTip *tip ) void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) { wxString tmp( tip ); - gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL ); + gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), NULL ); } #endif // wxUSE_TOOLTIPS @@ -4281,13 +3736,6 @@ 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) { // do we need to apply any changes at all? @@ -4302,13 +3750,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() ) @@ -4380,7 +3823,7 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style) if (style == wxBG_STYLE_CUSTOM) { - GdkWindow *window = (GdkWindow*) NULL; + GdkWindow *window = NULL; if (m_wxwindow) window = GTK_PIZZA(m_wxwindow)->bin_window; else @@ -4464,15 +3907,15 @@ void wxWindowGTK::DoCaptureMouse() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); - GdkWindow *window = (GdkWindow*) NULL; + GdkWindow *window = NULL; if (m_wxwindow) window = GTK_PIZZA(m_wxwindow)->bin_window; else window = GetConnectWidget()->window; - wxCHECK_RET( window, _T("CaptureMouse() failed") ); + wxCHECK_RET( window, wxT("CaptureMouse() failed") ); - wxCursor* cursor = & m_cursor; + const wxCursor* cursor = &m_cursor; if (!cursor->Ok()) cursor = wxSTANDARD_CURSOR; @@ -4482,7 +3925,7 @@ void wxWindowGTK::DoCaptureMouse() GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK), - (GdkWindow *) NULL, + NULL, cursor->GetCursor(), (guint32)GDK_CURRENT_TIME ); g_captureWindow = this; @@ -4495,9 +3938,9 @@ void wxWindowGTK::DoReleaseMouse() wxCHECK_RET( g_captureWindow, wxT("can't release mouse - not captured") ); - g_captureWindow = (wxWindowGTK*) NULL; + g_captureWindow = NULL; - GdkWindow *window = (GdkWindow*) NULL; + GdkWindow *window = NULL; if (m_wxwindow) window = GTK_PIZZA(m_wxwindow)->bin_window; else @@ -4664,7 +4107,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 ); @@ -4684,7 +4126,6 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) GetClientSize( &cw, &ch ); m_clearRegion.Intersect( 0, 0, cw, ch ); } -#endif m_clipPaintRegion = true; @@ -4738,8 +4179,19 @@ wxPoint wxGetMousePosition() } +// Needed for implementing e.g. combobox on wxGTK within a modal dialog. +void wxAddGrab(wxWindow* window) +{ + gtk_grab_add( (GtkWidget*) window->GetHandle() ); +} + +void wxRemoveGrab(wxWindow* window) +{ + gtk_grab_remove( (GtkWidget*) window->GetHandle() ); +} + // ---------------------------------------------------------------------------- -// wxDCModule +// wxWinModule // ---------------------------------------------------------------------------- class wxWinModule : public wxModule @@ -4768,4 +4220,10 @@ void wxWinModule::OnExit() gdk_gc_unref( g_eraseGC ); } -// vi:sts=4:sw=4:et +GdkWindow* wxWindowGTK::GTKGetDrawingWindow() const +{ + GdkWindow* window = NULL; + if (m_wxwindow) + window = GTK_PIZZA(m_wxwindow)->bin_window; + return window; +}