feat, input source, win->win
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
f11104fcb5
commit
4cbbb5b64f
@ -69,8 +69,6 @@ const String kOptionOpenInTabs = "allow-open-in-tabs";
|
||||
const String kOptionOpenInWindows = "allow-open-in-windows";
|
||||
const String kOptionForceAlwaysRelay = "force-always-relay";
|
||||
|
||||
const String kOptionInputSource = "input-source";
|
||||
|
||||
const String kUniLinksPrefix = "rustdesk://";
|
||||
const String kUrlActionClose = "close";
|
||||
|
||||
|
@ -1694,23 +1694,24 @@ class _KeyboardMenu extends StatelessWidget {
|
||||
final inputSource = stateGlobal.getInputSource();
|
||||
final enabled = !ffi.ffiModel.viewOnly;
|
||||
return Column(
|
||||
children: supportedInputSourceList.map((e) {
|
||||
final d = e as List<dynamic>;
|
||||
return RdoMenuButton<String>(
|
||||
child: Text(translate(d[1] as String)),
|
||||
value: d[0] as String,
|
||||
groupValue: inputSource,
|
||||
onChanged: enabled
|
||||
? (e) {
|
||||
if (e != null) {
|
||||
stateGlobal.setInputSource(e);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
ffi: ffi,
|
||||
);
|
||||
}).toList(),
|
||||
children: supportedInputSourceList.map((e) {
|
||||
final d = e as List<dynamic>;
|
||||
return RdoMenuButton<String>(
|
||||
child: Text(translate(d[1] as String)),
|
||||
value: d[0] as String,
|
||||
groupValue: inputSource,
|
||||
onChanged: enabled
|
||||
? (v) async {
|
||||
if (v != null) {
|
||||
await stateGlobal.setInputSource(ffi.sessionId, v);
|
||||
await ffi.ffiModel.checkDesktopKeyboardMode();
|
||||
}
|
||||
}
|
||||
: null,
|
||||
ffi: ffi,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
viewMode() {
|
||||
|
@ -735,16 +735,9 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
checkDesktopKeyboardMode() async {
|
||||
final curMode = await bind.sessionGetKeyboardMode(sessionId: sessionId);
|
||||
if (curMode != null) {
|
||||
if (bind.sessionIsKeyboardModeSupported(
|
||||
sessionId: sessionId, mode: curMode)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If current keyboard mode is not supported, change to another one.
|
||||
if (isInputSourceFlutter) {
|
||||
// Local side, flutter keyboard input source
|
||||
// Currently only map mode is supported, legacy mode is used for compatibility.
|
||||
for (final mode in [kKeyMapMode, kKeyLegacyMode]) {
|
||||
if (bind.sessionIsKeyboardModeSupported(
|
||||
sessionId: sessionId, mode: mode)) {
|
||||
@ -753,6 +746,15 @@ class FfiModel with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final curMode = await bind.sessionGetKeyboardMode(sessionId: sessionId);
|
||||
if (curMode != null) {
|
||||
if (bind.sessionIsKeyboardModeSupported(
|
||||
sessionId: sessionId, mode: curMode)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If current keyboard mode is not supported, change to another one.
|
||||
for (final mode in [kKeyMapMode, kKeyTranslateMode, kKeyLegacyMode]) {
|
||||
if (bind.sessionIsKeyboardModeSupported(
|
||||
sessionId: sessionId, mode: mode)) {
|
||||
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../consts.dart';
|
||||
@ -98,14 +99,14 @@ class StateGlobal {
|
||||
|
||||
String getInputSource({bool force = false}) {
|
||||
if (force || _inputSource.isEmpty) {
|
||||
_inputSource = bind.mainGetLocalOption(key: kOptionInputSource);
|
||||
_inputSource = bind.mainGetInputSource();
|
||||
}
|
||||
return _inputSource;
|
||||
}
|
||||
|
||||
void setInputSource(String v) async {
|
||||
await bind.mainSetLocalOption(key: kOptionInputSource, value: v);
|
||||
_inputSource = bind.mainGetLocalOption(key: kOptionInputSource);
|
||||
setInputSource(SessionID sessionId, String v) async {
|
||||
await bind.mainSetInputSource(sessionId: sessionId, value: v);
|
||||
_inputSource = bind.mainGetInputSource();
|
||||
}
|
||||
|
||||
StateGlobal._();
|
||||
|
@ -22,7 +22,7 @@ appveyor = { repository = "pythoneer/enigo-85xiy" }
|
||||
serde = { version = "1.0", optional = true }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
log = "0.4"
|
||||
rdev = { git = "https://github.com/fufesou/rdev" }
|
||||
rdev = { path = "../../../rdev" }
|
||||
tfc = { git = "https://github.com/fufesou/The-Fat-Controller" }
|
||||
hbb_common = { path = "../hbb_common" }
|
||||
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
common::make_fd_to_json,
|
||||
flutter::{self, session_add, session_add_existed, session_start_, sessions},
|
||||
input::*,
|
||||
keyboard::input_source::{change_input_source, get_cur_session_input_source},
|
||||
ui_interface::{self, *},
|
||||
};
|
||||
use flutter_rust_bridge::{StreamSink, SyncReturn};
|
||||
@ -468,16 +469,13 @@ pub fn session_handle_flutter_key_event(
|
||||
// As rust is multi-thread, it is possible that enter() is called before leave().
|
||||
// This will cause the keyboard input to take no effect.
|
||||
pub fn session_enter_or_leave(_session_id: SessionID, _enter: bool) -> SyncReturn<()> {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
if crate::keyboard::input_source::is_cur_input_source_rdev() {
|
||||
if let Some(session) = sessions::get_session_by_session_id(&_session_id) {
|
||||
let keyboard_mode = session.get_keyboard_mode();
|
||||
if _enter {
|
||||
set_cur_session_id_(_session_id, &keyboard_mode);
|
||||
session.enter(keyboard_mode);
|
||||
} else {
|
||||
session.leave(keyboard_mode);
|
||||
}
|
||||
if let Some(session) = sessions::get_session_by_session_id(&_session_id) {
|
||||
let keyboard_mode = session.get_keyboard_mode();
|
||||
if _enter {
|
||||
set_cur_session_id_(_session_id, &keyboard_mode);
|
||||
session.enter(keyboard_mode);
|
||||
} else {
|
||||
session.leave(keyboard_mode);
|
||||
}
|
||||
}
|
||||
SyncReturn(())
|
||||
@ -848,12 +846,7 @@ pub fn main_post_request(url: String, body: String, header: String) {
|
||||
}
|
||||
|
||||
pub fn main_get_local_option(key: String) -> SyncReturn<String> {
|
||||
let v = if key == crate::keyboard::input_source::CONFIG_OPTION_INPUT_SOURCE {
|
||||
crate::keyboard::input_source::get_cur_session_input_source()
|
||||
} else {
|
||||
get_local_option(key)
|
||||
};
|
||||
SyncReturn(v)
|
||||
SyncReturn(get_local_option(key))
|
||||
}
|
||||
|
||||
pub fn main_get_env(key: String) -> SyncReturn<String> {
|
||||
@ -861,11 +854,15 @@ pub fn main_get_env(key: String) -> SyncReturn<String> {
|
||||
}
|
||||
|
||||
pub fn main_set_local_option(key: String, value: String) {
|
||||
if key == crate::keyboard::input_source::CONFIG_OPTION_INPUT_SOURCE {
|
||||
crate::keyboard::input_source::change_input_source(&value);
|
||||
} else {
|
||||
set_local_option(key, value);
|
||||
}
|
||||
set_local_option(key, value)
|
||||
}
|
||||
|
||||
pub fn main_get_input_source() -> SyncReturn<String> {
|
||||
SyncReturn(get_cur_session_input_source())
|
||||
}
|
||||
|
||||
pub fn main_set_input_source(session_id: SessionID, value: String) {
|
||||
change_input_source(session_id, value);
|
||||
}
|
||||
|
||||
pub fn main_get_my_id() -> String {
|
||||
|
@ -34,6 +34,9 @@ const OS_LOWER_ANDROID: &str = "android";
|
||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||
static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
static IS_RDEV_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref TO_RELEASE: Arc<Mutex<HashMap<Key, Event>>> = Arc::new(Mutex::new(HashMap::new()));
|
||||
static ref MODIFIERS_STATE: Mutex<HashMap<Key, bool>> = {
|
||||
@ -55,6 +58,9 @@ pub mod client {
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub fn change_grab_status(state: GrabState, keyboard_mode: &str) {
|
||||
if !IS_RDEV_ENABLED.load(Ordering::SeqCst) {
|
||||
return;
|
||||
}
|
||||
match state {
|
||||
GrabState::Ready => {}
|
||||
GrabState::Run => {
|
||||
@ -78,10 +84,7 @@ pub mod client {
|
||||
#[cfg(target_os = "linux")]
|
||||
rdev::disable_grab();
|
||||
}
|
||||
GrabState::Exit => {
|
||||
#[cfg(target_os = "linux")]
|
||||
rdev::exit_grab_listen();
|
||||
}
|
||||
GrabState::Exit => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,6 +318,8 @@ pub fn start_grab_loop() {
|
||||
};
|
||||
}
|
||||
|
||||
// #[allow(dead_code)] is ok here. No need to stop grabbing loop.
|
||||
#[allow(dead_code)]
|
||||
pub fn stop_grab_loop() -> Result<(), rdev::GrabError> {
|
||||
#[cfg(any(target_os = "windows", target_os = "macos"))]
|
||||
rdev::exit_grab()?;
|
||||
@ -1076,8 +1081,9 @@ pub fn keycode_to_rdev_key(keycode: u32) -> Key {
|
||||
#[cfg(feature = "flutter")]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub mod input_source {
|
||||
use hbb_common::SessionID;
|
||||
|
||||
use crate::ui_interface::{get_local_option, set_local_option};
|
||||
use hbb_common::log;
|
||||
|
||||
pub const CONFIG_OPTION_INPUT_SOURCE: &str = "input-source";
|
||||
// rdev grab mode
|
||||
@ -1087,34 +1093,32 @@ pub mod input_source {
|
||||
pub const CONFIG_INPUT_SOURCE_2: &str = "Input source 2";
|
||||
pub const CONFIG_INPUT_SOURCE_2_TIP: &str = "input_source_2_tip";
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub const CONFIG_INPUT_SOURCE_DEFAULT: &str = CONFIG_INPUT_SOURCE_1;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const CONFIG_INPUT_SOURCE_DEFAULT: &str = CONFIG_INPUT_SOURCE_2;
|
||||
|
||||
pub fn init_input_source() {
|
||||
let cur_input_source = get_cur_session_input_source();
|
||||
if cur_input_source == CONFIG_INPUT_SOURCE_1 {
|
||||
#[cfg(target_os = "macos")]
|
||||
if !crate::platform::macos::is_can_input_monitoring(false) {
|
||||
log::error!("init_input_source, is_can_input_monitoring() false");
|
||||
set_local_option(
|
||||
CONFIG_OPTION_INPUT_SOURCE.to_string(),
|
||||
CONFIG_INPUT_SOURCE_2.to_string(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
if !crate::platform::linux::is_x11() {
|
||||
// If switching from X11 to Wayland, the grab loop will not be started.
|
||||
// Do not change the config here.
|
||||
return;
|
||||
}
|
||||
super::start_grab_loop();
|
||||
#[cfg(target_os = "linux")]
|
||||
if !crate::platform::linux::is_x11() {
|
||||
// If switching from X11 to Wayland, the grab loop will not be started.
|
||||
// Do not change the config here.
|
||||
return;
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
if !crate::platform::macos::is_can_input_monitoring(false) {
|
||||
log::error!("init_input_source, is_can_input_monitoring() false");
|
||||
set_local_option(
|
||||
CONFIG_OPTION_INPUT_SOURCE.to_string(),
|
||||
CONFIG_INPUT_SOURCE_2.to_string(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if cur_input_source == CONFIG_INPUT_SOURCE_1 {
|
||||
super::IS_RDEV_ENABLED.store(true, super::Ordering::SeqCst);
|
||||
}
|
||||
super::start_grab_loop();
|
||||
}
|
||||
|
||||
pub fn change_input_source(input_source: &str) {
|
||||
pub fn change_input_source(session_id: SessionID, input_source: String) {
|
||||
let cur_input_source = get_cur_session_input_source();
|
||||
if cur_input_source == input_source {
|
||||
return;
|
||||
@ -1125,17 +1129,16 @@ pub mod input_source {
|
||||
log::error!("change_input_source, is_can_input_monitoring() false");
|
||||
return;
|
||||
}
|
||||
// It is ok to start grab loop multiple times.
|
||||
super::start_grab_loop();
|
||||
super::IS_RDEV_ENABLED.store(true, super::Ordering::SeqCst);
|
||||
crate::flutter_ffi::session_enter_or_leave(session_id, true);
|
||||
} else if input_source == CONFIG_INPUT_SOURCE_2 {
|
||||
if let Err(e) = super::stop_grab_loop() {
|
||||
log::error!("change_input_source, stop_grab_loop error: {:?}", e);
|
||||
return;
|
||||
}
|
||||
// No need to stop grab loop.
|
||||
crate::flutter_ffi::session_enter_or_leave(session_id, false);
|
||||
super::IS_RDEV_ENABLED.store(false, super::Ordering::SeqCst);
|
||||
}
|
||||
set_local_option(
|
||||
CONFIG_OPTION_INPUT_SOURCE.to_string(),
|
||||
input_source.to_string(),
|
||||
);
|
||||
set_local_option(CONFIG_OPTION_INPUT_SOURCE.to_string(), input_source);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1152,11 +1155,6 @@ pub mod input_source {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_cur_input_source_rdev() -> bool {
|
||||
get_cur_session_input_source() == CONFIG_INPUT_SOURCE_1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_supported_input_source() -> Vec<(String, String)> {
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -5,8 +5,6 @@ use crate::{
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use rdev::{Event, EventType::*, KeyCode};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
@ -43,9 +41,6 @@ use crate::common::GrabState;
|
||||
use crate::keyboard;
|
||||
use crate::{client::Data, client::Interface};
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
const CHANGE_RESOLUTION_VALID_TIMEOUT_SECS: u64 = 15;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
@ -725,13 +720,11 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub fn enter(&self, keyboard_mode: String) {
|
||||
IS_IN.store(true, Ordering::SeqCst);
|
||||
keyboard::client::change_grab_status(GrabState::Run, &keyboard_mode);
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
pub fn leave(&self, keyboard_mode: String) {
|
||||
IS_IN.store(false, Ordering::SeqCst);
|
||||
keyboard::client::change_grab_status(GrabState::Wait, &keyboard_mode);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user