Skip to content
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

Move focus to main window of process if it's already running #49

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions src/Jarvis.Addin.Files/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to Spectre Systems AB under one or more agreements.
// Spectre Systems AB licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Jarvis.Addin.Files
{
internal sealed class Constants
{
internal sealed class Settings
{
public const string Version = "Files.Version";

internal sealed class Include
{
public const string Folders = "Files.Include.Folders";
public const string Extensions = "Files.Include.Extensions";
}

internal sealed class Exclude
{
public const string Folders = "Files.Exclude.Folders";
public const string Patterns = "Files.Exclude.Patterns";
}
}
}
}
4 changes: 3 additions & 1 deletion src/Jarvis.Addin.Files/FileAddin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.

using Autofac;
using Jarvis.Addin.Files.Drawing;
using Jarvis.Addin.Files.Icons;
using Jarvis.Addin.Files.Indexing;
using Jarvis.Addin.Files.Sources;
using Jarvis.Addin.Files.Sources.Uwp;
Expand All @@ -18,12 +18,14 @@ public void Configure(ContainerBuilder builder)
{
builder.RegisterType<FileProvider>().As<IQueryProvider>().SingleInstance();
builder.RegisterType<FileIndexer>().As<IBackgroundWorker>().As<IFileIndex>().SingleInstance();
builder.RegisterType<FileSettingsSeeder>().As<ISettingsSeeder>().SingleInstance();

// Sources
builder.RegisterType<StartMenuIndexSource>().As<IFileIndexSource>().SingleInstance();
builder.RegisterType<UwpIndexSource>().As<IFileIndexSource>().SingleInstance();
builder.RegisterType<DocumentIndexSource>().As<IFileIndexSource>().SingleInstance();

// Utilities
builder.RegisterType<AppxManifestReader>().SingleInstance();
builder.RegisterType<IconLoader>().SingleInstance();
builder.RegisterType<NativeStreamProvider>().As<INativeStreamProvider>().SingleInstance();
Expand Down
42 changes: 39 additions & 3 deletions src/Jarvis.Addin.Files/FileProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,26 @@
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using Jarvis.Addin.Files.Drawing;
using Jarvis.Addin.Files.Extensions;
using Jarvis.Addin.Files.Icons;
using Jarvis.Addin.Files.Indexing;
using Jarvis.Addin.Files.Sources;
using Jarvis.Addin.Files.ViewModels;
using Jarvis.Core;
using Jarvis.Core.Interop;
using JetBrains.Annotations;
using Spectre.System.IO;
using static Jarvis.Addin.Files.Sources.Uwp.ShellInterop;
using Path = System.IO.Path;

namespace Jarvis.Addin.Files
{
[UsedImplicitly]
internal sealed class FileProvider : QueryProvider<FileResult>
internal sealed class FileProvider : QueryProvider<FileResult, FileSettingsViewModel>
{
private readonly IFileIndex _index;
private readonly IconLoader _loader;
Expand Down Expand Up @@ -55,7 +62,36 @@ protected override Task ExecuteAsync(FileResult result)

if (result.Path.Scheme == "shell")
{
Process.Start(path);
if (path.EndsWith("lnk") && result.OriginalEntry is StartMenuIndexSourceEntry startMenuEntry)
{
path = WebUtility.UrlDecode(startMenuEntry.TargetPath.ToUri("shell").AbsolutePath).TrimStart('/');
}
var existingProcess = Process
.GetProcesses()
.FirstOrDefault(process =>
{
var processPath = new StringBuilder(1024);
var size = processPath.Capacity;
var processHandle = Win32.OpenProcess(0x1000, false, process.Id);
Win32.QueryFullProcessImageName(processHandle, 0, processPath, out size);
return processPath.ToString() == path;
});

if (existingProcess != null)
{
Win32.SetForegroundWindow(existingProcess.MainWindowHandle);

var rect = new Win32.W32Rect();
Win32.GetWindowRect(existingProcess.MainWindowHandle, ref rect);
if (rect.Top < 0 && rect.Right < 0 && rect.Bottom < 0 && rect.Left < 0) // Window is minimized
{
Win32.ShowWindow(existingProcess.MainWindowHandle, 1);
}
}
else
{
Process.Start(path);
}
}
else if (result.Path.Scheme == "uwp")
{
Expand Down
5 changes: 4 additions & 1 deletion src/Jarvis.Addin.Files/FileResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Diagnostics;
using Jarvis.Addin.Files.Indexing;
using Jarvis.Core;

namespace Jarvis.Addin.Files
Expand All @@ -18,9 +19,10 @@ internal sealed class FileResult : IQueryResult, IEquatable<FileResult>
public string Description { get; }
public float Distance { get; }
public float Score { get; }
public IndexedEntry OriginalEntry { get; }

public FileResult(QueryResultType type, Uri path, Uri icon,
string title, string description, float distance, float score)
string title, string description, float distance, float score, IndexedEntry originalEntry)
{
Type = type;
Path = path;
Expand All @@ -29,6 +31,7 @@ public FileResult(QueryResultType type, Uri path, Uri icon,
Description = description;
Distance = distance;
Score = score;
OriginalEntry = originalEntry;
}

public override bool Equals(object obj)
Expand Down
82 changes: 82 additions & 0 deletions src/Jarvis.Addin.Files/FileSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Licensed to Spectre Systems AB under one or more agreements.
// Spectre Systems AB licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Jarvis.Core;
using Spectre.System.IO;

namespace Jarvis.Addin.Files
{
internal sealed class FileSettings
{
public int Version { get; set; }
public HashSet<DirectoryPath> IncludedFolders { get; }
public HashSet<string> IncludedExtensions { get; }
public HashSet<DirectoryPath> ExcludedFolders { get; }
public HashSet<string> ExcludedPatterns { get; }

public const int CurrentVersion = 1;

public FileSettings()
{
IncludedFolders = new HashSet<DirectoryPath>(new PathComparer(false));
IncludedExtensions = new HashSet<string>(StringComparer.Ordinal);
ExcludedFolders = new HashSet<DirectoryPath>(new PathComparer(false));
ExcludedPatterns = new HashSet<string>(StringComparer.Ordinal);
}

public static FileSettings Load(ISettingsStore settings)
{
var model = new FileSettings
{
Version = settings.Get<int>(Constants.Settings.Version)
};

// Load included folders.
var includeFolders = settings.Get<string>(Constants.Settings.Include.Folders);
if (includeFolders != null)
{
model.IncludedFolders.AddRange(includeFolders
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => new DirectoryPath(s)));
}

// Load included extensions.
var includeExtensions = settings.Get<string>(Constants.Settings.Include.Extensions);
if (!string.IsNullOrWhiteSpace(includeExtensions))
{
model.IncludedExtensions.AddRange(includeExtensions.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
}

// Load excluded folders.
var excludeFolders = settings.Get<string>(Constants.Settings.Exclude.Folders);
if (excludeFolders != null)
{
model.ExcludedFolders.AddRange(excludeFolders
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => new DirectoryPath(s)));
}

// Load excluded patterns.
var excludePatterns = settings.Get<string>(Constants.Settings.Exclude.Patterns);
if (!string.IsNullOrWhiteSpace(excludePatterns))
{
model.ExcludedPatterns.AddRange(excludePatterns.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries));
}

return model;
}

public void Save(ISettingsStore settings)
{
settings.Set(Constants.Settings.Version, CurrentVersion);
settings.Set(Constants.Settings.Include.Folders, string.Join("|", IncludedFolders.Select(p => p.FullPath)));
settings.Set(Constants.Settings.Include.Extensions, string.Join("|", IncludedExtensions));
settings.Set(Constants.Settings.Exclude.Folders, string.Join("|", ExcludedFolders.Select(p => p.FullPath)));
settings.Set(Constants.Settings.Exclude.Patterns, string.Join("|", ExcludedPatterns));
}
}
}
44 changes: 44 additions & 0 deletions src/Jarvis.Addin.Files/FileSettingsSeeder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to Spectre Systems AB under one or more agreements.
// Spectre Systems AB licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using Jarvis.Core;
using Spectre.System.IO;

namespace Jarvis.Addin.Files
{
internal sealed class FileSettingsSeeder : ISettingsSeeder
{
public void Seed(ISettingsStore store)
{
var model = FileSettings.Load(store);

if (model.Version == 0)
{
Initialize(model);
model.Save(store);
}
}

private static void Initialize(FileSettings model)
{
// Included folders.
model.IncludedFolders.Add(new DirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)));
model.IncludedFolders.Add(new DirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)));
model.IncludedFolders.Add(new DirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.MyVideos)));
model.IncludedFolders.Add(new DirectoryPath(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)));

// Included extensions.
model.IncludedExtensions.AddRange(new[]
{
"ai", "avi", "doc", "docx", "eps", "flv", "gif", "htm", "html",
"jpeg", "jpg", "mov", "mp3", "mp4", "mpg", "mpeg", "odt", "ogg", "ogv", "pdf", "png", "ppt", "psd",
"rar", "rtf", "svg", "txt", "wav", "wma", "xls", "xlsx", "zip"
});

// Excluded patterns.
model.ExcludedPatterns.AddRange(new[] { ".git", "node_modules", "packages" });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using System.Threading.Tasks;
using System.Windows.Media;

namespace Jarvis.Addin.Files.Drawing
namespace Jarvis.Addin.Files.Icons
{
internal sealed class IconLoader
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using System.Windows.Media.Imaging;
using Jarvis.Core.Interop;

namespace Jarvis.Addin.Files.Drawing
namespace Jarvis.Addin.Files.Icons
{
internal static class ShellIconLoader
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using ColorConverter = System.Windows.Media.ColorConverter;
using Pen = System.Windows.Media.Pen;

namespace Jarvis.Addin.Files.Drawing
namespace Jarvis.Addin.Files.Icons
{
internal static class UwpIconLoader
{
Expand Down
Loading