fix:reconnect time,enter password focus,wrong gesture tap-up;ctrl soft keyboard
This commit is contained in:
parent
b30299cc12
commit
c188a6f93f
@ -10,6 +10,7 @@ import android.os.Build
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.WindowManager
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
@ -125,6 +126,18 @@ class MainActivity : FlutterActivity() {
|
|||||||
result.success(true)
|
result.success(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"enable_soft_keyboard" -> {
|
||||||
|
// https://blog.csdn.net/hanye2020/article/details/105553780
|
||||||
|
try {
|
||||||
|
if (call.arguments as Boolean) {
|
||||||
|
window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
|
||||||
|
} else {
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
result.success(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
result.error("-1", "No such method", null)
|
result.error("-1", "No such method", null)
|
||||||
}
|
}
|
||||||
|
@ -249,6 +249,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
if (displays.length > 0) {
|
if (displays.length > 0) {
|
||||||
showLoading(translate('Connected, waiting for image...'));
|
showLoading(translate('Connected, waiting for image...'));
|
||||||
_waitForImage = true;
|
_waitForImage = true;
|
||||||
|
_reconnects = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -148,6 +148,7 @@ hideChatWindowOverlay() {
|
|||||||
|
|
||||||
toggleChatOverlay() {
|
toggleChatOverlay() {
|
||||||
if (iconOverlayEntry == null || windowOverlayEntry == null) {
|
if (iconOverlayEntry == null || windowOverlayEntry == null) {
|
||||||
|
FFI.invokeMethod("enable_soft_keyboard", true);
|
||||||
showChatIconOverlay();
|
showChatIconOverlay();
|
||||||
showChatWindowOverlay();
|
showChatWindowOverlay();
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,6 +60,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
FFI.listenToMouse(false);
|
FFI.listenToMouse(false);
|
||||||
|
FFI.invokeMethod("enable_soft_keyboard", true);
|
||||||
_mobileFocusNode.dispose();
|
_mobileFocusNode.dispose();
|
||||||
_physicalFocusNode.dispose();
|
_physicalFocusNode.dispose();
|
||||||
FFI.close();
|
FFI.close();
|
||||||
@ -90,6 +91,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
if (v < 100) {
|
if (v < 100) {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: []);
|
overlays: []);
|
||||||
|
FFI.invokeMethod("enable_soft_keyboard", false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,6 +183,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void openKeyboard() {
|
void openKeyboard() {
|
||||||
|
FFI.invokeMethod("enable_soft_keyboard", true);
|
||||||
// destroy first, so that our _value trick can work
|
// destroy first, so that our _value trick can work
|
||||||
_value = initText;
|
_value = initText;
|
||||||
setState(() => _showEdit = false);
|
setState(() => _showEdit = false);
|
||||||
@ -193,7 +196,6 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
_timer = Timer(Duration(milliseconds: 30), () {
|
_timer = Timer(Duration(milliseconds: 30), () {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.show');
|
|
||||||
_mobileFocusNode.requestFocus();
|
_mobileFocusNode.requestFocus();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -211,48 +213,59 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
final pi = Provider.of<FfiModel>(context).pi;
|
final pi = Provider.of<FfiModel>(context).pi;
|
||||||
final hideKeyboard = isKeyboardShown() && _showEdit;
|
final hideKeyboard = isKeyboardShown() && _showEdit;
|
||||||
final showActionButton = !_showBar || hideKeyboard;
|
final showActionButton = !_showBar || hideKeyboard;
|
||||||
|
final keyboard = FFI.ffiModel.permissions['keyboard'] != false;
|
||||||
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
clientClose();
|
clientClose();
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: getRawPointerAndKeyBody(
|
||||||
// resizeToAvoidBottomInset: true,
|
keyboard,
|
||||||
floatingActionButton: !showActionButton
|
Scaffold(
|
||||||
? null
|
// resizeToAvoidBottomInset: true,
|
||||||
: FloatingActionButton(
|
floatingActionButton: !showActionButton
|
||||||
mini: !hideKeyboard,
|
? null
|
||||||
child: Icon(
|
: FloatingActionButton(
|
||||||
hideKeyboard ? Icons.expand_more : Icons.expand_less),
|
mini: !hideKeyboard,
|
||||||
backgroundColor: MyTheme.accent,
|
child: Icon(
|
||||||
onPressed: () {
|
hideKeyboard ? Icons.expand_more : Icons.expand_less),
|
||||||
setState(() {
|
backgroundColor: MyTheme.accent,
|
||||||
if (hideKeyboard) {
|
onPressed: () {
|
||||||
_showEdit = false;
|
setState(() {
|
||||||
_mobileFocusNode.unfocus();
|
if (hideKeyboard) {
|
||||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
_showEdit = false;
|
||||||
_physicalFocusNode.requestFocus();
|
FFI.invokeMethod("enable_soft_keyboard", false);
|
||||||
} else {
|
_mobileFocusNode.unfocus();
|
||||||
_showBar = !_showBar;
|
_physicalFocusNode.requestFocus();
|
||||||
}
|
} else {
|
||||||
});
|
_showBar = !_showBar;
|
||||||
}),
|
}
|
||||||
bottomNavigationBar:
|
});
|
||||||
_showBar && pi.displays != null ? getBottomAppBar() : null,
|
}),
|
||||||
body: Overlay(
|
bottomNavigationBar:
|
||||||
initialEntries: [
|
_showBar && pi.displays != null ? getBottomAppBar() : null,
|
||||||
OverlayEntry(builder: (context) {
|
body: Overlay(
|
||||||
final keyboard = FFI.ffiModel.permissions['keyboard'] != false;
|
initialEntries: [
|
||||||
return Container(
|
OverlayEntry(builder: (context) {
|
||||||
color: Colors.black,
|
return Container(
|
||||||
child: getRawPointerAndKeyBody(keyboard));
|
color: Colors.black,
|
||||||
})
|
// child: getRawPointerAndKeyBody(keyboard));
|
||||||
],
|
child: isDesktop
|
||||||
)),
|
? getBodyForDesktopWithListener(keyboard)
|
||||||
|
: SafeArea(
|
||||||
|
child: Container(
|
||||||
|
color: MyTheme.canvasColor,
|
||||||
|
child: _isPhysicalKeyboard
|
||||||
|
? getBodyForMobile()
|
||||||
|
: getBodyForMobileWithGesture())));
|
||||||
|
})
|
||||||
|
],
|
||||||
|
))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getRawPointerAndKeyBody(bool keyboard) {
|
Widget getRawPointerAndKeyBody(bool keyboard, Widget child) {
|
||||||
return Listener(
|
return Listener(
|
||||||
onPointerHover: (e) {
|
onPointerHover: (e) {
|
||||||
if (e.kind != ui.PointerDeviceKind.mouse) return;
|
if (e.kind != ui.PointerDeviceKind.mouse) return;
|
||||||
@ -351,14 +364,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
}
|
}
|
||||||
return KeyEventResult.handled;
|
return KeyEventResult.handled;
|
||||||
},
|
},
|
||||||
child: isDesktop
|
child: child))));
|
||||||
? getBodyForDesktopWithListener(keyboard)
|
|
||||||
: SafeArea(
|
|
||||||
child: Container(
|
|
||||||
color: MyTheme.canvasColor,
|
|
||||||
child: _isPhysicalKeyboard
|
|
||||||
? getBodyForMobile()
|
|
||||||
: getBodyForMobileWithGesture()))))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getBottomAppBar() {
|
Widget getBottomAppBar() {
|
||||||
@ -490,7 +496,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode);
|
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onHoldDragCancel: () {
|
onHoldDragEnd: (_) {
|
||||||
if (!_touchMode) {
|
if (!_touchMode) {
|
||||||
FFI.sendMouse('up', MouseButtons.left);
|
FFI.sendMouse('up', MouseButtons.left);
|
||||||
}
|
}
|
||||||
@ -499,8 +505,6 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
if (_touchMode) {
|
if (_touchMode) {
|
||||||
FFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy);
|
FFI.cursorModel.move(d.localPosition.dx, d.localPosition.dy);
|
||||||
FFI.sendMouse('down', MouseButtons.left);
|
FFI.sendMouse('down', MouseButtons.left);
|
||||||
} else {
|
|
||||||
FFI.sendMouse('up', MouseButtons.left);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onOneFingerPanUpdate: (d) {
|
onOneFingerPanUpdate: (d) {
|
||||||
@ -543,6 +547,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
textInputAction: TextInputAction.newline,
|
textInputAction: TextInputAction.newline,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
enableSuggestions: false,
|
enableSuggestions: false,
|
||||||
|
autofocus: true,
|
||||||
focusNode: _mobileFocusNode,
|
focusNode: _mobileFocusNode,
|
||||||
maxLines: null,
|
maxLines: null,
|
||||||
initialValue: _value,
|
initialValue: _value,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
@ -10,15 +12,15 @@ void clientClose() {
|
|||||||
const SEC1 = Duration(seconds: 1);
|
const SEC1 = Duration(seconds: 1);
|
||||||
void showSuccess({Duration duration = SEC1}) {
|
void showSuccess({Duration duration = SEC1}) {
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
showToast(translate("Successful"),duration:SEC1);
|
showToast(translate("Successful"), duration: SEC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showError({Duration duration = SEC1}){
|
void showError({Duration duration = SEC1}) {
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
showToast(translate("Error"),duration:SEC1);
|
showToast(translate("Error"), duration: SEC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePasswordDialog(){
|
void updatePasswordDialog() {
|
||||||
final p0 = TextEditingController();
|
final p0 = TextEditingController();
|
||||||
final p1 = TextEditingController();
|
final p1 = TextEditingController();
|
||||||
var validateLength = false;
|
var validateLength = false;
|
||||||
@ -43,7 +45,7 @@ void updatePasswordDialog(){
|
|||||||
if (validateLength != val) {
|
if (validateLength != val) {
|
||||||
// use delay to make setState success
|
// use delay to make setState success
|
||||||
Future.delayed(Duration(microseconds: 1),
|
Future.delayed(Duration(microseconds: 1),
|
||||||
() => setState(() => validateLength = val));
|
() => setState(() => validateLength = val));
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
? null
|
? null
|
||||||
@ -62,7 +64,7 @@ void updatePasswordDialog(){
|
|||||||
final val = p0.text == v;
|
final val = p0.text == v;
|
||||||
if (validateSame != val) {
|
if (validateSame != val) {
|
||||||
Future.delayed(Duration(microseconds: 1),
|
Future.delayed(Duration(microseconds: 1),
|
||||||
() => setState(() => validateSame = val));
|
() => setState(() => validateSame = val));
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
? null
|
? null
|
||||||
@ -82,14 +84,14 @@ void updatePasswordDialog(){
|
|||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: (validateLength && validateSame)
|
onPressed: (validateLength && validateSame)
|
||||||
? () async {
|
? () async {
|
||||||
close();
|
close();
|
||||||
showLoading(translate("Waiting"));
|
showLoading(translate("Waiting"));
|
||||||
if(await FFI.serverModel.updatePassword(p0.text)){
|
if (await FFI.serverModel.updatePassword(p0.text)) {
|
||||||
showSuccess();
|
showSuccess();
|
||||||
}else{
|
} else {
|
||||||
showError();
|
showError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text(translate('OK')),
|
child: Text(translate('OK')),
|
||||||
),
|
),
|
||||||
@ -115,7 +117,6 @@ void enterPasswordDialog(String id) {
|
|||||||
),
|
),
|
||||||
value: remember,
|
value: remember,
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
debugPrint("onChanged");
|
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
setState(() => remember = v);
|
setState(() => remember = v);
|
||||||
}
|
}
|
||||||
@ -181,11 +182,25 @@ class PasswordWidget extends StatefulWidget {
|
|||||||
|
|
||||||
class _PasswordWidgetState extends State<PasswordWidget> {
|
class _PasswordWidgetState extends State<PasswordWidget> {
|
||||||
bool _passwordVisible = false;
|
bool _passwordVisible = false;
|
||||||
|
final _focusNode = FocusNode();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
Timer(Duration(milliseconds: 50), () => _focusNode.requestFocus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_focusNode.unfocus();
|
||||||
|
_focusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextField(
|
return TextField(
|
||||||
autofocus: true,
|
focusNode: _focusNode,
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
obscureText: !_passwordVisible,
|
obscureText: !_passwordVisible,
|
||||||
//This will obscure text dynamically
|
//This will obscure text dynamically
|
||||||
|
@ -236,6 +236,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
|
|||||||
GestureDragUpdateCallback? onHoldDragUpdate;
|
GestureDragUpdateCallback? onHoldDragUpdate;
|
||||||
GestureDragDownCallback? onHoldDragDown;
|
GestureDragDownCallback? onHoldDragDown;
|
||||||
GestureDragCancelCallback? onHoldDragCancel;
|
GestureDragCancelCallback? onHoldDragCancel;
|
||||||
|
GestureDragEndCallback? onHoldDragEnd;
|
||||||
|
|
||||||
bool _isStart = false;
|
bool _isStart = false;
|
||||||
|
|
||||||
@ -253,7 +254,8 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
|
|||||||
case kPrimaryButton:
|
case kPrimaryButton:
|
||||||
if (onHoldDragStart == null &&
|
if (onHoldDragStart == null &&
|
||||||
onHoldDragUpdate == null &&
|
onHoldDragUpdate == null &&
|
||||||
onHoldDragCancel == null) {
|
onHoldDragCancel == null &&
|
||||||
|
onHoldDragEnd == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -305,6 +307,10 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
|
|||||||
if (event is PointerUpEvent) {
|
if (event is PointerUpEvent) {
|
||||||
if (_firstTap == null && _secondTap == null) {
|
if (_firstTap == null && _secondTap == null) {
|
||||||
_registerFirstTap(tracker);
|
_registerFirstTap(tracker);
|
||||||
|
} else if (_secondTap != null) {
|
||||||
|
if (event.pointer == _secondTap!.pointer) {
|
||||||
|
if (onHoldDragEnd != null) onHoldDragEnd!(DragEndDetails());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_reject(tracker);
|
_reject(tracker);
|
||||||
}
|
}
|
||||||
@ -739,6 +745,7 @@ RawGestureDetector getMixinGestureDetector({
|
|||||||
GestureDragStartCallback? onHoldDragStart,
|
GestureDragStartCallback? onHoldDragStart,
|
||||||
GestureDragUpdateCallback? onHoldDragUpdate,
|
GestureDragUpdateCallback? onHoldDragUpdate,
|
||||||
GestureDragCancelCallback? onHoldDragCancel,
|
GestureDragCancelCallback? onHoldDragCancel,
|
||||||
|
GestureDragEndCallback? onHoldDragEnd,
|
||||||
GestureTapDownCallback? onDoubleFinerTap,
|
GestureTapDownCallback? onDoubleFinerTap,
|
||||||
GestureDragStartCallback? onOneFingerPanStart,
|
GestureDragStartCallback? onOneFingerPanStart,
|
||||||
GestureDragUpdateCallback? onOneFingerPanUpdate,
|
GestureDragUpdateCallback? onOneFingerPanUpdate,
|
||||||
@ -782,6 +789,7 @@ RawGestureDetector getMixinGestureDetector({
|
|||||||
..onHoldDragStart = onHoldDragStart
|
..onHoldDragStart = onHoldDragStart
|
||||||
..onHoldDragUpdate = onHoldDragUpdate
|
..onHoldDragUpdate = onHoldDragUpdate
|
||||||
..onHoldDragCancel = onHoldDragCancel
|
..onHoldDragCancel = onHoldDragCancel
|
||||||
|
..onHoldDragEnd = onHoldDragEnd
|
||||||
}),
|
}),
|
||||||
DoubleFinerTapGestureRecognizer: GestureRecognizerFactoryWithHandlers<
|
DoubleFinerTapGestureRecognizer: GestureRecognizerFactoryWithHandlers<
|
||||||
DoubleFinerTapGestureRecognizer>(
|
DoubleFinerTapGestureRecognizer>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user