Merge branch 'win32_gtk4_set_icon_list' into 'main'

GdkWin32: implement surface's "icon_list" property setter

See merge request GNOME/gtk!6869
This commit is contained in:
Matthias Clasen
2024-02-17 14:06:10 +00:00
3 changed files with 104 additions and 10 deletions

View File

@@ -892,11 +892,11 @@ pixbuf_to_hicon (GdkPixbuf *pixbuf,
int x,
int y);
static GdkWin32HCursor *
gdk_win32hcursor_create_for_texture (GdkWin32Display *display,
GdkTexture *texture,
int x,
int y)
HICON
_gdk_win32_create_hicon_for_texture (GdkTexture *texture,
gboolean is_icon,
int x,
int y)
{
cairo_surface_t *surface;
GdkPixbuf *pixbuf;
@@ -906,13 +906,24 @@ gdk_win32hcursor_create_for_texture (GdkWin32Display *display,
surface = gdk_texture_download_surface (texture);
width = cairo_image_surface_get_width (surface);
height = cairo_image_surface_get_height (surface);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
icon = pixbuf_to_hicon (pixbuf, FALSE, x, y);
icon = pixbuf_to_hicon (pixbuf, is_icon, x, y);
g_object_unref (pixbuf);
return icon;
}
static GdkWin32HCursor *
gdk_win32hcursor_create_for_texture (GdkWin32Display *display,
GdkTexture *texture,
int x,
int y)
{
HICON icon = _gdk_win32_create_hicon_for_texture (texture, FALSE, x, y);
return gdk_win32_hcursor_new (display, (HCURSOR) icon, TRUE);
}

View File

@@ -211,6 +211,11 @@ Win32Cursor * win32_cursor_theme_get_cursor (Win32CursorTheme *theme,
void win32_cursor_theme_destroy (Win32CursorTheme *theme);
Win32CursorTheme *_gdk_win32_display_get_cursor_theme (GdkWin32Display *win32_display);
HICON _gdk_win32_create_hicon_for_texture (GdkTexture *texture,
gboolean is_icon,
int x,
int y);
gboolean _gdk_win32_display_has_pending (GdkDisplay *display);
void _gdk_win32_display_queue_events (GdkDisplay *display);

View File

@@ -4308,6 +4308,82 @@ gdk_win32_surface_set_shadow_width (GdkSurface *window,
impl->shadow_y = top + bottom;
}
static void
gdk_win32_surface_set_icon_list (GdkSurface *surface,
GList *textures)
{
GdkTexture *texture, *big_texture, *small_texture;
gint big_diff, small_diff;
gint big_w, big_h, small_w, small_h;
gint w, h;
gint dw, dh, diff;
HICON small_hicon, big_hicon;
GdkWin32Surface *impl;
if (GDK_SURFACE_DESTROYED (surface))
return;
impl = GDK_WIN32_SURFACE (surface);
/* ideal sizes for small and large icons */
big_w = GetSystemMetrics (SM_CXICON);
big_h = GetSystemMetrics (SM_CYICON);
small_w = GetSystemMetrics (SM_CXSMICON);
small_h = GetSystemMetrics (SM_CYSMICON);
/* find closest sized icons in the list */
big_texture = NULL;
small_texture = NULL;
big_diff = 0;
small_diff = 0;
while (textures)
{
texture = (GdkTexture*) textures->data;
w = gdk_texture_get_width (texture);
h = gdk_texture_get_height (texture);
dw = ABS (w - big_w);
dh = ABS (h - big_h);
diff = dw*dw + dh*dh;
if (big_texture == NULL || diff < big_diff)
{
big_texture = texture;
big_diff = diff;
}
dw = ABS (w - small_w);
dh = ABS (h - small_h);
diff = dw*dw + dh*dh;
if (small_texture == NULL || diff < small_diff)
{
small_texture = texture;
small_diff = diff;
}
textures = textures->next;
}
if (big_texture == NULL || small_texture == NULL)
return;
/* Create the icons */
big_hicon = big_texture ? _gdk_win32_create_hicon_for_texture (big_texture, TRUE, 0, 0) : NULL;
small_hicon = small_texture ? _gdk_win32_create_hicon_for_texture (small_texture, TRUE, 0, 0) : NULL;
/* Set the icons */
SendMessage (GDK_SURFACE_HWND (surface), WM_SETICON, ICON_BIG,
(LPARAM)big_hicon);
SendMessage (GDK_SURFACE_HWND (surface), WM_SETICON, ICON_SMALL,
(LPARAM)small_hicon);
/* Store the icons, destroying any previous icons */
if (impl->hicon_big)
GDI_CALL (DestroyIcon, (impl->hicon_big));
impl->hicon_big = big_hicon;
if (impl->hicon_small)
GDI_CALL (DestroyIcon, (impl->hicon_small));
impl->hicon_small = small_hicon;
}
double
_gdk_win32_surface_get_scale (GdkSurface *surface)
@@ -4738,6 +4814,8 @@ gdk_win32_toplevel_set_property (GObject *object,
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
gdk_win32_surface_set_icon_list (surface, g_value_get_pointer (value));
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
break;
case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED: