+ 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);
+ {
+ const wxCharBuffer data = wxGTK_CONV( string );
+ if ( data )
+ pango_layout_set_text(layout, data, strlen(data));
+ }
+
+ 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 (layout);
+}
+
+void wxWindowGTK::GTKDisableFocusOutEvent()
+{
+ g_signal_handlers_block_by_func( m_focusWidget,
+ (gpointer) gtk_window_focus_out_callback, this);
+}
+
+void wxWindowGTK::GTKEnableFocusOutEvent()
+{
+ g_signal_handlers_unblock_by_func( m_focusWidget,
+ (gpointer) gtk_window_focus_out_callback, this);
+}
+
+bool wxWindowGTK::GTKHandleFocusIn()
+{
+ // Disable default focus handling for custom windows since the default GTK+
+ // handler issues a repaint
+ const bool retval = m_wxwindow ? true : false;
+
+
+ // NB: if there's still unprocessed deferred focus-out event (see
+ // GTKHandleFocusOut() for explanation), we need to process it first so
+ // that the order of focus events -- focus-out first, then focus-in
+ // elsewhere -- is preserved
+ if ( gs_deferredFocusOut )
+ {
+ if ( GTKNeedsToFilterSameWindowFocus() &&
+ gs_deferredFocusOut == this )
+ {
+ // GTK+ focus changed from this wxWindow back to itself, so don't
+ // emit any events at all
+ wxLogTrace(TRACE_FOCUS,
+ "filtered out spurious focus change within %s(%p, %s)",
+ GetClassInfo()->GetClassName(), this, GetLabel());
+ gs_deferredFocusOut = NULL;
+ return retval;
+ }
+
+ // otherwise we need to send focus-out first
+ wxASSERT_MSG ( gs_deferredFocusOut != this,
+ "GTKHandleFocusIn(GTKFocus_Normal) called even though focus changed back to itself - derived class should handle this" );
+ GTKHandleDeferredFocusOut();
+ }
+
+
+ wxLogTrace(TRACE_FOCUS,
+ "handling focus_in event for %s(%p, %s)",
+ GetClassInfo()->GetClassName(), this, GetLabel());
+
+ if (m_imData)
+ gtk_im_context_focus_in(m_imData->context);
+
+ gs_currentFocus = this;
+ gs_pendingFocus = NULL;
+
+#if wxUSE_CARET
+ // caret needs to be informed about focus change
+ wxCaret *caret = GetCaret();
+ if ( caret )
+ {
+ caret->OnSetFocus();
+ }
+#endif // wxUSE_CARET
+
+ // Notify the parent keeping track of focus for the kbd navigation
+ // purposes that we got it.
+ wxChildFocusEvent eventChildFocus(static_cast<wxWindow*>(this));
+ GTKProcessEvent(eventChildFocus);
+
+ wxFocusEvent eventFocus(wxEVT_SET_FOCUS, GetId());
+ eventFocus.SetEventObject(this);
+ GTKProcessEvent(eventFocus);
+
+ return retval;
+}
+
+bool wxWindowGTK::GTKHandleFocusOut()
+{
+ // Disable default focus handling for custom windows since the default GTK+
+ // handler issues a repaint
+ const bool retval = m_wxwindow ? true : false;
+
+
+ // NB: If a control is composed of several GtkWidgets and when focus
+ // changes from one of them to another within the same wxWindow, we get
+ // a focus-out event followed by focus-in for another GtkWidget owned
+ // by the same wx control. We don't want to generate two spurious
+ // wxEVT_SET_FOCUS events in this case, so we defer sending wx events
+ // from GTKHandleFocusOut() until we know for sure it's not coming back
+ // (i.e. in GTKHandleFocusIn() or at idle time).
+ if ( GTKNeedsToFilterSameWindowFocus() )
+ {
+ wxASSERT_MSG( gs_deferredFocusOut == NULL,
+ "deferred focus out event already pending" );
+ wxLogTrace(TRACE_FOCUS,
+ "deferring focus_out event for %s(%p, %s)",
+ GetClassInfo()->GetClassName(), this, GetLabel());
+ gs_deferredFocusOut = this;
+ return retval;