Files
rustdesk/flutter/lib/consts.dart
Luke 6ad56075d6 Drag whole toolbar; snap to all four edges of the remote session window (#15051)
* Drag whole toolbar; snap to all four edges

Today the drag handle on the remote-session toolbar repositions only
the handle row -- the icons themselves stay centered at the top. This
change applies the position to the entire toolbar wrapper so dragging
the handle moves the whole thing, and extends snapping from top-only
to any of the four window edges.

When docked left/right the toolbar reflows vertically. A live ghost
preview shows where the toolbar will land while you drag, with a small
hysteresis bias to keep the preview from flickering near corners.

The legacy 'remote-menubar-drag-x' session option is read as a fallback
on first load so existing users keep their saved horizontal position;
new option keys are 'remote-menubar-edge' and 'remote-menubar-frac'.

Tested locally on Windows. macOS / Linux / web desktop use the same
shared widget with no platform-specific calls, but I did not verify
them.

* Load edge independently and clamp loaded fraction

Addresses CodeRabbit review on #15051: parse the saved edge regardless
of whether the new fraction option is present so a partial write of
frac doesn't reset the toolbar back to top, and clamp the loaded
fraction to the kOptionRemoteMenubarDragLeft/Right contract so a
corrupted or out-of-range saved value can't bypass the bounds until
the user drags again.

* Require edge activation zone to switch dock; preserve horizontal slide

Per review feedback on #15051: nearest-edge-wins made a low-intent
horizontal slide too easy to escalate into a high-impact orientation
change (vertical reflow on left/right dock). The default drag now
keeps the toolbar on its current dock edge and just updates the
fraction along that edge -- the prior horizontal-slide behavior.

An alternate edge is only previewed/committed when the cursor enters
its 32 px activation zone; once previewed, the cursor has to move
back 64 px before reverting (hysteresis at the zone boundary).

* Gate multi-edge docking behind a settings toggle; default = horizontal slide

Replaces the activation-zone approach with an explicit opt-in setting
in Settings -> Other ("Allow docking remote toolbar to any window
edge"). This addresses the concern that a low-intent horizontal drag
shouldn't be able to trigger a high-impact orientation change, while
still letting users who want multi-edge docking opt in cleanly.

Default (toggle off):
  - The original horizontal slide is preserved.
  - The bug fix from the first commit still applies: dragging the
    handle moves the whole toolbar, and the position persists across
    collapse/expand (no more re-center on re-open).
  - Draggable is axis-locked to horizontal so the feedback widget
    stays on the top line during drag.

Opt-in (toggle on):
  - Full nearest-edge wins with the live preview ghost and corner
    hysteresis; toolbar reflows vertically on left/right docks.
  - Draggable is unlocked for 2D drag.

Reads the option via mainGetLocalBoolOptionSync so the toolbar's
default state matches what the settings checkbox shows; the option
key uses the allow- prefix so unset defaults to off.

Takes effect on next session (setting is read at session init).

The setting key (allow-multi-edge-toolbar-dock) is read by the
existing local-options machinery and persists per-install without
needing to be registered in libs/hbb_common's KEYS_LOCAL_SETTINGS.
Can add that registration in a parallel hbb_common PR if preferred.

* Fix remote toolbar drag positioning & persistence

Align drag fraction calculation with the toolbar's actual travel range,
keep preview sizing stable during drag, and preserve legacy horizontal
position storage when multi-edge docking is disabled.

Signed-off-by: fufesou <linlong1266@gmail.com>

* Remote toolbar snap edges

1. Translations
2. Apply option to remote windows on changed

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix: avoid remote toolbar docking jumps on setting reload

Signed-off-by: fufesou <linlong1266@gmail.com>

* Fix remote toolbar docking updates and drag sync

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact: translation key

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(toolbar-snap-edges): test web

Signed-off-by: fufesou <linlong1266@gmail.com>

* Fix remote toolbar docking sync and vertical layout

Signed-off-by: fufesou <linlong1266@gmail.com>

* Fix remote toolbar monitor controls on side docks

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-05-24 19:08:45 +08:00

696 lines
26 KiB
Dart

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get.dart';
const int kMaxVirtualDisplayCount = 4;
const int kAllVirtualDisplay = -1;
const double kDesktopRemoteTabBarHeight = 28.0;
const int kInvalidWindowId = -1;
const int kMainWindowId = 0;
const kAllDisplayValue = -1;
const kKeyLegacyMode = 'legacy';
const kKeyMapMode = 'map';
const kKeyTranslateMode = 'translate';
const String kPlatformAdditionsIsWayland = "is_wayland";
const String kPlatformAdditionsHeadless = "headless";
const String kPlatformAdditionsIsInstalled = "is_installed";
const String kPlatformAdditionsIddImpl = "idd_impl";
const String kPlatformAdditionsRustDeskVirtualDisplays =
"rustdesk_virtual_displays";
const String kPlatformAdditionsAmyuniVirtualDisplays =
"amyuni_virtual_displays";
const String kPlatformAdditionsHasFileClipboard = "has_file_clipboard";
const String kPlatformAdditionsSupportedPrivacyModeImpl =
"supported_privacy_mode_impl";
const String kPeerPlatformWindows = "Windows";
const String kPeerPlatformLinux = "Linux";
const String kPeerPlatformMacOS = "Mac OS";
const String kPeerPlatformAndroid = "Android";
const String kPeerPlatformWebDesktop = "WebDesktop";
const double kScrollbarThickness = 12.0;
/// [kAppTypeMain] used by 'Desktop Main Page' , 'Mobile (Client and Server)', "Install Page"
const String kAppTypeMain = "main";
/// [kAppTypeConnectionManager] only for 'Desktop CM Page'
const String kAppTypeConnectionManager = "cm";
const String kAppTypeDesktopRemote = "remote";
const String kAppTypeDesktopFileTransfer = "file transfer";
const String kAppTypeDesktopViewCamera = "view camera";
const String kAppTypeDesktopPortForward = "port forward";
const String kAppTypeDesktopTerminal = "terminal";
const String kWindowMainWindowOnTop = "main_window_on_top";
const String kWindowRefreshCurrentUser = "refresh_current_user";
const String kWindowGetWindowInfo = "get_window_info";
const String kWindowGetScreenList = "get_screen_list";
// This method is not used, maybe it can be removed.
const String kWindowDisableGrabKeyboard = "disable_grab_keyboard";
const String kWindowActionRebuild = "rebuild";
const String kWindowEventHide = "hide";
const String kWindowEventShow = "show";
const String kWindowConnect = "connect";
const String kWindowBumpMouse = "bump_mouse";
const String kWindowEventNewRemoteDesktop = "new_remote_desktop";
const String kWindowEventNewFileTransfer = "new_file_transfer";
const String kWindowEventNewViewCamera = "new_view_camera";
const String kWindowEventNewPortForward = "new_port_forward";
const String kWindowEventNewTerminal = "new_terminal";
const String kWindowEventRestoreTerminalSessions = "restore_terminal_sessions";
const String kWindowEventActiveSession = "active_session";
const String kWindowEventActiveDisplaySession = "active_display_session";
const String kWindowEventGetRemoteList = "get_remote_list";
const String kWindowEventGetSessionIdList = "get_session_id_list";
const String kWindowEventRemoteWindowCoords = "remote_window_coords";
const String kWindowEventSetFullscreen = "set_fullscreen";
const String kWindowEventMoveTabToNewWindow = "move_tab_to_new_window";
const String kWindowEventGetCachedSessionData = "get_cached_session_data";
const String kWindowEventOpenMonitorSession = "open_monitor_session";
const String kOptionViewStyle = "view_style";
const String kOptionScrollStyle = "scroll_style";
const String kOptionEdgeScrollEdgeThickness = "edge-scroll-edge-thickness";
const String kOptionImageQuality = "image_quality";
const String kOptionOpenNewConnInTabs = "enable-open-new-connections-in-tabs";
const String kOptionTextureRender = "use-texture-render";
const String kOptionD3DRender = "allow-d3d-render";
const String kOptionOpenInTabs = "allow-open-in-tabs";
const String kOptionOpenInWindows = "allow-open-in-windows";
const String kOptionForceAlwaysRelay = "force-always-relay";
const String kOptionViewOnly = "view_only";
const String kOptionEnableLanDiscovery = "enable-lan-discovery";
const String kOptionWhitelist = "whitelist";
const String kOptionEnableAbr = "enable-abr";
const String kOptionEnableRecordSession = "enable-record-session";
const String kOptionDirectServer = "direct-server";
const String kOptionDirectAccessPort = "direct-access-port";
const String kOptionAllowAutoDisconnect = "allow-auto-disconnect";
const String kOptionAutoDisconnectTimeout = "auto-disconnect-timeout";
const String kOptionEnableHwcodec = "enable-hwcodec";
const String kOptionAllowAutoRecordIncoming = "allow-auto-record-incoming";
const String kOptionAllowAutoRecordOutgoing = "allow-auto-record-outgoing";
const String kOptionVideoSaveDirectory = "video-save-directory";
const String kOptionAccessMode = "access-mode";
const String kOptionEnableKeyboard = "enable-keyboard";
// "Settings -> Security -> Permissions"
const String kOptionEnableRemotePrinter = "enable-remote-printer";
const String kOptionEnableClipboard = "enable-clipboard";
const String kOptionEnableFileTransfer = "enable-file-transfer";
const String kOptionEnableAudio = "enable-audio";
const String kOptionEnableCamera = "enable-camera";
const String kOptionEnableTerminal = "enable-terminal";
const String kOptionTerminalPersistent = "terminal-persistent";
const String kOptionEnableTunnel = "enable-tunnel";
const String kOptionEnableRemoteRestart = "enable-remote-restart";
const String kOptionEnableBlockInput = "enable-block-input";
const String kOptionEnablePrivacyMode = "enable-privacy-mode";
const String kOptionEnablePermChangeInAcceptWindow =
"enable-perm-change-in-accept-window";
const String kOptionAllowRemoteConfigModification =
"allow-remote-config-modification";
const String kOptionVerificationMethod = "verification-method";
const String kOptionApproveMode = "approve-mode";
const String kOptionAllowNumericOneTimePassword =
"allow-numeric-one-time-password";
const String kOptionCollapseToolbar = "collapse_toolbar";
const String kOptionHideToolbar = "hide-toolbar";
const String kOptionShowRemoteCursor = "show_remote_cursor";
const String kOptionFollowRemoteCursor = "follow_remote_cursor";
const String kOptionFollowRemoteWindow = "follow_remote_window";
const String kOptionZoomCursor = "zoom-cursor";
const String kOptionShowQualityMonitor = "show_quality_monitor";
const String kOptionDisableAudio = "disable_audio";
const String kOptionEnableFileCopyPaste = "enable-file-copy-paste";
// "Settings -> Display -> Other default options"
const String kOptionDisableClipboard = "disable_clipboard";
const String kOptionLockAfterSessionEnd = "lock_after_session_end";
const String kOptionPrivacyMode = "privacy_mode";
const String kOptionTouchMode = "touch-mode";
const String kOptionI444 = "i444";
const String kOptionSwapLeftRightMouse = "swap-left-right-mouse";
const String kOptionCodecPreference = "codec-preference";
const String kOptionRemoteMenubarDragLeft = "remote-menubar-drag-left";
const String kOptionRemoteMenubarDragRight = "remote-menubar-drag-right";
const String kOptionRemoteMenubarEdge = "remote-menubar-edge";
const String kOptionRemoteMenubarFraction = "remote-menubar-frac";
const String kOptionAllowMultiEdgeToolbarDock =
"allow-multi-edge-toolbar-dock";
const String kOptionHideAbTagsPanel = "hideAbTagsPanel";
const String kOptionRemoteMenubarState = "remoteMenubarState";
const String kOptionPeerSorting = "peer-sorting";
const String kOptionPeerTabIndex = "peer-tab-index";
const String kOptionPeerTabOrder = "peer-tab-order";
const String kOptionPeerTabVisible = "peer-tab-visible";
const String kOptionPeerCardUiType = "peer-card-ui-type";
const String kOptionCurrentAbName = "current-ab-name";
const String kOptionEnableConfirmClosingTabs = "enable-confirm-closing-tabs";
const String kOptionAllowAlwaysSoftwareRender = "allow-always-software-render";
const String kOptionEnableCheckUpdate = "enable-check-update";
const String kOptionAllowAutoUpdate = "allow-auto-update";
const String kOptionAllowLinuxHeadless = "allow-linux-headless";
const String kOptionAllowRemoveWallpaper = "allow-remove-wallpaper";
const String kOptionStopService = "stop-service";
const String kOptionDirectxCapture = "enable-directx-capture";
const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification";
const String kOptionEnableUdpPunch = "enable-udp-punch";
const String kOptionEnableIpv6Punch = "enable-ipv6-punch";
const String kOptionEnableTrustedDevices = "enable-trusted-devices";
const String kOptionShowVirtualMouse = "show-virtual-mouse";
const String kOptionVirtualMouseScale = "virtual-mouse-scale";
const String kOptionShowVirtualJoystick = "show-virtual-joystick";
const String kOptionAllowAskForNoteAtEndOfConnection = "allow-ask-for-note";
const String kOptionEnableShowTerminalExtraKeys = "enable-show-terminal-extra-keys";
// network options
const String kOptionAllowWebSocket = "allow-websocket";
const String kOptionAllowInsecureTLSFallback = "allow-insecure-tls-fallback";
const String kOptionDisableUdp = "disable-udp";
const String kOptionEnableFlutterHttpOnRust = "enable-flutter-http-on-rust";
// builtin options
const String kOptionHideServerSetting = "hide-server-settings";
const String kOptionHideProxySetting = "hide-proxy-settings";
const String kOptionHideWebSocketSetting = "hide-websocket-settings";
const String kOptionHideStopService = "hide-stop-service";
const String kOptionHideRemotePrinterSetting = "hide-remote-printer-settings";
const String kOptionHideSecuritySetting = "hide-security-settings";
const String kOptionHideNetworkSetting = "hide-network-settings";
const String kOptionRemovePresetPasswordWarning =
"remove-preset-password-warning";
const String kOptionDisableChangePermanentPassword =
"disable-change-permanent-password";
const String kOptionDisableChangeId = "disable-change-id";
const String kOptionDisableUnlockPin = "disable-unlock-pin";
const kHideUsernameOnCard = "hide-username-on-card";
const String kOptionHideHelpCards = "hide-help-cards";
const String kOptionAllowDeepLinkPassword = "allow-deep-link-password";
const String kOptionAllowDeepLinkServerSettings =
"allow-deep-link-server-settings";
const String kOptionToggleViewOnly = "view-only";
const String kOptionToggleShowMyCursor = "show-my-cursor";
const String kOptionDisableFloatingWindow = "disable-floating-window";
const String kOptionKeepScreenOn = "keep-screen-on";
const String kOptionKeepAwakeDuringIncomingSessions = "keep-awake-during-incoming-sessions";
const String kOptionKeepAwakeDuringOutgoingSessions = "keep-awake-during-outgoing-sessions";
const String kOptionShowMobileAction = "showMobileActions";
const String kUrlActionClose = "close";
const String kTabLabelHomePage = "Home";
const String kTabLabelSettingPage = "Settings";
const String kWindowPrefix = "wm_";
const int kWindowMainId = 0;
const String kPointerEventKindTouch = "touch";
const String kPointerEventKindMouse = "mouse";
const String kMouseEventTypeDefault = "";
const String kMouseEventTypePanStart = "pan_start";
const String kMouseEventTypePanUpdate = "pan_update";
const String kMouseEventTypePanEnd = "pan_end";
const String kMouseEventTypeDown = "down";
const String kMouseEventTypeUp = "up";
const String kKeyFlutterKey = "flutter_key";
const String kKeyShowDisplaysAsIndividualWindows =
'displays_as_individual_windows';
const String kKeyUseAllMyDisplaysForTheRemoteSession =
'use_all_my_displays_for_the_remote_session';
const String kKeyShowMonitorsToolbar = 'show_monitors_toolbar';
const String kKeyReverseMouseWheel = "reverse_mouse_wheel";
const String kMsgboxTextWaitingForImage = 'Connected, waiting for image...';
// the executable name of the portable version
const String kEnvPortableExecutable = "RUSTDESK_APPNAME";
const Color kColorWarn = Color.fromARGB(255, 245, 133, 59);
const Color kColorCanvas = Colors.black;
const int kMobileDefaultDisplayWidth = 720;
const int kMobileDefaultDisplayHeight = 1280;
const int kDesktopDefaultDisplayWidth = 1080;
const int kDesktopDefaultDisplayHeight = 720;
const int kMobileMaxDisplaySize = 1280;
const int kDesktopMaxDisplaySize = 3840;
const double kDesktopFileTransferRowHeight = 30.0;
const double kDesktopFileTransferHeaderHeight = 25.0;
const double kMinFps = 5;
const double kDefaultFps = 30;
const double kMaxFps = 120;
const double kMinQuality = 10;
const double kDefaultQuality = 50;
const double kMaxQuality = 100;
const double kMaxMoreQuality = 2000;
// trackpad speed
const String kKeyTrackpadSpeed = 'trackpad-speed';
const int kMinTrackpadSpeed = 10;
const int kDefaultTrackpadSpeed = 100;
const int kMaxTrackpadSpeed = 1000;
// relative mouse mode
/// Throttle duration (in milliseconds) for updating pointer lock center during
/// window move/resize events. Lower values provide more responsive updates but
/// may cause performance issues during rapid window operations.
const int kDefaultPointerLockCenterThrottleMs = 100;
/// Minimum server version required for relative mouse mode (MOUSE_TYPE_MOVE_RELATIVE).
/// Servers older than this version will ignore relative mouse events.
///
/// IMPORTANT: This value must be kept in sync with the Rust constant
/// `MIN_VERSION_RELATIVE_MOUSE_MODE` in `src/common.rs`.
const String kMinVersionForRelativeMouseMode = '1.4.5';
/// Maximum delta value for relative mouse movement.
/// Large values could cause issues with i32 overflow on server side,
/// and no reasonable mouse movement should exceed this bound.
///
/// IMPORTANT: This value must be kept in sync with the Rust constant
/// `MAX_RELATIVE_MOUSE_DELTA` in `src/server/input_service.rs`.
const int kMaxRelativeMouseDelta = 10000;
/// Debounce duration (in milliseconds) for relative mouse mode toggle.
/// This prevents double-toggle from race condition between Rust rdev grab loop
/// and Flutter keyboard handling. Value should be small enough to allow
/// intentional quick toggles but large enough to prevent accidental double-triggers.
const int kRelativeMouseModeToggleDebounceMs = 150;
// incomming (should be incoming) is kept, because change it will break the previous setting.
const String kKeyPrinterIncomingJobAction = 'printer-incomming-job-action';
const String kValuePrinterIncomingJobDismiss = 'dismiss';
const String kValuePrinterIncomingJobDefault = '';
const String kValuePrinterIncomingJobSelected = 'selected';
const String kKeyPrinterSelected = 'printer-selected-name';
const String kKeyPrinterSave = 'allow-printer-dialog-save';
const String kKeyPrinterAllowAutoPrint = 'allow-printer-auto-print';
double kNewWindowOffset = isWindows
? 56.0
: isLinux
? 50.0
: isMacOS
? 30.0
: 50.0;
EdgeInsets get kDragToResizeAreaPadding => !kUseCompatibleUiMode && isLinux
? stateGlobal.fullscreen.isTrue || stateGlobal.isMaximized.value
? EdgeInsets.zero
: EdgeInsets.all(5.0)
: EdgeInsets.zero;
// https://en.wikipedia.org/wiki/Non-breaking_space
const int $nbsp = 0x00A0;
extension StringExtension on String {
String get nonBreaking => replaceAll(' ', String.fromCharCode($nbsp));
}
const Size kConnectionManagerWindowSizeClosedChat = Size(300, 490);
const Size kConnectionManagerWindowSizeOpenChat = Size(700, 490);
// Tabbar transition duration, now we remove the duration
const Duration kTabTransitionDuration = Duration.zero;
const double kEmptyMarginTop = 50;
const double kDesktopIconButtonSplashRadius = 20;
/// [kMinCursorSize] indicates min cursor (w, h)
const int kMinCursorSize = 12;
const kFullScreenEdgeSize = 0.0;
const kMaximizeEdgeSize = 0.0;
// Do not use kWindowResizeEdgeSize directly. Use `windowResizeEdgeSize` in `common.dart` instead.
const kWindowResizeEdgeSize = 5.0;
final kWindowBorderWidth = isWindows ? 0.0 : 1.0;
const kDesktopMenuPadding = EdgeInsets.only(left: 12.0, right: 3.0);
const kFrameBorderRadius = 12.0;
const kFrameClipRRectBorderRadius = 12.0;
const kFrameBoxShadowBlurRadius = 32.0;
const kFrameBoxShadowOffsetFocused = 4.0;
const kFrameBoxShadowOffsetUnfocused = 2.0;
const kInvalidValueStr = 'InvalidValueStr';
// Config key shared by flutter and other ui.
const kCommConfKeyTheme = 'theme';
const kCommConfKeyLang = 'lang';
const kMobilePageConstraints = BoxConstraints(maxWidth: 600);
/// [kMouseControlDistance] indicates the distance that self-side move to get control of mouse.
const kMouseControlDistance = 12;
/// [kMouseControlTimeoutMSec] indicates the timeout (in milliseconds) that self-side can get control of mouse.
const kMouseControlTimeoutMSec = 1000;
/// [kRemoteViewStyleOriginal] Show remote image without scaling.
const kRemoteViewStyleOriginal = 'original';
/// [kRemoteViewStyleAdaptive] Show remote image scaling by ratio factor.
const kRemoteViewStyleAdaptive = 'adaptive';
/// [kRemoteViewStyleCustom] Show remote image at a user-defined scale percent.
const kRemoteViewStyleCustom = 'custom';
/// [kRemoteScrollStyleAuto] Scroll image auto by position.
const kRemoteScrollStyleAuto = 'scrollauto';
/// [kRemoteScrollStyleBar] Scroll image with scroll bar.
const kRemoteScrollStyleBar = 'scrollbar';
/// [kRemoteScrollStyleEdge] Scroll image auto at edges.
const kRemoteScrollStyleEdge = 'scrolledge';
/// [kScrollModeDefault] Mouse or touchpad, the default scroll mode.
const kScrollModeDefault = 'default';
/// [kScrollModeReverse] Mouse or touchpad, the reverse scroll mode.
const kScrollModeReverse = 'reverse';
/// [kRemoteImageQualityBest] Best image quality.
const kRemoteImageQualityBest = 'best';
/// [kRemoteImageQualityBalanced] Balanced image quality, mid performance.
const kRemoteImageQualityBalanced = 'balanced';
/// [kRemoteImageQualityLow] Low image quality, better performance.
const kRemoteImageQualityLow = 'low';
/// [kRemoteImageQualityCustom] Custom image quality.
const kRemoteImageQualityCustom = 'custom';
const kIgnoreDpi = true;
const Set<PointerDeviceKind> kTouchBasedDeviceKinds = {
PointerDeviceKind.touch,
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
};
// Scale custom related constants
const String kCustomScalePercentKey =
'custom_scale_percent'; // Flutter option key for storing custom scale percent (integer 5-1000)
const int kScaleCustomMinPercent = 5;
const int kScaleCustomPivotPercent = 100; // 100% should be at 1/3 of track
const int kScaleCustomMaxPercent = 1000;
const double kScaleCustomPivotPos = 1.0 / 3.0; // first 1/3 → up to 100%
const double kScaleCustomDetentEpsilon =
0.006; // snap range around pivot (~0.6%)
const Duration kDebounceCustomScaleDuration = Duration(milliseconds: 300);
// ================================ mobile ================================
// Magic numbers, maybe need to avoid it or use a better way to get them.
const kMobileDelaySoftKeyboard = Duration(milliseconds: 30);
const kMobileDelaySoftKeyboardFocus = Duration(milliseconds: 30);
/// Android constants
const kActionApplicationDetailsSettings =
"android.settings.APPLICATION_DETAILS_SETTINGS";
const kActionAccessibilitySettings = "android.settings.ACCESSIBILITY_SETTINGS";
const kRecordAudio = "android.permission.RECORD_AUDIO";
const kManageExternalStorage = "android.permission.MANAGE_EXTERNAL_STORAGE";
const kRequestIgnoreBatteryOptimizations =
"android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
const kSystemAlertWindow = "android.permission.SYSTEM_ALERT_WINDOW";
const kAndroid13Notification = "android.permission.POST_NOTIFICATIONS";
/// Android channel invoke type key
class AndroidChannel {
static final kStartAction = "start_action";
static final kGetStartOnBootOpt = "get_start_on_boot_opt";
static final kSetStartOnBootOpt = "set_start_on_boot_opt";
static final kSyncAppDirConfigPath = "sync_app_dir";
}
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _keyLabels
/// see [LogicalKeyboardKey.keyLabel]
const Map<int, String> logicalKeyMap = <int, String>{
0x00000000020: 'VK_SPACE',
0x00000000022: 'VK_QUOTE',
0x0000000002c: 'VK_COMMA',
0x0000000002d: 'VK_MINUS',
0x0000000002f: 'VK_SLASH',
0x00000000030: 'VK_0',
0x00000000031: 'VK_1',
0x00000000032: 'VK_2',
0x00000000033: 'VK_3',
0x00000000034: 'VK_4',
0x00000000035: 'VK_5',
0x00000000036: 'VK_6',
0x00000000037: 'VK_7',
0x00000000038: 'VK_8',
0x00000000039: 'VK_9',
0x0000000003b: 'VK_SEMICOLON',
0x0000000003d: 'VK_PLUS', // it is =
0x0000000005b: 'VK_LBRACKET',
0x0000000005c: 'VK_BACKSLASH',
0x0000000005d: 'VK_RBRACKET',
0x00000000061: 'VK_A',
0x00000000062: 'VK_B',
0x00000000063: 'VK_C',
0x00000000064: 'VK_D',
0x00000000065: 'VK_E',
0x00000000066: 'VK_F',
0x00000000067: 'VK_G',
0x00000000068: 'VK_H',
0x00000000069: 'VK_I',
0x0000000006a: 'VK_J',
0x0000000006b: 'VK_K',
0x0000000006c: 'VK_L',
0x0000000006d: 'VK_M',
0x0000000006e: 'VK_N',
0x0000000006f: 'VK_O',
0x00000000070: 'VK_P',
0x00000000071: 'VK_Q',
0x00000000072: 'VK_R',
0x00000000073: 'VK_S',
0x00000000074: 'VK_T',
0x00000000075: 'VK_U',
0x00000000076: 'VK_V',
0x00000000077: 'VK_W',
0x00000000078: 'VK_X',
0x00000000079: 'VK_Y',
0x0000000007a: 'VK_Z',
0x00100000008: 'VK_BACK',
0x00100000009: 'VK_TAB',
0x0010000000d: 'VK_ENTER',
0x0010000001b: 'VK_ESCAPE',
0x0010000007f: 'VK_DELETE',
0x00100000104: 'VK_CAPITAL',
0x00100000301: 'VK_DOWN',
0x00100000302: 'VK_LEFT',
0x00100000303: 'VK_RIGHT',
0x00100000304: 'VK_UP',
0x00100000305: 'VK_END',
0x00100000306: 'VK_HOME',
0x00100000307: 'VK_NEXT',
0x00100000308: 'VK_PRIOR',
0x00100000401: 'VK_CLEAR',
0x00100000407: 'VK_INSERT',
0x00100000504: 'VK_CANCEL',
0x00100000506: 'VK_EXECUTE',
0x00100000508: 'VK_HELP',
0x00100000509: 'VK_PAUSE',
0x0010000050c: 'VK_SELECT',
0x00100000608: 'VK_PRINT',
0x00100000705: 'VK_CONVERT',
0x00100000706: 'VK_FINAL',
0x00100000711: 'VK_HANGUL',
0x00100000712: 'VK_HANJA',
0x00100000713: 'VK_JUNJA',
0x00100000718: 'VK_KANA',
0x00100000719: 'VK_KANJI',
0x00100000801: 'VK_F1',
0x00100000802: 'VK_F2',
0x00100000803: 'VK_F3',
0x00100000804: 'VK_F4',
0x00100000805: 'VK_F5',
0x00100000806: 'VK_F6',
0x00100000807: 'VK_F7',
0x00100000808: 'VK_F8',
0x00100000809: 'VK_F9',
0x0010000080a: 'VK_F10',
0x0010000080b: 'VK_F11',
0x0010000080c: 'VK_F12',
0x00100000d2b: 'Apps',
0x00200000002: 'VK_SLEEP',
0x00200000100: 'VK_CONTROL',
0x00200000101: 'RControl',
0x00200000102: 'VK_SHIFT',
0x00200000103: 'RShift',
0x00200000104: 'VK_MENU',
0x00200000105: 'RAlt',
0x002000001f0: 'VK_CONTROL',
0x002000001f2: 'VK_SHIFT',
0x002000001f4: 'VK_MENU',
0x002000001f6: 'Meta',
0x0020000022a: 'VK_MULTIPLY',
0x0020000022b: 'VK_ADD',
0x0020000022d: 'VK_SUBTRACT',
0x0020000022e: 'VK_DECIMAL',
0x0020000022f: 'VK_DIVIDE',
0x00200000230: 'VK_NUMPAD0',
0x00200000231: 'VK_NUMPAD1',
0x00200000232: 'VK_NUMPAD2',
0x00200000233: 'VK_NUMPAD3',
0x00200000234: 'VK_NUMPAD4',
0x00200000235: 'VK_NUMPAD5',
0x00200000236: 'VK_NUMPAD6',
0x00200000237: 'VK_NUMPAD7',
0x00200000238: 'VK_NUMPAD8',
0x00200000239: 'VK_NUMPAD9',
};
/// flutter/packages/flutter/lib/src/services/keyboard_key.dart -> _debugName
/// see [PhysicalKeyboardKey.debugName] -> _debugName
const Map<int, String> physicalKeyMap = <int, String>{
0x00010082: 'VK_SLEEP',
0x00070004: 'VK_A',
0x00070005: 'VK_B',
0x00070006: 'VK_C',
0x00070007: 'VK_D',
0x00070008: 'VK_E',
0x00070009: 'VK_F',
0x0007000a: 'VK_G',
0x0007000b: 'VK_H',
0x0007000c: 'VK_I',
0x0007000d: 'VK_J',
0x0007000e: 'VK_K',
0x0007000f: 'VK_L',
0x00070010: 'VK_M',
0x00070011: 'VK_N',
0x00070012: 'VK_O',
0x00070013: 'VK_P',
0x00070014: 'VK_Q',
0x00070015: 'VK_R',
0x00070016: 'VK_S',
0x00070017: 'VK_T',
0x00070018: 'VK_U',
0x00070019: 'VK_V',
0x0007001a: 'VK_W',
0x0007001b: 'VK_X',
0x0007001c: 'VK_Y',
0x0007001d: 'VK_Z',
0x0007001e: 'VK_1',
0x0007001f: 'VK_2',
0x00070020: 'VK_3',
0x00070021: 'VK_4',
0x00070022: 'VK_5',
0x00070023: 'VK_6',
0x00070024: 'VK_7',
0x00070025: 'VK_8',
0x00070026: 'VK_9',
0x00070027: 'VK_0',
0x00070028: 'VK_ENTER',
0x00070029: 'VK_ESCAPE',
0x0007002a: 'VK_BACK',
0x0007002b: 'VK_TAB',
0x0007002c: 'VK_SPACE',
0x0007002d: 'VK_MINUS',
0x0007002e: 'VK_PLUS', // it is =
0x0007002f: 'VK_LBRACKET',
0x00070030: 'VK_RBRACKET',
0x00070033: 'VK_SEMICOLON',
0x00070034: 'VK_QUOTE',
0x00070036: 'VK_COMMA',
0x00070038: 'VK_SLASH',
0x00070039: 'VK_CAPITAL',
0x0007003a: 'VK_F1',
0x0007003b: 'VK_F2',
0x0007003c: 'VK_F3',
0x0007003d: 'VK_F4',
0x0007003e: 'VK_F5',
0x0007003f: 'VK_F6',
0x00070040: 'VK_F7',
0x00070041: 'VK_F8',
0x00070042: 'VK_F9',
0x00070043: 'VK_F10',
0x00070044: 'VK_F11',
0x00070045: 'VK_F12',
0x00070049: 'VK_INSERT',
0x0007004a: 'VK_HOME',
0x0007004b: 'VK_PRIOR', // Page Up
0x0007004c: 'VK_DELETE',
0x0007004d: 'VK_END',
0x0007004e: 'VK_NEXT', // Page Down
0x0007004f: 'VK_RIGHT',
0x00070050: 'VK_LEFT',
0x00070051: 'VK_DOWN',
0x00070052: 'VK_UP',
0x00070053: 'Num Lock', // TODO rust not impl
0x00070054: 'VK_DIVIDE', // numpad
0x00070055: 'VK_MULTIPLY',
0x00070056: 'VK_SUBTRACT',
0x00070057: 'VK_ADD',
0x00070058: 'VK_ENTER', // num enter
0x00070059: 'VK_NUMPAD1',
0x0007005a: 'VK_NUMPAD2',
0x0007005b: 'VK_NUMPAD3',
0x0007005c: 'VK_NUMPAD4',
0x0007005d: 'VK_NUMPAD5',
0x0007005e: 'VK_NUMPAD6',
0x0007005f: 'VK_NUMPAD7',
0x00070060: 'VK_NUMPAD8',
0x00070061: 'VK_NUMPAD9',
0x00070062: 'VK_NUMPAD0',
0x00070063: 'VK_DECIMAL',
0x00070075: 'VK_HELP',
0x00070077: 'VK_SELECT',
0x00070088: 'VK_KANA',
0x0007008a: 'VK_CONVERT',
0x000700e0: 'VK_CONTROL',
0x000700e1: 'VK_SHIFT',
0x000700e2: 'VK_MENU',
0x000700e3: 'Meta',
0x000700e4: 'RControl',
0x000700e5: 'RShift',
0x000700e6: 'RAlt',
0x000700e7: 'RWin',
0x000c00b1: 'VK_PAUSE',
0x000c00cd: 'VK_PAUSE',
0x000c019e: 'LOCK_SCREEN',
0x000c0208: 'VK_PRINT',
};
/// The windows targets in the publish time order.
enum WindowsTarget {
naw, // not a windows target
xp,
vista,
w7,
w8,
w8_1,
w10,
w11
}
/// A convenient method to transform a build number to the corresponding windows version.
extension WindowsTargetExt on int {
WindowsTarget get windowsVersion => getWindowsTarget(this);
}
const kCheckSoftwareUpdateFinish = 'check_software_update_finish';