mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-01-18 15:53:00 +08:00
linux_wayland_support: dup detecting function of x11 or wayland
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
634cb5ef1a
commit
00dc473703
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1266,6 +1266,7 @@ name = "enigo"
|
|||||||
version = "0.0.14"
|
version = "0.0.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-graphics 0.22.3",
|
"core-graphics 0.22.3",
|
||||||
|
"hbb_common",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"objc",
|
"objc",
|
||||||
|
@ -22,6 +22,7 @@ appveyor = { repository = "pythoneer/enigo-85xiy" }
|
|||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
serde_derive = { version = "1.0", optional = true }
|
serde_derive = { version = "1.0", optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
hbb_common = { path = "../hbb_common" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
with_serde = ["serde", "serde_derive"]
|
with_serde = ["serde", "serde_derive"]
|
||||||
|
@ -74,7 +74,7 @@ pub use macos::Enigo;
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod linux;
|
mod linux;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub use crate::linux::{is_x11, Enigo};
|
pub use crate::linux::Enigo;
|
||||||
|
|
||||||
/// DSL parser module
|
/// DSL parser module
|
||||||
pub mod dsl;
|
pub mod dsl;
|
||||||
|
@ -3,35 +3,3 @@ mod pynput;
|
|||||||
mod xdo;
|
mod xdo;
|
||||||
|
|
||||||
pub use self::nix_impl::Enigo;
|
pub use self::nix_impl::Enigo;
|
||||||
|
|
||||||
/// Check if display manager is x11.
|
|
||||||
pub fn is_x11() -> bool {
|
|
||||||
let stdout =
|
|
||||||
match std::process::Command::new("sh")
|
|
||||||
.arg("-c")
|
|
||||||
.arg("loginctl show-session $(loginctl | awk '/tty/ {print $1}') -p Type | awk -F= '{print $2}'")
|
|
||||||
.output() {
|
|
||||||
Ok(output) => {
|
|
||||||
output.stdout
|
|
||||||
},
|
|
||||||
Err(_) => {
|
|
||||||
match std::process::Command::new("sh")
|
|
||||||
.arg("-c")
|
|
||||||
.arg("echo $XDG_SESSION_TYPE")
|
|
||||||
.output() {
|
|
||||||
Ok(output) => {
|
|
||||||
output.stdout
|
|
||||||
},
|
|
||||||
Err(_) => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Ok(display_manager) = std::str::from_utf8(&stdout) {
|
|
||||||
display_manager.trim() == "x11"
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -40,7 +40,7 @@ impl Enigo {
|
|||||||
impl Default for Enigo {
|
impl Default for Enigo {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
is_x11: crate::linux::is_x11(),
|
is_x11: "x11" == hbb_common::platform::linux::get_display_server(),
|
||||||
uinput_keyboard: None,
|
uinput_keyboard: None,
|
||||||
uinput_mouse: None,
|
uinput_mouse: None,
|
||||||
xdo: EnigoXdo::default(),
|
xdo: EnigoXdo::default(),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
pub mod compress;
|
pub mod compress;
|
||||||
pub mod protos;
|
pub mod protos;
|
||||||
|
pub mod platform;
|
||||||
pub use protos::message as message_proto;
|
pub use protos::message as message_proto;
|
||||||
pub use protos::rendezvous as rendezvous_proto;
|
pub use protos::rendezvous as rendezvous_proto;
|
||||||
pub use bytes;
|
pub use bytes;
|
||||||
|
102
libs/hbb_common/src/platform/linux.rs
Normal file
102
libs/hbb_common/src/platform/linux.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use crate::ResultType;
|
||||||
|
|
||||||
|
pub fn get_display_server() -> String {
|
||||||
|
let session = get_value_of_seat0(0);
|
||||||
|
get_display_server_of_session(&session)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_display_server_of_session(session: &str) -> String {
|
||||||
|
if let Ok(output) = std::process::Command::new("loginctl")
|
||||||
|
.args(vec!["show-session", "-p", "Type", session])
|
||||||
|
.output()
|
||||||
|
// Check session type of the session
|
||||||
|
{
|
||||||
|
let display_server = String::from_utf8_lossy(&output.stdout)
|
||||||
|
.replace("Type=", "")
|
||||||
|
.trim_end()
|
||||||
|
.into();
|
||||||
|
if display_server == "tty" {
|
||||||
|
// If the type is tty...
|
||||||
|
if let Ok(output) = std::process::Command::new("loginctl")
|
||||||
|
.args(vec!["show-session", "-p", "TTY", session])
|
||||||
|
.output()
|
||||||
|
// Get the tty number
|
||||||
|
{
|
||||||
|
let tty: String = String::from_utf8_lossy(&output.stdout)
|
||||||
|
.replace("TTY=", "")
|
||||||
|
.trim_end()
|
||||||
|
.into();
|
||||||
|
if let Ok(xorg_results) = run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty))
|
||||||
|
// And check if Xorg is running on that tty
|
||||||
|
{
|
||||||
|
if xorg_results.trim_end().to_string() != "" {
|
||||||
|
// If it is, manually return "x11", otherwise return tty
|
||||||
|
"x11".to_owned()
|
||||||
|
} else {
|
||||||
|
display_server
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If any of these commands fail just fall back to the display server
|
||||||
|
display_server
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
display_server
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If the session is not a tty, then just return the type as usual
|
||||||
|
display_server
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"".to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_value_of_seat0(i: usize) -> String {
|
||||||
|
if let Ok(output) = std::process::Command::new("loginctl").output() {
|
||||||
|
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
||||||
|
if line.contains("seat0") {
|
||||||
|
if let Some(sid) = line.split_whitespace().nth(0) {
|
||||||
|
if is_active(sid) {
|
||||||
|
if let Some(uid) = line.split_whitespace().nth(i) {
|
||||||
|
return uid.to_owned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73
|
||||||
|
if let Ok(output) = std::process::Command::new("loginctl").output() {
|
||||||
|
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
||||||
|
if let Some(sid) = line.split_whitespace().nth(0) {
|
||||||
|
let d = get_display_server_of_session(sid);
|
||||||
|
if is_active(sid) && d != "tty" {
|
||||||
|
if let Some(uid) = line.split_whitespace().nth(i) {
|
||||||
|
return uid.to_owned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "".to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_active(sid: &str) -> bool {
|
||||||
|
if let Ok(output) = std::process::Command::new("loginctl")
|
||||||
|
.args(vec!["show-session", "-p", "State", sid])
|
||||||
|
.output()
|
||||||
|
{
|
||||||
|
String::from_utf8_lossy(&output.stdout).contains("active")
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_cmds(cmds: String) -> ResultType<String> {
|
||||||
|
let output = std::process::Command::new("sh")
|
||||||
|
.args(vec!["-c", &cmds])
|
||||||
|
.output()?;
|
||||||
|
Ok(String::from_utf8_lossy(&output.stdout).to_string())
|
||||||
|
}
|
2
libs/hbb_common/src/platform/mod.rs
Normal file
2
libs/hbb_common/src/platform/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub mod linux;
|
@ -52,31 +52,30 @@ pub enum Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_wayland() -> bool {
|
pub fn is_x11() -> bool {
|
||||||
std::env::var("IS_WAYLAND").is_ok()
|
"x11" == hbb_common::platform::linux::get_display_server()
|
||||||
|| std::env::var("XDG_SESSION_TYPE") == Ok("wayland".to_owned())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
pub fn primary() -> io::Result<Display> {
|
pub fn primary() -> io::Result<Display> {
|
||||||
Ok(if is_wayland() {
|
Ok(if is_x11() {
|
||||||
Display::WAYLAND(wayland::Display::primary()?)
|
|
||||||
} else {
|
|
||||||
Display::X11(x11::Display::primary()?)
|
Display::X11(x11::Display::primary()?)
|
||||||
|
} else {
|
||||||
|
Display::WAYLAND(wayland::Display::primary()?)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all() -> io::Result<Vec<Display>> {
|
pub fn all() -> io::Result<Vec<Display>> {
|
||||||
Ok(if is_wayland() {
|
Ok(if is_x11() {
|
||||||
wayland::Display::all()?
|
|
||||||
.drain(..)
|
|
||||||
.map(|x| Display::WAYLAND(x))
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
x11::Display::all()?
|
x11::Display::all()?
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|x| Display::X11(x))
|
.map(|x| Display::X11(x))
|
||||||
.collect()
|
.collect()
|
||||||
|
} else {
|
||||||
|
wayland::Display::all()?
|
||||||
|
.drain(..)
|
||||||
|
.map(|x| Display::WAYLAND(x))
|
||||||
|
.collect()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::{CursorData, ResultType};
|
use super::{CursorData, ResultType};
|
||||||
|
pub use hbb_common::platform::linux::*;
|
||||||
use hbb_common::{allow_err, bail, log};
|
use hbb_common::{allow_err, bail, log};
|
||||||
use libc::{c_char, c_int, c_void};
|
use libc::{c_char, c_int, c_void};
|
||||||
use std::{
|
use std::{
|
||||||
@ -8,6 +9,7 @@ use std::{
|
|||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Xdo = *const c_void;
|
type Xdo = *const c_void;
|
||||||
|
|
||||||
pub const PA_SAMPLE_RATE: u32 = 48000;
|
pub const PA_SAMPLE_RATE: u32 = 48000;
|
||||||
@ -335,17 +337,6 @@ pub fn get_active_userid() -> String {
|
|||||||
get_value_of_seat0(1)
|
get_value_of_seat0(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_active(sid: &str) -> bool {
|
|
||||||
if let Ok(output) = std::process::Command::new("loginctl")
|
|
||||||
.args(vec!["show-session", "-p", "State", sid])
|
|
||||||
.output()
|
|
||||||
{
|
|
||||||
String::from_utf8_lossy(&output.stdout).contains("active")
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_cm() -> bool {
|
fn get_cm() -> bool {
|
||||||
if let Ok(output) = std::process::Command::new("ps").args(vec!["aux"]).output() {
|
if let Ok(output) = std::process::Command::new("ps").args(vec!["aux"]).output() {
|
||||||
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
||||||
@ -401,89 +392,6 @@ fn get_display() -> String {
|
|||||||
last
|
last
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_value_of_seat0(i: usize) -> String {
|
|
||||||
if let Ok(output) = std::process::Command::new("loginctl").output() {
|
|
||||||
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
|
||||||
if line.contains("seat0") {
|
|
||||||
if let Some(sid) = line.split_whitespace().nth(0) {
|
|
||||||
if is_active(sid) {
|
|
||||||
if let Some(uid) = line.split_whitespace().nth(i) {
|
|
||||||
return uid.to_owned();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73
|
|
||||||
if let Ok(output) = std::process::Command::new("loginctl").output() {
|
|
||||||
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
|
||||||
if let Some(sid) = line.split_whitespace().nth(0) {
|
|
||||||
let d = get_display_server_of_session(sid);
|
|
||||||
if is_active(sid) && d != "tty" {
|
|
||||||
if let Some(uid) = line.split_whitespace().nth(i) {
|
|
||||||
return uid.to_owned();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "".to_owned();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_display_server() -> String {
|
|
||||||
let session = get_value_of_seat0(0);
|
|
||||||
get_display_server_of_session(&session)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_display_server_of_session(session: &str) -> String {
|
|
||||||
if let Ok(output) = std::process::Command::new("loginctl")
|
|
||||||
.args(vec!["show-session", "-p", "Type", session])
|
|
||||||
.output()
|
|
||||||
// Check session type of the session
|
|
||||||
{
|
|
||||||
let display_server = String::from_utf8_lossy(&output.stdout)
|
|
||||||
.replace("Type=", "")
|
|
||||||
.trim_end()
|
|
||||||
.into();
|
|
||||||
if display_server == "tty" {
|
|
||||||
// If the type is tty...
|
|
||||||
if let Ok(output) = std::process::Command::new("loginctl")
|
|
||||||
.args(vec!["show-session", "-p", "TTY", session])
|
|
||||||
.output()
|
|
||||||
// Get the tty number
|
|
||||||
{
|
|
||||||
let tty: String = String::from_utf8_lossy(&output.stdout)
|
|
||||||
.replace("TTY=", "")
|
|
||||||
.trim_end()
|
|
||||||
.into();
|
|
||||||
if let Ok(xorg_results) = run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty))
|
|
||||||
// And check if Xorg is running on that tty
|
|
||||||
{
|
|
||||||
if xorg_results.trim_end().to_string() != "" {
|
|
||||||
// If it is, manually return "x11", otherwise return tty
|
|
||||||
"x11".to_owned()
|
|
||||||
} else {
|
|
||||||
display_server
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If any of these commands fail just fall back to the display server
|
|
||||||
display_server
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
display_server
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the session is not a tty, then just return the type as usual
|
|
||||||
display_server
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
"".to_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_login_wayland() -> bool {
|
pub fn is_login_wayland() -> bool {
|
||||||
if let Ok(contents) = std::fs::read_to_string("/etc/gdm3/custom.conf") {
|
if let Ok(contents) = std::fs::read_to_string("/etc/gdm3/custom.conf") {
|
||||||
contents.contains("#WaylandEnable=false")
|
contents.contains("#WaylandEnable=false")
|
||||||
@ -690,13 +598,6 @@ pub fn is_installed() -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_cmds(cmds: String) -> ResultType<String> {
|
|
||||||
let output = std::process::Command::new("sh")
|
|
||||||
.args(vec!["-c", &cmds])
|
|
||||||
.output()?;
|
|
||||||
Ok(String::from_utf8_lossy(&output.stdout).to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_env_tries(name: &str, uid: &str, n: usize) -> String {
|
fn get_env_tries(name: &str, uid: &str, n: usize) -> String {
|
||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
let x = get_env(name, uid);
|
let x = get_env(name, uid);
|
||||||
|
@ -193,7 +193,7 @@ fn check_display_changed(
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
// wayland do not support changing display for now
|
// wayland do not support changing display for now
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ impl DerefMut for CapturerInfo {
|
|||||||
fn get_capturer(use_yuv: bool) -> ResultType<CapturerInfo> {
|
fn get_capturer(use_yuv: bool) -> ResultType<CapturerInfo> {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
return super::wayland::get_capturer();
|
return super::wayland::get_capturer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -702,7 +702,7 @@ pub fn handle_one_frame_encoded(
|
|||||||
fn get_display_num() -> usize {
|
fn get_display_num() -> usize {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
return if let Ok(n) = super::wayland::get_display_num() {
|
return if let Ok(n) = super::wayland::get_display_num() {
|
||||||
n
|
n
|
||||||
} else {
|
} else {
|
||||||
@ -745,7 +745,7 @@ pub(super) fn get_displays_2(all: &Vec<Display>) -> (usize, Vec<DisplayInfo>) {
|
|||||||
pub async fn get_displays() -> ResultType<(usize, Vec<DisplayInfo>)> {
|
pub async fn get_displays() -> ResultType<(usize, Vec<DisplayInfo>)> {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
return super::wayland::get_displays().await;
|
return super::wayland::get_displays().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -774,7 +774,7 @@ pub fn refresh() {
|
|||||||
fn get_primary() -> usize {
|
fn get_primary() -> usize {
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
return match super::wayland::get_primary() {
|
return match super::wayland::get_primary() {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(_) => 0,
|
Err(_) => 0,
|
||||||
|
@ -28,7 +28,7 @@ impl super::video_service::TraitCapturer for *mut Capturer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn check_init() -> ResultType<()> {
|
async fn check_init() -> ResultType<()> {
|
||||||
if scrap::is_wayland() {
|
if !scrap::is_x11() {
|
||||||
let mut minx = 0;
|
let mut minx = 0;
|
||||||
let mut maxx = 0;
|
let mut maxx = 0;
|
||||||
let mut miny = 0;
|
let mut miny = 0;
|
||||||
@ -96,7 +96,7 @@ async fn check_init() -> ResultType<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear() {
|
pub fn clear() {
|
||||||
if !scrap::is_wayland() {
|
if scrap::is_x11() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ pub(super) fn get_display_num() -> ResultType<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_capturer() -> ResultType<super::video_service::CapturerInfo> {
|
pub(super) fn get_capturer() -> ResultType<super::video_service::CapturerInfo> {
|
||||||
if !scrap::is_wayland() {
|
if scrap::is_x11() {
|
||||||
bail!("Do not call this function if not wayland");
|
bail!("Do not call this function if not wayland");
|
||||||
}
|
}
|
||||||
let addr = *CAP_DISPLAY_INFO.read().unwrap();
|
let addr = *CAP_DISPLAY_INFO.read().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user