mirror of
https://github.com/QL-Win/QuickLook.git
synced 2026-02-28 01:00:17 +08:00
Fix #715: add 1s timeout before any previewing request
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -80,7 +78,7 @@ namespace QuickLook
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CheckUpdate();
|
||||
RunListener(e);
|
||||
|
||||
@@ -115,7 +113,7 @@ namespace QuickLook
|
||||
|
||||
PluginManager.GetInstance();
|
||||
ViewWindowManager.GetInstance();
|
||||
BackgroundListener.GetInstance();
|
||||
KeystrokeDispatcher.GetInstance();
|
||||
PipeServerManager.GetInstance();
|
||||
}
|
||||
|
||||
@@ -128,7 +126,7 @@ namespace QuickLook
|
||||
|
||||
PipeServerManager.GetInstance().Dispose();
|
||||
TrayIconManager.GetInstance().Dispose();
|
||||
BackgroundListener.GetInstance().Dispose();
|
||||
KeystrokeDispatcher.GetInstance().Dispose();
|
||||
ViewWindowManager.GetInstance().Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using QuickLook.Common.NativeMethods;
|
||||
using KeyEventArgs = System.Windows.Forms.KeyEventArgs;
|
||||
using KeyEventHandler = System.Windows.Forms.KeyEventHandler;
|
||||
|
||||
namespace QuickLook
|
||||
namespace QuickLook.Helpers
|
||||
{
|
||||
internal class GlobalKeyboardHook : IDisposable
|
||||
{
|
||||
@@ -31,7 +30,6 @@ namespace QuickLook
|
||||
|
||||
private User32.KeyboardHookProc _callback;
|
||||
private IntPtr _hhook = IntPtr.Zero;
|
||||
internal List<Keys> HookedKeys = new List<Keys>();
|
||||
|
||||
protected GlobalKeyboardHook()
|
||||
{
|
||||
@@ -72,25 +70,23 @@ namespace QuickLook
|
||||
|
||||
private int HookProc(int code, int wParam, ref User32.KeyboardHookStruct lParam)
|
||||
{
|
||||
if (code >= 0)
|
||||
if (!IsWindowsKeyPressed())
|
||||
{
|
||||
var key = (Keys) lParam.vkCode;
|
||||
if (HookedKeys.Contains(key))
|
||||
{
|
||||
key = AddModifiers(key);
|
||||
if (code < 0)
|
||||
return User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
|
||||
|
||||
var kea = new KeyEventArgs(key);
|
||||
if (wParam == User32.WM_KEYDOWN || wParam == User32.WM_SYSKEYDOWN)
|
||||
KeyDown?.Invoke(this, kea);
|
||||
if (wParam == User32.WM_KEYUP || wParam == User32.WM_SYSKEYUP)
|
||||
KeyUp?.Invoke(this, kea);
|
||||
if (kea.Handled)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (IsWindowsKeyPressed())
|
||||
return User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
|
||||
|
||||
return User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
|
||||
var key = (Keys) lParam.vkCode;
|
||||
key = AddModifiers(key);
|
||||
|
||||
var kea = new KeyEventArgs(key);
|
||||
|
||||
if (wParam == User32.WM_KEYDOWN || wParam == User32.WM_SYSKEYDOWN)
|
||||
KeyDown?.Invoke(this, kea);
|
||||
else if (wParam == User32.WM_KEYUP || wParam == User32.WM_SYSKEYUP)
|
||||
KeyUp?.Invoke(this, kea);
|
||||
|
||||
return kea.Handled ? 1 : User32.CallNextHookEx(_hhook, code, wParam, ref lParam);
|
||||
}
|
||||
|
||||
private bool IsWindowsKeyPressed()
|
||||
@@ -16,22 +16,35 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using QuickLook.Common.Helpers;
|
||||
using QuickLook.Helpers;
|
||||
|
||||
namespace QuickLook
|
||||
{
|
||||
internal class BackgroundListener : IDisposable
|
||||
internal class KeystrokeDispatcher : IDisposable
|
||||
{
|
||||
private static BackgroundListener _instance;
|
||||
private static KeystrokeDispatcher _instance;
|
||||
|
||||
private static HashSet<Keys> _validKeys;
|
||||
|
||||
private GlobalKeyboardHook _hook;
|
||||
private bool _isKeyDownInDesktopOrShell;
|
||||
private long _lastInvalidKeyPressTick;
|
||||
|
||||
protected BackgroundListener()
|
||||
private const long VALID_KEY_PRESS_DELAY = TimeSpan.TicksPerSecond * 1;
|
||||
|
||||
protected KeystrokeDispatcher()
|
||||
{
|
||||
InstallKeyHook(KeyDownEventHandler, KeyUpEventHandler);
|
||||
|
||||
_validKeys = new HashSet<Keys>(new[]
|
||||
{
|
||||
Keys.Up, Keys.Down, Keys.Left, Keys.Right,
|
||||
Keys.Enter, Keys.Space, Keys.Escape
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -55,7 +68,7 @@ namespace QuickLook
|
||||
if (e.Modifiers != Keys.None)
|
||||
return;
|
||||
|
||||
// set variable only when KeyDown
|
||||
// check if the window is valid at the time of pressing a key, used for case 1
|
||||
if (isKeyDown)
|
||||
{
|
||||
_isKeyDownInDesktopOrShell = NativeMethods.QuickLook.GetFocusedWindowType() !=
|
||||
@@ -64,17 +77,32 @@ namespace QuickLook
|
||||
_isKeyDownInDesktopOrShell |= WindowHelper.IsForegroundWindowBelongToSelf();
|
||||
}
|
||||
|
||||
// call InvokeRoutine only when the KeyDown is valid
|
||||
// call InvokeRoutine only when:
|
||||
// (1) user released a key which was pressed in a valid window, or
|
||||
// (2) user pressed a key in a valid window
|
||||
if (_isKeyDownInDesktopOrShell)
|
||||
InvokeRoutine(e.KeyCode, isKeyDown);
|
||||
|
||||
// reset variable only when KeyUp
|
||||
// in case 2, reset the variable
|
||||
if (!isKeyDown)
|
||||
_isKeyDownInDesktopOrShell = false;
|
||||
}
|
||||
|
||||
private void InvokeRoutine(Keys key, bool isKeyDown)
|
||||
{
|
||||
if (!_validKeys.Contains(key))
|
||||
{
|
||||
Debug.WriteLine($"Invalid keypress: key={key},down={isKeyDown}, time={_lastInvalidKeyPressTick}");
|
||||
|
||||
_lastInvalidKeyPressTick = DateTime.Now.Ticks;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DateTime.Now.Ticks - _lastInvalidKeyPressTick < VALID_KEY_PRESS_DELAY)
|
||||
return;
|
||||
|
||||
_lastInvalidKeyPressTick = 0L;
|
||||
|
||||
Debug.WriteLine($"InvokeRoutine: key={key},down={isKeyDown}");
|
||||
|
||||
if (isKeyDown)
|
||||
@@ -110,20 +138,13 @@ namespace QuickLook
|
||||
{
|
||||
_hook = GlobalKeyboardHook.GetInstance();
|
||||
|
||||
_hook.HookedKeys.Add(Keys.Enter);
|
||||
_hook.HookedKeys.Add(Keys.Space);
|
||||
_hook.HookedKeys.Add(Keys.Escape);
|
||||
_hook.HookedKeys.Add(Keys.Up);
|
||||
_hook.HookedKeys.Add(Keys.Down);
|
||||
_hook.HookedKeys.Add(Keys.Left);
|
||||
_hook.HookedKeys.Add(Keys.Right);
|
||||
_hook.KeyDown += downHandler;
|
||||
_hook.KeyUp += upHandler;
|
||||
}
|
||||
|
||||
internal static BackgroundListener GetInstance()
|
||||
internal static KeystrokeDispatcher GetInstance()
|
||||
{
|
||||
return _instance ?? (_instance = new BackgroundListener());
|
||||
return _instance ?? (_instance = new KeystrokeDispatcher());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,8 +180,8 @@
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="BackgroundListener.cs" />
|
||||
<Compile Include="GlobalKeyboardHook.cs" />
|
||||
<Compile Include="KeystrokeDispatcher.cs" />
|
||||
<Compile Include="Helpers\GlobalKeyboardHook.cs" />
|
||||
<Compile Include="ViewerWindow.xaml.cs">
|
||||
<DependentUpon>ViewerWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
||||
Reference in New Issue
Block a user