Compare commits

...

11 Commits

6 changed files with 114 additions and 24 deletions

View File

@@ -26,12 +26,12 @@ jobs:
- name: Build - name: Build
run: | run: |
echo "${{matrix.platform.name}} ${{ github.event.release.tag_name }}" echo "${{matrix.platform.name}} ${{ github.event.release.tag_name }}"
dotnet build src\\Eve-O-Preview\\Eve-O-Preview.csproj --configuration Release -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" dotnet build src\\Eve-O-Preview\\Eve-O-Preview.csproj --configuration Release -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" -p:FileVersion="${{ github.event.release.tag_name }}"
- name: BuildPackage - name: BuildPackage
run: | run: |
git log --pretty=format:'%d %s' ${GITHUB_REF} | perl -pe 's| \(.*tag: v(\d+.\d+.\d+(-preview\d{3})?)(, .*?)*\)|\n## \1\n|g' git log --pretty=format:'%d %s' ${GITHUB_REF} | perl -pe 's| \(.*tag: v(\d+.\d+.\d+(-preview\d{3})?)(, .*?)*\)|\n## \1\n|g'
# Build everything # Build everything
dotnet publish src\\Eve-O-Preview\\Eve-O-Preview.csproj -c Release -o "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}" -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" --self-contained ${{matrix.platform.self_contained}} dotnet publish src\\Eve-O-Preview\\Eve-O-Preview.csproj -c Release -o "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}" -p:EVEOTARGET="${{matrix.platform.name}}" -p:AssemblyVersion="${{ github.event.release.tag_name }}" -p:FileVersion="${{ github.event.release.tag_name }}" --self-contained ${{matrix.platform.self_contained}}
- name: Create archive - name: Create archive
run: | run: |
Compress-Archive -Path "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}\\*" -Destination "Release-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}.zip" Compress-Archive -Path "Eve-O-Preview-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}\\*" -Destination "Release-${{ github.event.release.tag_name }}-${{ matrix.platform.name }}.zip"

View File

@@ -264,6 +264,7 @@ namespace EveOPreview.Configuration.Implementation
public Color ActiveClientHighlightColor { get; set; } public Color ActiveClientHighlightColor { get; set; }
public Color OverlayLabelColor { get; set; } public Color OverlayLabelColor { get; set; }
public int OverlayLabelSize { get; set; } public int OverlayLabelSize { get; set; }
[JsonProperty("IconName")]
public string IconName { get; set; } public string IconName { get; set; }
public int ActiveClientHighlightThickness { get; set; } public int ActiveClientHighlightThickness { get; set; }
@@ -271,6 +272,9 @@ namespace EveOPreview.Configuration.Implementation
[JsonProperty("LoginThumbnailLocation")] [JsonProperty("LoginThumbnailLocation")]
public Point LoginThumbnailLocation { get; set; } public Point LoginThumbnailLocation { get; set; }
[JsonProperty("ToggleTrackingHotkey")]
public string ToggleTrackingHotkey { get; set; }
[JsonProperty] [JsonProperty]
private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; } private Dictionary<string, Dictionary<string, Point>> PerClientLayout { get; set; }
[JsonProperty] [JsonProperty]
@@ -284,7 +288,7 @@ namespace EveOPreview.Configuration.Implementation
[JsonProperty] [JsonProperty]
private List<string> PriorityClients { get; set; } private List<string> PriorityClients { get; set; }
[JsonProperty] [JsonProperty]
private List<string> ExecutablesToPreview { get; set; } public List<string> ExecutablesToPreview { get; set; }
public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation) public Point GetThumbnailLocation(string currentClient, string activeClient, Point defaultLocation)
{ {

View File

@@ -26,6 +26,8 @@ namespace EveOPreview.Configuration
List<string> CycleGroup5BackwardHotkeys { get; set; } List<string> CycleGroup5BackwardHotkeys { get; set; }
Dictionary<string, int> CycleGroup5ClientsOrder { get; set; } Dictionary<string, int> CycleGroup5ClientsOrder { get; set; }
string ToggleTrackingHotkey { get; set; }
Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; } Dictionary<string, Color> PerClientActiveClientHighlightColor { get; set; }
Dictionary<string, Size> PerClientThumbnailSize { get; set; } Dictionary<string, Size> PerClientThumbnailSize { get; set; }
@@ -89,6 +91,7 @@ namespace EveOPreview.Configuration
bool IsPriorityClient(string currentClient); bool IsPriorityClient(string currentClient);
bool IsExecutableToPreview(string processName); bool IsExecutableToPreview(string processName);
List<string> ExecutablesToPreview { get; set; }
bool IsThumbnailDisabled(string currentClient); bool IsThumbnailDisabled(string currentClient);
void ToggleThumbnail(string currentClient, bool isDisabled); void ToggleThumbnail(string currentClient, bool isDisabled);

View File

@@ -250,9 +250,18 @@ namespace EveOPreview.Presenters
private void OpenDocumentationLink() private void OpenDocumentationLink()
{ {
// funtimes
// https://brockallen.com/2016/09/24/process-start-for-urls-on-net-core/
// https://github.com/dotnet/runtime/issues/17938
// TODO Move out to a separate service / presenter / message handler // TODO Move out to a separate service / presenter / message handler
#if LINUX
Process.Start("xdg-open", new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
#else
ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri); ProcessStartInfo processStartInfo = new ProcessStartInfo(new Uri(MainFormPresenter.FORUM_URL).AbsoluteUri);
processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo); Process.Start(processStartInfo);
#endif
} }
private string GetApplicationVersion() private string GetApplicationVersion()

View File

@@ -2,14 +2,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
namespace EveOPreview.Services.Implementation namespace EveOPreview.Services.Implementation
{ {
sealed class ProcessMonitor : IProcessMonitor sealed class ProcessMonitor : IProcessMonitor
{ {
#region Private constants #region Private constants
private const string DEFAULT_PROCESS_NAME = "ExeFile"; private const string DEFAULT_PROCESS_NAME = "Uwow-64";
private const string CURRENT_PROCESS_NAME = "EVE-O-Preview"; private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
#endregion #endregion
#region Private fields #region Private fields
@@ -91,7 +92,16 @@ namespace EveOPreview.Services.Implementation
continue; // No need to monitor non-visual processes continue; // No need to monitor non-visual processes
} }
string mainWindowTitle = process.MainWindowTitle; // Get all processes with same name and sort by PID
var sameNameProcesses = Process.GetProcessesByName(processName)
.Where(p => p.MainWindowHandle != IntPtr.Zero)
.OrderBy(p => p.Id)
.ToList();
// Find index of current process in sorted list
int index = sameNameProcesses.FindIndex(p => p.Id == process.Id);
string mainWindowTitle = $"{process.MainWindowTitle} ({index + 1})";
this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle); this._processCache.TryGetValue(mainWindowHandle, out string cachedTitle);
if (cachedTitle == null) if (cachedTitle == null)
@@ -108,9 +118,9 @@ namespace EveOPreview.Services.Implementation
this._processCache[mainWindowHandle] = mainWindowTitle; this._processCache[mainWindowHandle] = mainWindowTitle;
updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle)); updatedProcesses.Add(new ProcessInfo(mainWindowHandle, mainWindowTitle));
} }
knownProcesses.Remove(mainWindowHandle);
} }
knownProcesses.Remove(mainWindowHandle);
} }
foreach (IntPtr index in knownProcesses) foreach (IntPtr index in knownProcesses)

View File

@@ -7,6 +7,9 @@ using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Threading; using System.Windows.Threading;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using EveOPreview.Configuration; using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages; using EveOPreview.Mediator.Messages;
using EveOPreview.UI.Hotkeys; using EveOPreview.UI.Hotkeys;
@@ -49,6 +52,7 @@ namespace EveOPreview.Services
private int _hideThumbnailsDelay; private int _hideThumbnailsDelay;
private List<HotkeyHandler> _cycleClientHotkeyHandlers = new List<HotkeyHandler>(); private List<HotkeyHandler> _cycleClientHotkeyHandlers = new List<HotkeyHandler>();
private HotkeyHandler _toggleTrackingHotkey;
#endregion #endregion
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory) public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
@@ -77,20 +81,57 @@ namespace EveOPreview.Services
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay; this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay;
RegisterCycleClientHotkey(this._configuration.CycleGroup1ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup1ClientsOrder); // RegisterCycleClientHotkey(this._configuration.CycleGroup1ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup1ClientsOrder);
RegisterCycleClientHotkey(this._configuration.CycleGroup1BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup1ClientsOrder); // RegisterCycleClientHotkey(this._configuration.CycleGroup1BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup1ClientsOrder);
//
// RegisterCycleClientHotkey(this._configuration.CycleGroup2ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup2ClientsOrder);
// RegisterCycleClientHotkey(this._configuration.CycleGroup2BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup2ClientsOrder);
//
// RegisterCycleClientHotkey(this._configuration.CycleGroup3ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup3ClientsOrder);
// RegisterCycleClientHotkey(this._configuration.CycleGroup3BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup3ClientsOrder);
//
// RegisterCycleClientHotkey(this._configuration.CycleGroup4ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup4ClientsOrder);
// RegisterCycleClientHotkey(this._configuration.CycleGroup4BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup4ClientsOrder);
//
// RegisterCycleClientHotkey(this._configuration.CycleGroup5ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup5ClientsOrder);
// RegisterCycleClientHotkey(this._configuration.CycleGroup5BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup5ClientsOrder);
//
// Setup toggle tracking hotkey (Ctrl+T)
var mainHandle = this._processMonitor.GetMainProcess().Handle;
System.Diagnostics.Debug.WriteLine($"Registering hotkey with main window handle: {mainHandle}");
this._toggleTrackingHotkey = new HotkeyHandler(mainHandle, Keys.Alt | Keys.F16);
this._toggleTrackingHotkey.Pressed += (object s, HandledEventArgs e) =>
{
var foregroundHandle = this._windowManager.GetForegroundWindowHandle();
if (foregroundHandle != IntPtr.Zero)
{
uint processId;
GetWindowThreadProcessId(foregroundHandle, out processId);
var process = Process.GetProcessById((int)processId);
RegisterCycleClientHotkey(this._configuration.CycleGroup2ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup2ClientsOrder); if (process != null)
RegisterCycleClientHotkey(this._configuration.CycleGroup2BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup2ClientsOrder); {
System.Diagnostics.Debug.WriteLine($"Found process: {process.ProcessName}");
RegisterCycleClientHotkey(this._configuration.CycleGroup3ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup3ClientsOrder); if (_configuration.IsExecutableToPreview(process.ProcessName))
RegisterCycleClientHotkey(this._configuration.CycleGroup3BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup3ClientsOrder); {
System.Diagnostics.Debug.WriteLine("Removing from executables to preview");
RegisterCycleClientHotkey(this._configuration.CycleGroup4ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup4ClientsOrder); var exesToPreview = _configuration.ExecutablesToPreview.ToList();
RegisterCycleClientHotkey(this._configuration.CycleGroup4BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup4ClientsOrder); exesToPreview.Remove(process.ProcessName.ToLower());
_configuration.ExecutablesToPreview = exesToPreview;
RegisterCycleClientHotkey(this._configuration.CycleGroup5ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup5ClientsOrder); }
RegisterCycleClientHotkey(this._configuration.CycleGroup5BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup5ClientsOrder); else
{
System.Diagnostics.Debug.WriteLine("Adding to executables to preview");
var exesToPreview = _configuration.ExecutablesToPreview.ToList();
exesToPreview.Add(process.ProcessName.ToLower());
_configuration.ExecutablesToPreview = exesToPreview;
}
e.Handled = true;
}
}
};
var registered = this._toggleTrackingHotkey.Register();
System.Diagnostics.Debug.WriteLine($"Hotkey registration result: {registered}");
} }
public IThumbnailView GetClientByTitle(string title) public IThumbnailView GetClientByTitle(string title)
@@ -127,7 +168,7 @@ namespace EveOPreview.Services
IOrderedEnumerable<KeyValuePair<string, int>> clientOrder; IOrderedEnumerable<KeyValuePair<string, int>> clientOrder;
Dictionary<string, int> _cycleOrder = new Dictionary<string, int>(cycleOrder); Dictionary<string, int> _cycleOrder = new Dictionary<string, int>(cycleOrder);
if ( _cycleOrder.Count == 0 ) if ( _cycleOrder.Count == 0 )
{ {
int order = 0; int order = 0;
foreach( var x in _thumbnailViews) foreach( var x in _thumbnailViews)
@@ -197,7 +238,7 @@ namespace EveOPreview.Services
if (_thumbnailViews.Any(x => x.Value.Title == t.Key)) if (_thumbnailViews.Any(x => x.Value.Title == t.Key))
{ {
var ptr = t.Key.Equals("EVE") ? var ptr = t.Key.Equals("EVE") ?
(isForwards ? _thumbnailViews.OrderBy(x => x.Value.Id.ToInt64()) : _thumbnailViews.OrderByDescending(x => x.Value.Id.ToInt64())).First(x => x.Value.Title == t.Key) (isForwards ? _thumbnailViews.OrderBy(x => x.Value.Id.ToInt64()) : _thumbnailViews.OrderByDescending(x => x.Value.Id.ToInt64())).First(x => x.Value.Title == t.Key)
: _thumbnailViews.First(x => x.Value.Title == t.Key); : _thumbnailViews.First(x => x.Value.Title == t.Key);
SetActive(ptr); SetActive(ptr);
@@ -498,7 +539,7 @@ namespace EveOPreview.Services
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays; view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetHighlight( view.SetHighlight(
this._configuration.EnableActiveClientHighlight && (view.Id == this._activeClient.Handle), this._configuration.EnableActiveClientHighlight && (view.Id == this._activeClient.Handle),
this._configuration.ActiveClientHighlightThickness); this._configuration.ActiveClientHighlightThickness);
if (!view.IsActive) if (!view.IsActive)
@@ -566,6 +607,11 @@ namespace EveOPreview.Services
if (this._configuration.MinimizeInactiveClients && !this._configuration.IsPriorityClient(this._activeClient.Title)) if (this._configuration.MinimizeInactiveClients && !this._configuration.IsPriorityClient(this._activeClient.Title))
{ {
this._windowManager.MinimizeWindow(this._activeClient.Handle, this._configuration.WindowsAnimationStyle, false); this._windowManager.MinimizeWindow(this._activeClient.Handle, this._configuration.WindowsAnimationStyle, false);
#if LINUX
this._windowManager.ActivateWindow(foregroundClientHandle, foregroundClientTitle);
#else
this._windowManager.ActivateWindow(foregroundClientHandle, this._configuration.WindowsAnimationStyle);
#endif
} }
this._activeClient = (foregroundClientHandle, foregroundClientTitle); this._activeClient = (foregroundClientHandle, foregroundClientTitle);
@@ -949,5 +995,23 @@ namespace EveOPreview.Services
&& (top > ThumbnailManager.WINDOW_POSITION_THRESHOLD_LOW) && (top < ThumbnailManager.WINDOW_POSITION_THRESHOLD_HIGH) && (top > ThumbnailManager.WINDOW_POSITION_THRESHOLD_LOW) && (top < ThumbnailManager.WINDOW_POSITION_THRESHOLD_HIGH)
&& (width > ThumbnailManager.WINDOW_SIZE_THRESHOLD) && (height > ThumbnailManager.WINDOW_SIZE_THRESHOLD); && (width > ThumbnailManager.WINDOW_SIZE_THRESHOLD) && (height > ThumbnailManager.WINDOW_SIZE_THRESHOLD);
} }
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
} }
} }