How do I make my symbolic icons theme-aware?

I’m trying to make my symbolic icons theme-aware, the icons show, but no matter how much I follow this guide on how to make them theme aware, they won’t change colour when the theme goes from light to dark. They will always stay the same colour.

There must be something wrong with my code or how I’ve implemented it. Is there anything else I need to do to make them theme aware?

Test Project.csproj:

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<Nullable>enable</Nullable>
		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="GirCore.Adw-1" Version="0.5.0" />
	</ItemGroup>

	<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
		<Exec Command="glib-compile-resources --sourcedir ./Properties ./Properties/org.resource.test.gresource.xml --target=$(OutDir)/org.resource.test.gresource" />
	</Target>

</Project>

Program.cs:

using Adw;
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;

namespace Kermalis.VGMusicStudio.GTK4
{
	class Program
	{
		public Program()
		{
		}

		static void OnActivate(object sender, EventArgs e)
		{
			var win = new TestWindow();
			win.SetApplication((Gtk.Application)sender);

			win.Present();
			win.Unref();
		}

		static void OnOpen(Gio.Application sender, Gio.Application.OpenSignalArgs args)
		{
			OnActivate(sender, args);
		}

		static int Main(string[] args)
		{
			var app = Adw.Application.New("org.resource.test", Gio.ApplicationFlags.FlagsNone);
			app.Register(Gio.Cancellable.GetCurrent());
			GLib.Functions.Setenv("GSK_RENDERER", "cairo", false);
			app.OnActivate += OnActivate;
			if (File.Exists(Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!) + "/org.resource.test.gresource"))
			{
				//Load file from program directory, required for `dotnet run`
				Gio.Functions.ResourcesRegister(Gio.Functions.ResourceLoad(Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!) + "/org.resource.test.gresource"));
			}
			else
			{
				var prefixes = new List<string> {
					Directory.GetParent(Directory.GetParent(Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!))!.FullName)!.FullName,
					Directory.GetParent(Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!))!.FullName,
					"/usr"
				};
				foreach (var prefix in prefixes)
				{
					if (File.Exists(prefix + "/share/org.resource.test/org.resource.test.gresource"))
					{
						Gio.Functions.ResourcesRegister(Gio.Functions.ResourceLoad(Path.GetFullPath(prefix + "/share/org.resource.test/org.resource.test.gresource")));
						break;
					}
				}
			}
			app.OnOpen += OnOpen;
			var stat = app.Run(args.Length, args);
			app.Unref();
			return stat;
		}
	}
}

TestWindow.cs:

public class TestWindow : Gtk.Window
{
    public TestWindow()
    {
        Title = "Test Window";
        DefaultWidth = 200;
        DefaultHeight = 200;
        Child = Gtk.Image.NewFromResource("/org/resource/test/icons/scalable/playlist/vgms-playlist-symbolic.svg");
    }
}

org.resource.test.gresource.xml:

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/org/resource/test/icons/scalable/playlist">
    <file preprocess="xml-stripblanks">vgms-song-symbolic.svg</file>
    <file preprocess="xml-stripblanks">vgms-playlist-symbolic.svg</file>
  </gresource>
</gresources>

vgms-playlist-symbolic.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" sodipodi:docname="playlist-symbolic.svg" inkscape:version="1.4 (e7c3feb100, 2024-10-09)">
    <sodipodi:namedview pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" inkscape:zoom="35.620504" inkscape:cx="6.8499873" inkscape:cy="8.7028527" inkscape:window-width="1247" inkscape:window-height="755" inkscape:window-x="532" inkscape:window-y="162" inkscape:window-maximized="0" inkscape:current-layer="svg1"/>
    <g stroke="#2e3335" stroke-linecap="round">
        <g fill="none">
            <path d="m 3.3813964 1.579921 l 9.8439656 0.01363 s 1.738361 0.052133 1.751982 1.9408047 c 0.01394 1.9302754 0.01244 9.1208763 0.01244 9.1208763 s 0.0303 1.783453 -1.965463 1.783453 c -1.790264 0 -9.7350092 -0.0054 -9.7350092 -0.0054 s -2.2484579 0.03662 -2.2388266 -2.203367 c 0.010207 -2.3716076 0.00246 -8.6847637 0.00246 -8.6847637 s 0.1329334 -1.9858936 2.3283235 -1.9652232 z" stroke-linejoin="round" sodipodi:nodetypes="ccscscsccc"/>
            <path d="m 7.5588912 4.2424777 l 4.7679348 -0.0106238" sodipodi:nodetypes="cc"/>
            <path d="m 7.55561 6.6495169 l 4.767935 -0.010627" sodipodi:nodetypes="cc" inkscape:label="path3"/>
            <path d="m 3.8236505 9.3167275 l 8.4670135 0.00585" sodipodi:nodetypes="cc" inkscape:label="path4"/>
            <path d="m 3.8280933 11.706394 l 8.4670127 0.0058" sodipodi:nodetypes="cc" inkscape:label="path5"/>
        </g>
        <path d="m 3.7585088 4.287589 l 1.6933562 1.1343826 l -1.6933562 1.1837058 z" stroke-linejoin="round" stroke-width="1.2" sodipodi:nodetypes="cccc" inkscape:label="path6"/>
    </g>
</svg>

vgms-song-symbolic.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="song-symbolic.svg">
    <sodipodi:namedview pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" inkscape:zoom="32" inkscape:cx="8.09375" inkscape:cy="4.71875" inkscape:window-width="1247" inkscape:window-height="1011" inkscape:window-x="176" inkscape:window-y="44" inkscape:window-maximized="0" inkscape:current-layer="svg1"/>
    <g transform="matrix(0.34811753 0 0 0.38216691 -4.316766 -3.558098)">
        <ellipse cx="25.206993" cy="42.452393" rx="11.39936" ry="7.802021"/>
        <path d="m 31.504207 13.374752 v 29.257776 l 5.071942 0.06804 l 0.09494 -29.308904 c 0.02086 -3.6253596 -5.120021 -3.6043596 -5.166858 -0.01691 z" sodipodi:nodetypes="cccccc"/>
        <path d="m 57.465771 24.277408 c -5.18302 3.555562 -6.933044 5.200634 -9.91802 -3.809235 c -2.591511 -7.822232 -12.691755 -7.42717 -12.691755 -7.42717 l 0.19935 10.666681 s 3.654692 -0.395062 6.644895 4.819758 c 2.990204 5.21482 6.194805 5.627537 9.103508 3.871609 c 4.319184 -2.607409 6.662022 -8.121643 6.662022 -8.121643 z" sodipodi:nodetypes="csccssc"/>
    </g>
</svg>

One thing to note is that I have also attempted using Symbolic Preview, but even that doesn’t work.

What am I doing wrong? There must be something I’m doing wrong.

Hi,

The theme recoloring only applies to icon images, so you have to use another API to make gtk understand it’s an icon:

        Child = Gtk.Image.NewFromIconName("vgms-playlist-symbolic");

The icons are automatically searched under the resource path /org/resource/test/icons/. However I’m not sure scalable/playlist is a valid subpath, try scalable/actions or scalable/places if that still doesn’t work.

Also, I remember I read somewhere that the icons only get their fill value recolored, not the stroke one, and your vgms-playlist-symbolic.svg doesn’t use fills but strokes only…

All the solutions fixed it! Well and truly! Not sure which one it was that fixed it, but it could’ve been all of them that fixed the issue. Now my symbolic icons are theme aware.

Thank you so much!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.