Giter Club home page Giter Club logo

hotkey_manager's Introduction

hotkey_manager

pub version

This plugin allows Flutter desktop apps to defines system/inapp wide hotkey (i.e. shortcut).


English | 简体中文


Platform Support

Linux macOS Windows
✔️ ✔️ ✔️

Quick Start

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  hotkey_manager: ^0.2.3

Or

dependencies:
  hotkey_manager:
    git:
      path: packages/hotkey_manager
      url: https://github.com/leanflutter/hotkey_manager.git
      ref: main

Linux requirements

Run the following command

sudo apt-get install keybinder-3.0

Usage

import 'package:hotkey_manager/hotkey_manager.dart';

void main() async {
  // Must add this line.
  WidgetsFlutterBinding.ensureInitialized();
  // For hot reload, `unregisterAll()` needs to be called.
  await hotKeyManager.unregisterAll();

  runApp(MyApp());
}

Register/Unregsiter a system/inapp wide hotkey.

// ⌥ + Q
HotKey _hotKey = HotKey(
  key: PhysicalKeyboardKey.keyQ,
  modifiers: [HotKeyModifier.alt],
  // Set hotkey scope (default is HotKeyScope.system)
  scope: HotKeyScope.inapp, // Set as inapp-wide hotkey.
);
await hotKeyManager.register(
  _hotKey,
  keyDownHandler: (hotKey) {
    print('onKeyDown+${hotKey.toJson()}');
  },
  // Only works on macOS.
  keyUpHandler: (hotKey){
    print('onKeyUp+${hotKey.toJson()}');
  } ,
);

await hotKeyManager.unregister(_hotKey);

await hotKeyManager.unregisterAll();

Use HotKeyRecorder widget to help you record a hotkey.

HotKeyRecorder(
  onHotKeyRecorded: (hotKey) {
    _hotKey = hotKey;
    setState(() {});
  },
),

Please see the example app of this plugin for a full example.

Who's using it?

  • Airclap - Send any file to any device. cross platform, ultra fast and easy to use.
  • AuthPass - Password Manager based on Flutter for all platforms. Keepass 2.x (kdbx 3.x) compatible.
  • Biyi (比译) - A convenient translation and dictionary app.

API

HotKeyManager

Method Description Linux macOS Windows
register register an system/inapp wide hotkey. ✔️ ✔️ ✔️
unregister unregister an system/inapp wide hotkey. ✔️ ✔️ ✔️
unregisterAll unregister all system/inapp wide hotkeys. ✔️ ✔️ ✔️

Related Links

License

MIT

hotkey_manager's People

Contributors

aexei avatar alexmercerind avatar hpoul avatar liangludev avatar lijy91 avatar merrit avatar qwertyyb avatar snowcrash5 avatar zhengbomo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hotkey_manager's Issues

[Bug] HotKeyRecorder is not working with specific hotkeys

Specifically, any key combinations of shift+(any key) and shift+alt+(any key) is not working and onHotKeyRecorded is never triggered with those key combinations. Haven't tested with other platforms but I'm currently having this problem on windows 11.

[BUG] 在 inApp 级别的快捷键回调中执行 windowManager.hide(),然后再 windowManager.show 发现 inApp 级别的快捷键都失效了。

macOS

我注册了一个 inApp 级别的快捷键,在其回调函数中执行了 windowManager.hide() 。
同时我还注册一个 system 级别的快捷键,通过回调控制 windowManager 的 hide 和 show 。

通过 inApp 级别的快捷键,hide 软件之后再次 show ,发现其他 inApp 快捷键都失效或者不正常工作了。

我在回调里,通过 Future.delayed 执行 hide 就不会出现这种情况。

 Future.delayed(const Duration(milliseconds: 200), () {
    windowManager.hide();
  });

Overriding platform-wide shortcuts?

Tried the example app, and I wasn't able to register a new shortcut for already defined macOS-level shortcuts, for example Command + Q (which quits the app) or Command + Space (brings up Spotlight search).

Is there any way to be able to override such keyboard combos? I am sure this is possible on other desktop apps, e.g. I can do it for iTerm or Android Studio through their keyboard preferences, so I am looking to also have that feature in my Flutter app.

无法注册系统级别热键

比如下面这些热键,注册后无法监听到热键,并且系统热键还是生效的

// macOS
HotKey(KeyCode.space, modifiers: [KeyModifier.meta], scope: HotKeyScope.system);
HotKey(KeyCode.space, modifiers: [KeyModifier.meta, KeyModifier.alt], scope: HotKeyScope.system);

// Windows
HotKey(KeyCode.tab, modifiers: [KeyModifier.meta], scope: HotKeyScope.system);
HotKey(KeyCode.tab, modifiers: [KeyModifier.alt], scope: HotKeyScope.system);
HotKey(KeyCode.f4, modifiers: [KeyModifier.alt], scope: HotKeyScope.system);

KeyCode.backquote注册时空指针异常

环境:macos flutter sdk 3.0.1 hotkey_manager: ^0.1.7

HotKey(
KeyCode.backquote,
modifiers: [KeyModifier.control],
scope: HotKeyScope.system,
)
KeyCode.backquote报错,使用KeyCode.keyQ就不会
hotkey_manager/HotkeyManagerPlugin.swift:42: Fatal error: Unexpectedly found nil while unwrapping an Optional value

web suppport

does this web support web? and can it support it?

Fails to register Pause key

Try to bind the Pause / Break key: Shows in GUI, appears to work.. hotkey never triggers.

I loaded the project in the debugger, I am thinking the issue may be the keystring.

In debugger it looks like it doesn't return a usable value: 0x1e75e50 ""

Build failure on Linux

Hey, interested to try this out!

For me it fails to build on a new flutter project as soon as the dependency is added:

Details

❯ flutter run -d linux -v
[  +43 ms] executing: uname -m
[  +21 ms] Exit code 0 from: uname -m
[        ] x86_64
[   +3 ms] executing: [/home/merritt/Applications/tools/flutter/] git -c log.showSignature=false log -n 1 --pretty=format:%H
[   +5 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
[        ] 19c61fed0da681ba2068c97e22add3bde38e51e4
[        ] executing: [/home/merritt/Applications/tools/flutter/] git tag --points-at 19c61fed0da681ba2068c97e22add3bde38e51e4
[   +9 ms] Exit code 0 from: git tag --points-at 19c61fed0da681ba2068c97e22add3bde38e51e4
[        ] 2.5.0-5.2.pre
[   +6 ms] executing: [/home/merritt/Applications/tools/flutter/] git rev-parse --abbrev-ref --symbolic @{u}
[   +4 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{u}
[        ] origin/beta
[        ] executing: [/home/merritt/Applications/tools/flutter/] git ls-remote --get-url origin
[   +3 ms] Exit code 0 from: git ls-remote --get-url origin
[        ] https://github.com/flutter/flutter.git
[  +55 ms] executing: [/home/merritt/Applications/tools/flutter/] git rev-parse --abbrev-ref HEAD
[   +4 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
[        ] beta
[  +47 ms] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterWebSdk' is not required, skipping update.
[   +2 ms] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'WindowsUwpEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[  +49 ms] Artifact Instance of 'AndroidGenSnapshotArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'AndroidInternalBuildArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'IOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterWebSdk' is not required, skipping update.
[        ] Artifact Instance of 'WindowsEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'WindowsUwpEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSEngineArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'LinuxFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'MacOSFuchsiaSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerSDKArtifacts' is not required, skipping update.
[        ] Artifact Instance of 'FlutterRunnerDebugSymbols' is not required, skipping update.
[  +47 ms] Skipping pub get: version match.
[  +14 ms] Found plugin hotkey_manager at /home/merritt/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.6/
[  +71 ms] Found plugin hotkey_manager at /home/merritt/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.6/
[  +14 ms] Generating /home/merritt/Downloads/flutter_hotkey_demo/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
[  +71 ms] Initializing file store
[   +5 ms] Skipping target: gen_localizations
[   +2 ms] Skipping target: gen_dart_plugin_registrant
[        ] Skipping target: _composite
[   +1 ms] complete
[   +3 ms] Launching lib/main.dart on Linux in debug mode...
[   +3 ms] /home/merritt/Applications/tools/flutter/bin/cache/dart-sdk/bin/dart --disable-dart-dev
/home/merritt/Applications/tools/flutter/bin/cache/artifacts/engine/linux-x64/frontend_server.dart.snapshot --sdk-root
/home/merritt/Applications/tools/flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --incremental --target=flutter --debugger-module-names --experimental-emit-debug-metadata
-DFLUTTER_WEB_AUTO_DETECT=true --output-dill /tmp/flutter_tools.ZEJHLO/flutter_tool.PYCTQJ/app.dill --packages /home/merritt/Downloads/flutter_hotkey_demo/.dart_tool/package_config.json
-Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --filesystem-scheme org-dartlang-root --initialize-from-dill
build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill --enable-experiment=alternative-invalidation-strategy
[  +18 ms] Building Linux application...
[  +14 ms] <- compile package:flutter_hotkey_demo/main.dart
[   +1 ms] executing: [build/linux/x64/debug/] cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DFLUTTER_TARGET_PLATFORM=linux-x64 /home/merritt/Downloads/flutter_hotkey_demo/linux
[  +35 ms] -- Checking for module 'keybinder-3.0'
[        ] --   No package 'keybinder-3.0' found
[        ] -- Configuring incomplete, errors occurred!
[        ] See also "/home/merritt/Downloads/flutter_hotkey_demo/build/linux/x64/debug/CMakeFiles/CMakeOutput.log".
[        ] CMake Error at /usr/share/cmake-3.18/Modules/FindPkgConfig.cmake:545 (message):
[        ]   A required package was not found
[        ] Call Stack (most recent call first):
[        ]   /usr/share/cmake-3.18/Modules/FindPkgConfig.cmake:733 (_pkg_check_modules_internal)
[        ]   flutter/ephemeral/.plugin_symlinks/hotkey_manager/linux/CMakeLists.txt:10 (pkg_check_modules)
[   +8 ms] Building Linux application... (completed in 56ms)
[+5525 ms] Exception: Unable to generate build files
[        ] "flutter run" took 5,920ms.
[   +3 ms] 
           #0      throwToolExit (package:flutter_tools/src/base/common.dart:10:3)
           #1      RunCommand.runCommand (package:flutter_tools/src/commands/run.dart:669:9)
           <asynchronous suspension>
           #2      FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1125:27)
           <asynchronous suspension>
           #3      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
           <asynchronous suspension>
           #4      CommandRunner.runCommand (package:args/command_runner.dart:209:13)
           <asynchronous suspension>
           #5      FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:288:9)
           <asynchronous suspension>
           #6      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
           <asynchronous suspension>
           #7      FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:236:5)
           <asynchronous suspension>
           #8      run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
           <asynchronous suspension>
           #9      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
           <asynchronous suspension>
           #10     main (package:flutter_tools/executable.dart:92:3)
           <asynchronous suspension>
           
           
[  +81 ms] ensureAnalyticsSent: 79ms
[   +1 ms] Running shutdown hooks
[        ] Shutdown hooks complete
[        ] exiting with code 1

❯ flutter --version
Flutter 2.5.0-5.2.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 19c61fed0d (13 days ago) • 2021-08-18 17:10:31 -0700
Engine • revision 7a4c4505f6
Tools • Dart 2.14.0 (build 2.14.0-377.7.beta)

Linux wayland support

Gnome with wayland can’t bind hot key.

WARNING **: 22:21:22.322: Binding '<Alt>s' failed!

[Windows] keyUpHandler is not being invoked

In example project we have 2 handlers:

 void _keyDownHandler(HotKey hotKey) {
   String log = 'keyDown ${describeEnum(hotKey.keyCode)} (${hotKey.scope})';
   BotToast.showText(text: log);
   print(log);
 }

 void _keyUpHandler(HotKey hotKey) {
   String log = 'keyUp   ${describeEnum(hotKey.keyCode)} (${hotKey.scope})';
   print(log);
 }

keyDownHandler is being called properly, but keyUpHandler not. It can be easily observed because _keyUpHandler should print log but it doesn't do that.

Can not response "Ctrl + Shift + Z" if "Ctrl + Z" has been registered first

Please try the code sample appended.
If "Ctrl + Shift + Z" is registerd after "Ctrl + Z", it it does not work

I think this is caused by the HotKeyManager._handleRawKeyEvent method using _hotKeyList.firstWhere to match the hotkey.
Maybe you need sort _hotKeyList after register a new hotkey
or match modifierKey strictly in HotKeyManager._handleRawKeyEvent

Code sample
import 'package:flutter/material.dart';
import 'package:hotkey_manager/hotkey_manager.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  hotKeyManager.unregisterAll();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String lastAcceptedHotkey = '';

  HotKey ctrlZ = HotKey(
    KeyCode.keyZ,
    modifiers: [KeyModifier.control],
    scope: HotKeyScope.inapp,
  );

  HotKey ctrlShiftZ = HotKey(
    KeyCode.keyZ,
    modifiers: [KeyModifier.control, KeyModifier.shift],
    scope: HotKeyScope.inapp,
  );

  void _keyUpHandler(HotKey hotkey) {
    lastAcceptedHotkey = hotkey.toString();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () async {
              await hotKeyManager.unregisterAll();
              hotKeyManager.register(ctrlZ, keyUpHandler: _keyUpHandler);
              hotKeyManager.register(ctrlShiftZ, keyUpHandler: _keyUpHandler);
            },
            child: const Text('Register order: CtrlZ, CtrlShiftZ'),
          ),
          ElevatedButton(
            onPressed: () async {
              await hotKeyManager.unregisterAll();
              hotKeyManager.register(ctrlShiftZ, keyUpHandler: _keyUpHandler);
              hotKeyManager.register(ctrlZ, keyUpHandler: _keyUpHandler);
            },
            child: const Text('Register order: CtrlShiftZ, CtrlZ'),
          ),
          Text('lastAcceptedHotkey: $lastAcceptedHotkey'),
        ],
      ),
    );
  }
}

快捷键影响输入框输入

如果快捷键和输入框出现冲突会出现无法在输入框输入的问题:

比如快捷键设置为空格,那么在所有的TextField中都无法输入空格

先前的版本^0.1.8相反,会出现既能输入又会执行快捷键

现在可行的办法是使用^0.1.8版本,根据焦点判定是否执行快捷键方法:

await hotKeyManager.register(
  toggle,
  keyDownHandler: (hotKey) {
    if(!textController.hasFocus){
      // 执行快捷键指令
    }
  },
);

希望可以在输入的时候判断是否触发快捷键,或者添加回掉函数判断是否要执行快捷键绑定的操作

background mode issue

Is the current solution working for recognizing the Enter key in the background mode? Can I configure it to handle any key, such as A-Z or any other key? in only background mode

compilation error on Flutter 2.5.0-5.2.pre

flutter --version
Flutter 2.5.0-5.2.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 19c61fed0d (10 days ago) • 2021-08-18 17:10:31 -0700
Engine • revision 7a4c4505f6
Tools • Dart 2.14.0 (build 2.14.0-377.7.beta)

The results of flutter run -v

[  +14 ms]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:6:36:
Error: Getter not found: 'none'.
[        ]   KeyCode.none: LogicalKeyboardKey.none,
[        ]                                    ^^^^
[   +7 ms]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:12:37:
Error: Getter not found: 'turbo'.
[        ]   KeyCode.turbo: LogicalKeyboardKey.turbo,
[        ]                                     ^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:13:51:
Error: Getter not found: 'privacyScreenToggle'.
[        ]   KeyCode.privacyScreenToggle: LogicalKeyboardKey.privacyScreenToggle,
[        ]                                                   ^^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:16:51:
Error: Getter not found: 'displayToggleIntExt'.
[        ]   KeyCode.displayToggleIntExt: LogicalKeyboardKey.displayToggleIntExt,
[        ]                                                   ^^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:17:43:
Error: Getter not found: 'usbReserved'.
[        ]   KeyCode.usbReserved: LogicalKeyboardKey.usbReserved,
[        ]                                           ^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:18:48:
Error: Getter not found: 'usbErrorRollOver'.
[        ]   KeyCode.usbErrorRollOver: LogicalKeyboardKey.usbErrorRollOver,
[        ]                                                ^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:19:43:
Error: Getter not found: 'usbPostFail'.
[        ]   KeyCode.usbPostFail: LogicalKeyboardKey.usbPostFail,
[        ]                                           ^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:20:49:
Error: Getter not found: 'usbErrorUndefined'.
[        ]   KeyCode.usbErrorUndefined: LogicalKeyboardKey.usbErrorUndefined,
[        ]                                                 ^^^^^^^^^^^^^^^^^
[   +1 ms]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:159:47:
Error: Getter not found: 'numpadBackspace'.
[        ]   KeyCode.numpadBackspace: LogicalKeyboardKey.numpadBackspace,
[        ]                                               ^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:160:49:
Error: Getter not found: 'numpadMemoryStore'.
[        ]   KeyCode.numpadMemoryStore: LogicalKeyboardKey.numpadMemoryStore,
[        ]                                                 ^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:161:50:
Error: Getter not found: 'numpadMemoryRecall'.
[        ]   KeyCode.numpadMemoryRecall: LogicalKeyboardKey.numpadMemoryRecall,
[        ]                                                  ^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:162:49:
Error: Getter not found: 'numpadMemoryClear'.
[        ]   KeyCode.numpadMemoryClear: LogicalKeyboardKey.numpadMemoryClear,
[        ]                                                 ^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:163:47:
Error: Getter not found: 'numpadMemoryAdd'.
[        ]   KeyCode.numpadMemoryAdd: LogicalKeyboardKey.numpadMemoryAdd,
[        ]                                               ^^^^^^^^^^^^^^^
[   +1 ms]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:164:52:
Error: Getter not found: 'numpadMemorySubtract'.
[        ]   KeyCode.numpadMemorySubtract: LogicalKeyboardKey.numpadMemorySubtract,
[        ]                                                    ^^^^^^^^^^^^^^^^^^^^
[   +1 ms]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:165:48:
Error: Getter not found: 'numpadSignChange'.
[        ]   KeyCode.numpadSignChange: LogicalKeyboardKey.numpadSignChange,
[        ]                                                ^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:166:43:
Error: Getter not found: 'numpadClear'.
[        ]   KeyCode.numpadClear: LogicalKeyboardKey.numpadClear,
[        ]                                           ^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:167:48:
Error: Getter not found: 'numpadClearEntry'.
[        ]   KeyCode.numpadClearEntry: LogicalKeyboardKey.numpadClearEntry,
[        ]                                                ^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:180:48:
Error: Getter not found: 'brightnessToggle'.
[        ]   KeyCode.brightnessToggle: LogicalKeyboardKey.brightnessToggle,
[        ]                                                ^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:181:49:
Error: Getter not found: 'brightnessMinimum'.
[        ]   KeyCode.brightnessMinimum: LogicalKeyboardKey.brightnessMinimum,
[        ]                                                 ^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:182:49:
Error: Getter not found: 'brightnessMaximum'.
[        ]   KeyCode.brightnessMaximum: LogicalKeyboardKey.brightnessMaximum,
[        ]                                                 ^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:183:46:
Error: Getter not found: 'brightnessAuto'.
[        ]   KeyCode.brightnessAuto: LogicalKeyboardKey.brightnessAuto,
[        ]                                              ^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:184:42:
Error: Getter not found: 'kbdIllumUp'.
[        ]   KeyCode.kbdIllumUp: LogicalKeyboardKey.kbdIllumUp,
[        ]                                          ^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:185:44:
Error: Getter not found: 'kbdIllumDown'.
[        ]   KeyCode.kbdIllumDown: LogicalKeyboardKey.kbdIllumDown,
[        ]                                            ^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:188:44:
Error: Getter not found: 'programGuide'.
[        ]   KeyCode.programGuide: LogicalKeyboardKey.programGuide,
[        ]                                            ^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:203:41:
Error: Getter not found: 'bassBoost'.
[        ]   KeyCode.bassBoost: LogicalKeyboardKey.bassBoost,
[        ]                                         ^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:204:43:
Error: Getter not found: 'mediaSelect'.
[        ]   KeyCode.mediaSelect: LogicalKeyboardKey.mediaSelect,
[        ]                                           ^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:210:42:
Error: Getter not found: 'launchApp2'.
[        ]   KeyCode.launchApp2: LogicalKeyboardKey.launchApp2,
[        ]                                          ^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:211:42:
Error: Getter not found: 'launchApp1'.
[        ]   KeyCode.launchApp1: LogicalKeyboardKey.launchApp1,
[        ]                                          ^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:212:53:
Error: Getter not found: 'launchInternetBrowser'.
[        ]   KeyCode.launchInternetBrowser: LogicalKeyboardKey.launchInternetBrowser,
[        ]                                                     ^^^^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:214:42:
Error: Getter not found: 'lockScreen'.
[        ]   KeyCode.lockScreen: LogicalKeyboardKey.lockScreen,
[        ]                                          ^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:216:42:
Error: Getter not found: 'selectTask'.
[        ]   KeyCode.selectTask: LogicalKeyboardKey.selectTask,
[        ]                                          ^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:217:47:
Error: Getter not found: 'launchDocuments'.
[        ]   KeyCode.launchDocuments: LogicalKeyboardKey.launchDocuments,
[        ]                                               ^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:219:52:
Error: Getter not found: 'launchKeyboardLayout'.
[        ]   KeyCode.launchKeyboardLayout: LogicalKeyboardKey.launchKeyboardLayout,
[        ]                                                    ^^^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:222:50:
Error: Getter not found: 'launchAudioBrowser'.
[        ]   KeyCode.launchAudioBrowser: LogicalKeyboardKey.launchAudioBrowser,
[        ]                                                  ^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:241:52:
Error: Getter not found: 'keyboardLayoutSelect'.
[        ]   KeyCode.keyboardLayoutSelect: LogicalKeyboardKey.keyboardLayoutSelect,
[        ]                                                    ^^^^^^^^^^^^^^^^^^^^
[        ]
../../../../../Development/flutter/.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.0.3/lib/src/enums/key_code.dart:242:46:
Error: Getter not found: 'showAllWindows'.
[        ]   KeyCode.showAllWindows: LogicalKeyboardKey.showAllWindows,
[        ]                                              ^^^^^^^^^^^^^^
[+1601 ms] note: Build preparation complete

Migrate to new HardwareKeyboard class

hotkey_manger now use the depreacted RawKeyboard class, the new class is HardwareKeyboard page.

And I found some bugs about RawKeyboard that official has said below:

Compared to RawKeyboard
RawKeyboard is the legacy API, and will be deprecated and removed in the future. It is recommended to always use HardwareKeyboard and KeyEvent APIs (such as FocusNode.onKeyEvent) to handle key events.

Behavior-wise, RawKeyboard provides a less unified, less regular event model than HardwareKeyboard. For example:

  • Down events might not be matched with an up event, and vice versa (the set of pressed keys is silently updated).
  • The logical key of the down event might not be the same as that of the up event.
  • Down events and repeat events are not easily distinguishable (must be tracked manually).
  • Lock modes (such as CapsLock) only have their "enabled" state recorded. There's no way to acquire their pressing state.

Has a bug User macOS

import 'package:flutter/material.dart';
import 'package:hotkey_manager/hotkey_manager.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await hotKeyManager.unregisterAll();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();

    registerHotkey();
  }

  void registerHotkey() async {
    HotKey hotKey = HotKey(
      KeyCode.keyG,
      modifiers: [
        KeyModifier.meta,
      ],
      scope: HotKeyScope.inapp,
    );
    await hotKeyManager.register(
      hotKey,
      keyDownHandler: (hotKey) {
        print('onKeyDown+${hotKey.toJson()}');
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: const Color(0xFFDBDDE0).withOpacity(0.21),
        alignment: Alignment.center,
        child: const TextField(
          decoration: InputDecoration(hintText: 'search'),
        ),
      ),
    );
  }
}

Has no effect on only one key "control"

I want to listen the control key on keyboad with mouse left click to select multiply widget on Windows or Linux desktop platform.
But it is has no effect when i listen control key.

// register control hostkey
hotKeyManager.register(HotKey(KeyCode.control), keyUpHandler: _hotkeyUpHandler);

启动报错

/Users/XXX/macos/Pods/HotKey/Sources/HotKey/KeyCombo.swift:26:22: warning: setter argument 'newValue' was never used, but the property was accessed
                        carbonModifiers = modifiers.carbonFlags
                                          ^
                        carbonModifiers = modifiers.carbonFlags
                                          ^~~~~~~~~
                                          newValue
/Users/XXX/macos/Pods/Pods.xcodeproj: warning: The macOS deployment target 'MACOSX_DEPLOYMENT_TARGET' is set to 10.9, but the range of supported deployment target versions is 10.13 to 13.1.99. (in target 'HotKey' from project 'Pods')

这个报错要怎么搞?

请问如何拦截系统快捷键默认行为

比如 macOS 系统,焦点在 TextField 上按下 alt + 1 - 9 的数字时,会输入 ¡ ™ £ ¢ ∞ § ¶ • ª 等符号,我不希望输入这些符号。因为我会监听这个快捷键,自己输入一些特定内容。

注册应用内热键(alt+s)后,触发一次后按住(alt)会一直触发

问题

注册应用内热键(alt+s)后,触发一次后按住(alt)会一直触发

环境

[√] Flutter (Channel stable, 2.10.2, on Microsoft Windows [Version 10.0.18363.1556], locale zh-CN)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.9.2)
[√] Android Studio (version 2021.1)
[√] IntelliJ IDEA Ultimate Edition (version 2020.3)
[√] IntelliJ IDEA Ultimate Edition (version 2021.2)

代码

本库示例代码

HotKeyScope.system doesn't work on linux

final HotKey hotKey = HotKey(
KeyCode.keyE,
modifiers: [KeyModifier.control, KeyModifier.shift],
scope: HotKeyScope.system,
identifier: 'cunt',
);

doesn't work. I have keybinder-3.0 installed. I'm on the latest debian.

Phantom key presses

Hello,
First of all - thank you for your package. It saved me a ton of time.
I'm on macOS v13.0.1, M1 macbook. Everything written below is related to inapp hotkeys.

I added a log to hotkey_manager.dart file, _handleRawKeyEvent method to track everything that happens in the package.

    print(
        'RawKeyEvent: lastPressedKey: $_lastPressedHotKey, identifier: ${_lastPressedHotKey?.identifier} $value, ${value.character}, ${value.logicalKey}');

On any keypress i receive 2 additional events:

KeyDown: RawKeyEvent: lastPressedKey: null, identifier: null RawKeyDownEvent#c6e77(logicalKey: LogicalKeyboardKey#d0ba2(keyId: "0x200000100", keyLabel: "Control Left", debugName: "Control Left"), physicalKey: PhysicalKeyboardKey#ea6e1(usbHidUsage: "0x000700e0", debugName: "Control Left"), repeat: false), null, LogicalKeyboardKey#d0ba2(keyId: "0x200000100", keyLabel: "Control Left", debugName: "Control Left")

KeyDown: flutter: RawKeyEvent: lastPressedKey: null, identifier: null RawKeyUpEvent#7fb91(logicalKey: LogicalKeyboardKey#df100(keyId: "0x200000102", keyLabel: "Shift Left", debugName: "Shift Left"), physicalKey: PhysicalKeyboardKey#ed430(usbHidUsage: "0x000700e1", debugName: "Shift Left")), null, LogicalKeyboardKey#df100(keyId: "0x200000102", keyLabel: "Shift Left", debugName: "Shift Left")

KeyUp for them is never registered.
It doesn't bother me, just noticed. The actual problem is below:

If you register any key to hide the app on keyDown, then keyUp event is never triggered for that key. Therefore method 'handleRawKeyEvent' inside raw_keyboard.dart never removes that key from _keysPressed. As the result
HotKey? hotKey = _hotKeyList.firstWhereOrNull( inside hotkey_manager.dart
triggers the following code inside 'raw_keyboard.dart' class
bool isKeyPressed(LogicalKeyboardKey key) => RawKeyboard.instance.keysPressed.contains(key);
returns true for an event it shouldn't be triggering (because firstWhereOrNull iterates over all registered hotkeys)

I made a workaround by hiding the window on keyUp event, however the problematic code is still inside.

ALT+F4

Is it possible to override system hotkeys like ALT+F4 to stop it from closing the app?

backquote在windows上注册不能触发

环境:windows
HotKey _hotKey = HotKey(
KeyCode.backquote,
modifiers: [KeyModifier.control],
// 设置热键范围(默认为 HotKeyScope.system)
scope: HotKeyScope.system, // 设置为应用范围的热键。
);

dependencies:
hotkey_manager: ^0.1.7

control+backquote不能触发,keycode换成其他的就没问题,比如换成keyQ
多台电脑测试过,均是如此。

Register Alt+Q, and just pressing the Q key will also perform the keyDownHandler callback

HotKey _hotKey = HotKey(
      key: PhysicalKeyboardKey.keyQ,
      modifiers: [HotKeyModifier.alt],
      // Set hotkey scope (default is HotKeyScope.system)
      scope: HotKeyScope.inapp, // Set as inapp-wide hotkey.
    );
await hotKeyManager.register(
      _hotKey,
      keyDownHandler: (hotKey) {
        print('onKeyDown+${hotKey.toJson()}');
      },
      // Only works on macOS.
      keyUpHandler: (hotKey) {
        print('onKeyUp+${hotKey.toJson()}');
      },
    );

Register only Alt+Q or Alt+Q and Q, press Q, and only perform the keyDownHandler callback of Alt+Q, need help to check,thanks.

Not able to compile on Linux

Hi,
I tried version 0.1.7 on MacOS: it works :)
I tried the same code on Linux (Ubuntu), I can't compile and get the following error:

ERROR: ../../.pub-cache/hosted/pub.dartlang.org/hotkey_manager-0.1.7/lib/src/hotkey_manager.dart:42:17: Error: The getter 'repeat' isn't defined for the class 'RawKeyDownEvent'.
ERROR:  - 'RawKeyDownEvent' is from 'package:flutter/src/services/raw_keyboard.dart' ('../flutter/packages/flutter/lib/src/services/raw_keyboard.dart').
ERROR: Try correcting the name to the name of an existing getter, or defining a getter or field named 'repeat'.
ERROR:       if (value.repeat) return;

For info, I installed keybinder-3.0 and libkeybinder-3.0-dev.

[✓] Flutter (Channel stable, 2.8.1, on Ubuntu 20.04.4 LTS 5.13.0-40-generic, locale en_US.UTF-8)
    • Flutter version 2.8.1 at /home/fab/Git/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 77d935af4d (5 months ago), 2021-12-16 08:37:33 -0800
    • Engine revision 890a5fca2e
    • Dart version 2.15.1

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /home/fab/Android/Sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: /snap/android-studio/119/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
    • All Android licenses accepted.

[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Linux toolchain - develop for Linux desktop
    • clang version 10.0.0-4ubuntu1
    • cmake version 3.16.3
    • ninja version 1.10.0
    • pkg-config version 0.29.1

[✓] Android Studio (version 2021.1)
    • Android Studio at /snap/android-studio/119/android-studio
    • Flutter plugin version 67.1.1
    • Dart plugin version 211.7817
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] Connected device (1 available)
    • Linux (desktop) • linux • linux-x64 • Ubuntu 20.04.4 LTS 5.13.0-40-generic

I registered the shift key using hotkey manager, but it does not work.

I registered the shift key using hotkey manager, but it does not work.

if (hotKey.keyCode == KeyCode.shift) {
await hotKeyManager.register(
hotKey,
keyDownHandler: keyDownHandler,
keyUpHandler: keyUpHandler,
);
}

handleHotKeyRegister(HotKey(
  KeyCode.shift,
  scope: HotKeyScope.inapp,
));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.