Source function in GLib.timeout_add() doesn't get called

I really need to ask a really curious question about the timeout_add() function in GLib (which is known as GLib.Functions.TimeoutAdd() in the C# bindings).

How does the source function inside of the TimeoutAdd not get called at all? And how does it get prevented from the source function inside of it being called?

The reason I ask, is because the project I’m currently working on needs a timer, but when I try to implement the TimeoutAdd(), it doesn’t work at all.

It lands on the break point when I set it, but it’s source function that I add in there, which in this case is PosTimerTick, doesn’t get called at all, not even once, I’ve even set break points in that method and it doesn’t even land on any of the break points, meaning that it doesn’t even enter into the function.

So I’m really curious, if there’s anything that completely blocks TimeoutAdd from being called? Is there anything?

I know that it’s only the project I’m working on that’s affected, and I’ve checked with other projects that have it implemented, and it has no problems, and I’ve even tried implementing the same function in the same way as those projects, but it doesn’t work.

So it’s really not making any sense as to why it’s not working.

And just to verify that it’s running in the same thread as the GUI, yes it is, and it’s supposed to anyways.

So is there anything at all that prevents a timeout_add source func from not even running once? I’m really really curious.

Here’s the code in VG Music Studio:

public void LetUIKnowPlayerIsPlaying()
    {
        // Prevents method from being used if timer is already active
        // if (_timer.Enabled)
        // {
        //     return;
        // }

        // Ensures a GlobalConfig Instance is created if one doesn't exist
        if (GlobalConfig.Instance == null)
        {
            GlobalConfig.Init(); // A new instance needs to be initialized before it can do anything
        }

        // Configures the buttons when player is playing a sequenced track
        _buttonPause.Sensitive = _buttonStop.Sensitive = true; // Setting the 'Sensitive' property to 'true' enables the buttons, allowing you to click on them
        _buttonPause.Label = Strings.PlayerPause;
        //GLib.Functions.TimeoutSourceNew((uint)(1_000.0 / GlobalConfig.Instance!.RefreshRate));
        GLib.Functions.TimeoutAdd(0, (uint)(1_000.0 / GlobalConfig.Instance!.RefreshRate), new GLib.SourceFunc(PosTimerTick));
        //GLib.Functions.TestTimerStart();
        // _timer.Interval = (int)(1_000.0 / GlobalConfig.Instance!.RefreshRate);
        // _timer.Start();
        Show();
    }
    private bool PosTimerTick()
    {
        if (Engine.Instance is not null)
        {
            if (_positionBarFree)
            {
                UpdatePositionIndicators(Engine.Instance!.Player.ElapsedTicks);
                return true;
            }
        }
        return false;
    }

And here’s the one from some other project that works:

private void OnPlayToggled(object sender, EventArgs args)
        {
            // play/pause audio
            if (Audio != null)
            {
                string statusText;

                // Do we play or pause?
                if (PlayButton.Active)
                {
                    Audio.Play();
                    PlayButton.SetIconName("media-playback-pause-symbolic");
                    statusText = $"Playing {LoadedFilename}";
                    GLib.Functions.TimeoutAdd(0, 50, new GLib.SourceFunc(CheckPlayback));        // 20x a second, nice and smooth
                }
                else
                {
                    Audio.Pause();
                    PlayButton.SetIconName("media-playback-start-symbolic");
                    statusText = $"Paused {LoadedFilename}";
                }

                // Update GUI
                StatusLabel.SetText(statusText);
            }
        }
private bool CheckPlayback()
        {
            // We need to have an audio file
            if (Audio == null)
                return false;

            if (Audio.IsPlaying)
            {
                if (!MovingPlaybackSlider)
                {
                    double playbackValue = Map(Audio.Cursor, 0, Audio.Duration.TotalSeconds, PlaybackSlider.Adjustment.Lower, PlaybackSlider.Adjustment.Upper);
                    PlaybackSlider.Adjustment.Value = playbackValue;
                }

                return true;
            }

            // If not, don't do anything
            PlayButton.Active = false;      // Un-toggle play
            return false;
        }

Thank you in advance!

You have to iterate a main context. See this tutorial.

Since you’re writing a GUI application, just use GtkApplication and call g_application_run().

I’m absolutely sure I’ve got g_application_run() equivalent in the main function, which is Gtk.Application.Run(argc, argv) in C#, as seen on _app.Run(args.Length + 1, argv), and is called near the very beginning of the application (and it has to, or it the application will exit without doing anything).

using Adw;
using System;

namespace Kermalis.VGMusicStudio.GTK4
{
	internal class Program
	{
		private static readonly Adw.Application _app = Application.New("org.Kermalis.VGMusicStudio.GTK4", Gio.ApplicationFlags.FlagsNone);

		[STAThread]
		public static int Main(string[] args)
		{
			_app.Register(Gio.Cancellable.GetCurrent());
			
			var win = new MainWindow(_app);

			_app.OnActivate += OnActivate;

			void OnActivate(Gio.Application sender, EventArgs e)
			{
				// Add Main Window
				_app.AddWindow(win);
			}

			var argv = new string[args.Length + 1];
			argv[0] = "Kermalis.VGMusicStudio.GTK4";
			args.CopyTo(argv, 1);
			return _app.Run(args.Length + 1, argv);
		}
	}
}

Do I need to add more g_application_run() in the application? I’m sure there’s something missing, but I don’t know what it is that I’m missing.

No, you only call it once. That should be all you need.

Thought so. But I’m really curious if there’s anything that can prevent a g_timeout_add() from starting? Because what I’m trying to do is get the Gtk.Scale to update on each interval of the g_timeout_add(), does it need anything else other than a g_timeout_add()?

Are you blocking the main loop in any other way? Like a busy loop somewhere?

Hi,

I never used gtk with C#, but according to this tutorial, the call should be something like:

GLib.Timeout.Add(50, new GLib.TimeoutHandler(CheckPlayback));

As I was debugging, I paused the debugger to see what the threads were doing, and here’s what they were doing:

Thread 0 in the call stack was on _app.run(args.Length + 1, argv), which is g_application_run():

Threads 1 and 3 are empty, but Thread 2 is on Thread.Sleep((int)(timeToWait * 1_000)), as seen here:

From what I can tell, GirCore (the C# binding I use) implements g_timeout_add() params as this:

public static uint TimeoutAdd(int priority, uint interval, SourceFunc function)

It has a priority, interval and the source function.

The way I used TimeoutAdd, was this:

GLib.Functions.TimeoutAdd(0, (uint)(1_000.0 / GlobalConfig.Instance!.RefreshRate), new GLib.SourceFunc(PosTimerTick));

I have actually tried implementing it as GLib.Functions.TimeoutAdd(0, 50, new GLib.SourceFunc(PosTimerTick)) previously, but still doesn’t operate.

Does the name of the source function have to be “CheckPlayback”? And does the source function have to have specific stuff in there in order for it to run through the source function?

This is how my source function is currently set up and doesn’t work:

private bool PosTimerTick()
    {
        if (Engine.Instance is not null)
        {
            if (_positionBarFree)
            {
                UpdatePositionIndicators(Engine.Instance!.Player.ElapsedTicks);
                return true;
            }
        }
        return false;
    }

So somehow the thread MP2K_Player.Tick (seen in the screenshot) is interfering with the main thread. I’m not exactly sure how it works, or how it’s preventing the main thread from running the GLib.TimeoutAdd source function. But is there any way I can make it work while some other thread is active? Or do I have to completely remove the thread that’s running the MP2K_Player?

That really doesn’t make sense. A secondary thread that is sleeping shouldn’t affect a main context that’s running on another thread.

At this point, you might want to try simplifying the problem by writing a minimal test program that reproduces your issue.

You’re certain the thread that’s iterating the default main context is not the thread that is calling MP2K_Player.Tick? Because that would be the most likely explanation here.

I even commented out the CreateThread() within the Player class (which MP2K_Player.Tick is called from). And the GLib.TimeoutAdd source function still doesn’t get called.

So I was wrong about MP2K_Player.Tick being the cause.

I’m not sure what else could be preventing it from being called. I’m still struggling to figure it out.

You should probably try and create a minimal reproducible example to eliminate other possibilities for the problem.

From your messages above it seems you’re not certain about the prototype for the TimeoutAdd function, so it’s possible the priority and interval arguments are being swapped around. Try and discount that possibility by getting TimeoutAdd working in a trivial program, to verify that the arguments are what you think they are.

Try changing the interval down to 0, which should cause it to fire on the next main context iteration.

Okay, I’ve found the issue, and it’s really not something anyone would really expect. It wasn’t within any of the code of my project. After I attempted to reproduce the issue, I found that the issue was due to having too many <ContentWithTargetPath> entries in my .csproj file.

I’m still really puzzled as to how this happens, because normally anything in a .csproj file shouldn’t interfere with any GLib Timeout functions.

Here’s the .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>

	<ItemGroup>
		<ProjectReference Include="..\VG Music Studio - Core\VG Music Studio - Core.csproj" />
	</ItemGroup>

	<ItemGroup>
		<ContentWithTargetPath Include="../VG Music Studio - Core/*.yaml">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/share/glib-2.0/**" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>../../../share/glib-2.0/%(RecursiveDir)/%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/share/glib-2.0/**" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>../../../share/glib-2.0/%(RecursiveDir)/%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\share\glib-2.0\**" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>..\..\..\share\glib-2.0\%(RecursiveDir)\%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libadwaita-1.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libadwaita-1.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libadwaita-1-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgtk-4.so.1" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgtk-4.1.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgtk-4-1.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libpangowin32-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libpangocairo-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libpangocairo-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libpango-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libadwaita-1.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libpango-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libharfbuzz.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libharfbuzz-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgdk_pixbuf-2.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgdk_pixbuf-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libcairo-gobject.2.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libcairo-gobject-2.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libcairo.so.2" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libcairo.2.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libcairo-2.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgraphene-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgraphene-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgraphene-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgio-2.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgio-2.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgio-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgobject-2.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgobject-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libglib-2.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libglib-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgmodule-2.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgmodule-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgtksourceview-5.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgtksourceview-5.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgtksourceview-5-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libharfbuzz-gobject.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libharfbuzz-gobject.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libharfbuzz-gobject-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgstreamer-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgstreamer-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgstreamer-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgstaudio-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgstaudio-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgstaudio-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgstbase-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgstbase-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgstbase-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgstpbutils-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgstpbutils-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgstpbutils-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libgstvideo-1.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/local/lib/libgstvideo-1.0.0.dylib" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="C:\msys64\mingw64\bin\libgstvideo-1.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>
		<ContentWithTargetPath Include="/usr/lib/x86_64-linux-gnu/libsoup-3.0.so.0" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
			<TargetPath>%(Filename)%(Extension)</TargetPath>
		</ContentWithTargetPath>

    <ContentWithTargetPath Include="C:/msys64/mingw64/bin/libfribidi-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <TargetPath>%(Filename)%(Extension)</TargetPath>
    </ContentWithTargetPath>
    <ContentWithTargetPath Include="C:/msys64/mingw64/bin/libglib-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <TargetPath>%(Filename)%(Extension)</TargetPath>
    </ContentWithTargetPath>
    <ContentWithTargetPath Include="C:/msys64/mingw64/bin/libgio-2.0-0.dll" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' ">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <TargetPath>%(Filename)%(Extension)</TargetPath>
    </ContentWithTargetPath>

... (Removed due to character limit in posts. Body is limited to 32000 characters)

   </ItemGroup>

</Project>

Could it be a bug in GLib? Could it be a bug in the CLR itself? Or could it be a bug with the .NET compiler? This is one of the most bizarre issues I’ve ever encountered. lol

GLib knows nothing about csproj files, so it’s either an issue in the language bindings, or the run time.