mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-09-17 09:51:08 +03:00
Compare commits
11 Commits
main-497a1
...
main-00c5e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00c5eee8d8 | ||
|
|
6b1eddef7a | ||
|
|
09889cd839 | ||
|
|
c194df791d | ||
|
|
b316af6a8f | ||
|
|
d09a574380 | ||
|
|
b115208aad | ||
|
|
392af44cbe | ||
|
|
133e1ae81d | ||
|
|
6fb7e24746 | ||
|
|
d1f41180e3 |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -105,7 +105,7 @@ jobs:
|
|||||||
# see https://github.com/wingtk/gvsbuild/pull/1004
|
# see https://github.com/wingtk/gvsbuild/pull/1004
|
||||||
Move-Item "C:\Program Files\Git\usr\bin" "C:\Program Files\Git\usr\notbin"
|
Move-Item "C:\Program Files\Git\usr\bin" "C:\Program Files\Git\usr\notbin"
|
||||||
Move-Item "C:\Program Files\Git\bin" "C:\Program Files\Git\notbin"
|
Move-Item "C:\Program Files\Git\bin" "C:\Program Files\Git\notbin"
|
||||||
gvsbuild build --msys-dir=C:\msys64 gtk4 libadwaita librsvg
|
gvsbuild build --vs-ver=vs2026 --msys-dir=C:\msys64 gtk4 libadwaita librsvg
|
||||||
Move-Item "C:\Program Files\Git\usr\notbin" "C:\Program Files\Git\usr\bin"
|
Move-Item "C:\Program Files\Git\usr\notbin" "C:\Program Files\Git\usr\bin"
|
||||||
Move-Item "C:\Program Files\Git\notbin" "C:\Program Files\Git\bin"
|
Move-Item "C:\Program Files\Git\notbin" "C:\Program Files\Git\bin"
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -204,7 +204,11 @@ jobs:
|
|||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: |
|
files: |
|
||||||
lan-mouse-linux-x86_64/lan-mouse-linux-x86_64
|
lan-mouse-linux-x86_64/lan-mouse-linux-x86_64
|
||||||
|
lan-mouse-linux-x86_64/target/release/bundle/deb/lan-mouse_*.deb
|
||||||
|
lan-mouse-linux-x86_64/target/release/bundle/appimage/lan-mouse_*.AppImage
|
||||||
lan-mouse-linux-arm64/lan-mouse-linux-arm64
|
lan-mouse-linux-arm64/lan-mouse-linux-arm64
|
||||||
|
lan-mouse-linux-arm64/target/release/bundle/deb/lan-mouse_*.deb
|
||||||
|
lan-mouse-linux-arm64/target/release/bundle/appimage/lan-mouse_*.AppImage
|
||||||
lan-mouse-macos-intel/lan-mouse-macos-intel.zip
|
lan-mouse-macos-intel/lan-mouse-macos-intel.zip
|
||||||
lan-mouse-macos-arm64/lan-mouse-macos-arm64.zip
|
lan-mouse-macos-arm64/lan-mouse-macos-arm64.zip
|
||||||
lan-mouse-windows-x86_64/lan-mouse-windows-x86_64.zip
|
lan-mouse-windows-x86_64/lan-mouse-windows-x86_64.zip
|
||||||
|
|||||||
10
.github/workflows/rust.yml
vendored
10
.github/workflows/rust.yml
vendored
@@ -40,7 +40,6 @@ jobs:
|
|||||||
- test
|
- test
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
- name: Install Linux deps
|
- name: Install Linux deps
|
||||||
if: runner.os == 'Linux'
|
if: runner.os == 'Linux'
|
||||||
run: |
|
run: |
|
||||||
@@ -49,6 +48,13 @@ jobs:
|
|||||||
- name: Install macOS dependencies
|
- name: Install macOS dependencies
|
||||||
if: runner.os == 'macOS'
|
if: runner.os == 'macOS'
|
||||||
run: brew install gtk4 libadwaita imagemagick
|
run: brew install gtk4 libadwaita imagemagick
|
||||||
|
- name: Record macOS native lib versions for cache key
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
echo "MACOS_LIB_VER=$(brew list --versions glib gtk4 libadwaita | tr '\n' '_')" >> "$GITHUB_ENV"
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
prefix-key: ${{ env.MACOS_LIB_VER }}
|
||||||
- name: Install Windows Dependencies - create gtk dir
|
- name: Install Windows Dependencies - create gtk dir
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
run: mkdir C:\gtk-build\gtk\x64\release
|
run: mkdir C:\gtk-build\gtk\x64\release
|
||||||
@@ -77,7 +83,7 @@ jobs:
|
|||||||
py -m venv .venv
|
py -m venv .venv
|
||||||
.venv\Scripts\activate.ps1
|
.venv\Scripts\activate.ps1
|
||||||
py -m pip install gvsbuild
|
py -m pip install gvsbuild
|
||||||
gvsbuild build --msys-dir=C:\msys64 gtk4 libadwaita librsvg
|
gvsbuild build --vs-ver=vs2026 --msys-dir=C:\msys64 gtk4 libadwaita librsvg
|
||||||
- name: cargo build
|
- name: cargo build
|
||||||
if: matrix.job == 'build'
|
if: matrix.job == 'build'
|
||||||
run: cargo build
|
run: cargo build
|
||||||
|
|||||||
39
Cargo.lock
generated
39
Cargo.lock
generated
@@ -1898,12 +1898,6 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.4.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
@@ -2489,12 +2483,14 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reis"
|
name = "reis"
|
||||||
version = "0.5.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00939c5c526a1b4054ef8d9d96b3f92227f08ca355965e986741b556eda6d289"
|
checksum = "81f3fedd2777cde52c1be5e572efbec485eac7b801c47820eda388d4f13b9c4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"enumflags2",
|
||||||
"rustix 0.38.44",
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"rustix",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2540,19 +2536,6 @@ dependencies = [
|
|||||||
"nom",
|
"nom",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustix"
|
|
||||||
version = "0.38.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.11.0",
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys 0.4.15",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
@@ -2562,7 +2545,7 @@ dependencies = [
|
|||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.12.1",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2880,7 +2863,7 @@ dependencies = [
|
|||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.4.2",
|
"getrandom 0.4.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.1.4",
|
"rustix",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3388,7 +3371,7 @@ checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
"rustix 1.1.4",
|
"rustix",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
]
|
]
|
||||||
@@ -3400,7 +3383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
|
checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.0",
|
"bitflags 2.11.0",
|
||||||
"rustix 1.1.4",
|
"rustix",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
]
|
]
|
||||||
@@ -4065,7 +4048,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
"ordered-stream",
|
"ordered-stream",
|
||||||
"rustix 1.1.4",
|
"rustix",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
14
flake.lock
generated
14
flake.lock
generated
@@ -2,16 +2,16 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772963539,
|
"lastModified": 1788405554,
|
||||||
"narHash": "sha256-9jVDGZnvCckTGdYT53d/EfznygLskyLQXYwJLKMPsZs=",
|
"narHash": "sha256-r2f1oUwixlgq9zOdYLqJLfS/lWBT60/IITjhTKI59JU=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "9dcb002ca1690658be4a04645215baea8b95f31d",
|
"rev": "a5cc6f2c37bf518436dc8d1c288ccd0c43c2f4c4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-unstable",
|
"ref": "nixos-26.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
@@ -29,11 +29,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773025773,
|
"lastModified": 1788505699,
|
||||||
"narHash": "sha256-Wik8+xApNfldpUFjPmJkPdg0RrvUPSWGIZis+A/0N1w=",
|
"narHash": "sha256-PSPDCdbEBEbSDCWcqv5GkbyD2ACQ9Diz6vmEbWdy4dM=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "3c06fdbbd36ff60386a1e590ee0cd52dcd1892bf",
|
"rev": "9eccf73c5b810052f08aa77ae0548c383259f17f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
24
flake.nix
24
flake.nix
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
description = "Nix Flake for lan-mouse";
|
description = "Nix Flake for lan-mouse";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
# 26.05 used here to keep allowing builds on x86_64-darwin, bump this to unstable once they deprecate 26.05
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05";
|
||||||
rust-overlay = {
|
rust-overlay = {
|
||||||
url = "github:oxalica/rust-overlay";
|
url = "github:oxalica/rust-overlay";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@@ -30,7 +31,24 @@
|
|||||||
let
|
let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [ rust-overlay.overlays.default ];
|
overlays = [
|
||||||
|
rust-overlay.overlays.default
|
||||||
|
|
||||||
|
#NOTE: appstream's meson build injects the literal string
|
||||||
|
# "none required" into linker flags on 'aarch64-darwin', causing clang to fail.
|
||||||
|
# remove this overlay once we bump nixpkgs to unstable branch
|
||||||
|
(
|
||||||
|
final: prev:
|
||||||
|
lib.optionalAttrs prev.stdenv.hostPlatform.isDarwin {
|
||||||
|
appstream = prev.appstream.overrideAttrs (old: {
|
||||||
|
postConfigure = (old.postConfigure or "") + ''
|
||||||
|
substituteInPlace build.ninja \
|
||||||
|
--replace-fail "none required" ""
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
};
|
};
|
||||||
# Default toolchain for devshell
|
# Default toolchain for devshell
|
||||||
rustToolchain = pkgs.rust-bin.stable.latest.default.override {
|
rustToolchain = pkgs.rust-bin.stable.latest.default.override {
|
||||||
@@ -80,7 +98,7 @@
|
|||||||
libadwaita
|
libadwaita
|
||||||
librsvg
|
librsvg
|
||||||
]
|
]
|
||||||
++ lib.optionals pkgs.stdenv.isLinux [
|
++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [
|
||||||
libX11
|
libX11
|
||||||
libXtst
|
libXtst
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ ashpd = { version = "0.13.9", default-features = false, features = [
|
|||||||
"input_capture",
|
"input_capture",
|
||||||
"tokio",
|
"tokio",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
reis = { version = "0.5.0", features = ["tokio"], optional = true }
|
reis = { version = "0.7.0", features = ["tokio"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
core-graphics = { version = "0.25.0", features = ["highsierra"] }
|
core-graphics = { version = "0.25.0", features = ["highsierra"] }
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ struct State {
|
|||||||
focused: Option<Arc<Window>>,
|
focused: Option<Arc<Window>>,
|
||||||
global_list: GlobalList,
|
global_list: GlobalList,
|
||||||
globals: Globals,
|
globals: Globals,
|
||||||
wayland_fd: RawFd,
|
|
||||||
read_guard: Option<ReadEventsGuard>,
|
read_guard: Option<ReadEventsGuard>,
|
||||||
qh: QueueHandle<Self>,
|
qh: QueueHandle<Self>,
|
||||||
pending_events: VecDeque<(Position, CaptureEvent)>,
|
pending_events: VecDeque<(Position, CaptureEvent)>,
|
||||||
@@ -138,7 +137,7 @@ struct Inner {
|
|||||||
|
|
||||||
impl AsRawFd for Inner {
|
impl AsRawFd for Inner {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
self.state.wayland_fd
|
self.queue.as_fd().as_raw_fd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +331,6 @@ impl LayerShellInputCapture {
|
|||||||
active_windows: Vec::new(),
|
active_windows: Vec::new(),
|
||||||
focused: None,
|
focused: None,
|
||||||
qh,
|
qh,
|
||||||
wayland_fd: queue.as_fd().as_raw_fd(),
|
|
||||||
read_guard: None,
|
read_guard: None,
|
||||||
pending_events: VecDeque::new(),
|
pending_events: VecDeque::new(),
|
||||||
outputs: vec![],
|
outputs: vec![],
|
||||||
@@ -548,13 +546,12 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
fn read(&mut self) -> bool {
|
fn read(&mut self) {
|
||||||
match self.state.read_guard.take().unwrap().read() {
|
match self.state.read_guard.take().unwrap().read() {
|
||||||
Ok(_) => true,
|
Ok(_) => {}
|
||||||
Err(WaylandError::Io(e)) if e.kind() == ErrorKind::WouldBlock => false,
|
Err(WaylandError::Io(e)) if e.kind() == ErrorKind::WouldBlock => {}
|
||||||
Err(WaylandError::Io(e)) => {
|
Err(WaylandError::Io(e)) => {
|
||||||
log::error!("error reading from wayland socket: {e}");
|
log::error!("error reading from wayland socket: {e}");
|
||||||
false
|
|
||||||
}
|
}
|
||||||
Err(WaylandError::Protocol(e)) => {
|
Err(WaylandError::Protocol(e)) => {
|
||||||
panic!("wayland protocol violation: {e}")
|
panic!("wayland protocol violation: {e}")
|
||||||
@@ -564,16 +561,11 @@ impl Inner {
|
|||||||
|
|
||||||
fn prepare_read(&mut self) -> io::Result<()> {
|
fn prepare_read(&mut self) -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.queue.prepare_read() {
|
if let Some(guard) = self.queue.prepare_read() {
|
||||||
None => match self.queue.dispatch_pending(&mut self.state) {
|
self.state.read_guard = Some(guard);
|
||||||
Ok(_) => continue,
|
break Ok(());
|
||||||
Err(DispatchError::Backend(WaylandError::Io(e))) => return Err(e),
|
} else {
|
||||||
Err(e) => panic!("failed to dispatch wayland events: {e}"),
|
self.dispatch_events();
|
||||||
},
|
|
||||||
Some(r) => {
|
|
||||||
self.state.read_guard = Some(r);
|
|
||||||
break Ok(());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -655,13 +647,7 @@ impl Stream for LayerShellInputCapture {
|
|||||||
let inner = guard.get_inner_mut();
|
let inner = guard.get_inner_mut();
|
||||||
|
|
||||||
// read events
|
// read events
|
||||||
while inner.read() {
|
inner.read();
|
||||||
// prepare next read
|
|
||||||
match inner.prepare_read() {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => return Poll::Ready(Some(Err(e.into()))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dispatch the events
|
// dispatch the events
|
||||||
inner.dispatch_events();
|
inner.dispatch_events();
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ use reis::{
|
|||||||
use std::{
|
use std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io,
|
env, io,
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
os::unix::net::UnixStream,
|
os::unix::net::UnixStream,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::{Arc, LazyLock},
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@@ -50,6 +50,25 @@ use super::{
|
|||||||
* prevents receiving further events after a session has been disabled once.
|
* prevents receiving further events after a session has been disabled once.
|
||||||
* Therefore the session needs to be recreated when the barriers are updated */
|
* Therefore the session needs to be recreated when the barriers are updated */
|
||||||
|
|
||||||
|
/* mutter also kills the session whenever ei devices come and go, so there the
|
||||||
|
* whole session has to be torn down and recreated on every device change.
|
||||||
|
* Elsewhere that is pure overhead: each restart costs a CreateSession +
|
||||||
|
* ConnectToEIS round trip, and compositors that keep per-session state around
|
||||||
|
* (hyprland leaks a keymap fd per eis session, see hyprwm/Hyprland) can be
|
||||||
|
* driven out of file descriptors by the churn.
|
||||||
|
* Set LM_RESTART_SESSION_ON_DEVICE_CHANGE=1/0 to override the default. */
|
||||||
|
static RESTART_SESSION_ON_DEVICE_CHANGE: LazyLock<bool> =
|
||||||
|
LazyLock::new(restart_session_on_device_change);
|
||||||
|
|
||||||
|
fn restart_session_on_device_change() -> bool {
|
||||||
|
match env::var("LM_RESTART_SESSION_ON_DEVICE_CHANGE").as_deref() {
|
||||||
|
Ok("1") => true,
|
||||||
|
Ok("0") => false,
|
||||||
|
_ => env::var("XDG_CURRENT_DESKTOP")
|
||||||
|
.is_ok_and(|desktops| desktops.to_uppercase().split(':').any(|d| d == "GNOME")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// events that necessitate restarting the capture session
|
/// events that necessitate restarting the capture session
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
enum LibeiNotifyEvent {
|
enum LibeiNotifyEvent {
|
||||||
@@ -413,7 +432,15 @@ async fn do_capture_session(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// find client corresponding to barrier
|
// find client corresponding to barrier
|
||||||
let pos = *pos_for_barrier_id.get(&barrier_id).expect("invalid barrier id");
|
let pos = match pos_for_barrier_id.get(&barrier_id) {
|
||||||
|
Some(id) => *id,
|
||||||
|
None => {
|
||||||
|
log::warn!("INVALID BARRIER ID: Id {barrier_id} does not exist!");
|
||||||
|
let id = find_corresponding_client(&barriers, activated.cursor_position().expect("no cursor position reported by compositor"));
|
||||||
|
let pos = *pos_for_barrier_id.get(&id).expect("invalid barrier id");
|
||||||
|
pos
|
||||||
|
},
|
||||||
|
};
|
||||||
current_pos.replace(Some(pos));
|
current_pos.replace(Some(pos));
|
||||||
|
|
||||||
// client entered => send event
|
// client entered => send event
|
||||||
@@ -529,15 +556,6 @@ fn distance_to_line(line: ((f32, f32), (f32, f32)), p: (f32, f32)) -> f32 {
|
|||||||
distance
|
distance
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALL_CAPABILITIES: &[DeviceCapability] = &[
|
|
||||||
DeviceCapability::Pointer,
|
|
||||||
DeviceCapability::PointerAbsolute,
|
|
||||||
DeviceCapability::Keyboard,
|
|
||||||
DeviceCapability::Touch,
|
|
||||||
DeviceCapability::Scroll,
|
|
||||||
DeviceCapability::Button,
|
|
||||||
];
|
|
||||||
|
|
||||||
async fn handle_ei_event(
|
async fn handle_ei_event(
|
||||||
ei_event: EiEvent,
|
ei_event: EiEvent,
|
||||||
current_client: Option<Position>,
|
current_client: Option<Position>,
|
||||||
@@ -545,25 +563,43 @@ async fn handle_ei_event(
|
|||||||
event_tx: &Sender<(Position, CaptureEvent)>,
|
event_tx: &Sender<(Position, CaptureEvent)>,
|
||||||
release_session: &Notify,
|
release_session: &Notify,
|
||||||
) -> Result<(), CaptureError> {
|
) -> Result<(), CaptureError> {
|
||||||
|
let all_capabilities = DeviceCapability::Pointer
|
||||||
|
| DeviceCapability::PointerAbsolute
|
||||||
|
| DeviceCapability::Keyboard
|
||||||
|
| DeviceCapability::Touch
|
||||||
|
| DeviceCapability::Scroll
|
||||||
|
| DeviceCapability::Button;
|
||||||
match ei_event {
|
match ei_event {
|
||||||
EiEvent::SeatAdded(s) => {
|
EiEvent::SeatAdded(s) => {
|
||||||
s.seat.bind_capabilities(ALL_CAPABILITIES);
|
s.seat.bind_capabilities(all_capabilities);
|
||||||
context.flush().map_err(|e| io::Error::new(e.kind(), e))?;
|
context.flush().map_err(|e| io::Error::new(e.kind(), e))?;
|
||||||
}
|
}
|
||||||
EiEvent::SeatRemoved(_) | /* EiEvent::DeviceAdded(_) | */ EiEvent::DeviceRemoved(_) => {
|
EiEvent::SeatRemoved(_) => {
|
||||||
log::debug!("releasing session: {ei_event:?}");
|
log::debug!("releasing session: {ei_event:?}");
|
||||||
release_session.notify_waiters();
|
release_session.notify_waiters();
|
||||||
}
|
}
|
||||||
|
/* EiEvent::DeviceAdded(_) | */
|
||||||
|
EiEvent::DeviceRemoved(_) => {
|
||||||
|
if *RESTART_SESSION_ON_DEVICE_CHANGE {
|
||||||
|
log::debug!("releasing session: {ei_event:?}");
|
||||||
|
release_session.notify_waiters();
|
||||||
|
} else {
|
||||||
|
log::debug!("ignoring device change: {ei_event:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
EiEvent::DevicePaused(_) | EiEvent::DeviceResumed(_) => {}
|
EiEvent::DevicePaused(_) | EiEvent::DeviceResumed(_) => {}
|
||||||
EiEvent::DeviceStartEmulating(_) => log::debug!("START EMULATING"),
|
EiEvent::DeviceStartEmulating(_) => log::debug!("START EMULATING"),
|
||||||
EiEvent::DeviceStopEmulating(_) => log::debug!("STOP EMULATING"),
|
EiEvent::DeviceStopEmulating(_) => log::debug!("STOP EMULATING"),
|
||||||
EiEvent::Disconnected(d) => {
|
EiEvent::Disconnected(d) => {
|
||||||
return Err(CaptureError::Disconnected(format!("{:?}", d.reason)))
|
return Err(CaptureError::Disconnected(format!("{:?}", d.reason)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(pos) = current_client {
|
if let Some(pos) = current_client {
|
||||||
for event in Event::from_ei_event(ei_event) {
|
for event in Event::from_ei_event(ei_event) {
|
||||||
event_tx.send((pos, CaptureEvent::Input(event))).await.expect("no channel");
|
event_tx
|
||||||
|
.send((pos, CaptureEvent::Input(event)))
|
||||||
|
.await
|
||||||
|
.expect("no channel");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ ashpd = { version = "0.13.9", default-features = false, features = [
|
|||||||
"screencast",
|
"screencast",
|
||||||
"tokio",
|
"tokio",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
reis = { version = "0.5.0", features = ["tokio"], optional = true }
|
reis = { version = "0.7.0", features = ["tokio"], optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
bitflags = "2.6.0"
|
bitflags = "2.6.0"
|
||||||
|
|||||||
@@ -291,14 +291,12 @@ async fn ei_event_handler(
|
|||||||
) -> Result<(), EmulationError> {
|
) -> Result<(), EmulationError> {
|
||||||
loop {
|
loop {
|
||||||
let event = events.next().await.ok_or(EmulationError::EndOfStream)??;
|
let event = events.next().await.ok_or(EmulationError::EndOfStream)??;
|
||||||
const CAPABILITIES: &[DeviceCapability] = &[
|
let capabilities = DeviceCapability::Pointer
|
||||||
DeviceCapability::Pointer,
|
| DeviceCapability::PointerAbsolute
|
||||||
DeviceCapability::PointerAbsolute,
|
| DeviceCapability::Keyboard
|
||||||
DeviceCapability::Keyboard,
|
| DeviceCapability::Touch
|
||||||
DeviceCapability::Touch,
|
| DeviceCapability::Scroll
|
||||||
DeviceCapability::Scroll,
|
| DeviceCapability::Button;
|
||||||
DeviceCapability::Button,
|
|
||||||
];
|
|
||||||
log::debug!("{event:?}");
|
log::debug!("{event:?}");
|
||||||
match event {
|
match event {
|
||||||
EiEvent::Disconnected(e) => {
|
EiEvent::Disconnected(e) => {
|
||||||
@@ -306,7 +304,7 @@ async fn ei_event_handler(
|
|||||||
return Err(EmulationError::EndOfStream);
|
return Err(EmulationError::EndOfStream);
|
||||||
}
|
}
|
||||||
EiEvent::SeatAdded(e) => {
|
EiEvent::SeatAdded(e) => {
|
||||||
e.seat().bind_capabilities(CAPABILITIES);
|
e.seat().bind_capabilities(capabilities);
|
||||||
}
|
}
|
||||||
EiEvent::SeatRemoved(e) => {
|
EiEvent::SeatRemoved(e) => {
|
||||||
log::debug!("seat removed: {:?}", e.seat());
|
log::debug!("seat removed: {:?}", e.seat());
|
||||||
@@ -314,7 +312,6 @@ async fn ei_event_handler(
|
|||||||
EiEvent::DeviceAdded(e) => {
|
EiEvent::DeviceAdded(e) => {
|
||||||
let device_type = e.device().device_type();
|
let device_type = e.device().device_type();
|
||||||
log::debug!("device added: {device_type:?}");
|
log::debug!("device added: {device_type:?}");
|
||||||
e.device().device();
|
|
||||||
let device = e.device();
|
let device = e.device();
|
||||||
if let Some(pointer) = e.device().interface::<Pointer>() {
|
if let Some(pointer) = e.device().interface::<Pointer>() {
|
||||||
devices
|
devices
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
thiserror = "2.0.0"
|
thiserror = "2.0.0"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os="macos")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os="macos")))'.dependencies]
|
||||||
reis = { version = "0.5.0", optional = true }
|
reis = { version = "0.7.0", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["libei"]
|
default = ["libei"]
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ rustPlatform.buildRustPackage {
|
|||||||
libadwaita
|
libadwaita
|
||||||
librsvg
|
librsvg
|
||||||
]
|
]
|
||||||
++ lib.optionals stdenv.isLinux [
|
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
libX11
|
libX11
|
||||||
libXtst
|
libXtst
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ in {
|
|||||||
};
|
};
|
||||||
systemd = mkOption {
|
systemd = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = pkgs.stdenv.isLinux;
|
default = pkgs.stdenv.hostPlatform.isLinux;
|
||||||
description = "Whether to enable to systemd service for lan-mouse on linux.";
|
description = "Whether to enable to systemd service for lan-mouse on linux.";
|
||||||
};
|
};
|
||||||
launchd = mkOption {
|
launchd = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = pkgs.stdenv.isDarwin;
|
default = pkgs.stdenv.hostPlatform.isDarwin;
|
||||||
description = "Whether to enable to launchd service for lan-mouse on macOS.";
|
description = "Whether to enable to launchd service for lan-mouse on macOS.";
|
||||||
};
|
};
|
||||||
settings = lib.mkOption {
|
settings = lib.mkOption {
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_from_disk(&mut self) -> Result<bool, io::Error> {
|
pub fn read_from_disk(&mut self) -> Result<bool, io::Error> {
|
||||||
log::info!("reading config from {:?}", &self.config_path);
|
log::info!("reading config from {:?}", self.config_path);
|
||||||
|
|
||||||
let current_config = fs::read_to_string(&self.config_path)?;
|
let current_config = fs::read_to_string(&self.config_path)?;
|
||||||
let current_config = match current_config.parse::<DocumentMut>() {
|
let current_config = match current_config.parse::<DocumentMut>() {
|
||||||
@@ -548,7 +548,7 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_back(&mut self) -> Result<(), io::Error> {
|
pub fn write_back(&mut self) -> Result<(), io::Error> {
|
||||||
log::info!("writing config to {:?}", &self.config_path);
|
log::info!("writing config to {:?}", self.config_path);
|
||||||
/* the new config */
|
/* the new config */
|
||||||
let new_config = self.config_toml.clone().unwrap_or_default();
|
let new_config = self.config_toml.clone().unwrap_or_default();
|
||||||
let new_config = toml_edit::ser::to_string_pretty(&new_config).expect("config");
|
let new_config = toml_edit::ser::to_string_pretty(&new_config).expect("config");
|
||||||
|
|||||||
Reference in New Issue
Block a user