diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index cd685f27ff..a7f4f7fcf9 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -1796,41 +1796,6 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style) void wxTextCtrl::DoApplyWidgetStyle(GtkRcStyle *style) { -#ifdef __WXGTK3__ - // Preserve selection colors, otherwise the GTK_STATE_FLAG_NORMAL override - // will be used, and the selection is invisible - const GtkStateFlags selectedFocused = - GtkStateFlags(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED); - // remove any previous override - gtk_widget_override_color(m_text, GTK_STATE_FLAG_NORMAL, NULL); - gtk_widget_override_color(m_text, selectedFocused, NULL); - gtk_widget_override_background_color(m_text, GTK_STATE_FLAG_NORMAL, NULL); - gtk_widget_override_background_color(m_text, selectedFocused, NULL); - const bool fg_ok = m_foregroundColour.IsOk(); - const bool bg_ok = m_backgroundColour.IsOk(); - if (fg_ok || bg_ok) - { - GdkRGBA *fg_orig, *bg_orig; - GtkStyleContext* context = gtk_widget_get_style_context(m_text); - gtk_style_context_save(context); - if (IsMultiLine()) - gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW); - gtk_style_context_set_state(context, selectedFocused); - gtk_style_context_get(context, selectedFocused, - "color", &fg_orig, "background-color", &bg_orig, - NULL); - gtk_style_context_restore(context); - - if (fg_ok) - gtk_widget_override_color(m_text, selectedFocused, fg_orig); - if (bg_ok) - gtk_widget_override_background_color(m_text, selectedFocused, bg_orig); - - gdk_rgba_free(fg_orig); - gdk_rgba_free(bg_orig); - } -#endif // __WXGTK3__ - GTKApplyStyle(m_text, style); } diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index bcf04ba8ad..f7ed030f29 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -4561,27 +4561,121 @@ GtkRcStyle* wxWindowGTK::GTKCreateWidgetStyle() void wxWindowGTK::GTKApplyWidgetStyle(bool forceStyle) { - if (forceStyle || m_font.IsOk() || - m_foregroundColour.IsOk() || m_backgroundColour.IsOk()) + const wxColour& fg = m_foregroundColour; + const wxColour& bg = m_backgroundColour; + const bool isFg = fg.IsOk(); + const bool isBg = bg.IsOk(); + const bool isFont = m_font.IsOk(); + if (forceStyle || isFg || isBg || isFont) { #ifdef __WXGTK3__ - if (m_backgroundColour.IsOk()) + GString* css = g_string_new("*{"); + if (isFg) { - // create a GtkStyleProvider to override "background-image" - if (m_styleProvider == NULL) - m_styleProvider = GTK_STYLE_PROVIDER(gtk_css_provider_new()); - const char css[] = - "*{background-image:-gtk-gradient(linear,0 0,0 1," - "from(rgba(%u,%u,%u,%g)),to(rgba(%u,%u,%u,%g)))}"; - char buf[sizeof(css) + 20]; - const unsigned r = m_backgroundColour.Red(); - const unsigned g = m_backgroundColour.Green(); - const unsigned b = m_backgroundColour.Blue(); - const double a = m_backgroundColour.Alpha() / 255.0; - g_snprintf(buf, sizeof(buf), css, r, g, b, a, r, g, b, a); - gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(m_styleProvider), buf, -1, NULL); + g_string_append_printf(css, "color:%s;", + static_cast(fg.GetAsString(wxC2S_HTML_SYNTAX))); + } + if (isBg) + { + g_string_append_printf(css, "background:%s;", + static_cast(bg.GetAsString(wxC2S_HTML_SYNTAX))); + } + if (isFont) + { + g_string_append(css, "font:"); + const PangoFontDescription* pfd = m_font.GetNativeFontInfo()->description; + if (gtk_check_version(3,22,0)) + g_string_append(css, wxGtkString(pango_font_description_to_string(pfd))); + else + { + const PangoFontMask pfm = pango_font_description_get_set_fields(pfd); + if (pfm & PANGO_FONT_MASK_STYLE) + { + const char* s = ""; + switch (pango_font_description_get_style(pfd)) + { + case PANGO_STYLE_NORMAL: break; + case PANGO_STYLE_OBLIQUE: s = "oblique "; break; + case PANGO_STYLE_ITALIC: s = "italic "; break; + } + g_string_append(css, s); + } + if (pfm & PANGO_FONT_MASK_VARIANT) + { + switch (pango_font_description_get_variant(pfd)) + { + case PANGO_VARIANT_NORMAL: + break; + case PANGO_VARIANT_SMALL_CAPS: + g_string_append(css, "small-caps "); + break; + } + } + if (pfm & PANGO_FONT_MASK_WEIGHT) + { + const int weight = pango_font_description_get_weight(pfd); + if (weight != PANGO_WEIGHT_NORMAL) + g_string_append_printf(css, "%d ", weight); + } + if (pfm & PANGO_FONT_MASK_STRETCH) + { + const char* s = ""; + switch (pango_font_description_get_stretch(pfd)) + { + case PANGO_STRETCH_ULTRA_CONDENSED: s = "ultra-condensed "; break; + case PANGO_STRETCH_EXTRA_CONDENSED: s = "extra-condensed "; break; + case PANGO_STRETCH_CONDENSED: s = "condensed "; break; + case PANGO_STRETCH_SEMI_CONDENSED: s = "semi-condensed "; break; + case PANGO_STRETCH_NORMAL: break; + case PANGO_STRETCH_SEMI_EXPANDED: s = "semi-expanded "; break; + case PANGO_STRETCH_EXPANDED: s = "expanded "; break; + case PANGO_STRETCH_EXTRA_EXPANDED: s = "extra-expanded "; break; + case PANGO_STRETCH_ULTRA_EXPANDED: s = "ultra-expanded "; break; + } + g_string_append(css, s); + } + if (pfm & PANGO_FONT_MASK_SIZE) + { + const int size = pango_font_description_get_size(pfd); + if (pango_font_description_get_size_is_absolute(pfd)) + g_string_append_printf(css, "%dpx ", size); + else + g_string_append_printf(css, "%dpt ", size / PANGO_SCALE); + } + if (pfm & PANGO_FONT_MASK_FAMILY) + { + g_string_append_printf(css, "\"%s\"", + pango_font_description_get_family(pfd)); + } + } + } + g_string_append_c(css, '}'); + + if (isFg && isBg) + { + // Selection will be invisible, so add textview selection colors. + // This is specifically for wxTextCtrl, but may be useful for other + // controls, and seems to do no harm to apply to all. + const wxColour fg_sel(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + const wxColour bg_sel(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); + const char* s = "*:selected"; + if (gtk_check_version(3,20,0) == NULL) + s = "selection"; + g_string_append_printf(css, "%s{color:%s;background:%s}", s, + static_cast(fg_sel.GetAsString(wxC2S_HTML_SYNTAX)), + static_cast(bg_sel.GetAsString(wxC2S_HTML_SYNTAX))); + } + + if (m_styleProvider == NULL && (isFg || isBg || isFont)) + m_styleProvider = GTK_STYLE_PROVIDER(gtk_css_provider_new()); + + wxGtkString s(g_string_free(css, false)); + if (m_styleProvider) + { + gtk_css_provider_load_from_data( + GTK_CSS_PROVIDER(m_styleProvider), s, -1, NULL); + DoApplyWidgetStyle(NULL); } - DoApplyWidgetStyle(NULL); #else GtkRcStyle* style = GTKCreateWidgetStyle(); DoApplyWidgetStyle(style); @@ -4599,34 +4693,9 @@ void wxWindowGTK::DoApplyWidgetStyle(GtkRcStyle *style) void wxWindowGTK::GTKApplyStyle(GtkWidget* widget, GtkRcStyle* WXUNUSED_IN_GTK3(style)) { #ifdef __WXGTK3__ - const PangoFontDescription* pfd = NULL; - if (m_font.IsOk()) - pfd = m_font.GetNativeFontInfo()->description; - gtk_widget_override_font(widget, pfd); - gtk_widget_override_color(widget, GTK_STATE_FLAG_NORMAL, m_foregroundColour); - gtk_widget_override_background_color(widget, GTK_STATE_FLAG_NORMAL, m_backgroundColour); - - // setting background color has no effect with some themes when the widget style - // has a "background-image" property, so we need to override that as well - GtkStyleContext* context = gtk_widget_get_style_context(widget); - if (m_styleProvider) - gtk_style_context_remove_provider(context, m_styleProvider); - cairo_pattern_t* pattern = NULL; - if (m_backgroundColour.IsOk()) - { - gtk_style_context_save(context); - gtk_style_context_set_state(context, GTK_STATE_FLAG_NORMAL); - gtk_style_context_get(context, - GTK_STATE_FLAG_NORMAL, "background-image", &pattern, NULL); - gtk_style_context_restore(context); - } - if (pattern) - { - cairo_pattern_destroy(pattern); - gtk_style_context_add_provider(context, - m_styleProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - } + gtk_style_context_add_provider(context, + m_styleProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); #else gtk_widget_modify_style(widget, style); #endif