Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9557ebb
Add domain settings payload 1/4
KeyffMS Jul 26, 2026
5a8bb8a
Add domain settings payload segment 01.00
KeyffMS Jul 26, 2026
954cc89
Add domain settings payload segment 01.01
KeyffMS Jul 26, 2026
8e24437
Add domain settings payload segment 01.02
KeyffMS Jul 26, 2026
ee48055
Add domain settings payload segment 01.03
KeyffMS Jul 26, 2026
802f96d
Add domain settings payload segment 01.04
KeyffMS Jul 26, 2026
f2cd2f7
Add domain settings payload segment 02.00
KeyffMS Jul 26, 2026
7c778a8
Add domain settings payload segment 02.01
KeyffMS Jul 26, 2026
5b1fcb6
Add domain settings payload segment 02.02
KeyffMS Jul 26, 2026
42c6391
Add domain settings payload segment 02.03
KeyffMS Jul 26, 2026
a726ea4
Add domain settings payload segment 02.04
KeyffMS Jul 26, 2026
ee3c464
Add domain settings payload segment 03.00
KeyffMS Jul 26, 2026
7e92f2c
Add domain settings payload segment 03.01
KeyffMS Jul 26, 2026
178d181
Add domain settings payload segment 03.02
KeyffMS Jul 26, 2026
e0b75ae
Add domain settings payload segment 03.03
KeyffMS Jul 26, 2026
44ea6a4
Add domain settings payload segment 03.04
KeyffMS Jul 26, 2026
56f394c
Validate and publish domain settings refactor
KeyffMS Jul 26, 2026
801f3e6
Fix renamed test references in domain settings validation
KeyffMS Jul 26, 2026
a88b184
Centralize profile definitions and isolate settings persistence
github-actions[bot] Jul 26, 2026
e1259a5
Add temporary PR 71 source snapshot workflow
KeyffMS Jul 26, 2026
2c43d02
Finalize PR 71 terminology and validation
KeyffMS Jul 26, 2026
e990a21
Complete application-assignment terminology
github-actions[bot] Jul 26, 2026
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
29 changes: 16 additions & 13 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ CreateWorkingCopy
Domain-service mutation
SettingsStore.Save
SettingsNormalizer.Normalize
(explicit idempotent passes)
PersistedSettingsMapper.FromDomain
atomic file replacement
SettingsStore atomic file replacement
Current.ReplaceWith
Expand All @@ -58,9 +59,10 @@ A failed mutation or failed write does not replace committed settings and does n
|---|---|
| Settings transaction and published snapshots | `SettingsCoordinator` |
| Settings JSON persistence and atomic replacement | `SettingsStore` |
| Migration, scope canonicalization, normalization, recovery, and reference repair | `SettingsNormalizer` |
| Persisted JSON DTOs and legacy-field migration | `PersistedSettingsMapper` |
| Schema, profile, assignment and reference normalization | explicit `ISettingsNormalizationPass` implementations |
| Runtime use-case orchestration | `RuntimeCoordinator` |
| Application assignment mutations and overlay scope | `ApplicationProfileManagementService` |
| Application assignment mutations and overlay scope | `ApplicationAssignmentService` |
| Visual-profile lifecycle and tuning | `VisualProfileManagementService` |
| Automatic-mode mutation | `AutomaticModeManagementService` |
| Runtime mode, target, profile, suppression, and message | `ApplicationStateController` |
Expand All @@ -73,23 +75,24 @@ A failed mutation or failed write does not replace committed settings and does n
| Native call failure classification and diagnostics | `NativeCall` |
| Native target kind, rendering, geometry refresh, and transition grace | `MagnifierOverlay` |
| Notification-area presentation | `TrayPresenter` |
| Application-table presentation and edit mechanics | `ApplicationProfilesGrid` |
| Application-table presentation and edit mechanics | `ApplicationAssignmentsGrid` |
| Configuration use cases and dialogs | `ConfigurationForm` |
| Selector editing contract | `ModernSelectorEditingControl` |

## Sources of truth

| Data or rule | Source of truth |
|---|---|
| Persisted automatic mode, applications, assignments, scopes, and profiles | `SightAdaptSettings` committed through `SettingsCoordinator` |
| Persisted JSON shape and legacy compatibility | `PersistedSightAdaptSettings` and `PersistedSettingsMapper` |
| Committed automatic mode, assignments, scopes, and profiles | `SightAdaptSettings` committed through `SettingsCoordinator` |
| Runtime mode, target, active profile, suppression, and message | `ApplicationStateController.Current` |
| Actual overlay resource and target | `OverlayController` and active `MagnifierOverlay` |
| Per-application overlay scope | `ApplicationProfile.OverlayScopeId` |
| Optional native-menu profile reference and inheritance sentinel | `ApplicationProfile.MenuVisualProfileId` and `ApplicationMenuProfilePolicy` |
| Per-application overlay scope | `ApplicationAssignment.OverlayScopeId` |
| Optional native-menu profile reference and inheritance sentinel | `ApplicationAssignment.MenuVisualProfileId` and `ApplicationMenuProfilePolicy` |
| Scope enum values, canonical identifiers, aliases, default, and display names | `OverlayScopePolicy` definition table |
| Profile IDs, fallback, user-ID, and name rules | `VisualProfilePolicy` |
| Canonical profile values | `VisualProfileDefaults` |
| Supported transforms and tuning capability | `VisualTransformCatalog` |
| Built-in profile IDs, names, transforms, ordering, tuning capability and canonicalization | `VisualProfileCatalog` definition table |
| Assignment defaults, fallbacks, user-ID and user-name rules | `VisualProfilePolicy` |
| Canonical tuning values and numeric normalization | `VisualProfileDefaults` |
| Parameter ranges | `VisualProfileLimits` |
| Product name, version, milestone, repository, author, and license | project and assembly metadata exposed through `ProductInfo` |

Expand Down Expand Up @@ -136,7 +139,7 @@ Native menu detection, menu-overlay creation, and cross-filter refresh are subor

## Configuration grid boundary

`ApplicationProfilesGrid` owns columns, rows, selectors, status painting, selection, empty state, stable executable-path keys, separate typed change events, row updates, and failed-cell restoration. It does not know about persistence or dialogs.
`ApplicationAssignmentsGrid` owns columns, rows, selectors, status painting, selection, empty state, stable executable-path keys, separate typed change events, row updates, and failed-cell restoration. It does not know about persistence or dialogs.

`ConfigurationForm` resolves current committed assignments and translates typed grid events into domain-service mutations wrapped by `SettingsCoordinator.Commit`. It suppresses only its own synchronous full refresh during a grid-originated commit.

Expand Down
62 changes: 62 additions & 0 deletions src/SightAdapt/ApplicationAssignment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace SightAdapt;

internal sealed class ApplicationAssignment
{
public string DisplayName { get; set; } = string.Empty;

public string ExecutableName { get; set; } = string.Empty;

public string ExecutablePath { get; set; } = string.Empty;

public bool Enabled { get; set; } = true;

public string VisualProfileId { get; set; } =
VisualProfilePolicy.NewAssignmentProfileId;

public string? MenuVisualProfileId { get; set; }

private string _overlayScopeId =
OverlayScopePolicy.ToId(OverlayScopePolicy.Default);

public string OverlayScopeId
{
get => _overlayScopeId;
set => _overlayScopeId = value ?? string.Empty;
}

public OverlayScope OverlayScope =>
OverlayScopePolicy.ParseRequired(OverlayScopeId);

public ApplicationAssignment CreateWorkingCopy()
{
return new ApplicationAssignment
{
DisplayName = DisplayName,
ExecutableName = ExecutableName,
ExecutablePath = ExecutablePath,
Enabled = Enabled,
VisualProfileId = VisualProfileId,
MenuVisualProfileId = MenuVisualProfileId,
OverlayScopeId = OverlayScopeId,
};
}

public bool Matches(ApplicationIdentity identity)
{
ArgumentNullException.ThrowIfNull(identity);

if (!string.IsNullOrWhiteSpace(ExecutablePath) &&
!string.IsNullOrWhiteSpace(identity.ExecutablePath))
{
return string.Equals(
ExecutablePath,
identity.ExecutablePath,
StringComparison.OrdinalIgnoreCase);
}

return string.Equals(
ExecutableName,
identity.ExecutableName,
StringComparison.OrdinalIgnoreCase);
}
}
Loading