185: [Bug] Previews flicker when switching between clients with 'Hide previews when EVE client not active'
This commit is contained in:
@@ -32,9 +32,11 @@ namespace EveOPreview.Configuration.Implementation
|
||||
this.HideActiveClientThumbnail = false;
|
||||
this.MinimizeInactiveClients = false;
|
||||
this.ShowThumbnailsAlwaysOnTop = true;
|
||||
this.HideThumbnailsOnLostFocus = false;
|
||||
this.EnablePerClientThumbnailLayouts = false;
|
||||
|
||||
this.HideThumbnailsOnLostFocus = false;
|
||||
this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec)
|
||||
|
||||
this.ThumbnailSize = new Size(384, 216);
|
||||
this.ThumbnailMinimumSize = new Size(192, 108);
|
||||
this.ThumbnailMaximumSize = new Size(960, 540);
|
||||
@@ -79,7 +81,6 @@ namespace EveOPreview.Configuration.Implementation
|
||||
public bool HideActiveClientThumbnail { get; set; }
|
||||
public bool MinimizeInactiveClients { get; set; }
|
||||
public bool ShowThumbnailsAlwaysOnTop { get; set; }
|
||||
public bool HideThumbnailsOnLostFocus { get; set; }
|
||||
|
||||
public bool EnablePerClientThumbnailLayouts
|
||||
{
|
||||
@@ -95,6 +96,9 @@ namespace EveOPreview.Configuration.Implementation
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideThumbnailsOnLostFocus { get; set; }
|
||||
public int HideThumbnailsDelay { get; set; }
|
||||
|
||||
public Size ThumbnailSize { get; set; }
|
||||
public Size ThumbnailMaximumSize { get; set; }
|
||||
public Size ThumbnailMinimumSize { get; set; }
|
||||
|
@@ -16,9 +16,11 @@ namespace EveOPreview.Configuration
|
||||
bool HideActiveClientThumbnail { get; set; }
|
||||
bool MinimizeInactiveClients { get; set; }
|
||||
bool ShowThumbnailsAlwaysOnTop { get; set; }
|
||||
bool HideThumbnailsOnLostFocus { get; set; }
|
||||
bool EnablePerClientThumbnailLayouts { get; set; }
|
||||
|
||||
bool HideThumbnailsOnLostFocus { get; set; }
|
||||
int HideThumbnailsDelay { get; set; }
|
||||
|
||||
Size ThumbnailSize { get; set; }
|
||||
Size ThumbnailMinimumSize { get; set; }
|
||||
Size ThumbnailMaximumSize { get; set; }
|
||||
|
@@ -8,15 +8,21 @@ namespace EveOPreview.Services.Implementation
|
||||
{
|
||||
#region Private constants
|
||||
private const string DEFAULT_PROCESS_NAME = "ExeFile";
|
||||
private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
|
||||
#endregion
|
||||
|
||||
#region Private fields
|
||||
private readonly IDictionary<IntPtr, string> _processCache;
|
||||
private IProcessInfo _currentProcessInfo;
|
||||
#endregion
|
||||
|
||||
public ProcessMonitor()
|
||||
{
|
||||
this._processCache = new Dictionary<IntPtr, string>(512);
|
||||
|
||||
// This field cannot be initialized properly in constructor
|
||||
// At the moment this code is executed the main application window is not yet initialized
|
||||
this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, "");
|
||||
}
|
||||
|
||||
private bool IsMonitoredProcess(string processName)
|
||||
@@ -25,6 +31,41 @@ namespace EveOPreview.Services.Implementation
|
||||
return String.Equals(processName, ProcessMonitor.DEFAULT_PROCESS_NAME, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private IProcessInfo GetCurrentProcessInfo()
|
||||
{
|
||||
var currentProcess = Process.GetCurrentProcess();
|
||||
return new ProcessInfo(currentProcess.MainWindowHandle, currentProcess.MainWindowTitle);
|
||||
}
|
||||
|
||||
public IProcessInfo GetMainProcess()
|
||||
{
|
||||
if (this._currentProcessInfo.Handle == IntPtr.Zero)
|
||||
{
|
||||
var processInfo = this.GetCurrentProcessInfo();
|
||||
|
||||
// Are we initialized yet?
|
||||
if (processInfo.Title != "")
|
||||
{
|
||||
this._currentProcessInfo = processInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return this._currentProcessInfo;
|
||||
}
|
||||
|
||||
public ICollection<IProcessInfo> GetAllProcesses()
|
||||
{
|
||||
ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count);
|
||||
|
||||
// TODO Lock list here just in case
|
||||
foreach (KeyValuePair<IntPtr, string> entry in this._processCache)
|
||||
{
|
||||
result.Add(new ProcessInfo(entry.Key, entry.Value));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses)
|
||||
{
|
||||
addedProcesses = new List<IProcessInfo>(16);
|
||||
@@ -76,18 +117,5 @@ namespace EveOPreview.Services.Implementation
|
||||
this._processCache.Remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<IProcessInfo> GetAllProcesses()
|
||||
{
|
||||
ICollection<IProcessInfo> result = new List<IProcessInfo>(this._processCache.Count);
|
||||
|
||||
// TODO Lock list here just in case
|
||||
foreach (KeyValuePair<IntPtr, string> entry in this._processCache)
|
||||
{
|
||||
result.Add(new ProcessInfo(entry.Key, entry.Value));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -41,6 +41,7 @@ namespace EveOPreview.Services
|
||||
private bool _isHoverEffectActive;
|
||||
|
||||
private int _refreshCycleCount;
|
||||
private int _hideThumbnailsDelay;
|
||||
#endregion
|
||||
|
||||
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
|
||||
@@ -66,6 +67,8 @@ namespace EveOPreview.Services
|
||||
this._thumbnailUpdateTimer = new DispatcherTimer();
|
||||
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
|
||||
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
|
||||
|
||||
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
@@ -180,10 +183,19 @@ namespace EveOPreview.Services
|
||||
{
|
||||
// TODO Split this method
|
||||
IntPtr foregroundWindowHandle = this._windowManager.GetForegroundWindowHandle();
|
||||
|
||||
// The foreground window can be NULL in certain circumstances, such as when a window is losing activation.
|
||||
// It is safer to just skip this refresh round than to do something while the system state is undefined
|
||||
if (foregroundWindowHandle == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string foregroundWindowTitle = null;
|
||||
|
||||
// Check if the foreground window handle is one of the known handles for client windows or their thumbnails
|
||||
bool isClientWindow = this.IsClientWindowActive(foregroundWindowHandle);
|
||||
bool isMainWindowActive = this.IsMainWindowActive(foregroundWindowHandle);
|
||||
|
||||
if (foregroundWindowHandle == this._activeClient.Handle)
|
||||
{
|
||||
@@ -195,14 +207,9 @@ namespace EveOPreview.Services
|
||||
foregroundWindowTitle = foregroundView.Title;
|
||||
}
|
||||
else if (!isClientWindow)
|
||||
{
|
||||
// Under some circumstances Foreground WindowHandle can be zero
|
||||
// (f.e. when Thumbnail is silently stealing focus from the currently open app)
|
||||
if (foregroundWindowHandle != IntPtr.Zero)
|
||||
{
|
||||
this._externalApplication = foregroundWindowHandle;
|
||||
}
|
||||
}
|
||||
|
||||
// No need to minimize EVE clients when switching out to non-EVE window (like thumbnail)
|
||||
if (!string.IsNullOrEmpty(foregroundWindowTitle))
|
||||
@@ -210,7 +217,25 @@ namespace EveOPreview.Services
|
||||
this.SwitchActiveClient(foregroundWindowHandle, foregroundWindowTitle);
|
||||
}
|
||||
|
||||
bool hideAllThumbnails = this._configuration.HideThumbnailsOnLostFocus && !isClientWindow;
|
||||
bool hideAllThumbnails = this._configuration.HideThumbnailsOnLostFocus && !(isClientWindow || isMainWindowActive);
|
||||
|
||||
// Wait for some time before hiding all previews
|
||||
if (hideAllThumbnails)
|
||||
{
|
||||
this._hideThumbnailsDelay--;
|
||||
if (this._hideThumbnailsDelay > 0)
|
||||
{
|
||||
hideAllThumbnails = false; // Postpone the 'hide all' operation
|
||||
}
|
||||
else
|
||||
{
|
||||
this._hideThumbnailsDelay = 0; // Stop the counter
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay; // Reset the counter
|
||||
}
|
||||
|
||||
this._refreshCycleCount++;
|
||||
|
||||
@@ -456,6 +481,7 @@ namespace EveOPreview.Services
|
||||
this.EnqueueLocationChange(view);
|
||||
}
|
||||
|
||||
// Checks whether currently active window belongs to an EVE client or its thumbnail
|
||||
private bool IsClientWindowActive(IntPtr windowHandle)
|
||||
{
|
||||
if (windowHandle == IntPtr.Zero)
|
||||
@@ -476,6 +502,12 @@ namespace EveOPreview.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check whether the currently active window belongs to EVE-O Preview itself
|
||||
private bool IsMainWindowActive(IntPtr windowHandle)
|
||||
{
|
||||
return (this._processMonitor.GetMainProcess().Handle == windowHandle);
|
||||
}
|
||||
|
||||
private void ThumbnailZoomIn(IThumbnailView view)
|
||||
{
|
||||
this.DisableViewEvents();
|
||||
|
@@ -4,6 +4,7 @@ namespace EveOPreview.Services
|
||||
{
|
||||
public interface IProcessMonitor
|
||||
{
|
||||
IProcessInfo GetMainProcess();
|
||||
ICollection<IProcessInfo> GetAllProcesses();
|
||||
void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses);
|
||||
}
|
||||
|
Reference in New Issue
Block a user