LenovoLegionToolkit

Форк
0
112 строк · 3.5 Кб
1
using System;
2
using System.Threading.Tasks;
3
using LenovoLegionToolkit.Lib.Features;
4
using LenovoLegionToolkit.Lib.Settings;
5
using LenovoLegionToolkit.Lib.Utils;
6
using NeoSmart.AsyncLock;
7
using Windows.Win32;
8
using Windows.Win32.UI.Input.KeyboardAndMouse;
9
using Windows.Win32.UI.WindowsAndMessaging;
10

11
namespace LenovoLegionToolkit.Lib.Controllers;
12

13
public class SmartFnLockController
14
{
15
    private readonly AsyncLock _lock = new();
16

17
    private readonly FnLockFeature _feature;
18
    private readonly ApplicationSettings _settings;
19

20
    private bool _ctrlDepressed;
21
    private bool _shiftDepressed;
22
    private bool _altDepressed;
23
    private bool _restoreFnLock;
24

25
    public SmartFnLockController(FnLockFeature feature, ApplicationSettings settings)
26
    {
27
        _feature = feature ?? throw new ArgumentNullException(nameof(feature));
28
        _settings = settings ?? throw new ArgumentNullException(nameof(settings));
29
    }
30

31
    public void OnKeyboardEvent(nuint wParam, KBDLLHOOKSTRUCT kbStruct)
32
    {
33
        if (_settings.Store.SmartFnLockFlags == 0)
34
            return;
35

36
        Task.Run(async () =>
37
        {
38
            try
39
            {
40
                using (await _lock.LockAsync().ConfigureAwait(false))
41
                    await OnKeyboardEventAsync(wParam, kbStruct).ConfigureAwait(false);
42
            }
43
            catch (Exception ex)
44
            {
45
                if (Log.Instance.IsTraceEnabled)
46
                    Log.Instance.Trace($"Failed to handle keyboard event.", ex);
47
            }
48
        });
49
    }
50

51
    private async Task OnKeyboardEventAsync(nuint wParam, KBDLLHOOKSTRUCT kbStruct)
52
    {
53
        if (IsModifierKeyPressed(wParam, kbStruct))
54
        {
55
            if (_restoreFnLock)
56
                return;
57

58
            var state = await _feature.GetStateAsync().ConfigureAwait(false);
59
            if (state == FnLockState.Off)
60
                return;
61

62
            if (Log.Instance.IsTraceEnabled)
63
                Log.Instance.Trace($"Disabling Fn Lock temporarily...");
64

65
            await _feature.SetStateAsync(FnLockState.Off).ConfigureAwait(false);
66
            _restoreFnLock = true;
67
        }
68
        else if (_restoreFnLock)
69
        {
70
            if (Log.Instance.IsTraceEnabled)
71
                Log.Instance.Trace($"Re-enabling Fn Lock...");
72

73
            await _feature.SetStateAsync(FnLockState.On).ConfigureAwait(false);
74
            _restoreFnLock = false;
75
        }
76
    }
77

78
    private bool IsModifierKeyPressed(nuint wParam, KBDLLHOOKSTRUCT kbStruct)
79
    {
80
        var isKeyDown = wParam is PInvoke.WM_KEYDOWN or PInvoke.WM_SYSKEYDOWN;
81
        var vkKeyCode = (VIRTUAL_KEY)kbStruct.vkCode;
82

83
        if (vkKeyCode is VIRTUAL_KEY.VK_LCONTROL or VIRTUAL_KEY.VK_RCONTROL)
84
            _ctrlDepressed = isKeyDown;
85

86
        if (vkKeyCode is VIRTUAL_KEY.VK_LSHIFT or VIRTUAL_KEY.VK_RSHIFT)
87
            _shiftDepressed = isKeyDown;
88

89
        if (vkKeyCode is VIRTUAL_KEY.VK_LMENU or VIRTUAL_KEY.VK_RMENU)
90
            _altDepressed = isKeyDown;
91

92
        if (!_ctrlDepressed && !_shiftDepressed && !_altDepressed)
93
            return false;
94

95
        var result = false;
96
        var flags = _settings.Store.SmartFnLockFlags;
97

98
        if (flags.HasFlag(ModifierKey.Ctrl))
99
            result |= _ctrlDepressed;
100

101
        if (flags.HasFlag(ModifierKey.Shift))
102
            result |= _shiftDepressed;
103

104
        if (flags.HasFlag(ModifierKey.Alt))
105
            result |= _altDepressed;
106

107
        if (Log.Instance.IsTraceEnabled)
108
            Log.Instance.Trace($"Modifier key is depressed: {result} [ctrl={_ctrlDepressed}, shift={_shiftDepressed}, alt={_altDepressed}, flags={flags}]");
109

110
        return result;
111
    }
112
}
113

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.