Skip to content

Commit

Permalink
refact: clipboard listener
Browse files Browse the repository at this point in the history
Signed-off-by: fufesou <[email protected]>
  • Loading branch information
fufesou committed Dec 27, 2024
1 parent f5e8828 commit 938c1c3
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 217 deletions.
17 changes: 0 additions & 17 deletions .github/workflows/flutter-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,6 @@ jobs:
unzip \
wget \
xz-utils \
fuse \
libfuse-dev
# we have libopus compiled by us.
apt-get remove -y libopus-dev || true
Expand All @@ -1551,13 +1550,6 @@ jobs:
# start build
pushd /workspace
export VCPKG_ROOT=/opt/artifacts/vcpkg
# # build libfuse for feature "unix-file-copy-paste", we can use `apt install fuse3,libfuse3-dev` if we use ubuntu 20.04
# sudo apt install -y meson ninja-build
# git clone https://github.com/libfuse/libfuse.git
# pushd libfuse
# git checkout fuse-3.16.2
# mkdir build && cd build && meson .. && ninja install
# popd
if [[ "${{ matrix.job.arch }}" == "aarch64" ]]; then
export JOBS="--jobs 3"
else
Expand Down Expand Up @@ -1804,7 +1796,6 @@ jobs:
wget \
xz-utils \
zip \
fuse \
libfuse-dev
# arm-linux needs CMake and vcokg built from source as there
# are no prebuilts available from Kitware and Microsoft
Expand Down Expand Up @@ -1882,14 +1873,6 @@ jobs:
exit 1
fi
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
# # build libfuse for feature "unix-file-copy-paste", we can use `apt install fuse3,libfuse3-dev` if we use ubuntu 20.04
# sudo apt install -y meson ninja-build
# git clone https://github.com/libfuse/libfuse.git
# pushd libfuse
# git checkout fuse-3.16.2
# mkdir build && cd build && meson .. && ninja install
# popd
# build rustdesk
python3 ./res/inline-sciter.py
export CARGO_INCREMENTAL=0
cargo build --features inline${{ matrix.job.extra_features }} --release --bins --jobs 1
Expand Down
1 change: 1 addition & 0 deletions appimage/AppImageBuilder-aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ AppDir:
- libcanberra-gtk3-module
- libpam0g
- libdrm2
- libfuse2
exclude:
- humanity-icon-theme
- hicolor-icon-theme
Expand Down
1 change: 1 addition & 0 deletions appimage/AppImageBuilder-x86_64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ AppDir:
- libcanberra-gtk3-module
- libpam0g
- libdrm2
- libfuse2
exclude:
- humanity-icon-theme
- hicolor-icon-theme
Expand Down
1 change: 1 addition & 0 deletions libs/clipboard/src/platform/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ impl FuseServer {

let mut retry_times = 0;

// to-do: more tests needed
loop {
let reply = self.rx.recv_timeout(self.timeout).map_err(|e| {
log::error!("failed to receive file list from channel: {:?}", e);
Expand Down
2 changes: 1 addition & 1 deletion res/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ arch=('x86_64')
url=""
license=('AGPL-3.0')
groups=()
depends=('gtk3' 'xdotool' 'libxcb' 'libxfixes' 'alsa-lib' 'libva' 'libappindicator-gtk3' 'pam' 'gst-plugins-base' 'gst-plugin-pipewire')
depends=('gtk3' 'xdotool' 'libxcb' 'libxfixes' 'alsa-lib' 'libva' 'libappindicator-gtk3' 'pam' 'gst-plugins-base' 'gst-plugin-pipewire' 'libfuse2')
makedepends=()
checkdepends=()
optdepends=()
Expand Down
118 changes: 53 additions & 65 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use crate::clipboard::clipboard_listener;
use async_trait::async_trait;
use bytes::Bytes;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
Expand Down Expand Up @@ -174,6 +176,8 @@ pub fn get_key_state(key: enigo::Key) -> bool {
}

impl Client {
const CLIENT_CLIPBOARD_NAME: &'static str = "client-clipboard";

/// Start a new connection.
pub async fn start(
peer: &str,
Expand Down Expand Up @@ -685,6 +689,8 @@ impl Client {
if crate::flutter::sessions::has_sessions_running(ConnType::DEFAULT_CONN) {
return;
}
#[cfg(not(target_os = "android"))]
clipboard_listener::unsubscribe(Self::CLIENT_CLIPBOARD_NAME);
CLIPBOARD_STATE.lock().unwrap().running = false;
}

Expand All @@ -703,40 +709,33 @@ impl Client {
}

let (tx_cb_result, rx_cb_result) = mpsc::channel();
let handler = ClientClipboardHandler {
ctx: None,
tx_cb_result,
#[cfg(not(feature = "flutter"))]
client_clip_ctx: _client_clip_ctx,
};

let (tx_start_res, rx_start_res) = mpsc::channel();
let h = crate::clipboard::start_clipbard_master_thread(handler, tx_start_res);
let shutdown = match rx_start_res.recv() {
Ok((Some(s), _)) => s,
Ok((None, err)) => {
log::error!("{}", err);
return None;
}
Err(e) => {
log::error!("Failed to create clipboard listener: {}", e);
return None;
}
};
if let Err(e) =
clipboard_listener::subscribe(Self::CLIENT_CLIPBOARD_NAME.to_owned(), tx_cb_result)
{
log::error!("Failed to subscribe clipboard listener: {}", e);
return None;
}

clipboard_lock.running = true;

let (tx_started, rx_started) = unbounded_channel();

log::info!("Start text clipboard loop");
log::info!("Start client clipboard loop");
std::thread::spawn(move || {
tx_started.send(()).ok();
let mut handler = ClientClipboardHandler {
ctx: None,
#[cfg(not(feature = "flutter"))]
client_clip_ctx: _client_clip_ctx,
};

tx_started.send(()).ok();
loop {
if !CLIPBOARD_STATE.lock().unwrap().running {
break;
}
match rx_cb_result.recv_timeout(Duration::from_millis(CLIPBOARD_INTERVAL)) {
Ok(CallbackResult::Next) => {
handler.check_clipboard();
}
Ok(CallbackResult::Stop) => {
log::debug!("Clipboard listener stopped");
break;
Expand All @@ -746,12 +745,13 @@ impl Client {
break;
}
Err(RecvTimeoutError::Timeout) => {}
_ => {}
Err(RecvTimeoutError::Disconnected) => {
log::error!("Clipboard listener disconnected");
break;
}
}
}
log::info!("Stop text clipboard loop");
shutdown.signal();
h.join().ok();
log::info!("Stop client clipboard loop");
CLIPBOARD_STATE.lock().unwrap().running = false;
});

Expand All @@ -766,7 +766,7 @@ impl Client {
}
clipboard_lock.running = true;

log::info!("Start text clipboard loop");
log::info!("Start client clipboard loop");
std::thread::spawn(move || {
loop {
if !CLIPBOARD_STATE.lock().unwrap().running {
Expand All @@ -783,7 +783,7 @@ impl Client {

std::thread::sleep(Duration::from_millis(CLIPBOARD_INTERVAL));
}
log::info!("Stop text clipboard loop");
log::info!("Stop client clipboard loop");
CLIPBOARD_STATE.lock().unwrap().running = false;
});

Expand All @@ -807,7 +807,6 @@ impl ClipboardState {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
struct ClientClipboardHandler {
ctx: Option<crate::clipboard::ClipboardContext>,
tx_cb_result: Sender<CallbackResult>,
#[cfg(not(feature = "flutter"))]
client_clip_ctx: Option<ClientClipboardContext>,
}
Expand Down Expand Up @@ -843,6 +842,30 @@ impl ClientClipboardHandler {
}
}

fn check_clipboard(&mut self) {
if CLIPBOARD_STATE.lock().unwrap().running {
#[cfg(feature = "unix-file-copy-paste")]
if self.is_file_required() {
if let Some(msg) =
check_clipboard_files(&mut self.ctx, ClipboardSide::Client, false)
{
if !msg.is_empty() {
let msg =
crate::clipboard_file::clip_2_msg(unix_file_clip::get_format_list());
self.send_msg(msg, true);
return;
}
}
}

if self.is_text_required() {
if let Some(msg) = check_clipboard(&mut self.ctx, ClipboardSide::Client, false) {
self.send_msg(msg, false);
}
}
}
}

#[inline]
#[cfg(feature = "flutter")]
fn send_msg(&self, msg: Message, _is_file: bool) {
Expand Down Expand Up @@ -875,41 +898,6 @@ impl ClientClipboardHandler {
}
}

#[cfg(not(any(target_os = "android", target_os = "ios")))]
impl ClipboardHandler for ClientClipboardHandler {
fn on_clipboard_change(&mut self) -> CallbackResult {
if CLIPBOARD_STATE.lock().unwrap().running {
#[cfg(feature = "unix-file-copy-paste")]
if self.is_file_required() {
if let Some(msg) =
check_clipboard_files(&mut self.ctx, ClipboardSide::Client, false)
{
if !msg.is_empty() {
let msg =
crate::clipboard_file::clip_2_msg(unix_file_clip::get_format_list());
self.send_msg(msg, true);
return CallbackResult::Next;
}
}
}

if self.is_text_required() {
if let Some(msg) = check_clipboard(&mut self.ctx, ClipboardSide::Client, false) {
self.send_msg(msg, false);
}
}
}
CallbackResult::Next
}

fn on_clipboard_error(&mut self, error: io::Error) -> CallbackResult {
self.tx_cb_result
.send(CallbackResult::StopWithError(error))
.ok();
CallbackResult::Next
}
}

/// Audio handler for the [`Client`].
#[derive(Default)]
pub struct AudioHandler {
Expand Down
Loading

0 comments on commit 938c1c3

Please sign in to comment.