cleanups
This commit is contained in:
parent
6d466c65a4
commit
579869f2f0
21 changed files with 168 additions and 2771 deletions
|
|
@ -3,6 +3,11 @@ name = "cursor-move-webapp"
|
|||
version = "0.1.0"
|
||||
authors = ["Mona Mayrhofer <mona.mayrhofer@proton.me>"]
|
||||
edition = "2024"
|
||||
repository = "https://github.com/mona-mayrhofer/cursor-mover-app"
|
||||
categories = ["tools"]
|
||||
keywords = ["tools", "cursor", "remote"]
|
||||
license = "EUPL-1.2"
|
||||
description = "A web application for controlling your cursor and keyboard via a smartphone browser."
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
@ -10,25 +15,25 @@ edition = "2024"
|
|||
dioxus = { version = "0.7.3", features = ["router", "fullstack", "logger"] }
|
||||
dioxus-html = { version = "0.7.3", features = ["serialize"] }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
wasmtimer = "0.4.3"
|
||||
|
||||
|
||||
wayland-client = { version = "0.31.12", optional = true }
|
||||
wayland-protocols-wlr = { version = "0.3.10", features = ["client"], optional = true }
|
||||
tokio = {version = "1.49.0", optional = true}
|
||||
rustix = { version = "1.1.4", optional = true, features = ["time"] }
|
||||
rustix = { version = "1.1.4", optional = true, features = ["time"], default-features = false }
|
||||
wayland-protocols-misc = { version = "0.3.10", features = ["client"], optional = true }
|
||||
wayland-protocols = { version = "0.32.10", features = ["client", "staging"], optional = true }
|
||||
xkb = {version = "0.3.0", optional = true}
|
||||
memfile = {version = "0.3.2", optional = true}
|
||||
wasmtimer = "0.4.3"
|
||||
|
||||
[features]
|
||||
default = ["web"]
|
||||
# The feature that are only required for the web = ["dioxus/web"] build target should be optional and only enabled in the web = ["dioxus/web"] feature
|
||||
web = ["dioxus/web"]
|
||||
# The feature that are only required for the desktop = ["dioxus/desktop"] build target should be optional and only enabled in the desktop = ["dioxus/desktop"] feature
|
||||
desktop = ["dioxus/desktop"]
|
||||
#desktop = ["dioxus/desktop"]
|
||||
# The feature that are only required for the mobile = ["dioxus/mobile"] build target should be optional and only enabled in the mobile = ["dioxus/mobile"] feature
|
||||
mobile = ["dioxus/mobile"]
|
||||
#mobile = ["dioxus/mobile"]
|
||||
# The feature that are only required for the server = ["dioxus/server"] build target should be optional and only enabled in the server = ["dioxus/server"] feature
|
||||
server = ["dioxus/server",
|
||||
"dep:wayland-client",
|
||||
|
|
@ -37,7 +42,6 @@ server = ["dioxus/server",
|
|||
"dep:wayland-protocols",
|
||||
"dep:tokio",
|
||||
"dep:rustix",
|
||||
"dep:xkb",
|
||||
"dep:memfile"
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
use dioxus::{
|
||||
fullstack::{CborEncoding, WebSocketOptions, Websocket, extract::State, use_websocket},
|
||||
html::{
|
||||
geometry::{ElementSpace, euclid::Point2D},
|
||||
input_data::MouseButton,
|
||||
},
|
||||
html::input_data::MouseButton,
|
||||
logger::tracing,
|
||||
prelude::*,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub fn KeyboardArea(onevent: EventHandler<ClientEvent>) -> Element {
|
|||
let v = evt.value();
|
||||
input_state.set(v.clone());
|
||||
|
||||
onevent.call(ClientEvent::TextInputEvent { text: v })
|
||||
onevent.call(ClientEvent::TextInputEvent { text: v });
|
||||
});
|
||||
let key_press_handler = use_callback(move |evt: Event<KeyboardData>| {
|
||||
if input_state.read().is_empty() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
ops::Sub,
|
||||
time::Duration,
|
||||
};
|
||||
use std::{collections::HashMap, ops::Sub, time::Duration};
|
||||
|
||||
use dioxus::{
|
||||
html::{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ const BUTTON_RIGHT: u32 = 0x111;
|
|||
const BUTTON_MIDDLE: u32 = 0x112;
|
||||
|
||||
// https://wayland.app/protocols/wayland#wl_keyboard:enum:keymap_format
|
||||
#[expect(unused)]
|
||||
const NO_KEYMAP: u32 = 0;
|
||||
const XKB_V1: u32 = 1;
|
||||
|
||||
|
|
@ -233,8 +234,11 @@ enum InputProxyServiceState {
|
|||
keymap: Keymap,
|
||||
},
|
||||
Running {
|
||||
#[expect(unused)]
|
||||
seat: WlSeat,
|
||||
#[expect(unused)]
|
||||
virtual_pointer_manager: ZwlrVirtualPointerManagerV1,
|
||||
#[expect(unused)]
|
||||
virtual_keyboard_manager: ZwpVirtualKeyboardManagerV1,
|
||||
|
||||
virtual_pointer: ZwlrVirtualPointerV1,
|
||||
|
|
@ -282,7 +286,7 @@ impl InputProxyServiceState {
|
|||
}
|
||||
}
|
||||
|
||||
fn input_method_mut(&mut self) -> Option<&mut InputMethod> {
|
||||
const fn input_method_mut(&mut self) -> Option<&mut InputMethod> {
|
||||
match self {
|
||||
Self::Running { input_method, .. } => Some(input_method),
|
||||
Self::Incomplete { .. } => None,
|
||||
|
|
@ -480,7 +484,6 @@ impl Dispatch<ZwpInputMethodV2, ()> for InputProxyServiceState {
|
|||
_conn: &Connection,
|
||||
_qhandle: &QueueHandle<Self>,
|
||||
) {
|
||||
panic!();
|
||||
tracing::warn!("Unknown event received from ZwpInputMethodV2");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
#![expect(unused)]
|
||||
|
||||
use dioxus::logger::tracing;
|
||||
|
||||
fn is_key_string(s: &str) -> bool {
|
||||
s.chars().all(|c| !c.is_control()) && s.chars().skip(1).all(|c| !c.is_ascii())
|
||||
}
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub fn web_key_to_linux_keycode(s: &str) -> Option<u32> {
|
||||
tracing::info!("Converting {s}");
|
||||
match s {
|
||||
|
|
|
|||
|
|
@ -57,16 +57,14 @@ impl MouseFilterBuffer {
|
|||
|
||||
let mut i = self.buffer.iter();
|
||||
|
||||
let mut last = if let Some(it) = i.find(|it| it.time >= start_time) {
|
||||
it
|
||||
} else {
|
||||
let Some(mut last) = i.find(|it| it.time >= start_time) else {
|
||||
return Vector2D::zero();
|
||||
};
|
||||
let start_time = last.time;
|
||||
let mut last_time = last.time;
|
||||
|
||||
for point in i {
|
||||
total_distance += (point.position - last.position);
|
||||
total_distance += point.position - last.position;
|
||||
last = point;
|
||||
last_time = point.time;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::components::{Controls, MouseArea};
|
||||
use crate::components::Controls;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
/// The Home page component that will be rendered when the current route is `[Route::Home]`
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
[package]
|
||||
name = "cursor-mover-app"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = "EUPL-1.2"
|
||||
description = "A web-application that lets you remotely control your cursor."
|
||||
repository = "https://forgejo.monalith.xyz/Nionidh/cursor-mover-app"
|
||||
keywords = ["web", "application", "cursor", "control"]
|
||||
categories = ["web-programming"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.49.0", features = ["full"] }
|
||||
wayland-client = "0.31.12"
|
||||
wayland-protocols-wlr = { version = "0.3.10", features = ["client"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
@ -1 +0,0 @@
|
|||
The main application
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
use std::{
|
||||
alloc::System,
|
||||
f64,
|
||||
future::poll_fn,
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use tokio::{
|
||||
select,
|
||||
time::{self, Instant},
|
||||
};
|
||||
use wayland_client::{Connection, Dispatch, Proxy, QueueHandle, protocol::wl_registry};
|
||||
use wayland_protocols_wlr::virtual_pointer::v1::client::{
|
||||
zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1,
|
||||
zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
struct AppData {
|
||||
virtual_pointer: Option<ZwlrVirtualPointerV1>,
|
||||
}
|
||||
|
||||
impl Dispatch<ZwlrVirtualPointerV1, ()> for AppData {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
proxy: &ZwlrVirtualPointerV1,
|
||||
event: <ZwlrVirtualPointerV1 as Proxy>::Event,
|
||||
data: &(),
|
||||
conn: &Connection,
|
||||
qhandle: &QueueHandle<Self>,
|
||||
) {
|
||||
println!("VPointerData");
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<ZwlrVirtualPointerManagerV1, ()> for AppData {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
proxy: &ZwlrVirtualPointerManagerV1,
|
||||
event: <ZwlrVirtualPointerManagerV1 as Proxy>::Event,
|
||||
data: &(),
|
||||
conn: &Connection,
|
||||
qhandle: &QueueHandle<Self>,
|
||||
) {
|
||||
println!("ZwlrEvent")
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<wl_registry::WlRegistry, ()> for AppData {
|
||||
fn event(
|
||||
app_data: &mut Self,
|
||||
registry: &wl_registry::WlRegistry,
|
||||
event: wl_registry::Event,
|
||||
_: &(),
|
||||
_: &Connection,
|
||||
queue_handle: &QueueHandle<Self>,
|
||||
) {
|
||||
println!("WlRegistry Event");
|
||||
if let wl_registry::Event::Global {
|
||||
name,
|
||||
interface,
|
||||
version,
|
||||
} = event
|
||||
&& interface == "zwlr_virtual_pointer_manager_v1"
|
||||
{
|
||||
app_data.virtual_pointer.get_or_insert_with(|| {
|
||||
let manager = registry.bind::<ZwlrVirtualPointerManagerV1, _, _>(
|
||||
name,
|
||||
version,
|
||||
queue_handle,
|
||||
(),
|
||||
);
|
||||
|
||||
let pointer = manager.create_virtual_pointer(None, queue_handle, ());
|
||||
|
||||
println!("Virtual pointer manager created");
|
||||
pointer
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let connection = Connection::connect_to_env().unwrap();
|
||||
let display = connection.display();
|
||||
|
||||
let mut event_queue = connection.new_event_queue();
|
||||
let queue_handle = event_queue.handle();
|
||||
let _registry = display.get_registry(&queue_handle, ());
|
||||
println!("Advertized globals:");
|
||||
|
||||
let mut appdata = AppData::default();
|
||||
event_queue.roundtrip(&mut appdata).unwrap();
|
||||
|
||||
let mut interval = time::interval(Duration::from_millis(15));
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
loop {
|
||||
if Instant::now().duration_since(start) > Duration::from_secs(5) {
|
||||
break;
|
||||
}
|
||||
|
||||
select! {
|
||||
poll = poll_fn(|cx| event_queue.poll_dispatch_pending(cx, &mut appdata)) => {
|
||||
println!("Did the mash");
|
||||
},
|
||||
now = interval.tick() => {
|
||||
if let Some(pointer) = appdata.virtual_pointer.as_mut() {
|
||||
handle_pointer_motion(now, &pointer);
|
||||
}
|
||||
event_queue.flush().unwrap();
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_pointer_motion(
|
||||
time: Instant,
|
||||
pointer: &ZwlrVirtualPointerV1,
|
||||
) {
|
||||
let time = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_millis();
|
||||
|
||||
let x = ((time as f64 / 1000.0 * f64::consts::PI).sin() * 10.0);
|
||||
let y = ((time as f64 / 1000.0 * f64::consts::PI).cos() * 10.0);
|
||||
|
||||
pointer.motion(time as u32, x, y);
|
||||
pointer.frame();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue