96 Commits
Author SHA1 Message Date
d829d1410a fix(linux): serve the Wayland login screen the DRM backend was built for (#15792)
* fix(linux): serve the Wayland login screen the DRM backend was built for

The login screen support in #15420 never worked on a real greeter. fufesou found
it: the session is refused, and with the refusal commented out the client gets a
failed connection instead of a screen.

One premise under all of it. `get_values_of_seat0` is
`_get_values_of_seat0(.., ignore_gdm_wayland = true)`, so a gdm/sddm Wayland
session is skipped by construction and `get_display_server` falls back to x11.
That was correct while the portal was the only backend, since the portal cannot
serve a greeter at all. The DRM path never talks to the compositor, which is
precisely why it can serve one, so the premise stops holding there and every
x11-vs-Wayland decision in the tree answers x11 at a login screen.

The central change is the memoised `IS_X11`: when it reads x11 and seat0 is a
Wayland greeter, answer Wayland. That covers fifteen routing sites at once, and
it is under `cfg(feature = "drm")`, so a build without the backend keeps the
current answer exactly. `is_x11_for_drm` is the unmemoised form for the two
retry loops that must keep asking while a boot is still naming the session, and
the memoised accessor is scoped to per-frame callers in the per-session
`--server`, which the service only spawns once it has identified the session.

Input was the last layer and lived outside all of that. `Enigo` decides
x11-vs-Wayland once in `Default::default()`, from the same seat0 lookup, and on
"x11" routes every key and mouse event to xdo; with no X server that context is
null and libxdo drops them without an error. So the uinput devices were created,
the compositor opened them, and nothing was ever written to them. `set_is_x11`
is now called where the custom devices are installed, which is only reached once
`!is_x11()` is already established. The unit test pins both directions, since a
one-directional test passes against the bug.

With no compositor reachable, the uinput desktop rect comes from the DRM display
list instead: those are the same displays being captured, so the coordinate space
matches by construction. Telling the truth about a greeter also makes four
compositor-probing paths reachable where the probe cannot answer; all four
already treat an empty output list as "nothing to do", so they skip it and 11818
"Could not find wayland compositor" warnings in one session became 1.

Tested on an sddm Plasma Wayland greeter, MacBook T2, 2880x1800: the greeter
renders, typing from the client enters characters in the password field, a click
at an absolute coordinate opens the greeter session combo, the service pre-warm
primes in 994 us instead of timing out, and the privileged service maps no EGL
during a live capture. Not proven on gdm under Wayland.

Known limitations: non-ASCII characters cannot be typed at a greeter, because
that path goes through the clipboard and the clipboard here is X11 only; and at
a multi-monitor greeter the pointer reaches the first display only, since every
DRM output reports origin (0,0) on Wayland and there is no arrangement to derive
without the compositor.

* fix(linux): a Wayland greeter the DRM backend can serve is not headless

fufesou reported the login screen still failing on Ubuntu 24.04 with gdm3, with
the client asking for OS credentials to start an X session instead of showing the
greeter. Reproduced on a real gdm greeter here.

Same premise as the rest of the branch, one more consumer. `DesktopManager::new`
reads seat0 through `get_values_of_seat0`, which skips a gdm/sddm Wayland session
by construction, so at a greeter it finds no session at all and
`get_supported_display_seat0_username` returns None from its empty-username arm.
That makes `is_headless()` true, so the service advertises headless and
`try_start_desktop` answers `LOGIN_MSG_DESKTOP_SESSION_NOT_READY`. The corrected
`IS_X11` does not reach this one: it asks who owns seat0, not which display
server is running.

So ask again, with the greeter visible, when the DRM backend can capture and
inject into it. At query time rather than in `new()`, because the DRM probe has
not necessarily settled when the desktop manager is constructed, and the answer
would latch for the process lifetime. In a normal session the latched username is
a real user and the extra read is skipped.

* chore: drop the hbb_common bump, this branch does not need it

The bump carried rustdesk/hbb_common#580, the compositor-socket fallback. Nothing
here depends on it: the greeter paths in this branch are the ones that run when
compositor data is unavailable, which is what the commit before this one states as
a known limitation. Keeping the bump would only block the greeter fix behind a
review of a separate change, and would import that change's blocking review items
into this path.

* fix(linux): let the uinput uid gate see the greeter that owns seat0

Input at a real greeter was rejected by our own authorization. Measured on Ubuntu
24.04 with gdm3: the root service logs

  Rejected unauthorized connection on uinput ipc channel:
  postfix=_uinput_control, peer_uid=Some(120), active_uid=None

and the greeter's `--server` gets ECONNRESET out of `setup_uinput`, so no uinput
device is ever created and neither keyboard nor mouse reaches the greeter.

uid 120 is gdm, the owner of the only active seat0 session. `active_uid` is None
because the uinput authorizer deliberately bypasses the service-loop cache and
takes a fresh seat0 lookup, and the fresh read hides a Wayland greeter by
construction. The cache-based gates do not have the problem: `Desktop::refresh`
fills it through the greeter-visible read, which is also why capture and config
sync work at a greeter while input does not.

So make the fresh read agree with the cache. It keeps the property the uinput gate
wants, a lookup that cannot be stale, and it still compares the peer against the
uid of the session that owns seat0 -- which at a greeter is the greeter.

* fix: settle the DRM probe before routing login to X11, and read seat0 fresh

Two findings from the #15792 review, both verified against the code:

- drm_login_screen_seat0_username asked the cached probe, so a client
  arriving before warm_availability publishes its verdict read "no DRM"
  and, with allow-linux-headless=Y, try_start_x_session could start Xorg
  over a live Wayland greeter. Ask the probing form instead, and only
  after the cheap seat0 read says a Wayland greeter is actually there: a
  bounded definitive verdict is affordable on a login-time path.

- get_supported_display_seat0_username trusted the seat0 values cached in
  DesktopManager::new(), which go stale across a logout or a fast user
  switch: a stale non-greeter name skipped the greeter probe and was
  returned as the supported display owner. Read seat0 fresh on every
  query; every call site is connection-time, so the extra loginctl read
  is cheap.

Regression-tested on a real sddm Wayland greeter: capture streams the
greeter, the RustDesk password dialog is the only prompt, and five typed
characters appeared in the greeter password field over uinput with zero
"Rejected unauthorized connection" lines in the service log.

* fix: ask the greeter compositor for the multi-monitor layout

The display arrangement and the pointer mapping were wrong at a
multi-monitor login screen, and the mechanism is measured on a two-head
virtio VM: DRM has no origins, so every display was advertised at (0,0)
(a stacked arrangement on the client), and the uinput range was taken
from the union of the DRM modes while the compositor had arranged the
outputs side by side.

Both came from the same premise, written before the hbb_common socket
fallback existed: "a login screen has no compositor to ask".
wayland_outputs_askable() skipped the wl_output augmentation at any
greeter, and update_uinput_resolution took the DRM union directly. The
premise is false now: a greeter runs a compositor, and the socket
fallback reaches it with no environment variables, measured answering
two outputs at the VM greeter while the old gate was still routing
around it.

Drop the gate and take the compositor-first path everywhere. Where the
fallback cannot answer, the output list comes back empty and both call
sites degrade to exactly the old behavior, so a build against an older
hbb_common is unchanged.

* fix: augment a single display too, and probe the desktop rect off the executor

Two follow-ups from the automated re-review of cd80c3dee, both verified:

- augment_with_wayland_geometry skipped the compositor below two DRM
  displays, but on a multi-GPU host the one connector this service can
  open may sit at a non-zero origin of the compositor layout, and DRM
  alone reports (0,0).

- the desktop rect for uinput can now block for the socket probe
  deadline, and update_uinput_resolution runs on current-thread
  runtimes; move the query into spawn_blocking.

The third re-review finding, the warm-up allegedly skipping Wayland
greeters, is refuted: warm_availability probes while is_x11_for_drm()
is false, which includes a Wayland greeter, and the greeter log of the
VM run behind cd80c3dee shows the warm succeeding there.

* fix: baseline the layout from the blocking task, and augment a lone output's origin

The layout snapshot after the rect lookup still ran on the executor: a
failed compositor lookup is not cached, so the snapshot synchronously
repeated the whole socket probe there. The baseline is now computed
inside the same blocking task, from the snapshot the successful lookup
just cached, or omitted when only the raw DRM union was available,
which keeps the #15601 remap inactive exactly where origins are
unknown.

A single compositor output now hands its origin to a single connector:
the lone output can sit at a non-zero origin the DRM side cannot see.
Scale stays 1 on purpose, matching how a single display is advertised
at physical size, and more connectors than the one output stays
unaugmented, since the layout-order fallback would plant that origin on
a guess.

Also refresh the get_primary_index doc that still said augmentation
declines below two connectors.

* fix: read the DRM probe as a tri-state, and keep pre-auth seat0 checks cache-only

is_available() answered false both for a definitive no-DRM verdict and
for a probe that had simply not settled (another probe in flight, or a
failure still below the disable threshold), and the login-screen
decision turned that transient false into no-greeter: try_start_x_session
could put Xorg over a live greeter in exactly the window the probe
needed. The machinery now answers Available/Unavailable/Unsettled, and
only a definitive Unavailable routes the seat toward X11.

Connection setup also ran the whole lookup pre-auth: constructing
LinuxHeadlessHandle called is_headless() before authentication, holding
DESKTOP_MANAGER while loginctl ran and, at a greeter, while the DRM
probe waited out its handshake. An unauthenticated peer could occupy a
worker for seconds and serialize every other connection on the mutex.
is_headless() now answers from a snapshot refreshed off-thread, and the
fresh lookup became a free function called with the manager lock
released everywhere; the enforcing decisions, get_username and
try_start_x_session, still read seat0 fresh.

Also drops seat0_display_server, dead since the fresh-read change.

* fix: respect RUSTDESK_FORCED_DISPLAY_SERVER over the greeter correction

The greeter correction rewired IS_X11 and is_x11_for_drm() to Wayland
whenever seat0 looks like a Wayland greeter, including when the operator
explicitly forced the display server: get_display_server() kept honoring
the override while the DRM routing gates contradicted it, leaving
capture and input routing internally inconsistent. The correction now
only adjusts the auto-detected answer.

* fix: honest pre-auth snapshot, sticky negative verdict, and a complete forced-x11 gate

Four defects found by an adversarial review of the two previous
commits, all in their new lines:

- The empty-snapshot fallback derived headless from the manager's
  boot-time seat0 read, which is blank at a Wayland greeter (the
  loginctl wrapper skips greeter sessions), so the first connection of
  every server process at a greeter answered headless=true, the
  opposite of the comment on it. No snapshot now answers NOT headless,
  the snapshot is seeded at start_xdesktop, and the boot-time cache is
  gone entirely (it had no reader left).

- wait_desktop_cm_ready gated on a bool stored at construction, which
  can lag one seat0 transition behind and skipped the CM-ready wait
  right after a logout. It re-reads the snapshot at call time.

- A settled Unavailable was erased at NEGATIVE_TTL expiry (state to
  Unknown, failure counter to zero), so a permanently helper-less box
  reopened the Unsettled window every 30 seconds and the login decision
  kept adopting a greeter nothing can serve. The verdict now stays
  Unavailable while an off-thread re-probe re-verifies it: a failed or
  empty re-probe restamps the no, and only a non-empty list flips it.

- The forced-x11 gate only covered IS_X11 and is_x11_for_drm, while
  the seat0 adoption path still probed DRM and admitted greeter
  sessions whose capture and input then routed to X11. Greeter
  adoption now yields to an operator-forced X11, degrading to upstream
  behavior: the connection is refused at the login screen.

* fix: keep the login request path off the probe entirely

try_start_desktop runs while handling a LoginRequest, before password
validation, and at a Wayland greeter its seat0 lookup reached the
probing availability form: an unauthenticated peer could park a worker
for the probe deadline. The greeter adoption now reads a cached
tri-state that never blocks; when the state is Unknown it kicks the
probe off-thread and answers Unsettled, which the login decision treats
as a possibly servable greeter until it settles. Settling lives in the
startup warm-up, that kick, and the TTL re-verifiers; the blocking form
stays for the capture-side callers, where waiting is acceptable.

* fix: run the pre-auth desktop start off the executor, guard the refresh flag, trim comments

From fufesou's #15792 re-review (no blocking issues) plus a bot pass:

- try_start_desktop now runs on spawn_blocking. It executes loginctl,
  and PAM when a session must start, while handling a LoginRequest
  before password validation, so a slow logind must not tie up an async
  request worker; the blocking pool absorbs it.

- kick_seat0_refresh releases SEAT0_REFRESH_IN_FLIGHT through an RAII
  guard, so a panic in the refresh thread cannot freeze is_headless on a
  stale snapshot for the process lifetime.

- drm_can_serve_login_screen stays Available-only, and the reason is now
  in the code: it is deliberately not symmetric with the seat0 adoption
  gate. Adoption yields Xorg only on a definitive Unavailable; admission
  accepts only on a definitive Available; both wait through an unsettled
  probe. Admitting there would black-screen a client on a helper-less
  box, so a review suggestion to make them agree is declined.

- Trimmed two over-long comments to the repo's three-line rule.

* fix(linux): harden DRM login-screen startup

Keep unauthenticated headless checks cache-only, bound OS-session startup to one blocking task, and surface JoinError failures.

Wire the isolated Wayland probe consumer and update hbb_common plus libdrmtap 0.5.4.

* fix(linux): headless refresh state

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(linux): keep headless startup state consistent

- gate concurrent desktop startup attempts
- route CM IPC after refreshing desktop state
- avoid blocking seat0 queries in the CM retry loop
- preserve newer seat0 snapshots during overlapping refreshes
- derive DRM geometry and primary display from one Wayland snapshot

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: rustdesk <71636191+rustdesk@users.noreply.github.com>
Co-authored-by: rustdesk <info@rustdesk.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-08-13 20:22:41 +08:00
just-some-tall-bloke 2b40c61d8e Fix spelling and grammar errors in comments (#15370)
- dbus.rs: fix grammar (add 'between', pluralize 'processes')
- win_impl.rs: fix typo 'hight' -> 'high', idiom 'such called' -> 'so-called'
- startwm.sh: fix typo 'loging' -> 'logging'
- lib.rs: fix copy-paste error in doc comments for scroll buttons
- message.proto: fix typo 'Clipobard' -> 'Clipboard'
2026-06-22 15:26:51 +08:00
Sergiusz Michalik 38f1300717 fix(linux): enable mouse side buttons in remote sessions (#14848)
* fix(linux): enable mouse side buttons in remote sessions

Flutter's Linux embedder never delivers X11 button 8/9 (back/forward)
events to Dart, so mouse side buttons were silently dropped in remote
sessions.

Intercept these buttons at the GDK level via button-press/release-event
handlers on all windows (main + sub-windows) and forward them through
a dedicated platform channel to the active InputModel session.

Also add a defensive XSetPointerMapping call during enigo init to
extend the X11 core pointer button map to 9 buttons on servers where
it is smaller (e.g. minimal X server configurations).

* fix: address review feedback for side button support

- Use XOpenDisplay/XCloseDisplay instead of reading Display* from
  xdo_t's private struct layout at offset 0 (fragile ABI assumption)
- Track side button down ownership per button via a Map instead of a
  single slot, preventing cross-button mismatch on overlapping presses

* fix: gate side buttons on view-only and fix teardown

- Skip side button events in view-only sessions (consistent with
  other mouse entry points)
- Release held side buttons on session close to avoid stuck buttons
  on the remote
- Drop unpaired 'up' events instead of falling back to the active
  model, which could send to the wrong session

* docs: add clarifying comments from review feedback

- Note global scope of XSetPointerMapping and that it runs once
  via lazy_static singleton
- Clarify sub-window callback is safe on X11-only builds
- Document per-isolate design of initSideButtonChannel

* fix: replace broken XSetPointerMapping with diagnostic check

XSetPointerMapping requires the length to match XGetPointerMapping's
return value - it cannot extend the button count. The previous code
would trigger a BadValue X error on servers with fewer than 9 buttons.

Replace with a diagnostic-only check that logs whether the core
pointer has enough buttons for side button simulation. RustDesk's
uinput "Mouse passthrough" device already provides the needed buttons
in practice.

Also add .catchError to fire-and-forget side button releases during
session teardown to prevent unhandled async errors.

* fix: ensure side button releases bypass permission checks

If permissions change between button down and up (e.g. keyboardPerm
revoked, view-only toggled), sendMouse's early return would suppress
the release, leaving a stuck button on the remote.

Add _sendMouseUnchecked that bypasses permission checks, used for:
- Side button 'up' events (matching a recorded 'down')
- Forced releases during session teardown

Gate all permission checks (isViewOnly, keyboardPerm, isViewCamera)
at the 'down' entry point before recording in _sideButtonDownModels.

* fix: add NULL guards and avoid blocking platform channel handler

- Add NULL checks for FL_VIEW cast and channel creation in
  on_subwindow_created (review feedback from fufesou)
- Use fire-and-forget (unawaited) for _sendMouseUnchecked calls
  inside the platform channel handler to avoid blocking platform
  messages when sessionSendMouse is slow (review feedback from Copilot)

* fix: remove circular import and skip X11 check on Wayland

- Move initSideButtonChannel() call from initEnv() in main.dart to
  the InputModel constructor, removing the circular import between
  main.dart and input_model.dart
- Skip check_x11_button_map() when DISPLAY is not set to avoid
  noisy warnings on pure Wayland environments
2026-04-25 12:46:05 +08:00
fufesou 732b250815 fix(keyboard): legacy mode (#14435)
* fix(keyboard): legacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* Simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(keyboard): legacy mode, chr to seq

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(keyboard): legacy mode, early return if (!hotkey)&down

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(keyboard): legacy mode, pair down/up

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-03-02 19:07:09 +08:00
fufesou 779b7aaf02 feat(wayland): keyboard mode, legacy translate (#14317)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-02-15 16:43:21 +08:00
fufesou be4bbd018d fix(install): linux xdo (#14096)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-01-21 20:43:15 +08:00
fufesou 998b75856d feat: Add relative mouse mode (#13928)
* feat: Add relative mouse mode

- Add "Relative Mouse Mode" toggle in desktop toolbar and bind to InputModel
- Implement relative mouse movement path: Flutter pointer deltas -> `type: move_relative` -> new `MOUSE_TYPE_MOVE_RELATIVE` in Rust
- In server input service, simulate relative movement via Enigo and keep latest cursor position in sync
- Track pointer-lock center in Flutter (local widget + screen coordinates) and re-center OS cursor after each relative move
- Update pointer-lock center on window move/resize/restore/maximize and when remote display geometry changes
- Hide local cursor when relative mouse mode is active (both Flutter cursor and OS cursor), restore on leave/disable
- On Windows, clip OS cursor to the window rect while in relative mode and release clip when leaving/turning off
- Implement platform helpers: `get_cursor_pos`, `set_cursor_pos`, `show_cursor`, `clip_cursor` (no-op clip/hide on Linux for now)
- Add keyboard shortcut Ctrl+Alt+Shift+M to toggle relative mode (enabled by default, works on all platforms)
- Remove `enable-relative-mouse-shortcut` config option - shortcut is now always available when keyboard permission is granted
- Handle window blur/focus/minimize events to properly release/restore cursor constraints
- Add MOUSE_TYPE_MASK constant and unit tests for mouse event constants

Note: Relative mouse mode state is NOT persisted to config (session-only).
Note: On Linux, show_cursor and clip_cursor are no-ops; cursor hiding is handled by Flutter side.

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(mouse): relative mouse mode, exit hint

Signed-off-by: fufesou <linlong1266@gmail.com>

* refact(relative mouse): shortcut

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-01-09 10:03:14 +08:00
fufesou 6144a1c97e fix: osx, reset modifiers' state after locking screen (#11806)
https://github.com/rustdesk/rustdesk/issues/11802

Signed-off-by: fufesou <linlong1266@gmail.com>
2025-05-19 21:02:07 +08:00
fufesou 2d403913b5 fix: enigo, macos, F11 (#11371)
Signed-off-by: fufesou <linlong1266@gmail.com>
2025-04-06 10:42:15 +08:00
fufesou afc8bb71dc feat: mobile, key help tool, more keys (#10068)
* feat: mobile, key help tool, vk_enter

Signed-off-by: fufesou <linlong1266@gmail.com>

* Mobile, add more function keys

Signed-off-by: fufesou <linlong1266@gmail.com>

* Mobile, more virtual function keys

Signed-off-by: fufesou <linlong1266@gmail.com>

* uinput, menu maps key_compose

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-11-29 00:56:38 +08:00
fufesou 7a3e1fe648 fix: ->macos, mouse events, key flags (#9733)
* fix: win->macos, mouse events,  key flags

Signed-off-by: fufesou <linlong1266@gmail.com>

* comments

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2024-10-24 14:33:37 +08:00
fufesou 40239a1c41 feat: macos, mouse button, back&forward (#9185)
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-08-27 15:20:29 +08:00
fufesou d18e95703e fix: mouse forward back (#8705)
Signed-off-by: fufesou <linlong1266@gmail.com>
2024-07-14 03:49:16 +08:00
fufesou 7b37e5183c update rdev, fix grab system utf8, fallback on linux
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-09-15 15:35:44 +08:00
fufesou 6e21f8410a debug, macos trackpad, flutter
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-06-11 15:56:09 +08:00
fufesou c4f9650d7f fix, win mouse, touchpad scroll
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-06-07 20:01:01 +08:00
fufesou f72593c281 tmp commit
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-04-08 19:49:11 +08:00
fufesou 4a8d61ac09 Do not sync led, when Control, Shift, Alt, Tab, Enter are pressed
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-04-08 15:35:10 +08:00
fufesou 850f48abb8 remove unused code from https://github.com/fufesou/ustdsk/comit/b526bf4a67f7e05b2d3f739864ecc31carembc18a85
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-04-07 16:28:34 +08:00
fufesou ac74ed1914 legacy mode, win, fix layout code simulation
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-04-06 17:53:07 +08:00
fufesou 0b417ac479 start --server on gmd wayland, just for communications, no connections will be established
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-03-31 16:42:35 +08:00
Chieh Wang d7dbe41ada better error info 2023-03-20 15:28:14 +08:00
asur4s 2aae2ca513 Refector key click && Clear remapped keycodes 2023-03-18 20:55:35 -07:00
fufesou b733ad9379 refact register_breakdown_handler
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-02-19 10:19:28 +08:00
fufesou b2d13647be translate mode, mac --> win, debug 2
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-02-14 21:42:31 +08:00
fufesou 00867276ed fix wayland input
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-10 14:18:25 +08:00
Josh Soref c89e104f3e spelling: regardless
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:59:08 -05:00
Josh Soref 4993635652 spelling: platforms
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:59:08 -05:00
Josh Soref f91daf046a spelling: invocation
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:59:08 -05:00
Josh Soref 69595b7b67 spelling: implementation
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:59:08 -05:00
Josh Soref 53556ba06c spelling: essentially
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:58:33 -05:00
Josh Soref 8c901c2585 spelling: custom
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-01-09 12:58:33 -05:00
sj6219 c5e39f4bbb windows extended key 2023-01-06 20:07:43 +09:00
fufesou 20ba62870e remove unimplemented!
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-05 17:52:57 +08:00
fufesou b4feae33bb support linux mouse back/forward
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-05 17:47:26 +08:00
fufesou 97cf85d1b7 mouse forward back support on windows
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-05 17:47:26 +08:00
fufesou 97718b33a6 remove expect
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2023-01-02 13:11:25 +08:00
fufesou 01ade73304 fix macos sticky fn, https://stackoverflow.com/questions/74938870/sticky-fn-after-home-is-simulated-programmatically-macos
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-12-29 14:37:09 +08:00
KG7x 71103886e6 Fix typo 2022-12-25 20:21:13 +03:00
fufesou fff6aad1c5 compile win & macos
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-11-25 19:28:43 +08:00
fufesou 9dfa02a702 Fix wayland input after Lock and Wake
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-11-25 19:28:43 +08:00
xxrl 260c924010 opt: mac scroll to fast 2022-11-08 23:05:43 +08:00
rustdesk e8182e762d remove another transmute_copy 2022-10-31 23:41:51 +08:00
rustdesk 4c9dadc41a fix transmute crash 2022-10-31 23:03:52 +08:00
fufesou 3c9ac9e4d7 wayland: fix enigo init
Signed-off-by: fufesou <shuanglongchen@yeah.net>
2022-10-17 21:55:26 +08:00
asur4s 2d7cd7c864 Refactor: tfc 2022-09-05 11:50:42 -04:00
asur4s 72d357e14b Refactor get led state 2022-09-05 08:07:13 -04:00
Asura 4421d08384 Delete reset function about enigo 2022-09-01 20:24:50 -07:00
Asura 37dbfcc86d Delete pynput from repo 2022-08-31 23:07:52 -07:00
Asura 25525cda3f Add translte mode in input_service 2022-07-27 20:01:42 -07:00