From 65c91667f93b27e713c15badf45f79daaf74933b Mon Sep 17 00:00:00 2001 From: o9000 Date: Mon, 20 Nov 2017 10:15:12 +0100 Subject: [PATCH] Implement tinting by icon content (bugfixes) --- src/config.c | 6 +++- src/taskbar/task.c | 60 +++++++++++++++++++++++++++------- src/taskbar/task.h | 1 + src/tint2conf/background_gui.c | 4 +-- src/tint2conf/properties_rw.c | 8 ++--- src/util/common.c | 21 ++++++++++++ src/util/common.h | 1 + 7 files changed, 83 insertions(+), 18 deletions(-) diff --git a/src/config.c b/src/config.c index 46ed2d8..58969e9 100644 --- a/src/config.c +++ b/src/config.c @@ -1092,6 +1092,9 @@ void add_entry(char *key, char *value) panel_config.g_task.config_background_mask |= (1 << status); if (status == TASK_NORMAL) panel_config.g_task.area.bg = panel_config.g_task.background[TASK_NORMAL]; + if (panel_config.g_task.background[status]->border_content_tint_weight > 0 || + panel_config.g_task.background[status]->fill_content_tint_weight > 0) + panel_config.g_task.has_content_tint = TRUE; } } // "tooltip" is deprecated but here for backwards compatibility @@ -1144,7 +1147,8 @@ void add_entry(char *key, char *value) systray_monitor = MAX(0, config_get_monitor(value)); } else if (strcmp(key, "systray_name_filter") == 0) { if (systray_hide_name_filter) { - fprintf(stderr, "tint2: Error: duplicate option 'systray_name_filter'. Please use it only once. See https://gitlab.com/o9000/tint2/issues/652\n"); + fprintf(stderr, "tint2: Error: duplicate option 'systray_name_filter'. Please use it only once. See " + "https://gitlab.com/o9000/tint2/issues/652\n"); free(systray_hide_name_filter); } systray_hide_name_filter = strdup(value); diff --git a/src/taskbar/task.c b/src/taskbar/task.c index bcbfab9..0a17b28 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -281,24 +281,18 @@ gboolean task_update_title(Task *task) return TRUE; } -void task_update_icon(Task *task) +Imlib_Image task_get_icon(Window win, int icon_size) { - Panel *panel = task->area.panel; - if (!panel->g_task.has_icon) - return; - - task_remove_icon(task); - Imlib_Image img = NULL; if (!img) { int len; - gulong *data = server_get_property(task->win, server.atom._NET_WM_ICON, XA_CARDINAL, &len); + gulong *data = server_get_property(win, server.atom._NET_WM_ICON, XA_CARDINAL, &len); if (data) { if (len > 0) { // get ARGB icon int w, h; - gulong *tmp_data = get_best_icon(data, get_icon_count(data, len), len, &w, &h, panel->g_task.icon_size1); + gulong *tmp_data = get_best_icon(data, get_icon_count(data, len), len, &w, &h, icon_size); if (tmp_data) { DATA32 icon_data[w * h]; for (int j = 0; j < w * h; ++j) @@ -311,7 +305,7 @@ void task_update_icon(Task *task) } if (!img) { - XWMHints *hints = XGetWMHints(server.display, task->win); + XWMHints *hints = XGetWMHints(server.display, win); if (hints) { if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) { // get width, height and depth for the pixmap @@ -333,6 +327,46 @@ void task_update_icon(Task *task) img = imlib_clone_image(); } + return img; +} + +void task_update_icon(Task *task) +{ + Panel *panel = task->area.panel; + if (!panel->g_task.has_icon) { + if (panel_config.g_task.has_content_tint) { + Imlib_Image img = task_get_icon(task->win, panel->g_task.icon_size1); + Color icon_color; + get_image_mean_color(img, &icon_color); + for (int k = 0; k < TASK_STATE_COUNT; ++k) { + task->icon_color[k] = icon_color; + adjust_color(&task->icon_color[k], + panel->g_task.alpha[k], + panel->g_task.saturation[k], + panel->g_task.brightness[k]); + if (panel_config.mouse_effects) { + task->icon_color_hover[k] = icon_color; + adjust_color(&task->icon_color_hover[k], + panel_config.mouse_over_alpha, + panel_config.mouse_over_saturation, + panel_config.mouse_over_brightness); + task->icon_color_press[k] = icon_color; + adjust_color(&task->icon_color_press[k], + panel_config.mouse_pressed_alpha, + panel_config.mouse_pressed_saturation, + panel_config.mouse_pressed_brightness); + } + } + imlib_context_set_image(img); + imlib_free_image(); + } + return; + } + + task_remove_icon(task); + + Imlib_Image img = task_get_icon(task->win, panel->g_task.icon_size1); + // transform icons imlib_context_set_image(img); imlib_image_set_has_alpha(1); @@ -647,7 +681,11 @@ void task_refresh_thumbnail(Task *task) task->thumbnail = thumbnail; task->thumbnail_last_update = get_time(); if (debug_thumbnails) - fprintf(stderr, YELLOW "tint2: %s took %f ms (window: %s)" RESET "\n", __func__, 1000 * (task->thumbnail_last_update - now), task->title ? task->title : ""); + fprintf(stderr, + YELLOW "tint2: %s took %f ms (window: %s)" RESET "\n", + __func__, + 1000 * (task->thumbnail_last_update - now), + task->title ? task->title : ""); if (g_tooltip.mapped && (g_tooltip.area == &task->area)) { tooltip_update_contents_for(&task->area); tooltip_update(); diff --git a/src/taskbar/task.h b/src/taskbar/task.h index 47d9ff0..dc93b9b 100644 --- a/src/taskbar/task.h +++ b/src/taskbar/task.h @@ -42,6 +42,7 @@ typedef struct GlobalTask { // starting position for text ~ task_padding + task_border + icon_size double text_posx, text_height; gboolean has_font; + gboolean has_content_tint; PangoFontDescription *font_desc; Color font[TASK_STATE_COUNT]; int config_font_mask; diff --git a/src/tint2conf/background_gui.c b/src/tint2conf/background_gui.c index df8d972..d2940ba 100644 --- a/src/tint2conf/background_gui.c +++ b/src/tint2conf/background_gui.c @@ -184,7 +184,7 @@ void create_background(GtkWidget *parent) gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - background_fill_content_tint_weight = gtk_spin_button_new_with_range(0, 1, 0.01); + background_fill_content_tint_weight = gtk_spin_button_new_with_range(0, 100, 1); gtk_widget_show(background_fill_content_tint_weight); gtk_table_attach(GTK_TABLE(table), background_fill_content_tint_weight, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; @@ -211,7 +211,7 @@ void create_background(GtkWidget *parent) gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - background_border_content_tint_weight = gtk_spin_button_new_with_range(0, 1, 0.01); + background_border_content_tint_weight = gtk_spin_button_new_with_range(0, 100, 1); gtk_widget_show(background_border_content_tint_weight); gtk_table_attach(GTK_TABLE(table), background_border_content_tint_weight, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; diff --git a/src/tint2conf/properties_rw.c b/src/tint2conf/properties_rw.c index 2705df2..c4c5880 100644 --- a/src/tint2conf/properties_rw.c +++ b/src/tint2conf/properties_rw.c @@ -251,8 +251,8 @@ void config_write_backgrounds(FILE *fp) strcat(sides, "R"); fprintf(fp, "border_sides = %s\n", sides); - fprintf(fp, "border_content_tint_weight = %d\n", (int)(100 * border_weight)); - fprintf(fp, "fill_content_tint_weight = %d\n", (int)(100 * fill_weight)); + fprintf(fp, "border_content_tint_weight = %d\n", (int)(border_weight)); + fprintf(fp, "fill_content_tint_weight = %d\n", (int)(fill_weight)); config_write_color(fp, "background_color", *fillColor, fillOpacity); config_write_color(fp, "border_color", *borderColor, borderOpacity); @@ -1240,10 +1240,10 @@ void add_entry(char *key, char *value) gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient_press), id); background_force_update(); } else if (strcmp(key, "border_content_tint_weight") == 0) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_border_content_tint_weight), atoi(value) / 100.); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_border_content_tint_weight), atoi(value)); background_force_update(); } else if (strcmp(key, "fill_content_tint_weight") == 0) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_fill_content_tint_weight), atoi(value) / 100.); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_fill_content_tint_weight), atoi(value)); background_force_update(); } diff --git a/src/util/common.c b/src/util/common.c index b31cd4e..08c2826 100644 --- a/src/util/common.c +++ b/src/util/common.c @@ -1087,8 +1087,29 @@ void get_image_mean_color(const Imlib_Image image, Color *mean_color) } } + if (!count) + count = 1; mean_color->alpha = 1.0; mean_color->rgb[0] = sum_r / 255.0 / count; mean_color->rgb[1] = sum_g / 255.0 / count; mean_color->rgb[2] = sum_b / 255.0 / count; } + +void adjust_color(Color *color, int alpha, int saturation, int brightness) +{ + if (alpha == 100 && saturation == 0 && brightness == 0) + return; + DATA32 argb = (((DATA32)(color->alpha * 255) & 0xff) << 24) | + (((DATA32)(color->rgb[0] * 255) & 0xff) << 16) | + (((DATA32)(color->rgb[1] * 255) & 0xff) << 8) | + (((DATA32)(color->rgb[2] * 255) & 0xff) << 0); + adjust_asb(&argb, 1, 1, alpha / 100.0, saturation / 100.0, brightness / 100.0); + DATA32 a = (argb >> 24) & 0xff; + DATA32 r = (argb >> 16) & 0xff; + DATA32 g = (argb >> 8) & 0xff; + DATA32 b = (argb) & 0xff; + color->alpha = a / 255.; + color->rgb[0] = r / 255.; + color->rgb[1] = g / 255.; + color->rgb[2] = b / 255.; +} diff --git a/src/util/common.h b/src/util/common.h index bdcb235..c916288 100644 --- a/src/util/common.h +++ b/src/util/common.h @@ -109,6 +109,7 @@ Imlib_Image load_image(const char *path, int cached); // * 1 = white void adjust_asb(DATA32 *data, int w, int h, float alpha_adjust, float satur_adjust, float bright_adjust); Imlib_Image adjust_icon(Imlib_Image original, int alpha, int saturation, int brightness); +void adjust_color(Color *color, int alpha, int saturation, int brightness); void create_heuristic_mask(DATA32 *data, int w, int h);