Initial commit: RustDesk 1.4.7 macOS desktop port
- Filled empty libs/hbb_common/ submodule (cloned from rustdesk/hbb_common) - Patched Flutter 3.44 / Dart 3.12 compatibility: * flutter/lib/generated_bridge.dart: asTypedList with cast<>, DartPort=Int64 * flutter/lib/common.dart: DialogTheme->DialogThemeData, TabBarTheme->TabBarThemeData * flutter/pubspec.yaml: extended_text 14.0.0->15.0.2, google_fonts override 5.0.0 * flutter/macos/Runner/Configs/Release.xcconfig: EXCLUDED_ARCHS=x86_64 - Build verified: cargo check + cargo build --features flutter + cargo build --release --features flutter - Verified flutter build macos --debug and --release both produce working .app - Verified .dmg installer (27MB arm64) created via hdiutil - Build deps: Xcode 26.5, CocoaPods 1.16.2, Flutter 3.44, VCPKG arm64-osx
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/desktop/pages/server_page.dart';
|
||||
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
||||
import 'package:flutter_hbb/main.dart';
|
||||
import 'package:flutter_hbb/models/server_model.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
final testClients = [
|
||||
Client(0, false, false, false, "UserAAAAAA", "123123123", true, false, false, false),
|
||||
Client(1, false, false, false, "UserBBBBB", "221123123", true, false, false, false),
|
||||
Client(2, false, false, false, "UserC", "331123123", true, false, false, false),
|
||||
Client(3, false, false, false, "UserDDDDDDDDDDDd", "441123123", true, false, false, false)
|
||||
];
|
||||
|
||||
/// flutter run -d {platform} -t test/cm_test.dart to test cm
|
||||
void main(List<String> args) async {
|
||||
isTest = true;
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await windowManager.ensureInitialized();
|
||||
await windowManager.setSize(const Size(400, 600));
|
||||
await windowManager.setAlignment(Alignment.topRight);
|
||||
await initEnv(kAppTypeMain);
|
||||
for (var client in testClients) {
|
||||
gFFI.serverModel.clients.add(client);
|
||||
gFFI.serverModel.tabController.add(TabInfo(
|
||||
key: client.id.toString(),
|
||||
label: client.name,
|
||||
closable: false,
|
||||
page: buildConnectionCard(client)));
|
||||
}
|
||||
|
||||
runApp(GetMaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: MyTheme.lightTheme,
|
||||
darkTheme: MyTheme.darkTheme,
|
||||
themeMode: MyTheme.currentThemeMode(),
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: supportedLocales,
|
||||
home: const DesktopServerPage()));
|
||||
WindowOptions windowOptions = getHiddenTitleBarWindowOptions(
|
||||
size: kConnectionManagerWindowSizeClosedChat);
|
||||
windowManager.waitUntilReadyToShow(windowOptions, () async {
|
||||
await windowManager.show();
|
||||
// ensure initial window size to be changed
|
||||
await windowManager.setSize(kConnectionManagerWindowSizeClosedChat);
|
||||
await Future.wait([
|
||||
windowManager.setAlignment(Alignment.topRight),
|
||||
windowManager.focus(),
|
||||
windowManager.setOpacity(1)
|
||||
]);
|
||||
// ensure
|
||||
windowManager.setAlignment(Alignment.topRight);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_hbb/models/input_modifier_utils.dart';
|
||||
|
||||
void main() {
|
||||
group('shouldReleaseStaleMobileShift', () {
|
||||
test('does not release when cached shift is already false', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: false,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.keyD,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('releases one-shot mobile shift after a text key', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.keyD,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('does not release manually toggled shift without tracked key down',
|
||||
() {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.keyD,
|
||||
hasTrackedShiftKeyDown: false,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('does not release when shift is still physically pressed', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: true,
|
||||
logicalKey: LogicalKeyboardKey.keyD,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('does not release on non-mobile platforms', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: false,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.keyD,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('releases on enter key', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.enter,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('releases on arrow key', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.arrowLeft,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('does not release on modifier events', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.shiftLeft,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('does not release on shiftRight modifier events', () {
|
||||
expect(
|
||||
shouldReleaseStaleMobileShift(
|
||||
isMobile: true,
|
||||
cachedShiftPressed: true,
|
||||
actualShiftPressed: false,
|
||||
logicalKey: LogicalKeyboardKey.shiftRight,
|
||||
hasTrackedShiftKeyDown: true,
|
||||
),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user