Merge branch 'dev' into 250412-SettingWindowFont

This commit is contained in:
Jack Ye 2025-04-19 11:10:40 +08:00 committed by GitHub
commit 9133f2f951
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 319 additions and 161 deletions

91
.github/workflows/dotnet.yml vendored Normal file
View file

@ -0,0 +1,91 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
name: Build
on:
workflow_dispatch:
push:
branches:
- dev
- master
pull_request:
jobs:
build:
runs-on: windows-latest
env:
FlowVersion: 1.19.5
NUGET_CERT_REVOCATION_MODE: offline
BUILD_NUMBER: ${{ github.run_number }}
steps:
- uses: actions/checkout@v4
- name: Set Flow.Launcher.csproj version
id: update
uses: vers-one/dotnet-project-version-updater@v1.5
with:
file: |
"**/SolutionAssemblyInfo.cs"
version: ${{ env.FlowVersion }}.${{ env.BUILD_NUMBER }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
# cache: true
# cache-dependency-path: |
# Flow.Launcher/packages.lock.json
# Flow.Launcher.Core/packages.lock.json
# Flow.Launcher.Infrastructure/packages.lock.json
# Flow.Launcher.Plugin/packages.lock.json
- name: Install vpk
run: dotnet tool install -g vpk
- name: Restore dependencies
run: nuget restore
- name: Build
run: dotnet build --no-restore -c Release
- name: Initialize Service
run: |
sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest
net start WSearch
- name: Test
run: dotnet test --no-build --verbosity normal -c Release
- name: Perform post_build tasks
shell: powershell
run: .\Scripts\post_build.ps1
- name: Upload Plugin Nupkg
uses: actions/upload-artifact@v4
with:
name: Plugin nupkg
path: |
Output\Release\Flow.Launcher.Plugin.*.nupkg
compression-level: 0
- name: Upload Setup
uses: actions/upload-artifact@v4
with:
name: Flow Installer
path: |
Output\Packages\Flow-Launcher-*.exe
compression-level: 0
- name: Upload Portable Version
uses: actions/upload-artifact@v4
with:
name: Portable Version
path: |
Output\Packages\Flow-Launcher-Portable.zip
compression-level: 0
- name: Upload Full Nupkg
uses: actions/upload-artifact@v4
with:
name: Full nupkg
path: |
Output\Packages\FlowLauncher-*-full.nupkg
compression-level: 0
- name: Upload Release Information
uses: actions/upload-artifact@v4
with:
name: RELEASES
path: |
Output\Packages\RELEASES
compression-level: 0

View file

@ -16,12 +16,12 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
public record CommunityPluginSource(string ManifestFileUrl)
{
private static readonly string ClassName = nameof(CommunityPluginSource);
// We should not initialize API in static constructor because it will create another API instance
private static IPublicAPI api = null;
private static IPublicAPI API => api ??= Ioc.Default.GetRequiredService<IPublicAPI>();
private static readonly string ClassName = nameof(CommunityPluginSource);
private string latestEtag = "";
private List<UserPlugin> plugins = new();
@ -70,7 +70,7 @@ namespace Flow.Launcher.Core.ExternalPlugins
else
{
API.LogWarn(ClassName, $"Failed to load resource {ManifestFileUrl} with response {response.StatusCode}");
return plugins;
return null;
}
}
catch (Exception e)
@ -83,7 +83,7 @@ namespace Flow.Launcher.Core.ExternalPlugins
{
API.LogException(ClassName, "Error Occurred", e);
}
return plugins;
return null;
}
}
}

View file

@ -40,10 +40,14 @@ namespace Flow.Launcher.Core.ExternalPlugins
var completedTask = await Task.WhenAny(tasks);
if (completedTask.IsCompletedSuccessfully)
{
// one of the requests completed successfully; keep its results
// and cancel the remaining http requests.
pluginResults = await completedTask;
cts.Cancel();
var result = await completedTask;
if (result != null)
{
// one of the requests completed successfully; keep its results
// and cancel the remaining http requests.
pluginResults = result;
cts.Cancel();
}
}
tasks.Remove(completedTask);
}

View file

@ -1,12 +1,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Infrastructure.Hotkey;
using Flow.Launcher.Infrastructure.Logger;
@ -14,7 +9,6 @@ using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using SystemFonts = System.Windows.SystemFonts;
namespace Flow.Launcher.Infrastructure.UserSettings
{
@ -38,69 +32,6 @@ namespace Flow.Launcher.Infrastructure.UserSettings
_storage.Save();
}
private string language = Constant.SystemLanguageCode;
private static readonly Dictionary<string, string> LanguageToNotoSans = new()
{
{ "ko", "Noto Sans KR" },
{ "ja", "Noto Sans JP" },
{ "zh-CN", "Noto Sans SC" },
{ "zh-SG", "Noto Sans SC" },
{ "zh-Hans", "Noto Sans SC" },
{ "zh-TW", "Noto Sans TC" },
{ "zh-HK", "Noto Sans TC" },
{ "zh-MO", "Noto Sans TC" },
{ "zh-Hant", "Noto Sans TC" },
{ "th", "Noto Sans Thai" },
{ "ar", "Noto Sans Arabic" },
{ "he", "Noto Sans Hebrew" },
{ "hi", "Noto Sans Devanagari" },
{ "bn", "Noto Sans Bengali" },
{ "ta", "Noto Sans Tamil" },
{ "el", "Noto Sans Greek" },
{ "ru", "Noto Sans" },
{ "en", "Noto Sans" },
{ "fr", "Noto Sans" },
{ "de", "Noto Sans" },
{ "es", "Noto Sans" },
{ "pt", "Noto Sans" }
};
public static string GetSystemDefaultFont(bool? useNoto = null)
{
try
{
if (useNoto != false)
{
var culture = CultureInfo.CurrentCulture;
var language = culture.Name; // e.g., "zh-TW"
var langPrefix = language.Split('-')[0]; // e.g., "zh"
if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
{
if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
return notoFont;
}
}
var font = SystemFonts.MessageFontFamily;
if (font.FamilyNames.TryGetValue(System.Windows.Markup.XmlLanguage.GetLanguage("en-US"), out var englishName))
{
return englishName;
}
return font.Source ?? "Segoe UI";
}
catch
{
return "Segoe UI";
}
}
private static bool TryGetNotoFont(string langKey, out string notoFont)
{
return LanguageToNotoSans.TryGetValue(langKey, out notoFont);
}
private string _theme = Constant.DefaultTheme;
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
@ -121,12 +52,13 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public string CycleHistoryUpHotkey { get; set; } = $"{KeyConstant.Alt} + Up";
public string CycleHistoryDownHotkey { get; set; } = $"{KeyConstant.Alt} + Down";
private string _language = Constant.SystemLanguageCode;
public string Language
{
get => language;
get => _language;
set
{
language = value;
_language = value;
OnPropertyChanged();
}
}
@ -152,15 +84,15 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public double QueryBoxFontSize { get; set; } = 16;
public double ResultItemFontSize { get; set; } = 16;
public double ResultSubItemFontSize { get; set; } = 13;
public string QueryBoxFont { get; set; } = GetSystemDefaultFont();
public string QueryBoxFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string QueryBoxFontStyle { get; set; }
public string QueryBoxFontWeight { get; set; }
public string QueryBoxFontStretch { get; set; }
public string ResultFont { get; set; } = GetSystemDefaultFont();
public string ResultFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string ResultFontStyle { get; set; }
public string ResultFontWeight { get; set; }
public string ResultFontStretch { get; set; }
public string ResultSubFont { get; set; } = GetSystemDefaultFont();
public string ResultSubFont { get; set; } = Win32Helper.GetSystemDefaultFont();
public string ResultSubFontStyle { get; set; }
public string ResultSubFontWeight { get; set; }
public string ResultSubFontStretch { get; set; }
@ -184,7 +116,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public double? SettingWindowLeft { get; set; } = null;
public WindowState SettingWindowState { get; set; } = WindowState.Normal;
bool _showPlaceholder { get; set; } = true;
private bool _showPlaceholder { get; set; } = true;
public bool ShowPlaceholder
{
get => _showPlaceholder;
@ -197,7 +129,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
}
}
string _placeholderText { get; set; } = string.Empty;
private string _placeholderText { get; set; } = string.Empty;
public string PlaceholderText
{
get => _placeholderText;
@ -376,7 +308,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public bool StartFlowLauncherOnSystemStartup { get; set; } = false;
public bool UseLogonTaskForStartup { get; set; } = false;
public bool HideOnStartup { get; set; } = true;
bool _hideNotifyIcon { get; set; }
private bool _hideNotifyIcon;
public bool HideNotifyIcon
{
get => _hideNotifyIcon;
@ -554,5 +486,4 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Mica,
MicaAlt
}
}

View file

@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using Flow.Launcher.Infrastructure.UserSettings;
using Microsoft.Win32;
@ -14,6 +17,7 @@ using Windows.Win32.Graphics.Dwm;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
using SystemFonts = System.Windows.SystemFonts;
namespace Flow.Launcher.Infrastructure
{
@ -595,5 +599,73 @@ namespace Flow.Launcher.Infrastructure
}
#endregion
#region System Font
private static readonly Dictionary<string, string> _languageToNotoSans = new()
{
{ "ko", "Noto Sans KR" },
{ "ja", "Noto Sans JP" },
{ "zh-CN", "Noto Sans SC" },
{ "zh-SG", "Noto Sans SC" },
{ "zh-Hans", "Noto Sans SC" },
{ "zh-TW", "Noto Sans TC" },
{ "zh-HK", "Noto Sans TC" },
{ "zh-MO", "Noto Sans TC" },
{ "zh-Hant", "Noto Sans TC" },
{ "th", "Noto Sans Thai" },
{ "ar", "Noto Sans Arabic" },
{ "he", "Noto Sans Hebrew" },
{ "hi", "Noto Sans Devanagari" },
{ "bn", "Noto Sans Bengali" },
{ "ta", "Noto Sans Tamil" },
{ "el", "Noto Sans Greek" },
{ "ru", "Noto Sans" },
{ "en", "Noto Sans" },
{ "fr", "Noto Sans" },
{ "de", "Noto Sans" },
{ "es", "Noto Sans" },
{ "pt", "Noto Sans" }
};
public static string GetSystemDefaultFont()
{
try
{
var culture = CultureInfo.CurrentCulture;
var language = culture.Name; // e.g., "zh-TW"
var langPrefix = language.Split('-')[0]; // e.g., "zh"
// First, try to find by full name, and if not found, fallback to prefix
if (TryGetNotoFont(language, out var notoFont) || TryGetNotoFont(langPrefix, out notoFont))
{
// If the font is installed, return it
if (Fonts.SystemFontFamilies.Any(f => f.Source.Equals(notoFont)))
{
return notoFont;
}
}
// If Noto font is not found, fallback to the system default font
var font = SystemFonts.MessageFontFamily;
if (font.FamilyNames.TryGetValue(XmlLanguage.GetLanguage("en-US"), out var englishName))
{
return englishName;
}
return font.Source ?? "Segoe UI";
}
catch
{
return "Segoe UI";
}
}
private static bool TryGetNotoFont(string langKey, out string notoFont)
{
return _languageToNotoSans.TryGetValue(langKey, out notoFont);
}
#endregion
}
}

View file

@ -223,11 +223,15 @@ namespace Flow.Launcher.Plugin
Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action<double> reportProgress = null, CancellationToken token = default);
/// <summary>
/// Add ActionKeyword and update action keyword metadata for specific plugin
/// Add ActionKeyword and update action keyword metadata for specific plugin.
/// Before adding, please check if action keyword is already assigned by <see cref="ActionKeywordAssigned"/>
/// </summary>
/// <param name="pluginId">ID for plugin that needs to add action keyword</param>
/// <param name="newActionKeyword">The actionkeyword that is supposed to be added</param>
/// <remarks>
/// If new action keyword contains any whitespace, FL will still add it but it will not work for users.
/// So plugin should check the whitespace before calling this function.
/// </remarks>
void AddActionKeyword(string pluginId, string newActionKeyword);
/// <summary>
@ -280,9 +284,10 @@ namespace Flow.Launcher.Plugin
T LoadSettingJsonStorage<T>() where T : new();
/// <summary>
/// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.Launcher
/// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.
/// This method will save the original instance loaded with LoadJsonStorage.
/// This API call is for manually Save. Flow will automatically save all setting type that has called LoadSettingJsonStorage or SaveSettingJsonStorage previously.
/// This API call is for manually Save.
/// Flow will automatically save all setting type that has called <see cref="LoadSettingJsonStorage"/> or <see cref="SaveSettingJsonStorage"/> previously.
/// </summary>
/// <typeparam name="T">Type for Serialization</typeparam>
/// <returns></returns>
@ -424,9 +429,10 @@ namespace Flow.Launcher.Plugin
Task<T> LoadCacheBinaryStorageAsync<T>(string cacheName, string cacheDirectory, T defaultData) where T : new();
/// <summary>
/// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.Launcher
/// Save BinaryStorage for current plugin's cache. This is the method used to save cache to binary in Flow.
/// This method will save the original instance loaded with LoadCacheBinaryStorageAsync.
/// This API call is for manually Save. Flow will automatically save all cache type that has called LoadCacheBinaryStorageAsync or SaveCacheBinaryStorageAsync previously.
/// This API call is for manually Save.
/// Flow will automatically save all cache type that has called <see cref="LoadCacheBinaryStorageAsync"/> or <see cref="SaveCacheBinaryStorageAsync"/> previously.
/// </summary>
/// <typeparam name="T">Type for Serialization</typeparam>
/// <param name="cacheName">Cache file name</param>

View file

@ -202,18 +202,11 @@ namespace Flow.Launcher
{
// we try to enable auto-startup on first launch, or reenable if it was removed
// but the user still has the setting set
if (_settings.StartFlowLauncherOnSystemStartup && !Helper.AutoStartup.IsEnabled)
if (_settings.StartFlowLauncherOnSystemStartup)
{
try
{
if (_settings.UseLogonTaskForStartup)
{
Helper.AutoStartup.EnableViaLogonTask();
}
else
{
Helper.AutoStartup.EnableViaRegistry();
}
Helper.AutoStartup.CheckIsEnabled(_settings.UseLogonTaskForStartup);
}
catch (Exception e)
{

View file

@ -3,7 +3,6 @@ using System.IO;
using System.Linq;
using System.Security.Principal;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Microsoft.Win32;
using Microsoft.Win32.TaskScheduler;
@ -17,29 +16,37 @@ public class AutoStartup
private const string LogonTaskName = $"{Constant.FlowLauncher} Startup";
private const string LogonTaskDesc = $"{Constant.FlowLauncher} Auto Startup";
public static bool IsEnabled
public static void CheckIsEnabled(bool useLogonTaskForStartup)
{
get
// We need to check both because if both of them are enabled,
// Hide Flow Launcher on startup will not work since the later one will trigger main window show event
var logonTaskEnabled = CheckLogonTask();
var registryEnabled = CheckRegistry();
if (useLogonTaskForStartup)
{
// Check if logon task is enabled
if (CheckLogonTask())
// Enable logon task
if (!logonTaskEnabled)
{
return true;
Enable(true);
}
// Check if registry is enabled
try
// Disable registry
if (registryEnabled)
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
var path = key?.GetValue(Constant.FlowLauncher) as string;
return path == Constant.ExecutablePath;
Disable(false);
}
catch (Exception e)
}
else
{
// Enable registry
if (!registryEnabled)
{
App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
Enable(false);
}
// Disable logon task
if (logonTaskEnabled)
{
Disable(true);
}
return false;
}
}
@ -70,22 +77,28 @@ public class AutoStartup
return false;
}
private static bool CheckRegistry()
{
try
{
using var key = Registry.CurrentUser.OpenSubKey(StartupPath, true);
var path = key?.GetValue(Constant.FlowLauncher) as string;
return path == Constant.ExecutablePath;
}
catch (Exception e)
{
App.API.LogError(ClassName, $"Ignoring non-critical registry error (querying if enabled): {e}");
}
return false;
}
public static void DisableViaLogonTaskAndRegistry()
{
Disable(true);
Disable(false);
}
public static void EnableViaLogonTask()
{
Enable(true);
}
public static void EnableViaRegistry()
{
Enable(false);
}
public static void ChangeToViaLogonTask()
{
Disable(false);

View file

@ -5,7 +5,6 @@ using NHotkey;
using NHotkey.Wpf;
using Flow.Launcher.ViewModel;
using ChefKeys;
using Flow.Launcher.Infrastructure.Logger;
using CommunityToolkit.Mvvm.DependencyInjection;
namespace Flow.Launcher.Helper;

View file

@ -58,7 +58,7 @@
<system:String x:Key="setAutoStartFailed">Error setting launch on startup</system:String>
<system:String x:Key="hideFlowLauncherWhenLoseFocus">Hide Flow Launcher when focus is lost</system:String>
<system:String x:Key="dontPromptUpdateMsg">Do not show new version notifications</system:String>
<system:String x:Key="SearchWindowPosition">Search Window Position</system:String>
<system:String x:Key="SearchWindowPosition">Search Window Location</system:String>
<system:String x:Key="SearchWindowScreenRememberLastLaunchLocation">Remember Last Position</system:String>
<system:String x:Key="SearchWindowScreenCursor">Monitor with Mouse Cursor</system:String>
<system:String x:Key="SearchWindowScreenFocus">Monitor with Focused Window</system:String>

View file

@ -22,7 +22,7 @@
<SolidColorBrush x:Key="BasicSystemAccentColor" Color="{m:DynamicColor SystemAccentColor}" />
<SolidColorBrush x:Key="Color00B" Color="#CEFAFAFA" />
<SolidColorBrush x:Key="Color00B" Color="#FAFAFA" />
<SolidColorBrush x:Key="Color01B" Color="#f3f3f3" />
<SolidColorBrush x:Key="Color02B" Color="#ffffff" />
<SolidColorBrush x:Key="Color03B" Color="#e5e5e5" />

View file

@ -48,11 +48,11 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
{
if (UseLogonTaskForStartup)
{
AutoStartup.EnableViaLogonTask();
AutoStartup.ChangeToViaLogonTask();
}
else
{
AutoStartup.EnableViaRegistry();
AutoStartup.ChangeToViaRegistry();
}
}
else

View file

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Globalization;
using System.IO;
using System.Linq;
@ -17,13 +17,12 @@ using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using ModernWpf;
using ThemeManagerForColorSchemeSwitch = ModernWpf.ThemeManager;
using System.Windows.Controls;
namespace Flow.Launcher.SettingPages.ViewModels;
public partial class SettingsPaneThemeViewModel : BaseModel
{
private string DefaultFont = Settings.GetSystemDefaultFont();
private readonly string DefaultFont = Win32Helper.GetSystemDefaultFont();
public string BackdropSubText => !Win32Helper.IsBackdropSupported() ? App.API.GetTranslation("BackdropTypeDisabledToolTip") : "";
public Settings Settings { get; }
private readonly Theme _theme = Ioc.Default.GetRequiredService<Theme>();

View file

@ -80,6 +80,7 @@
Width="135"
HorizontalAlignment="Left"
VerticalAlignment="Center"
DataObject.Pasting="TextBox_Pasting"
PreviewKeyDown="TxtCurrentActionKeyword_OnKeyDown"
Text="{Binding ActionKeyword}" />
</StackPanel>

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
@ -85,7 +86,7 @@ namespace Flow.Launcher.Plugin.Explorer.Views
DialogResult = false;
Close();
}
private void TxtCurrentActionKeyword_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
@ -94,14 +95,34 @@ namespace Flow.Launcher.Plugin.Explorer.Views
OnDoneButtonClick(sender, e);
e.Handled = true;
}
if (e.Key == Key.Space)
{
e.Handled = true;
}
}
private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(DataFormats.Text))
{
string text = e.DataObject.GetData(DataFormats.Text) as string;
if (!string.IsNullOrEmpty(text) && text.Any(char.IsWhiteSpace))
{
e.CancelCommand();
}
}
else
{
e.CancelCommand();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))

View file

@ -56,13 +56,13 @@
</Button>
</Grid>
</StackPanel>
<StackPanel Margin="26,12,26,0">
<StackPanel Margin="26 12 26 0">
<Grid>
<StackPanel>
<StackPanel Grid.Row="0" Margin="0,0,0,12">
<StackPanel Grid.Row="0" Margin="0 0 0 12">
<TextBlock
Grid.Column="0"
Margin="0,0,0,0"
Margin="0 0 0 0"
FontSize="20"
FontWeight="SemiBold"
Text="{DynamicResource flowlauncher_plugin_websearch_window_title}"
@ -75,7 +75,7 @@
TextAlignment="Left"
TextWrapping="WrapWithOverflow" />
<TextBox
Margin="0,12,0,12"
Margin="0 12 0 12"
FontSize="14"
FontWeight="SemiBold"
IsReadOnly="True"
@ -83,7 +83,7 @@
TextAlignment="Center"
TextWrapping="WrapWithOverflow" />
<TextBlock
Margin="0,0,0,14"
Margin="0 0 0 14"
FontSize="14"
Text="{DynamicResource flowlauncher_plugin_websearch_guide_3}"
TextAlignment="Left"
@ -105,7 +105,7 @@
<TextBlock
Grid.Row="0"
Grid.Column="0"
Margin="10,10,15,10"
Margin="10 10 15 10"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
FontSize="14"
@ -120,7 +120,7 @@
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="10,10,15,10"
Margin="10 10 15 10"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -131,7 +131,7 @@
Orientation="Horizontal">
<Button
Height="35"
Margin="10,0,0,0"
Margin="10 0 0 0"
VerticalAlignment="Center"
Click="OnSelectIconClick"
Content="{DynamicResource flowlauncher_plugin_websearch_select_icon}" />
@ -139,13 +139,13 @@
Name="imgPreviewIcon"
Width="24"
Height="24"
Margin="14,0,0,0"
Margin="14 0 0 0"
VerticalAlignment="Center" />
</StackPanel>
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="10,10,15,10"
Margin="10 10 15 10"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -160,7 +160,7 @@
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="10,10,15,10"
Margin="10 10 15 10"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -168,14 +168,16 @@
<TextBox
Grid.Row="3"
Grid.Column="1"
Margin="10,0,10,0"
Margin="10 0 10 0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
DataObject.Pasting="TextBox_Pasting"
PreviewKeyDown="TextBox_PreviewKeyDown"
Text="{Binding SearchSource.ActionKeyword}" />
<TextBlock
Grid.Row="4"
Grid.Column="0"
Margin="10,10,15,15"
Margin="10 10 15 15"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="14"
@ -183,7 +185,7 @@
<CheckBox
Grid.Row="4"
Grid.Column="1"
Margin="10,10,10,15"
Margin="10 10 10 15"
VerticalAlignment="Center"
IsChecked="{Binding SearchSource.Enabled}" />
</Grid>
@ -196,16 +198,16 @@
Grid.Row="1"
Background="{DynamicResource PopupButtonAreaBGColor}"
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
BorderThickness="0,1,0,0">
BorderThickness="0 1 0 0">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<Button
MinWidth="140"
Margin="10,0,5,0"
Margin="10 0 5 0"
Click="OnCancelButtonClick"
Content="{DynamicResource flowlauncher_plugin_websearch_cancel}" />
<Button
MinWidth="140"
Margin="5,0,10,0"
Margin="5 0 10 0"
Click="OnConfirmButtonClick"
Content="{DynamicResource flowlauncher_plugin_websearch_confirm}"
Style="{DynamicResource AccentButtonStyle}" />

View file

@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using Microsoft.Win32;
namespace Flow.Launcher.Plugin.WebSearch
@ -145,6 +147,30 @@ namespace Flow.Launcher.Plugin.WebSearch
}
}
}
//Block Space Input
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
e.Handled = true;
}
}
private void TextBox_Pasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(DataFormats.Text))
{
string text = e.DataObject.GetData(DataFormats.Text) as string;
if (!string.IsNullOrEmpty(text) && text.Any(char.IsWhiteSpace))
{
e.CancelCommand();
}
}
else
{
e.CancelCommand();
}
}
}
public enum Action

View file

@ -1,5 +1,5 @@
param(
[string]$config = "Release",
[string]$config = "Release",
[string]$solution = (Join-Path $PSScriptRoot ".." -Resolve)
)
Write-Host "Config: $config"
@ -40,11 +40,11 @@ function Delete-Unused ($path, $config) {
$target = "$path\Output\$config"
$included = Get-ChildItem $target -Filter "*.dll"
foreach ($i in $included){
$deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" }
$deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" }
$deleteList | ForEach-Object{ Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName }
$deleteList | Remove-Item
}
Remove-Item -Path $target -Include "*.xml" -Recurse
Remove-Item -Path $target -Include "*.xml" -Recurse
}
function Remove-CreateDumpExe ($path, $config) {
@ -87,7 +87,7 @@ function Pack-Squirrel-Installer ($path, $version, $output) {
Squirrel --releasify $nupkg --releaseDir $temp --setupIcon $icon --no-msi | Write-Output
Move-Item $temp\* $output -Force
Remove-Item $temp
$file = "$output\Flow-Launcher-Setup.exe"
Write-Host "Filename: $file"
@ -107,7 +107,7 @@ function Publish-Self-Contained ($p) {
}
function Publish-Portable ($outputLocation, $version) {
& $outputLocation\Flow-Launcher-Setup.exe --silent | Out-Null
mkdir "$env:LocalAppData\FlowLauncher\app-$version\UserData"
Compress-Archive -Path $env:LocalAppData\FlowLauncher -DestinationPath $outputLocation\Flow-Launcher-Portable.zip
@ -119,7 +119,7 @@ function Main {
Copy-Resources $p
if ($config -eq "Release"){
Delete-Unused $p $config
Publish-Self-Contained $p
@ -134,4 +134,4 @@ function Main {
}
}
Main
Main