X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8700aedc160ae543900b7dacfccc984648c2e9c1..6d325d81bc739bf545df5c00183fc7d5880b8a43:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index a1b9f5657b..cd98009b09 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -145,7 +145,7 @@ extern GtkContainerClass *pizza_parent_class; thw wxWindow class has a member variable called m_widget which holds a pointer to this widget. When the window class represents a GTK native widget, this is (in most cases) the only GTK widget the class manages. E.g. the - wxStatitText class handles only a GtkLabel widget a pointer to which you + wxStaticText class handles only a GtkLabel widget a pointer to which you can find in m_widget (defined in wxWindow) When the class has a client area for drawing into and for containing children @@ -1097,6 +1097,17 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (g_blockEventsOnDrag) return FALSE; +#ifdef __WXGTK20__ + if (win->m_imContext) + { + // In GTK 2.0, we need to hand over the key event to an input method + // and the IM will emit a "commit" event containing the actual utf8 + // character. In that case the EVT_CHAR events will be sent from + // there. + if ( gtk_im_context_filter_keypress(win->m_imContext, gdk_event) ) + return TRUE; + } +#endif wxKeyEvent event( wxEVT_KEY_DOWN ); if ( !wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) @@ -1134,56 +1145,41 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, { long key_code; KeySym keysym = gdk_event->keyval; -#ifdef __WXGTK20__ - // In GTK 2.0, we need to hand over the key event to an input method - // and the IM will emit a "commit" event containing the actual utf8 - // character. In that case the EVT_CHAR events will be sent from - // there. But only do it this way for non-KeySym keys. - key_code = wxTranslateKeySymToWXKey(gdk_event->keyval, FALSE /* isChar */); - if ( !key_code && win->m_imContext ) - { - gtk_im_context_filter_keypress ( (GtkIMContext*) win->m_imContext, gdk_event ); - ret = TRUE; - } - else -#endif + // Find key code for EVT_CHAR and EVT_CHAR_HOOK events + key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */); + if ( !key_code ) { - // Find key code for EVT_CHAR and EVT_CHAR_HOOK events - key_code = wxTranslateKeySymToWXKey(keysym, TRUE /* isChar */); - if ( !key_code ) + if ( gdk_event->length == 1 ) { - if ( gdk_event->length == 1 ) - { - key_code = (unsigned char)gdk_event->string[0]; - } - else if ( wxIsAsciiKeysym(keysym) ) - { - // ASCII key - key_code = (unsigned char)keysym; - } + key_code = (unsigned char)gdk_event->string[0]; } - - if ( key_code ) + else if ( wxIsAsciiKeysym(keysym) ) { - wxLogTrace(TRACE_KEYS, _T("Char event: %ld"), key_code); + // ASCII key + key_code = (unsigned char)keysym; + } + } - event.m_keyCode = key_code; + if ( key_code ) + { + wxLogTrace(TRACE_KEYS, _T("Char event: %ld"), key_code); - // Implement OnCharHook by checking ancesteror top level windows - wxWindow *parent = win; - while (parent && !parent->IsTopLevel()) - parent = parent->GetParent(); - if (parent) - { - event.SetEventType( wxEVT_CHAR_HOOK ); - ret = parent->GetEventHandler()->ProcessEvent( event ); - } + event.m_keyCode = key_code; - if (!ret) - { - event.SetEventType(wxEVT_CHAR); - ret = win->GetEventHandler()->ProcessEvent( event ); - } + // Implement OnCharHook by checking ancesteror top level windows + wxWindow *parent = win; + while (parent && !parent->IsTopLevel()) + parent = parent->GetParent(); + if (parent) + { + event.SetEventType( wxEVT_CHAR_HOOK ); + ret = parent->GetEventHandler()->ProcessEvent( event ); + } + + if (!ret) + { + event.SetEventType(wxEVT_CHAR); + ret = win->GetEventHandler()->ProcessEvent( event ); } } } @@ -1274,11 +1270,15 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, if (event.m_uniChar < 256) event.m_keyCode = event.m_uniChar; #else - gunichar uniChar = g_utf8_get_char( str ); - // We cannot handle Unicode in non-Unicode mode - if (uniChar > 255) return; - - event.m_keyCode = uniChar; + wchar_t unistr[2]; + unistr[0] = g_utf8_get_char(str); + unistr[1] = 0; + wxCharBuffer ansistr(wxConvLocal.cWC2MB(unistr)); + // We cannot handle characters that cannot be represented in + // current locale's charset in non-Unicode mode: + if (ansistr.data() == NULL) return; + + event.m_keyCode = ansistr[0u]; #endif @@ -1534,8 +1534,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, wxEventType event_type = wxEVT_NULL; - // GdkDisplay is a GTK+ 2.1.0 thing -#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 1, 0) + // GdkDisplay is a GTK+ 2.2.0 thing +#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 2, 0) if ( gdk_event->type == GDK_2BUTTON_PRESS && gdk_event->button >= 1 && gdk_event->button <= 3 ) { @@ -1900,6 +1900,11 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, if (g_isIdle) wxapp_install_idle_handler(); +#ifdef __WXGTK20__ + if (win->m_imContext) + gtk_im_context_focus_in(win->m_imContext); +#endif + if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; @@ -1988,6 +1993,11 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk if (g_isIdle) wxapp_install_idle_handler(); +#ifdef __WXGTK20__ + if (win->m_imContext) + gtk_im_context_focus_out(win->m_imContext); +#endif + if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; @@ -2307,17 +2317,11 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) if (g_isIdle) wxapp_install_idle_handler(); - if (win->m_delayedBackgroundColour && !win->GetThemeEnabled()) - win->GtkSetBackgroundColour( win->GetBackgroundColour() ); - - if (win->m_delayedForegroundColour && !win->GetThemeEnabled()) - win->GtkSetForegroundColour( win->GetForegroundColour() ); - #ifdef __WXGTK20__ if (win->m_imContext) { GtkPizza *pizza = GTK_PIZZA( m_widget ); - gtk_im_context_set_client_window( (GtkIMContext*) win->m_imContext, pizza->bin_window ); + gtk_im_context_set_client_window( win->m_imContext, pizza->bin_window ); } #endif @@ -2575,9 +2579,6 @@ void wxWindowGTK::Init() m_cursor = *wxSTANDARD_CURSOR; - m_delayedForegroundColour = FALSE; - m_delayedBackgroundColour = FALSE; - #ifdef __WXGTK20__ m_imContext = NULL; m_x11Context = NULL; @@ -2622,9 +2623,6 @@ bool wxWindowGTK::Create( wxWindow *parent, m_insertCallback = wxInsertChildInWindow; - // always needed for background clearing - m_delayedBackgroundColour = TRUE; - m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); @@ -2707,17 +2705,6 @@ bool wxWindowGTK::Create( wxWindow *parent, gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); -#ifdef __WXGTK20__ - // Create input method handler - m_imContext = (GtkIMMulticontext*) gtk_im_multicontext_new (); - - // Cannot handle drawing preedited text yet - gtk_im_context_set_use_preedit( (GtkIMContext*) m_imContext, FALSE ); - - g_signal_connect (G_OBJECT (m_imContext), "commit", - G_CALLBACK (gtk_wxwindow_commit_cb), this); -#endif - gtk_widget_show( m_wxwindow ); if (m_parent) @@ -2813,18 +2800,18 @@ void wxWindowGTK::PostCreation() #else // gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), !HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); #endif + } #ifdef __WXGTK20__ // Create input method handler - m_imContext = (GtkIMMulticontext*) gtk_im_multicontext_new (); + m_imContext = gtk_im_multicontext_new(); // Cannot handle drawing preedited text yet - gtk_im_context_set_use_preedit( (GtkIMContext*) m_imContext, FALSE ); + gtk_im_context_set_use_preedit( m_imContext, FALSE ); g_signal_connect (G_OBJECT (m_imContext), "commit", - G_CALLBACK (gtk_wxwindow_commit_cb), this); + 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", @@ -3975,68 +3962,24 @@ void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) } #endif // wxUSE_TOOLTIPS -void wxWindowGTK::GtkSetBackgroundColour( const wxColour &colour ) -{ - GdkWindow *window = (GdkWindow*) NULL; - if (m_wxwindow) - window = GTK_PIZZA(m_wxwindow)->bin_window; - else - window = GetConnectWidget()->window; - - wxASSERT( window ); - - // We need the pixel value e.g. for background clearing. - m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); - - if (m_wxwindow) - { - // wxMSW doesn't clear the window here, either. - gdk_window_set_background( window, m_backgroundColour.GetColor() ); - } - - ApplyWidgetStyle(); -} - bool wxWindowGTK::SetBackgroundColour( const wxColour &colour ) { wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") ); if (!wxWindowBase::SetBackgroundColour(colour)) - return FALSE; - - GdkWindow *window = (GdkWindow*) NULL; - if (m_wxwindow) - window = GTK_PIZZA(m_wxwindow)->bin_window; - else - window = GetConnectWidget()->window; + return false; - if (!window) - { - // indicate that a new style has been set - // but it couldn't get applied as the - // widget hasn't been realized yet. - m_delayedBackgroundColour = TRUE; - return TRUE; - } - else + if (colour.Ok()) { - GtkSetBackgroundColour( colour ); + // We need the pixel value e.g. for background clearing. + m_backgroundColour.CalcPixel(gtk_widget_get_colormap(m_widget)); } - return TRUE; -} - -void wxWindowGTK::GtkSetForegroundColour( const wxColour &colour ) -{ - GdkWindow *window = (GdkWindow*) NULL; - if (m_wxwindow) - window = GTK_PIZZA(m_wxwindow)->bin_window; - else - window = GetConnectWidget()->window; - - wxASSERT( window ); + // apply style change (forceStyle=true so that new style is applied + // even if the bg colour changed from valid to wxNullColour): + ApplyWidgetStyle(true); - ApplyWidgetStyle(); + return true; } bool wxWindowGTK::SetForegroundColour( const wxColour &colour ) @@ -4045,30 +3988,20 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour ) if (!wxWindowBase::SetForegroundColour(colour)) { - // don't leave if the GTK widget has just - // been realized - if (!m_delayedForegroundColour) return FALSE; - } - - GdkWindow *window = (GdkWindow*) NULL; - if (m_wxwindow) - window = GTK_PIZZA(m_wxwindow)->bin_window; - else - window = GetConnectWidget()->window; - - if (!window) - { - // indicate that a new style has been set - // but it couldn't get applied as the - // widget hasn't been realized yet. - m_delayedForegroundColour = TRUE; + return false; } - else + + if (colour.Ok()) { - GtkSetForegroundColour( colour ); + // We need the pixel value e.g. for background clearing. + m_foregroundColour.CalcPixel(gtk_widget_get_colormap(m_widget)); } - return TRUE; + // apply style change (forceStyle=true so that new style is applied + // even if the bg colour changed from valid to wxNullColour): + ApplyWidgetStyle(true); + + return true; } #ifdef __WXGTK20__ @@ -4086,18 +4019,19 @@ PangoContext *wxWindowGTK::GtkGetPangoX11Context() } #endif -GtkRcStyle *wxWindowGTK::CreateWidgetStyle() +GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle) { // do we need to apply any changes at all? - if ( !m_hasFont && !m_hasFgCol && - (!m_hasBgCol || !m_backgroundColour.Ok()) ) + if ( !forceStyle && + !m_font.Ok() && + !m_foregroundColour.Ok() && !m_backgroundColour.Ok() ) { return NULL; } GtkRcStyle *style = gtk_rc_style_new(); - if ( m_hasFont ) + if ( m_font.Ok() ) { #ifdef __WXGTK20__ style->font_desc = @@ -4108,41 +4042,41 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle() #endif } - if ( m_hasFgCol ) + if ( m_foregroundColour.Ok() ) { - m_foregroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) ); + GdkColor *fg = m_foregroundColour.GetColor(); - style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_NORMAL] = *fg; style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG; - style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_PRELIGHT] = *fg; style->color_flags[GTK_STATE_PRELIGHT] = GTK_RC_FG; - style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); + style->fg[GTK_STATE_ACTIVE] = *fg; style->color_flags[GTK_STATE_ACTIVE] = GTK_RC_FG; } - if ( m_hasBgCol && m_backgroundColour.Ok() ) + 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(); + GdkColor *bg = m_backgroundColour.GetColor(); + + style->bg[GTK_STATE_NORMAL] = *bg; + style->base[GTK_STATE_NORMAL] = *bg; style->color_flags[GTK_STATE_NORMAL] = (GtkRcFlags) (style->color_flags[GTK_STATE_NORMAL] | GTK_RC_BG | GTK_RC_BASE); - style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_PRELIGHT] = *bg; + style->base[GTK_STATE_PRELIGHT] = *bg; style->color_flags[GTK_STATE_PRELIGHT] = (GtkRcFlags) (style->color_flags[GTK_STATE_PRELIGHT] | GTK_RC_BG | GTK_RC_BASE); - style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_ACTIVE] = *bg; + style->base[GTK_STATE_ACTIVE] = *bg; style->color_flags[GTK_STATE_ACTIVE] = (GtkRcFlags) (style->color_flags[GTK_STATE_ACTIVE] | GTK_RC_BG | GTK_RC_BASE); - style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); - style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor(); + style->bg[GTK_STATE_INSENSITIVE] = *bg; + style->base[GTK_STATE_INSENSITIVE] = *bg; style->color_flags[GTK_STATE_INSENSITIVE] = (GtkRcFlags) (style->color_flags[GTK_STATE_INSENSITIVE] | GTK_RC_BG | GTK_RC_BASE); } @@ -4150,10 +4084,26 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle() return style; } -void wxWindowGTK::ApplyWidgetStyle() +void wxWindowGTK::ApplyWidgetStyle(bool forceStyle) +{ + GtkRcStyle *style = CreateWidgetStyle(forceStyle); + if ( style ) + { + DoApplyWidgetStyle(style); + gtk_rc_style_unref(style); + } +} + +void wxWindowGTK::DoApplyWidgetStyle(GtkRcStyle *style) { + if (m_wxwindow) + // should we also do m_widget in this case? + gtk_widget_modify_style(m_wxwindow, style); + else + gtk_widget_modify_style(m_widget, style); } + //----------------------------------------------------------------------------- // Pop-up menu stuff //----------------------------------------------------------------------------- @@ -4296,24 +4246,16 @@ bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window ) bool wxWindowGTK::SetFont( const wxFont &font ) { - if (!wxWindowBase::SetFont(font) || !m_widget) - { - return FALSE; - } + wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") ); - wxColour sysbg = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ); - if ( sysbg == m_backgroundColour ) - { - m_backgroundColour = wxNullColour; - ApplyWidgetStyle(); - m_backgroundColour = sysbg; - } - else - { - ApplyWidgetStyle(); - } + if (!wxWindowBase::SetFont(font)) + return false; - return TRUE; + // apply style change (forceStyle=true so that new style is applied + // even if the font changed from valid to wxNullFont): + ApplyWidgetStyle(true); + + return true; } void wxWindowGTK::DoCaptureMouse()