leanflutter/hotkey_manager

Build failure on Linux

Merrit opened this issue · 8 comments

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)

On linux platform it depends on keybinder-3.0, You need to install it.

sudo apt-get install keybinder-3.0

Thanks! On Ubuntu-based distros this is:

sudo apt install libkeybinder-3.0-dev

Now it compiles correctly. 👍

On run however it throws an exception at instance.register():

  final _hotkey = HotKey(
    KeyCode.f6,
    modifiers: [KeyModifier.control, KeyModifier.shift],
  );

  await HotKeyManager.instance.register(
    _hotkey,
    keyDownHandler: (hotKey) {
      print('keyDown');
    },
    keyUpHandler: (hotKey) {
      print('keyUp');
    },
  );

_CastError (Null check operator used on a null value)

#0 MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:121:86)
#1 MethodChannel.setMethodCallHandler (package:flutter/src/services/platform_channel.dart:375:5)
#2 HotKeyManager._init (package:hotkey_manager/src/hotkey_manager.dart:28:14)
#3 HotKeyManager.register (package:hotkey_manager/src/hotkey_manager.dart:85:24)
#4 main (package:flutter_hotkey_demo/main.dart:12:32)
#5 _runMainZoned.. (dart:ui/hooks.dart:145:25)
#6 _rootRun (dart:async/zone.dart:1428:13)
#7 _CustomZone.run (dart:async/zone.dart:1328:19)
#8 _runZoned (dart:async/zone.dart:1863:10)
#9 runZonedGuarded (dart:async/zone.dart:1851:12)
#10 _runMainZoned. (dart:ui/hooks.dart:141:5)
#11 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:283:19)
#12 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Can you provide the code for flutter_hotkey_demo

Please don't use it in main function.

Alright, tried moving it out of main and it works some of the time. (Where do you recommend to initialize?)

"some of the time" because when it doesn't work; after hot reload I have seen it:

  1. Fire the call back 3 times per press of the hotkey
  2. Trigger an exception:

"No element"

Stacktrace:

#0 ListMixin.firstWhere (dart:collection/list.dart:167:5)
#1 HotKeyManager._methodCallHandler (package:hotkey_manager/src/hotkey_manager.dart:62:33)
#2 MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:386:55)
#3 MethodChannel.setMethodCallHandler. (package:flutter/src/services/platform_channel.dart:379:34)
#4 _DefaultBinaryMessenger.setMessageHandler. (package:flutter/src/services/binding.dart:379:35)
#5 _DefaultBinaryMessenger.setMessageHandler. (package:flutter/src/services/binding.dart:376:46)
#6 _invoke2. (dart:ui/hooks.dart:205:15)
#7 _rootRun (dart:async/zone.dart:1428:13)
#8 _CustomZone.run (dart:async/zone.dart:1328:19)
#9 _CustomZone.runGuarded (dart:async/zone.dart:1236:7)
#10 _invoke2 (dart:ui/hooks.dart:204:10)
#11 _ChannelCallbackRecord.invoke (dart:ui/channel_buffers.dart:42:5)
#12 _Channel.push (dart:ui/channel_buffers.dart:132:31)
#13 ChannelBuffers.push (dart:ui/channel_buffers.dart:329:17)
#14 PlatformDispatcher._dispatchPlatformMessage (dart:ui/platform_dispatcher.dart:544:22)
#15 _dispatchPlatformMessage (dart:ui/hooks.dart:92:31)

Code is just from a new flutter project:

import 'dart:developer';

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

Future<void> main() async {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: const HomePage(),
    );
  }
}

Future<void> startHotkey() async {
  final _hotkey = HotKey(
    KeyCode.f6,
    modifiers: [KeyModifier.control, KeyModifier.shift],
  );

  await HotKeyManager.instance.register(
    _hotkey,
    keyDownHandler: (hotKey) => log('keyDown'),
    keyUpHandler: (hotKey) => log('keyUp'),
  );
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    startHotkey();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Hotkey test'),
      ),
    );
  }
}

By the way, is there a specific reason this requires Flutter, and doesn't support a dart application? I could see it being very useful for that use case as well.

  1. I reconfirmed that it works on main, but I need to add WidgetsFlutterBinding.ensureInitialized()
  2. For hot reload, HotKeyManager.instance.unregisterAll() needs to be called;
  3. No element error is fixed on macOS platform , Windows and Linux platform will fixed later.
void main() {
+  WidgetsFlutterBinding.ensureInitialized();

  final _hotkey = HotKey(
    KeyCode.keyF,
    modifiers: [KeyModifier.alt],
  );

+  HotKeyManager.instance.unregisterAll();
  HotKeyManager.instance.register(
    _hotkey,
    keyDownHandler: (hotKey) => print('keyDown'),
    keyUpHandler: (hotKey) => print('keyUp'),
  );

  runApp(MyApp());
}

Please upgrade to 0.1.0

dependencies:
  hotkey_manager: ^0.1.0

New version seems to be working good in my brief testing. Thanks!

Love that you've made it feel simple and seamless, great work ❤️