Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
- Initial Velopack release setup
- Removed `AutoStartOnStartup` from config
- Removed `RefreshPeriod` from the Weather section
- Made `FitMode` work
- Bundle in default wallpapers to work with the default config
- Bumped config schema to 3
- Fix windows notifications not working
4 changes: 2 additions & 2 deletions Canopy.Core/Canopy.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
<PackageReference Include="SolarCalculator" Version="3.6.1"/>
<PackageReference Include="StbImageSharp" Version="2.30.15"/>
<PackageReference Include="SynesthesiaDev.Codon.Codec" Version="2026.730.0"/>
<PackageReference Include="SynesthesiaDev.Synx.Codon" Version="2026.811.0"/>
<PackageReference Include="SynesthesiaDev.Synx.Codon" Version="2026.816.0" />
<PackageReference Include="SynesthesiaUtils" Version="2026.804.0"/>
<PackageReference Include="Vanara.PInvoke.Shell32" Version="5.0.5" />
<PackageReference Include="Velopack" Version="1.2.110-ge826545" />
</ItemGroup>

Expand All @@ -29,7 +30,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Extensions\"/>
<Folder Include="Resources\"/>
</ItemGroup>

Expand Down
3 changes: 3 additions & 0 deletions Canopy.Core/Canopy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ public void Initialize()
{
using var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(CurrentConfig.General.RefreshPeriod));
while (await timer.WaitForNextTickAsync())
{
Refresh();
await Updater.CheckForUpdates(this);
}
});

Platform.InitializeTray(this);
Expand Down
19 changes: 17 additions & 2 deletions Canopy.Core/Configuration/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

using Codon.Codec;
using Codon.Codec.Versioned;
using Synesthesia.Utils.Extensions;
using SynesthesiaDev.Synx;
using SynesthesiaDev.Synx.Codon;
using SynesthesiaDev.Synx.Types;

namespace Canopy.Configuration;
Expand Down Expand Up @@ -41,7 +44,7 @@ List<Wallpaper> Wallpapers

public static readonly VersionedStructCodec<Config> VERSIONED_CODEC = new VersionedStructCodec<Config>
{
CurrentSchemaVersion = 2,
CurrentSchemaVersion = 3,
InnerCodec = CODEC,
SchemaMigrationRegistry = SchemaMigrationRegistry.Builder().For<ISynxElement>(builder =>
{
Expand All @@ -50,12 +53,24 @@ List<Wallpaper> Wallpapers
output.Put(transcoder.EncodeString("_schema"), transcoder.EncodeString(DEFAULT._schema));
Canopy.ConfigMigrated = true;
});

builder.Add(2, (transcoder, _, output) =>
{
output.Put(transcoder.EncodeString("ChangeSystemThemesDependingOnTime"), transcoder.EncodeBool(DEFAULT.System.ChangeSystemThemesDependingOnTime));
Canopy.ConfigMigrated = true;
});

builder.Add(3, (transcoder, input, output) =>
{
var updaterConfig = UpdaterConfig.CODEC.Decode(SynxTranscoder.INSTANCE, input.GetValue("Updater").Object());
if (updaterConfig.Source.EndsWith("releases/") || updaterConfig.Source.EndsWith("releases"))
{
updaterConfig = updaterConfig with { Source = updaterConfig.Source.RemoveSuffix("releases/".RemoveSuffix("releases")) };
output.Put("Updater", UpdaterConfig.CODEC.Encode(SynxTranscoder.INSTANCE, updaterConfig));
}

Canopy.ConfigMigrated = true;
});
})
};

}
6 changes: 2 additions & 4 deletions Canopy.Core/Configuration/GeneralConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
namespace Canopy.Configuration;

public record GeneralConfig(
bool AutoStartOnStartup,
int RefreshPeriod,
Wallpaper.FitMode FitMode,
bool UseSolarNoonAsMidday
)
{
public static readonly GeneralConfig DEFAULT = new GeneralConfig(true, 60_000, Wallpaper.FitMode.Fill, true);
public static readonly GeneralConfig DEFAULT = new GeneralConfig( 60_000, Wallpaper.FitMode.Fill, true);

public static readonly StructCodec<GeneralConfig> CODEC = StructCodec.For<GeneralConfig>()
.Field("AutoStartOnStartup", Codecs.BOOLEAN, g => g.AutoStartOnStartup)
.Field("RefreshPeriod", Codecs.INT, g => g.RefreshPeriod)
.Field("FitMode", Codecs.Enum<Wallpaper.FitMode>(), g => g.FitMode)
.Field("UseSolarNoonAsMidday", Codecs.BOOLEAN, g => g.UseSolarNoonAsMidday)
.Build((autoStart, refresh, fitMode, noon) => new GeneralConfig(autoStart, refresh, fitMode, noon));
.Build((refresh, fitMode, noon) => new GeneralConfig(refresh, fitMode, noon));
}
2 changes: 1 addition & 1 deletion Canopy.Core/Configuration/UpdaterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Canopy.Configuration;
public record UpdaterConfig(UpdaterConfig.Release ReleaseStream, bool AutoUpdate, string Source)
{

public static readonly UpdaterConfig DEFAULT = new UpdaterConfig(Release.Release, true, "https://github.com/SynesthesiaDev/Canopy/releases");
public static readonly UpdaterConfig DEFAULT = new UpdaterConfig(Release.Release, true, "https://github.com/SynesthesiaDev/Canopy");

public static readonly StructCodec<UpdaterConfig> CODEC = StructCodec.For<UpdaterConfig>()
.Field("ReleaseStream", Codecs.Enum<Release>(), u => u.ReleaseStream)
Expand Down
10 changes: 0 additions & 10 deletions Canopy.Core/Configuration/Wallpaper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,3 @@ public enum FitMode

public override string ToString() => $"Wallpaper(Path={Path}, Time={Time.ToListString()}, Weather={Weather.ToListString()}, Season={Season.ToListString()}, Holiday={Holiday}, Accent={Accent})";
}


// public record Wallpaper(
// string Path,
// List<TimeOfDay> Time,
// List<WeatherType> Weather,
// List<SeasonType> Season,
// Holiday? Holiday = null,
// string? Accent = null
// )
6 changes: 2 additions & 4 deletions Canopy.Core/Configuration/WeatherConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ namespace Canopy.Configuration;

public record WeatherConfig(
bool UseAutoLocation,
int RefreshInterval,
WeatherConfig.OfflineMode OfflineFallback,
WeatherConfig.ManualCoordinates? Coordinates
)
{
public static readonly WeatherConfig DEFAULT = new WeatherConfig(true, 60_000, OfflineMode.UseLastKnownState, new ManualCoordinates(Latitude: 50.087555, Longitude: 14.421194));
public static readonly WeatherConfig DEFAULT = new WeatherConfig(true, OfflineMode.UseLastKnownState, new ManualCoordinates(Latitude: 50.087555, Longitude: 14.421194));

public static readonly StructCodec<WeatherConfig> CODEC = StructCodec.For<WeatherConfig>()
.Field("UseAutoLocation", Codecs.BOOLEAN, w => w.UseAutoLocation)
.Field("RefreshInterval", Codecs.INT, w => w.RefreshInterval)
.Field("OfflineFallback", Codecs.Enum<OfflineMode>(), w => w.OfflineFallback)
.Field("Coordinates", ManualCoordinates.CODEC.Optional(), w => w.Coordinates.ToOptional())
.Build((b, i, arg3, arg4) => new WeatherConfig(b, i, arg3, arg4.Value));
.Build((b, arg3, arg4) => new WeatherConfig(b, arg3, arg4.Value));

public enum OfflineMode
{
Expand Down
4 changes: 3 additions & 1 deletion Canopy.Windows/CanopyPlatformWindows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Canopy.Windows.Extensions;
using H.NotifyIcon.Core;
using Microsoft.Win32;
using Serilog;
Expand All @@ -30,7 +31,7 @@
var tempPath = Path.Combine(Path.GetTempPath(), $"canopy-wallpaper-{Guid.NewGuid().ToString()}.bpm");
File.WriteAllBytes(tempPath, convertToBmp(File.ReadAllBytes(path)));

var result = SystemParametersInfo

Check warning on line 34 in Canopy.Windows/CanopyPlatformWindows.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'User32.SystemParametersInfo(User32.SPI, uint, string, User32.SPIF)' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
(
SPI.SPI_SETDESKWALLPAPER,
0,
Expand All @@ -52,14 +53,15 @@
try
{
wallpaper.SetWallpaper(null, path);
wallpaper.SetPosition(Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_FILL);
wallpaper.SetPosition(Canopy.CurrentConfig.General.FitMode.ToShellPos());

Check warning on line 56 in Canopy.Windows/CanopyPlatformWindows.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.IDesktopWallpaper.SetPosition(Shell32.DESKTOP_WALLPAPER_POSITION)' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
}
finally
{
Marshal.ReleaseComObject(wallpaper);
}
}


public void SetTheme(ICanopyPlatform.Theme theme)
{
var useLightTheme = (theme == ICanopyPlatform.Theme.Light).ToInt();
Expand Down
24 changes: 24 additions & 0 deletions Canopy.Windows/Extensions/FitModeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2026 SynesthesiaDev <synesthesiadev@proton.me>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using Canopy.Configuration;
using Vanara.PInvoke;

namespace Canopy.Windows.Extensions;

public static class FitModeExtensions
{
public static Shell32.DESKTOP_WALLPAPER_POSITION ToShellPos(this Wallpaper.FitMode fitMode)
{
return fitMode switch
{
Wallpaper.FitMode.Fill => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_FILL,

Check warning on line 15 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_FILL' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
Wallpaper.FitMode.Fit => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_FIT,

Check warning on line 16 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_FIT' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
Wallpaper.FitMode.Stretch => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_STRETCH,

Check warning on line 17 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_STRETCH' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
Wallpaper.FitMode.Tile => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_TILE,

Check warning on line 18 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_TILE' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
Wallpaper.FitMode.Center => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_CENTER,

Check warning on line 19 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_CENTER' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
Wallpaper.FitMode.Span => Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_SPAN,

Check warning on line 20 in Canopy.Windows/Extensions/FitModeExtensions.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Shell32.DESKTOP_WALLPAPER_POSITION.DWPOS_SPAN' is only supported on: 'windows'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
_ => throw new ArgumentOutOfRangeException(nameof(fitMode), fitMode, null)
};
}
}
13 changes: 4 additions & 9 deletions schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ Below are all schemas related to the config file.

## General

- `AutoStartOnStartup`
- Automatically start Canopy when system starts up
- Type: `Boolean`

- `RefreshPeriod`
- Interval at which Canopy will check current conditions and potentially apply new wallpaper _(Keep in mind, the API limit for weather api is 10,000 requests a day!)_
- Type: `Int`
Expand Down Expand Up @@ -147,27 +143,27 @@ Following are the schemas for messages Canopy sends over the websocket as JSON:
# Default Config File

```hocon
_schemaVersion = 1
_schemaVersion = 3
_schema = "https://github.com/SynesthesiaDev/Canopy/blob/main/schema.md"
General = {
AutoStartOnStartup = true
RefreshPeriod = 60000
FitMode = "Fill"
UseSolarNoonAsMidday = true
}
System = {
UseLegacyWindowsApi = false
ApplyToAllMacOsSpaces = true
UpdateLockScreen = false
DontUpdateWhenBatteryLow = true
ChangeSystemThemesDependingOnTime = false
}
Updater = {
ReleaseStream = "Release"
AutoUpdate = true
Source = "https://github.com/SynesthesiaDev/Canopy/releases"
Source = "https://github.com/SynesthesiaDev/Canopy"
}
Weather = {
UseAutoLocation = true
RefreshInterval = 60000
OfflineFallback = "UseLastKnownState"
Coordinates = {
Longitude = 14.421194
Expand Down Expand Up @@ -308,5 +304,4 @@ Wallpapers = [
Accent = "#1b2836"
}
]

```
Loading