-
-
Notifications
You must be signed in to change notification settings - Fork 548
Avalonia migration #4214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
taooceros
wants to merge
43
commits into
dev
Choose a base branch
from
avalonia_migration
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+23,354
−1,955
Open
Avalonia migration #4214
Changes from 39 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
4120407
Add initial Avalonia UI project for migration
taooceros e961dc5
Wire up Avalonia UI to actual plugin system
taooceros 2079531
Fix MainWindow to use shared ViewModel from DI and add console logging
taooceros 065dc19
Add global hotkey support for Avalonia UI
taooceros f3d3f80
Add DynamicData sorting, result persistence, and Windows Shell icon l…
taooceros 2466b90
Fix UI blocking by running plugin queries on thread pool
taooceros 192eb4d
Add context menu support for results in Avalonia UI
taooceros 36e3530
Add internationalization support for Avalonia UI
taooceros 5d80816
Refactor i18n to be self-initializing via DI
taooceros c68a03e
Delay window show until plugins are initialized
taooceros ed668f3
Add glyph icon support for results
taooceros 29b2664
Improve glyph support and embed Segoe Fluent Icons
taooceros 0f9b932
Add hotkey recorder with manual modifier tracking
taooceros 8a99881
Add detailed Avalonia migration checklist
taooceros 1d94565
Expand GeneralSettingsPage with ~25 settings using FluentAvalonia Set…
taooceros 1209ca5
Fix flickering & add result highlighting
taooceros 0e1af22
Implement WPF plugin settings hosting in Avalonia
taooceros fb9721c
refactor: move history storage to infrastructure and implement WPF se…
taooceros dda5874
Migrate Program plugin settings to Avalonia and fix scroll issues
taooceros 19913fa
Fix OpenSettings command: ensure Main Window hides before showing Set…
taooceros 2b328e5
Fix OpenSettings command: ensure Main Window hides before showing Set…
taooceros 32aa3ff
Fix MainWindow visibility logic:
taooceros d9bfe49
Fix MainWindow startup visibility and OpenSettings logic
taooceros 0c2f026
Implement comprehensive Plugins Settings page in Avalonia
taooceros c0d1767
feat(avalonia): add Avalonia settings views for 8 plugins
taooceros 5e1411f
feat(avalonia): add Plugin Store settings page with virtualized grid
taooceros ae0bdbc
ci: trigger builds on draft PRs and add Avalonia artifact
taooceros 82390b5
ci: add Avalonia build processing to post_build script
taooceros e726c44
ci: add self-contained publish for Avalonia build
taooceros e337f9e
feat(explorer): add Avalonia ActionKeywordSetting dialog
taooceros 0681332
fix(explorer): complete Avalonia migration and fix action keyword cra…
shengkai16 8ee32df
fix(avalonia): fix localization keys in settings pages
shengkai16 8300235
fix(avalonia): fix enum translation in settings pages
shengkai16 9c99c7c
feat(avalonia): implement HighlightTextConverter with theme-aware sty…
shengkai16 c507bb9
chore(git): remove codemap files from tracking and add to gitignore
shengkai16 fbcd700
ci(github): add avalonia_migration branch to build triggers
shengkai16 c51c029
Merge branch 'dev' into avalonia_migration
shengkai16 5e1ec2b
fix(avalonia): update PluginManager API calls for Release build
shengkai16 54827a1
sk
shengkai16 0e90bc1
chore(avalonia): remove build cleanup targets and update lock file
b0dfd0b
feat(avalonia): implement preview hotkey setting and update migration…
45e2ce4
docs(avalonia): mark text highlighting as done in checklist
11eefa4
chore: upgrade from .NET 9 to .NET 10
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -304,4 +304,5 @@ Output-Performance.txt | |
|
|
||
| # vscode | ||
| .vscode | ||
| .history | ||
| .history**/codemap.md | ||
| .slim/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| # AGENTS.md - Flow.Launcher | ||
|
|
||
| Windows productivity launcher (like Alfred/Raycast) with dual UI frameworks: | ||
| - **WPF**: `Flow.Launcher/` (original) | ||
| - **Avalonia**: `Flow.Launcher.Avalonia/` (migration ~35-40%) | ||
| - **.NET 9.0** targeting `net9.0-windows10.0.19041.0` | ||
| - **CommunityToolkit.Mvvm** for MVVM | ||
|
|
||
| See `AVALONIA_MIGRATION_CHECKLIST.md` for migration progress. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| # Build | ||
| dotnet build | ||
| dotnet build -c Release | ||
| nuget restore | ||
|
|
||
| # Test (NUnit 4.x) | ||
| dotnet test | ||
| dotnet test --filter "FullyQualifiedName~FuzzyMatcherTest" | ||
| dotnet test --filter "Name~WhenSearching" | ||
|
|
||
| # Run | ||
| ./Output/Debug/Flow.Launcher.exe # WPF | ||
| ./Output/Debug/Avalonia/Flow.Launcher.Avalonia.exe # Avalonia | ||
| ``` | ||
|
|
||
| ## Code Style | ||
|
|
||
| ### Naming | ||
| - **PascalCase**: types, public members, methods, properties | ||
| - **camelCase**: locals, parameters | ||
| - **_camelCase**: private fields (underscore prefix) | ||
| - **PascalCase**: constants (per `.editorconfig`) | ||
| - No `this.` qualifier | ||
|
|
||
| ### C# Conventions | ||
| ```csharp | ||
| // File-scoped namespaces | ||
| namespace Flow.Launcher.ViewModel; | ||
|
|
||
| // Prefer var when type is apparent | ||
| var results = new List<Result>(); | ||
|
|
||
| // Allman braces, always required | ||
| if (condition) | ||
| { | ||
| DoSomething(); | ||
| } | ||
|
|
||
| // 4-space indent (code), 2-space (XML/XAML) | ||
| ``` | ||
|
|
||
| ### Imports | ||
| - Sort system directives first (`dotnet_sort_system_directives_first = true`) | ||
| - Using placement: outside namespace | ||
|
|
||
| ### Error Handling | ||
| - Use nullable reference types (enabled in Avalonia project) | ||
| - Prefer `is null` checks over reference equality | ||
| - Use null propagation and coalesce expressions | ||
|
|
||
| ### XAML (XamlStyler) | ||
| - One attribute per line (except ≤2) | ||
| - Space before closing slash: `<Element />` | ||
| - Attribute order: `x:Class` → `xmlns` → `x:Key/Name` → layout → size → margin/padding → others | ||
|
|
||
| **WPF**: `.xaml` with `xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"` | ||
| **Avalonia**: `.axaml` with `xmlns="https://github.com/avaloniaui"` | ||
|
|
||
| ## MVVM Patterns | ||
|
|
||
| ```csharp | ||
| // Avalonia: CommunityToolkit.Mvvm | ||
| public partial class MainViewModel : ObservableObject | ||
| { | ||
| [ObservableProperty] | ||
| private string _queryText = string.Empty; | ||
|
|
||
| [RelayCommand] | ||
| private void Search() { } | ||
| } | ||
|
|
||
| // WPF: BaseModel with manual INPC | ||
| public class MainViewModel : BaseModel | ||
| { | ||
| public string QueryText | ||
| { | ||
| get => _queryText; | ||
| set | ||
| { | ||
| if (_queryText != value) | ||
| { | ||
| _queryText = value; | ||
| OnPropertyChanged(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Plugin Architecture | ||
|
|
||
| ```csharp | ||
| public interface IAsyncPlugin | ||
| { | ||
| Task<List<Result>> QueryAsync(Query query, CancellationToken token); | ||
| Task InitAsync(PluginInitContext context); | ||
| } | ||
|
|
||
| // Result creation | ||
| new Result | ||
| { | ||
| Title = "Title", | ||
| SubTitle = "Subtitle", | ||
| IcoPath = "Images/icon.png", | ||
| Score = 100, | ||
| Action = context => true // return true to hide window | ||
| }; | ||
| ``` | ||
|
|
||
| ## Avalonia Migration Notes | ||
|
|
||
| | WPF | Avalonia | | ||
| |-----|----------| | ||
| | `.xaml` | `.axaml` | | ||
| | `Visibility` | `IsVisible` | | ||
| | `Collapsed` | Not available | | ||
| | `BoolToVisibilityConverter` | Direct bool binding | | ||
| | `xmlns:microsoft` | `xmlns:avaloniaui` | | ||
|
|
||
| Use `#if AVALONIA` for conditional compilation. | ||
|
|
||
| ## Testing | ||
|
|
||
| ```csharp | ||
| [TestFixture] | ||
| public class FuzzyMatcherTest | ||
| { | ||
| [Test] | ||
| public void WhenSearching_ThenReturnsExpectedResults() | ||
| { | ||
| var matcher = new StringMatcher(null); | ||
| var result = matcher.FuzzyMatch("chr", "Chrome"); | ||
| ClassicAssert.IsTrue(result.RawScore > 0); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Key Files | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `MainViewModel.cs` | Search window logic | | ||
| | `ResultsViewModel.cs` | Results management | | ||
| | `Settings.cs` | User settings | | ||
| | `PluginManager.cs` | Plugin lifecycle | | ||
| | `StringMatcher.cs` | Fuzzy search | | ||
| | `IPublicAPI.cs` | Plugin API | | ||
|
|
||
| ## Gotchas | ||
|
|
||
| 1. Build order matters - plugins must build before WPF | ||
| 2. Build kills running `Flow.Launcher.exe` automatically | ||
| 3. Plugins run in separate app domains | ||
| 4. Settings auto-save via Fody PropertyChanged | ||
| 5. Some tests require Windows Search service (`WSearch`) | ||
| 6. Avalonia has `<Nullable>enable</Nullable>`, WPF does not | ||
|
|
||
| ## Resources | ||
|
|
||
| - `.editorconfig` - C#/VB style rules | ||
| - `Settings.XamlStyler` - XAML formatting | ||
| - `Flow.Launcher.Plugin/README.md` - Plugin SDK docs | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: The gotchas list says plugins run in separate AppDomains, but the code loads plugins via AssemblyLoadContext in the same process. This mismatch can mislead contributors about isolation behavior; update the doc to reflect the actual loading model.
Prompt for AI agents