diff --git a/packages/hotkey_manager/example/lib/pages/home.dart b/packages/hotkey_manager/example/lib/pages/home.dart index 9748e98..579acfc 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.keyCode.name} (${hotKey.scope})'; + String log = 'keyDown ${hotKey.physicalKey.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.keyCode.name} (${hotKey.scope})'; + String log = 'keyUp ${hotKey.physicalKey.debugName} (${hotKey.scope})'; if (kDebugMode) { print(log); } diff --git a/packages/hotkey_manager/example/lib/widgets/record_hotkey_dialog.dart b/packages/hotkey_manager/example/lib/widgets/record_hotkey_dialog.dart index de2d668..479e1bb 100644 --- a/packages/hotkey_manager/example/lib/widgets/record_hotkey_dialog.dart +++ b/packages/hotkey_manager/example/lib/widgets/record_hotkey_dialog.dart @@ -1,3 +1,4 @@ +import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; @@ -16,10 +17,22 @@ class RecordHotKeyDialog extends StatefulWidget { class _RecordHotKeyDialogState extends State { HotKey? _hotKey; + void _handleSetAsInappWideChanged(bool newValue) { + if (_hotKey == null) { + BotToast.showText(text: 'Please record a hotkey first.'); + return; + } + _hotKey = HotKey( + key: _hotKey!.key, + modifiers: _hotKey?.modifiers, + scope: newValue ? HotKeyScope.inapp : HotKeyScope.system, + ); + setState(() {}); + } + @override Widget build(BuildContext context) { return AlertDialog( - // title: Text('Rewind and remember'), content: SingleChildScrollView( child: ListBody( children: [ @@ -45,20 +58,25 @@ class _RecordHotKeyDialogState extends State { ], ), ), - Row( - children: [ - Checkbox( - value: _hotKey?.scope == HotKeyScope.inapp, - onChanged: (newValue) { - _hotKey?.scope = - newValue! ? HotKeyScope.inapp : HotKeyScope.system; - setState(() {}); - }, - ), - const Text( - 'Set as inapp-wide hotkey. (default is system-wide)', - ), - ], + GestureDetector( + onTap: () { + _handleSetAsInappWideChanged( + _hotKey?.scope != HotKeyScope.inapp, + ); + }, + child: Row( + children: [ + Checkbox( + value: _hotKey?.scope == HotKeyScope.inapp, + onChanged: (newValue) { + _handleSetAsInappWideChanged(newValue!); + }, + ), + const Text( + 'Set as inapp-wide hotkey. (default is system-wide)', + ), + ], + ), ), ], ), diff --git a/packages/hotkey_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/hotkey_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift index 440ccad..9f9ff7e 100644 --- a/packages/hotkey_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/packages/hotkey_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,8 +5,8 @@ import FlutterMacOS import Foundation -import hotkey_manager +import hotkey_manager_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - HotkeyManagerPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerPlugin")) + HotkeyManagerMacosPlugin.register(with: registry.registrar(forPlugin: "HotkeyManagerMacosPlugin")) } diff --git a/packages/hotkey_manager/example/macos/Podfile.lock b/packages/hotkey_manager/example/macos/Podfile.lock index 0483de0..0792fe7 100644 --- a/packages/hotkey_manager/example/macos/Podfile.lock +++ b/packages/hotkey_manager/example/macos/Podfile.lock @@ -1,13 +1,13 @@ PODS: - FlutterMacOS (1.0.0) - - HotKey (0.1.2) - - hotkey_manager (0.0.1): + - HotKey (0.2.0) + - hotkey_manager_macos (0.0.1): - FlutterMacOS - HotKey DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - - hotkey_manager (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager/macos`) + - hotkey_manager_macos (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos`) SPEC REPOS: trunk: @@ -16,13 +16,13 @@ SPEC REPOS: EXTERNAL SOURCES: FlutterMacOS: :path: Flutter/ephemeral - hotkey_manager: - :path: Flutter/ephemeral/.symlinks/plugins/hotkey_manager/macos + hotkey_manager_macos: + :path: Flutter/ephemeral/.symlinks/plugins/hotkey_manager_macos/macos SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - HotKey: ad59450195936c10992438c4210f673de5aee43e - hotkey_manager: c32bf0bfe8f934b7bc17ab4ad5c4c142960b023c + HotKey: e96d8a2ddbf4591131e2bb3f54e69554d90cdca6 + hotkey_manager_macos: 1e2edb0c7ae4fe67108af44a9d3445de41404160 PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 diff --git a/packages/hotkey_manager/lib/hotkey_manager.dart b/packages/hotkey_manager/lib/hotkey_manager.dart index 09b1b14..da36364 100644 --- a/packages/hotkey_manager/lib/hotkey_manager.dart +++ b/packages/hotkey_manager/lib/hotkey_manager.dart @@ -1,6 +1,4 @@ -export './src/enums/key_code.dart'; -export './src/enums/key_modifier.dart'; -export './src/hotkey.dart'; +export 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; export './src/hotkey_manager.dart'; export './src/widgets/hotkey_recorder.dart'; export './src/widgets/hotkey_virtual_view.dart'; diff --git a/packages/hotkey_manager/lib/src/enums/key_code.dart b/packages/hotkey_manager/lib/src/enums/key_code.dart deleted file mode 100644 index 3ff5ae5..0000000 --- a/packages/hotkey_manager/lib/src/enums/key_code.dart +++ /dev/null @@ -1,688 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -const Map _knownLogicalKeys = - { - // KeyCode.none: LogicalKeyboardKey.none, - KeyCode.hyper: LogicalKeyboardKey.hyper, - KeyCode.superKey: LogicalKeyboardKey.superKey, - KeyCode.fnLock: LogicalKeyboardKey.fnLock, - KeyCode.suspend: LogicalKeyboardKey.suspend, - KeyCode.resume: LogicalKeyboardKey.resume, - // KeyCode.turbo: LogicalKeyboardKey.turbo, - // KeyCode.privacyScreenToggle: LogicalKeyboardKey.privacyScreenToggle, - KeyCode.sleep: LogicalKeyboardKey.sleep, - KeyCode.wakeUp: LogicalKeyboardKey.wakeUp, - // KeyCode.displayToggleIntExt: LogicalKeyboardKey.displayToggleIntExt, - // KeyCode.usbReserved: LogicalKeyboardKey.usbReserved, - // KeyCode.usbErrorRollOver: LogicalKeyboardKey.usbErrorRollOver, - // KeyCode.usbPostFail: LogicalKeyboardKey.usbPostFail, - // KeyCode.usbErrorUndefined: LogicalKeyboardKey.usbErrorUndefined, - KeyCode.keyA: LogicalKeyboardKey.keyA, - KeyCode.keyB: LogicalKeyboardKey.keyB, - KeyCode.keyC: LogicalKeyboardKey.keyC, - KeyCode.keyD: LogicalKeyboardKey.keyD, - KeyCode.keyE: LogicalKeyboardKey.keyE, - KeyCode.keyF: LogicalKeyboardKey.keyF, - KeyCode.keyG: LogicalKeyboardKey.keyG, - KeyCode.keyH: LogicalKeyboardKey.keyH, - KeyCode.keyI: LogicalKeyboardKey.keyI, - KeyCode.keyJ: LogicalKeyboardKey.keyJ, - KeyCode.keyK: LogicalKeyboardKey.keyK, - KeyCode.keyL: LogicalKeyboardKey.keyL, - KeyCode.keyM: LogicalKeyboardKey.keyM, - KeyCode.keyN: LogicalKeyboardKey.keyN, - KeyCode.keyO: LogicalKeyboardKey.keyO, - KeyCode.keyP: LogicalKeyboardKey.keyP, - KeyCode.keyQ: LogicalKeyboardKey.keyQ, - KeyCode.keyR: LogicalKeyboardKey.keyR, - KeyCode.keyS: LogicalKeyboardKey.keyS, - KeyCode.keyT: LogicalKeyboardKey.keyT, - KeyCode.keyU: LogicalKeyboardKey.keyU, - KeyCode.keyV: LogicalKeyboardKey.keyV, - KeyCode.keyW: LogicalKeyboardKey.keyW, - KeyCode.keyX: LogicalKeyboardKey.keyX, - KeyCode.keyY: LogicalKeyboardKey.keyY, - KeyCode.keyZ: LogicalKeyboardKey.keyZ, - KeyCode.digit1: LogicalKeyboardKey.digit1, - KeyCode.digit2: LogicalKeyboardKey.digit2, - KeyCode.digit3: LogicalKeyboardKey.digit3, - KeyCode.digit4: LogicalKeyboardKey.digit4, - KeyCode.digit5: LogicalKeyboardKey.digit5, - KeyCode.digit6: LogicalKeyboardKey.digit6, - KeyCode.digit7: LogicalKeyboardKey.digit7, - KeyCode.digit8: LogicalKeyboardKey.digit8, - KeyCode.digit9: LogicalKeyboardKey.digit9, - KeyCode.digit0: LogicalKeyboardKey.digit0, - KeyCode.enter: LogicalKeyboardKey.enter, - KeyCode.escape: LogicalKeyboardKey.escape, - KeyCode.backspace: LogicalKeyboardKey.backspace, - KeyCode.tab: LogicalKeyboardKey.tab, - KeyCode.space: LogicalKeyboardKey.space, - KeyCode.minus: LogicalKeyboardKey.minus, - KeyCode.numberSign: LogicalKeyboardKey.numberSign, - KeyCode.multiply: LogicalKeyboardKey.asterisk, - KeyCode.add: LogicalKeyboardKey.add, - KeyCode.equal: LogicalKeyboardKey.equal, - KeyCode.bracketLeft: LogicalKeyboardKey.bracketLeft, - KeyCode.bracketRight: LogicalKeyboardKey.bracketRight, - KeyCode.backslash: LogicalKeyboardKey.backslash, - KeyCode.semicolon: LogicalKeyboardKey.semicolon, - KeyCode.quote: LogicalKeyboardKey.quote, - KeyCode.backquote: LogicalKeyboardKey.backquote, - KeyCode.comma: LogicalKeyboardKey.comma, - KeyCode.period: LogicalKeyboardKey.period, - KeyCode.slash: LogicalKeyboardKey.slash, - KeyCode.capsLock: LogicalKeyboardKey.capsLock, - KeyCode.f1: LogicalKeyboardKey.f1, - KeyCode.f2: LogicalKeyboardKey.f2, - KeyCode.f3: LogicalKeyboardKey.f3, - KeyCode.f4: LogicalKeyboardKey.f4, - KeyCode.f5: LogicalKeyboardKey.f5, - KeyCode.f6: LogicalKeyboardKey.f6, - KeyCode.f7: LogicalKeyboardKey.f7, - KeyCode.f8: LogicalKeyboardKey.f8, - KeyCode.f9: LogicalKeyboardKey.f9, - KeyCode.f10: LogicalKeyboardKey.f10, - KeyCode.f11: LogicalKeyboardKey.f11, - KeyCode.f12: LogicalKeyboardKey.f12, - KeyCode.printScreen: LogicalKeyboardKey.printScreen, - KeyCode.scrollLock: LogicalKeyboardKey.scrollLock, - KeyCode.pause: LogicalKeyboardKey.pause, - KeyCode.insert: LogicalKeyboardKey.insert, - KeyCode.home: LogicalKeyboardKey.home, - KeyCode.pageUp: LogicalKeyboardKey.pageUp, - KeyCode.delete: LogicalKeyboardKey.delete, - KeyCode.end: LogicalKeyboardKey.end, - KeyCode.pageDown: LogicalKeyboardKey.pageDown, - KeyCode.arrowRight: LogicalKeyboardKey.arrowRight, - KeyCode.arrowLeft: LogicalKeyboardKey.arrowLeft, - KeyCode.arrowDown: LogicalKeyboardKey.arrowDown, - KeyCode.arrowUp: LogicalKeyboardKey.arrowUp, - KeyCode.numLock: LogicalKeyboardKey.numLock, - KeyCode.numpadDivide: LogicalKeyboardKey.numpadDivide, - KeyCode.numpadMultiply: LogicalKeyboardKey.numpadMultiply, - KeyCode.numpadSubtract: LogicalKeyboardKey.numpadSubtract, - KeyCode.numpadAdd: LogicalKeyboardKey.numpadAdd, - KeyCode.numpadEnter: LogicalKeyboardKey.numpadEnter, - KeyCode.numpad1: LogicalKeyboardKey.numpad1, - KeyCode.numpad2: LogicalKeyboardKey.numpad2, - KeyCode.numpad3: LogicalKeyboardKey.numpad3, - KeyCode.numpad4: LogicalKeyboardKey.numpad4, - KeyCode.numpad5: LogicalKeyboardKey.numpad5, - KeyCode.numpad6: LogicalKeyboardKey.numpad6, - KeyCode.numpad7: LogicalKeyboardKey.numpad7, - KeyCode.numpad8: LogicalKeyboardKey.numpad8, - KeyCode.numpad9: LogicalKeyboardKey.numpad9, - KeyCode.numpad0: LogicalKeyboardKey.numpad0, - KeyCode.numpadDecimal: LogicalKeyboardKey.numpadDecimal, - KeyCode.intlBackslash: LogicalKeyboardKey.intlBackslash, - KeyCode.contextMenu: LogicalKeyboardKey.contextMenu, - KeyCode.power: LogicalKeyboardKey.power, - KeyCode.numpadEqual: LogicalKeyboardKey.numpadEqual, - KeyCode.f13: LogicalKeyboardKey.f13, - KeyCode.f14: LogicalKeyboardKey.f14, - KeyCode.f15: LogicalKeyboardKey.f15, - KeyCode.f16: LogicalKeyboardKey.f16, - KeyCode.f17: LogicalKeyboardKey.f17, - KeyCode.f18: LogicalKeyboardKey.f18, - KeyCode.f19: LogicalKeyboardKey.f19, - KeyCode.f20: LogicalKeyboardKey.f20, - KeyCode.f21: LogicalKeyboardKey.f21, - KeyCode.f22: LogicalKeyboardKey.f22, - KeyCode.f23: LogicalKeyboardKey.f23, - KeyCode.f24: LogicalKeyboardKey.f24, - KeyCode.open: LogicalKeyboardKey.open, - KeyCode.help: LogicalKeyboardKey.help, - KeyCode.select: LogicalKeyboardKey.select, - KeyCode.again: LogicalKeyboardKey.again, - KeyCode.undo: LogicalKeyboardKey.undo, - KeyCode.cut: LogicalKeyboardKey.cut, - KeyCode.copy: LogicalKeyboardKey.copy, - KeyCode.paste: LogicalKeyboardKey.paste, - KeyCode.find: LogicalKeyboardKey.find, - KeyCode.audioVolumeMute: LogicalKeyboardKey.audioVolumeMute, - KeyCode.audioVolumeUp: LogicalKeyboardKey.audioVolumeUp, - KeyCode.audioVolumeDown: LogicalKeyboardKey.audioVolumeDown, - KeyCode.numpadComma: LogicalKeyboardKey.numpadComma, - KeyCode.intlRo: LogicalKeyboardKey.intlRo, - KeyCode.kanaMode: LogicalKeyboardKey.kanaMode, - KeyCode.intlYen: LogicalKeyboardKey.intlYen, - KeyCode.convert: LogicalKeyboardKey.convert, - KeyCode.nonConvert: LogicalKeyboardKey.nonConvert, - KeyCode.lang1: LogicalKeyboardKey.lang1, - KeyCode.lang2: LogicalKeyboardKey.lang2, - KeyCode.lang3: LogicalKeyboardKey.lang3, - KeyCode.lang4: LogicalKeyboardKey.lang4, - KeyCode.lang5: LogicalKeyboardKey.lang5, - KeyCode.abort: LogicalKeyboardKey.abort, - KeyCode.props: LogicalKeyboardKey.props, - KeyCode.numpadParenLeft: LogicalKeyboardKey.numpadParenLeft, - KeyCode.numpadParenRight: LogicalKeyboardKey.numpadParenRight, - // KeyCode.numpadBackspace: LogicalKeyboardKey.numpadBackspace, - // KeyCode.numpadMemoryStore: LogicalKeyboardKey.numpadMemoryStore, - // KeyCode.numpadMemoryRecall: LogicalKeyboardKey.numpadMemoryRecall, - // KeyCode.numpadMemoryClear: LogicalKeyboardKey.numpadMemoryClear, - // KeyCode.numpadMemoryAdd: LogicalKeyboardKey.numpadMemoryAdd, - // KeyCode.numpadMemorySubtract: LogicalKeyboardKey.numpadMemorySubtract, - // KeyCode.numpadSignChange: LogicalKeyboardKey.numpadSignChange, - // KeyCode.numpadClear: LogicalKeyboardKey.numpadClear, - // KeyCode.numpadClearEntry: LogicalKeyboardKey.numpadClearEntry, - KeyCode.controlLeft: LogicalKeyboardKey.controlLeft, - KeyCode.shiftLeft: LogicalKeyboardKey.shiftLeft, - KeyCode.altLeft: LogicalKeyboardKey.altLeft, - KeyCode.metaLeft: LogicalKeyboardKey.metaLeft, - KeyCode.controlRight: LogicalKeyboardKey.controlRight, - KeyCode.shiftRight: LogicalKeyboardKey.shiftRight, - KeyCode.altRight: LogicalKeyboardKey.altRight, - KeyCode.metaRight: LogicalKeyboardKey.metaRight, - KeyCode.info: LogicalKeyboardKey.info, - KeyCode.closedCaptionToggle: LogicalKeyboardKey.closedCaptionToggle, - KeyCode.brightnessUp: LogicalKeyboardKey.brightnessUp, - KeyCode.brightnessDown: LogicalKeyboardKey.brightnessDown, - // KeyCode.brightnessToggle: LogicalKeyboardKey.brightnessToggle, - // KeyCode.brightnessMinimum: LogicalKeyboardKey.brightnessMinimum, - // KeyCode.brightnessMaximum: LogicalKeyboardKey.brightnessMaximum, - // KeyCode.brightnessAuto: LogicalKeyboardKey.brightnessAuto, - // KeyCode.kbdIllumUp: LogicalKeyboardKey.kbdIllumUp, - // KeyCode.kbdIllumDown: LogicalKeyboardKey.kbdIllumDown, - KeyCode.mediaLast: LogicalKeyboardKey.mediaLast, - KeyCode.launchPhone: LogicalKeyboardKey.launchPhone, - // KeyCode.programGuide: LogicalKeyboardKey.programGuide, - KeyCode.exit: LogicalKeyboardKey.exit, - KeyCode.channelUp: LogicalKeyboardKey.channelUp, - KeyCode.channelDown: LogicalKeyboardKey.channelDown, - KeyCode.mediaPlay: LogicalKeyboardKey.mediaPlay, - KeyCode.mediaPause: LogicalKeyboardKey.mediaPause, - KeyCode.mediaRecord: LogicalKeyboardKey.mediaRecord, - KeyCode.mediaFastForward: LogicalKeyboardKey.mediaFastForward, - KeyCode.mediaRewind: LogicalKeyboardKey.mediaRewind, - KeyCode.mediaTrackNext: LogicalKeyboardKey.mediaTrackNext, - KeyCode.mediaTrackPrevious: LogicalKeyboardKey.mediaTrackPrevious, - KeyCode.mediaStop: LogicalKeyboardKey.mediaStop, - KeyCode.eject: LogicalKeyboardKey.eject, - KeyCode.mediaPlayPause: LogicalKeyboardKey.mediaPlayPause, - KeyCode.speechInputToggle: LogicalKeyboardKey.speechInputToggle, - // KeyCode.bassBoost: LogicalKeyboardKey.bassBoost, - // KeyCode.mediaSelect: LogicalKeyboardKey.mediaSelect, - KeyCode.launchWordProcessor: LogicalKeyboardKey.launchWordProcessor, - KeyCode.launchSpreadsheet: LogicalKeyboardKey.launchSpreadsheet, - KeyCode.launchMail: LogicalKeyboardKey.launchMail, - KeyCode.launchContacts: LogicalKeyboardKey.launchContacts, - KeyCode.launchCalendar: LogicalKeyboardKey.launchCalendar, - // KeyCode.launchApp2: LogicalKeyboardKey.launchApp2, - // KeyCode.launchApp1: LogicalKeyboardKey.launchApp1, - // KeyCode.launchInternetBrowser: LogicalKeyboardKey.launchInternetBrowser, - KeyCode.logOff: LogicalKeyboardKey.logOff, - // KeyCode.lockScreen: LogicalKeyboardKey.lockScreen, - KeyCode.launchControlPanel: LogicalKeyboardKey.launchControlPanel, - // KeyCode.selectTask: LogicalKeyboardKey.selectTask, - // KeyCode.launchDocuments: LogicalKeyboardKey.launchDocuments, - KeyCode.spellCheck: LogicalKeyboardKey.spellCheck, - // KeyCode.launchKeyboardLayout: LogicalKeyboardKey.launchKeyboardLayout, - KeyCode.launchScreenSaver: LogicalKeyboardKey.launchScreenSaver, - KeyCode.launchAssistant: LogicalKeyboardKey.launchAssistant, - // KeyCode.launchAudioBrowser: LogicalKeyboardKey.launchAudioBrowser, - KeyCode.newKey: LogicalKeyboardKey.newKey, - KeyCode.close: LogicalKeyboardKey.close, - KeyCode.save: LogicalKeyboardKey.save, - KeyCode.print: LogicalKeyboardKey.print, - KeyCode.browserSearch: LogicalKeyboardKey.browserSearch, - KeyCode.browserHome: LogicalKeyboardKey.browserHome, - KeyCode.browserBack: LogicalKeyboardKey.browserBack, - KeyCode.browserForward: LogicalKeyboardKey.browserForward, - KeyCode.browserStop: LogicalKeyboardKey.browserStop, - KeyCode.browserRefresh: LogicalKeyboardKey.browserRefresh, - KeyCode.browserFavorites: LogicalKeyboardKey.browserFavorites, - KeyCode.zoomIn: LogicalKeyboardKey.zoomIn, - KeyCode.zoomOut: LogicalKeyboardKey.zoomOut, - KeyCode.zoomToggle: LogicalKeyboardKey.zoomToggle, - KeyCode.redo: LogicalKeyboardKey.redo, - KeyCode.mailReply: LogicalKeyboardKey.mailReply, - KeyCode.mailForward: LogicalKeyboardKey.mailForward, - KeyCode.mailSend: LogicalKeyboardKey.mailSend, - // KeyCode.keyboardLayoutSelect: LogicalKeyboardKey.keyboardLayoutSelect, - // KeyCode.showAllWindows: LogicalKeyboardKey.showAllWindows, - KeyCode.gameButton1: LogicalKeyboardKey.gameButton1, - KeyCode.gameButton2: LogicalKeyboardKey.gameButton2, - KeyCode.gameButton3: LogicalKeyboardKey.gameButton3, - KeyCode.gameButton4: LogicalKeyboardKey.gameButton4, - KeyCode.gameButton5: LogicalKeyboardKey.gameButton5, - KeyCode.gameButton6: LogicalKeyboardKey.gameButton6, - KeyCode.gameButton7: LogicalKeyboardKey.gameButton7, - KeyCode.gameButton8: LogicalKeyboardKey.gameButton8, - KeyCode.gameButton9: LogicalKeyboardKey.gameButton9, - KeyCode.gameButton10: LogicalKeyboardKey.gameButton10, - KeyCode.gameButton11: LogicalKeyboardKey.gameButton11, - KeyCode.gameButton12: LogicalKeyboardKey.gameButton12, - KeyCode.gameButton13: LogicalKeyboardKey.gameButton13, - KeyCode.gameButton14: LogicalKeyboardKey.gameButton14, - KeyCode.gameButton15: LogicalKeyboardKey.gameButton15, - KeyCode.gameButton16: LogicalKeyboardKey.gameButton16, - KeyCode.gameButtonA: LogicalKeyboardKey.gameButtonA, - KeyCode.gameButtonB: LogicalKeyboardKey.gameButtonB, - KeyCode.gameButtonC: LogicalKeyboardKey.gameButtonC, - KeyCode.gameButtonLeft1: LogicalKeyboardKey.gameButtonLeft1, - KeyCode.gameButtonLeft2: LogicalKeyboardKey.gameButtonLeft2, - KeyCode.gameButtonMode: LogicalKeyboardKey.gameButtonMode, - KeyCode.gameButtonRight1: LogicalKeyboardKey.gameButtonRight1, - KeyCode.gameButtonRight2: LogicalKeyboardKey.gameButtonRight2, - KeyCode.gameButtonSelect: LogicalKeyboardKey.gameButtonSelect, - KeyCode.gameButtonStart: LogicalKeyboardKey.gameButtonStart, - KeyCode.gameButtonThumbLeft: LogicalKeyboardKey.gameButtonThumbLeft, - KeyCode.gameButtonThumbRight: LogicalKeyboardKey.gameButtonThumbRight, - KeyCode.gameButtonX: LogicalKeyboardKey.gameButtonX, - KeyCode.gameButtonY: LogicalKeyboardKey.gameButtonY, - KeyCode.gameButtonZ: LogicalKeyboardKey.gameButtonZ, - KeyCode.fn: LogicalKeyboardKey.fn, - KeyCode.shift: LogicalKeyboardKey.shift, - KeyCode.meta: LogicalKeyboardKey.meta, - KeyCode.alt: LogicalKeyboardKey.alt, - KeyCode.control: LogicalKeyboardKey.control, -}; - -enum KeyCode { - // none, - hyper, - superKey, - fnLock, - suspend, - resume, - // turbo, - // privacyScreenToggle, - sleep, - wakeUp, - // displayToggleIntExt, - // usbReserved, - // usbErrorRollOver, - // usbPostFail, - // usbErrorUndefined, - keyA, - keyB, - keyC, - keyD, - keyE, - keyF, - keyG, - keyH, - keyI, - keyJ, - keyK, - keyL, - keyM, - keyN, - keyO, - keyP, - keyQ, - keyR, - keyS, - keyT, - keyU, - keyV, - keyW, - keyX, - keyY, - keyZ, - digit1, - digit2, - digit3, - digit4, - digit5, - digit6, - digit7, - digit8, - digit9, - digit0, - enter, - escape, - backspace, - tab, - space, - add, - minus, - numberSign, - multiply, - equal, - bracketLeft, - bracketRight, - backslash, - semicolon, - quote, - backquote, - comma, - period, - slash, - capsLock, - f1, - f2, - f3, - f4, - f5, - f6, - f7, - f8, - f9, - f10, - f11, - f12, - printScreen, - scrollLock, - pause, - insert, - home, - pageUp, - delete, - end, - pageDown, - arrowRight, - arrowLeft, - arrowDown, - arrowUp, - numLock, - numpadDivide, - numpadMultiply, - numpadSubtract, - numpadAdd, - numpadEnter, - numpad1, - numpad2, - numpad3, - numpad4, - numpad5, - numpad6, - numpad7, - numpad8, - numpad9, - numpad0, - numpadDecimal, - intlBackslash, - contextMenu, - power, - numpadEqual, - f13, - f14, - f15, - f16, - f17, - f18, - f19, - f20, - f21, - f22, - f23, - f24, - open, - help, - select, - again, - undo, - cut, - copy, - paste, - find, - audioVolumeMute, - audioVolumeUp, - audioVolumeDown, - numpadComma, - intlRo, - kanaMode, - intlYen, - convert, - nonConvert, - lang1, - lang2, - lang3, - lang4, - lang5, - abort, - props, - numpadParenLeft, - numpadParenRight, - // numpadBackspace, - // numpadMemoryStore, - // numpadMemoryRecall, - // numpadMemoryClear, - // numpadMemoryAdd, - // numpadMemorySubtract, - // numpadSignChange, - // numpadClear, - // numpadClearEntry, - controlLeft, - shiftLeft, - altLeft, - metaLeft, - controlRight, - shiftRight, - altRight, - metaRight, - info, - closedCaptionToggle, - brightnessUp, - brightnessDown, - // brightnessToggle, - // brightnessMinimum, - // brightnessMaximum, - // brightnessAuto, - // kbdIllumUp, - // kbdIllumDown, - mediaLast, - launchPhone, - // programGuide, - exit, - channelUp, - channelDown, - mediaPlay, - mediaPause, - mediaRecord, - mediaFastForward, - mediaRewind, - mediaTrackNext, - mediaTrackPrevious, - mediaStop, - eject, - mediaPlayPause, - speechInputToggle, - // bassBoost, - // mediaSelect, - launchWordProcessor, - launchSpreadsheet, - launchMail, - launchContacts, - launchCalendar, - // launchApp2, - // launchApp1, - // launchInternetBrowser, - logOff, - // lockScreen, - launchControlPanel, - // selectTask, - // launchDocuments, - spellCheck, - // launchKeyboardLayout, - launchScreenSaver, - launchAssistant, - // launchAudioBrowser, - newKey, - close, - save, - print, - browserSearch, - browserHome, - browserBack, - browserForward, - browserStop, - browserRefresh, - browserFavorites, - zoomIn, - zoomOut, - zoomToggle, - redo, - mailReply, - mailForward, - mailSend, - // keyboardLayoutSelect, - // showAllWindows, - gameButton1, - gameButton2, - gameButton3, - gameButton4, - gameButton5, - gameButton6, - gameButton7, - gameButton8, - gameButton9, - gameButton10, - gameButton11, - gameButton12, - gameButton13, - gameButton14, - gameButton15, - gameButton16, - gameButtonA, - gameButtonB, - gameButtonC, - gameButtonLeft1, - gameButtonLeft2, - gameButtonMode, - gameButtonRight1, - gameButtonRight2, - gameButtonSelect, - gameButtonStart, - gameButtonThumbLeft, - gameButtonThumbRight, - gameButtonX, - gameButtonY, - gameButtonZ, - fn, - shift, - meta, - alt, - control, -} - -final Map _knownKeyLabels = { - KeyCode.keyA: 'A', - KeyCode.keyB: 'B', - KeyCode.keyC: 'C', - KeyCode.keyD: 'D', - KeyCode.keyE: 'E', - KeyCode.keyF: 'F', - KeyCode.keyG: 'G', - KeyCode.keyH: 'H', - KeyCode.keyI: 'I', - KeyCode.keyJ: 'J', - KeyCode.keyK: 'K', - KeyCode.keyL: 'L', - KeyCode.keyM: 'M', - KeyCode.keyN: 'N', - KeyCode.keyO: 'O', - KeyCode.keyP: 'P', - KeyCode.keyQ: 'Q', - KeyCode.keyR: 'R', - KeyCode.keyS: 'S', - KeyCode.keyT: 'T', - KeyCode.keyU: 'U', - KeyCode.keyV: 'V', - KeyCode.keyW: 'W', - KeyCode.keyX: 'X', - KeyCode.keyY: 'Y', - KeyCode.keyZ: 'Z', - KeyCode.digit1: '1', - KeyCode.digit2: '2', - KeyCode.digit3: '3', - KeyCode.digit4: '4', - KeyCode.digit5: '5', - KeyCode.digit6: '6', - KeyCode.digit7: '7', - KeyCode.digit8: '8', - KeyCode.digit9: '9', - KeyCode.digit0: '0', - KeyCode.enter: '↩︎', - KeyCode.escape: '⎋', - KeyCode.backspace: '←', - KeyCode.tab: '⇥', - KeyCode.space: '␣', - KeyCode.numberSign: '#', - KeyCode.minus: '-', - KeyCode.multiply: '*', - KeyCode.add: '+', - KeyCode.equal: '=', - KeyCode.bracketLeft: '[', - KeyCode.bracketRight: ']', - KeyCode.backslash: '\\', - KeyCode.semicolon: ';', - KeyCode.quote: '"', - KeyCode.backquote: '`', - KeyCode.comma: ',', - KeyCode.period: '.', - KeyCode.slash: '/', - KeyCode.capsLock: '⇪', - KeyCode.f1: 'F1', - KeyCode.f2: 'F2', - KeyCode.f3: 'F3', - KeyCode.f4: 'F4', - KeyCode.f5: 'F5', - KeyCode.f6: 'F6', - KeyCode.f7: 'F7', - KeyCode.f8: 'F8', - KeyCode.f9: 'F9', - KeyCode.f10: 'F10', - KeyCode.f11: 'F11', - KeyCode.f12: 'F12', - KeyCode.home: '↖', - KeyCode.pageUp: '⇞', - KeyCode.delete: '⌫', - KeyCode.end: '↘', - KeyCode.pageDown: '⇟', - KeyCode.arrowRight: '→', - KeyCode.arrowLeft: '←', - KeyCode.arrowDown: '↓', - KeyCode.arrowUp: '↑', - KeyCode.controlLeft: '⌃', - KeyCode.shiftLeft: '⇧', - KeyCode.altLeft: '⌥', - KeyCode.metaLeft: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', - KeyCode.controlRight: '⌃', - KeyCode.shiftRight: '⇧', - KeyCode.altRight: '⌥', - KeyCode.metaRight: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', - KeyCode.fn: 'fn', - KeyCode.shift: '⇧', - KeyCode.meta: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', - KeyCode.alt: '⌥', - KeyCode.control: '⌃', -}; - -extension KeyCodeParser on KeyCode { - static KeyCode? fromLogicalKey(LogicalKeyboardKey logicalKey) { - List logicalKeyIdList = - _knownLogicalKeys.values.map((e) => e.keyId).toList(); - if (!logicalKeyIdList.contains(logicalKey.keyId)) return null; - - return _knownLogicalKeys.entries - .firstWhere((entry) => entry.value.keyId == logicalKey.keyId) - .key; - } - - LogicalKeyboardKey get logicalKey { - return _knownLogicalKeys[this]!; - } - - static KeyCode parse(String string) { - return KeyCode.values.firstWhere((e) => e.name == string); - } - - String get stringValue { - return name; - } - - int get keyId { - return logicalKey.keyId; - } - - String get keyLabel { - return _knownKeyLabels[this] ?? logicalKey.keyLabel; - } -} diff --git a/packages/hotkey_manager/lib/src/enums/key_modifier.dart b/packages/hotkey_manager/lib/src/enums/key_modifier.dart deleted file mode 100644 index d5f4b91..0000000 --- a/packages/hotkey_manager/lib/src/enums/key_modifier.dart +++ /dev/null @@ -1,103 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart' show kIsWeb; -import 'package:flutter/services.dart'; - -const Map> _knownLogicalKeys = - >{ - KeyModifier.capsLock: [ - LogicalKeyboardKey.capsLock, - ], - KeyModifier.shift: [ - LogicalKeyboardKey.shift, - LogicalKeyboardKey.shiftLeft, - LogicalKeyboardKey.shiftRight, - ], - KeyModifier.control: [ - LogicalKeyboardKey.control, - LogicalKeyboardKey.controlLeft, - LogicalKeyboardKey.controlRight, - ], - KeyModifier.alt: [ - LogicalKeyboardKey.alt, - LogicalKeyboardKey.altLeft, - LogicalKeyboardKey.altRight, - ], - KeyModifier.meta: [ - LogicalKeyboardKey.meta, - LogicalKeyboardKey.metaLeft, - LogicalKeyboardKey.metaRight, - ], - KeyModifier.fn: [ - LogicalKeyboardKey.fn, - ], -}; - -const Map _knownModifierKeys = - { - KeyModifier.capsLock: ModifierKey.capsLockModifier, - KeyModifier.shift: ModifierKey.shiftModifier, - KeyModifier.control: ModifierKey.controlModifier, - KeyModifier.alt: ModifierKey.altModifier, - KeyModifier.meta: ModifierKey.metaModifier, - KeyModifier.fn: ModifierKey.functionModifier, -}; - -final Map _knownKeyLabels = { - KeyModifier.capsLock: '⇪', - KeyModifier.shift: '⇧', - KeyModifier.control: (!kIsWeb && Platform.isMacOS) ? '⌃' : 'Ctrl', - KeyModifier.alt: (!kIsWeb && Platform.isMacOS) ? '⌥' : 'Alt', - KeyModifier.meta: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', - KeyModifier.fn: 'fn', -}; - -enum KeyModifier { - capsLock, - shift, - control, - alt, // Alt / Option key - meta, // Command / Win key - fn, -} - -extension KeyModifierParser on KeyModifier { - static KeyModifier parse(String string) { - return KeyModifier.values.firstWhere((e) => e.name == string); - } - - static KeyModifier? fromModifierKey(ModifierKey modifierKey) { - return _knownModifierKeys.entries - .firstWhere((entry) => entry.value == modifierKey) - .key; - } - - ModifierKey get modifierKey { - return _knownModifierKeys[this]!; - } - - static KeyModifier? fromLogicalKey(LogicalKeyboardKey logicalKey) { - List logicalKeyIdList = []; - - for (List item in _knownLogicalKeys.values) { - logicalKeyIdList.addAll(item.map((e) => e.keyId).toList()); - } - if (!logicalKeyIdList.contains(logicalKey.keyId)) return null; - - return _knownLogicalKeys.entries - .firstWhere( - (entry) => entry.value.map((e) => e.keyId).contains(logicalKey.keyId), - ) - .key; - } - - List get logicalKeys { - return _knownLogicalKeys[this]!; - } - - String get stringValue => name; - - String get keyLabel { - return _knownKeyLabels[this] ?? name; - } -} diff --git a/packages/hotkey_manager/lib/src/hotkey.dart b/packages/hotkey_manager/lib/src/hotkey.dart deleted file mode 100644 index 8b94c61..0000000 --- a/packages/hotkey_manager/lib/src/hotkey.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:hotkey_manager/src/enums/key_code.dart'; -import 'package:hotkey_manager/src/enums/key_modifier.dart'; -import 'package:uuid/uuid.dart'; - -enum HotKeyScope { - system, - inapp, -} - -class HotKey { - HotKey( - this.keyCode, { - this.modifiers, - String? identifier, - HotKeyScope? scope, - }) { - if (identifier != null) this.identifier = identifier; - if (scope != null) this.scope = scope; - } - - factory HotKey.fromJson(Map json) { - return HotKey( - KeyCodeParser.parse(json['keyCode']), - modifiers: List.from(json['modifiers']) - .map((e) => KeyModifierParser.parse(e)) - .toList(), - identifier: json['identifier'], - scope: HotKeyScope.values.firstWhere( - (e) => e.name == json['scope'], - orElse: () => HotKeyScope.system, - ), - ); - } - - KeyCode keyCode; - List? modifiers; - String identifier = const Uuid().v4(); - HotKeyScope scope = HotKeyScope.system; - - Map toJson() { - return { - 'keyCode': keyCode.stringValue, - 'modifiers': modifiers?.map((e) => e.stringValue).toList() ?? [], - 'identifier': identifier, - 'scope': scope.name, - }; - } - - @override - String toString() { - return '${modifiers?.map((e) => e.keyLabel).join('')}${keyCode.keyLabel}'; - } -} diff --git a/packages/hotkey_manager/lib/src/hotkey_manager.dart b/packages/hotkey_manager/lib/src/hotkey_manager.dart index 22f3128..b1f2b03 100644 --- a/packages/hotkey_manager/lib/src/hotkey_manager.dart +++ b/packages/hotkey_manager/lib/src/hotkey_manager.dart @@ -1,13 +1,8 @@ -// ignore_for_file: avoid_print - import 'dart:async'; import 'package:collection/collection.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:hotkey_manager/src/enums/key_code.dart'; -import 'package:hotkey_manager/src/enums/key_modifier.dart'; -import 'package:hotkey_manager/src/hotkey.dart'; - -typedef HotKeyHandler = void Function(HotKey hotKey); +import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; class HotKeyManager { HotKeyManager._(); @@ -15,7 +10,7 @@ class HotKeyManager { /// The shared instance of [HotKeyManager]. static final HotKeyManager instance = HotKeyManager._(); - final MethodChannel _channel = const MethodChannel('hotkey_manager'); + HotKeyManagerPlatform get _platform => HotKeyManagerPlatform.instance; bool _inited = false; final List _hotKeyList = []; @@ -26,29 +21,56 @@ class HotKeyManager { HotKey? _lastPressedHotKey; void _init() { - RawKeyboard.instance.addListener(_handleRawKeyEvent); - _channel.setMethodCallHandler(_methodCallHandler); + HardwareKeyboard.instance.addHandler(_handleKeyEvent); + _platform.onKeyEventReceiver.listen((event) { + if (kDebugMode) { + print(event); + } + String type = event['type'] as String; + Map data = event['data'] as Map; + String identifier = data['identifier'] as String; + HotKey? hotKey = _hotKeyList.firstWhereOrNull( + (e) => e.identifier == identifier, + ); + if (hotKey != null) { + switch (type) { + case 'onKeyDown': + if (_keyDownHandlerMap.containsKey(identifier)) { + _keyDownHandlerMap[identifier]!(hotKey); + } + break; + case 'onKeyUp': + if (_keyUpHandlerMap.containsKey(identifier)) { + _keyUpHandlerMap[identifier]!(hotKey); + } + break; + default: + UnimplementedError(); + } + } + }); _inited = true; } - _handleRawKeyEvent(RawKeyEvent value) { - if (value is RawKeyUpEvent && _lastPressedHotKey != null) { + bool _handleKeyEvent(KeyEvent keyEvent) { + if (keyEvent is KeyUpEvent && _lastPressedHotKey != null) { HotKeyHandler? handler = _keyUpHandlerMap[_lastPressedHotKey!.identifier]; if (handler != null) handler(_lastPressedHotKey!); _lastPressedHotKey = null; - return; + return true; } - if (value is RawKeyDownEvent) { - if (value.repeat) return; + if (keyEvent is KeyDownEvent) { HotKey? hotKey = _hotKeyList.firstWhereOrNull( (e) { + List? pressedModifierKeys = + ModifierKey.values // pressed modifier keys + .where((e) => e.isModifierPressed) + .toList(); return e.scope == HotKeyScope.inapp && - value.isKeyPressed(e.keyCode.logicalKey) && - value.data.modifiersPressed.keys.length == - (e.modifiers ?? []).length && - (e.modifiers ?? []).every( - (m) => value.data.isModifierPressed(m.modifierKey), + keyEvent.logicalKey == e.logicalKey && + pressedModifierKeys.every( + (modifierKey) => (e.modifiers ?? []).contains(modifierKey), ); }, ); @@ -59,32 +81,7 @@ class HotKeyManager { _lastPressedHotKey = hotKey; } } - } - - Future _methodCallHandler(MethodCall call) async { - String identifier = call.arguments['identifier']; - HotKey? hotKey = _hotKeyList.firstWhereOrNull( - (e) => e.identifier == identifier, - ); - if (hotKey == null) { - print('[Warning] Can\'t find registered hotKey.'); - return; - } - - switch (call.method) { - case 'onKeyDown': - if (_keyDownHandlerMap.containsKey(identifier)) { - _keyDownHandlerMap[identifier]!(hotKey); - } - break; - case 'onKeyUp': - if (_keyUpHandlerMap.containsKey(identifier)) { - _keyUpHandlerMap[identifier]!(hotKey); - } - break; - default: - UnimplementedError(); - } + return true; } List get registeredHotKeyList => _hotKeyList; @@ -97,7 +94,7 @@ class HotKeyManager { if (!_inited) _init(); if (hotKey.scope == HotKeyScope.system) { - await _channel.invokeMethod('register', hotKey.toJson()); + await _platform.register(hotKey); } if (keyDownHandler != null) { _keyDownHandlerMap.update( @@ -121,7 +118,7 @@ class HotKeyManager { if (!_inited) _init(); if (hotKey.scope == HotKeyScope.system) { - await _channel.invokeMethod('unregister', hotKey.toJson()); + await _platform.unregister(hotKey); } if (_keyDownHandlerMap.containsKey(hotKey.identifier)) { _keyDownHandlerMap.remove(hotKey.identifier); @@ -136,7 +133,7 @@ class HotKeyManager { Future unregisterAll() async { if (!_inited) _init(); - await _channel.invokeMethod('unregisterAll'); + await _platform.unregisterAll(); _keyDownHandlerMap.clear(); _keyUpHandlerMap.clear(); diff --git a/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart b/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart index 2024e87..09fd66c 100644 --- a/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart +++ b/packages/hotkey_manager/lib/src/widgets/hotkey_recorder.dart @@ -1,11 +1,7 @@ -import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - -import 'package:hotkey_manager/src/enums/key_code.dart'; -import 'package:hotkey_manager/src/enums/key_modifier.dart'; -import 'package:hotkey_manager/src/hotkey.dart'; import 'package:hotkey_manager/src/widgets/hotkey_virtual_view.dart'; +import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; class HotKeyRecorder extends StatefulWidget { const HotKeyRecorder({ @@ -29,54 +25,37 @@ class _HotKeyRecorderState extends State { if (widget.initalHotKey != null) { _hotKey = widget.initalHotKey!; } - RawKeyboard.instance.addListener(_handleRawKeyEvent); + HardwareKeyboard.instance.addHandler(_handleKeyEvent); super.initState(); } @override void dispose() { - RawKeyboard.instance.removeListener(_handleRawKeyEvent); + HardwareKeyboard.instance.removeHandler(_handleKeyEvent); super.dispose(); } - _handleRawKeyEvent(RawKeyEvent value) { - if (value is! RawKeyDownEvent) return; - - KeyCode? keyCode; - List? keyModifiers; - - keyCode = KeyCode.values.firstWhereOrNull( - (kc) { - if (!value.isKeyPressed(kc.logicalKey)) return false; - KeyModifier? keyModifier = - KeyModifierParser.fromLogicalKey(kc.logicalKey); - - if (keyModifier != null && - value.data.isModifierPressed(keyModifier.modifierKey)) { - return false; - } - - return true; - }, - ); - keyModifiers = KeyModifier.values - .where((km) => value.data.isModifierPressed(km.modifierKey)) + bool _handleKeyEvent(KeyEvent keyEvent) { + if (keyEvent is KeyUpEvent) return false; + PhysicalKeyboardKey? key = keyEvent.physicalKey; + List? pressedModifierKeys = ModifierKey.values + .where((e) => e.isModifierPressed) // pressed modifier keys .toList(); - - if (keyCode != null) { - _hotKey = HotKey( - keyCode, - modifiers: keyModifiers, - ); - if (widget.initalHotKey != null) { - _hotKey?.identifier = widget.initalHotKey!.identifier; - _hotKey?.scope = widget.initalHotKey!.scope; - } - - widget.onHotKeyRecorded(_hotKey!); - - setState(() {}); + if (pressedModifierKeys.isNotEmpty) { + // Remove the modifier keys from the list of pressed keys + pressedModifierKeys = pressedModifierKeys + .where((e) => !e.physicalKeys.contains(key)) // linewrap + .toList(); } + _hotKey = HotKey( + identifier: widget.initalHotKey?.identifier, + key: key, + modifiers: pressedModifierKeys, + scope: widget.initalHotKey?.scope ?? HotKeyScope.system, + ); + widget.onHotKeyRecorded(_hotKey!); + setState(() {}); + return true; } @override 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 8c88a53..687dc82 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,6 @@ import 'package:flutter/material.dart'; -import 'package:hotkey_manager/hotkey_manager.dart'; +import 'package:flutter/services.dart'; +import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; class _VirtualKeyView extends StatelessWidget { const _VirtualKeyView({ @@ -50,12 +51,12 @@ class HotKeyVirtualView extends StatelessWidget { return Wrap( spacing: 8, children: [ - for (KeyModifier keyModifier in hotKey.modifiers ?? []) + for (ModifierKey modifierKey in hotKey.modifiers ?? []) _VirtualKeyView( - keyLabel: keyModifier.keyLabel, + keyLabel: modifierKey.keyLabel, ), _VirtualKeyView( - keyLabel: hotKey.keyCode.keyLabel, + keyLabel: hotKey.physicalKey.keyLabel, ), ], ); diff --git a/packages/hotkey_manager/macos/Classes/HotKeyExtension+Key.swift b/packages/hotkey_manager/macos/Classes/HotKeyExtension+Key.swift deleted file mode 100644 index 5129faf..0000000 --- a/packages/hotkey_manager/macos/Classes/HotKeyExtension+Key.swift +++ /dev/null @@ -1,150 +0,0 @@ -// -// HotKeyExtension+Key.swift -// hotkey_manager -// -// Created by Lijy91 on 2021/7/23. -// - -import HotKey - -extension Key { - public init?(pluginKeyCode: String) { - switch pluginKeyCode { - // MARK: - Letters - case "keyA": self = .a - case "keyB": self = .b - case "keyC": self = .c - case "keyD": self = .d - case "keyE": self = .e - case "keyF": self = .f - case "keyG": self = .g - case "keyH": self = .h - case "keyI": self = .i - case "keyJ": self = .j - case "keyK": self = .k - case "keyL": self = .l - case "keyM": self = .m - case "keyN": self = .n - case "keyO": self = .o - case "keyP": self = .p - case "keyQ": self = .q - case "keyR": self = .r - case "keyS": self = .s - case "keyT": self = .t - case "keyU": self = .u - case "keyV": self = .v - case "keyW": self = .w - case "keyX": self = .x - case "keyY": self = .y - case "keyZ": self = .z - - // MARK: - Numbers - case "digit0": self = .zero - case "digit1": self = .one - case "digit2": self = .two - case "digit3": self = .three - case "digit4": self = .four - case "digit5": self = .five - case "digit6": self = .six - case "digit7": self = .seven - case "digit8": self = .eight - case "digit9": self = .nine - - // MARK: - Symbols - case "period": self = .period - case "quote": self = .quote - case "bracketRight": self = .rightBracket - case "semicolon": self = .semicolon - case "slash": self = .slash - case "backslash": self = .backslash - case "comma": self = .comma - case "equal": self = .equal - case "grave": self = .grave // Backtick - case "bracketLeft": self = .leftBracket - case "minus": self = .minus - - // MARK: - Whitespace - case "space": self = .space - case "tab": self = .tab - case "enter": self = .return - - // MARK: - Modifiers - case "meta": self = .command - case "metaLeft": self = .command - case "metaRight": self = .rightCommand - case "alt": self = .option - case "altLeft": self = .option - case "altRight": self = .rightOption - case "control": self = .control - case "controlLeft": self = .control - case "controlRight": self = .rightControl - case "shift": self = .shift - case "shiftLeft": self = .shift - case "shiftRight": self = .rightShift - case "fn": self = .function - case "capsLock": self = .capsLock - - // MARK: - Navigation - case "pageUp": self = .pageUp - case "pageDown": self = .pageDown - case "home": self = .home - case "end": self = .end - case "arrowUp": self = .upArrow - case "arrowRight": self = .rightArrow - case "arrowDown": self = .downArrow - case "arrowLeft": self = .leftArrow - - // MARK: - Functions - case "f1": self = .f1 - case "f2": self = .f2 - case "f3": self = .f3 - case "f4": self = .f4 - case "f5": self = .f5 - case "f6": self = .f6 - case "f7": self = .f7 - case "f8": self = .f8 - case "f9": self = .f9 - case "f10": self = .f10 - case "f11": self = .f11 - case "f12": self = .f12 - case "f13": self = .f13 - case "f14": self = .f14 - case "f15": self = .f15 - case "f16": self = .f16 - case "f17": self = .f17 - case "f18": self = .f18 - case "f19": self = .f19 - case "f20": self = .f20 - - // MARK: - Keypad - case "numpad0": self = .keypad0 - case "numpad1": self = .keypad1 - case "numpad2": self = .keypad2 - case "numpad3": self = .keypad3 - case "numpad4": self = .keypad4 - case "numpad5": self = .keypad5 - case "numpad6": self = .keypad6 - case "numpad7": self = .keypad7 - case "numpad8": self = .keypad8 - case "numpad9": self = .keypad9 - case "numpadClear": self = .keypadClear - case "numpadDecimal": self = .keypadDecimal - case "numpadDivide": self = .keypadDivide - case "numpadEnter": self = .keypadEnter - case "numpadEquals": self = .keypadEquals - case "numpadMinus": self = .keypadMinus - case "numpadMultiply": self = .keypadMultiply - case "numpadAdd": self = .keypadPlus - - // MARK: - Misc - case "escape": self = .escape - case "delete": self = .delete - case "forwardDelete": self = .forwardDelete - case "help": self = .help - case "audioVolumeUp": self = .volumeUp - case "audioVolumeDown": self = .volumeDown - case "audioVolumeMute": self = .mute - default: return nil - } - } -} diff --git a/packages/hotkey_manager/pubspec.yaml b/packages/hotkey_manager/pubspec.yaml index fdf7ebb..a032b4a 100644 --- a/packages/hotkey_manager/pubspec.yaml +++ b/packages/hotkey_manager/pubspec.yaml @@ -22,7 +22,11 @@ dependencies: collection: ^1.17.1 flutter: sdk: flutter - uuid: ">=3.0.7 <5.0.0" + # hotkey_manager_linux: ^0.2.0 + hotkey_manager_macos: ^0.2.0 + hotkey_manager_platform_interface: ^0.2.0 + # hotkey_manager_windows: ^0.2.0 + uuid: '>=3.0.7 <5.0.0' dev_dependencies: dependency_validator: ^3.0.0 @@ -33,9 +37,9 @@ dev_dependencies: flutter: plugin: platforms: - linux: - pluginClass: HotkeyManagerPlugin + # linux: + # default_package: hotkey_manager_linux macos: - pluginClass: HotkeyManagerPlugin - windows: - pluginClass: HotkeyManagerPlugin + default_package: hotkey_manager_macos + # windows: + # default_package: hotkey_manager_windows diff --git a/packages/hotkey_manager_macos/.gitignore b/packages/hotkey_manager_macos/.gitignore new file mode 100644 index 0000000..ac5aa98 --- /dev/null +++ b/packages/hotkey_manager_macos/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/hotkey_manager_macos/.metadata b/packages/hotkey_manager_macos/.metadata new file mode 100644 index 0000000..6422a99 --- /dev/null +++ b/packages/hotkey_manager_macos/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "67457e669f79e9f8d13d7a68fe09775fefbb79f4" + channel: "stable" + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 + base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 + - platform: macos + create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 + base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/hotkey_manager_macos/CHANGELOG.md b/packages/hotkey_manager_macos/CHANGELOG.md new file mode 100644 index 0000000..2f145ce --- /dev/null +++ b/packages/hotkey_manager_macos/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.2.0 + +* First release. diff --git a/packages/hotkey_manager_macos/LICENSE b/packages/hotkey_manager_macos/LICENSE new file mode 100644 index 0000000..eea05ab --- /dev/null +++ b/packages/hotkey_manager_macos/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2024 LiJianying + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/hotkey_manager_macos/README.md b/packages/hotkey_manager_macos/README.md new file mode 100644 index 0000000..cf173ae --- /dev/null +++ b/packages/hotkey_manager_macos/README.md @@ -0,0 +1,12 @@ +# hotkey_manager_macos + +[![pub version][pub-image]][pub-url] + +[pub-image]: https://img.shields.io/pub/v/hotkey_manager_macos.svg +[pub-url]: https://pub.dev/packages/hotkey_manager_macos + +The macOS implementation of [hotkey_manager](https://pub.dev/packages/hotkey_manager). + +## License + +[MIT](./LICENSE) diff --git a/packages/hotkey_manager_macos/analysis_options.yaml b/packages/hotkey_manager_macos/analysis_options.yaml new file mode 100644 index 0000000..095b1d6 --- /dev/null +++ b/packages/hotkey_manager_macos/analysis_options.yaml @@ -0,0 +1 @@ +include: package:mostly_reasonable_lints/flutter.yaml diff --git a/packages/hotkey_manager/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift b/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift similarity index 56% rename from packages/hotkey_manager/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift rename to packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift index 01b8900..4e8284c 100644 --- a/packages/hotkey_manager/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift +++ b/packages/hotkey_manager_macos/macos/Classes/HotKeyExtension+NSEventModifierFlags.swift @@ -8,22 +8,22 @@ extension NSEvent.ModifierFlags { public init(pluginModifiers: Array) { self.init() - if (pluginModifiers.contains("capsLock")) { + if (pluginModifiers.contains("capsLockModifier")) { insert(.capsLock) } - if (pluginModifiers.contains("shift")) { + if (pluginModifiers.contains("shiftModifier")) { insert(.shift) } - if (pluginModifiers.contains("control")) { + if (pluginModifiers.contains("controlModifier")) { insert(.control) } - if (pluginModifiers.contains("alt")) { + if (pluginModifiers.contains("altModifier")) { insert(.option) } - if (pluginModifiers.contains("meta")) { + if (pluginModifiers.contains("metaModifier")) { insert(.command) } - if (pluginModifiers.contains("fn")) { + if (pluginModifiers.contains("functionModifier")) { insert(.function) } } diff --git a/packages/hotkey_manager/macos/Classes/HotkeyManagerPlugin.swift b/packages/hotkey_manager_macos/macos/Classes/HotkeyManagerMacosPlugin.swift similarity index 50% rename from packages/hotkey_manager/macos/Classes/HotkeyManagerPlugin.swift rename to packages/hotkey_manager_macos/macos/Classes/HotkeyManagerMacosPlugin.swift index b98a111..a46b1e4 100644 --- a/packages/hotkey_manager/macos/Classes/HotkeyManagerPlugin.swift +++ b/packages/hotkey_manager_macos/macos/Classes/HotkeyManagerMacosPlugin.swift @@ -3,16 +3,27 @@ import FlutterMacOS import HotKey import Carbon -public class HotkeyManagerPlugin: NSObject, FlutterPlugin { - var channel: FlutterMethodChannel! +public class HotkeyManagerMacosPlugin: NSObject, FlutterPlugin, FlutterStreamHandler { + private var _eventSink: FlutterEventSink? var hotKeyDict: Dictionary = [:] public static func register(with registrar: FlutterPluginRegistrar) { - let channel = FlutterMethodChannel(name: "hotkey_manager", binaryMessenger: registrar.messenger) - let instance = HotkeyManagerPlugin() - instance.channel = channel + let channel = FlutterMethodChannel(name: "dev.leanflutter.plugins/hotkey_manager", binaryMessenger: registrar.messenger) + let instance = HotkeyManagerMacosPlugin() registrar.addMethodCallDelegate(instance, channel: channel) + let eventChannel = FlutterEventChannel(name: "dev.leanflutter.plugins/hotkey_manager_event", binaryMessenger: registrar.messenger) + eventChannel.setStreamHandler(instance) + } + + public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { + self._eventSink = events + return nil; + } + + public func onCancel(withArguments arguments: Any?) -> FlutterError? { + self._eventSink = nil + return nil } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { @@ -34,22 +45,35 @@ public class HotkeyManagerPlugin: NSObject, FlutterPlugin { public func register(_ call: FlutterMethodCall, result: @escaping FlutterResult) { let args:[String: Any] = call.arguments as! [String: Any] - let keyCode = args["keyCode"] as! String + let keyCode = args["keyCode"] as! UInt32 let modifiers = args["modifiers"] as! Array let identifier = args["identifier"] as! String - self.hotKeyDict[identifier] = HotKey( - key: Key.init(pluginKeyCode: keyCode)!, + let hotKey: HotKey = HotKey( + key: Key(carbonKeyCode: keyCode)!, modifiers: NSEvent.ModifierFlags.init(pluginModifiers: modifiers) ) - self.hotKeyDict[identifier]!.keyDownHandler = { - let arguments: NSDictionary = call.arguments as! NSDictionary - self.channel.invokeMethod("onKeyDown", arguments: arguments, result: nil) + hotKey.keyDownHandler = { + guard let eventSink = self._eventSink else { + return + } + let event: NSDictionary = [ + "type": "onKeyDown", + "data": call.arguments as! NSDictionary, + ] + eventSink(event) } - self.hotKeyDict[identifier]!.keyUpHandler = { - let arguments: NSDictionary = call.arguments as! NSDictionary - self.channel.invokeMethod("onKeyUp", arguments: arguments, result: nil) + hotKey.keyUpHandler = { + guard let eventSink = self._eventSink else { + return + } + let event: NSDictionary = [ + "type": "onKeyUp", + "data": call.arguments as! NSDictionary, + ] + eventSink(event) } + self.hotKeyDict[identifier] = hotKey result(true) } diff --git a/packages/hotkey_manager/macos/hotkey_manager.podspec b/packages/hotkey_manager_macos/macos/hotkey_manager_macos.podspec similarity index 70% rename from packages/hotkey_manager/macos/hotkey_manager.podspec rename to packages/hotkey_manager_macos/macos/hotkey_manager_macos.podspec index 366835a..63c7356 100644 --- a/packages/hotkey_manager/macos/hotkey_manager.podspec +++ b/packages/hotkey_manager_macos/macos/hotkey_manager_macos.podspec @@ -1,23 +1,24 @@ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint hotkey_manager.podspec` to validate before publishing. +# Run `pod lib lint hotkey_manager_macos.podspec` to validate before publishing. # Pod::Spec.new do |s| - s.name = 'hotkey_manager' + s.name = 'hotkey_manager_macos' s.version = '0.0.1' - s.summary = 'A new flutter plugin project.' + s.summary = 'A new Flutter plugin project.' s.description = <<-DESC -A new flutter plugin project. +A new Flutter plugin project. DESC s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'FlutterMacOS' s.dependency 'HotKey' - s.platform = :osx, '10.14' + s.platform = :osx, '10.11' s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } s.swift_version = '5.0' end diff --git a/packages/hotkey_manager_macos/pubspec.yaml b/packages/hotkey_manager_macos/pubspec.yaml new file mode 100644 index 0000000..a423b14 --- /dev/null +++ b/packages/hotkey_manager_macos/pubspec.yaml @@ -0,0 +1,26 @@ +name: hotkey_manager_macos +description: macOS implementation of the hotkey_manager plugin. +version: 0.2.0 +repository: https://github.com/leanflutter/hotkey_manager/tree/main/packages/hotkey_manager_macos + +environment: + sdk: '>=3.0.0 <4.0.0' + flutter: '>=3.3.0' + +dependencies: + flutter: + sdk: flutter + hotkey_manager_platform_interface: ^0.2.0 + +dev_dependencies: + flutter_test: + sdk: flutter + mostly_reasonable_lints: ^0.1.1 + +flutter: + plugin: + implements: hotkey_manager + platforms: + macos: + pluginClass: HotkeyManagerMacosPlugin + 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 915ef8c..a9e5dd8 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,6 +2,8 @@ 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/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/extensions/modifier_key.dart b/packages/hotkey_manager_platform_interface/lib/src/extensions/modifier_key.dart new file mode 100644 index 0000000..dd849e1 --- /dev/null +++ b/packages/hotkey_manager_platform_interface/lib/src/extensions/modifier_key.dart @@ -0,0 +1,54 @@ +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/extensions/physical_keyboard_key.dart b/packages/hotkey_manager_platform_interface/lib/src/extensions/physical_keyboard_key.dart new file mode 100644 index 0000000..a614dba --- /dev/null +++ b/packages/hotkey_manager_platform_interface/lib/src/extensions/physical_keyboard_key.dart @@ -0,0 +1,97 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +final Map _knownKeyLabels = + { + PhysicalKeyboardKey.keyA: 'A', + PhysicalKeyboardKey.keyB: 'B', + PhysicalKeyboardKey.keyC: 'C', + PhysicalKeyboardKey.keyD: 'D', + PhysicalKeyboardKey.keyE: 'E', + PhysicalKeyboardKey.keyF: 'F', + PhysicalKeyboardKey.keyG: 'G', + PhysicalKeyboardKey.keyH: 'H', + PhysicalKeyboardKey.keyI: 'I', + PhysicalKeyboardKey.keyJ: 'J', + PhysicalKeyboardKey.keyK: 'K', + PhysicalKeyboardKey.keyL: 'L', + PhysicalKeyboardKey.keyM: 'M', + PhysicalKeyboardKey.keyN: 'N', + PhysicalKeyboardKey.keyO: 'O', + PhysicalKeyboardKey.keyP: 'P', + PhysicalKeyboardKey.keyQ: 'Q', + PhysicalKeyboardKey.keyR: 'R', + PhysicalKeyboardKey.keyS: 'S', + PhysicalKeyboardKey.keyT: 'T', + PhysicalKeyboardKey.keyU: 'U', + PhysicalKeyboardKey.keyV: 'V', + PhysicalKeyboardKey.keyW: 'W', + PhysicalKeyboardKey.keyX: 'X', + PhysicalKeyboardKey.keyY: 'Y', + PhysicalKeyboardKey.keyZ: 'Z', + PhysicalKeyboardKey.digit1: '1', + PhysicalKeyboardKey.digit2: '2', + PhysicalKeyboardKey.digit3: '3', + PhysicalKeyboardKey.digit4: '4', + PhysicalKeyboardKey.digit5: '5', + PhysicalKeyboardKey.digit6: '6', + PhysicalKeyboardKey.digit7: '7', + PhysicalKeyboardKey.digit8: '8', + PhysicalKeyboardKey.digit9: '9', + PhysicalKeyboardKey.digit0: '0', + PhysicalKeyboardKey.enter: '↩︎', + PhysicalKeyboardKey.escape: '⎋', + PhysicalKeyboardKey.backspace: '←', + PhysicalKeyboardKey.tab: '⇥', + PhysicalKeyboardKey.space: '␣', + PhysicalKeyboardKey.minus: '-', + PhysicalKeyboardKey.equal: '=', + PhysicalKeyboardKey.bracketLeft: '[', + PhysicalKeyboardKey.bracketRight: ']', + PhysicalKeyboardKey.backslash: '\\', + PhysicalKeyboardKey.semicolon: ';', + PhysicalKeyboardKey.quote: '"', + PhysicalKeyboardKey.backquote: '`', + PhysicalKeyboardKey.comma: ',', + PhysicalKeyboardKey.period: '.', + PhysicalKeyboardKey.slash: '/', + PhysicalKeyboardKey.capsLock: '⇪', + PhysicalKeyboardKey.f1: 'F1', + PhysicalKeyboardKey.f2: 'F2', + PhysicalKeyboardKey.f3: 'F3', + PhysicalKeyboardKey.f4: 'F4', + PhysicalKeyboardKey.f5: 'F5', + PhysicalKeyboardKey.f6: 'F6', + PhysicalKeyboardKey.f7: 'F7', + PhysicalKeyboardKey.f8: 'F8', + PhysicalKeyboardKey.f9: 'F9', + PhysicalKeyboardKey.f10: 'F10', + PhysicalKeyboardKey.f11: 'F11', + PhysicalKeyboardKey.f12: 'F12', + PhysicalKeyboardKey.home: '↖', + PhysicalKeyboardKey.pageUp: '⇞', + PhysicalKeyboardKey.delete: '⌫', + PhysicalKeyboardKey.end: '↘', + PhysicalKeyboardKey.pageDown: '⇟', + PhysicalKeyboardKey.arrowRight: '→', + PhysicalKeyboardKey.arrowLeft: '←', + PhysicalKeyboardKey.arrowDown: '↓', + PhysicalKeyboardKey.arrowUp: '↑', + PhysicalKeyboardKey.controlLeft: '⌃', + PhysicalKeyboardKey.shiftLeft: '⇧', + PhysicalKeyboardKey.altLeft: '⌥', + PhysicalKeyboardKey.metaLeft: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', + PhysicalKeyboardKey.controlRight: '⌃', + PhysicalKeyboardKey.shiftRight: '⇧', + PhysicalKeyboardKey.altRight: '⌥', + PhysicalKeyboardKey.metaRight: (!kIsWeb && Platform.isMacOS) ? '⌘' : '⊞', + PhysicalKeyboardKey.fn: 'fn', +}; + +extension PhysicalKeyboardKeyExt on PhysicalKeyboardKey { + String get keyLabel { + return _knownKeyLabels[this] ?? debugName ?? 'Unknown'; + } +} diff --git a/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_method_channel.dart b/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_method_channel.dart index e1627e9..8055e87 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_method_channel.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_method_channel.dart @@ -1,13 +1,27 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:hotkey_manager_platform_interface/src/hotkey.dart'; -import 'package:hotkey_manager_platform_interface/src/hotkey_manager_platform_interface.dart'; +import 'package:hotkey_manager_platform_interface/hotkey_manager_platform_interface.dart'; +// ignore: implementation_imports +import 'package:uni_platform/src/extensions/keyboard_key.dart'; -/// An implementation of [HotkeyManagerPlatform] that uses method channels. -class MethodChannelHotkeyManager extends HotkeyManagerPlatform { +/// An implementation of [HotKeyManagerPlatform] that uses method channels. +class MethodChannelHotKeyManager extends HotKeyManagerPlatform { /// The method channel used to interact with the native platform. @visibleForTesting - final methodChannel = const MethodChannel('hotkey_manager'); + final methodChannel = const MethodChannel( + 'dev.leanflutter.plugins/hotkey_manager', + ); + + /// The event channel used to receive events from the native platform. + @visibleForTesting + final eventChannel = const EventChannel( + 'dev.leanflutter.plugins/hotkey_manager_event', + ); + + @override + Stream> get onKeyEventReceiver { + return eventChannel.receiveBroadcastStream().cast>(); + } @override Future getPlatformVersion() async { @@ -17,17 +31,19 @@ class MethodChannelHotkeyManager extends HotkeyManagerPlatform { } @override - Future register( - HotKey hotKey, { - HotKeyHandler? keyDownHandler, - HotKeyHandler? keyUpHandler, - }) async { - await methodChannel.invokeMethod('register', hotKey.toJson()); + Future register(HotKey hotKey) async { + await methodChannel.invokeMethod('register', { + 'keyCode': hotKey.physicalKey.keyCode, + ...hotKey.toJson(), + }); } @override Future unregister(HotKey hotKey) async { - await methodChannel.invokeMethod('unregister', hotKey.toJson()); + await methodChannel.invokeMethod('unregister', { + 'keyCode': hotKey.physicalKey.keyCode, + ...hotKey.toJson(), + }); } @override diff --git a/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_platform_interface.dart b/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_platform_interface.dart index 885ad90..1ac3446 100644 --- a/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_platform_interface.dart +++ b/packages/hotkey_manager_platform_interface/lib/src/hotkey_manager_platform_interface.dart @@ -2,23 +2,23 @@ import 'package:hotkey_manager_platform_interface/src/hotkey.dart'; import 'package:hotkey_manager_platform_interface/src/hotkey_manager_method_channel.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -abstract class HotkeyManagerPlatform extends PlatformInterface { - /// Constructs a HotkeyManagerPlatform. - HotkeyManagerPlatform() : super(token: _token); +abstract class HotKeyManagerPlatform extends PlatformInterface { + /// Constructs a HotKeyManagerPlatform. + HotKeyManagerPlatform() : super(token: _token); static final Object _token = Object(); - static HotkeyManagerPlatform _instance = MethodChannelHotkeyManager(); + static HotKeyManagerPlatform _instance = MethodChannelHotKeyManager(); - /// The default instance of [HotkeyManagerPlatform] to use. + /// The default instance of [HotKeyManagerPlatform] to use. /// - /// Defaults to [MethodChannelHotkeyManager]. - static HotkeyManagerPlatform get instance => _instance; + /// Defaults to [MethodChannelHotKeyManager]. + static HotKeyManagerPlatform get instance => _instance; /// Platform-specific implementations should set this with their own - /// platform-specific class that extends [HotkeyManagerPlatform] when + /// platform-specific class that extends [HotKeyManagerPlatform] when /// they register themselves. - static set instance(HotkeyManagerPlatform instance) { + static set instance(HotKeyManagerPlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; } @@ -27,19 +27,19 @@ abstract class HotkeyManagerPlatform extends PlatformInterface { throw UnimplementedError('platformVersion() has not been implemented.'); } - Future register( - HotKey hotKey, { - HotKeyHandler? keyDownHandler, - HotKeyHandler? keyUpHandler, - }) async { - + Stream> get onKeyEventReceiver { + throw UnimplementedError('onKeyEventReceiver() has not been implemented.'); } - Future unregister(HotKey hotKey) async { + Future register(HotKey hotKey) async { + throw UnimplementedError('register() has not been implemented.'); + } + Future unregister(HotKey hotKey) { + throw UnimplementedError('unregister() has not been implemented.'); } Future unregisterAll() async { - + throw UnimplementedError('unregisterAll() has not been implemented.'); } } diff --git a/packages/hotkey_manager_platform_interface/test/src/hotkey_manager_method_channel_test.dart b/packages/hotkey_manager_platform_interface/test/src/hotkey_manager_method_channel_test.dart index 2f74a43..c5490a4 100644 --- a/packages/hotkey_manager_platform_interface/test/src/hotkey_manager_method_channel_test.dart +++ b/packages/hotkey_manager_platform_interface/test/src/hotkey_manager_method_channel_test.dart @@ -5,7 +5,7 @@ import 'package:hotkey_manager_platform_interface/src/hotkey_manager_method_chan void main() { TestWidgetsFlutterBinding.ensureInitialized(); - MethodChannelHotkeyManager platform = MethodChannelHotkeyManager(); + MethodChannelHotKeyManager platform = MethodChannelHotKeyManager(); const MethodChannel channel = MethodChannel( 'dev.leanflutter.plugins/hotkey_manager', );