-    //Format mnemonics properly for GTK2. This can be called from GTK1.x, but
-    //it's not very useful because mnemonics don't exist prior to GTK2.
-    wxString label2;
-    for (size_t i = 0; i < label.Len(); i++)
-    {
-        if (label.GetChar(i) == wxT('&'))
-        {
-            //Mnemonic escape sequence "&&" is a literal "&" in the output.
-            if (label.GetChar(i + 1) == wxT('&'))
-            {
-                label2 << wxT('&');
-                i++;
-            }
-            //Handle special case of "&_" (i.e. "_" is the mnemonic).
-            //FIXME - Is it possible to use "_" as a GTK mnemonic? Just use a
-            //dash for now.
-            else if (label.GetChar(i + 1) == wxT('_'))
-            {
-                label2 << wxT("_-");
-                i++;
-            }
-            //Replace WX mnemonic indicator "&" with GTK indicator "_".
-            else
-            {
-                label2 << wxT('_');
-            }
-        }
-        else if (label.GetChar(i) == wxT('_'))
-        {
-            //Escape any underlines in the string so GTK doesn't use them.
-            label2 << wxT("__");
-        }
-        else
-        {
-            label2 << label.GetChar(i);
-        }
-    }
-    return label2;
+    // save the original label
+    wxControlBase::SetLabel(label);
+
+    const wxString labelGTK = GTKConvertMnemonics(label);
+    gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
+}
+
+void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label)
+{
+    const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label);
+    gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK));
+}
+
+
+// ----------------------------------------------------------------------------
+// GtkFrame helpers
+//
+// GtkFrames do in fact support mnemonics in GTK2+ but not through
+// gtk_frame_set_label, rather you need to use a custom label widget
+// instead (idea gleaned from the native gtk font dialog code in GTK)
+// ----------------------------------------------------------------------------
+
+GtkWidget* wxControl::GTKCreateFrame(const wxString& label)
+{
+    const wxString labelGTK = GTKConvertMnemonics(label);
+    GtkWidget* labelwidget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK));
+    gtk_widget_show(labelwidget); // without this it won't show...
+
+    GtkWidget* framewidget = gtk_frame_new(NULL);
+    gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
+
+    return framewidget; // note that the label is already set so you'll
+                        // only need to call wxControl::SetLabel afterwards
+}
+
+void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
+{
+    GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
+    GTKSetLabelForLabel(labelwidget, label);