diff --git a/VdLabel/Config.cs b/VdLabel/Config.cs index 9d525ed..68a5dbc 100644 --- a/VdLabel/Config.cs +++ b/VdLabel/Config.cs @@ -33,7 +33,11 @@ record DesktopConfig public IReadOnlyList TargetWindows { get; init; } = []; } -record WindowConfig(WindowMatchType MatchType, WindowPatternType PatternType, string Pattern); +record WindowConfig(WindowMatchType MatchType, WindowPatternType PatternType, string Pattern) +{ + public string? TitlePattern { get; init; } + public WindowPatternType TitlePatternType { get; init; } +} enum WindowMatchType { diff --git a/VdLabel/MainViewModel.cs b/VdLabel/MainViewModel.cs index 53a94f2..cfd0db4 100644 --- a/VdLabel/MainViewModel.cs +++ b/VdLabel/MainViewModel.cs @@ -333,6 +333,10 @@ public async Task FindWindow(WindowConfigViewModel config) WindowMatchType.Path => info.Path, _ => throw new NotSupportedException(), }; + if (config.MatchType != WindowMatchType.Title && string.IsNullOrEmpty(config.TitlePattern)) + { + config.TitlePattern = info.Title; + } } public DesktopConfig GetSaveConfig() @@ -344,16 +348,27 @@ public DesktopConfig GetSaveConfig() Utf8Command = this.Utf8Command, Command = this.Command, ImagePath = this.ImagePath, - TargetWindows = this.TargetWindows.Select(c => new WindowConfig(c.MatchType, c.PatternType, c.Pattern)).ToArray(), + TargetWindows = this.TargetWindows.Select(c => new WindowConfig(c.MatchType, c.PatternType, c.Pattern) + { + TitlePattern = c.TitlePattern, + TitlePatternType = c.TitlePatternType, + }).ToArray(), }; } partial class WindowConfigViewModel(WindowConfig? config = null) : ObservableObject { [ObservableProperty] + [NotifyPropertyChangedFor(nameof(IsTitlePatternVisible))] private WindowMatchType matchType = config?.MatchType ?? default; [ObservableProperty] private WindowPatternType patternType = config?.PatternType ?? default; [ObservableProperty] private string pattern = config?.Pattern ?? string.Empty; + [ObservableProperty] + private WindowPatternType titlePatternType = config?.TitlePatternType ?? WindowPatternType.Wildcard; + [ObservableProperty] + private string? titlePattern = config?.TitlePattern; + + public bool IsTitlePatternVisible => this.MatchType != WindowMatchType.Title; } diff --git a/VdLabel/MainWindow.xaml b/VdLabel/MainWindow.xaml index 93c3833..fee8b5f 100644 --- a/VdLabel/MainWindow.xaml +++ b/VdLabel/MainWindow.xaml @@ -430,6 +430,7 @@ + + + diff --git a/VdLabel/Properties/Resources.Designer.cs b/VdLabel/Properties/Resources.Designer.cs index a5b6b5f..a72c37c 100644 --- a/VdLabel/Properties/Resources.Designer.cs +++ b/VdLabel/Properties/Resources.Designer.cs @@ -483,6 +483,15 @@ public static string TargetWindow { } } + /// + /// タイトルパターン に類似しているローカライズされた文字列を検索します。 + /// + public static string TitlePattern { + get { + return ResourceManager.GetString("TitlePattern", resourceCulture); + } + } + /// /// テスト に類似しているローカライズされた文字列を検索します。 /// diff --git a/VdLabel/Properties/Resources.en.resx b/VdLabel/Properties/Resources.en.resx index 6cad63f..5761a3c 100644 --- a/VdLabel/Properties/Resources.en.resx +++ b/VdLabel/Properties/Resources.en.resx @@ -168,6 +168,9 @@ Target Window + + Title Pattern + Add diff --git a/VdLabel/Properties/Resources.resx b/VdLabel/Properties/Resources.resx index 17f847e..26af669 100644 --- a/VdLabel/Properties/Resources.resx +++ b/VdLabel/Properties/Resources.resx @@ -164,6 +164,9 @@ 対象ウィンドウ + + タイトルパターン + 追加 diff --git a/VdLabel/WindowMonitor.cs b/VdLabel/WindowMonitor.cs index 3b3fad2..8171f25 100644 --- a/VdLabel/WindowMonitor.cs +++ b/VdLabel/WindowMonitor.cs @@ -15,7 +15,7 @@ class WindowMonitor(ILogger logger, IConfigStore configStore) : B private bool needReload = true; private TargetWindow[] targetWindows = []; - private record TargetWindow(Guid DesktopId, WindowMatchType MatchType, Regex Regex); + private record TargetWindow(Guid DesktopId, WindowMatchType MatchType, Regex Regex, Regex? TitleRegex); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { @@ -54,7 +54,8 @@ static Regex ToRegex(WindowPatternType patternType, string pattern) var config = await this.configStore.Load().ConfigureAwait(false); this.targetWindows = config.DesktopConfigs .SelectMany(c => c.TargetWindows.Select(p => (c.Id, p))) - .Select(c => new TargetWindow(c.Id, c.p.MatchType, ToRegex(c.p.PatternType, c.p.Pattern))) + .Select(c => new TargetWindow(c.Id, c.p.MatchType, ToRegex(c.p.PatternType, c.p.Pattern), + c.p.TitlePattern is { } tp ? ToRegex(c.p.TitlePatternType, tp) : null)) .ToArray(); this.checkedWindows.Clear(); this.logger.LogDebug("ターゲットプロセス再読み込み"); @@ -119,7 +120,8 @@ private void CheckWindows() return true; } - if (this.targetWindows.FirstOrDefault(t => t.Regex.IsMatch(GetCheckText(t.MatchType, path, commandLine, windowTitle))) is not { } target) + if (this.targetWindows.FirstOrDefault(t => t.Regex.IsMatch(GetCheckText(t.MatchType, path, commandLine, windowTitle)) + && (t.TitleRegex is null || t.TitleRegex.IsMatch(windowTitle))) is not { } target) { // ウィンドウがターゲットでない場合はチェック済みとする this.checkedWindows[hWnd] = windowTitle;