mirror of
https://github.com/kangyu-california/PersistentWindows.git
synced 2025-05-11 04:55:39 +02:00
capture user move window action instantly with precision without using delay timer
This commit is contained in:
parent
29f24db354
commit
aa8b478eda
1 changed files with 32 additions and 50 deletions
|
@ -22,9 +22,6 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
private const int MaxRestoreTimesRemote = 6; // for remote session
|
private const int MaxRestoreTimesRemote = 6; // for remote session
|
||||||
|
|
||||||
private const int CaptureLatency = 3000; // milliseconds to wait for window position capture, should be bigger than RestoreLatency
|
private const int CaptureLatency = 3000; // milliseconds to wait for window position capture, should be bigger than RestoreLatency
|
||||||
private const int MaxCaptureLatency = 15000; // max latency to capture OS moves, needed for slow RDP session
|
|
||||||
private const int MaxUserMovePerSecond = 4; // maximum speed of window move/resize by human
|
|
||||||
private const int MinOsMoveWindows = 5; // minimum number of moving windows to measure in order to recognize OS initiated move
|
|
||||||
|
|
||||||
// window position database
|
// window position database
|
||||||
private Dictionary<string, Dictionary<string, ApplicationDisplayMetrics>> monitorApplications = null;
|
private Dictionary<string, Dictionary<string, ApplicationDisplayMetrics>> monitorApplications = null;
|
||||||
|
@ -37,14 +34,8 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
private Object controlLock = new Object();
|
private Object controlLock = new Object();
|
||||||
private string validDisplayKeyForCapture = null;
|
private string validDisplayKeyForCapture = null;
|
||||||
|
|
||||||
// capture control: window move/resize activity
|
|
||||||
private int userMoves = 0; // user initiated window move/resize events
|
|
||||||
private DateTime firstEventTime;
|
|
||||||
private HashSet<IntPtr> pendingCaptureWindows = new HashSet<IntPtr>();
|
|
||||||
|
|
||||||
// restore control
|
// restore control
|
||||||
private bool restoringWindowPos = false; // about to restore
|
private bool restoringWindowPos = false; // about to restore
|
||||||
private bool osMove = false; // window move/resize is initiated by OS
|
|
||||||
private int restoreTimes = 0;
|
private int restoreTimes = 0;
|
||||||
private int restoreNestLevel = 0; // nested call level
|
private int restoreNestLevel = 0; // nested call level
|
||||||
|
|
||||||
|
@ -71,7 +62,6 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
BeginCaptureApplicationsOnCurrentDisplays();
|
BeginCaptureApplicationsOnCurrentDisplays();
|
||||||
});
|
});
|
||||||
|
|
||||||
firstEventTime = DateTime.Now;
|
|
||||||
validDisplayKeyForCapture = GetDisplayKey();
|
validDisplayKeyForCapture = GetDisplayKey();
|
||||||
StartCaptureTimer(); //initial capture
|
StartCaptureTimer(); //initial capture
|
||||||
|
|
||||||
|
@ -85,7 +75,6 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
{
|
{
|
||||||
Log.Trace("Restore Finished");
|
Log.Trace("Restore Finished");
|
||||||
restoringWindowPos = false;
|
restoringWindowPos = false;
|
||||||
osMove = false;
|
|
||||||
ResetState();
|
ResetState();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -244,25 +233,6 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
Log.Trace(log);
|
Log.Trace(log);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DateTime now = DateTime.Now;
|
|
||||||
|
|
||||||
if (pendingCaptureWindows.Count() == 0)
|
|
||||||
{
|
|
||||||
firstEventTime = now;
|
|
||||||
}
|
|
||||||
pendingCaptureWindows.Add(hwnd);
|
|
||||||
|
|
||||||
// figure out if all pending capture moves are OS initiated
|
|
||||||
double elapsedMs = (now - firstEventTime).TotalMilliseconds;
|
|
||||||
if (userMoves == 0
|
|
||||||
&& pendingCaptureWindows.Count >= MinOsMoveWindows
|
|
||||||
&& elapsedMs * MaxUserMovePerSecond / 1000 < pendingCaptureWindows.Count)
|
|
||||||
{
|
|
||||||
osMove = true;
|
|
||||||
Log.Trace("os move detected. user moves :{0}, total moved windows : {1}, elapsed milliseconds {2}",
|
|
||||||
userMoves, pendingCaptureWindows.Count, elapsedMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (restoringWindowPos)
|
if (restoringWindowPos)
|
||||||
{
|
{
|
||||||
switch (eventType)
|
switch (eventType)
|
||||||
|
@ -271,6 +241,7 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
// if user opened new window, don't abort restore, as new window is not affected by restore anyway
|
// if user opened new window, don't abort restore, as new window is not affected by restore anyway
|
||||||
return;
|
return;
|
||||||
case User32Events.EVENT_OBJECT_LOCATIONCHANGE:
|
case User32Events.EVENT_OBJECT_LOCATIONCHANGE:
|
||||||
|
// let it trigger next restore
|
||||||
break;
|
break;
|
||||||
case User32Events.EVENT_SYSTEM_MINIMIZESTART:
|
case User32Events.EVENT_SYSTEM_MINIMIZESTART:
|
||||||
case User32Events.EVENT_SYSTEM_MINIMIZEEND:
|
case User32Events.EVENT_SYSTEM_MINIMIZEEND:
|
||||||
|
@ -283,7 +254,8 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
{
|
{
|
||||||
lock (databaseLock)
|
lock (databaseLock)
|
||||||
{
|
{
|
||||||
StartCaptureApplicationsOnCurrentDisplays();
|
string displayKey = GetDisplayKey();
|
||||||
|
CaptureWindow(window, eventType, DateTime.Now, displayKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -307,6 +279,34 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
switch (eventType)
|
||||||
|
{
|
||||||
|
case User32Events.EVENT_OBJECT_LOCATIONCHANGE:
|
||||||
|
break;
|
||||||
|
case User32Events.EVENT_SYSTEM_FOREGROUND:
|
||||||
|
case User32Events.EVENT_SYSTEM_MINIMIZESTART:
|
||||||
|
case User32Events.EVENT_SYSTEM_MINIMIZEEND:
|
||||||
|
case User32Events.EVENT_SYSTEM_MOVESIZEEND:
|
||||||
|
var thread = new Thread(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (databaseLock)
|
||||||
|
{
|
||||||
|
string displayKey = GetDisplayKey();
|
||||||
|
CaptureWindow(window, eventType, DateTime.Now, displayKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.Start();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (eventType != User32Events.EVENT_OBJECT_LOCATIONCHANGE)
|
if (eventType != User32Events.EVENT_OBJECT_LOCATIONCHANGE)
|
||||||
{
|
{
|
||||||
userMoves++;
|
userMoves++;
|
||||||
|
@ -316,6 +316,7 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
{
|
{
|
||||||
StartCaptureTimer();
|
StartCaptureTimer();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -424,22 +425,6 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restoringWindowPos && userMoves == 0 && pendingCaptureWindows.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osMove)
|
|
||||||
{
|
|
||||||
// postpone capture to wait for restore
|
|
||||||
osMove = false;
|
|
||||||
if (!restoringWindowPos)
|
|
||||||
{
|
|
||||||
StartCaptureTimer(MaxCaptureLatency);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (databaseLock)
|
lock (databaseLock)
|
||||||
{
|
{
|
||||||
StartCaptureApplicationsOnCurrentDisplays();
|
StartCaptureApplicationsOnCurrentDisplays();
|
||||||
|
@ -467,15 +452,12 @@ namespace Ninjacrab.PersistentWindows.Common
|
||||||
|
|
||||||
// reset capture statistics for next capture period
|
// reset capture statistics for next capture period
|
||||||
CancelCaptureTimer();
|
CancelCaptureTimer();
|
||||||
pendingCaptureWindows.Clear();
|
|
||||||
userMoves = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartCaptureApplicationsOnCurrentDisplays()
|
private void StartCaptureApplicationsOnCurrentDisplays()
|
||||||
{
|
{
|
||||||
restoringWindowPos = false;
|
restoringWindowPos = false;
|
||||||
osMove = false;
|
|
||||||
ResetState();
|
ResetState();
|
||||||
CaptureApplicationsOnCurrentDisplays();
|
CaptureApplicationsOnCurrentDisplays();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue