refact: texture render as an option (#8168)

* refact: texture render as an option

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

* refact: texture render, translation

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

* refact: texture render as option

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

* Update ui_interface.rs

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
This commit is contained in:
fufesou
2024-05-28 16:42:30 +08:00
committed by GitHub
parent 010b17509a
commit 72ec86b58d
66 changed files with 481 additions and 282 deletions

View File

@@ -387,10 +387,25 @@ class _GeneralState extends State<_General> {
isServer: false,
),
// though this is related to GUI, but opengl problem affects all users, so put in config rather than local
if (isLinux)
Tooltip(
message: translate('software_render_tip'),
child: _OptionCheckBox(
context,
"Always use software rendering",
kOptionAllowAlwaysSoftwareRender,
),
),
Tooltip(
message: translate('software_render_tip'),
child: _OptionCheckBox(context, "Always use software rendering",
kOptionAllowAlwaysSoftwareRender),
message: translate('texture_render_tip'),
child: _OptionCheckBox(
context,
"Use texture rendering",
kOptionTextureRender,
optGetter: bind.mainGetUseTextureRender,
optSetter: (k, v) async =>
await bind.mainSetLocalOption(key: k, value: v ? 'Y' : 'N'),
),
),
if (!bind.isCustomClient())
_OptionCheckBox(
@@ -426,7 +441,7 @@ class _GeneralState extends State<_General> {
context,
'Remove wallpaper during incoming sessions',
kOptionAllowRemoveWallpaper,
update: () {
update: (bool v) {
setState(() {});
},
),
@@ -457,8 +472,8 @@ class _GeneralState extends State<_General> {
context,
'Enable hardware codec',
kOptionEnableHwcodec,
update: () {
if (mainGetBoolOptionSync(kOptionEnableHwcodec)) {
update: (bool v) {
if (v) {
bind.mainCheckHwcodec();
}
},
@@ -941,7 +956,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
List<Widget> directIp(BuildContext context) {
TextEditingController controller = TextEditingController();
update() => setState(() {});
update(bool v) => setState(() {});
RxBool applyEnabled = false.obs;
return [
_OptionCheckBox(context, 'Enable direct IP access', kOptionDirectServer,
@@ -1102,7 +1117,7 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
List<Widget> autoDisconnect(BuildContext context) {
TextEditingController controller = TextEditingController();
update() => setState(() {});
update(bool v) => setState(() {});
RxBool applyEnabled = false.obs;
return [
_OptionCheckBox(
@@ -1803,33 +1818,41 @@ Widget _Card(
}
// ignore: non_constant_identifier_names
Widget _OptionCheckBox(BuildContext context, String label, String key,
{Function()? update,
bool reverse = false,
bool enabled = true,
Icon? checkedIcon,
bool? fakeValue,
bool isServer = true}) {
bool value =
isServer ? mainGetBoolOptionSync(key) : mainGetLocalBoolOptionSync(key);
Widget _OptionCheckBox(
BuildContext context,
String label,
String key, {
Function(bool)? update,
bool reverse = false,
bool enabled = true,
Icon? checkedIcon,
bool? fakeValue,
bool isServer = true,
bool Function()? optGetter,
Future<void> Function(String, bool)? optSetter,
}) {
getOpt() => optGetter != null
? optGetter()
: (isServer
? mainGetBoolOptionSync(key)
: mainGetLocalBoolOptionSync(key));
bool value = getOpt();
final isOptFixed = isOptionFixed(key);
if (reverse) value = !value;
var ref = value.obs;
onChanged(option) async {
if (option != null) {
if (reverse) option = !option;
isServer
? await mainSetBoolOption(key, option)
: await mainSetLocalBoolOption(key, option);
final readOption = isServer
? mainGetBoolOptionSync(key)
: mainGetLocalBoolOptionSync(key);
final setter =
optSetter ?? (isServer ? mainSetBoolOption : mainSetLocalBoolOption);
await setter(key, option);
final readOption = getOpt();
if (reverse) {
ref.value = !readOption;
} else {
ref.value = readOption;
}
update?.call();
update?.call(readOption);
}
}

View File

@@ -16,7 +16,6 @@ import '../../common.dart';
import '../../common/widgets/dialog.dart';
import '../../common/widgets/toolbar.dart';
import '../../models/model.dart';
import '../../models/desktop_render_texture.dart';
import '../../models/platform_model.dart';
import '../../common/shared_state.dart';
import '../../utils/image.dart';
@@ -593,12 +592,11 @@ class _ImagePaintState extends State<ImagePaint> {
onHover: (evt) {},
child: child);
});
if (c.imageOverflow.isTrue && c.scrollStyle == ScrollStyle.scrollbar) {
final paintWidth = c.getDisplayWidth() * s;
final paintHeight = c.getDisplayHeight() * s;
final paintSize = Size(paintWidth, paintHeight);
final paintWidget = useTextureRender
final paintWidget = m.useTextureRender
? _BuildPaintTextureRender(
c, s, Offset.zero, paintSize, isViewOriginal())
: _buildScrollbarNonTextureRender(m, paintSize, s);
@@ -619,7 +617,7 @@ class _ImagePaintState extends State<ImagePaint> {
));
} else {
if (c.size.width > 0 && c.size.height > 0) {
final paintWidget = useTextureRender
final paintWidget = m.useTextureRender
? _BuildPaintTextureRender(
c,
s,

View File

@@ -7,7 +7,6 @@ import 'package:flutter_hbb/common/widgets/audio_input.dart';
import 'package:flutter_hbb/common/widgets/toolbar.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/models/desktop_render_texture.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:flutter_hbb/plugin/widgets/desc_ui.dart';
@@ -615,14 +614,14 @@ class _MonitorMenu extends StatelessWidget {
bind.mainGetUserDefaultOption(key: kKeyShowMonitorsToolbar) == 'Y';
bool get supportIndividualWindows =>
useTextureRender && ffi.ffiModel.pi.isSupportMultiDisplay;
!isWeb && ffi.ffiModel.pi.isSupportMultiDisplay;
@override
Widget build(BuildContext context) => showMonitorsToolbar
? buildMultiMonitorMenu()
: Obx(() => buildMonitorMenu());
? buildMultiMonitorMenu(context)
: Obx(() => buildMonitorMenu(context));
Widget buildMonitorMenu() {
Widget buildMonitorMenu(BuildContext context) {
final width = SimpleWrapper<double>(0);
final monitorsIcon =
globalMonitorsWidget(width, Colors.white, Colors.black38);
@@ -636,20 +635,23 @@ class _MonitorMenu extends StatelessWidget {
menuStyle: MenuStyle(
padding:
MaterialStatePropertyAll(EdgeInsets.symmetric(horizontal: 6))),
menuChildrenGetter: () => [buildMonitorSubmenuWidget()]);
menuChildrenGetter: () => [buildMonitorSubmenuWidget(context)]);
}
Widget buildMultiMonitorMenu() {
return Row(children: buildMonitorList(true));
Widget buildMultiMonitorMenu(BuildContext context) {
return Row(children: buildMonitorList(context, true));
}
Widget buildMonitorSubmenuWidget() {
Widget buildMonitorSubmenuWidget(BuildContext context) {
final m = Provider.of<ImageModel>(context);
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(children: buildMonitorList(false)),
supportIndividualWindows ? Divider() : Offstage(),
supportIndividualWindows ? chooseDisplayBehavior() : Offstage(),
Row(children: buildMonitorList(context, false)),
supportIndividualWindows && m.useTextureRender ? Divider() : Offstage(),
supportIndividualWindows && m.useTextureRender
? chooseDisplayBehavior()
: Offstage(),
],
);
}
@@ -680,7 +682,7 @@ class _MonitorMenu extends StatelessWidget {
),
);
List<Widget> buildMonitorList(bool isMulti) {
List<Widget> buildMonitorList(BuildContext context, bool isMulti) {
final List<Widget> monitorList = [];
final pi = ffi.ffiModel.pi;
@@ -735,7 +737,10 @@ class _MonitorMenu extends StatelessWidget {
for (int i = 0; i < pi.displays.length; i++) {
monitorList.add(buildMonitorButton(i));
}
if (supportIndividualWindows && pi.displays.length > 1) {
final m = Provider.of<ImageModel>(context);
if (supportIndividualWindows &&
m.useTextureRender &&
pi.displays.length > 1) {
monitorList.add(buildMonitorButton(kAllDisplayValue));
}
return monitorList;
@@ -818,7 +823,12 @@ class _MonitorMenu extends StatelessWidget {
}
RxInt display = CurrentDisplayState.find(id);
if (display.value != i) {
if (isChooseDisplayToOpenInNewWindow(pi, ffi.sessionId)) {
final isChooseDisplayToOpenInNewWindow = pi.isSupportMultiDisplay &&
bind.mainGetUseTextureRender() &&
bind.sessionGetDisplaysAsIndividualWindows(
sessionId: ffi.sessionId) ==
'Y';
if (isChooseDisplayToOpenInNewWindow) {
openMonitorInNewTabOrWindow(i, ffi.id, pi);
} else {
openMonitorInTheSameTab(i, ffi, pi, updateCursorPos: !isMulti);