commit
3fc686c3d6
@ -198,7 +198,7 @@ Please ensure that you are running these commands from the root of the RustDesk
|
|||||||
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
|
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
|
||||||
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
|
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
|
||||||
- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: Flutter code for mobile
|
- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: Flutter code for mobile
|
||||||
- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: Javascript for Flutter web client
|
- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: JavaScript for Flutter web client
|
||||||
|
|
||||||
## Snapshot
|
## Snapshot
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ efforts from contributors on the same issue.
|
|||||||
|
|
||||||
- Add tests relevant to the fixed bug or new feature.
|
- Add tests relevant to the fixed bug or new feature.
|
||||||
|
|
||||||
For specific git instructions, see [GitHub workflow 101](https://github.com/servo/servo/wiki/Github-workflow).
|
For specific git instructions, see [GitHub workflow 101](https://github.com/servo/servo/wiki/GitHub-workflow).
|
||||||
|
|
||||||
## Conduct
|
## Conduct
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ An open-source remote desktop application, the open source TeamViewer alternativ
|
|||||||
Source code: https://github.com/rustdesk/rustdesk
|
Source code: https://github.com/rustdesk/rustdesk
|
||||||
Doc: https://rustdesk.com/docs/en/manual/mobile/
|
Doc: https://rustdesk.com/docs/en/manual/mobile/
|
||||||
|
|
||||||
In order for a remote device to control your Android device via mouse or touch, you need to allow RustDesk to use the "Accessibility" service, RustDesk uses AccessibilityService API to implement Addroid remote control.
|
In order for a remote device to control your Android device via mouse or touch, you need to allow RustDesk to use the "Accessibility" service, RustDesk uses AccessibilityService API to implement Android remote control.
|
||||||
|
|
||||||
In addition to remote control, you can also transfer files between Android devices and PCs easily with RustDesk.
|
In addition to remote control, you can also transfer files between Android devices and PCs easily with RustDesk.
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ Future<bool?> loginDialog() async {
|
|||||||
),
|
),
|
||||||
LoginWidgetOP(
|
LoginWidgetOP(
|
||||||
ops: [
|
ops: [
|
||||||
ConfigOP(op: 'Github', iconWidth: 20),
|
ConfigOP(op: 'GitHub', iconWidth: 20),
|
||||||
ConfigOP(op: 'Google', iconWidth: 20),
|
ConfigOP(op: 'Google', iconWidth: 20),
|
||||||
ConfigOP(op: 'Okta', iconWidth: 38),
|
ConfigOP(op: 'Okta', iconWidth: 38),
|
||||||
],
|
],
|
||||||
|
@ -44,7 +44,7 @@ class _ConnectionPageState extends State<ConnectionPage>
|
|||||||
var svcStatusCode = 0.obs;
|
var svcStatusCode = 0.obs;
|
||||||
var svcIsUsingPublicServer = true.obs;
|
var svcIsUsingPublicServer = true.obs;
|
||||||
|
|
||||||
bool isWindowMinisized = false;
|
bool isWindowMinimized = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -80,13 +80,13 @@ class _ConnectionPageState extends State<ConnectionPage>
|
|||||||
void onWindowEvent(String eventName) {
|
void onWindowEvent(String eventName) {
|
||||||
super.onWindowEvent(eventName);
|
super.onWindowEvent(eventName);
|
||||||
if (eventName == 'minimize') {
|
if (eventName == 'minimize') {
|
||||||
isWindowMinisized = true;
|
isWindowMinimized = true;
|
||||||
} else if (eventName == 'maximize' || eventName == 'restore') {
|
} else if (eventName == 'maximize' || eventName == 'restore') {
|
||||||
if (isWindowMinisized && Platform.isWindows) {
|
if (isWindowMinimized && Platform.isWindows) {
|
||||||
// windows can't update when minisized.
|
// windows can't update when minimized.
|
||||||
Get.forceAppUpdate();
|
Get.forceAppUpdate();
|
||||||
}
|
}
|
||||||
isWindowMinisized = false;
|
isWindowMinimized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,7 +1436,7 @@ Widget _lock(
|
|||||||
|
|
||||||
_LabeledTextField(
|
_LabeledTextField(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String lable,
|
String label,
|
||||||
TextEditingController controller,
|
TextEditingController controller,
|
||||||
String errorText,
|
String errorText,
|
||||||
bool enabled,
|
bool enabled,
|
||||||
@ -1447,7 +1447,7 @@ _LabeledTextField(
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Text(
|
child: Text(
|
||||||
'${translate(lable)}:',
|
'${translate(label)}:',
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
style: TextStyle(color: _disabledTextColor(context, enabled)),
|
style: TextStyle(color: _disabledTextColor(context, enabled)),
|
||||||
),
|
),
|
||||||
|
@ -127,8 +127,8 @@ class _PortForwardPageState extends State<PortForwardPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildTunnel(BuildContext context) {
|
buildTunnel(BuildContext context) {
|
||||||
text(String lable) => Expanded(
|
text(String label) => Expanded(
|
||||||
child: Text(translate(lable)).marginOnly(left: _kTextLeftMargin));
|
child: Text(translate(label)).marginOnly(left: _kTextLeftMargin));
|
||||||
|
|
||||||
return Theme(
|
return Theme(
|
||||||
data: Theme.of(context)
|
data: Theme.of(context)
|
||||||
@ -241,8 +241,8 @@ class _PortForwardPageState extends State<PortForwardPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildTunnelDataRow(BuildContext context, _PortForward pf, int index) {
|
Widget buildTunnelDataRow(BuildContext context, _PortForward pf, int index) {
|
||||||
text(String lable) => Expanded(
|
text(String label) => Expanded(
|
||||||
child: Text(lable, style: const TextStyle(fontSize: 20))
|
child: Text(label, style: const TextStyle(fontSize: 20))
|
||||||
.marginOnly(left: _kTextLeftMargin));
|
.marginOnly(left: _kTextLeftMargin));
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
@ -285,11 +285,11 @@ class _PortForwardPageState extends State<PortForwardPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildRdp(BuildContext context) {
|
buildRdp(BuildContext context) {
|
||||||
text1(String lable) => Expanded(
|
text1(String label) => Expanded(
|
||||||
child: Text(translate(lable)).marginOnly(left: _kTextLeftMargin));
|
child: Text(translate(label)).marginOnly(left: _kTextLeftMargin));
|
||||||
text2(String lable) => Expanded(
|
text2(String label) => Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
lable,
|
label,
|
||||||
style: const TextStyle(fontSize: 20),
|
style: const TextStyle(fontSize: 20),
|
||||||
).marginOnly(left: _kTextLeftMargin));
|
).marginOnly(left: _kTextLeftMargin));
|
||||||
return Theme(
|
return Theme(
|
||||||
|
@ -6,7 +6,7 @@ import 'package:flutter_hbb/models/platform_model.dart';
|
|||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
|
|
||||||
typedef KBChoosedCallback = Future<bool> Function(String);
|
typedef KBChosenCallback = Future<bool> Function(String);
|
||||||
|
|
||||||
const double _kImageMarginVertical = 6.0;
|
const double _kImageMarginVertical = 6.0;
|
||||||
const double _kImageMarginHorizontal = 10.0;
|
const double _kImageMarginHorizontal = 10.0;
|
||||||
@ -25,12 +25,12 @@ const _kKBLayoutImageMap = {
|
|||||||
class _KBImage extends StatelessWidget {
|
class _KBImage extends StatelessWidget {
|
||||||
final String kbLayoutType;
|
final String kbLayoutType;
|
||||||
final double imageWidth;
|
final double imageWidth;
|
||||||
final RxString choosedType;
|
final RxString chosenType;
|
||||||
const _KBImage({
|
const _KBImage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.kbLayoutType,
|
required this.kbLayoutType,
|
||||||
required this.imageWidth,
|
required this.imageWidth,
|
||||||
required this.choosedType,
|
required this.chosenType,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -40,7 +40,7 @@ class _KBImage extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(_kBorderRadius),
|
borderRadius: BorderRadius.circular(_kBorderRadius),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: choosedType.value == kbLayoutType
|
color: chosenType.value == kbLayoutType
|
||||||
? _kImageBorderColor
|
? _kImageBorderColor
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
width: _kImageBoarderWidth,
|
width: _kImageBoarderWidth,
|
||||||
@ -66,13 +66,13 @@ class _KBImage extends StatelessWidget {
|
|||||||
class _KBChooser extends StatelessWidget {
|
class _KBChooser extends StatelessWidget {
|
||||||
final String kbLayoutType;
|
final String kbLayoutType;
|
||||||
final double imageWidth;
|
final double imageWidth;
|
||||||
final RxString choosedType;
|
final RxString chosenType;
|
||||||
final KBChoosedCallback cb;
|
final KBChosenCallback cb;
|
||||||
const _KBChooser({
|
const _KBChooser({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.kbLayoutType,
|
required this.kbLayoutType,
|
||||||
required this.imageWidth,
|
required this.imageWidth,
|
||||||
required this.choosedType,
|
required this.chosenType,
|
||||||
required this.cb,
|
required this.cb,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class _KBChooser extends StatelessWidget {
|
|||||||
onChanged(String? v) async {
|
onChanged(String? v) async {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
if (await cb(v)) {
|
if (await cb(v)) {
|
||||||
choosedType.value = v;
|
chosenType.value = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ class _KBChooser extends StatelessWidget {
|
|||||||
child: _KBImage(
|
child: _KBImage(
|
||||||
kbLayoutType: kbLayoutType,
|
kbLayoutType: kbLayoutType,
|
||||||
imageWidth: imageWidth,
|
imageWidth: imageWidth,
|
||||||
choosedType: choosedType,
|
chosenType: chosenType,
|
||||||
),
|
),
|
||||||
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
style: TextButton.styleFrom(padding: EdgeInsets.zero),
|
||||||
),
|
),
|
||||||
@ -105,7 +105,7 @@ class _KBChooser extends StatelessWidget {
|
|||||||
Obx(() => Radio(
|
Obx(() => Radio(
|
||||||
splashRadius: 0,
|
splashRadius: 0,
|
||||||
value: kbLayoutType,
|
value: kbLayoutType,
|
||||||
groupValue: choosedType.value,
|
groupValue: chosenType.value,
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
)),
|
)),
|
||||||
Text(kbLayoutType),
|
Text(kbLayoutType),
|
||||||
@ -121,14 +121,14 @@ class _KBChooser extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KBLayoutTypeChooser extends StatelessWidget {
|
class KBLayoutTypeChooser extends StatelessWidget {
|
||||||
final RxString choosedType;
|
final RxString chosenType;
|
||||||
final double width;
|
final double width;
|
||||||
final double height;
|
final double height;
|
||||||
final double dividerWidth;
|
final double dividerWidth;
|
||||||
final KBChoosedCallback cb;
|
final KBChosenCallback cb;
|
||||||
KBLayoutTypeChooser({
|
KBLayoutTypeChooser({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.choosedType,
|
required this.chosenType,
|
||||||
required this.width,
|
required this.width,
|
||||||
required this.height,
|
required this.height,
|
||||||
required this.dividerWidth,
|
required this.dividerWidth,
|
||||||
@ -147,7 +147,7 @@ class KBLayoutTypeChooser extends StatelessWidget {
|
|||||||
_KBChooser(
|
_KBChooser(
|
||||||
kbLayoutType: _kKBLayoutTypeISO,
|
kbLayoutType: _kKBLayoutTypeISO,
|
||||||
imageWidth: imageWidth,
|
imageWidth: imageWidth,
|
||||||
choosedType: choosedType,
|
chosenType: chosenType,
|
||||||
cb: cb,
|
cb: cb,
|
||||||
),
|
),
|
||||||
VerticalDivider(
|
VerticalDivider(
|
||||||
@ -156,7 +156,7 @@ class KBLayoutTypeChooser extends StatelessWidget {
|
|||||||
_KBChooser(
|
_KBChooser(
|
||||||
kbLayoutType: _kKBLayoutTypeNotISO,
|
kbLayoutType: _kKBLayoutTypeNotISO,
|
||||||
imageWidth: imageWidth,
|
imageWidth: imageWidth,
|
||||||
choosedType: choosedType,
|
chosenType: chosenType,
|
||||||
cb: cb,
|
cb: cb,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -208,7 +208,7 @@ showKBLayoutTypeChooser(
|
|||||||
title:
|
title:
|
||||||
Text('${translate('Select local keyboard type')} ($localPlatform)'),
|
Text('${translate('Select local keyboard type')} ($localPlatform)'),
|
||||||
content: KBLayoutTypeChooser(
|
content: KBLayoutTypeChooser(
|
||||||
choosedType: KBLayoutType,
|
chosenType: KBLayoutType,
|
||||||
width: 360,
|
width: 360,
|
||||||
height: 200,
|
height: 200,
|
||||||
dividerWidth: 4.0,
|
dividerWidth: 4.0,
|
||||||
|
@ -906,7 +906,7 @@ class _TabState extends State<_Tab> with RestorationMixin {
|
|||||||
children: [
|
children: [
|
||||||
_buildTabContent(),
|
_buildTabContent(),
|
||||||
Obx((() => _CloseButton(
|
Obx((() => _CloseButton(
|
||||||
visiable: hover.value && widget.closable,
|
visible: hover.value && widget.closable,
|
||||||
tabSelected: isSelected,
|
tabSelected: isSelected,
|
||||||
onClose: () => widget.onClose(),
|
onClose: () => widget.onClose(),
|
||||||
)))
|
)))
|
||||||
@ -938,13 +938,13 @@ class _TabState extends State<_Tab> with RestorationMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CloseButton extends StatelessWidget {
|
class _CloseButton extends StatelessWidget {
|
||||||
final bool visiable;
|
final bool visible;
|
||||||
final bool tabSelected;
|
final bool tabSelected;
|
||||||
final Function onClose;
|
final Function onClose;
|
||||||
|
|
||||||
const _CloseButton({
|
const _CloseButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.visiable,
|
required this.visible,
|
||||||
required this.tabSelected,
|
required this.tabSelected,
|
||||||
required this.onClose,
|
required this.onClose,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
@ -954,7 +954,7 @@ class _CloseButton extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: _kIconSize,
|
width: _kIconSize,
|
||||||
child: Offstage(
|
child: Offstage(
|
||||||
offstage: !visiable,
|
offstage: !visible,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
customBorder: const RoundedRectangleBorder(),
|
customBorder: const RoundedRectangleBorder(),
|
||||||
onTap: () => onClose(),
|
onTap: () => onClose(),
|
||||||
|
@ -197,7 +197,7 @@ class InputModel {
|
|||||||
// Check update event type and set buttons to be sent.
|
// Check update event type and set buttons to be sent.
|
||||||
int buttons = _lastButtons;
|
int buttons = _lastButtons;
|
||||||
if (type == _kMouseEventMove) {
|
if (type == _kMouseEventMove) {
|
||||||
// flutter may emit move event if one button is pressed and anoter button
|
// flutter may emit move event if one button is pressed and another button
|
||||||
// is pressing or releasing.
|
// is pressing or releasing.
|
||||||
if (evt.buttons != _lastButtons) {
|
if (evt.buttons != _lastButtons) {
|
||||||
// For simplicity
|
// For simplicity
|
||||||
|
@ -9,7 +9,7 @@ set(BINARY_NAME "rustdesk")
|
|||||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||||
set(APPLICATION_ID "com.carriez.flutter_hbb")
|
set(APPLICATION_ID "com.carriez.flutter_hbb")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt into modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ target_link_libraries(flutter INTERFACE
|
|||||||
add_dependencies(flutter flutter_assemble)
|
add_dependencies(flutter flutter_assemble)
|
||||||
|
|
||||||
# === Flutter tool backend ===
|
# === Flutter tool backend ===
|
||||||
# _phony_ is a non-existent file to force this command to run every time,
|
# _phony_ is a nonexistent file to force this command to run every time,
|
||||||
# since currently there's no way to get a full input/output list from the
|
# since currently there's no way to get a full input/output list from the
|
||||||
# flutter tool.
|
# flutter tool.
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -82,10 +82,10 @@ export default class Connection {
|
|||||||
this._ws = ws;
|
this._ws = ws;
|
||||||
this._id = id;
|
this._id = id;
|
||||||
console.log(
|
console.log(
|
||||||
new Date() + ": Conntecting to rendezvoous server: " + uri + ", for " + id
|
new Date() + ": Connecting to rendezvous server: " + uri + ", for " + id
|
||||||
);
|
);
|
||||||
await ws.open();
|
await ws.open();
|
||||||
console.log(new Date() + ": Connected to rendezvoous server");
|
console.log(new Date() + ": Connected to rendezvous server");
|
||||||
const conn_type = rendezvous.ConnType.DEFAULT_CONN;
|
const conn_type = rendezvous.ConnType.DEFAULT_CONN;
|
||||||
const nat_type = rendezvous.NatType.SYMMETRIC;
|
const nat_type = rendezvous.NatType.SYMMETRIC;
|
||||||
const punch_hole_request = rendezvous.PunchHoleRequest.fromPartial({
|
const punch_hole_request = rendezvous.PunchHoleRequest.fromPartial({
|
||||||
|
@ -6,7 +6,7 @@ project(rustdesk LANGUAGES CXX)
|
|||||||
# the on-disk name of your application.
|
# the on-disk name of your application.
|
||||||
set(BINARY_NAME "rustdesk")
|
set(BINARY_NAME "rustdesk")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt into modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ target_include_directories(flutter_wrapper_app PUBLIC
|
|||||||
add_dependencies(flutter_wrapper_app flutter_assemble)
|
add_dependencies(flutter_wrapper_app flutter_assemble)
|
||||||
|
|
||||||
# === Flutter tool backend ===
|
# === Flutter tool backend ===
|
||||||
# _phony_ is a non-existent file to force this command to run every time,
|
# _phony_ is a nonexistent file to force this command to run every time,
|
||||||
# since currently there's no way to get a full input/output list from the
|
# since currently there's no way to get a full input/output list from the
|
||||||
# flutter tool.
|
# flutter tool.
|
||||||
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
|
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
|
||||||
|
@ -43,7 +43,7 @@ class WindowClassRegistrar {
|
|||||||
public:
|
public:
|
||||||
~WindowClassRegistrar() = default;
|
~WindowClassRegistrar() = default;
|
||||||
|
|
||||||
// Returns the singleton registar instance.
|
// Returns the singleton registrar instance.
|
||||||
static WindowClassRegistrar* GetInstance() {
|
static WindowClassRegistrar* GetInstance() {
|
||||||
if (!instance_) {
|
if (!instance_) {
|
||||||
instance_ = new WindowClassRegistrar();
|
instance_ = new WindowClassRegistrar();
|
||||||
|
@ -31,7 +31,7 @@ class Win32Window {
|
|||||||
// Creates and shows a win32 window with |title| and position and size using
|
// Creates and shows a win32 window with |title| and position and size using
|
||||||
// |origin| and |size|. New windows are created on the default monitor. Window
|
// |origin| and |size|. New windows are created on the default monitor. Window
|
||||||
// sizes are specified to the OS in physical pixels, hence to ensure a
|
// sizes are specified to the OS in physical pixels, hence to ensure a
|
||||||
// consistent size to will treat the width height passed in to this function
|
// consistent size to will treat the width height passed into this function
|
||||||
// as logical pixels and scale to appropriate for the default monitor. Returns
|
// as logical pixels and scale to appropriate for the default monitor. Returns
|
||||||
// true if the window was created successfully.
|
// true if the window was created successfully.
|
||||||
bool CreateAndShow(const std::wstring& title,
|
bool CreateAndShow(const std::wstring& title,
|
||||||
@ -77,7 +77,7 @@ class Win32Window {
|
|||||||
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
||||||
// is passed when the non-client area is being created and enables automatic
|
// is passed when the non-client area is being created and enables automatic
|
||||||
// non-client DPI scaling so that the non-client area automatically
|
// non-client DPI scaling so that the non-client area automatically
|
||||||
// responsponds to changes in DPI. All other messages are handled by
|
// responds to changes in DPI. All other messages are handled by
|
||||||
// MessageHandler.
|
// MessageHandler.
|
||||||
static LRESULT CALLBACK WndProc(HWND const window,
|
static LRESULT CALLBACK WndProc(HWND const window,
|
||||||
UINT const message,
|
UINT const message,
|
||||||
|
@ -21,7 +21,7 @@ pub use context_send::*;
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[serde(tag = "t", content = "c")]
|
#[serde(tag = "t", content = "c")]
|
||||||
pub enum ClipbaordFile {
|
pub enum ClipboardFile {
|
||||||
MonitorReady,
|
MonitorReady,
|
||||||
FormatList {
|
FormatList {
|
||||||
format_list: Vec<(i32, String)>,
|
format_list: Vec<(i32, String)>,
|
||||||
@ -61,8 +61,8 @@ struct ConnEnabled {
|
|||||||
struct MsgChannel {
|
struct MsgChannel {
|
||||||
peer_id: String,
|
peer_id: String,
|
||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
sender: UnboundedSender<ClipbaordFile>,
|
sender: UnboundedSender<ClipboardFile>,
|
||||||
receiver: Arc<TokioMutex<UnboundedReceiver<ClipbaordFile>>>,
|
receiver: Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
@ -89,7 +89,7 @@ pub fn get_client_conn_id(peer_id: &str) -> Option<i32> {
|
|||||||
|
|
||||||
pub fn get_rx_cliprdr_client(
|
pub fn get_rx_cliprdr_client(
|
||||||
peer_id: &str,
|
peer_id: &str,
|
||||||
) -> (i32, Arc<TokioMutex<UnboundedReceiver<ClipbaordFile>>>) {
|
) -> (i32, Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>>) {
|
||||||
let mut lock = VEC_MSG_CHANNEL.write().unwrap();
|
let mut lock = VEC_MSG_CHANNEL.write().unwrap();
|
||||||
match lock.iter().find(|x| x.peer_id == peer_id.to_owned()) {
|
match lock.iter().find(|x| x.peer_id == peer_id.to_owned()) {
|
||||||
Some(msg_channel) => (msg_channel.conn_id, msg_channel.receiver.clone()),
|
Some(msg_channel) => (msg_channel.conn_id, msg_channel.receiver.clone()),
|
||||||
@ -110,7 +110,7 @@ pub fn get_rx_cliprdr_client(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rx_cliprdr_server(conn_id: i32) -> Arc<TokioMutex<UnboundedReceiver<ClipbaordFile>>> {
|
pub fn get_rx_cliprdr_server(conn_id: i32) -> Arc<TokioMutex<UnboundedReceiver<ClipboardFile>>> {
|
||||||
let mut lock = VEC_MSG_CHANNEL.write().unwrap();
|
let mut lock = VEC_MSG_CHANNEL.write().unwrap();
|
||||||
match lock.iter().find(|x| x.conn_id == conn_id) {
|
match lock.iter().find(|x| x.conn_id == conn_id) {
|
||||||
Some(msg_channel) => msg_channel.receiver.clone(),
|
Some(msg_channel) => msg_channel.receiver.clone(),
|
||||||
@ -131,7 +131,7 @@ pub fn get_rx_cliprdr_server(conn_id: i32) -> Arc<TokioMutex<UnboundedReceiver<C
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn send_data(conn_id: i32, data: ClipbaordFile) {
|
fn send_data(conn_id: i32, data: ClipboardFile) {
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
if let Some(msg_channel) = VEC_MSG_CHANNEL
|
if let Some(msg_channel) = VEC_MSG_CHANNEL
|
||||||
.read()
|
.read()
|
||||||
@ -157,28 +157,28 @@ pub fn empty_clipboard(context: &mut Box<CliprdrClientContext>, conn_id: i32) ->
|
|||||||
pub fn server_clip_file(
|
pub fn server_clip_file(
|
||||||
context: &mut Box<CliprdrClientContext>,
|
context: &mut Box<CliprdrClientContext>,
|
||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
msg: ClipbaordFile,
|
msg: ClipboardFile,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
match msg {
|
match msg {
|
||||||
ClipbaordFile::MonitorReady => {
|
ClipboardFile::MonitorReady => {
|
||||||
log::debug!("server_monitor_ready called");
|
log::debug!("server_monitor_ready called");
|
||||||
let ret = server_monitor_ready(context, conn_id);
|
let ret = server_monitor_ready(context, conn_id);
|
||||||
log::debug!("server_monitor_ready called, return {}", ret);
|
log::debug!("server_monitor_ready called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FormatList { format_list } => {
|
ClipboardFile::FormatList { format_list } => {
|
||||||
log::debug!("server_format_list called");
|
log::debug!("server_format_list called");
|
||||||
let ret = server_format_list(context, conn_id, format_list);
|
let ret = server_format_list(context, conn_id, format_list);
|
||||||
log::debug!("server_format_list called, return {}", ret);
|
log::debug!("server_format_list called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FormatListResponse { msg_flags } => {
|
ClipboardFile::FormatListResponse { msg_flags } => {
|
||||||
log::debug!("format_list_response called");
|
log::debug!("format_list_response called");
|
||||||
let ret = server_format_list_response(context, conn_id, msg_flags);
|
let ret = server_format_list_response(context, conn_id, msg_flags);
|
||||||
log::debug!("server_format_list_response called, return {}", ret);
|
log::debug!("server_format_list_response called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FormatDataRequest {
|
ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id,
|
requested_format_id,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("format_data_request called");
|
log::debug!("format_data_request called");
|
||||||
@ -186,7 +186,7 @@ pub fn server_clip_file(
|
|||||||
log::debug!("server_format_data_request called, return {}", ret);
|
log::debug!("server_format_data_request called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FormatDataResponse {
|
ClipboardFile::FormatDataResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
format_data,
|
format_data,
|
||||||
} => {
|
} => {
|
||||||
@ -195,7 +195,7 @@ pub fn server_clip_file(
|
|||||||
log::debug!("server_format_data_response called, return {}", ret);
|
log::debug!("server_format_data_response called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FileContentsRequest {
|
ClipboardFile::FileContentsRequest {
|
||||||
stream_id,
|
stream_id,
|
||||||
list_index,
|
list_index,
|
||||||
dw_flags,
|
dw_flags,
|
||||||
@ -221,7 +221,7 @@ pub fn server_clip_file(
|
|||||||
log::debug!("server_file_contents_request called, return {}", ret);
|
log::debug!("server_file_contents_request called, return {}", ret);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
ClipbaordFile::FileContentsResponse {
|
ClipboardFile::FileContentsResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
@ -492,7 +492,7 @@ extern "C" fn client_format_list(
|
|||||||
}
|
}
|
||||||
conn_id = (*clip_format_list).connID as i32;
|
conn_id = (*clip_format_list).connID as i32;
|
||||||
}
|
}
|
||||||
let data = ClipbaordFile::FormatList { format_list };
|
let data = ClipboardFile::FormatList { format_list };
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
if conn_id == 0 {
|
if conn_id == 0 {
|
||||||
VEC_MSG_CHANNEL
|
VEC_MSG_CHANNEL
|
||||||
@ -519,7 +519,7 @@ extern "C" fn client_format_list_response(
|
|||||||
conn_id = (*format_list_response).connID as i32;
|
conn_id = (*format_list_response).connID as i32;
|
||||||
msg_flags = (*format_list_response).msgFlags as i32;
|
msg_flags = (*format_list_response).msgFlags as i32;
|
||||||
}
|
}
|
||||||
let data = ClipbaordFile::FormatListResponse { msg_flags };
|
let data = ClipboardFile::FormatListResponse { msg_flags };
|
||||||
send_data(conn_id, data);
|
send_data(conn_id, data);
|
||||||
|
|
||||||
0
|
0
|
||||||
@ -537,7 +537,7 @@ extern "C" fn client_format_data_request(
|
|||||||
conn_id = (*format_data_request).connID as i32;
|
conn_id = (*format_data_request).connID as i32;
|
||||||
requested_format_id = (*format_data_request).requestedFormatId as i32;
|
requested_format_id = (*format_data_request).requestedFormatId as i32;
|
||||||
}
|
}
|
||||||
let data = ClipbaordFile::FormatDataRequest {
|
let data = ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id,
|
requested_format_id,
|
||||||
};
|
};
|
||||||
// no need to handle result here
|
// no need to handle result here
|
||||||
@ -568,7 +568,7 @@ extern "C" fn client_format_data_response(
|
|||||||
.to_vec();
|
.to_vec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let data = ClipbaordFile::FormatDataResponse {
|
let data = ClipboardFile::FormatDataResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
format_data,
|
format_data,
|
||||||
};
|
};
|
||||||
@ -614,7 +614,7 @@ extern "C" fn client_file_contents_request(
|
|||||||
clip_data_id = (*file_contents_request).clipDataId as i32;
|
clip_data_id = (*file_contents_request).clipDataId as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = ClipbaordFile::FileContentsRequest {
|
let data = ClipboardFile::FileContentsRequest {
|
||||||
stream_id,
|
stream_id,
|
||||||
list_index,
|
list_index,
|
||||||
dw_flags,
|
dw_flags,
|
||||||
@ -653,7 +653,7 @@ extern "C" fn client_file_contents_response(
|
|||||||
.to_vec();
|
.to_vec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let data = ClipbaordFile::FileContentsResponse {
|
let data = ClipboardFile::FileContentsResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
|
@ -795,11 +795,11 @@ static HRESULT STDMETHODCALLTYPE CliprdrDataObject_QueryGetData(IDataObject *Thi
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject *This,
|
static HRESULT STDMETHODCALLTYPE CliprdrDataObject_GetCanonicalFormatEtc(IDataObject *This,
|
||||||
FORMATETC *pformatectIn,
|
FORMATETC *pformatetcIn,
|
||||||
FORMATETC *pformatetcOut)
|
FORMATETC *pformatetcOut)
|
||||||
{
|
{
|
||||||
(void)This;
|
(void)This;
|
||||||
(void)pformatectIn;
|
(void)pformatetcIn;
|
||||||
|
|
||||||
if (!pformatetcOut)
|
if (!pformatetcOut)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# Appveyor configuration template for Rust using rustup for Rust installation
|
# AppVeyor configuration template for Rust using rustup for Rust installation
|
||||||
# https://github.com/starkat99/appveyor-rust
|
# https://github.com/starkat99/appveyor-rust
|
||||||
|
|
||||||
## Operating System (VM environment) ##
|
## Operating System (VM environment) ##
|
||||||
|
|
||||||
# Rust needs at least Visual Studio 2013 Appveyor OS for MSVC targets.
|
# Rust needs at least Visual Studio 2013 AppVeyor OS for MSVC targets.
|
||||||
os: Visual Studio 2015
|
os: Visual Studio 2015
|
||||||
|
|
||||||
## Build Matrix ##
|
## Build Matrix ##
|
||||||
@ -83,7 +83,7 @@ environment:
|
|||||||
|
|
||||||
### Allowed failures ###
|
### Allowed failures ###
|
||||||
|
|
||||||
# See Appveyor documentation for specific details. In short, place any channel or targets you wish
|
# See AppVeyor documentation for specific details. In short, place any channel or targets you wish
|
||||||
# to allow build failures on (usually nightly at least is a wise choice). This will prevent a build
|
# to allow build failures on (usually nightly at least is a wise choice). This will prevent a build
|
||||||
# or test failure in the matching channels/targets from failing the entire build.
|
# or test failure in the matching channels/targets from failing the entire build.
|
||||||
matrix:
|
matrix:
|
||||||
@ -95,7 +95,7 @@ matrix:
|
|||||||
|
|
||||||
## Install Script ##
|
## Install Script ##
|
||||||
|
|
||||||
# This is the most important part of the Appveyor configuration. This installs the version of Rust
|
# This is the most important part of the AppVeyor configuration. This installs the version of Rust
|
||||||
# specified by the 'channel' and 'target' environment variables from the build matrix. This uses
|
# specified by the 'channel' and 'target' environment variables from the build matrix. This uses
|
||||||
# rustup to install Rust.
|
# rustup to install Rust.
|
||||||
#
|
#
|
||||||
@ -110,7 +110,7 @@ install:
|
|||||||
|
|
||||||
## Build Script ##
|
## Build Script ##
|
||||||
|
|
||||||
# 'cargo test' takes care of building for us, so disable Appveyor's build stage. This prevents
|
# 'cargo test' takes care of building for us, so disable AppVeyor's build stage. This prevents
|
||||||
# the "directory does not contain a project or solution file" error.
|
# the "directory does not contain a project or solution file" error.
|
||||||
build: false
|
build: false
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
//! or any other "special" key on the Linux, macOS and Windows operating system.
|
//! or any other "special" key on the Linux, macOS and Windows operating system.
|
||||||
//!
|
//!
|
||||||
//! Possible use cases could be for testing user interfaces on different
|
//! Possible use cases could be for testing user interfaces on different
|
||||||
//! plattforms,
|
//! platforms,
|
||||||
//! building remote control applications or just automating tasks for user
|
//! building remote control applications or just automating tasks for user
|
||||||
//! interfaces unaccessible by a public API or scripting language.
|
//! interfaces unaccessible by a public API or scripting language.
|
||||||
//!
|
//!
|
||||||
@ -206,7 +206,7 @@ pub trait MouseControllable {
|
|||||||
|
|
||||||
/// Click a mouse button
|
/// Click a mouse button
|
||||||
///
|
///
|
||||||
/// it's esentially just a consecutive invokation of
|
/// it's essentially just a consecutive invocation of
|
||||||
/// [mouse_down](trait.MouseControllable.html#tymethod.mouse_down) followed
|
/// [mouse_down](trait.MouseControllable.html#tymethod.mouse_down) followed
|
||||||
/// by a [mouse_up](trait.MouseControllable.html#tymethod.mouse_up). Just
|
/// by a [mouse_up](trait.MouseControllable.html#tymethod.mouse_up). Just
|
||||||
/// for
|
/// for
|
||||||
@ -468,7 +468,7 @@ pub trait KeyboardControllable {
|
|||||||
/// Emits keystrokes such that the given string is inputted.
|
/// Emits keystrokes such that the given string is inputted.
|
||||||
///
|
///
|
||||||
/// You can use many unicode here like: ❤️. This works
|
/// You can use many unicode here like: ❤️. This works
|
||||||
/// regadless of the current keyboardlayout.
|
/// regardless of the current keyboardlayout.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -13,7 +13,7 @@ pub struct Enigo {
|
|||||||
is_x11: bool,
|
is_x11: bool,
|
||||||
tfc: Option<TFC_Context>,
|
tfc: Option<TFC_Context>,
|
||||||
custom_keyboard: Option<CustomKeyboard>,
|
custom_keyboard: Option<CustomKeyboard>,
|
||||||
cutsom_mouse: Option<CustomMouce>,
|
custom_mouse: Option<CustomMouce>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Enigo {
|
impl Enigo {
|
||||||
@ -21,7 +21,7 @@ impl Enigo {
|
|||||||
pub fn delay(&self) -> u64 {
|
pub fn delay(&self) -> u64 {
|
||||||
self.xdo.delay()
|
self.xdo.delay()
|
||||||
}
|
}
|
||||||
/// Set delay of xdo implemetation.
|
/// Set delay of xdo implementation.
|
||||||
pub fn set_delay(&mut self, delay: u64) {
|
pub fn set_delay(&mut self, delay: u64) {
|
||||||
self.xdo.set_delay(delay)
|
self.xdo.set_delay(delay)
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ impl Enigo {
|
|||||||
}
|
}
|
||||||
/// Set custom mouse.
|
/// Set custom mouse.
|
||||||
pub fn set_custom_mouse(&mut self, custom_mouse: CustomMouce) {
|
pub fn set_custom_mouse(&mut self, custom_mouse: CustomMouce) {
|
||||||
self.cutsom_mouse = Some(custom_mouse)
|
self.custom_mouse = Some(custom_mouse)
|
||||||
}
|
}
|
||||||
/// Get custom keyboard.
|
/// Get custom keyboard.
|
||||||
pub fn get_custom_keyboard(&mut self) -> &mut Option<CustomKeyboard> {
|
pub fn get_custom_keyboard(&mut self) -> &mut Option<CustomKeyboard> {
|
||||||
@ -39,7 +39,7 @@ impl Enigo {
|
|||||||
}
|
}
|
||||||
/// Get custom mouse.
|
/// Get custom mouse.
|
||||||
pub fn get_custom_mouse(&mut self) -> &mut Option<CustomMouce> {
|
pub fn get_custom_mouse(&mut self) -> &mut Option<CustomMouce> {
|
||||||
&mut self.cutsom_mouse
|
&mut self.custom_mouse
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tfc_key_down_or_up(&mut self, key: Key, down: bool, up: bool) -> bool {
|
fn tfc_key_down_or_up(&mut self, key: Key, down: bool, up: bool) -> bool {
|
||||||
@ -99,7 +99,7 @@ impl Default for Enigo {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
custom_keyboard: None,
|
custom_keyboard: None,
|
||||||
cutsom_mouse: None,
|
custom_mouse: None,
|
||||||
xdo: EnigoXdo::default(),
|
xdo: EnigoXdo::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_move_to(x, y);
|
self.xdo.mouse_move_to(x, y);
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_move_to(x, y)
|
mouse.mouse_move_to(x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_move_relative(x, y);
|
self.xdo.mouse_move_relative(x, y);
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_move_relative(x, y)
|
mouse.mouse_move_relative(x, y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_down(button)
|
self.xdo.mouse_down(button)
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_down(button)
|
mouse.mouse_down(button)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -147,7 +147,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_up(button)
|
self.xdo.mouse_up(button)
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_up(button)
|
mouse.mouse_up(button)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_click(button)
|
self.xdo.mouse_click(button)
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_click(button)
|
mouse.mouse_click(button)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_scroll_x(length)
|
self.xdo.mouse_scroll_x(length)
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_scroll_x(length)
|
mouse.mouse_scroll_x(length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ impl MouseControllable for Enigo {
|
|||||||
if self.is_x11 {
|
if self.is_x11 {
|
||||||
self.xdo.mouse_scroll_y(length)
|
self.xdo.mouse_scroll_y(length)
|
||||||
} else {
|
} else {
|
||||||
if let Some(mouse) = &mut self.cutsom_mouse {
|
if let Some(mouse) = &mut self.custom_mouse {
|
||||||
mouse.mouse_scroll_y(length)
|
mouse.mouse_scroll_y(length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ enum ImageQuality {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message VideoCodecState {
|
message VideoCodecState {
|
||||||
enum PerferCodec {
|
enum PreferCodec {
|
||||||
Auto = 0;
|
Auto = 0;
|
||||||
VPX = 1;
|
VPX = 1;
|
||||||
H264 = 2;
|
H264 = 2;
|
||||||
@ -455,7 +455,7 @@ message VideoCodecState {
|
|||||||
int32 score_vpx = 1;
|
int32 score_vpx = 1;
|
||||||
int32 score_h264 = 2;
|
int32 score_h264 = 2;
|
||||||
int32 score_h265 = 3;
|
int32 score_h265 = 3;
|
||||||
PerferCodec perfer = 4;
|
PreferCodec prefer = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message OptionMessage {
|
message OptionMessage {
|
||||||
@ -503,7 +503,7 @@ message AudioFrame {
|
|||||||
|
|
||||||
// Notify peer to show message box.
|
// Notify peer to show message box.
|
||||||
message MessageBox {
|
message MessageBox {
|
||||||
// Message type. Refer to flutter/lib/commom.dart/msgBox().
|
// Message type. Refer to flutter/lib/common.dart/msgBox().
|
||||||
string msgtype = 1;
|
string msgtype = 1;
|
||||||
string title = 2;
|
string title = 2;
|
||||||
// English
|
// English
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use crate::ResultType;
|
use crate::ResultType;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref DISTRO: Disto = Disto::new();
|
pub static ref DISTRO: Distro = Distro::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Disto {
|
pub struct Distro {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub version_id: String,
|
pub version_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Disto {
|
impl Distro {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
|
let name = run_cmds("awk -F'=' '/^NAME=/ {print $2}' /etc/os-release".to_owned())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
@ -74,7 +74,7 @@ impl BinaryReader {
|
|||||||
assert!(BIN_DATA.len() > IDENTIFIER_LENGTH, "bin data invalid!");
|
assert!(BIN_DATA.len() > IDENTIFIER_LENGTH, "bin data invalid!");
|
||||||
let mut iden = String::from_utf8_lossy(&BIN_DATA[base..base + IDENTIFIER_LENGTH]);
|
let mut iden = String::from_utf8_lossy(&BIN_DATA[base..base + IDENTIFIER_LENGTH]);
|
||||||
if iden != "rustdesk" {
|
if iden != "rustdesk" {
|
||||||
panic!("bin file is not vaild!");
|
panic!("bin file is not valid!");
|
||||||
}
|
}
|
||||||
base += IDENTIFIER_LENGTH;
|
base += IDENTIFIER_LENGTH;
|
||||||
loop {
|
loop {
|
||||||
|
@ -23,7 +23,7 @@ use hbb_common::{
|
|||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
config::{Config2, PeerConfig},
|
config::{Config2, PeerConfig},
|
||||||
lazy_static,
|
lazy_static,
|
||||||
message_proto::video_codec_state::PerferCodec,
|
message_proto::video_codec_state::PreferCodec,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
@ -149,29 +149,29 @@ impl Encoder {
|
|||||||
&& states.iter().all(|(_, s)| s.score_h265 > 0);
|
&& states.iter().all(|(_, s)| s.score_h265 > 0);
|
||||||
|
|
||||||
// Preference first
|
// Preference first
|
||||||
let mut preference = PerferCodec::Auto;
|
let mut preference = PreferCodec::Auto;
|
||||||
let preferences: Vec<_> = states
|
let preferences: Vec<_> = states
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, s)| {
|
.filter(|(_, s)| {
|
||||||
s.perfer == PerferCodec::VPX.into()
|
s.prefer == PreferCodec::VPX.into()
|
||||||
|| s.perfer == PerferCodec::H264.into() && enabled_h264
|
|| s.prefer == PreferCodec::H264.into() && enabled_h264
|
||||||
|| s.perfer == PerferCodec::H265.into() && enabled_h265
|
|| s.prefer == PreferCodec::H265.into() && enabled_h265
|
||||||
})
|
})
|
||||||
.map(|(_, s)| s.perfer)
|
.map(|(_, s)| s.prefer)
|
||||||
.collect();
|
.collect();
|
||||||
if preferences.len() > 0 && preferences.iter().all(|&p| p == preferences[0]) {
|
if preferences.len() > 0 && preferences.iter().all(|&p| p == preferences[0]) {
|
||||||
preference = preferences[0].enum_value_or(PerferCodec::Auto);
|
preference = preferences[0].enum_value_or(PreferCodec::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
match preference {
|
match preference {
|
||||||
PerferCodec::VPX => *name.lock().unwrap() = None,
|
PreferCodec::VPX => *name.lock().unwrap() = None,
|
||||||
PerferCodec::H264 => {
|
PreferCodec::H264 => {
|
||||||
*name.lock().unwrap() = best.h264.map_or(None, |c| Some(c.name))
|
*name.lock().unwrap() = best.h264.map_or(None, |c| Some(c.name))
|
||||||
}
|
}
|
||||||
PerferCodec::H265 => {
|
PreferCodec::H265 => {
|
||||||
*name.lock().unwrap() = best.h265.map_or(None, |c| Some(c.name))
|
*name.lock().unwrap() = best.h265.map_or(None, |c| Some(c.name))
|
||||||
}
|
}
|
||||||
PerferCodec::Auto => {
|
PreferCodec::Auto => {
|
||||||
// score encoder
|
// score encoder
|
||||||
let mut score_vpx = SCORE_VPX;
|
let mut score_vpx = SCORE_VPX;
|
||||||
let mut score_h264 = best.h264.as_ref().map_or(0, |c| c.score);
|
let mut score_h264 = best.h264.as_ref().map_or(0, |c| c.score);
|
||||||
@ -252,7 +252,7 @@ impl Decoder {
|
|||||||
score_vpx: SCORE_VPX,
|
score_vpx: SCORE_VPX,
|
||||||
score_h264: best.h264.map_or(0, |c| c.score),
|
score_h264: best.h264.map_or(0, |c| c.score),
|
||||||
score_h265: best.h265.map_or(0, |c| c.score),
|
score_h265: best.h265.map_or(0, |c| c.score),
|
||||||
perfer: Self::codec_preference(_id).into(),
|
prefer: Self::codec_preference(_id).into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -272,7 +272,7 @@ impl Decoder {
|
|||||||
score_vpx: SCORE_VPX,
|
score_vpx: SCORE_VPX,
|
||||||
score_h264,
|
score_h264,
|
||||||
score_h265,
|
score_h265,
|
||||||
perfer: Self::codec_preference(_id).into(),
|
prefer: Self::codec_preference(_id).into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -405,19 +405,19 @@ impl Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "hwcodec", feature = "mediacodec"))]
|
#[cfg(any(feature = "hwcodec", feature = "mediacodec"))]
|
||||||
fn codec_preference(id: &str) -> PerferCodec {
|
fn codec_preference(id: &str) -> PreferCodec {
|
||||||
let codec = PeerConfig::load(id)
|
let codec = PeerConfig::load(id)
|
||||||
.options
|
.options
|
||||||
.get("codec-preference")
|
.get("codec-preference")
|
||||||
.map_or("".to_owned(), |c| c.to_owned());
|
.map_or("".to_owned(), |c| c.to_owned());
|
||||||
if codec == "vp9" {
|
if codec == "vp9" {
|
||||||
PerferCodec::VPX
|
PreferCodec::VPX
|
||||||
} else if codec == "h264" {
|
} else if codec == "h264" {
|
||||||
PerferCodec::H264
|
PreferCodec::H264
|
||||||
} else if codec == "h265" {
|
} else if codec == "h265" {
|
||||||
PerferCodec::H265
|
PreferCodec::H265
|
||||||
} else {
|
} else {
|
||||||
PerferCodec::Auto
|
PreferCodec::Auto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ use hwcodec::{
|
|||||||
ffmpeg::{CodecInfo, CodecInfos, DataFormat},
|
ffmpeg::{CodecInfo, CodecInfos, DataFormat},
|
||||||
AVPixelFormat,
|
AVPixelFormat,
|
||||||
Quality::{self, *},
|
Quality::{self, *},
|
||||||
RateContorl::{self, *},
|
RateControl::{self, *},
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_YUV420P;
|
|||||||
pub const DEFAULT_TIME_BASE: [i32; 2] = [1, 30];
|
pub const DEFAULT_TIME_BASE: [i32; 2] = [1, 30];
|
||||||
const DEFAULT_GOP: i32 = 60;
|
const DEFAULT_GOP: i32 = 60;
|
||||||
const DEFAULT_HW_QUALITY: Quality = Quality_Default;
|
const DEFAULT_HW_QUALITY: Quality = Quality_Default;
|
||||||
const DEFAULT_RC: RateContorl = RC_DEFAULT;
|
const DEFAULT_RC: RateControl = RC_DEFAULT;
|
||||||
|
|
||||||
pub struct HwEncoder {
|
pub struct HwEncoder {
|
||||||
encoder: Encoder,
|
encoder: Encoder,
|
||||||
@ -293,8 +293,8 @@ pub fn check_config() {
|
|||||||
quality: DEFAULT_HW_QUALITY,
|
quality: DEFAULT_HW_QUALITY,
|
||||||
rc: DEFAULT_RC,
|
rc: DEFAULT_RC,
|
||||||
};
|
};
|
||||||
let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx));
|
let encoders = CodecInfo::score(Encoder::available_encoders(ctx));
|
||||||
let decoders = CodecInfo::score(Decoder::avaliable_decoders());
|
let decoders = CodecInfo::score(Decoder::available_decoders());
|
||||||
|
|
||||||
if let Ok(old_encoders) = get_config(CFG_KEY_ENCODER) {
|
if let Ok(old_encoders) = get_config(CFG_KEY_ENCODER) {
|
||||||
if let Ok(old_decoders) = get_config(CFG_KEY_DECODER) {
|
if let Ok(old_decoders) = get_config(CFG_KEY_DECODER) {
|
||||||
|
@ -262,7 +262,7 @@ impl Capturer {
|
|||||||
_ => {
|
_ => {
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"Unknown roration".to_string(),
|
"Unknown rotation".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -134,7 +134,7 @@ const char* GetLastMsg();
|
|||||||
*
|
*
|
||||||
* @param b [in] TRUE to enable printing message.
|
* @param b [in] TRUE to enable printing message.
|
||||||
*
|
*
|
||||||
* @remark For now, no need to read evironment variable to check if should print.
|
* @remark For now, no need to read environment variable to check if should print.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
VOID SetPrintErrMsg(BOOL b);
|
VOID SetPrintErrMsg(BOOL b);
|
||||||
|
@ -45,7 +45,7 @@ def expand():
|
|||||||
if line_strip.startswith('("'):
|
if line_strip.startswith('("'):
|
||||||
k, v = line_split(line_strip)
|
k, v = line_split(line_strip)
|
||||||
if k in dict:
|
if k in dict:
|
||||||
# embrased with " to avoid empty v
|
# embraced with " to avoid empty v
|
||||||
line = line.replace('"%s"'%v, '"%s"'%dict[k])
|
line = line.replace('"%s"'%v, '"%s"'%dict[k])
|
||||||
else:
|
else:
|
||||||
line = line.replace(v, "")
|
line = line.replace(v, "")
|
||||||
|
@ -825,7 +825,7 @@ impl VideoHandler {
|
|||||||
/// Handle a new video frame.
|
/// Handle a new video frame.
|
||||||
pub fn handle_frame(&mut self, vf: VideoFrame) -> ResultType<bool> {
|
pub fn handle_frame(&mut self, vf: VideoFrame) -> ResultType<bool> {
|
||||||
if vf.timestamp != 0 {
|
if vf.timestamp != 0 {
|
||||||
// Update the lantency controller with the latest timestamp.
|
// Update the latency controller with the latest timestamp.
|
||||||
self.latency_controller
|
self.latency_controller
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -1662,7 +1662,7 @@ pub fn send_mouse(
|
|||||||
interface.send(Data::Message(msg_out));
|
interface.send(Data::Message(msg_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Avtivate OS by sending mouse movement.
|
/// Activate OS by sending mouse movement.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
@ -1690,7 +1690,7 @@ fn activate_os(interface: &impl Interface) {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `p` - The password.
|
/// * `p` - The password.
|
||||||
/// * `avtivate` - Whether to activate OS.
|
/// * `activate` - Whether to activate OS.
|
||||||
/// * `interface` - The interface for sending data.
|
/// * `interface` - The interface for sending data.
|
||||||
pub fn input_os_password(p: String, activate: bool, interface: impl Interface) {
|
pub fn input_os_password(p: String, activate: bool, interface: impl Interface) {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
@ -1703,7 +1703,7 @@ pub fn input_os_password(p: String, activate: bool, interface: impl Interface) {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `p` - The password.
|
/// * `p` - The password.
|
||||||
/// * `avtivate` - Whether to activate OS.
|
/// * `activate` - Whether to activate OS.
|
||||||
/// * `interface` - The interface for sending data.
|
/// * `interface` - The interface for sending data.
|
||||||
fn _input_os_password(p: String, activate: bool, interface: impl Interface) {
|
fn _input_os_password(p: String, activate: bool, interface: impl Interface) {
|
||||||
if activate {
|
if activate {
|
||||||
|
@ -15,7 +15,7 @@ const MIN_LATENCY: i64 = 100;
|
|||||||
/// Only sync the audio to video, not the other way around.
|
/// Only sync the audio to video, not the other way around.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LatencyController {
|
pub struct LatencyController {
|
||||||
last_video_remote_ts: i64, // generated on remote deivce
|
last_video_remote_ts: i64, // generated on remote device
|
||||||
update_time: Instant,
|
update_time: Instant,
|
||||||
allow_audio: bool,
|
allow_audio: bool,
|
||||||
}
|
}
|
||||||
|
@ -728,11 +728,11 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
self.handler.adapt_size();
|
self.handler.adapt_size();
|
||||||
self.send_opts_after_login(peer).await;
|
self.send_opts_after_login(peer).await;
|
||||||
}
|
}
|
||||||
let incomming_format = CodecFormat::from(&vf);
|
let incoming_format = CodecFormat::from(&vf);
|
||||||
if self.video_format != incomming_format {
|
if self.video_format != incoming_format {
|
||||||
self.video_format = incomming_format.clone();
|
self.video_format = incoming_format.clone();
|
||||||
self.handler.update_quality_status(QualityStatus {
|
self.handler.update_quality_status(QualityStatus {
|
||||||
codec_format: Some(incomming_format),
|
codec_format: Some(incoming_format),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -915,7 +915,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("error recving digest: {}", err);
|
println!("error receiving digest: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use clipboard::ClipbaordFile;
|
use clipboard::ClipboardFile;
|
||||||
use hbb_common::message_proto::*;
|
use hbb_common::message_proto::*;
|
||||||
|
|
||||||
pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
pub fn clip_2_msg(clip: ClipboardFile) -> Message {
|
||||||
match clip {
|
match clip {
|
||||||
ClipbaordFile::MonitorReady => Message {
|
ClipboardFile::MonitorReady => Message {
|
||||||
union: Some(message::Union::Cliprdr(Cliprdr {
|
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||||
union: Some(cliprdr::Union::Ready(CliprdrMonitorReady {
|
union: Some(cliprdr::Union::Ready(CliprdrMonitorReady {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -12,7 +12,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ClipbaordFile::FormatList { format_list } => {
|
ClipboardFile::FormatList { format_list } => {
|
||||||
let mut formats: Vec<CliprdrFormat> = Vec::new();
|
let mut formats: Vec<CliprdrFormat> = Vec::new();
|
||||||
for v in format_list.iter() {
|
for v in format_list.iter() {
|
||||||
formats.push(CliprdrFormat {
|
formats.push(CliprdrFormat {
|
||||||
@ -32,7 +32,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClipbaordFile::FormatListResponse { msg_flags } => Message {
|
ClipboardFile::FormatListResponse { msg_flags } => Message {
|
||||||
union: Some(message::Union::Cliprdr(Cliprdr {
|
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||||
union: Some(cliprdr::Union::FormatListResponse(
|
union: Some(cliprdr::Union::FormatListResponse(
|
||||||
CliprdrServerFormatListResponse {
|
CliprdrServerFormatListResponse {
|
||||||
@ -44,7 +44,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ClipbaordFile::FormatDataRequest {
|
ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id,
|
requested_format_id,
|
||||||
} => Message {
|
} => Message {
|
||||||
union: Some(message::Union::Cliprdr(Cliprdr {
|
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||||
@ -58,7 +58,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ClipbaordFile::FormatDataResponse {
|
ClipboardFile::FormatDataResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
format_data,
|
format_data,
|
||||||
} => Message {
|
} => Message {
|
||||||
@ -74,7 +74,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ClipbaordFile::FileContentsRequest {
|
ClipboardFile::FileContentsRequest {
|
||||||
stream_id,
|
stream_id,
|
||||||
list_index,
|
list_index,
|
||||||
dw_flags,
|
dw_flags,
|
||||||
@ -102,7 +102,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
ClipbaordFile::FileContentsResponse {
|
ClipboardFile::FileContentsResponse {
|
||||||
msg_flags,
|
msg_flags,
|
||||||
stream_id,
|
stream_id,
|
||||||
requested_data,
|
requested_data,
|
||||||
@ -123,28 +123,28 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn msg_2_clip(msg: Cliprdr) -> Option<ClipbaordFile> {
|
pub fn msg_2_clip(msg: Cliprdr) -> Option<ClipboardFile> {
|
||||||
match msg.union {
|
match msg.union {
|
||||||
Some(cliprdr::Union::Ready(_)) => Some(ClipbaordFile::MonitorReady),
|
Some(cliprdr::Union::Ready(_)) => Some(ClipboardFile::MonitorReady),
|
||||||
Some(cliprdr::Union::FormatList(data)) => {
|
Some(cliprdr::Union::FormatList(data)) => {
|
||||||
let mut format_list: Vec<(i32, String)> = Vec::new();
|
let mut format_list: Vec<(i32, String)> = Vec::new();
|
||||||
for v in data.formats.iter() {
|
for v in data.formats.iter() {
|
||||||
format_list.push((v.id, v.format.clone()));
|
format_list.push((v.id, v.format.clone()));
|
||||||
}
|
}
|
||||||
Some(ClipbaordFile::FormatList { format_list })
|
Some(ClipboardFile::FormatList { format_list })
|
||||||
}
|
}
|
||||||
Some(cliprdr::Union::FormatListResponse(data)) => Some(ClipbaordFile::FormatListResponse {
|
Some(cliprdr::Union::FormatListResponse(data)) => Some(ClipboardFile::FormatListResponse {
|
||||||
msg_flags: data.msg_flags,
|
msg_flags: data.msg_flags,
|
||||||
}),
|
}),
|
||||||
Some(cliprdr::Union::FormatDataRequest(data)) => Some(ClipbaordFile::FormatDataRequest {
|
Some(cliprdr::Union::FormatDataRequest(data)) => Some(ClipboardFile::FormatDataRequest {
|
||||||
requested_format_id: data.requested_format_id,
|
requested_format_id: data.requested_format_id,
|
||||||
}),
|
}),
|
||||||
Some(cliprdr::Union::FormatDataResponse(data)) => Some(ClipbaordFile::FormatDataResponse {
|
Some(cliprdr::Union::FormatDataResponse(data)) => Some(ClipboardFile::FormatDataResponse {
|
||||||
msg_flags: data.msg_flags,
|
msg_flags: data.msg_flags,
|
||||||
format_data: data.format_data.into(),
|
format_data: data.format_data.into(),
|
||||||
}),
|
}),
|
||||||
Some(cliprdr::Union::FileContentsRequest(data)) => {
|
Some(cliprdr::Union::FileContentsRequest(data)) => {
|
||||||
Some(ClipbaordFile::FileContentsRequest {
|
Some(ClipboardFile::FileContentsRequest {
|
||||||
stream_id: data.stream_id,
|
stream_id: data.stream_id,
|
||||||
list_index: data.list_index,
|
list_index: data.list_index,
|
||||||
dw_flags: data.dw_flags,
|
dw_flags: data.dw_flags,
|
||||||
@ -156,7 +156,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option<ClipbaordFile> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
Some(cliprdr::Union::FileContentsResponse(data)) => {
|
Some(cliprdr::Union::FileContentsResponse(data)) => {
|
||||||
Some(ClipbaordFile::FileContentsResponse {
|
Some(ClipboardFile::FileContentsResponse {
|
||||||
msg_flags: data.msg_flags,
|
msg_flags: data.msg_flags,
|
||||||
stream_id: data.stream_id,
|
stream_id: data.stream_id,
|
||||||
requested_data: data.requested_data.into(),
|
requested_data: data.requested_data.into(),
|
||||||
|
@ -9,7 +9,7 @@ use parity_tokio_ipc::{
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub use clipboard::ClipbaordFile;
|
pub use clipboard::ClipboardFile;
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err, bail, bytes,
|
allow_err, bail, bytes,
|
||||||
bytes_codec::BytesCodec,
|
bytes_codec::BytesCodec,
|
||||||
@ -191,7 +191,7 @@ pub enum Data {
|
|||||||
Test,
|
Test,
|
||||||
SyncConfig(Option<(Config, Config2)>),
|
SyncConfig(Option<(Config, Config2)>),
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
ClipbaordFile(ClipbaordFile),
|
ClipboardFile(ClipboardFile),
|
||||||
ClipboardFileEnabled(bool),
|
ClipboardFileEnabled(bool),
|
||||||
PrivacyModeState((i32, PrivacyModeState)),
|
PrivacyModeState((i32, PrivacyModeState)),
|
||||||
TestRendezvousServer,
|
TestRendezvousServer,
|
||||||
|
@ -13,7 +13,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("setup_server_tip", "For faster connection, please set up your own server"),
|
("setup_server_tip", "For faster connection, please set up your own server"),
|
||||||
("Auto Login", "Auto Login (Only valid if you set \"Lock after session end\")"),
|
("Auto Login", "Auto Login (Only valid if you set \"Lock after session end\")"),
|
||||||
("whitelist_tip", "Only whitelisted IP can access me"),
|
("whitelist_tip", "Only whitelisted IP can access me"),
|
||||||
("whitelist_sep", "Seperated by comma, semicolon, spaces or new line"),
|
("whitelist_sep", "Separated by comma, semicolon, spaces or new line"),
|
||||||
("Wrong credentials", "Wrong username or password"),
|
("Wrong credentials", "Wrong username or password"),
|
||||||
("invalid_http", "must start with http:// or https://"),
|
("invalid_http", "must start with http:// or https://"),
|
||||||
("install_daemon_tip", "For starting on boot, you need to install system service."),
|
("install_daemon_tip", "For starting on boot, you need to install system service."),
|
||||||
|
@ -707,9 +707,9 @@ pub fn get_double_click_time() -> u32 {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let mut double_click_time = 0u32;
|
let mut double_click_time = 0u32;
|
||||||
let property = std::ffi::CString::new("gtk-double-click-time").unwrap();
|
let property = std::ffi::CString::new("gtk-double-click-time").unwrap();
|
||||||
let setings = gtk_settings_get_default();
|
let settings = gtk_settings_get_default();
|
||||||
g_object_get(
|
g_object_get(
|
||||||
setings,
|
settings,
|
||||||
property.as_ptr(),
|
property.as_ptr(),
|
||||||
&mut double_click_time as *mut u32,
|
&mut double_click_time as *mut u32,
|
||||||
0 as *const libc::c_void,
|
0 as *const libc::c_void,
|
||||||
|
@ -331,7 +331,7 @@ pub fn get_cursor_data(hcursor: u64) -> ResultType<CursorData> {
|
|||||||
*/
|
*/
|
||||||
let mut colors: Vec<u8> = Vec::new();
|
let mut colors: Vec<u8> = Vec::new();
|
||||||
colors.reserve((size.height * size.width) as usize * 4);
|
colors.reserve((size.height * size.width) as usize * 4);
|
||||||
// TIFF is rgb colrspace, no need to convert
|
// TIFF is rgb colorspace, no need to convert
|
||||||
// let cs: id = msg_send![class!(NSColorSpace), sRGBColorSpace];
|
// let cs: id = msg_send![class!(NSColorSpace), sRGBColorSpace];
|
||||||
for y in 0..(size.height as _) {
|
for y in 0..(size.height as _) {
|
||||||
for x in 0..(size.width as _) {
|
for x in 0..(size.width as _) {
|
||||||
@ -440,7 +440,7 @@ pub fn start_os_service() {
|
|||||||
.status()
|
.status()
|
||||||
.ok();
|
.ok();
|
||||||
println!("The others killed");
|
println!("The others killed");
|
||||||
// launchctl load/unload/start agent not work in daemon, show not priviledged.
|
// launchctl load/unload/start agent not work in daemon, show not privileged.
|
||||||
// sudo launchctl asuser 501 open -n also not allowed.
|
// sudo launchctl asuser 501 open -n also not allowed.
|
||||||
std::process::Command::new("launchctl")
|
std::process::Command::new("launchctl")
|
||||||
.args(&[
|
.args(&[
|
||||||
|
@ -469,10 +469,10 @@ impl RendezvousMediator {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_relay_server(&self, provided_by_rendzvous_server: String) -> String {
|
fn get_relay_server(&self, provided_by_rendezvous_server: String) -> String {
|
||||||
let mut relay_server = Config::get_option("relay-server");
|
let mut relay_server = Config::get_option("relay-server");
|
||||||
if relay_server.is_empty() {
|
if relay_server.is_empty() {
|
||||||
relay_server = provided_by_rendzvous_server;
|
relay_server = provided_by_rendezvous_server;
|
||||||
}
|
}
|
||||||
if relay_server.is_empty() {
|
if relay_server.is_empty() {
|
||||||
relay_server = crate::increase_port(&self.host, 1);
|
relay_server = crate::increase_port(&self.host, 1);
|
||||||
|
@ -148,7 +148,7 @@ impl Connection {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let (tx_from_cm_holder, mut rx_from_cm) = mpsc::unbounded_channel::<ipc::Data>();
|
let (tx_from_cm_holder, mut rx_from_cm) = mpsc::unbounded_channel::<ipc::Data>();
|
||||||
// holding tx_from_cm_holde to avoid cpu burning of rx_from_cm.recv when all sender closed
|
// holding tx_from_cm_holder to avoid cpu burning of rx_from_cm.recv when all sender closed
|
||||||
let tx_from_cm = tx_from_cm_holder.clone();
|
let tx_from_cm = tx_from_cm_holder.clone();
|
||||||
let (tx_to_cm, rx_to_cm) = mpsc::unbounded_channel::<ipc::Data>();
|
let (tx_to_cm, rx_to_cm) = mpsc::unbounded_channel::<ipc::Data>();
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel::<(Instant, Arc<Message>)>();
|
let (tx, mut rx) = mpsc::unbounded_channel::<(Instant, Arc<Message>)>();
|
||||||
@ -319,7 +319,7 @@ impl Connection {
|
|||||||
allow_err!(conn.stream.send_raw(bytes).await);
|
allow_err!(conn.stream.send_raw(bytes).await);
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
ipc::Data::ClipbaordFile(_clip) => {
|
ipc::Data::ClipboardFile(_clip) => {
|
||||||
if conn.file_transfer_enabled() {
|
if conn.file_transfer_enabled() {
|
||||||
allow_err!(conn.stream.send(&clip_2_msg(_clip)).await);
|
allow_err!(conn.stream.send(&clip_2_msg(_clip)).await);
|
||||||
}
|
}
|
||||||
@ -593,7 +593,7 @@ impl Connection {
|
|||||||
Some(data) = rx_from_cm.recv() => {
|
Some(data) = rx_from_cm.recv() => {
|
||||||
match data {
|
match data {
|
||||||
ipc::Data::Close => {
|
ipc::Data::Close => {
|
||||||
bail!("Close requested from selfection manager");
|
bail!("Close requested from selection manager");
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -663,7 +663,7 @@ impl Connection {
|
|||||||
self.send_login_error("Your ip is blocked by the peer")
|
self.send_login_error("Your ip is blocked by the peer")
|
||||||
.await;
|
.await;
|
||||||
Self::post_alarm_audit(
|
Self::post_alarm_audit(
|
||||||
AlarmAuditType::IpWhiltelist, //"ip whiltelist",
|
AlarmAuditType::IpWhitelist, //"ip whitelist",
|
||||||
true,
|
true,
|
||||||
json!({
|
json!({
|
||||||
"ip":addr.ip(),
|
"ip":addr.ip(),
|
||||||
@ -1309,7 +1309,7 @@ impl Connection {
|
|||||||
if self.file_transfer_enabled() {
|
if self.file_transfer_enabled() {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if let Some(clip) = msg_2_clip(_clip) {
|
if let Some(clip) = msg_2_clip(_clip) {
|
||||||
self.send_to_cm(ipc::Data::ClipbaordFile(clip))
|
self.send_to_cm(ipc::Data::ClipboardFile(clip))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1857,8 +1857,8 @@ mod privacy_mode {
|
|||||||
pub(super) fn turn_on_privacy(_conn_id: i32) -> ResultType<bool> {
|
pub(super) fn turn_on_privacy(_conn_id: i32) -> ResultType<bool> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let plugin_exitst = crate::ui::win_privacy::turn_on_privacy(_conn_id)?;
|
let plugin_exist = crate::ui::win_privacy::turn_on_privacy(_conn_id)?;
|
||||||
Ok(plugin_exitst)
|
Ok(plugin_exist)
|
||||||
}
|
}
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
{
|
{
|
||||||
@ -1875,7 +1875,7 @@ struct ConnAuditResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum AlarmAuditType {
|
pub enum AlarmAuditType {
|
||||||
IpWhiltelist = 0,
|
IpWhitelist = 0,
|
||||||
ManyWrongPassword = 1,
|
ManyWrongPassword = 1,
|
||||||
FrequentAttempt = 2,
|
FrequentAttempt = 2,
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ fn active_mouse_(conn: i32) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let in_actived_dist = |a: i32, b: i32| -> bool { (a - b).abs() < MOUSE_ACTIVE_DISTANCE };
|
let in_active_dist = |a: i32, b: i32| -> bool { (a - b).abs() < MOUSE_ACTIVE_DISTANCE };
|
||||||
|
|
||||||
// Check if input is in valid range
|
// Check if input is in valid range
|
||||||
match crate::get_cursor_pos() {
|
match crate::get_cursor_pos() {
|
||||||
@ -496,7 +496,7 @@ fn active_mouse_(conn: i32) -> bool {
|
|||||||
let lock = LATEST_PEER_INPUT_CURSOR.lock().unwrap();
|
let lock = LATEST_PEER_INPUT_CURSOR.lock().unwrap();
|
||||||
(lock.x, lock.y)
|
(lock.x, lock.y)
|
||||||
};
|
};
|
||||||
let mut can_active = in_actived_dist(last_in_x, x) && in_actived_dist(last_in_y, y);
|
let mut can_active = in_active_dist(last_in_x, x) && in_active_dist(last_in_y, y);
|
||||||
// The cursor may not have been moved to last input position if system is busy now.
|
// The cursor may not have been moved to last input position if system is busy now.
|
||||||
// While this is not a common case, we check it again after some time later.
|
// While this is not a common case, we check it again after some time later.
|
||||||
if !can_active {
|
if !can_active {
|
||||||
@ -505,7 +505,7 @@ fn active_mouse_(conn: i32) -> bool {
|
|||||||
std::thread::sleep(std::time::Duration::from_micros(10));
|
std::thread::sleep(std::time::Duration::from_micros(10));
|
||||||
// Sleep here can also somehow suppress delay accumulation.
|
// Sleep here can also somehow suppress delay accumulation.
|
||||||
if let Some((x2, y2)) = crate::get_cursor_pos() {
|
if let Some((x2, y2)) = crate::get_cursor_pos() {
|
||||||
can_active = in_actived_dist(last_in_x, x2) && in_actived_dist(last_in_y, y2);
|
can_active = in_active_dist(last_in_x, x2) && in_active_dist(last_in_y, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !can_active {
|
if !can_active {
|
||||||
|
@ -203,7 +203,7 @@ mod utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// functions called in seperate SYSTEM user process.
|
// functions called in separate SYSTEM user process.
|
||||||
pub mod server {
|
pub mod server {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ pub mod server {
|
|||||||
}
|
}
|
||||||
ConnCount(Some(n)) => {
|
ConnCount(Some(n)) => {
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
log::info!("Connnection count equals 0, exit");
|
log::info!("Connection count equals 0, exit");
|
||||||
stream.send(&Data::DataPortableService(WillClose)).await.ok();
|
stream.send(&Data::DataPortableService(WillClose)).await.ok();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -756,7 +756,7 @@ pub mod client {
|
|||||||
log::info!("portable service status mismatch");
|
log::info!("portable service status mismatch");
|
||||||
}
|
}
|
||||||
if portable_service_running {
|
if portable_service_running {
|
||||||
log::info!("Create shared memeory capturer");
|
log::info!("Create shared memory capturer");
|
||||||
return Ok(Box::new(CapturerPortable::new(current_display, use_yuv)));
|
return Ok(Box::new(CapturerPortable::new(current_display, use_yuv)));
|
||||||
} else {
|
} else {
|
||||||
log::debug!("Create capturer dxgi|gdi");
|
log::debug!("Create capturer dxgi|gdi");
|
||||||
|
@ -309,9 +309,9 @@ pub fn test_create_capturer(privacy_mode_id: i32, timeout_millis: u64) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn check_uac_switch(privacy_mode_id: i32, captuerer_privacy_mode_id: i32) -> ResultType<()> {
|
fn check_uac_switch(privacy_mode_id: i32, capturer_privacy_mode_id: i32) -> ResultType<()> {
|
||||||
if captuerer_privacy_mode_id != 0 {
|
if capturer_privacy_mode_id != 0 {
|
||||||
if privacy_mode_id != captuerer_privacy_mode_id {
|
if privacy_mode_id != capturer_privacy_mode_id {
|
||||||
if !crate::ui::win_privacy::is_process_consent_running()? {
|
if !crate::ui::win_privacy::is_process_consent_running()? {
|
||||||
bail!("consent.exe is running");
|
bail!("consent.exe is running");
|
||||||
}
|
}
|
||||||
@ -330,7 +330,7 @@ pub(super) struct CapturerInfo {
|
|||||||
pub ndisplay: usize,
|
pub ndisplay: usize,
|
||||||
pub current: usize,
|
pub current: usize,
|
||||||
pub privacy_mode_id: i32,
|
pub privacy_mode_id: i32,
|
||||||
pub _captuerer_privacy_mode_id: i32,
|
pub _capturer_privacy_mode_id: i32,
|
||||||
pub capturer: Box<dyn TraitCapturer>,
|
pub capturer: Box<dyn TraitCapturer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,29 +371,29 @@ fn get_capturer(use_yuv: bool, portable_service_running: bool) -> ResultType<Cap
|
|||||||
|
|
||||||
let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
|
let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let captuerer_privacy_mode_id = privacy_mode_id;
|
let capturer_privacy_mode_id = privacy_mode_id;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let mut captuerer_privacy_mode_id = privacy_mode_id;
|
let mut capturer_privacy_mode_id = privacy_mode_id;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
if captuerer_privacy_mode_id != 0 {
|
if capturer_privacy_mode_id != 0 {
|
||||||
if crate::ui::win_privacy::is_process_consent_running()? {
|
if crate::ui::win_privacy::is_process_consent_running()? {
|
||||||
captuerer_privacy_mode_id = 0;
|
capturer_privacy_mode_id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Try create capturer with captuerer privacy mode id {}",
|
"Try create capturer with capturer privacy mode id {}",
|
||||||
captuerer_privacy_mode_id,
|
capturer_privacy_mode_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if privacy_mode_id != 0 {
|
if privacy_mode_id != 0 {
|
||||||
if privacy_mode_id != captuerer_privacy_mode_id {
|
if privacy_mode_id != capturer_privacy_mode_id {
|
||||||
log::info!("In privacy mode, but show UAC prompt window for now");
|
log::info!("In privacy mode, but show UAC prompt window for now");
|
||||||
} else {
|
} else {
|
||||||
log::info!("In privacy mode, the peer side cannot watch the screen");
|
log::info!("In privacy mode, the peer side cannot watch the screen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let capturer = create_capturer(
|
let capturer = create_capturer(
|
||||||
captuerer_privacy_mode_id,
|
capturer_privacy_mode_id,
|
||||||
display,
|
display,
|
||||||
use_yuv,
|
use_yuv,
|
||||||
current,
|
current,
|
||||||
@ -406,7 +406,7 @@ fn get_capturer(use_yuv: bool, portable_service_running: bool) -> ResultType<Cap
|
|||||||
ndisplay,
|
ndisplay,
|
||||||
current,
|
current,
|
||||||
privacy_mode_id,
|
privacy_mode_id,
|
||||||
_captuerer_privacy_mode_id: captuerer_privacy_mode_id,
|
_capturer_privacy_mode_id: capturer_privacy_mode_id,
|
||||||
capturer,
|
capturer,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -493,7 +493,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
|||||||
|
|
||||||
while sp.ok() {
|
while sp.ok() {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
check_uac_switch(c.privacy_mode_id, c._captuerer_privacy_mode_id)?;
|
check_uac_switch(c.privacy_mode_id, c._capturer_privacy_mode_id)?;
|
||||||
|
|
||||||
let mut video_qos = VIDEO_QOS.lock().unwrap();
|
let mut video_qos = VIDEO_QOS.lock().unwrap();
|
||||||
if video_qos.check_if_updated() {
|
if video_qos.check_if_updated() {
|
||||||
@ -602,7 +602,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
|||||||
if !scrap::is_x11() {
|
if !scrap::is_x11() {
|
||||||
if would_block_count >= 100 {
|
if would_block_count >= 100 {
|
||||||
super::wayland::release_resource();
|
super::wayland::release_resource();
|
||||||
bail!("Wayland capturer none 100 times, try restart captuere");
|
bail!("Wayland capturer none 100 times, try restart capture");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,7 +637,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
|||||||
while wait_begin.elapsed().as_millis() < timeout_millis as _ {
|
while wait_begin.elapsed().as_millis() < timeout_millis as _ {
|
||||||
check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
|
check_privacy_mode_changed(&sp, c.privacy_mode_id)?;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
check_uac_switch(c.privacy_mode_id, c._captuerer_privacy_mode_id)?;
|
check_uac_switch(c.privacy_mode_id, c._capturer_privacy_mode_id)?;
|
||||||
frame_controller.try_wait_next(&mut fetched_conn_ids, 300);
|
frame_controller.try_wait_next(&mut fetched_conn_ids, 300);
|
||||||
// break if all connections have received current frame
|
// break if all connections have received current frame
|
||||||
if fetched_conn_ids.len() >= frame_controller.send_conn_ids.len() {
|
if fetched_conn_ids.len() >= frame_controller.send_conn_ids.len() {
|
||||||
|
@ -276,7 +276,7 @@ pub(super) fn get_capturer() -> ResultType<super::video_service::CapturerInfo> {
|
|||||||
ndisplay: cap_display_info.num,
|
ndisplay: cap_display_info.num,
|
||||||
current: cap_display_info.current,
|
current: cap_display_info.current,
|
||||||
privacy_mode_id: 0,
|
privacy_mode_id: 0,
|
||||||
_captuerer_privacy_mode_id: 0,
|
_capturer_privacy_mode_id: 0,
|
||||||
capturer: Box::new(cap_display_info.capturer.clone()),
|
capturer: Box::new(cap_display_info.capturer.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class Body: Reactor.Component
|
|||||||
var disconnected = c.disconnected;
|
var disconnected = c.disconnected;
|
||||||
var show_elevation_btn = handler.can_elevate() && show_elevation && !c.is_file_transfer && c.port_forward.length == 0;
|
var show_elevation_btn = handler.can_elevate() && show_elevation && !c.is_file_transfer && c.port_forward.length == 0;
|
||||||
var show_accept_btn = handler.get_option('approve-mode') != 'password';
|
var show_accept_btn = handler.get_option('approve-mode') != 'password';
|
||||||
// below size:* is work around for Linux, it already set in css, but not work, shit sciter
|
// below size:* is a workaround for Linux, it already set in css, but not work, shit sciter
|
||||||
return <div .content style="size:*">
|
return <div .content style="size:*">
|
||||||
<div .left-panel>
|
<div .left-panel>
|
||||||
<div .icon-and-id>
|
<div .icon-and-id>
|
||||||
@ -42,7 +42,7 @@ class Body: Reactor.Component
|
|||||||
<div .id style="font-weight: bold; font-size: 1.2em;">{c.name}</div>
|
<div .id style="font-weight: bold; font-size: 1.2em;">{c.name}</div>
|
||||||
<div .id>({c.peer_id})</div>
|
<div .id>({c.peer_id})</div>
|
||||||
<div style="margin-top: 1.2em">{auth
|
<div style="margin-top: 1.2em">{auth
|
||||||
? <span>{disconnected ? translate('Disconnected') : translate('Connected')}{" "}<span #time>{getElaspsed(c.time, c.now)}</span></span>
|
? <span>{disconnected ? translate('Disconnected') : translate('Connected')}{" "}<span #time>{getElapsed(c.time, c.now)}</span></span>
|
||||||
: <span>{translate('Request access to your device')}{"..."}</span>}
|
: <span>{translate('Request access to your device')}{"..."}</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -442,7 +442,7 @@ function self.ready() {
|
|||||||
view.move(sw - w, 0, w, h);
|
view.move(sw - w, 0, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getElaspsed(time, now) {
|
function getElapsed(time, now) {
|
||||||
var seconds = Date.diff(time, now, #seconds);
|
var seconds = Date.diff(time, now, #seconds);
|
||||||
var hours = seconds / 3600;
|
var hours = seconds / 3600;
|
||||||
var days = hours / 24;
|
var days = hours / 24;
|
||||||
@ -482,7 +482,7 @@ function updateTime() {
|
|||||||
if (el) {
|
if (el) {
|
||||||
var c = connections[body.cur];
|
var c = connections[body.cur];
|
||||||
if (c && c.authorized && !c.disconnected) {
|
if (c && c.authorized && !c.disconnected) {
|
||||||
el.text = getElaspsed(c.time, c.now);
|
el.text = getElapsed(c.time, c.now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateTime();
|
updateTime();
|
||||||
|
@ -13,7 +13,7 @@ class Install: Reactor.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div><button|checkbox #startmenu checked>{translate('Create start menu shortcuts')}</button></div>
|
<div><button|checkbox #startmenu checked>{translate('Create start menu shortcuts')}</button></div>
|
||||||
<div><button|checkbox #desktopicon checked>{translate('Create desktop icon')}</button></div>
|
<div><button|checkbox #desktopicon checked>{translate('Create desktop icon')}</button></div>
|
||||||
<div #aggrement .link style="margin-top: 2em;">{translate('End-user license agreement')}</div>
|
<div #agreement .link style="margin-top: 2em;">{translate('End-user license agreement')}</div>
|
||||||
<div>{translate('agreement_tip')}</div>
|
<div>{translate('agreement_tip')}</div>
|
||||||
<div style="height: 1px; background: gray; margin-top: 1em" />
|
<div style="height: 1px; background: gray; margin-top: 1em" />
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right;">
|
||||||
@ -46,7 +46,7 @@ class Install: Reactor.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event click $(#aggrement) {
|
event click $(#agreement) {
|
||||||
view.open_url("http://rustdesk.com/privacy");
|
view.open_url("http://rustdesk.com/privacy");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ impl DelegateState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut LAUCHED: bool = false;
|
static mut LAUNCHED: bool = false;
|
||||||
|
|
||||||
impl AppHandler for Rc<Host> {
|
impl AppHandler for Rc<Host> {
|
||||||
fn command(&mut self, cmd: u32) {
|
fn command(&mut self, cmd: u32) {
|
||||||
@ -109,7 +109,7 @@ unsafe fn set_delegate(handler: Option<Box<dyn AppHandler>>) {
|
|||||||
|
|
||||||
extern "C" fn application_did_finish_launching(_this: &mut Object, _: Sel, _notification: id) {
|
extern "C" fn application_did_finish_launching(_this: &mut Object, _: Sel, _notification: id) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LAUCHED = true;
|
LAUNCHED = true;
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
let () = msg_send![NSApp(), activateIgnoringOtherApps: YES];
|
let () = msg_send![NSApp(), activateIgnoringOtherApps: YES];
|
||||||
@ -122,7 +122,7 @@ extern "C" fn application_should_handle_open_untitled_file(
|
|||||||
_sender: id,
|
_sender: id,
|
||||||
) -> BOOL {
|
) -> BOOL {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !LAUCHED {
|
if !LAUNCHED {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
hbb_common::log::debug!("icon clicked on finder");
|
hbb_common::log::debug!("icon clicked on finder");
|
||||||
|
@ -120,7 +120,7 @@ function resetWheel() {
|
|||||||
|
|
||||||
var INERTIA_ACCELERATION = 30;
|
var INERTIA_ACCELERATION = 30;
|
||||||
|
|
||||||
// not good, precision not enough to simulate accelation effect,
|
// not good, precision not enough to simulate acceleration effect,
|
||||||
// seems have to use pixel based rather line based delta
|
// seems have to use pixel based rather line based delta
|
||||||
function accWheel(v, is_x) {
|
function accWheel(v, is_x) {
|
||||||
if (wheeling) return;
|
if (wheeling) return;
|
||||||
|
@ -253,7 +253,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
if !pre_enabled && ContextSend::is_enabled() {
|
if !pre_enabled && ContextSend::is_enabled() {
|
||||||
allow_err!(
|
allow_err!(
|
||||||
self.stream
|
self.stream
|
||||||
.send(&Data::ClipbaordFile(clipboard::ClipbaordFile::MonitorReady))
|
.send(&Data::ClipboardFile(clipboard::ClipboardFile::MonitorReady))
|
||||||
.await
|
.await
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
rx_clip = rx_clip1.lock().await;
|
rx_clip = rx_clip1.lock().await;
|
||||||
} else {
|
} else {
|
||||||
let rx_clip2;
|
let rx_clip2;
|
||||||
(_tx_clip, rx_clip2) = unbounded_channel::<clipboard::ClipbaordFile>();
|
(_tx_clip, rx_clip2) = unbounded_channel::<clipboard::ClipboardFile>();
|
||||||
rx_clip1 = Arc::new(TokioMutex::new(rx_clip2));
|
rx_clip1 = Arc::new(TokioMutex::new(rx_clip2));
|
||||||
rx_clip = rx_clip1.lock().await;
|
rx_clip = rx_clip1.lock().await;
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
Data::ClipbaordFile(_clip) => {
|
Data::ClipboardFile(_clip) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
let conn_id = self.conn_id;
|
let conn_id = self.conn_id;
|
||||||
@ -394,7 +394,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
clip_file = rx_clip.recv() => match clip_file {
|
clip_file = rx_clip.recv() => match clip_file {
|
||||||
Some(_clip) => {
|
Some(_clip) => {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
allow_err!(self.tx.send(Data::ClipbaordFile(_clip)));
|
allow_err!(self.tx.send(Data::ClipboardFile(_clip)));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
//
|
//
|
||||||
|
@ -936,7 +936,7 @@ pub fn account_auth_result() -> String {
|
|||||||
serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default()
|
serde_json::to_string(&account::OidcSession::get_result()).unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
// notice: avoiding create ipc connecton repeatly,
|
// notice: avoiding create ipc connection repeatedly,
|
||||||
// because windows named pipe has serious memory leak issue.
|
// because windows named pipe has serious memory leak issue.
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc::Data>) {
|
async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc::Data>) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user