Fixing issues when color picker freezes (#8376)
* Fixing issue when color picker was frozen because other application was locking clipboard * Fixed another issue where holding activation keys constantly would trigger show color picker numberous times and it would cause some events to be attached multiple times
This commit is contained in:
parent
aa3dd133c7
commit
375953641b
|
@ -14,6 +14,8 @@ namespace ColorPicker.Helpers
|
|||
{
|
||||
private readonly IColorEditorViewModel _colorEditorViewModel;
|
||||
private ColorEditorWindow _colorEditorWindow;
|
||||
private bool _colorPickerShown;
|
||||
private object _colorPickerVisibilityLock = new object();
|
||||
|
||||
[ImportingConstructor]
|
||||
public AppStateHandler(IColorEditorViewModel colorEditorViewModel)
|
||||
|
@ -30,16 +32,30 @@ namespace ColorPicker.Helpers
|
|||
|
||||
public void ShowColorPicker()
|
||||
{
|
||||
AppShown?.Invoke(this, EventArgs.Empty);
|
||||
Application.Current.MainWindow.Opacity = 0;
|
||||
Application.Current.MainWindow.Visibility = Visibility.Visible;
|
||||
lock (_colorPickerVisibilityLock)
|
||||
{
|
||||
if (!_colorPickerShown)
|
||||
{
|
||||
AppShown?.Invoke(this, EventArgs.Empty);
|
||||
Application.Current.MainWindow.Opacity = 0;
|
||||
Application.Current.MainWindow.Visibility = Visibility.Visible;
|
||||
_colorPickerShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void HideColorPicker()
|
||||
{
|
||||
Application.Current.MainWindow.Opacity = 0;
|
||||
Application.Current.MainWindow.Visibility = Visibility.Collapsed;
|
||||
AppHidden?.Invoke(this, EventArgs.Empty);
|
||||
lock (_colorPickerVisibilityLock)
|
||||
{
|
||||
if (_colorPickerShown)
|
||||
{
|
||||
Application.Current.MainWindow.Opacity = 0;
|
||||
Application.Current.MainWindow.Visibility = Visibility.Collapsed;
|
||||
AppHidden?.Invoke(this, EventArgs.Empty);
|
||||
_colorPickerShown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowColorPickerEditor()
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using static ColorPicker.NativeMethods;
|
||||
|
||||
namespace ColorPicker.Helpers
|
||||
{
|
||||
|
@ -23,15 +25,24 @@ namespace ColorPicker.Helpers
|
|||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(colorRepresentationToCopy);
|
||||
Clipboard.SetDataObject(colorRepresentationToCopy);
|
||||
break;
|
||||
}
|
||||
catch (COMException ex)
|
||||
{
|
||||
var hwnd = GetOpenClipboardWindow();
|
||||
var sb = new StringBuilder(501);
|
||||
_ = GetWindowText(hwnd.ToInt32(), sb, 500);
|
||||
var applicationUsingClipboard = sb.ToString();
|
||||
|
||||
if ((uint)ex.ErrorCode != ErrorCodeClipboardCantOpen)
|
||||
{
|
||||
Logger.LogError("Failed to set text into clipboard", ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("Failed to set text into clipboard, application that is locking clipboard - " + applicationUsingClipboard, ex);
|
||||
}
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(10);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Input;
|
||||
using ColorPicker.Helpers;
|
||||
using ColorPicker.Settings;
|
||||
|
@ -21,10 +22,12 @@ namespace ColorPicker.Keyboard
|
|||
{
|
||||
private readonly AppStateHandler _appStateHandler;
|
||||
private readonly IUserSettings _userSettings;
|
||||
private List<string> _previouslyPressedKeys;
|
||||
|
||||
private List<string> _activationKeys = new List<string>();
|
||||
private GlobalKeyboardHook _keyboardHook;
|
||||
private bool disposedValue;
|
||||
private bool _activationShortcutPressed;
|
||||
|
||||
[ImportingConstructor]
|
||||
public KeyboardMonitor(AppStateHandler appStateHandler, IUserSettings userSettings)
|
||||
|
@ -80,26 +83,38 @@ namespace ColorPicker.Keyboard
|
|||
// If the last key pressed is a modifier key, then currentlyPressedKeys cannot possibly match with _activationKeys
|
||||
// because _activationKeys contains exactly 1 non-modifier key. Hence, there's no need to check if `name` is a
|
||||
// modifier key or to do any additional processing on it.
|
||||
|
||||
// Check pressed modifier keys.
|
||||
AddModifierKeys(currentlyPressedKeys);
|
||||
|
||||
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown || e.KeyboardState == GlobalKeyboardHook.KeyboardState.SysKeyDown)
|
||||
{
|
||||
// Check pressed modifier keys.
|
||||
AddModifierKeys(currentlyPressedKeys);
|
||||
|
||||
currentlyPressedKeys.Add(name);
|
||||
}
|
||||
|
||||
currentlyPressedKeys.Sort();
|
||||
|
||||
if (currentlyPressedKeys.Count == 0 && _previouslyPressedKeys.Count != 0)
|
||||
{
|
||||
// no keys pressed, we can enable activation shortcut again
|
||||
_activationShortcutPressed = false;
|
||||
}
|
||||
|
||||
_previouslyPressedKeys = currentlyPressedKeys;
|
||||
|
||||
if (ArraysAreSame(currentlyPressedKeys, _activationKeys))
|
||||
{
|
||||
if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor)
|
||||
// avoid triggering this action multiple times as this will be called nonstop while keys are pressed
|
||||
if (!_activationShortcutPressed)
|
||||
{
|
||||
_appStateHandler.ShowColorPickerEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
_appStateHandler.ShowColorPicker();
|
||||
_activationShortcutPressed = true;
|
||||
if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor)
|
||||
{
|
||||
_appStateHandler.ShowColorPickerEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
_appStateHandler.ShowColorPicker();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorPicker
|
||||
{
|
||||
|
@ -161,5 +162,11 @@ namespace ColorPicker
|
|||
/// </summary>
|
||||
public IntPtr AdditionalInformation;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetOpenClipboardWindow();
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetWindowText(int hwnd, StringBuilder text, int count);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue