diff --git a/packages/hotkey_manager/example/lib/pages/home.dart b/packages/hotkey_manager/example/lib/pages/home.dart index 76a5922..2e55778 100644 --- a/packages/hotkey_manager/example/lib/pages/home.dart +++ b/packages/hotkey_manager/example/lib/pages/home.dart @@ -17,7 +17,7 @@ class _HomePageState extends State { List _registeredHotKeyList = []; void _keyDownHandler(HotKey hotKey) { - String log = 'keyDown ${hotKey.physicalKey.debugName} (${hotKey.scope})'; + String log = 'keyDown ${hotKey.debugName} (${hotKey.scope})'; BotToast.showText(text: log); if (kDebugMode) { print(log); @@ -25,7 +25,7 @@ class _HomePageState extends State { } void _keyUpHandler(HotKey hotKey) { - String log = 'keyUp ${hotKey.physicalKey.debugName} (${hotKey.scope})'; + String log = 'keyUp ${hotKey.debugName} (${hotKey.scope})'; BotToast.showText(text: log); if (kDebugMode) { print(log); diff --git a/packages/hotkey_manager/example/macos/Runner.xcodeproj/project.pbxproj b/packages/hotkey_manager/example/macos/Runner.xcodeproj/project.pbxproj index 975fb11..a95c317 100644 --- a/packages/hotkey_manager/example/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/hotkey_manager/example/macos/Runner.xcodeproj/project.pbxproj @@ -259,7 +259,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C80D4294CF70F00263BE5 = { diff --git a/packages/hotkey_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/hotkey_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3776531..2d61950 100644 --- a/packages/hotkey_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/hotkey_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ ? pressedModifierKeys = - ModifierKey.values // pressed modifier keys - .where((e) => e.isModifierPressed) - .toList(); + List? modifiers = HotKeyModifier.values + .where((e) => e.physicalKeys.any(physicalKeysPressed.contains)) + .toList(); return e.scope == HotKeyScope.inapp && keyEvent.logicalKey == e.logicalKey && - pressedModifierKeys.every( - (modifierKey) => (e.modifiers ?? []).contains(modifierKey), - ); + modifiers.every((e.modifiers ?? []).contains); }, ); if (hotKey != null) { diff --git a/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart b/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart index 09fd66c..cee4482 100644 --- a/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart +++ b/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart @@ -37,20 +37,21 @@ class _HotKeyRecorderState extends State { bool _handleKeyEvent(KeyEvent keyEvent) { if (keyEvent is KeyUpEvent) return false; + final physicalKeysPressed = HardwareKeyboard.instance.physicalKeysPressed; PhysicalKeyboardKey? key = keyEvent.physicalKey; - List? pressedModifierKeys = ModifierKey.values - .where((e) => e.isModifierPressed) // pressed modifier keys + List? modifiers = HotKeyModifier.values + .where((e) => e.physicalKeys.any(physicalKeysPressed.contains)) .toList(); - if (pressedModifierKeys.isNotEmpty) { - // Remove the modifier keys from the list of pressed keys - pressedModifierKeys = pressedModifierKeys + if (modifiers.isNotEmpty) { + // Remove the key from the modifiers list if it is a modifier + modifiers = modifiers .where((e) => !e.physicalKeys.contains(key)) // linewrap .toList(); } _hotKey = HotKey( identifier: widget.initalHotKey?.identifier, key: key, - modifiers: pressedModifierKeys, + modifiers: modifiers, scope: widget.initalHotKey?.scope ?? HotKeyScope.system, ); widget.onHotKeyRecorded(_hotKey!); diff --git a/packages/hotkey_manager/lib/src/widgets/hotkey_virtual_view.dart b/packages/hotkey_manager/lib/src/widgets/hotkey_virtual_view.dart index 687dc82..c3dc3b3 100644 --- a/packages/hotkey_manager/lib/src/widgets/hotkey_virtual_view.dart +++ b/packages/hotkey_manager/lib/src/widgets/hotkey_virtual_view.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; class _VirtualKeyView extends StatelessWidget { @@ -51,9 +50,9 @@ class HotKeyVirtualView extends StatelessWidget { return Wrap( spacing: 8, children: [ - for (ModifierKey modifierKey in hotKey.modifiers ?? []) + for (HotKeyModifier modifier in hotKey.modifiers ?? []) _VirtualKeyView( - keyLabel: modifierKey.keyLabel, + keyLabel: modifier.physicalKeys.first.keyLabel, ), _VirtualKeyView( keyLabel: hotKey.physicalKey.keyLabel, diff --git a/packages/hotkey_manager_linux/linux/hotkey_manager_linux_plugin.cc b/packages/hotkey_manager_linux/linux/hotkey_manager_linux_plugin.cc index ec21a5d..74fabe2 100644 --- a/packages/hotkey_manager_linux/linux/hotkey_manager_linux_plugin.cc +++ b/packages/hotkey_manager_linux/linux/hotkey_manager_linux_plugin.cc @@ -56,14 +56,16 @@ guint get_mods(const std::vector& modifiers) { guint mods = 0; for (int i = 0; i < modifiers.size(); i++) { guint mod = 0; - if (modifiers[i] == "shiftModifier") - mod = GDK_SHIFT_MASK; - else if (modifiers[i] == "controlModifier") - mod = GDK_CONTROL_MASK; - else if (modifiers[i] == "altModifier") + if (modifiers[i] == "alt") mod = GDK_MOD1_MASK; - else if (modifiers[i] == "metaModifier") + else if (modifiers[i] == "capsLock") + mod = GDK_LOCK_MASK; + else if (modifiers[i] == "control") + mod = GDK_CONTROL_MASK; + else if (modifiers[i] == "meta") mod = GDK_META_MASK; + else if (modifiers[i] == "shift") + mod = GDK_SHIFT_MASK; mods = mods | mod; } return mods; diff --git a/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift b/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift index 4e8284c..0e4c98b 100644 --- a/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift +++ b/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift @@ -8,23 +8,23 @@ extension NSEvent.ModifierFlags { public init(pluginModifiers: Array) { self.init() - if (pluginModifiers.contains("capsLockModifier")) { - insert(.capsLock) + if (pluginModifiers.contains("alt")) { + insert(.option) } - if (pluginModifiers.contains("shiftModifier")) { - insert(.shift) + if (pluginModifiers.contains("capsLock")) { + insert(.capsLock) } - if (pluginModifiers.contains("controlModifier")) { + if (pluginModifiers.contains("control")) { insert(.control) } - if (pluginModifiers.contains("altModifier")) { - insert(.option) + if (pluginModifiers.contains("fn")) { + insert(.function) } - if (pluginModifiers.contains("metaModifier")) { + if (pluginModifiers.contains("meta")) { insert(.command) } - if (pluginModifiers.contains("functionModifier")) { - insert(.function) + if (pluginModifiers.contains("shift")) { + insert(.shift) } } } diff --git a/packages/hotkey_manager_platform_interface/lib/hotkey_manager_platform_interface.dart b/packages/hotkey_manager_platform_interface/lib/hotkey_manager_platform_interface.dart index a9e5dd8..abf0d2d 100644 --- a/packages/hotkey_manager_platform_interface/lib/hotkey_manager_platform_interface.dart +++ b/packages/hotkey_manager_platform_interface/lib/hotkey_manager_platform_interface.dart @@ -2,8 +2,7 @@ library hotkey_manager_platform_interface; export 'src/enums/key_code.dart'; export 'src/enums/key_modifier.dart'; -export 'src/extensions/modifier_key.dart'; -export 'src/extensions/physical_keyboard_key.dart'; +export 'src/extensions/keyboard_key.dart'; export 'src/hotkey.dart'; export 'src/hotkey_manager_method_channel.dart'; export 'src/hotkey_manager_platform_interface.dart'; diff --git a/packages/hotkey_manager_platform_interface/lib/src/enums/key_code.dart b/packages/hotkey_manager_platform_interface/lib/src/enums/key_code.dart index 3ff5ae5..e357f7d 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/enums/key_code.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/enums/key_code.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use_from_same_package + import 'dart:io'; import 'package:flutter/foundation.dart'; @@ -283,6 +285,9 @@ const Map _knownLogicalKeys = KeyCode.control: LogicalKeyboardKey.control, }; +@Deprecated( + 'No longer supported, Use `PhysicalKeyboardKey` instead. ', +) enum KeyCode { // none, hyper, diff --git a/packages/hotkey_manager_platform_interface/lib/src/enums/key_modifier.dart b/packages/hotkey_manager_platform_interface/lib/src/enums/key_modifier.dart index d5f4b91..e31a04c 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/enums/key_modifier.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/enums/key_modifier.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package + import 'dart:io'; import 'package:flutter/foundation.dart' show kIsWeb; @@ -52,6 +54,9 @@ final Map _knownKeyLabels = { KeyModifier.fn: 'fn', }; +@Deprecated( + 'No longer supported, Use `HotKeyModifier` instead. ', +) enum KeyModifier { capsLock, shift, diff --git a/packages/hotkey_manager_platform_interface/lib/src/extensions/physical_keyboard_key.dart b/packages/hotkey_manager_platform_interface/lib/src/extensions/keyboard_key.dart similarity index 88% rename from packages/hotkey_manager_platform_interface/lib/src/extensions/physical_keyboard_key.dart rename to packages/hotkey_manager_platform_interface/lib/src/extensions/keyboard_key.dart index a614dba..572c3c9 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/extensions/physical_keyboard_key.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/extensions/keyboard_key.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:uni_platform/uni_platform.dart'; final Map _knownKeyLabels = { @@ -90,8 +91,14 @@ final Map _knownKeyLabels = PhysicalKeyboardKey.fn: 'fn', }; -extension PhysicalKeyboardKeyExt on PhysicalKeyboardKey { +extension KeyboardKeyExt on KeyboardKey { String get keyLabel { - return _knownKeyLabels[this] ?? debugName ?? 'Unknown'; + PhysicalKeyboardKey? physicalKey; + if (this is LogicalKeyboardKey) { + physicalKey = (this as LogicalKeyboardKey).physicalKey; + } else if (this is PhysicalKeyboardKey) { + physicalKey = this as PhysicalKeyboardKey; + } + return _knownKeyLabels[physicalKey] ?? physicalKey?.debugName ?? 'Unknown'; } } diff --git a/packages/hotkey_manager_platform_interface/lib/src/extensions/modifier_key.dart b/packages/hotkey_manager_platform_interface/lib/src/extensions/modifier_key.dart deleted file mode 100644 index dd849e1..0000000 --- a/packages/hotkey_manager_platform_interface/lib/src/extensions/modifier_key.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -final Map _knownModifierKeyLabels = { - ModifierKey.capsLockModifier: '⇪', - ModifierKey.shiftModifier: '⇧', - ModifierKey.controlModifier: (!kIsWeb && Platform.isMacOS) ? '⌃' : 'Ctrl', - ModifierKey.altModifier: (!kIsWeb && Platform.isMacOS) ? '⌥' : 'Alt', - ModifierKey.metaModifier: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', - ModifierKey.functionModifier: 'fn', -}; - -const _modifierKeyMap = >{ - ModifierKey.capsLockModifier: [ - PhysicalKeyboardKey.capsLock, - ], - ModifierKey.shiftModifier: [ - PhysicalKeyboardKey.shiftLeft, - PhysicalKeyboardKey.shiftRight, - ], - ModifierKey.controlModifier: [ - PhysicalKeyboardKey.controlLeft, - PhysicalKeyboardKey.controlRight, - ], - ModifierKey.altModifier: [ - PhysicalKeyboardKey.altLeft, - PhysicalKeyboardKey.altRight, - ], - ModifierKey.metaModifier: [ - PhysicalKeyboardKey.metaLeft, - PhysicalKeyboardKey.metaRight, - ], - ModifierKey.functionModifier: [ - PhysicalKeyboardKey.fn, - ], -}; - -extension ModifierKeyExt on ModifierKey { - String get keyLabel => _knownModifierKeyLabels[this] ?? ''; - - bool get isModifierPressed { - final physicalKeysPressed = HardwareKeyboard.instance.physicalKeysPressed; - if (_modifierKeyMap[this] != null) { - return _modifierKeyMap[this]!.any(physicalKeysPressed.contains); - } - return false; - } - - List get physicalKeys { - return _modifierKeyMap[this] ?? []; - } -} diff --git a/packages/hotkey_manager_platform_interface/lib/src/hotkey.dart b/packages/hotkey_manager_platform_interface/lib/src/hotkey.dart index b11bdbd..f3ee7f6 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/hotkey.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/hotkey.dart @@ -1,7 +1,7 @@ import 'package:flutter/services.dart'; +import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; import 'package:json_annotation/json_annotation.dart'; -// ignore: implementation_imports -import 'package:uni_platform/src/extensions/keyboard_key.dart'; +import 'package:uni_platform/uni_platform.dart'; import 'package:uuid/uuid.dart'; part 'hotkey.g.dart'; @@ -10,6 +10,40 @@ const _uuid = Uuid(); typedef HotKeyHandler = void Function(HotKey hotKey); +enum HotKeyModifier { + alt([ + PhysicalKeyboardKey.altLeft, + PhysicalKeyboardKey.altRight, + ]), + capsLock([ + PhysicalKeyboardKey.capsLock, + ]), + control([ + PhysicalKeyboardKey.controlLeft, + PhysicalKeyboardKey.controlRight, + ]), + fn([ + PhysicalKeyboardKey.fn, + ]), + meta([ + PhysicalKeyboardKey.metaLeft, + PhysicalKeyboardKey.metaRight, + ]), + shift([ + PhysicalKeyboardKey.shiftLeft, + PhysicalKeyboardKey.shiftRight, + ]); + + const HotKeyModifier(this.physicalKeys); + + final List physicalKeys; + + bool get isModifierPressed { + final physicalKeysPressed = HardwareKeyboard.instance.physicalKeysPressed; + return physicalKeys.any(physicalKeysPressed.contains); + } +} + enum HotKeyScope { system, inapp, @@ -26,11 +60,14 @@ class HotKey { this.scope = HotKeyScope.system, }) : identifier = identifier ?? _uuid.v4(); - factory HotKey.fromJson(Map json) => _$HotKeyFromJson(json); + factory HotKey.fromJson(Map json) { + if (json['keyCode'] is String) return _$HotKeyFromOldJson(json); + return _$HotKeyFromJson(json); + } final String identifier; final KeyboardKey key; - final List? modifiers; + final List? modifiers; final HotKeyScope scope; LogicalKeyboardKey get logicalKey { @@ -57,9 +94,14 @@ class HotKey { ); } - @override - String toString() { - return '${modifiers?.map((e) => e.name).join('')}${key.hashCode}'; + String get debugName { + return [ + ...(modifiers ?? []).map((e) { + final firstPhysicalKey = e.physicalKeys.first; + return firstPhysicalKey.debugName; + }), + physicalKey.debugName, + ].join(' + '); } Map toJson() => _$HotKeyToJson(this); @@ -103,3 +145,20 @@ class _KeyboardKeyConverter }..removeWhere((key, value) => value == null); } } + +// Convert HotKey from old JSON format +HotKey _$HotKeyFromOldJson(Map json) { + LogicalKeyboardKey logicalKey = + KeyCodeParser.parse(json['keyCode']).logicalKey; + return HotKey( + identifier: json['identifier'] as String, + key: logicalKey.physicalKey!, + modifiers: ((json['modifiers'] as List?) ?? []).map((modifier) { + return HotKeyModifier.values.firstWhere((e) => e.name == modifier); + }).toList(), + scope: HotKeyScope.values.firstWhere( + (e) => e.name == json['scope'] as String, + orElse: () => HotKeyScope.system, + ), + ); +} diff --git a/packages/hotkey_manager_platform_interface/lib/src/hotkey.g.dart b/packages/hotkey_manager_platform_interface/lib/src/hotkey.g.dart index 4ed46ae..0c77a37 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/hotkey.g.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/hotkey.g.dart @@ -10,7 +10,7 @@ HotKey _$HotKeyFromJson(Map json) => HotKey( identifier: json['identifier'] as String?, key: const _KeyboardKeyConverter().fromJson(json['key'] as Map), modifiers: (json['modifiers'] as List?) - ?.map((e) => $enumDecode(_$ModifierKeyEnumMap, e)) + ?.map((e) => $enumDecode(_$HotKeyModifierEnumMap, e)) .toList(), scope: $enumDecodeNullable(_$HotKeyScopeEnumMap, json['scope']) ?? HotKeyScope.system, @@ -20,20 +20,17 @@ Map _$HotKeyToJson(HotKey instance) => { 'identifier': instance.identifier, 'key': const _KeyboardKeyConverter().toJson(instance.key), 'modifiers': - instance.modifiers?.map((e) => _$ModifierKeyEnumMap[e]!).toList(), + instance.modifiers?.map((e) => _$HotKeyModifierEnumMap[e]!).toList(), 'scope': _$HotKeyScopeEnumMap[instance.scope]!, }; -const _$ModifierKeyEnumMap = { - ModifierKey.controlModifier: 'controlModifier', - ModifierKey.shiftModifier: 'shiftModifier', - ModifierKey.altModifier: 'altModifier', - ModifierKey.metaModifier: 'metaModifier', - ModifierKey.capsLockModifier: 'capsLockModifier', - ModifierKey.numLockModifier: 'numLockModifier', - ModifierKey.scrollLockModifier: 'scrollLockModifier', - ModifierKey.functionModifier: 'functionModifier', - ModifierKey.symbolModifier: 'symbolModifier', +const _$HotKeyModifierEnumMap = { + HotKeyModifier.alt: 'alt', + HotKeyModifier.capsLock: 'capsLock', + HotKeyModifier.control: 'control', + HotKeyModifier.fn: 'fn', + HotKeyModifier.meta: 'meta', + HotKeyModifier.shift: 'shift', }; const _$HotKeyScopeEnumMap = { diff --git a/packages/hotkey_manager_platform_interface/test/src/hotkey_test.dart b/packages/hotkey_manager_platform_interface/test/src/hotkey_test.dart new file mode 100644 index 0000000..b438494 --- /dev/null +++ b/packages/hotkey_manager_platform_interface/test/src/hotkey_test.dart @@ -0,0 +1,35 @@ +import 'dart:convert'; + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:hotkey_manager_platform_interface/src/hotkey.dart'; + +String oldHotKeyJson1 = + '{"keyCode":"keyZ","modifiers":["meta","shift"],"identifier":"01","scope":"system"}'; +String oldHotKeyJson2 = + '{"keyCode":"keyA","modifiers":["alt","shift"],"identifier":"02","scope":"system"}'; +String newHotKeyJson1 = + '{"identifier":"01","key":{"usageCode":458781},"modifiers":["meta","shift"],"scope":"system"}'; +String newHotKeyJson2 = + '{"identifier":"02","key":{"usageCode":458756},"modifiers":["alt","shift"],"scope":"system"}'; + +void main() { + test('should be compatible with old JSON', () async { + final hotKey1 = HotKey.fromJson(json.decode(oldHotKeyJson1)); + expect(hotKey1.key, PhysicalKeyboardKey.keyZ); + expect(hotKey1.modifiers?.first, HotKeyModifier.meta); + expect(hotKey1.modifiers?.last, HotKeyModifier.shift); + final hotKey2 = HotKey.fromJson(json.decode(oldHotKeyJson2)); + expect(hotKey2.key, PhysicalKeyboardKey.keyA); + expect(hotKey2.modifiers?.first, HotKeyModifier.alt); + expect(hotKey2.modifiers?.last, HotKeyModifier.shift); + final newHotKey1 = HotKey.fromJson(json.decode(newHotKeyJson1)); + expect(newHotKey1.key, PhysicalKeyboardKey.keyZ); + expect(newHotKey1.modifiers?.first, HotKeyModifier.meta); + expect(newHotKey1.modifiers?.last, HotKeyModifier.shift); + final newHotKey2 = HotKey.fromJson(json.decode(newHotKeyJson2)); + expect(newHotKey2.key, PhysicalKeyboardKey.keyA); + expect(newHotKey2.modifiers?.first, HotKeyModifier.alt); + expect(newHotKey2.modifiers?.last, HotKeyModifier.shift); + }); +} diff --git a/packages/hotkey_manager_windows/windows/hotkey_manager_windows_plugin.cpp b/packages/hotkey_manager_windows/windows/hotkey_manager_windows_plugin.cpp index 9db00c7..8922919 100644 --- a/packages/hotkey_manager_windows/windows/hotkey_manager_windows_plugin.cpp +++ b/packages/hotkey_manager_windows/windows/hotkey_manager_windows_plugin.cpp @@ -142,14 +142,14 @@ UINT HotkeyManagerWindowsPlugin::GetFsModifiersFromString( UINT fs_modifiers = 0x0000; for (int32_t i = 0; i < modifiers.size(); i++) { UINT fs_modifier = 0x0000; - if (modifiers[i] == "shiftModifier") { - fs_modifier = MOD_SHIFT; - } else if (modifiers[i] == "controlModifier") { - fs_modifier = MOD_CONTROL; - } else if (modifiers[i] == "altModifier") { + if (modifiers[i] == "alt") { fs_modifier = MOD_ALT; - } else if (modifiers[i] == "metaModifier") { + } else if (modifiers[i] == "control") { + fs_modifier = MOD_CONTROL; + } else if (modifiers[i] == "meta") { fs_modifier = MOD_WIN; + } else if (modifiers[i] == "shift") { + fs_modifier = MOD_SHIFT; } fs_modifiers = fs_modifiers | fs_modifier; }