Skip to content

Commit 225d002

Browse files
Merge branch 'FixProgramUID' of https://github.com/VictoriousRaptor/Flow.Launcher into FixProgramUID
2 parents 2f5789f + c8b80f4 commit 225d002

File tree

9 files changed

+393
-395
lines changed

9 files changed

+393
-395
lines changed

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public string Language
5252
public double SettingWindowHeight { get; set; } = 700;
5353
public double SettingWindowTop { get; set; }
5454
public double SettingWindowLeft { get; set; }
55+
public System.Windows.WindowState SettingWindowState { get; set; } = WindowState.Normal;
5556

5657
public int CustomExplorerIndex { get; set; } = 0;
5758

Flow.Launcher/Flow.Launcher.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
</PackageReference>
9999
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
100100
<PackageReference Include="SharpVectors" Version="1.7.6" />
101+
<PackageReference Include="VirtualizingWrapPanel" Version="1.5.7" />
101102
</ItemGroup>
102103

103104
<ItemGroup>
@@ -120,7 +121,7 @@
120121
<!-- Work around https://github.com/dotnet/wpf/issues/6792 -->
121122

122123
<ItemGroup>
123-
<FilteredAnalyzer Include="@(Analyzer->Distinct())" />
124+
<FilteredAnalyzer Include="@(Analyzer-&gt;Distinct())" />
124125
<Analyzer Remove="@(Analyzer)" />
125126
<Analyzer Include="@(FilteredAnalyzer)" />
126127
</ItemGroup>

Flow.Launcher/Resources/Dark.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
<SolidColorBrush x:Key="CustomContextDisabled" Color="#868686" />
7070
<SolidColorBrush x:Key="ContextSeparator" Color="#3c3c3c" />
7171

72+
<SolidColorBrush x:Key="HoverStoreGrid2">#272727</SolidColorBrush>
73+
7274
<Color x:Key="Color01">#202020</Color>
7375
<Color x:Key="Color02">#2b2b2b</Color>
7476
<Color x:Key="Color03">#1d1d1d</Color>

Flow.Launcher/Resources/Light.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
<SolidColorBrush x:Key="CustomContextDisabled" Color="#868686" />
6363
<SolidColorBrush x:Key="ContextSeparator" Color="#dadada" />
6464

65+
<SolidColorBrush x:Key="HoverStoreGrid2">#f6f6f6</SolidColorBrush>
66+
6567
<Color x:Key="Color01">#f3f3f3</Color>
6668
<Color x:Key="Color02">#ffffff</Color>
6769
<Color x:Key="Color03">#e5e5e5</Color>

Flow.Launcher/SettingWindow.xaml

Lines changed: 251 additions & 323 deletions
Large diffs are not rendered by default.

Flow.Launcher/SettingWindow.xaml.cs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@
88
using Flow.Launcher.Plugin.SharedCommands;
99
using Flow.Launcher.ViewModel;
1010
using ModernWpf;
11+
using ModernWpf.Controls;
1112
using System;
13+
using System.Drawing.Printing;
1214
using System.IO;
1315
using System.Windows;
16+
using System.Windows.Controls.Primitives;
1417
using System.Windows.Data;
1518
using System.Windows.Forms;
1619
using System.Windows.Input;
1720
using System.Windows.Interop;
21+
using System.Windows.Media;
1822
using System.Windows.Navigation;
23+
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
1924
using Button = System.Windows.Controls.Button;
2025
using Control = System.Windows.Controls.Control;
2126
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
@@ -39,10 +44,6 @@ public SettingWindow(IPublicAPI api, SettingWindowViewModel viewModel)
3944
API = api;
4045
InitializePosition();
4146
InitializeComponent();
42-
43-
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(StoreListBox.ItemsSource);
44-
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Category");
45-
view.GroupDescriptions.Add(groupDescription);
4647
}
4748

4849
#region General
@@ -252,6 +253,7 @@ private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
252253

253254
private void OnClosed(object sender, EventArgs e)
254255
{
256+
settings.SettingWindowState = WindowState;
255257
settings.SettingWindowTop = Top;
256258
settings.SettingWindowLeft = Left;
257259
viewModel.Save();
@@ -296,17 +298,35 @@ private void ClearLogFolder(object sender, RoutedEventArgs e)
296298
}
297299
}
298300

299-
private void OnPluginStoreRefreshClick(object sender, RoutedEventArgs e)
301+
private static T FindParent<T>(DependencyObject child) where T : DependencyObject
300302
{
301-
_ = viewModel.RefreshExternalPluginsAsync();
302-
}
303+
//get parent item
304+
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
303305

306+
//we've reached the end of the tree
307+
if (parentObject == null) return null;
308+
309+
//check if the parent matches the type we're looking for
310+
T parent = parentObject as T;
311+
if (parent != null)
312+
return parent;
313+
else
314+
return FindParent<T>(parentObject);
315+
}
316+
304317
private void OnExternalPluginInstallClick(object sender, RoutedEventArgs e)
305318
{
306-
if (sender is Button { DataContext: PluginStoreItemViewModel plugin })
319+
if (sender is not Button { DataContext: PluginStoreItemViewModel plugin } button)
307320
{
308-
viewModel.DisplayPluginQuery($"install {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"));
321+
return;
309322
}
323+
324+
if (storeClickedButton != null)
325+
{
326+
FlyoutService.GetFlyout(storeClickedButton).Hide();
327+
}
328+
329+
viewModel.DisplayPluginQuery($"install {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"));
310330
}
311331

312332
private void OnExternalPluginUninstallClick(object sender, MouseButtonEventArgs e)
@@ -317,18 +337,30 @@ private void OnExternalPluginUninstallClick(object sender, MouseButtonEventArgs
317337
viewModel.DisplayPluginQuery($"uninstall {name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"));
318338
}
319339

340+
320341
}
321342

322343
private void OnExternalPluginUninstallClick(object sender, RoutedEventArgs e)
323344
{
345+
if (storeClickedButton != null)
346+
{
347+
FlyoutService.GetFlyout(storeClickedButton).Hide();
348+
}
349+
324350
if (sender is Button { DataContext: PluginStoreItemViewModel plugin })
325351
viewModel.DisplayPluginQuery($"uninstall {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"));
352+
326353
}
327354

328355
private void OnExternalPluginUpdateClick(object sender, RoutedEventArgs e)
329356
{
357+
if (storeClickedButton != null)
358+
{
359+
FlyoutService.GetFlyout(storeClickedButton).Hide();
360+
}
330361
if (sender is Button { DataContext: PluginStoreItemViewModel plugin })
331362
viewModel.DisplayPluginQuery($"update {plugin.Name}", PluginManager.GetPluginForId("9f8f9b14-2518-4907-b211-35ab6290dee7"));
363+
332364
}
333365

334366
private void window_MouseDown(object sender, MouseButtonEventArgs e) /* for close hotkey popup */
@@ -522,6 +554,7 @@ public void InitializePosition()
522554
Top = WindowTop();
523555
Left = WindowLeft();
524556
}
557+
WindowState = settings.SettingWindowState;
525558
}
526559
public double WindowLeft()
527560
{
@@ -541,5 +574,21 @@ public double WindowTop()
541574
return top;
542575
}
543576

577+
private Button storeClickedButton;
578+
579+
private void StoreListItem_Click(object sender, RoutedEventArgs e)
580+
{
581+
if (sender is not Button button)
582+
return;
583+
584+
storeClickedButton = button;
585+
586+
var flyout = FlyoutService.GetFlyout(button);
587+
flyout.Closed += (_, _) =>
588+
{
589+
storeClickedButton = null;
590+
};
591+
592+
}
544593
}
545594
}

Flow.Launcher/ViewModel/SettingWindowViewModel.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
using Flow.Launcher.Plugin;
2121
using Flow.Launcher.Plugin.SharedModels;
2222
using System.Collections.ObjectModel;
23+
using CommunityToolkit.Mvvm.Input;
2324

2425
namespace Flow.Launcher.ViewModel
2526
{
26-
public class SettingWindowViewModel : BaseModel
27+
public partial class SettingWindowViewModel : BaseModel
2728
{
2829
private readonly Updater _updater;
2930
private readonly IPortable _portable;
@@ -330,7 +331,8 @@ public Control SettingProvider
330331
}
331332
}
332333

333-
public async Task RefreshExternalPluginsAsync()
334+
[RelayCommand]
335+
private async Task RefreshExternalPluginsAsync()
334336
{
335337
await PluginsManifest.UpdateManifestAsync();
336338
OnPropertyChanged(nameof(ExternalPlugins));
@@ -535,6 +537,8 @@ public Brush PreviewBackground
535537
var bitmap = new BitmapImage();
536538
bitmap.BeginInit();
537539
bitmap.StreamSource = memStream;
540+
bitmap.DecodePixelWidth = 800;
541+
bitmap.DecodePixelHeight = 600;
538542
bitmap.EndInit();
539543
var brush = new ImageBrush(bitmap)
540544
{

Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs

Lines changed: 64 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -579,92 +579,97 @@ internal string LogoPathFromUri(string uri)
579579
// windows 8.1 https://msdn.microsoft.com/en-us/library/windows/apps/hh965372.aspx#target_size
580580
// windows 8 https://msdn.microsoft.com/en-us/library/windows/apps/br211475.aspx
581581

582-
string path;
583-
if (uri.Contains("\\"))
584-
{
585-
path = Path.Combine(Package.Location, uri);
586-
}
587-
else
582+
string path = Path.Combine(Package.Location, uri);
583+
584+
var logoPath = TryToFindLogo(uri, path);
585+
if (String.IsNullOrEmpty(logoPath))
588586
{
587+
// TODO: Don't know why, just keep it at the moment
588+
// Maybe on older version of Windows 10?
589589
// for C:\Windows\MiracastView etc
590-
path = Path.Combine(Package.Location, "Assets", uri);
590+
return TryToFindLogo(uri, Path.Combine(Package.Location, "Assets", uri));
591591
}
592+
return logoPath;
592593

593-
var extension = Path.GetExtension(path);
594-
if (extension != null)
594+
string TryToFindLogo(string uri, string path)
595595
{
596-
var end = path.Length - extension.Length;
597-
var prefix = path.Substring(0, end);
598-
var paths = new List<string>
596+
var extension = Path.GetExtension(path);
597+
if (extension != null)
599598
{
600-
path
601-
};
602-
603-
var scaleFactors = new Dictionary<PackageVersion, List<int>>
604-
{
605-
// scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables,
599+
//if (File.Exists(path))
600+
//{
601+
// return path; // shortcut, avoid enumerating files
602+
//}
603+
604+
var logoNamePrefix = Path.GetFileNameWithoutExtension(uri); // e.g Square44x44
605+
var logoDir = Path.GetDirectoryName(path); // e.g ..\..\Assets
606+
if (String.IsNullOrEmpty(logoNamePrefix) || String.IsNullOrEmpty(logoDir) || !Directory.Exists(logoDir))
606607
{
607-
PackageVersion.Windows10, new List<int>
608-
{
609-
100,
610-
125,
611-
150,
612-
200,
613-
400
614-
}
615-
},
616-
{
617-
PackageVersion.Windows81, new List<int>
618-
{
619-
100,
620-
120,
621-
140,
622-
160,
623-
180
624-
}
625-
},
608+
// Known issue: Edge always triggers it since logo is not at uri
609+
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
610+
$"|{UserModelId} can't find logo uri for {uri} in package location (logo name or directory not found): {Package.Location}", new FileNotFoundException());
611+
return string.Empty;
612+
}
613+
614+
var files = Directory.EnumerateFiles(logoDir);
615+
616+
// Currently we don't care which one to choose
617+
// Just ignore all qualifiers
618+
// select like logo.[xxx_yyy].png
619+
// https://learn.microsoft.com/en-us/windows/uwp/app-resources/tailor-resources-lang-scale-contrast
620+
var logos = files.Where(file =>
621+
Path.GetFileName(file)?.StartsWith(logoNamePrefix, StringComparison.OrdinalIgnoreCase) ?? false
622+
&& extension.Equals(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase)
623+
);
624+
625+
var selected = logos.FirstOrDefault();
626+
var closest = selected;
627+
int min = int.MaxValue;
628+
foreach(var logo in logos)
626629
{
627-
PackageVersion.Windows8, new List<int>
630+
631+
var imageStream = File.OpenRead(logo);
632+
var decoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.IgnoreColorProfile, BitmapCacheOption.None);
633+
var height = decoder.Frames[0].PixelHeight;
634+
var width = decoder.Frames[0].PixelWidth;
635+
int pixelCountDiff = Math.Abs(height * width - 1936); // 44*44=1936
636+
if(pixelCountDiff < min)
628637
{
629-
100
638+
// try to find the closest to 44x44 logo
639+
closest = logo;
640+
if (pixelCountDiff == 0)
641+
break; // found 44x44
642+
min = pixelCountDiff;
630643
}
631644
}
632-
};
633645

634-
if (scaleFactors.ContainsKey(Package.Version))
635-
{
636-
foreach (var factor in scaleFactors[Package.Version])
646+
selected = closest;
647+
if (!string.IsNullOrEmpty(selected))
637648
{
638-
paths.Add($"{prefix}.scale-{factor}{extension}");
649+
return selected;
650+
}
651+
else
652+
{
653+
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
654+
$"|{UserModelId} can't find logo uri for {uri} in package location (can't find specified logo): {Package.Location}", new FileNotFoundException());
655+
return string.Empty;
639656
}
640-
}
641-
642-
var selected = paths.FirstOrDefault(File.Exists);
643-
if (!string.IsNullOrEmpty(selected))
644-
{
645-
return selected;
646657
}
647658
else
648659
{
649660
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
650-
$"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException());
661+
$"|Unable to find extension from {uri} for {UserModelId} " +
662+
$"in package location {Package.Location}", new FileNotFoundException());
651663
return string.Empty;
652664
}
653665
}
654-
else
655-
{
656-
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
657-
$"|Unable to find extension from {uri} for {UserModelId} " +
658-
$"in package location {Package.Location}", new FileNotFoundException());
659-
return string.Empty;
660-
}
661666
}
662667

663668

664669
public ImageSource Logo()
665670
{
666671
var logo = ImageFromPath(LogoPath);
667-
var plated = PlatedImage(logo);
672+
var plated = PlatedImage(logo); // TODO: maybe get plated directly from app package?
668673

669674
// todo magic! temp fix for cross thread object
670675
plated.Freeze();

appveyor.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ init:
77
- sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest
88
- net start WSearch
99

10+
cache:
11+
- '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change
12+
13+
1014
assembly_info:
1115
patch: true
1216
file: SolutionAssemblyInfo.cs
@@ -28,7 +32,9 @@ before_build:
2832
build:
2933
project: Flow.Launcher.sln
3034
verbosity: minimal
31-
after_build:
35+
test_script:
36+
- dotnet test --no-build -c Release
37+
after_test:
3238
- ps: .\Scripts\post_build.ps1
3339

3440
artifacts:

0 commit comments

Comments
 (0)