-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMain.cs
212 lines (177 loc) · 8.31 KB
/
Main.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Flow.Launcher.Plugin;
using Flow.Plugin.WindowWalker.Components;
using Flow.Plugin.WindowWalker.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using static Flow.Plugin.WindowWalker.Properties.Resources;
using ContextMenu = Flow.Plugin.WindowWalker.Components.ContextMenu;
namespace Flow.Plugin.WindowWalker
{
public class Main : IPlugin, IPluginI18n, IContextMenu, ISettingProvider, IDisposable
{
internal static readonly Dictionary<string, Window> cachedWindows = new Dictionary<string, Window>();
public const string IconPath = "Images/windowwalker.light.png";
// High score to displayed on top against results
// that are frequently selected by user which recieve a boost too from Flow.
public const int cachedWindowsScore = 500;
private SettingWindow? SettingWindow;
private bool disposedValue;
public static PluginInitContext Context { get; private set; } = null!;
public static Settings Settings { get; private set; } = null!;
internal static VirtualDesktopHelper VirtualDesktopHelperInstance { get; private set; } = null!;
public List<Result> Query(Query query)
{
if (query == null)
{
throw new ArgumentNullException(nameof(query));
}
if (cachedWindows.ContainsKey(query.Search))
{
if (cachedWindows[query.Search].IsWindow)
{
var window = cachedWindows[query.Search];
return new List<Result>
{
new Result
{
Title = window.Title,
IcoPath = !String.IsNullOrEmpty(window.Process.Image) ? window.Process.Image: IconPath,
Score = cachedWindowsScore,
SubTitle = $"{wox_plugin_windowwalker_running} : {window.Process.Name}",
ContextData = window,
Action = c =>
{
OpenWindows.Instance.UpdateFlowWindow();
window.SwitchToWindow();
if (OpenWindows.Instance.FlowWindow is not null &&
window.Desktop.ComVirtualDesktop is not null)
VirtualDesktopHelper.MoveWindowToDesktop(OpenWindows.Instance.FlowWindow.Hwnd, window.Desktop.ComVirtualDesktop);
return true;
}
}
};
}
else
{
cachedWindows.Remove(query.Search);
}
}
VirtualDesktopHelperInstance.UpdateDesktopList();
OpenWindows.Instance.UpdateOpenWindowsList();
var searchResults = SearchController.GetResult(query.Search, Settings.SearchWindowsAcrossAllVDesktop);
var results = searchResults.Where(x => !string.IsNullOrEmpty(x.Result.Title))
.Select(x => new Result()
{
Title = x.Result.Title,
IcoPath = !String.IsNullOrEmpty(x.Result.Process.Image) ? x.Result.Process.Image : IconPath,
Score = x.Score,
TitleHighlightData = x.SearchMatchesInTitle?.MatchData,
SubTitle =
$"{wox_plugin_windowwalker_running} : {x.Result.Process.Name}{(VirtualDesktopHelperInstance.GetDesktopCount() > 1 ? $" - {wox_plugin_windowwalker_Desktop}: {x.Result.Desktop.Name}" : "")}",
ContextData = x.Result,
Action = c =>
{
OpenWindows.Instance.UpdateFlowWindow();
if (c.SpecialKeyState.CtrlPressed)
{
x.Result.CloseThisWindow(true);
// Re-query
Context.API.ChangeQuery(query.RawQuery, true);
}
else
x.Result.SwitchToWindow();
if (OpenWindows.Instance.FlowWindow is not null &&
x.Result.Desktop.ComVirtualDesktop is not null)
VirtualDesktopHelper.MoveWindowToDesktop(OpenWindows.Instance.FlowWindow.Hwnd, x.Result.Desktop.ComVirtualDesktop);
return true;
},
}).ToList();
foreach (var result in results)
{
foreach (var cache in cachedWindows.Where(cache => cache.Value.Title == result.Title))
{
result.Title = $"{cache.Key} - {result.Title}";
if (string.IsNullOrEmpty(query.Search))
result.Score = cachedWindowsScore;
}
}
return results.OrderBy(x => x.Title).ToList();
}
public void Init(PluginInitContext context)
{
Context = context;
Settings = Context.API.LoadSettingJsonStorage<Settings>();
Log.API = Context.API;
VirtualDesktopHelperInstance = new VirtualDesktopHelper();
RegisterQuickAccessKeyword();
OpenWindows.Instance.UpdateOpenWindowsList();
}
public void RegisterQuickAccessKeyword()
{
Context.API.RegisterGlobalKeyboardCallback(API_GlobalKeyboardEvent);
}
private bool API_GlobalKeyboardEvent(int keyevent, int vkcode, SpecialKeyState state)
{
if (Settings.EnableQuickAccessHotKey &&
keyevent == 256 && vkcode == (int)Settings.QuickAccessHotKey.Key &&
state.CtrlPressed == Settings.QuickAccessHotKey.Ctrl &&
state.AltPressed == Settings.QuickAccessHotKey.Alt &&
state.ShiftPressed == Settings.QuickAccessHotKey.Shift &&
state.WinPressed == Settings.QuickAccessHotKey.Win) // 68 is D
{
var foreGroundWindowPtr = NativeMethods.GetForegroundWindow();
Window foreGroundWindow = new Window(foreGroundWindowPtr);
var quickAccessWindow = new QuickAccessKeywordAssignedWindow(foreGroundWindow);
quickAccessWindow.ShowDialog();
return false;
}
return true;
}
public string GetTranslatedPluginTitle()
{
return wox_plugin_windowwalker_plugin_name;
}
public string GetTranslatedPluginDescription()
{
return wox_plugin_windowwalker_plugin_description;
}
public List<Result> LoadContextMenus(Result selectedResult)
{
if (selectedResult == null)
return new List<Result>();
return selectedResult.ContextData is not Window window ? new List<Result>() : ContextMenu.GetContextMenu(window);
}
public Control CreateSettingPanel()
{
return SettingWindow ??= new SettingWindow(Settings);
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
SettingWindow?.Dispose();
}
disposedValue = true;
}
}
// override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
~Main()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}