app, libgimpwidgets: drop the thumbnail icon feature.

From years of discussions, it turns out that:
- The thumbnailed-Wilber icon replacing the generic icon of GIMP often
  makes the application harder to spot in the icon list of running
  processes.
- In single-window mode in particular, it makes even less sense as we
  just show the one active image anyway.
- Even in multi-window mode, nowadays many OSes or desktop group windows
  of a same application under one icon. So we end up with several image
  windows under a thumbnail only showing the top image. This happens in
  KDE, GNOME, Cinnamon and Windows at least apparently (as far as is
  being reported).
- Some platforms would just use only the OS-declared icon and not care
  about runtime-declared ones. This is apparently the case on macOS, and
  also on GNOME when the desktop file is seen by the desktop
  environment. So all our code about generating thumbnailed icon is
  wasted on these platform anyway.
- When intensively testing the current behavior, I had cases when the
  icon was not properly updated. We could of course investigate and fix
  the issues, but considering all the previous points, it might make
  more sense to simply drop the feature which is mostly useless, or
  worse bothersome, hence simplify the code greatly.
- Finally API to set icons from GdkPixbuf data has been removed in GTK4.
  So long term, trying to keep this whole machinery feels like just
  making our life difficult for a feature which all OSes seem to
  deprecate and which might not be possible anymore soon (or just get
  harder and harder to implement).

Note that I don't use gtk_window_set_default_icon_name() because it
would use the icon from our theme, yet so far we are not sure it makes
sense for the application icon which we probably always want to be the
same, whatever the chosen theme. Finally I just list various common icon
sizes because GTK API doesn't seem to be clever enough yet. I can't just
give it 1 SVG image (e.g. with gtk_window_set_default_icon_from_file())
and hope it does the resizing at the last minute. It turns out it
doesn't and we get an extra-small icon. So instead, let's generate
common sizes ourselves from the same SVG.
This commit is contained in:
Jehan 2021-07-06 01:16:36 +02:00
parent 36f103c95f
commit 3598562472
12 changed files with 75 additions and 244 deletions

View File

@ -126,8 +126,6 @@ libappdisplay_a_sources = \
gimpdisplayshell-filter-dialog.h \
gimpdisplayshell-layer-select.c \
gimpdisplayshell-layer-select.h \
gimpdisplayshell-icon.c \
gimpdisplayshell-icon.h \
gimpdisplayshell-items.c \
gimpdisplayshell-items.h \
gimpdisplayshell-profile.c \

View File

@ -44,7 +44,6 @@
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-handlers.h"
#include "gimpdisplayshell-icon.h"
#include "gimpdisplayshell-render.h"
#include "gimpdisplayshell-scroll.h"
#include "gimpdisplayshell-scrollbars.h"
@ -632,7 +631,6 @@ gimp_display_set_image (GimpDisplay *display,
else
{
gimp_display_shell_title_update (shell);
gimp_display_shell_icon_update (shell);
}
}

View File

@ -60,7 +60,6 @@
#include "gimpdisplayshell-callbacks.h"
#include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-handlers.h"
#include "gimpdisplayshell-icon.h"
#include "gimpdisplayshell-profile.h"
#include "gimpdisplayshell-render.h"
#include "gimpdisplayshell-rulers.h"
@ -124,8 +123,6 @@ static void gimp_display_shell_sample_point_remove_handler(GimpImage *i
static void gimp_display_shell_sample_point_move_handler (GimpImage *image,
GimpSamplePoint *sample_point,
GimpDisplayShell *shell);
static void gimp_display_shell_invalidate_preview_handler (GimpImage *image,
GimpDisplayShell *shell);
static void gimp_display_shell_mode_changed_handler (GimpImage *image,
GimpDisplayShell *shell);
static void gimp_display_shell_precision_changed_handler (GimpImage *image,
@ -276,9 +273,6 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
gimp_display_shell_sample_point_add_handler (image, list->data, shell);
}
g_signal_connect (image, "invalidate-preview",
G_CALLBACK (gimp_display_shell_invalidate_preview_handler),
shell);
g_signal_connect (image, "mode-changed",
G_CALLBACK (gimp_display_shell_mode_changed_handler),
shell);
@ -395,7 +389,6 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
shell);
gimp_display_shell_active_vectors_handler (image, shell);
gimp_display_shell_invalidate_preview_handler (image, shell);
gimp_display_shell_quick_mask_changed_handler (image, shell);
gimp_display_shell_profile_changed_handler (GIMP_COLOR_MANAGED (image),
shell);
@ -441,8 +434,6 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
user_context = gimp_get_user_context (shell->display->gimp);
gimp_display_shell_icon_update_stop (shell);
gimp_canvas_layer_boundary_set_layers (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary),
NULL);
@ -526,9 +517,6 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
g_signal_handlers_disconnect_by_func (image,
gimp_display_shell_mode_changed_handler,
shell);
g_signal_handlers_disconnect_by_func (image,
gimp_display_shell_invalidate_preview_handler,
shell);
g_signal_handlers_disconnect_by_func (image,
gimp_display_shell_guide_add_handler,
@ -906,13 +894,6 @@ gimp_display_shell_size_changed_detailed_handler (GimpImage *image,
}
}
static void
gimp_display_shell_invalidate_preview_handler (GimpImage *image,
GimpDisplayShell *shell)
{
gimp_display_shell_icon_update (shell);
}
static void
gimp_display_shell_mode_changed_handler (GimpImage *image,
GimpDisplayShell *shell)

View File

@ -1,146 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gegl.h>
#include <gtk/gtk.h>
#include "display-types.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "widgets/gimpwidgets-utils.h"
#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-icon.h"
#define GIMP_DISPLAY_UPDATE_ICON_TIMEOUT 1000
static gboolean gimp_display_shell_icon_update_idle (gpointer data);
/* public functions */
void
gimp_display_shell_icon_update (GimpDisplayShell *shell)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
gimp_display_shell_icon_update_stop (shell);
if (gimp_display_get_image (shell->display))
shell->icon_idle_id = g_timeout_add_full (G_PRIORITY_LOW,
GIMP_DISPLAY_UPDATE_ICON_TIMEOUT,
gimp_display_shell_icon_update_idle,
shell,
NULL);
else
gimp_display_shell_icon_update_idle (shell);
}
void
gimp_display_shell_icon_update_stop (GimpDisplayShell *shell)
{
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
if (shell->icon_idle_id)
{
g_source_remove (shell->icon_idle_id);
shell->icon_idle_id = 0;
}
}
/* private functions */
static gboolean
gimp_display_shell_icon_update_idle (gpointer data)
{
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (data);
GimpImage *image = gimp_display_get_image (shell->display);
GdkPixbuf *icon = NULL;
shell->icon_idle_id = 0;
if (image)
{
Gimp *gimp = gimp_display_get_gimp (shell->display);
GdkPixbuf *pixbuf;
gint width;
gint height;
gint scale_factor;
gdouble factor = ((gdouble) gimp_image_get_height (image) /
(gdouble) gimp_image_get_width (image));
if (factor >= 1)
{
height = MAX (shell->icon_size, 1);
width = MAX (((gdouble) shell->icon_size) / factor, 1);
}
else
{
height = MAX (((gdouble) shell->icon_size) * factor, 1);
width = MAX (shell->icon_size, 1);
}
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (shell));
width *= scale_factor;
height *= scale_factor;
pixbuf = gimp_viewable_get_pixbuf (GIMP_VIEWABLE (image),
gimp_get_user_context (gimp),
width, height);
icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
shell->icon_size * scale_factor,
shell->icon_size * scale_factor);
memset (gdk_pixbuf_get_pixels (icon), 0,
gdk_pixbuf_get_height (icon) *
gdk_pixbuf_get_rowstride (icon));
gdk_pixbuf_copy_area (pixbuf, 0, 0, width, height,
icon,
0, shell->icon_size * scale_factor - height);
pixbuf = gimp_widget_load_icon (GTK_WIDGET (shell), "gimp-wilber-outline",
shell->icon_size_small);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
gdk_pixbuf_composite (pixbuf, icon,
shell->icon_size * scale_factor - width,
0, width, height,
shell->icon_size * scale_factor - width,
0.0, 1.0, 1.0,
GDK_INTERP_NEAREST, 255);
g_object_unref (pixbuf);
}
g_object_set (shell, "icon", icon, NULL);
if (icon)
g_object_unref (icon);
return FALSE;
}

View File

@ -1,26 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_DISPLAY_SHELL_ICON_H__
#define __GIMP_DISPLAY_SHELL_ICON_H__
void gimp_display_shell_icon_update (GimpDisplayShell *shell);
void gimp_display_shell_icon_update_stop (GimpDisplayShell *shell);
#endif /* __GIMP_DISPLAY_SHELL_ICON_H__ */

View File

@ -103,7 +103,6 @@ enum
PROP_UNIT,
PROP_TITLE,
PROP_STATUS,
PROP_ICON,
PROP_SHOW_ALL,
PROP_INFINITE_CANVAS
};
@ -289,11 +288,6 @@ gimp_display_shell_class_init (GimpDisplayShellClass *klass)
NULL,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_ICON,
g_param_spec_object ("icon", NULL, NULL,
GDK_TYPE_PIXBUF,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_SHOW_ALL,
g_param_spec_boolean ("show-all",
NULL, NULL,
@ -337,9 +331,6 @@ gimp_display_shell_init (GimpDisplayShell *shell)
gimp_display_shell_items_init (shell);
shell->icon_size = 128;
shell->icon_size_small = 96;
shell->cursor_handedness = GIMP_HANDEDNESS_RIGHT;
shell->current_cursor = (GimpCursorType) -1;
shell->tool_cursor = GIMP_TOOL_CURSOR_NONE;
@ -831,7 +822,6 @@ gimp_display_shell_finalize (GObject *object)
g_clear_object (&shell->no_image_options);
g_clear_pointer (&shell->title, g_free);
g_clear_pointer (&shell->status, g_free);
g_clear_object (&shell->icon);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -866,11 +856,6 @@ gimp_display_shell_set_property (GObject *object,
g_free (shell->status);
shell->status = g_value_dup_string (value);
break;
case PROP_ICON:
if (shell->icon)
g_object_unref (shell->icon);
shell->icon = g_value_dup_object (value);
break;
case PROP_SHOW_ALL:
gimp_display_shell_set_show_all (shell, g_value_get_boolean (value));
break;
@ -909,9 +894,6 @@ gimp_display_shell_get_property (GObject *object,
case PROP_STATUS:
g_value_set_string (value, shell->status);
break;
case PROP_ICON:
g_value_set_object (value, shell->icon);
break;
case PROP_SHOW_ALL:
g_value_set_boolean (value, shell->show_all);
break;

View File

@ -134,11 +134,6 @@ struct _GimpDisplayShell
gchar *title; /* current title */
gchar *status; /* current default statusbar content */
gint icon_size; /* size of the icon pixbuf */
gint icon_size_small; /* size of the icon's wilber pixbuf */
guint icon_idle_id; /* ID of the idle-function */
GdkPixbuf *icon; /* icon */
guint fill_idle_id; /* display_shell_fill() idle ID */
GimpHandedness cursor_handedness;/* Handedness for cursor display */

View File

@ -262,9 +262,6 @@ static void gimp_image_window_shell_rotated (GimpDisplayShell *she
static void gimp_image_window_shell_title_notify (GimpDisplayShell *shell,
const GParamSpec *pspec,
GimpImageWindow *window);
static void gimp_image_window_shell_icon_notify (GimpDisplayShell *shell,
const GParamSpec *pspec,
GimpImageWindow *window);
static GtkWidget *
gimp_image_window_create_tab_label (GimpImageWindow *window,
GimpDisplayShell *shell);
@ -2015,12 +2012,8 @@ gimp_image_window_switch_page (GtkNotebook *notebook,
g_signal_connect (private->active_shell, "notify::title",
G_CALLBACK (gimp_image_window_shell_title_notify),
window);
g_signal_connect (private->active_shell, "notify::icon",
G_CALLBACK (gimp_image_window_shell_icon_notify),
window);
gtk_window_set_title (GTK_WINDOW (window), shell->title);
gtk_window_set_icon (GTK_WINDOW (window), shell->icon);
gimp_display_shell_appearance_update (private->active_shell);
@ -2121,9 +2114,6 @@ gimp_image_window_disconnect_from_active_shell (GimpImageWindow *window)
g_signal_handlers_disconnect_by_func (private->active_shell,
gimp_image_window_shell_title_notify,
window);
g_signal_handlers_disconnect_by_func (private->active_shell,
gimp_image_window_shell_icon_notify,
window);
if (private->menubar_manager)
gimp_image_window_hide_tooltip (private->menubar_manager, window);
@ -2332,14 +2322,6 @@ gimp_image_window_shell_title_notify (GimpDisplayShell *shell,
gtk_window_set_title (GTK_WINDOW (window), shell->title);
}
static void
gimp_image_window_shell_icon_notify (GimpDisplayShell *shell,
const GParamSpec *pspec,
GimpImageWindow *window)
{
gtk_window_set_icon (GTK_WINDOW (window), shell->icon);
}
static void
gimp_image_window_shell_close_button_callback (GimpDisplayShell *shell)
{

View File

@ -62,7 +62,6 @@ libappdisplay_sources = [
'gimpdisplayshell-filter.c',
'gimpdisplayshell-grab.c',
'gimpdisplayshell-handlers.c',
'gimpdisplayshell-icon.c',
'gimpdisplayshell-items.c',
'gimpdisplayshell-layer-select.c',
'gimpdisplayshell-profile.c',

View File

@ -56,6 +56,7 @@ libgimpwidgetsincludedir = $(includedir)/gimp-$(GIMP_API_VERSION)/libgimpwidgets
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"LibGimpWidgets\" \
-DGIMP_WIDGETS_COMPILATION \
-DDATADIR=\""$(datadir)"\" \
-I$(top_srcdir) \
$(GEGL_CFLAGS) \
$(GTK_CFLAGS) \

View File

@ -65,7 +65,9 @@ gimp_widgets_init (GimpHelpFunc standard_help_func,
GimpGetColorFunc get_background_func,
GimpEnsureModulesFunc ensure_modules_func)
{
GtkIconTheme *icon_theme;
const gchar *svg_icon = DATADIR "/icons/hicolor/scalable/apps/gimp.svg";
GList *icons = NULL;
GdkPixbuf *pixbuf;
g_return_if_fail (standard_help_func != NULL);
@ -81,12 +83,75 @@ gimp_widgets_init (GimpHelpFunc standard_help_func,
gimp_icons_init ();
icon_theme = gtk_icon_theme_get_for_screen (gdk_screen_get_default ());
if (gtk_icon_theme_has_icon (icon_theme, GIMP_ICON_WILBER "-symbolic"))
gtk_window_set_default_icon_name (GIMP_ICON_WILBER "-symbolic");
/* Loading the application icons. Unfortunately GTK doesn't know how
* to load any size from a single SVG, so we have to generate common
* sizes ourselves.
* To be fair, it could with gtk_window_set_default_icon_name() but
* then the application icon is dependant to the theme and for now at
* least, we want the installed icon.
*/
pixbuf = gdk_pixbuf_new_from_file (DATADIR "/icons/hicolor/16x16/apps/gimp.png", NULL);
if (pixbuf)
icons = g_list_prepend (icons, pixbuf);
else
gtk_window_set_default_icon_name (GIMP_ICON_WILBER);
g_warning ("Application icon missing: %s", DATADIR "/icons/hicolor/16x16/apps/gimp.png");
pixbuf = gdk_pixbuf_new_from_file (DATADIR "/icons/hicolor/32x32/apps/gimp.png", NULL);
if (pixbuf)
icons = g_list_prepend (icons, pixbuf);
else
g_warning ("Application icon missing: %s", DATADIR "/icons/hicolor/32x32/apps/gimp.png");
pixbuf = gdk_pixbuf_new_from_file (DATADIR "/icons/hicolor/48x48/apps/gimp.png", NULL);
if (pixbuf)
icons = g_list_prepend (icons, pixbuf);
else
g_warning ("Application icon missing: %s", DATADIR "/icons/hicolor/48x48/apps/gimp.png");
pixbuf = gdk_pixbuf_new_from_file (DATADIR "/icons/hicolor/64x64/apps/gimp.png", NULL);
if (pixbuf)
icons = g_list_prepend (icons, pixbuf);
else
g_warning ("Application icon missing: %s", DATADIR "/icons/hicolor/64x64/apps/gimp.png");
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 128, 128, NULL);
if (pixbuf)
{
/* Various common sizes from the same SVG. Why I go into such
* exhaustive list of sizes is that nowadays desktops/OSes use
* quite big icon sizes and in some cases, when they don't find
* the right one, GTK may render quite ugly resized/skewed image.
*/
icons = g_list_prepend (icons, pixbuf);
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 144, 144, NULL);
icons = g_list_prepend (icons, pixbuf);
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 160, 160, NULL);
icons = g_list_prepend (icons, pixbuf);
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 176, 176, NULL);
icons = g_list_prepend (icons, pixbuf);
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 192, 192, NULL);
icons = g_list_prepend (icons, pixbuf);
pixbuf = gdk_pixbuf_new_from_file_at_size (svg_icon, 224, 224, NULL);
icons = g_list_prepend (icons, pixbuf);
}
else
{
g_warning ("Application icon missing: %s", svg_icon);
}
pixbuf = gdk_pixbuf_new_from_file (DATADIR "/icons/hicolor/256x256/apps/gimp.png", NULL);
if (pixbuf)
icons = g_list_prepend (icons, pixbuf);
else
g_warning ("Application icon missing: %s", DATADIR "/icons/hicolor/256x256/apps/gimp.png");
gtk_window_set_default_icon_list (icons);
g_list_free_full (icons, g_object_unref);
gimp_widgets_init_foreign_enums ();

View File

@ -189,7 +189,9 @@ libgimpwidgets = library('gimpwidgets-'+ gimp_api_version,
dependencies: [
gegl, gtk3, lcms, math
],
c_args: [ '-DG_LOG_DOMAIN="LibGimpWidgets"', '-DGIMP_WIDGETS_COMPILATION', ],
c_args: [ '-DG_LOG_DOMAIN="LibGimpWidgets"', '-DGIMP_WIDGETS_COMPILATION',
'-DDATADIR="@0@"'.format(prefix / get_option('datadir')),
],
link_with: [
libgimpbase,
libgimpcolor,