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.HideActiveClientThumbnail = false;
|
||||||
this.MinimizeInactiveClients = false;
|
this.MinimizeInactiveClients = false;
|
||||||
this.ShowThumbnailsAlwaysOnTop = true;
|
this.ShowThumbnailsAlwaysOnTop = true;
|
||||||
this.HideThumbnailsOnLostFocus = false;
|
|
||||||
this.EnablePerClientThumbnailLayouts = false;
|
this.EnablePerClientThumbnailLayouts = false;
|
||||||
|
|
||||||
|
this.HideThumbnailsOnLostFocus = false;
|
||||||
|
this.HideThumbnailsDelay = 2; // 2 thumbnails refresh cycles (1.0 sec)
|
||||||
|
|
||||||
this.ThumbnailSize = new Size(384, 216);
|
this.ThumbnailSize = new Size(384, 216);
|
||||||
this.ThumbnailMinimumSize = new Size(192, 108);
|
this.ThumbnailMinimumSize = new Size(192, 108);
|
||||||
this.ThumbnailMaximumSize = new Size(960, 540);
|
this.ThumbnailMaximumSize = new Size(960, 540);
|
||||||
@@ -79,7 +81,6 @@ namespace EveOPreview.Configuration.Implementation
|
|||||||
public bool HideActiveClientThumbnail { get; set; }
|
public bool HideActiveClientThumbnail { get; set; }
|
||||||
public bool MinimizeInactiveClients { get; set; }
|
public bool MinimizeInactiveClients { get; set; }
|
||||||
public bool ShowThumbnailsAlwaysOnTop { get; set; }
|
public bool ShowThumbnailsAlwaysOnTop { get; set; }
|
||||||
public bool HideThumbnailsOnLostFocus { get; set; }
|
|
||||||
|
|
||||||
public bool EnablePerClientThumbnailLayouts
|
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 ThumbnailSize { get; set; }
|
||||||
public Size ThumbnailMaximumSize { get; set; }
|
public Size ThumbnailMaximumSize { get; set; }
|
||||||
public Size ThumbnailMinimumSize { get; set; }
|
public Size ThumbnailMinimumSize { get; set; }
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ namespace EveOPreview.Configuration
|
|||||||
bool HideActiveClientThumbnail { get; set; }
|
bool HideActiveClientThumbnail { get; set; }
|
||||||
bool MinimizeInactiveClients { get; set; }
|
bool MinimizeInactiveClients { get; set; }
|
||||||
bool ShowThumbnailsAlwaysOnTop { get; set; }
|
bool ShowThumbnailsAlwaysOnTop { get; set; }
|
||||||
bool HideThumbnailsOnLostFocus { get; set; }
|
|
||||||
bool EnablePerClientThumbnailLayouts { get; set; }
|
bool EnablePerClientThumbnailLayouts { get; set; }
|
||||||
|
|
||||||
|
bool HideThumbnailsOnLostFocus { get; set; }
|
||||||
|
int HideThumbnailsDelay { get; set; }
|
||||||
|
|
||||||
Size ThumbnailSize { get; set; }
|
Size ThumbnailSize { get; set; }
|
||||||
Size ThumbnailMinimumSize { get; set; }
|
Size ThumbnailMinimumSize { get; set; }
|
||||||
Size ThumbnailMaximumSize { get; set; }
|
Size ThumbnailMaximumSize { get; set; }
|
||||||
|
|||||||
@@ -8,15 +8,21 @@ namespace EveOPreview.Services.Implementation
|
|||||||
{
|
{
|
||||||
#region Private constants
|
#region Private constants
|
||||||
private const string DEFAULT_PROCESS_NAME = "ExeFile";
|
private const string DEFAULT_PROCESS_NAME = "ExeFile";
|
||||||
|
private const string CURRENT_PROCESS_NAME = "EVE-O Preview";
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private fields
|
#region Private fields
|
||||||
private readonly IDictionary<IntPtr, string> _processCache;
|
private readonly IDictionary<IntPtr, string> _processCache;
|
||||||
|
private IProcessInfo _currentProcessInfo;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public ProcessMonitor()
|
public ProcessMonitor()
|
||||||
{
|
{
|
||||||
this._processCache = new Dictionary<IntPtr, string>(512);
|
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)
|
private bool IsMonitoredProcess(string processName)
|
||||||
@@ -25,6 +31,41 @@ namespace EveOPreview.Services.Implementation
|
|||||||
return String.Equals(processName, ProcessMonitor.DEFAULT_PROCESS_NAME, StringComparison.OrdinalIgnoreCase);
|
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)
|
public void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses)
|
||||||
{
|
{
|
||||||
addedProcesses = new List<IProcessInfo>(16);
|
addedProcesses = new List<IProcessInfo>(16);
|
||||||
@@ -76,18 +117,5 @@ namespace EveOPreview.Services.Implementation
|
|||||||
this._processCache.Remove(index);
|
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 bool _isHoverEffectActive;
|
||||||
|
|
||||||
private int _refreshCycleCount;
|
private int _refreshCycleCount;
|
||||||
|
private int _hideThumbnailsDelay;
|
||||||
#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)
|
||||||
@@ -66,6 +67,8 @@ namespace EveOPreview.Services
|
|||||||
this._thumbnailUpdateTimer = new DispatcherTimer();
|
this._thumbnailUpdateTimer = new DispatcherTimer();
|
||||||
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
|
this._thumbnailUpdateTimer.Tick += ThumbnailUpdateTimerTick;
|
||||||
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
|
this._thumbnailUpdateTimer.Interval = new TimeSpan(0, 0, 0, 0, configuration.ThumbnailRefreshPeriod);
|
||||||
|
|
||||||
|
this._hideThumbnailsDelay = this._configuration.HideThumbnailsDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
@@ -180,10 +183,19 @@ namespace EveOPreview.Services
|
|||||||
{
|
{
|
||||||
// TODO Split this method
|
// TODO Split this method
|
||||||
IntPtr foregroundWindowHandle = this._windowManager.GetForegroundWindowHandle();
|
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;
|
string foregroundWindowTitle = null;
|
||||||
|
|
||||||
// Check if the foreground window handle is one of the known handles for client windows or their thumbnails
|
// Check if the foreground window handle is one of the known handles for client windows or their thumbnails
|
||||||
bool isClientWindow = this.IsClientWindowActive(foregroundWindowHandle);
|
bool isClientWindow = this.IsClientWindowActive(foregroundWindowHandle);
|
||||||
|
bool isMainWindowActive = this.IsMainWindowActive(foregroundWindowHandle);
|
||||||
|
|
||||||
if (foregroundWindowHandle == this._activeClient.Handle)
|
if (foregroundWindowHandle == this._activeClient.Handle)
|
||||||
{
|
{
|
||||||
@@ -195,14 +207,9 @@ namespace EveOPreview.Services
|
|||||||
foregroundWindowTitle = foregroundView.Title;
|
foregroundWindowTitle = foregroundView.Title;
|
||||||
}
|
}
|
||||||
else if (!isClientWindow)
|
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;
|
this._externalApplication = foregroundWindowHandle;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// No need to minimize EVE clients when switching out to non-EVE window (like thumbnail)
|
// No need to minimize EVE clients when switching out to non-EVE window (like thumbnail)
|
||||||
if (!string.IsNullOrEmpty(foregroundWindowTitle))
|
if (!string.IsNullOrEmpty(foregroundWindowTitle))
|
||||||
@@ -210,7 +217,25 @@ namespace EveOPreview.Services
|
|||||||
this.SwitchActiveClient(foregroundWindowHandle, foregroundWindowTitle);
|
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++;
|
this._refreshCycleCount++;
|
||||||
|
|
||||||
@@ -456,6 +481,7 @@ namespace EveOPreview.Services
|
|||||||
this.EnqueueLocationChange(view);
|
this.EnqueueLocationChange(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks whether currently active window belongs to an EVE client or its thumbnail
|
||||||
private bool IsClientWindowActive(IntPtr windowHandle)
|
private bool IsClientWindowActive(IntPtr windowHandle)
|
||||||
{
|
{
|
||||||
if (windowHandle == IntPtr.Zero)
|
if (windowHandle == IntPtr.Zero)
|
||||||
@@ -476,6 +502,12 @@ namespace EveOPreview.Services
|
|||||||
return false;
|
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)
|
private void ThumbnailZoomIn(IThumbnailView view)
|
||||||
{
|
{
|
||||||
this.DisableViewEvents();
|
this.DisableViewEvents();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace EveOPreview.Services
|
|||||||
{
|
{
|
||||||
public interface IProcessMonitor
|
public interface IProcessMonitor
|
||||||
{
|
{
|
||||||
|
IProcessInfo GetMainProcess();
|
||||||
ICollection<IProcessInfo> GetAllProcesses();
|
ICollection<IProcessInfo> GetAllProcesses();
|
||||||
void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses);
|
void GetUpdatedProcesses(out ICollection<IProcessInfo> addedProcesses, out ICollection<IProcessInfo> updatedProcesses, out ICollection<IProcessInfo> removedProcesses);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user