Skip to content

Commit bf9e2b6

Browse files
authored
Merge pull request #3 from devohmycode/0.1.1
feat: persist window state across sessions, migrate to .NET 10, and make CUDA backend configurable
2 parents 1fcd5c3 + cc826a5 commit bf9e2b6

11 files changed

Lines changed: 613 additions & 188 deletions

‎AcrylicSettingsWindow.xaml.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public sealed partial class AcrylicSettingsWindow : Window
1313
private bool _suppressChanges = true;
1414
private string _currentKind = "Base";
1515

16-
private DesktopAcrylicController? _acrylicController;
16+
private IDisposable? _acrylicController;
1717
private SystemBackdropConfiguration? _configSource;
1818

1919
private bool _isDragging;

‎AiManager.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace NoteUI;
99

1010
public class AiManager
1111
{
12+
1213
// ── Data models ──
1314

1415
public record ModelInfo(string Id, string Name);

‎AppSettings.cs‎

Lines changed: 216 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ public record BackdropSettings(
1414
string FallbackColor = "#000000",
1515
string Kind = "Base");
1616

17+
public record PersistedWindowState(
18+
string Type,
19+
string NoteId,
20+
int X,
21+
int Y,
22+
bool IsCompact = false);
23+
1724
public static class AppSettings
1825
{
1926
private static readonly string SettingsDir =
@@ -165,21 +172,42 @@ public static void SaveWebDavSettings(string url, string username, string passwo
165172
// ── Apply to any window ─────────────────────────────────────
166173

167174
public static void ApplyToWindow(Window window, BackdropSettings settings,
168-
ref DesktopAcrylicController? controller, ref SystemBackdropConfiguration? configSource)
175+
ref IDisposable? controller, ref SystemBackdropConfiguration? configSource)
169176
{
170177
controller?.Dispose();
171178
controller = null;
179+
configSource = null;
180+
window.SystemBackdrop = null;
181+
182+
if (settings.Type == "none")
183+
return;
172184

173-
if (settings.Type == "acrylic_custom")
185+
controller = CreateBackdropController(settings);
186+
if (controller is null)
187+
return;
188+
189+
configSource = new SystemBackdropConfiguration
174190
{
175-
window.SystemBackdrop = null;
191+
IsInputActive = true,
192+
Theme = SystemBackdropTheme.Default
193+
};
176194

177-
configSource = new SystemBackdropConfiguration();
178-
configSource.IsInputActive = true;
179-
if (window.Content is FrameworkElement fe)
180-
configSource.Theme = (SystemBackdropTheme)fe.ActualTheme;
195+
if (window.Content is FrameworkElement fe)
196+
configSource.Theme = (SystemBackdropTheme)fe.ActualTheme;
181197

182-
controller = new DesktopAcrylicController
198+
ConfigureBackdropController(
199+
controller,
200+
window.As<Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop>(),
201+
configSource);
202+
}
203+
204+
private static IDisposable? CreateBackdropController(BackdropSettings settings)
205+
{
206+
return settings.Type switch
207+
{
208+
"mica" when MicaController.IsSupported() => new MicaController(),
209+
"mica_alt" when MicaController.IsSupported() => new MicaController { Kind = MicaKind.BaseAlt },
210+
"acrylic_custom" when DesktopAcrylicController.IsSupported() => new DesktopAcrylicController
183211
{
184212
TintOpacity = (float)settings.TintOpacity,
185213
LuminosityOpacity = (float)settings.LuminosityOpacity,
@@ -188,22 +216,27 @@ public static void ApplyToWindow(Window window, BackdropSettings settings,
188216
Kind = settings.Kind == "Thin"
189217
? DesktopAcrylicKind.Thin
190218
: DesktopAcrylicKind.Base,
191-
};
219+
},
220+
_ when DesktopAcrylicController.IsSupported() => new DesktopAcrylicController(),
221+
_ => null
222+
};
223+
}
192224

193-
controller.AddSystemBackdropTarget(
194-
window.As<Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop>());
195-
controller.SetSystemBackdropConfiguration(configSource);
196-
}
197-
else
225+
private static void ConfigureBackdropController(
226+
IDisposable controller,
227+
Microsoft.UI.Composition.ICompositionSupportsSystemBackdrop target,
228+
SystemBackdropConfiguration config)
229+
{
230+
switch (controller)
198231
{
199-
configSource = null;
200-
window.SystemBackdrop = settings.Type switch
201-
{
202-
"mica" => new MicaBackdrop(),
203-
"mica_alt" => new MicaBackdrop { Kind = MicaKind.BaseAlt },
204-
"none" => null,
205-
_ => new DesktopAcrylicBackdrop()
206-
};
232+
case MicaController mica:
233+
mica.AddSystemBackdropTarget(target);
234+
mica.SetSystemBackdropConfiguration(config);
235+
break;
236+
case DesktopAcrylicController acrylic:
237+
acrylic.AddSystemBackdropTarget(target);
238+
acrylic.SetSystemBackdropConfiguration(config);
239+
break;
207240
}
208241
}
209242

@@ -268,6 +301,47 @@ public static string LoadThemeSetting()
268301
return "system";
269302
}
270303

304+
public static (int X, int Y)? LoadMainWindowPosition()
305+
{
306+
try
307+
{
308+
if (!File.Exists(SettingsPath))
309+
return null;
310+
311+
var json = File.ReadAllText(SettingsPath);
312+
var doc = JsonDocument.Parse(json);
313+
var root = doc.RootElement;
314+
if (root.TryGetProperty("mainWindowX", out var xProp) &&
315+
root.TryGetProperty("mainWindowY", out var yProp) &&
316+
xProp.TryGetInt32(out var x) &&
317+
yProp.TryGetInt32(out var y))
318+
{
319+
return (x, y);
320+
}
321+
}
322+
catch { }
323+
return null;
324+
}
325+
326+
public static bool LoadMainWindowCompact()
327+
{
328+
try
329+
{
330+
if (!File.Exists(SettingsPath))
331+
return false;
332+
333+
var json = File.ReadAllText(SettingsPath);
334+
var doc = JsonDocument.Parse(json);
335+
if (doc.RootElement.TryGetProperty("mainWindowCompact", out var compactProp) &&
336+
(compactProp.ValueKind == JsonValueKind.True || compactProp.ValueKind == JsonValueKind.False))
337+
{
338+
return compactProp.GetBoolean();
339+
}
340+
}
341+
catch { }
342+
return false;
343+
}
344+
271345
public static void SaveBackdropSettings(BackdropSettings settings)
272346
{
273347
MergeAndSaveSettings(new Dictionary<string, object>
@@ -286,6 +360,107 @@ public static void SaveThemeSetting(string theme)
286360
MergeAndSaveSettings(new Dictionary<string, object> { ["theme"] = theme });
287361
}
288362

363+
public static void SaveMainWindowPosition(Windows.Graphics.PointInt32 position)
364+
{
365+
MergeAndSaveSettings(new Dictionary<string, object>
366+
{
367+
["mainWindowX"] = position.X,
368+
["mainWindowY"] = position.Y
369+
});
370+
}
371+
372+
public static void SaveMainWindowCompact(bool isCompact)
373+
{
374+
MergeAndSaveSettings(new Dictionary<string, object>
375+
{
376+
["mainWindowCompact"] = isCompact
377+
});
378+
}
379+
380+
public static List<PersistedWindowState> LoadOpenWindows()
381+
{
382+
var result = new List<PersistedWindowState>();
383+
try
384+
{
385+
if (!File.Exists(SettingsPath))
386+
return result;
387+
388+
var json = File.ReadAllText(SettingsPath);
389+
var doc = JsonDocument.Parse(json);
390+
if (!doc.RootElement.TryGetProperty("openWindows", out var windowsProp))
391+
{
392+
return result;
393+
}
394+
395+
var arrayElement = windowsProp;
396+
JsonDocument? nestedDoc = null;
397+
if (windowsProp.ValueKind == JsonValueKind.String)
398+
{
399+
var raw = windowsProp.GetString();
400+
if (!string.IsNullOrWhiteSpace(raw))
401+
{
402+
nestedDoc = JsonDocument.Parse(raw);
403+
arrayElement = nestedDoc.RootElement;
404+
}
405+
}
406+
407+
if (arrayElement.ValueKind != JsonValueKind.Array)
408+
{
409+
nestedDoc?.Dispose();
410+
return result;
411+
}
412+
413+
foreach (var item in arrayElement.EnumerateArray())
414+
{
415+
if (item.ValueKind != JsonValueKind.Object)
416+
continue;
417+
418+
var type = item.TryGetProperty("type", out var typeProp)
419+
? typeProp.GetString() ?? ""
420+
: "";
421+
var noteId = item.TryGetProperty("noteId", out var noteIdProp)
422+
? noteIdProp.GetString() ?? ""
423+
: "";
424+
if (!item.TryGetProperty("x", out var xProp) ||
425+
!item.TryGetProperty("y", out var yProp) ||
426+
!xProp.TryGetInt32(out var x) ||
427+
!yProp.TryGetInt32(out var y) ||
428+
string.IsNullOrWhiteSpace(type))
429+
{
430+
continue;
431+
}
432+
433+
var isCompact =
434+
item.TryGetProperty("isCompact", out var compactProp) &&
435+
(compactProp.ValueKind == JsonValueKind.True || compactProp.ValueKind == JsonValueKind.False) &&
436+
compactProp.GetBoolean();
437+
438+
result.Add(new PersistedWindowState(type, noteId, x, y, isCompact));
439+
}
440+
441+
nestedDoc?.Dispose();
442+
}
443+
catch { }
444+
return result;
445+
}
446+
447+
public static void SaveOpenWindows(IEnumerable<PersistedWindowState> windows)
448+
{
449+
var payload = windows.Select(w => new Dictionary<string, object>
450+
{
451+
["type"] = w.Type,
452+
["noteId"] = w.NoteId,
453+
["x"] = w.X,
454+
["y"] = w.Y,
455+
["isCompact"] = w.IsCompact
456+
}).ToList();
457+
458+
MergeAndSaveSettings(new Dictionary<string, object>
459+
{
460+
["openWindows"] = payload
461+
});
462+
}
463+
289464
private static void MergeAndSaveSettings(Dictionary<string, object> newValues)
290465
{
291466
try
@@ -298,14 +473,7 @@ private static void MergeAndSaveSettings(Dictionary<string, object> newValues)
298473
foreach (var prop in doc.RootElement.EnumerateObject())
299474
{
300475
if (newValues.ContainsKey(prop.Name)) continue;
301-
existing[prop.Name] = prop.Value.ValueKind switch
302-
{
303-
JsonValueKind.Number => prop.Value.TryGetInt64(out var l) ? l : prop.Value.GetDouble(),
304-
JsonValueKind.String => prop.Value.GetString()!,
305-
JsonValueKind.True => true,
306-
JsonValueKind.False => false,
307-
_ => prop.Value.GetRawText()
308-
};
476+
existing[prop.Name] = ConvertJsonElement(prop.Value) ?? "";
309477
}
310478
}
311479

@@ -318,6 +486,24 @@ private static void MergeAndSaveSettings(Dictionary<string, object> newValues)
318486
catch { }
319487
}
320488

489+
private static object? ConvertJsonElement(JsonElement value)
490+
{
491+
return value.ValueKind switch
492+
{
493+
JsonValueKind.Object => value.EnumerateObject()
494+
.ToDictionary(p => p.Name, p => ConvertJsonElement(p.Value)),
495+
JsonValueKind.Array => value.EnumerateArray()
496+
.Select(ConvertJsonElement)
497+
.ToList(),
498+
JsonValueKind.String => value.GetString(),
499+
JsonValueKind.Number => value.TryGetInt64(out var l) ? l : value.GetDouble(),
500+
JsonValueKind.True => true,
501+
JsonValueKind.False => false,
502+
JsonValueKind.Null => null,
503+
_ => value.GetRawText()
504+
};
505+
}
506+
321507
public static Windows.UI.Color ParseColor(string hex)
322508
{
323509
hex = hex.TrimStart('#');

0 commit comments

Comments
 (0)