diff --git a/.vscode/settings.json b/.vscode/settings.json index 55443a1..b24ad62 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ "Cntrl", "dylib", "ffigen", + "Henkan", "hotplug", "intf", "libblkid", @@ -31,7 +32,8 @@ "Uhid", "upgrader", "Xinerama", - "xtest" + "xtest", + "Zenkaku" ], "search.exclude": { "**/lib/generated/": true, diff --git a/lib/app/client/client_screen.dart b/lib/app/client/client_screen.dart index 70f3171..f1e0d4a 100644 --- a/lib/app/client/client_screen.dart +++ b/lib/app/client/client_screen.dart @@ -71,6 +71,19 @@ class ClientScreen extends ScreenInterface { onMouseMove?.call(x, y); } + @override + void mouseRelativeMove(int x, int y) { + var reportData = Uint8List(5); + reportData[0] = 0x02; // Report ID + reportData[1] = buttonPressed ?? 0; // Button state + reportData[2] = x; // X movement + reportData[3] = y; // Y movement + reportData[4] = 0; // Wheel movement + _addInputReport(reportData); + relativeX = x; + relativeY = y; + } + @override void mouseWheel(int x, int y) { int wheel = x != 0 ? x : y; diff --git a/lib/app/data/dialog_handler.dart b/lib/app/data/dialog_handler.dart index 3f32067..ecd90fb 100644 --- a/lib/app/data/dialog_handler.dart +++ b/lib/app/data/dialog_handler.dart @@ -45,6 +45,26 @@ class DialogHandler { ); } + static void showSnackbar(String message) { + BuildContext? context = AppService.to.overlayContext; + if (context == null) { + logError("Navigator context is null: $message"); + return; + } + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + message, + style: const TextStyle(color: Colors.white), + ), + closeIconColor: Colors.white, + backgroundColor: Colors.orange, + duration: const Duration(seconds: 2), + showCloseIcon: true, + ), + ); + } + static void showInfoDialog({ required BuildContext context, required String title, diff --git a/lib/app/data/info_data.dart b/lib/app/data/info_data.dart index 9f5cfe0..8304393 100644 --- a/lib/app/data/info_data.dart +++ b/lib/app/data/info_data.dart @@ -63,3 +63,9 @@ This mode requires ADB, and can also work over wireless ADB Note: Both devices must be under same network '''; + +String get lockMouseTileInfo => ''' +Assign a hotkey to confine the mouse cursor within the bounds of a specific device. +Once locked, the mouse will only move relative to that device's screen. +Pressing the hotkey again will release the lock, allowing the mouse to move freely between devices. +'''; diff --git a/lib/app/models/screen_options.dart b/lib/app/models/screen_options.dart index 838e2f1..6dff747 100644 --- a/lib/app/models/screen_options.dart +++ b/lib/app/models/screen_options.dart @@ -3,9 +3,11 @@ class ScreenOptions { bool? win32KeepForeground; bool? clipboardSharing; int? switchCornerSize; + String? toggleKeyStroke; ScreenOptions({ this.relativeMouseMoves = false, + this.toggleKeyStroke, this.win32KeepForeground, this.clipboardSharing, this.switchCornerSize, @@ -18,6 +20,8 @@ class ScreenOptions { 'win32KeepForeground': win32KeepForeground, if (clipboardSharing != null) 'clipboardSharing': clipboardSharing, if (switchCornerSize != null) 'switchCornerSize': switchCornerSize, + if (toggleKeyStroke != null) + 'keystroke($toggleKeyStroke)': '; lockCursorToScreen(toggle)' }; } } diff --git a/lib/app/modules/dashboard/dashboard_view.dart b/lib/app/modules/dashboard/dashboard_view.dart index 41cde86..b4613fd 100644 --- a/lib/app/modules/dashboard/dashboard_view.dart +++ b/lib/app/modules/dashboard/dashboard_view.dart @@ -113,6 +113,7 @@ class _DashboardViewState extends State with WindowListener { SizedBox( width: min(450, MediaQuery.sizeOf(context).width), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 20), Watch((_) => _appService.userInternalServer.value @@ -123,6 +124,7 @@ class _DashboardViewState extends State with WindowListener { : const SizedBox.shrink()), const SizedBox(height: 20), const _ClientTitleWidget(), + const _CursorLockedWidget(), const SizedBox(height: 10), const _ClientsListWidget(), ], @@ -136,6 +138,31 @@ class _DashboardViewState extends State with WindowListener { } } +class _CursorLockedWidget extends StatelessWidget { + const _CursorLockedWidget(); + + @override + Widget build(BuildContext context) { + final SynergyService synergyService = SynergyService.to; + return Watch((_) => synergyService.cursorLocked.value + ? Row( + children: [ + const SizedBox(width: 10), + Text( + 'Cursor locked to current Screen', + style: Theme.of(context).textTheme.bodySmall, + ), + const SizedBox(width: 10), + const Icon( + Icons.lock, + size: 14, + ), + ], + ) + : const SizedBox.shrink()); + } +} + class _ClientsListWidget extends StatelessWidget { const _ClientsListWidget(); @@ -205,7 +232,7 @@ class _ClientTitleWidget extends StatelessWidget { Icons.info_outline, size: 18, ), - ) + ), ], ), Row( diff --git a/lib/app/modules/setting/choose_hotkey.dart b/lib/app/modules/setting/choose_hotkey.dart new file mode 100644 index 0000000..2606d24 --- /dev/null +++ b/lib/app/modules/setting/choose_hotkey.dart @@ -0,0 +1,148 @@ +import 'package:flutter/material.dart'; +import 'package:uni_control_hub/app/synergy/synergy_key_types.dart'; + +class ChooseHotkey extends StatefulWidget { + const ChooseHotkey({super.key}); + + @override + State createState() => _ChooseHotkeyState(); +} + +class _ChooseHotkeyState extends State { + String? selectedKey; + String? selectedModifier; + + String? get result { + if (selectedModifier != null && selectedKey == null) { + return '$selectedModifier+__'; + } else if (selectedKey != null && selectedModifier == null) { + return selectedKey; + } else if (selectedKey == null && selectedModifier == null) { + return null; + } else { + return '$selectedModifier+$selectedKey'; + } + } + + void returnResult() { + String? finalResult; + // only use result if Key is not empty + if (selectedKey != null) { + finalResult = result; + } + Navigator.pop(context, finalResult); + } + + FocusNode focusNode = FocusNode(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Choose Hotkey'), + leading: IconButton( + onPressed: returnResult, + icon: const Icon(Icons.arrow_back_ios), + ), + ), + body: Column( + children: [ + const SizedBox(height: 10), + Text('Result: ${result ?? '__'}'), + const SizedBox(height: 10), + const Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Text('Modifier (Optional) '), + Text('Key (Required)'), + ], + ), + const Divider(), + Expanded( + child: Row( + children: [ + Expanded( + child: ListView.builder( + itemCount: synergyKeyModifierList.length, + itemBuilder: (BuildContext context, int index) { + String key = synergyKeyModifierList[index]; + return Card( + color: selectedModifier == key + ? Theme.of(context).colorScheme.primaryContainer + : null, + child: ListTile( + title: Text(key), + onTap: () { + setState(() { + if (key == selectedModifier) { + selectedModifier = null; + } else { + selectedModifier = key; + } + }); + }, + ), + ); + }, + ), + ), + const VerticalDivider(), + Expanded( + child: ListView.builder( + itemCount: synergyKeyList.length, + itemBuilder: (BuildContext context, int index) { + String key = synergyKeyList[index]; + return Card( + color: selectedKey == key + ? Theme.of(context).colorScheme.primaryContainer + : null, + child: ListTile( + title: Text(key), + onTap: () { + setState(() { + if (key == selectedKey) { + selectedKey = null; + } else { + selectedKey = key; + } + }); + }, + ), + ); + }, + ), + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: () { + setState(() { + selectedKey = null; + selectedModifier = null; + }); + returnResult(); + }, + child: const Text('Cancel'), + ), + ), + const SizedBox(width: 10), + Expanded( + child: ElevatedButton( + onPressed: returnResult, + child: const Text('Set'), + ), + ), + ], + ), + ) + ], + ), + ); + } +} diff --git a/lib/app/modules/setting/lock_mouse_tile.dart b/lib/app/modules/setting/lock_mouse_tile.dart new file mode 100644 index 0000000..58378b3 --- /dev/null +++ b/lib/app/modules/setting/lock_mouse_tile.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_settings_ui/flutter_settings_ui.dart'; +import 'package:signals_flutter/signals_flutter.dart'; +import 'package:uni_control_hub/app/data/dialog_handler.dart'; +import 'package:uni_control_hub/app/data/info_data.dart'; +import 'package:uni_control_hub/app/data/logger.dart'; +import 'package:uni_control_hub/app/modules/setting/choose_hotkey.dart'; +import 'package:uni_control_hub/app/services/synergy_service.dart'; + +class LockMouseTile extends StatelessWidget { + const LockMouseTile({super.key}); + + void selectHotkey(BuildContext context, SynergyService synergyService) async { + String? result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ChooseHotkey(), + ), + ); + logInfo('Result $result'); + synergyService.toggleKeyStroke.value = result; + DialogHandler.showSuccess( + "Changes will take effect after you restart the server", + ); + } + + @override + Widget build(BuildContext context) { + final synergyService = SynergyService.to; + + return Watch( + (_) => SettingsTile( + title: Row( + children: [ + const Text('Lock Mouse Hotkey'), + const SizedBox(width: 10), + InkWell( + onTap: () { + DialogHandler.showInfoDialog( + context: context, + title: 'Lock Mouse to Device', + text: lockMouseTileInfo, + ); + }, + child: const Icon(Icons.info_outline, size: 19), + ) + ], + ), + trailing: Text( + synergyService.toggleKeyStroke.value ?? "Select Hotkey", + ), + onPressed: (context) => selectHotkey(context, synergyService), + leading: const Icon(Icons.ads_click), + ), + ); + } +} diff --git a/lib/app/modules/setting/settings_view.dart b/lib/app/modules/setting/settings_view.dart index ce293d8..9d743a6 100644 --- a/lib/app/modules/setting/settings_view.dart +++ b/lib/app/modules/setting/settings_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_settings_ui/flutter_settings_ui.dart'; import 'package:signals_flutter/signals_flutter.dart'; import 'package:uni_control_hub/app/modules/setting/android_connection_mode_tile.dart'; +import 'package:uni_control_hub/app/modules/setting/lock_mouse_tile.dart'; import 'package:uni_control_hub/app/modules/setting/uhid_port_tile.dart'; import 'package:uni_control_hub/app/services/app_service.dart'; import 'package:uni_control_hub/app/data/capabilities.dart'; @@ -46,7 +47,7 @@ class SettingsView extends StatelessWidget { onToggle: (value) { _appService.autoStartServer.value = value; }, - leading: const Icon(Icons.mouse), + leading: const Icon(Icons.dns), )), ), if (Capabilities.supportsBleConnection) @@ -65,6 +66,9 @@ class SettingsView extends StatelessWidget { SettingsSection( title: const Text('Client'), tiles: [ + const CustomSettingsTile( + child: LockMouseTile(), + ), const CustomSettingsTile( child: AndroidConnectionModeTile(), ), diff --git a/lib/app/services/storage_service.dart b/lib/app/services/storage_service.dart index c66184c..8aaed96 100644 --- a/lib/app/services/storage_service.dart +++ b/lib/app/services/storage_service.dart @@ -39,6 +39,11 @@ class StorageService { set testStatus(String? value) => value == null ? _removeDb('testStatus') : _writeDb('testStatus', value); + String? get toggleKeyStroke => _readDb('toggleKeyStroke'); + set toggleKeyStroke(String? value) => value == null + ? _removeDb('toggleKeyStroke') + : _writeDb('toggleKeyStroke', value); + int get uhidPort => _readDb('uhidPort') ?? 9945; set uhidPort(int value) => _writeDb('uhidPort', value); diff --git a/lib/app/services/synergy_service.dart b/lib/app/services/synergy_service.dart index 67ec430..81a326d 100644 --- a/lib/app/services/synergy_service.dart +++ b/lib/app/services/synergy_service.dart @@ -25,6 +25,8 @@ class SynergyService { String serverName = AppData.appName; Signal isSynergyServerRunning = Signal(false); + Signal toggleKeyStroke = Signal(null); + Signal cursorLocked = Signal(false); List clientAliases = [ ClientAlias.left(), @@ -35,6 +37,12 @@ class SynergyService { Future init() async { closeServerIfRunning(); + toggleKeyStroke.value = storageService.toggleKeyStroke; + + effect(() { + String? keyStroke = toggleKeyStroke.value; + storageService.toggleKeyStroke = keyStroke; + }); } Future toggleServer(BuildContext context) async { @@ -77,7 +85,7 @@ class SynergyService { configPath: configPath, screenName: serverName, doNotRestartOnFailure: true, - onLogs: logInfo, + onLogs: onLogs, onErrors: _parseError, onStop: stopServer, ); @@ -90,6 +98,18 @@ class SynergyService { storageService.synergyProcessId = pid; } + void onLogs(String logs) { + logInfo(logs); + String logsLower = logs.toLowerCase(); + if (logsLower.contains('cursor unlocked from current screen')) { + DialogHandler.showSnackbar('Cursor unlocked from current screen'); + cursorLocked.value = false; + } else if (logsLower.contains('cursor locked to current screen')) { + DialogHandler.showSnackbar('Cursor locked to current screen'); + cursorLocked.value = true; + } + } + void _parseError(error) { logError(error); if (error.toString().contains("Address already in use")) { @@ -103,6 +123,7 @@ class SynergyService { SynergyServer.stopServer(); storageService.synergyProcessId = null; isSynergyServerRunning.value = false; + cursorLocked.value = false; logInfo("Server stopped"); } @@ -148,6 +169,8 @@ class SynergyService { ], options: ScreenOptions( clipboardSharing: false, + relativeMouseMoves: toggleKeyStroke.value != null, + toggleKeyStroke: toggleKeyStroke.value, ), ); } diff --git a/lib/app/synergy/synergy_key_types.dart b/lib/app/synergy/synergy_key_types.dart new file mode 100644 index 0000000..526be2a --- /dev/null +++ b/lib/app/synergy/synergy_key_types.dart @@ -0,0 +1,183 @@ +List synergyKeyList = [ + "AltGr", + "Alt_L", + "Alt_R", + "AppMail", + "AppMedia", + "AppUser1", + "AppUser2", + "AudioDown", + "AudioMute", + "AudioNext", + "AudioPlay", + "AudioPrev", + "AudioStop", + "AudioUp", + "BackSpace", + "Begin", + "Break", + "Cancel", + "CapsLock", + "Clear", + "Control_L", + "Control_R", + "Delete", + "Down", + "Eject", + "End", + "Escape", + "Execute", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "F13", + "F14", + "F15", + "F16", + "F17", + "F18", + "F19", + "F20", + "F21", + "F22", + "F23", + "F24", + "F25", + "F26", + "F27", + "F28", + "F29", + "F30", + "F31", + "F32", + "F33", + "F34", + "F35", + "Find", + "Help", + "Henkan", + "Home", + "Hyper_L", + "Hyper_R", + "Insert", + "KP_0", + "KP_1", + "KP_2", + "KP_3", + "KP_4", + "KP_5", + "KP_6", + "KP_7", + "KP_8", + "KP_9", + "KP_Add", + "KP_Begin", + "KP_Decimal", + "KP_Delete", + "KP_Divide", + "KP_Down", + "KP_End", + "KP_Enter", + "KP_Equal", + "KP_F1", + "KP_F2", + "KP_F3", + "KP_F4", + "KP_Home", + "KP_Insert", + "KP_Left", + "KP_Multiply", + "KP_PageDown", + "KP_PageUp", + "KP_Right", + "KP_Separator", + "KP_Space", + "KP_Subtract", + "KP_Tab", + "KP_Up", + "Left", + "LeftTab", + "Linefeed", + "Menu", + "Meta_L", + "Meta_R", + "NumLock", + "PageDown", + "PageUp", + "Pause", + "Print", + "Redo", + "Return", + "Right", + "ScrollLock", + "Select", + "ShiftLock", + "Shift_L", + "Shift_R", + "Sleep", + "Super_L", + "Super_R", + "SysReq", + "Tab", + "Undo", + "Up", + "WWWBack", + "WWWFavorites", + "WWWForward", + "WWWHome", + "WWWRefresh", + "WWWSearch", + "WWWStop", + "Zenkaku", + "Space", + "Exclaim", + "DoubleQuote", + "Number", + "Dollar", + "Percent", + "Ampersand", + "Apostrophe", + "ParenthesisL", + "ParenthesisR", + "Asterisk", + "Plus", + "Comma", + "Minus", + "Period", + "Slash", + "Colon", + "Semicolon", + "Less", + "Equal", + "Greater", + "Question", + "At", + "BracketL", + "Backslash", + "BracketR", + "Circumflex", + "Underscore", + "Grave", + "BraceL", + "Bar", + "BraceR", + "Tilde" +]; + +const List synergyKeyModifierList = [ + "Alt", + "AltGr", + "Control", + "Meta", + "Shift", + "Super", +]; diff --git a/lib/app/synergy/syngery_key_logical.dart b/lib/app/synergy/syngery_key_logical.dart new file mode 100644 index 0000000..880e81c --- /dev/null +++ b/lib/app/synergy/syngery_key_logical.dart @@ -0,0 +1,174 @@ +// import 'package:flutter/services.dart'; + +// const Map keyNameMap = { +// "AltGr": LogicalKeyboardKey.altGraph, +// "Alt_L": LogicalKeyboardKey.altLeft, +// "Alt_R": LogicalKeyboardKey.altRight, +// "AudioDown": LogicalKeyboardKey.audioVolumeDown, +// "AudioMute": LogicalKeyboardKey.audioVolumeMute, +// "AudioNext": LogicalKeyboardKey.mediaTrackNext, +// "AudioPlay": LogicalKeyboardKey.mediaPlayPause, +// "AudioPrev": LogicalKeyboardKey.mediaTrackPrevious, +// "AudioStop": LogicalKeyboardKey.mediaStop, +// "AudioUp": LogicalKeyboardKey.audioVolumeUp, +// "BackSpace": LogicalKeyboardKey.backspace, +// "Cancel": LogicalKeyboardKey.cancel, +// "CapsLock": LogicalKeyboardKey.capsLock, +// "Clear": LogicalKeyboardKey.clear, +// "Control_L": LogicalKeyboardKey.controlLeft, +// "Control_R": LogicalKeyboardKey.controlRight, +// "Delete": LogicalKeyboardKey.delete, +// "Down": LogicalKeyboardKey.arrowDown, +// "Eject": LogicalKeyboardKey.eject, +// "End": LogicalKeyboardKey.end, +// "Escape": LogicalKeyboardKey.escape, +// "Execute": LogicalKeyboardKey.execute, +// "F1": LogicalKeyboardKey.f1, +// "F2": LogicalKeyboardKey.f2, +// "F3": LogicalKeyboardKey.f3, +// "F4": LogicalKeyboardKey.f4, +// "F5": LogicalKeyboardKey.f5, +// "F6": LogicalKeyboardKey.f6, +// "F7": LogicalKeyboardKey.f7, +// "F8": LogicalKeyboardKey.f8, +// "F9": LogicalKeyboardKey.f9, +// "F10": LogicalKeyboardKey.f10, +// "F11": LogicalKeyboardKey.f11, +// "F12": LogicalKeyboardKey.f12, +// "F13": LogicalKeyboardKey.f13, +// "F14": LogicalKeyboardKey.f14, +// "F15": LogicalKeyboardKey.f15, +// "F16": LogicalKeyboardKey.f16, +// "F17": LogicalKeyboardKey.f17, +// "F18": LogicalKeyboardKey.f18, +// "F19": LogicalKeyboardKey.f19, +// "F20": LogicalKeyboardKey.f20, +// "F21": LogicalKeyboardKey.f21, +// "F22": LogicalKeyboardKey.f22, +// "F23": LogicalKeyboardKey.f23, +// "F24": LogicalKeyboardKey.f24, +// "Find": LogicalKeyboardKey.find, +// "Help": LogicalKeyboardKey.help, +// "Henkan": LogicalKeyboardKey.convert, +// "Home": LogicalKeyboardKey.home, +// "Hyper_L": LogicalKeyboardKey.hyper, +// "Hyper_R": LogicalKeyboardKey.hyper, +// "Insert": LogicalKeyboardKey.insert, +// "KP_0": LogicalKeyboardKey.numpad0, +// "KP_1": LogicalKeyboardKey.numpad1, +// "KP_2": LogicalKeyboardKey.numpad2, +// "KP_3": LogicalKeyboardKey.numpad3, +// "KP_4": LogicalKeyboardKey.numpad4, +// "KP_5": LogicalKeyboardKey.numpad5, +// "KP_6": LogicalKeyboardKey.numpad6, +// "KP_7": LogicalKeyboardKey.numpad7, +// "KP_8": LogicalKeyboardKey.numpad8, +// "KP_9": LogicalKeyboardKey.numpad9, +// "KP_Add": LogicalKeyboardKey.numpadAdd, +// "KP_Decimal": LogicalKeyboardKey.numpadDecimal, +// "KP_Divide": LogicalKeyboardKey.numpadDivide, +// "KP_Enter": LogicalKeyboardKey.numpadEnter, +// "KP_Equal": LogicalKeyboardKey.numpadEqual, +// "KP_Multiply": LogicalKeyboardKey.numpadMultiply, +// "KP_Subtract": LogicalKeyboardKey.numpadSubtract, +// "Left": LogicalKeyboardKey.arrowLeft, +// "LeftTab": LogicalKeyboardKey.tab, +// "Menu": LogicalKeyboardKey.contextMenu, +// "Meta_L": LogicalKeyboardKey.metaLeft, +// "Meta_R": LogicalKeyboardKey.metaRight, +// "NumLock": LogicalKeyboardKey.numLock, +// "PageDown": LogicalKeyboardKey.pageDown, +// "PageUp": LogicalKeyboardKey.pageUp, +// "Pause": LogicalKeyboardKey.pause, +// "Print": LogicalKeyboardKey.printScreen, +// "Redo": LogicalKeyboardKey.redo, +// "Return": LogicalKeyboardKey.enter, +// "Right": LogicalKeyboardKey.arrowRight, +// "ScrollLock": LogicalKeyboardKey.scrollLock, +// "Select": LogicalKeyboardKey.select, +// "Shift_L": LogicalKeyboardKey.shiftLeft, +// "Shift_R": LogicalKeyboardKey.shiftRight, +// "Sleep": LogicalKeyboardKey.sleep, +// "Super_L": LogicalKeyboardKey.superKey, +// "Super_R": LogicalKeyboardKey.superKey, +// "Tab": LogicalKeyboardKey.tab, +// "Undo": LogicalKeyboardKey.undo, +// "Up": LogicalKeyboardKey.arrowUp, +// "WWWBack": LogicalKeyboardKey.browserBack, +// "WWWFavorites": LogicalKeyboardKey.browserFavorites, +// "WWWForward": LogicalKeyboardKey.browserForward, +// "WWWHome": LogicalKeyboardKey.browserHome, +// "WWWRefresh": LogicalKeyboardKey.browserRefresh, +// "WWWSearch": LogicalKeyboardKey.browserSearch, +// "WWWStop": LogicalKeyboardKey.browserStop, +// "Zenkaku": LogicalKeyboardKey.zenkakuHankaku, +// "Space": LogicalKeyboardKey.space, +// "Exclaim": LogicalKeyboardKey.exclamation, +// "DoubleQuote": LogicalKeyboardKey.quote, +// "Number": LogicalKeyboardKey.numberSign, +// "Dollar": LogicalKeyboardKey.dollar, +// "Percent": LogicalKeyboardKey.percent, +// "Ampersand": LogicalKeyboardKey.ampersand, +// "ParenthesisL": LogicalKeyboardKey.parenthesisLeft, +// "ParenthesisR": LogicalKeyboardKey.parenthesisRight, +// "Asterisk": LogicalKeyboardKey.asterisk, +// "Plus": LogicalKeyboardKey.add, +// "Comma": LogicalKeyboardKey.comma, +// "Minus": LogicalKeyboardKey.minus, +// "Period": LogicalKeyboardKey.period, +// "Slash": LogicalKeyboardKey.slash, +// "Colon": LogicalKeyboardKey.colon, +// "Semicolon": LogicalKeyboardKey.semicolon, +// "Less": LogicalKeyboardKey.less, +// "Equal": LogicalKeyboardKey.equal, +// "Greater": LogicalKeyboardKey.greater, +// "Question": LogicalKeyboardKey.question, +// "At": LogicalKeyboardKey.at, +// "BracketL": LogicalKeyboardKey.bracketLeft, +// "Backslash": LogicalKeyboardKey.backslash, +// "BracketR": LogicalKeyboardKey.bracketRight, +// "Circumflex": LogicalKeyboardKey.caret, +// "Underscore": LogicalKeyboardKey.underscore, +// "Grave": LogicalKeyboardKey.backquote, +// "BraceL": LogicalKeyboardKey.braceLeft, +// "Bar": LogicalKeyboardKey.bar, +// "BraceR": LogicalKeyboardKey.braceRight, +// "Tilde": LogicalKeyboardKey.tilde, +// "AppMedia": LogicalKeyboardKey.mediaPlayPause, +// "AppUser1": LogicalKeyboardKey.f13, +// "AppUser2": LogicalKeyboardKey.f14, +// "Begin": LogicalKeyboardKey.begin, +// "Break": LogicalKeyboardKey.pauseBreak, +// "AppMail": LogicalKeyboardKey.mail, +// "Apostrophe": LogicalKeyboardKey.apostrophe, +// "ShiftLock": LogicalKeyboardKey.shiftLock, +// "SysReq": LogicalKeyboardKey.sysReq, +// "KP_Down": LogicalKeyboardKey.down, +// "KP_End": LogicalKeyboardKey.numpadEnd, +// "KP_Begin": LogicalKeyboardKey.numpadBegin, +// "KP_Delete": LogicalKeyboardKey.numpadDelete, +// "KP_F1": LogicalKeyboardKey.numpadF1, +// "KP_F2": LogicalKeyboardKey.numpadF2, +// "KP_F3": LogicalKeyboardKey.numpadF3, +// "KP_F4": LogicalKeyboardKey.numpadF4, +// "KP_Home": LogicalKeyboardKey.numpadHome, +// "KP_Insert": LogicalKeyboardKey.numpadInsert, +// "KP_Left": LogicalKeyboardKey.numpadArrowLeft, +// "KP_PageDown": LogicalKeyboardKey.numpadPageDown, +// "KP_PageUp": LogicalKeyboardKey.numpadPageUp, +// "KP_Right": LogicalKeyboardKey.numpadArrowRight, +// "KP_Separator": LogicalKeyboardKey.numpadSeparator, +// "KP_Space": LogicalKeyboardKey.numpadSpace, +// "KP_Tab": LogicalKeyboardKey.numpadTab, +// "KP_Up": LogicalKeyboardKey.numpadArrowUp, +// "Linefeed": LogicalKeyboardKey.lineFeed, +// }; + +// const Map modifierNameMap = { +// "Alt": LogicalKeyboardKey.alt, +// "AltGr": LogicalKeyboardKey.altGraph, +// "Control": LogicalKeyboardKey.control, +// "Meta": LogicalKeyboardKey.meta, +// "Shift": LogicalKeyboardKey.shift, +// "Super": LogicalKeyboardKey.superKey, +// }; diff --git a/pubspec.yaml b/pubspec.yaml index 86d46db..917c734 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: uni_control_hub -version: 0.0.7 +version: 0.0.8 publish_to: none description: Seamlessly Bridge Your Devices environment: