diff --git a/src/display.h b/src/display.h index c1a8adbf9b9c2c2d7ecc8e21ccace76ecc73a55b..6b562e2f218a77195aa6133883bf49cb7a5e131a 100644 --- a/src/display.h +++ b/src/display.h @@ -275,7 +275,6 @@ enum typedef struct _Client Client; typedef struct _DisplayInfo DisplayInfo; -typedef struct _XfwmColor XfwmColor; typedef struct _xfwmPixmap xfwmPixmap; typedef struct _XfwmParams XfwmParams; typedef struct _ScreenInfo ScreenInfo; diff --git a/src/screen.c b/src/screen.c index e0252d572a617cc7f9803611bb4a2871ee1f7461..9077260135701bb73c241f20517e5ed300accca1 100644 --- a/src/screen.c +++ b/src/screen.c @@ -306,14 +306,6 @@ myScreenInit (DisplayInfo *display_info, GdkScreen *gscr, unsigned long event_ma screen_info->font_height = 0; screen_info->box_gc = None; - screen_info->title_colors[ACTIVE].gc = NULL; - screen_info->title_colors[ACTIVE].allocated = FALSE; - screen_info->title_colors[INACTIVE].gc = NULL; - screen_info->title_colors[INACTIVE].allocated = FALSE; - screen_info->title_shadow_colors[ACTIVE].gc = NULL; - screen_info->title_shadow_colors[ACTIVE].allocated = FALSE; - screen_info->title_shadow_colors[INACTIVE].gc = NULL; - screen_info->title_shadow_colors[INACTIVE].allocated = FALSE; for (i = 0; i < SIDE_COUNT; i++) { diff --git a/src/screen.h b/src/screen.h index e35cc0fc6a5080511a023926f118dbcaf4500e62..87256d4b63d9cabee847b22528ab84fdc2e68885 100644 --- a/src/screen.h +++ b/src/screen.h @@ -86,8 +86,8 @@ struct _ScreenInfo gint pointer_grabs; /* Theme pixmaps and other params, per screen */ - XfwmColor title_colors[2]; - XfwmColor title_shadow_colors[2]; + GdkRGBA title_colors[2]; + GdkRGBA title_shadow_colors[2]; xfwmPixmap buttons[BUTTON_COUNT][STATE_COUNT]; xfwmPixmap corners[CORNER_COUNT][2]; xfwmPixmap sides[SIDE_COUNT][2]; diff --git a/src/settings.c b/src/settings.c index 3d7065b19cdb46fe3c7a61e4a77352afb648d753..5b1be4c6107d8fead160fd2c41e1f6366f659899 100644 --- a/src/settings.c +++ b/src/settings.c @@ -248,50 +248,6 @@ loadXfconfData (ScreenInfo *screen_info, Settings *rc) } -/* Simple helper function to avoid copy/paste of code */ -static void -setXfwmColor (ScreenInfo *screen_info, XfwmColor *color, Settings *rc, int id, const gchar * name, const gchar * state) -{ - if (color->allocated) - { - gdk_colormap_free_colors (gdk_screen_get_system_colormap (screen_info->gscr), &color->col, 1); - color->allocated = FALSE; - } - - /** do a direct value_get_string */ - if (gdk_color_parse (g_value_get_string(rc[id].value), &color->col)) - { - if (gdk_colormap_alloc_color (gdk_screen_get_system_colormap (screen_info->gscr), - &color->col, FALSE, FALSE)) - { - color->allocated = TRUE; - if (color->gc) - { - g_object_unref (G_OBJECT (color->gc)); - } - color->gc = gdk_gc_new (myScreenGetGdkWindow (screen_info)); - gdk_gc_copy (color->gc, getUIStyle_gc (myScreenGetGtkWidget (screen_info), name, state)); - gdk_gc_set_foreground (color->gc, &color->col); - } - else - { - gdk_beep (); - if (G_VALUE_TYPE(rc[id].value) == G_TYPE_STRING) - g_message (_("%s: Cannot allocate color %s\n"), g_get_prgname (), g_value_get_string(rc[id].value)); - else - g_critical (_("%s: Cannot allocate color: GValue for color is not of type STRING"), g_get_prgname ()); - } - } - else - { - gdk_beep (); - if (G_VALUE_TYPE(rc[id].value) == G_TYPE_STRING) - g_message (_("%s: Cannot parse color %s\n"), g_get_prgname (), g_value_get_string(rc[id].value)); - else - g_critical (_("%s: Cannot parse color: GValue for color is not of type STRING"), g_get_prgname ()); - } -} - static int getTitleShadow (Settings *rc, const gchar * name) { @@ -425,7 +381,7 @@ loadTheme (ScreenInfo *screen_info, Settings *rc) { gchar *color; - color = getUIStyle (widget, ui_part[i], ui_state[i]); + color = getUIStyleString (widget, ui_part[i], ui_state[i]); setStringValue (rc[i].option, color, rc); g_free (color); } @@ -504,10 +460,10 @@ loadTheme (ScreenInfo *screen_info, Settings *rc) } } - setXfwmColor (screen_info, &screen_info->title_colors[ACTIVE], rc, 0, "fg", "selected"); - setXfwmColor (screen_info, &screen_info->title_colors[INACTIVE], rc, 1, "fg", "insensitive"); - setXfwmColor (screen_info, &screen_info->title_shadow_colors[ACTIVE], rc, 2, "dark", "selected"); - setXfwmColor (screen_info, &screen_info->title_shadow_colors[INACTIVE], rc, 3, "dark", "insensitive"); + gdk_rgba_parse (&screen_info->title_colors[ACTIVE], getStringValue ("active_text_color", rc)); + gdk_rgba_parse (&screen_info->title_colors[INACTIVE], getStringValue ("inactive_text_color", rc)); + gdk_rgba_parse (&screen_info->title_shadow_colors[ACTIVE], getStringValue ("active_text_shadow_color", rc)); + gdk_rgba_parse (&screen_info->title_shadow_colors[INACTIVE], getStringValue ("inactive_text_shadow_color", rc)); for (i = 0; i < SIDE_COUNT; i++) { diff --git a/src/settings.h b/src/settings.h index 845fcbe475f748d102dc4aa2a0c0ecb398d25a6c..9d4994d48823f76389398bfb0a12322b2f4c8641 100644 --- a/src/settings.h +++ b/src/settings.h @@ -155,13 +155,6 @@ enum PLACE_CENTER }; -struct _XfwmColor -{ - GdkColor col; - GdkGC *gc; - gboolean allocated; -}; - struct _Settings { gchar *option; diff --git a/src/ui_style.c b/src/ui_style.c index e38da9dc907d4954d0a58f6341fcc3dab224c915..8b34e43ac457e56de874c218aedd765b5f426d53 100644 --- a/src/ui_style.c +++ b/src/ui_style.c @@ -45,16 +45,23 @@ char *states[] = { }; char *names[] = { - "fg", "bg", "text", "base", "light", "dark", "mid", NULL + "fg", "bg", "light", "dark", "mid", NULL }; #define GTKSTYLE_FG 0 #define GTKSTYLE_BG 1 -#define GTKSTYLE_TEXT 2 -#define GTKSTYLE_BASE 3 -#define GTKSTYLE_LIGHT 4 -#define GTKSTYLE_DARK 5 -#define GTKSTYLE_MID 6 +#define GTKSTYLE_LIGHT 2 +#define GTKSTYLE_DARK 3 +#define GTKSTYLE_MID 4 + +#define GTKSTATE_NORMAL 0 +#define GTKSTATE_ACTIVE 1 +#define GTKSTATE_PRELIGHT 2 +#define GTKSTATE_SELECTED 3 +#define GTKSTATE_INSENSITIVE 4 + +#define LIGHTNESS_MULT 1.3 +#define DARKNESS_MULT 0.7 static gint state_value (const gchar * s) @@ -69,7 +76,7 @@ state_value (const gchar * s) { return (u); } - return (0); + return (-1); } static gint @@ -85,176 +92,277 @@ name_value (const gchar * s) { return (u); } - return (0); + return (-1); } -static gchar * -print_color (GtkWidget * win, GdkColor * c) +static void +rgb_to_hls (gdouble * r, gdouble * g, gdouble * b) { - gchar *s; - GdkColor real_color; - GdkColormap *cmap; + /* from gtkstyle.c in gtk2 branch */ + + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; - s = g_new (gchar, 14); - cmap = gtk_widget_get_colormap (GTK_WIDGET (win)); - if (cmap && GDK_IS_COLORMAP (cmap)) + max = MAX (red, MAX (green, blue)); + min = MIN (red, MIN (green, blue)); + + l = (max + min) / 2; + s = 0; + h = 0; + + if (max != min) { - gdk_colormap_query_color (cmap, c->pixel, &real_color); - g_snprintf (s, 14, "#%04x%04x%04x", real_color.red, real_color.green, - real_color.blue); + if (l <= 0.5) + s = (max - min) / (max + min); + else + s = (max - min) / (2 - max - min); + + delta = max - min; + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h *= 60; + if (h < 0.0) + h += 360; } + + *r = h; + *g = l; + *b = s; +} + +static void +hls_to_rgb (gdouble * h, gdouble * l, gdouble * s) +{ + /* from gtkstyle.c in gtk2 branch */ + + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + + if (lightness <= 0.5) + m2 = lightness * (1 + saturation); else + m2 = lightness + saturation - lightness * saturation; + m1 = 2 * lightness - m2; + + if (saturation == 0) { - g_snprintf (s, 14, "#%04x%04x%04x", c->red, c->green, c->blue); + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h + 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + r = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1 + (m2 - m1) * (240 - hue) / 60; + else + r = m1; + + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + g = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1 + (m2 - m1) * (240 - hue) / 60; + else + g = m1; + + hue = *h - 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + b = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1 + (m2 - m1) * (240 - hue) / 60; + else + b = m1; + + *h = r; + *l = g; + *s = b; } - return (s); } -static gchar * -print_colors (GtkWidget * win, GdkColor * x, int n) +static void +rgba_shade (GdkRGBA * color, gdouble value) { - return (print_color (win, x + n)); + rgb_to_hls (&color->red, &color->green, &color->blue); + color->green = MAX (MIN (color->green * value, 1), 0); + color->blue = MAX (MIN (color->blue * value, 1), 0); + hls_to_rgb (&color->red, &color->green, &color->blue); } -static gchar * -print_rc_style (GtkWidget * win, const gchar * name, const gchar * state, - GtkStyle * style) +gboolean +getUIStyleColor (GtkWidget * win, const gchar * name, const gchar * state, GdkRGBA * rgba) { - gchar *s; - gint n, m; + GtkStyleContext *ctx; + GdkRGBA *result; + GtkStateFlags flags; + gint gtkstyle; + gchar *property; + + TRACE ("entering getUIStyleColor"); - g_return_val_if_fail (state != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (win != NULL, FALSE); + g_return_val_if_fail (GTK_IS_WIDGET (win), FALSE); + g_return_val_if_fail (gtk_widget_get_realized (win), FALSE); - n = state_value (state); - m = name_value (name); + gtkstyle = name_value (name); - switch (m) + switch (gtkstyle) { case GTKSTYLE_FG: - s = print_colors (win, style->fg, n); + property = GTK_STYLE_PROPERTY_COLOR; break; case GTKSTYLE_BG: - s = print_colors (win, style->bg, n); - break; - case GTKSTYLE_TEXT: - s = print_colors (win, style->text, n); - break; - case GTKSTYLE_BASE: - s = print_colors (win, style->base, n); - break; case GTKSTYLE_LIGHT: - s = print_colors (win, style->light, n); - break; case GTKSTYLE_DARK: - s = print_colors (win, style->dark, n); - break; - default: case GTKSTYLE_MID: - s = print_colors (win, style->mid, n); + property = GTK_STYLE_PROPERTY_BACKGROUND_COLOR; break; + default: + return FALSE; } - return (s); -} -gchar * -getUIStyle (GtkWidget * win, const gchar * name, const gchar * state) -{ - GtkStyle *style; - gchar *s; - - TRACE ("entering getUIStyle"); - - g_return_val_if_fail (win != NULL, NULL); - g_return_val_if_fail (GTK_IS_WIDGET (win), NULL); - g_return_val_if_fail (gtk_widget_get_realized (win), NULL); - - style = gtk_rc_get_style (win); - if (!style) + switch (state_value (state)) { - style = gtk_widget_get_style (win); + case GTKSTATE_NORMAL: + flags = GTK_STATE_FLAG_NORMAL; + break; + case GTKSTATE_ACTIVE: + flags = GTK_STATE_FLAG_ACTIVE; + break; + case GTKSTATE_PRELIGHT: + flags = GTK_STATE_FLAG_PRELIGHT; + break; + case GTKSTATE_SELECTED: + flags = GTK_STATE_FLAG_SELECTED; + break; + case GTKSTATE_INSENSITIVE: + flags = GTK_STATE_FLAG_INSENSITIVE; + break; + default: + return FALSE; } - s = print_rc_style (win, name, state, style); - TRACE ("%s[%s]=%s", name, state, s); - return (s); -} -static GdkGC * -_getUIStyle_gc (const gchar * name, const gchar * state, GtkStyle * style) -{ - GdkGC *gc; - gint n, m; + ctx = gtk_widget_get_style_context (win); - g_return_val_if_fail (state != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (style != NULL, NULL); - g_return_val_if_fail (GTK_IS_STYLE(style), NULL); + gtk_style_context_save (ctx); + gtk_style_context_add_class (ctx, "gtkstyle-fallback"); + gtk_style_context_get (ctx, flags, property, &result, NULL); + gtk_style_context_restore (ctx); - n = state_value (state); - m = name_value (name); + *rgba = *result; - switch (m) + switch (gtkstyle) { - case GTKSTYLE_FG: - gc = style->fg_gc[n]; - break; - case GTKSTYLE_BG: - gc = style->bg_gc[n]; - break; - case GTKSTYLE_TEXT: - gc = style->text_gc[n]; - break; - case GTKSTYLE_BASE: - gc = style->base_gc[n]; - break; case GTKSTYLE_LIGHT: - gc = style->light_gc[n]; + rgba_shade (rgba, LIGHTNESS_MULT); break; case GTKSTYLE_DARK: - gc = style->dark_gc[n]; + rgba_shade (rgba, DARKNESS_MULT); break; - default: case GTKSTYLE_MID: - gc = style->mid_gc[n]; + rgba_shade (rgba, LIGHTNESS_MULT); + rgba_shade (result, DARKNESS_MULT); + rgba->red = (rgba->red + result->red) / 2; + rgba->green = (rgba->green + result->green) / 2; + rgba->blue = (rgba->blue + result->blue) / 2; break; } - return (gc); + gdk_rgba_free (result); + + return TRUE; } -GdkGC * -getUIStyle_gc (GtkWidget * win, const gchar * name, const gchar * state) +gchar * +getUIStyleString (GtkWidget * win, const gchar * name, const gchar * state) { - GtkStyle *style; + GdkRGBA color = {0, }; + GdkRGBA bg = {0, }; + gint red; + gint green; + gint blue; - TRACE ("entering getUIStyle_gc"); + TRACE ("entering getUIStyleString"); - g_return_val_if_fail (win != NULL, NULL); - g_return_val_if_fail (GTK_IS_WIDGET (win), NULL); - g_return_val_if_fail (gtk_widget_get_realized (win), NULL); - - style = gtk_rc_get_style (win); - if (!style) - { - style = gtk_widget_get_style (win); - } - if (!style) + if (getUIStyleColor (win, name, state, &color)) { - style = gtk_widget_get_default_style (); + if (color.alpha < 1 && g_strcmp0 (name, "bg") && getUIStyleColor (win, "bg", state, &bg)) + { + /* compose bg and fg colors to get opaque color */ + color.red = color.red * color.alpha + bg.red * (1 - color.alpha); + color.green = color.green * color.alpha + bg.green * (1 - color.alpha); + color.blue = color.blue * color.alpha + bg.blue * (1 - color.alpha); + } } - return (_getUIStyle_gc (name, state, style)); + + red = color.red * 0xff; + green = color.green * 0xff; + blue = color.blue * 0xff; + + return g_strdup_printf ("#%02x%02x%02x%02x%02x%02x", red, red, green, green, blue, blue); } PangoFontDescription * getUIPangoFontDesc (GtkWidget * win) { + GtkStyleContext *ctx; + PangoFontDescription *font_desc; + TRACE ("entering getUIPangoFontDesc"); g_return_val_if_fail (win != NULL, NULL); g_return_val_if_fail (GTK_IS_WIDGET (win), NULL); g_return_val_if_fail (gtk_widget_get_realized (win), NULL); - return (win->style->font_desc); + ctx = gtk_widget_get_style_context (win); + gtk_style_context_get (ctx, GTK_STATE_FLAG_NORMAL, + GTK_STYLE_PROPERTY_FONT, &font_desc, + NULL); + + return font_desc; } PangoContext * diff --git a/src/ui_style.h b/src/ui_style.h index aec3e3e9e13b1fffc4f0daf7b3032bc2ff0f96e6..a38bbc01d1981ac1a4eca6d8f1123f528ebe3f10 100644 --- a/src/ui_style.h +++ b/src/ui_style.h @@ -31,10 +31,11 @@ #include <gtk/gtk.h> #include <pango/pango-font.h> -gchar *getUIStyle (GtkWidget *, +gboolean getUIStyleColor (GtkWidget *, const gchar *, - const gchar *); -GdkGC *getUIStyle_gc (GtkWidget *, + const gchar *, + GdkRGBA *); +gchar *getUIStyleString (GtkWidget *, const gchar *, const gchar *); PangoFontDescription *getUIPangoFontDesc (GtkWidget *); diff --git a/src/wireframe.c b/src/wireframe.c index 9ac4e17e1861a53cfe9736b1c4a49348b3acd925..3f7338a8d6fd0ffc6306ce4b8697604cdb3ef516 100644 --- a/src/wireframe.c +++ b/src/wireframe.c @@ -181,26 +181,14 @@ wireframeUpdate (Client *c, WireFrame *wireframe) static void wireframeInitColor (WireFrame *wireframe) { - ScreenInfo *screen_info; - gchar *color; - GdkColor gcolor; + GdkRGBA rgba; - screen_info = wireframe->screen_info; - color = getUIStyle (myScreenGetGtkWidget (screen_info), "bg", "selected"); - if (gdk_color_parse (color, &gcolor)) - { - wireframe->red = (gdouble) gcolor.red / (gdouble) 65535; - wireframe->green = (gdouble) gcolor.green / (gdouble) 65535; - wireframe->blue = (gdouble) gcolor.blue / (gdouble) 65535; - } - else + if (getUIStyleColor (myScreenGetGtkWidget (wireframe->screen_info), "bg", "selected", &rgba)) { - g_warning ("Cannot parse color %s", color); - wireframe->red = 0.0; - wireframe->green = 0.5; - wireframe->blue = 1.0; + wireframe->red = rgba.red; + wireframe->green = rgba.green; + wireframe->blue = rgba.blue; } - g_free (color); } WireFrame *