349 Commits

Author SHA1 Message Date
abaf233a07 fix: adjust command line size to allow expanding
Some checks are pending
CodeQL Analysis / codeql (push) Waiting to run
Continuous Integration / ci-passed (push) Blocked by required conditions
Continuous Integration / test-results (push) Blocked by required conditions
Continuous Integration / lint-reuse (push) Waiting to run
Continuous Integration / lint-clang (push) Blocked by required conditions
Continuous Integration / analyze-valgrind (push) Blocked by required conditions
Continuous Integration / windows-2022-x64 (push) Blocked by required conditions
Continuous Integration / windows-2022-arm64 (push) Blocked by required conditions
Continuous Integration / macos-arm64 (push) Blocked by required conditions
Continuous Integration / macos-x64 (push) Blocked by required conditions
Continuous Integration / archlinux-x86_64 (push) Blocked by required conditions
Continuous Integration / debian-arm64 (push) Blocked by required conditions
Continuous Integration / debian-x86_64 (push) Blocked by required conditions
Continuous Integration / debian-testing-arm64 (push) Blocked by required conditions
Continuous Integration / debian-testing-x86_64 (push) Blocked by required conditions
Continuous Integration / fedora-42-arm64 (push) Blocked by required conditions
Continuous Integration / fedora-42-x86_64 (push) Blocked by required conditions
Continuous Integration / fedora-43-arm64 (push) Blocked by required conditions
Continuous Integration / fedora-43-x86_64 (push) Blocked by required conditions
Continuous Integration / opensuse-arm64 (push) Blocked by required conditions
Continuous Integration / opensuse-x86_64 (push) Blocked by required conditions
Continuous Integration / ubuntu-25.10-arm64 (push) Blocked by required conditions
Continuous Integration / ubuntu-25.10-x86_64 (push) Blocked by required conditions
Continuous Integration / ubuntu-26.04-arm64 (push) Blocked by required conditions
Continuous Integration / ubuntu-26.04-x86_64 (push) Blocked by required conditions
Continuous Integration / unix-freebsd (push) Blocked by required conditions
Continuous Integration / flatpak-aarch64 (push) Blocked by required conditions
Continuous Integration / flatpak-x86_64 (push) Blocked by required conditions
Continuous Integration / release (push) Blocked by required conditions
SonarCloud Analysis / sonar (push) Waiting to run
2026-03-19 10:41:22 +00:00
b251c98a4e fix: kill core orphan on gui death (linux) 2026-03-16 09:38:14 -04:00
23c8496e24 feat: allow users to run a script on entry or exit of a screen 2026-03-16 12:33:45 +00:00
18220a7847 chore: Fix Typo 2026-03-16 12:33:45 +00:00
a26698c377 repo: add an initial code of conduct 2026-03-16 07:28:03 -04:00
ac8cc42b7a fix: retry OpenClipboard() on Windows
OpenClipboard() can fail transiently when another process holds the
clipboard mutex. Add a retry loop (5 attempts, 5ms delay) so that
Deskflow handles brief contention gracefully instead of immediately
failing.
2026-03-12 08:19:43 -04:00
7126f31d3f fix: do not reset network if old interface is missing
fixes: #9552
2026-03-12 10:24:20 +00:00
44db410dad docs: rm copilotnote 2026-03-11 07:48:51 -04:00
bc7b1082e7 doc: fix ssl exception link 2026-03-11 07:48:51 -04:00
ea0bf9d56d docs: Update README.md include Copilot note 2026-03-08 18:38:07 +00:00
6657bdd9b1 build: not using cache to store global state for macOS signing 2026-03-08 18:21:34 +00:00
11871d343d refactor: check for not mac not win in placeof x or wayland in some cases 2026-03-06 08:57:31 -05:00
12cf55d4fc build: Replace WINAPI_CARBON with Q_OS_MAC 2026-03-06 08:57:31 -05:00
e4cf1392c9 build: Replace WINAPI_MSWINDOWS with Q_OS_WIN 2026-03-06 08:57:31 -05:00
f2a54f4af0 buid: replace NIH SYSAPI_WIN32 with Q_OS_WIN 2026-03-06 08:57:31 -05:00
fce1a37e97 build: remove SYSAPI_UNIX define 2026-03-06 08:57:31 -05:00
90e79dad75 refactor: SettingsDialog update ux for initial window state 2026-03-06 13:38:30 +00:00
8f8874370e refactor: SettingsDialog adjust wording of close to tray option 2026-03-06 13:38:30 +00:00
3d67865ffc refactor: SettingsDialog, new Window Behavior tab 2026-03-06 13:38:30 +00:00
22a303842e refactor: Settings Dialog Vertically center contents 2026-03-06 13:38:30 +00:00
c20671f1db build: ensuring macOS codesign is triggered for changes in core 2026-03-05 15:22:46 -05:00
844dac439a ci: macos capture build package attempt do not let it write to stdout 2026-03-04 07:58:39 -05:00
5e781e6095 i18n(es): fixing hostname field translation 2026-03-02 08:11:52 -05:00
2b379b31cd refactor: SettingsDialog adjust tab layout to have consistant top and bottom margins 2026-03-02 06:31:21 -05:00
8bb23179c4 refactor: SettingsDialog, adjust tray icon style layout 2026-03-02 06:31:21 -05:00
a8588ab507 refactor: SettingsDialog, Fix missing spacing in language combobox with some widget sets 2026-03-02 06:31:21 -05:00
c80cd56f27 fix: properly handling infinite timeout for macOS on EventQueue 2026-02-27 19:47:59 -05:00
7743d9008d refactor: checking for server config files read permissions upon start 2026-02-27 16:21:40 -05:00
2ecf91e50a refactor: adding function to check if server config file have the needed read permissions 2026-02-27 16:21:40 -05:00
d8c7367900 fix: visual error if core start emit errors that modify start/restart visibility 2026-02-27 16:21:40 -05:00
8a53b4bc8e ci: split build and package for mac os letting us retry dmg creation upto 5 times 2026-02-27 10:30:10 -05:00
fc1f3b0142 fix: macOS flicker when menu is first clicked if the app is set to autohide on startup
fixes: #9523
2026-02-27 12:25:14 +00:00
814d63af28 refactor: MainWindow::EvenFilter set keyEvent in if only 2026-02-27 12:25:14 +00:00
a9bfcf3c81 refactor: SettingsDialog remove minimum size from vertial spacer on network page 2026-02-26 13:10:24 +00:00
fb8104ff86 fix: security icon not being set for clients
fixes: #9524
2026-02-26 13:10:24 +00:00
a0a28e7a94 chore: remove untriggerable wayland warnings 2026-02-26 12:52:03 +00:00
9188d4b1c1 build: require libportal 0.9.1 2026-02-26 12:52:03 +00:00
d392547fd8 fix: ClientProxyUnknownFailure should also remove its client socket 2026-02-26 12:02:28 +00:00
220bf3178c fix: correctly deletes sockets that failed to become clients 2026-02-26 12:02:28 +00:00
c0692b6fc7 refactor: remove messages::showClientError, fix mainwindow calling showandactive for non error messages 2026-02-24 17:06:17 +00:00
47ed13868f refactor: ScreenSetupView remove unneeded include 2026-02-24 16:10:01 +00:00
09d4b1a27a refactor: Forward Declare more in gui/validators classes 2026-02-24 16:10:01 +00:00
4e641adae9 refactor: ComputerNameValidator define regex static where used 2026-02-24 16:10:01 +00:00
568f5c7fc5 refactor: SpacesValidator, use QChar::Space 2026-02-24 16:10:01 +00:00
a0ac24a42c refactor: NewScreenWidget::mousePressEvent remove remove unused arg 2026-02-24 16:10:01 +00:00
f69bd5601c refactor: make NetworkMonitor::validAddresses static 2026-02-24 16:10:01 +00:00
37728cc7a3 refactor: Settings::cleanComputerName do not store empty QString for nothing 2026-02-24 16:10:01 +00:00
b4dbce385c refactor: Mainwindow: prevent core from running while editing the host name 2026-02-24 15:57:22 +00:00
9aeb04b4a6 refactor: MainWindow do not allow the computer name to be edited if the core is running 2026-02-24 15:57:22 +00:00
3db4c60155 refactor: MainWindow add canRunCore method 2026-02-24 15:57:22 +00:00
c37c7e2354 ci: release dev docs from build/docs 2026-02-23 17:26:19 -05:00
4314159a0b Revert "chore: move LICENSE -> docs/LICENSE"
This reverts commit dd55247380.
2026-02-23 17:26:19 -05:00
7f4b942817 ci: install doxygen with depends everywhere 2026-02-23 17:02:05 -05:00
c2342d5124 docs: Included a generic Readme for the root of the documents 2026-02-23 17:02:05 -05:00
dd55247380 chore: move LICENSE -> docs/LICENSE 2026-02-23 17:02:05 -05:00
fe9407ca33 refactor: move SECURITY.md -> docs/Security.md, install it to CMAKE_INSTALL_DOCDIR 2026-02-23 17:02:05 -05:00
9376c68739 chore: move CONTRIBUTING.md => .github/CONTRIBUTING.md 2026-02-23 17:02:05 -05:00
439541fac1 chore: move README -> .github/README 2026-02-23 17:02:05 -05:00
dfae2aaf20 chore: move doc dir to docs 2026-02-23 17:02:05 -05:00
5ea8874583 refactor: move all status bar items to new status bar widget 2026-02-23 21:48:17 +00:00
07de9efe7c refactor: CoreProcess add signal for when the security level text changes 2026-02-23 21:48:17 +00:00
c791135160 refactor: move CoreProcess::ProcessState => common/Enums deskflow::core::ProcessState 2026-02-23 21:48:17 +00:00
79fdf3a1f6 refactor: mv CoreProcess::ConnectionState -> common/Enums deskflow::core::ConnectionState 2026-02-23 21:48:17 +00:00
76353eceb3 refactor: NetworkMonitor::validAddresses filter our based on humanreadable and add vEth for windows wsl to ignore list 2026-02-23 21:24:56 +00:00
fb60189078 feat: NetworkMointor::validAddresses, return the useable ip4 and ip6 address 2026-02-23 21:24:56 +00:00
3c140ed479 chore: rename NetworkMonitor::getAvalibleIpv4Addresses => NetworkMonitor::validAddresses 2026-02-23 21:24:56 +00:00
5b4dfefcf7 doc: document x / y scroll scale and invert 2026-02-23 21:24:56 +00:00
033e5530c3 refactor: remove the generic connection and hostname failures dialog
this dialog has been the cause of alot of confusion,
it will almost always show up incorrectly at least once when connecting a new client
if you accept the client side dialog before adding the screen to the server
fixes: #9497
2026-02-23 21:03:48 +00:00
727d6ff166 refactor: moving ServerApp::currentConfig to Settings::serverConfigFile 2026-02-23 07:15:49 -05:00
aa54bd329f fix: add Daemon::LogLevel to the list of valid config keys 2026-02-23 07:15:49 -05:00
692f43d8af refactor: SettingsDialog hide Advanced tab for portable version on windows 2026-02-21 07:56:47 +00:00
263a23fcaa fix: Settings dialog blocking return to Automatic
fixes:# 9501
2026-02-21 07:56:47 +00:00
bde89d4026 ci: Use Qt 6.10.2 on mac arm and windows builds 2026-02-20 14:38:42 +00:00
b3cecdde7f ci: remove unused add-kitware-repo action 2026-02-20 14:38:42 +00:00
5534232a1d i18n(ko): Update ko translation by bimppap
new string from https://github.com/deskflow/deskflow/pull/9478\#pullrequestreview-3829032105
2026-02-20 14:24:04 +00:00
4c7f546c60 fix: XWindowScreen, do not send a scroll delta for 0
fixes: #9477
2026-02-18 18:11:38 +00:00
1ca8695659 fix: Read fingerprint data before applying the initial config to prevent the fingerprint from being empty making the button hidden
fixes: #9483
2026-02-18 15:26:17 +00:00
e7363aaf8e ci: remove winget publish from our release
our last release was botched due to our repo being out of sync within a ~12hours of release a winget bot had already
completed the update and caused our future attempts with out now synced repo to fail. Lets lets winget bot do the winget release
2026-02-18 11:34:45 +00:00
6ccef50b7c refactor: SettingsDialog, hide advanced tab when running on macos 2026-02-17 13:41:47 +00:00
d7fb9bc6d2 refactor: SettingsDialog, move language to General 2026-02-17 13:41:47 +00:00
41197334f0 refactor: SettingsDialog move network items to own tab 2026-02-17 13:41:47 +00:00
74c25fdff6 refactor: SettingsDialog rename regular tab to general 2026-02-17 13:41:47 +00:00
f6348736e8 refactor: SettingsDialog, move Log settings to own tab 2026-02-17 13:41:47 +00:00
208556b5aa refactor: SettingsDialog, add reset to default button 2026-02-17 13:41:47 +00:00
58963de10f refactor: SettingsDialog add a reset button for settings, and tooltips for the buttonbox buttons 2026-02-17 13:41:47 +00:00
457c31fbaf refactor: SettingsDialog only allow save if modified 2026-02-17 13:41:47 +00:00
690d6a67ef refactor: SettingsDialog, no longer need coreProccess in the settings dialog 2026-02-17 13:41:47 +00:00
094cbadf91 i18n(ja): update Japanese(ja) translation
Check and update unfinished translation
2026-02-17 04:34:25 +00:00
760e3b99b0 Release 1.26.0
Some checks are pending
Continuous Integration / ci-passed (push) Blocked by required conditions
Continuous Integration / test-results (push) Blocked by required conditions
Continuous Integration / lint-reuse (push) Waiting to run
Continuous Integration / lint-clang (push) Blocked by required conditions
Continuous Integration / analyze-valgrind (push) Blocked by required conditions
Continuous Integration / windows-2022-x64 (push) Blocked by required conditions
Continuous Integration / windows-2022-arm64 (push) Blocked by required conditions
Continuous Integration / macos-arm64 (push) Blocked by required conditions
Continuous Integration / macos-x64 (push) Blocked by required conditions
Continuous Integration / archlinux-x86_64 (push) Blocked by required conditions
Continuous Integration / debian-arm64 (push) Blocked by required conditions
Continuous Integration / debian-x86_64 (push) Blocked by required conditions
Continuous Integration / debian-testing-arm64 (push) Blocked by required conditions
Continuous Integration / debian-testing-x86_64 (push) Blocked by required conditions
Continuous Integration / fedora-42-arm64 (push) Blocked by required conditions
Continuous Integration / fedora-42-x86_64 (push) Blocked by required conditions
Continuous Integration / fedora-43-arm64 (push) Blocked by required conditions
Continuous Integration / fedora-43-x86_64 (push) Blocked by required conditions
Continuous Integration / opensuse-arm64 (push) Blocked by required conditions
Continuous Integration / opensuse-x86_64 (push) Blocked by required conditions
Continuous Integration / ubuntu-25.10-arm64 (push) Blocked by required conditions
Continuous Integration / ubuntu-25.10-x86_64 (push) Blocked by required conditions
Continuous Integration / ubuntu-26.04-arm64 (push) Blocked by required conditions
Continuous Integration / ubuntu-26.04-x86_64 (push) Blocked by required conditions
Continuous Integration / unix-freebsd (push) Blocked by required conditions
Continuous Integration / flatpak-aarch64 (push) Blocked by required conditions
Continuous Integration / flatpak-x86_64 (push) Blocked by required conditions
Continuous Integration / release (push) Blocked by required conditions
Continuous Integration / winget-publish (push) Blocked by required conditions
2026-02-16 13:22:13 +00:00
042abd699d feat: support horizontal scroll modifiers 2026-02-16 12:45:03 +00:00
f6b1546f8b refactor: use a client config dialog for client options 2026-02-16 12:45:03 +00:00
2cc19c9f1e refactor: rename Settings::Client::InvertScrollDirection -> Settings::Client::InvertYScroll 2026-02-16 12:45:03 +00:00
329cf07275 chore: MainWindow use Connect to to label the client host text entry 2026-02-16 12:45:03 +00:00
99da66dbf7 fix: using a proper std::string to store KeyInfo buffers 2026-02-16 12:13:58 +00:00
3c6aa9999b refactor: MainWindow updateModeControls no longer takes a bool just check the process mode 2026-02-16 11:40:08 +00:00
19724e3b69 fix: enable m_actionStopCore based on cores state 2026-02-16 11:40:08 +00:00
b96619d726 refactor: prevent modecontrols from being updated twice on startup.
Apply config should toggle the core mode to ensure the labels and mode is set correctly post config
2026-02-16 11:40:08 +00:00
c9aaeaee2a refactor: MainWindow::CoreModeToggle set the new core mode here not updateModeControls 2026-02-16 11:40:08 +00:00
1b6def23d8 refactor: MainWindow::CoreModeToggle, use CoreMode type internally 2026-02-16 11:40:08 +00:00
c1172ab8b5 refactor: MainWindow only act on when the rb for mode is Checked, this prevents doing the full coreModeToggled twice when changing modes 2026-02-16 11:40:08 +00:00
12860646d2 i18n(zh_CN): remove extra peroid in translation 2026-02-16 11:40:08 +00:00
869bd0e2aa doc: update link for latest vc_redist 2026-02-14 14:18:33 +00:00
71929e8332 ci: don't fail ci-comment workflow on no PR
Can easily happen on force push
2026-02-12 17:40:34 +00:00
fe285dc192 ci: fix reference to nonexistent $dir var in ci-comment workflow 2026-02-12 17:40:34 +00:00
67066c339e ci: fix edge case in ci-comment workflow where old comment isn't deleted 2026-02-12 17:40:34 +00:00
759ed684e3 ci: count X emoji using grep in test-summary action
ci: handle when grep exits with code 1 in test-summary action
2026-02-12 17:40:34 +00:00
611a3300ba refactor: do not return true when checking physical ip is private or not return if a was private 2026-02-12 17:16:32 +00:00
64c104a5c2 refactor: include a point 2 point check when checking if an interface is virtual 2026-02-12 17:16:32 +00:00
f9857e102a fix: NetworkMonitor virtual sorting
fixes: #9459
make NetworkMonitor::isVirtualInterface a static member of NetworkMonitor
write tests for NetworkMonitor
2026-02-12 17:16:32 +00:00
9dc76c1caf ci: remove concurrency check for valgrind workflow 2026-02-12 16:28:32 +00:00
68f867b914 ci: use concurrency groups to allow updates to a branch to cancel in progress run of old version of that branch 2026-02-12 12:32:45 +00:00
dd77f79b17 build: enables CMP0156 policy if available (de-duplicates libraries on linker calls) 2026-02-11 21:18:22 +00:00
e555b63931 fix: extra "a" with Rime and apply clang-format 2026-02-11 14:33:04 +00:00
b33eb0135d ci: add step to install and test package binaries
fixes: #7774

Signed-off-by: Louis Labeyrie <labeyrielouis@gmail.com>
2026-02-11 13:10:41 +00:00
f9d7c75492 ci: use CodeQL v4
codeQL v3 is EOL in DEC 2026
2026-02-11 12:50:08 +00:00
a532f655c1 feat: support horizontal scrolling
fixes: #7220
based on 9f15b1bcf2
Co-authored-by: Evan Maddock <maddock.evan@vivaldi.net>
2026-02-11 11:59:28 +00:00
82588a7fc9 chore: remove unused privates from PlatformScreen 2026-02-11 11:59:28 +00:00
1f2d169b0d build: fix typo in daemonDepends
fixes: #9439
2026-02-09 12:45:51 +00:00
1c99736c16 refactor: SettingsDialog, scroll scale spinbox remove wraping and make step size .1 2026-02-09 09:02:21 +00:00
050cb649c2 refactor: use ScrollDelta for fakeMouseWheel 2026-02-09 09:02:21 +00:00
5612e99f1d refactor: Move the scrollModifiers to ISecondaryScreen 2026-02-09 09:02:21 +00:00
a520e3b2e9 refactor: check settigns for invertscroll in PlatformScreen 2026-02-06 12:51:39 +00:00
380f65954d chore: remove unused Settings::ScrollSpeed 2026-02-06 12:51:39 +00:00
0f6ec6c196 refactor: XWindowsScreen use a fixed minimum step value in place of the scroll speed setting 2026-02-06 12:51:39 +00:00
857326b274 refactor: rename PlatformScreen::mapClientScrollDirection -> PlatformScreen::applyClientScrollModifier
prepare for horizontal scroll support by having it handle pairs of x and y values
2026-02-06 12:51:39 +00:00
5e8a6f0bcb fix: vertical scroll scaling on all platforms
fixes: #9120
2026-02-06 12:51:39 +00:00
a960f2ff30 doc: update remoteHost comment to include list ability 2026-02-06 12:51:39 +00:00
5c3e1f182c build: add qt6-svg-plugins to the debian pacakges recommends, this should in most cases install the package if your system does not have it. fixes: #9426 2026-02-05 18:30:29 +00:00
84e1e722c0 fix: Send extra mouse buttons on mac os servers to clients 2026-02-04 09:56:10 +00:00
4200de66ee fix: scroll Issue on X11 by not checking for wheel in mapButtonToX 2026-02-04 09:45:25 +00:00
be4e861604 feat: use Computer in settings to replace name
provide Settings::upgradeSettings to upgrade the screenName -> computerName
Make a note to remove "ScreenName" for 2.0
2026-02-03 18:55:17 +00:00
8f5a4106d3 doc: use computer to replace screen when describing options 2026-02-03 18:55:17 +00:00
145e9ec926 chore: add CLAUDE.md to the gitignore 2026-02-03 18:43:41 +00:00
05c050b81e fix: handle back mouse on xwindows and windows
based on : 9f15b1bcf2
fixes: #5682
2026-02-03 09:41:22 +00:00
403c4ad9b9 fix: log protocol mismatch at INFO level
fixes: #7800
2026-01-30 13:07:04 +00:00
f065979b3f Fix: detect key repeat in libei input
For libei, there's no indication that a key is repeated.
However, sending repeated key down events (DKDN instead
of DKRP for the synergy protocol) can be confusing to
clients, which then causes issues like in #7971.

Detect repeated key down events in EiScreen server and
send them to the client with the repeat flag set, so in
e.g. synergy that causes the DKRP messages, to be less
confusing.

For me this fixes an issue where the synergy client is
creating a USB device, which requires repeated events
to be entirely dropped since the host OS where the USB
device is connected will do its own repeat when a key
is held down.
2026-01-30 12:19:29 +00:00
933617d5b1 ci: use Fancy Checkout v2 2026-01-30 09:10:08 +00:00
adbaef7dfb chore: remove unused test files not longer needed from old hellotests 2026-01-28 13:00:54 +00:00
fdf6a5b8f3 refactor: remove kProtocolName vars and use the NetworkProtocol instead
fixes: #9401
2026-01-28 12:12:02 +00:00
028b71a833 docs: remove note from readme about repology new package names 2026-01-28 08:21:24 +00:00
b2b2951fb7 docs: remove bounty links from the readme 2026-01-28 08:21:24 +00:00
dbed37e9ba refactor: networkprotocol, add string / enum conversion methods use them in config and elsewhere 2026-01-26 13:30:24 +00:00
0d3768d838 chore: fix minor typo in doxygen comments for events 2026-01-26 13:14:53 +00:00
be2546c27b refactor: remove legacy deps pattern and hello back class 2026-01-26 13:14:53 +00:00
6459eb40df chore: surface stopping messages in lower log level 2026-01-26 13:14:53 +00:00
555cb6888f build: flatpak update libei and google test to mach flathub build 2026-01-26 12:49:16 +00:00
a00230829c ci: Make sure that the ci-passed fails if any previous steps were not successful 2026-01-26 12:49:16 +00:00
1df5ab0851 ci: bump flatpaks built by runner to use kde-platform 6.10 to keep in sync with what flathub builds 2026-01-26 12:49:16 +00:00
26cb66c1e5 ci: use ubuntu-slim runner for ci comment and issue-check jobs 2026-01-26 12:49:16 +00:00
348e26564f ci: Continuous-Integration use ubuntu-slim runner where possible 2026-01-26 12:49:16 +00:00
1ed394e3ef refactor: remove DEBUG3 and move DEBUG3 messages to DEBUG2 2026-01-26 12:35:00 +00:00
2cf4fc8d0a refactor: remove DEBUG4 level and move any DEBUG4 messages to DEBUG3 2026-01-26 12:35:00 +00:00
d6ffcd37d7 refactor: remove DEBUG5 level and move any DEBUG5 message to DEBUG4 2026-01-26 12:35:00 +00:00
046c15736b chore: DaemonApp, remove unused and unimplemented init function and the enum InitResult return type it returned 2026-01-26 11:33:13 +00:00
6980e86d6a chore: DaemonApp, remove unused showHelp this is left over from when this was an application 2026-01-26 11:33:13 +00:00
973cc76927 chore: remove unused gui/CommandProcess 2026-01-26 11:33:13 +00:00
86c8c66b6e Feat: Add Korean(ko) translation 2026-01-23 13:16:33 +00:00
a5b2a4fab9 Fix: Add exception handling to setValue functions
Replace TODO comments with proper exception handling in ArchMiscWindows::setValue methods.
When a nullptr registry key is passed, the functions now throw std::invalid_argument
instead of silently returning, improving error handling and making bugs easier to detect.

Removed assert statements as they are redundant with the exception handling.

This addresses the TODO comments in lines 163 and 173.
2026-01-23 12:38:32 +00:00
e7eb324f16 chore: fix typos in variable names and log messages 2026-01-22 14:30:45 +00:00
1157bff34b doc: correct typos in README (macOS requirements and installation instructions) 2026-01-22 14:30:45 +00:00
3a242e7fc1 refactor: use windowsErrorToString instead of obsolete winsockErrorToString 2026-01-22 13:46:43 +00:00
fe179556ad fix: Settings, do not remove valid QRects from the state file 2026-01-22 13:30:12 +00:00
c7a427a94c fix: gui crash on clearsettings in debug mode
fixes: #9369
replaces: #9373
2026-01-22 12:51:34 +00:00
ed114252e2 refactor: WlClipboard, close not kill running copy process on exit 2026-01-22 12:35:54 +00:00
34f949dc72 refactor: WlClipboardTest can skip if unable to read data, this happens sometimes with wlclipboard 2026-01-20 11:38:34 +00:00
1763c82ccc refactor: correct WLClipboard test primary clipboard to compare the clipboards not call wait for condition 2026-01-20 11:38:34 +00:00
6d8804f08f chore: remove unused members of WlClipboardTests 2026-01-20 11:38:34 +00:00
ed7e29589b chore: adjust wording in pull request template 2026-01-20 10:16:21 +00:00
7641fe7549 ci: exit ci run if configure causes tr file updates 2026-01-20 10:16:21 +00:00
c63fd21c8e feat: Add a setting to allow the version to be shown in the windows title
fixes: #8538
replaces: #9351
2026-01-20 00:06:49 +00:00
281b3b8d07 fix: Clean settings values on start up
Settings will call cleanSettigs and cleanStateSettings on start up to remove any invalid or empty values in our config
fixes: #9333
2026-01-19 22:54:53 +00:00
d6fe8fa2d5 refactor: Settings::cleanSettings and Settings::cleanStateSettings, remove keys as long as they are empty 2026-01-19 22:54:53 +00:00
ffa887838f refactor: Settings::cleanSettings, skip internalConfig values 2026-01-19 22:54:53 +00:00
49f38c6a8b refactor: Settings::defaultValues, no need to return a QRect() for default windowgeometry as it will be cast to QVariant automaticly on return 2026-01-19 22:54:53 +00:00
7a2ceeedf4 refactor: Remove unneeded QVariant() when setting a setting empty to be removed 2026-01-19 22:54:53 +00:00
b25f083433 refactor: use Settings::value().toString().isEmpty() to check for empty setting values. This is because QVariant::isNull() no longer returns the internal types isNull() method. As a results "" is a non Null QVariant 2026-01-19 22:54:53 +00:00
c45d586bbf i18n(ru): add missing comments in russian ts file 2026-01-19 22:39:11 +00:00
d193af8cc8 feat: Add New Search Widget, use in the log
fixes: #8332
replaces: #9354
2026-01-19 22:39:11 +00:00
bb88bd8695 refactor: remove unneeded QIcon when setting from theme
explict cast when setting update url
2026-01-19 21:55:40 +00:00
73dbe62e48 refactor: ClientApp parse arg for network address use append for list 2026-01-19 21:22:18 +00:00
1163cb842c refactor: do not initilize already initilized screen when not sent with KeyboardbroadCastInfo 2026-01-19 21:22:18 +00:00
15db716f04 refactor: Server::handleSwitchToScreen use const for our info 2026-01-19 21:22:18 +00:00
9f8f805888 build: Add Pull Request Template 2026-01-19 20:07:10 +00:00
119f23a085 i18n(ru): fix and improve Russian translation
- Fixed numerous typos and grammatical errors (e.g., "адресс", "разроботчики").
- Unified technical terminology ("hash", "fingerprint", "IP address").
- Improved stylistic consistency by removing slang.
- Fixed plural forms (numerus) for better Russian localization.
2026-01-19 03:36:25 +00:00
aca274e9ee refactor: add (C) to copyright header where missing 2026-01-18 15:38:59 +00:00
50e7b3aadf Feat: Support multiple server IP addresses (#3665) 2026-01-17 16:26:21 +00:00
e5e53c02b5 Fix: Allow comma and semicolon in hotkey config (#7130) 2026-01-17 14:14:31 +00:00
938db301f0 refactor: modernize Server info structs to use C++ RAII
- Convert LockCursorToScreenInfo, SwitchToScreenInfo, SwitchInDirectionInfo,
  and KeyboardBroadcastInfo from C-style malloc/free structs to proper C++
  classes inheriting from EventData
- Replace char arrays with std::string for safer string handling
- Remove obsolete alloc() static methods in favor of constructors
- Update all call sites to use 'new' with constructors and getDataObject()
  instead of malloc with alloc() and getData()
- Add 'do nothing' comments to empty constructors for SonarQube scans
- Maintain EventFlags::DeliverImmediately for proper event delivery
- Reduces code by 48 lines and eliminates manual memory management
- Improves type safety and follows modern C++20 practices

This change makes the code more maintainable and less prone to memory leaks
by leveraging C++ destructors for automatic cleanup.
2026-01-16 09:38:29 +00:00
d8dfba6372 fix: OSXScreenSaver, do not call CFRelease for empty processesNames 2026-01-13 01:13:32 +00:00
7f57d53494 refactor: CoreProcess use FileTail::setWatchedFile if the file to tail changes 2026-01-12 11:18:40 +00:00
5e61a2b5ce refactor: new FileTail::setWatchedFile 2026-01-12 11:18:40 +00:00
2da14c3da3 fix: Coreprocess will attempt to create a daemon log before returning the path if it does not exist 2026-01-12 11:18:40 +00:00
cab33df72d chore: deskflow-daemon remove install and uninstall from usage 2026-01-12 11:18:40 +00:00
35ee17f959 fix: macOS server crash when client disconnects abruptly 2026-01-12 10:49:02 +00:00
7fdb26f2ea refactor: move deskflow/DaemonApp => apps/deskflow-daemon/DaemonApp 2026-01-07 14:36:55 +00:00
3993449594 refactor: daemonRunning is not used for client / server 2026-01-06 12:05:23 +00:00
f8ae8c5781 chore: remove unused daemonInfo from App and SubClasses 2026-01-06 12:05:23 +00:00
22dad7ac06 chore: remove unused App::daemonMainLoop 2026-01-06 12:05:23 +00:00
db10f1c5a4 chore: remove unused ClientApp / StaticApp daemonMainLoopStatic method 2026-01-06 12:05:23 +00:00
0c368f402b refactor: use ArchDaemonWindows::runDeamon directly
remove now unused ArchMiscWindows::runDaemon
2026-01-06 12:05:23 +00:00
0e04364d17 refactor: use ArchDaemonWindows::daemonFailed directly
remove now unused ArchMiscWindows::daemonFailed
update copyright year
2026-01-06 12:05:23 +00:00
3ff06b7d9a refactor: use ArchDaemonWindows::getDaemonQuitMessage directly
remove now unused ArchMiscWindows::getDaemonQuitMessage
2026-01-06 12:05:23 +00:00
c7da833f07 refactor: use ArchDaemonWindows::daemonRunning directly
removes:
  unused DAEMON_RUNNING define in App.h
  unused ArchMiscWindows::daemonRunning
update copyright years
2026-01-06 12:05:23 +00:00
09c1bd1582 refactor: MainWindow, unify how Automatic and Fixed Ip are displayed 2026-01-05 12:06:20 +00:00
d324dd1a93 refactor: MainWindow::updateIpLabel, simplify IPValid checks 2026-01-05 12:06:20 +00:00
889689bd8e fix: MainWindow, IpLabel Only now NoIP Detected if we are not running or started with no address 2026-01-05 12:06:20 +00:00
844ebf5216 refactor: Remove need for NetworkMonitor::getSuggestedIpAddress. Its always first if there is data 2026-01-05 12:06:20 +00:00
ae9ca35448 refactor: NetworkMonitor: use QStrings
allows us to simplify alot of the code around the lists and lets us also fliter lists easily

update copyright for 2026, add missing deskflow devlopers for mainwindow for 2025 work
2026-01-05 12:06:20 +00:00
dac9539ad9 refactor: EventQueue, use auto for EventQueueTimer pointers 2026-01-05 12:06:20 +00:00
b8e0415632 fix: macOS key repeat not working 2026-01-05 11:47:13 +00:00
3598eb6a47 refactor: RM IEventQueueBuffer::newTimer and IEventQueueBuffer::deleteTimer
port: https://github.com/input-leap/input-leap/pull/1592
Original Message:
  base: Remove IEventQueueBuffor newTimer and deleteTimer APIs
        In the current implementation timers are not platform-specific. On all
        currently supported platforms timer constrution and destruction is
        simple new and delete, so it does not make sense having this
        customization point.
Original Author: p12tic
Ported By: sithlord48
2026-01-02 12:27:24 +00:00
38722f7308 build: macos, add app to the utilities category 2026-01-02 12:03:31 +00:00
8d52facc0b fix: macos, prevent automatic termination during memory pressure
Disable macOS Automatic Termination to prevent the server/client from
being killed during memory pressure events. Adds NSSupportsAutomaticTermination
to Info.plist and programmatically disables termination in the Cocoa app.

Fixes #7329

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-02 12:03:31 +00:00
61fcad2c14 refactor: MainWindow::updateIpLabel, remove single use vars 2026-01-02 11:43:34 +00:00
a84e91a3f2 refactor: Mainwindow::updateIpLabel return early if we are using fixedIp from settings 2026-01-02 11:43:34 +00:00
c2314ad893 refactor: MainWindow, remove m_currentIPValid by reducing its scope to the method where its used 2026-01-02 11:43:34 +00:00
1973005e98 refactor: MainWindow, simplify ip update if core is not running 2026-01-02 11:43:34 +00:00
00235ba189 refactor: NetworkMonitor, use ranged sort for ip ranges 2026-01-02 11:43:34 +00:00
495277c7c9 refactor: NetworkMonitor, use isLocalLink to check for 169.254/16 range 2026-01-02 11:43:34 +00:00
a73057f3a7 refactor: NetworkMonitor, short phyical using isPrivateUse()
this an Ip is considered private when its in a RFC1918 range
10/8, 172.16/12 and 192.168/16 are private IPs
2026-01-02 11:43:34 +00:00
a0f06d907f refactor: NetworkMonitor, set m_isMonitoring initial state in header 2026-01-02 11:43:34 +00:00
3d8cf17d57 chore: gui Remove custom tab stops from settings dialog and use default 2025-12-30 18:31:05 +00:00
ca418b3ba5 chore: gui, Improve log message for disabled update check 2025-12-30 18:31:05 +00:00
189053697b refactor: Log server response on version check error
Qt `errorString()` only contains the error code and error text, but not the response body. And, in HTTP/2 the error string is gone but the error is still printed like it's there: https://bugreports.qt.io/browse/QTBUG-140126
2025-12-30 18:31:05 +00:00
e674d8b27c refactor: Rename setting Settings::Core::UpdateUrl => Settings::Gui::UpdateCheckUrl 2025-12-30 18:31:05 +00:00
7682e17afe refactor: Move src/lib/Config => src/lib/platform/XWindowsConfig
This file is used only in XWindows related platform code.
2025-12-30 17:22:00 +00:00
163ec18730 refactor: VersionInfo is now part of common 2025-12-30 17:22:00 +00:00
d27fd22d8f refactor: SettingsDialog adjust network section so IP is on left and port is on right 2025-12-30 17:03:47 +00:00
cbebaad3b8 feat: add network monitoring and IP address management
- introduce NetworkMonitor class to track network addresses change
- replace QLineEdit with QComboBox for interface selection in settings
- implement automatic IP detection and suggestion logic
- add signal-slot connections for real-time network updates

Log: add network monitoring and IP address management.
2025-12-30 17:03:47 +00:00
16d35349d3 build: use a tweak of 9999 when a valid version tag can not be found
loosely based on https:://github.com/deskflow/deskflow/pull/9303
where it was pointed out that using the gitrev as a fallback could create an invalid version
2025-12-30 13:41:33 +00:00
f8d9de1f2e build: platform, remove unneeeded include_dir for mac os system path 2025-12-30 13:41:33 +00:00
53d2c5e399 build: platform, remove link_wayland_libs macro and do it in its only used place allowing more simplification of the linking platform lib 2025-12-30 13:41:33 +00:00
89ee932db3 build: adjust spacing for cmake files 2025-12-30 13:41:33 +00:00
fb63b70e8d build: lib/common/CMakeLists.txt, remove unneeded unset calls 2025-12-30 13:41:33 +00:00
4a62e51d1d build: unset GITREV after use 2025-12-30 13:41:33 +00:00
2dd0360dec fix: Restore clipboard sharing after 53441821e0
We wanted the value contained in the string as size_t, not the size (length) of
the string. size_t is (normally) an alias for unsigned long, so toUlong() should
do the trick.
2025-12-30 13:16:36 +00:00
9976caafab refactor: LineEditValidator only call errorMessage::isEmpty once 2025-12-30 12:58:11 +00:00
530bcad8a6 chore: remove unused gui/Styles 2025-12-30 12:58:11 +00:00
949913cd6e refactor: use crimson for the error color 2025-12-30 12:58:11 +00:00
1855d33e1f refactor: ValidationError, use palette to set the colors used 2025-12-30 12:58:11 +00:00
ccd40c2927 refactor: validatorError::setMessage return early 2025-12-30 12:58:11 +00:00
6851046c5a refactor: validatorError, make clear a private method 2025-12-30 12:58:11 +00:00
1a9316150d refactor: ValidatorError, m_pLabel -> m_label 2025-12-30 12:58:11 +00:00
b56dd3f387 chore: ValidatorError, create explicit private section 2025-12-30 12:58:11 +00:00
2cbe2c65e8 refactor: screenSettingsDialog, do not set the initial style for name alias lineedits 2025-12-30 12:58:11 +00:00
b8b7799a47 refactor: LineEditValidator, adjust border style based on the Qt Style in use 2025-12-30 12:58:11 +00:00
2b8e7fa6b2 refactor: screensetting dialog, adjust spacers for dead corners 2025-12-30 12:58:11 +00:00
fdb5405e2c refactor: use system color for hyperlinks 2025-12-24 11:23:13 +00:00
0c440843b0 chore: replace deskflow::gui::style::kColorWhite with the svg color white 2025-12-24 11:23:13 +00:00
caf77fe342 chore: remove unused deskflow::gui::style::kLightGreyColor 2025-12-24 11:23:13 +00:00
b432cbc145 fix: error on start shows gui
do not show client errors if the windows is not visible
2025-12-23 13:28:02 +00:00
ce97817d45 refactor: constants, move kTlsFingerprintTrustedClientsFilename => Settings::defaultValue where used 2025-12-22 14:41:04 +00:00
2b4b6a8470 refactor: constants, move kTlsFingerprintTrustedServersFilename => Settings::defaultValue where used 2025-12-22 14:41:04 +00:00
5c34d0edc5 refactor: constants, move kTlsCertificateFileanme to => Settings::defaultValue where used 2025-12-22 14:41:04 +00:00
049f8d718a refactor: constants, move kTlsDir to => Settings::tlsDir where used 2025-12-22 14:41:04 +00:00
c693d258fd refactor: constants, move kDefaultLogFile to => Settings::defaultValue where used 2025-12-22 14:41:04 +00:00
b23e9f9b04 refactor: constants, move kDaemonLogFile => Settings::defaultValue where used 2025-12-22 14:41:04 +00:00
a5bb310e94 chore: constants remove unused kWindowsRegistryKey 2025-12-22 14:41:04 +00:00
7f3d661e31 refactor: net, lookup hostname using any valid Ip4 or Ip6 address
fixes: #9110
2025-12-22 14:24:02 +00:00
6982ce824f build (win32): do not include icu related dlls for windows deployments 2025-12-19 11:57:41 +00:00
0c5b7de554 build: reduce duplication by setting the win32 depends pre and post excludes in src/apps/CMakeLists 2025-12-19 11:57:41 +00:00
2a54f57532 chore: add Q_OBJECT macro to Validators with translations 2025-12-18 13:10:09 +00:00
f0e77c499b chore: settings, remove unneeded {} 2025-12-18 13:10:09 +00:00
fa78b957b5 refactor: settings, use state not settings in the log when changing the state file 2025-12-18 13:10:09 +00:00
60d5bb8378 chore (settings): fix typo peroid -> period 2025-12-18 13:10:09 +00:00
d8e2537d47 refactor: Settings::logLevelToInt simplify the method and add tests to cover it 2025-12-18 13:10:09 +00:00
425d427fce ci: adjust CI to use qt 6.10.1 with 6.9.3 being used for intel macs 2025-12-15 10:00:21 -05:00
8f972bf15e docs: add note about what versions of mac os are supported for arm and intel 2025-12-15 10:00:21 -05:00
c36074df9f docs: Add note to read me that windows 10 v1809 or higher is needed 2025-12-15 10:00:21 -05:00
5e347d8725 fix: Mac os log file not working
fixes: #9274
The log file path is not able to be empty since Settings::value will return the default path if it is, Do not send a c_str to create our FileLogger it wants a QString
2025-12-15 14:41:01 +00:00
ef734a869c build: make sure that translations are built before the source files
this makes sure that the I18N tests are not run before the translation files are generated.
2025-12-15 14:22:40 +00:00
c942de81e7 refactor: I18NTests add additional Tests 2025-12-15 14:22:40 +00:00
dfe6c82a5c refactor: I18N make sure m_currentLang is set to the 639 name on initial load 2025-12-15 14:22:40 +00:00
97b11bf2da refactor: I18n, add static s_prefix -> "_" to use when loading 2025-12-15 14:22:40 +00:00
023c9509e0 refactor: correct typo I18N::langaugesChanged => I18N::languagesChanged 2025-12-09 13:54:05 +00:00
b1bac23dcb chore: Add tests for I18N 2025-12-09 13:54:05 +00:00
13750f4175 chore: remove unused io/Filesystem 2025-12-08 11:24:36 +00:00
27579e4fae refactor: Move file open logic to SecureUtil where its used 2025-12-08 11:24:36 +00:00
cb4621cad7 chore: SecureUtils::generatePemSelfSignedCert take QString for path 2025-12-08 11:24:36 +00:00
2d682d9151 chore: io/FileSystem remove unused methods 2025-12-08 11:24:36 +00:00
26417a2543 ci: add dispatch event to homebrew-tap 2025-12-05 05:23:16 -05:00
87e6521f65 doc: add additional note about damaged app on mac os 2025-12-05 10:06:23 +00:00
b151666f6b refactor: I18N use short (ISO639) names to save and load not native strings, the documentation says we use these already 2025-12-04 08:27:59 -05:00
d1e2865319 fix: macOS not showing Colorful icon
fixes: #9255
2025-12-04 11:09:59 +00:00
70c54d6cf7 chore: remove unused Unicode::UTF8ToUCS4 2025-12-04 10:36:48 +00:00
62a73996b9 chore: remove unused Unicode::UTF8ToUTF32 2025-12-04 10:36:48 +00:00
75a1ab9719 chore: remove unused Unicode::UCS4ToUTF8 2025-12-04 10:36:48 +00:00
6174043c7f chore: remove unused Unicode::UTF32ToUTF8 2025-12-04 10:36:48 +00:00
bfc65ebf6b chore(tr): Add translators as CODEOWNERS for language files 2025-12-03 13:57:59 -05:00
53441821e0 refactor: Replace deskflow::string::stringToSizeType with QString::size() 2025-12-03 12:14:11 +00:00
f012cf2e4b refactor: replace deskflow::string::sizeTypeToString with QString::number() 2025-12-03 12:14:11 +00:00
c73923947a Fix Homebrew tap command in README
The correct command is `brew tap deskflow/tap` not `deskflow/homebrew-tap`.
Homebrew automatically strips the `homebrew-` prefix from repository names.

Related: https://github.com/deskflow/homebrew-tap/pull/6
2025-12-03 11:57:13 +00:00
a6daff59f6 refactor: SecureSocket::doWrite remove unnessessary reset of bufferSize 2025-12-02 08:37:30 -05:00
dc76366a48 fix: SecureSocket::secureConnect, uset SSL host name before connect 2025-12-02 08:37:30 -05:00
9b40bf2f9b chore: remove unused base/Path class 2025-12-02 08:37:30 -05:00
ea0222b1e6 refactor: App::loadConfig(const std::string&) => App::loadConfig(const QString &) 2025-12-02 08:37:30 -05:00
78234f60c4 refactor: base/Path use QString to convert to WString fo windows 2025-12-02 08:37:30 -05:00
7d07222832 refactor: SecureSocket::loadCertificates(const std::string) & => SecureSocket::loadCertificate(const QString &) 2025-12-02 08:37:30 -05:00
e5513101a6 refactor: Use the Settings::Gui::AutoStartCore to control if the Gui should start the core when starting up
removes Settings::Core::StartedBefore
2025-12-02 08:19:46 -05:00
df78f0757e refactor: Gui control if the server first shown message is shown with its own setting 2025-12-02 08:19:46 -05:00
8e8ab25fd0 refactor: use Settings::Gui::ShownFirstConnectionMessage to control message popup on initial connection a to client / server 2025-12-02 08:19:46 -05:00
b4e4277e08 refactor: add missing options 2025-12-02 08:19:46 -05:00
13219ca49c fix: only restore the size if the windows was in the tray
fixes: #9237
2025-12-01 08:39:01 -05:00
0446db93e6 refactor: handle error suppression in gui not message stack 2025-12-01 08:39:01 -05:00
a37d30c6ab refactor: SecureUtils::GenerateFingerprintArt, auto type for char pool 2025-12-01 13:20:47 +00:00
a78702d68f refactor: make DaemonIpcServer::writeToClietnSocket const 2025-12-01 13:20:47 +00:00
7831ba293a fix: Mac os Preferences missing when translated
fixes: #9226
In the MainWindow give all menu items a role to prevent mac os from misplacing them due to their label when translated
2025-11-30 10:14:46 -05:00
a01a6b0b89 fix: key repeat regression for windows caused by #9217 2025-11-30 14:48:35 +00:00
c1b5e125b0 refactor: ServerConnection: keep track of ignored clients so we only prompt for them once 2025-11-30 09:31:08 -05:00
accb9d9c59 refactor: ServerConnection: Handle the new client via signals
Use QtTests now that we can for ServerConnnecitonTests
2025-11-30 09:31:08 -05:00
11fa5d636e refactor: ServerConnection return a bool for the results of the newClientPrompt no Enum needed 2025-11-30 09:31:08 -05:00
cca6f80cb5 refactor: ClientConnection, use signal to ask for dialog
move ClientConnectionTests to Qt Tests
track if the dialog is open in the gui
track suppression in clientConnection based on connect / disconnect message
2025-11-30 14:13:35 +00:00
1ebcab60e2 refactor: Move messages client connection error to common, new common/Enums 2025-11-30 14:13:35 +00:00
2485916ad1 refactor: new signal ClientConnection::requestShowError 2025-11-30 14:13:35 +00:00
5287c51957 refactor: clearer ClientConnection::showMesssage logic 2025-11-30 14:13:35 +00:00
695dc04c00 refactor: new ClientError::NoError 2025-11-30 14:13:35 +00:00
fd94403a73 fix: ServerApp, do not blindly read the external config path for our settings location
use the default value unless the setting for using the external config is also set
fixes: #9227
2025-11-28 16:22:16 +00:00
d35716f574 feat: Configure default screen lock state
fixes: #7907
2025-11-27 08:22:13 -05:00
b6bc9202db chore: remove unused SecureUtils::pemFileCertFingerprint 2025-11-27 08:05:04 -05:00
4cb184989c refactor: TlsUtility::isCertValid we only use RSA keys for now 2025-11-27 08:05:04 -05:00
ff02285a6a refactor: move SecureUtils::getCertLength -> TlsUtility, and use Qt to get the length of the key file 2025-11-27 08:05:04 -05:00
1a6f81a34b refactor: SecureUtils use QStringLiterals where possible 2025-11-27 08:05:04 -05:00
2dfba73cfb refactor: use QCryptographicHash::Algorithm in place of Fingerprint::Type 2025-11-27 08:05:04 -05:00
52e0daba0f fix: deskflow-core always starts a new instance without --new-instance
fixes: #9216
2025-11-27 07:47:39 -05:00
2f5166fafa fix: keyholding
fixes: #7971
suggested by: PseudoResonance https://github.com/deskflow/deskflow/issues/7971#issuecomment-3570046036
2025-11-27 12:05:47 +00:00
274fae1e31 fix: macOS, crash when log is open and you minimize the gui
fixes: #9206
on macOS the minimize creates a race to show and hide the log
2025-11-25 11:54:24 -05:00
7e278b6210 chore: move gui/tls/TlsUtility -> gui/TlsUtility 2025-11-24 11:23:35 +00:00
5736566a79 refactor: TlsUtility a collection of methods in a namespace 2025-11-24 11:23:35 +00:00
bd4db268f1 chore: remove unused TlsCertificate class 2025-11-24 11:23:35 +00:00
c13421c20a refactor: TlsUtility::generateCertificate() handle all the steps internally and make method static 2025-11-24 11:23:35 +00:00
0d5d66b880 chore: remove unused Settings::tlsLocalDb we no longer use the local fingerprint file 2025-11-24 11:23:35 +00:00
ad01e296dc chore: remove unused TlsCertificate::generateFingerprint 2025-11-24 11:23:35 +00:00
4698326717 refactor: MainWindow keep a local copy of the fingerprint
This also makes it so MainWindow does not use the local_fingerprint file
2025-11-24 11:23:35 +00:00
2087097415 refactor: new static TlsUtility::certFingerprint to generate fingerprint on the fly 2025-11-24 11:23:35 +00:00
94eaa79768 chore: rename MainWindow::regenerateLocalFingerprints -> MainWindow::generateCertificate 2025-11-24 11:23:35 +00:00
6f10cd269e refactor: move TlsCertificate::getCertKeyLength -> static TlsUtility::getCertKeyLength 2025-11-24 11:23:35 +00:00
c4a2dfd300 chore: remove unused TlsUtility::persistCertificate 2025-11-24 11:23:35 +00:00
393c2fa9bc refactor: remove unused TlsCertificate::isCertificateValid 2025-11-24 11:23:35 +00:00
91b9680643 refactor: new static TlsUtiliy::isCertValid 2025-11-24 11:23:35 +00:00
4216acdb3a refactor: TlsUtility::isEnabled is now a static member 2025-11-24 11:23:35 +00:00
bc857a7cb4 ci: use debian stable-slim tag for debian builds 2025-11-22 21:43:06 +00:00
2039106be2 ci: reorder fedora so 42 is in the list before fedora 43 2025-11-22 21:43:06 +00:00
18ed5faf99 build: update flatpak recipe to use kde 6.10 platform 2025-11-22 21:43:06 +00:00
cdf9a5606d ci: add debian testing-slim tags 2025-11-22 21:43:06 +00:00
2166de2114 ci: Remove tomlplusplus and cli11 from freebsd build 2025-11-22 21:43:06 +00:00
15b6da097c i18n(ru): remove mistake and remade sentence for more logic meaning 2025-11-21 15:34:20 -05:00
3b2d687bfd ci: add ubuntu 26.04 runners 2025-11-21 15:10:48 -05:00
dc4947af5c ci: remove ubuntu 25.04 runners 2025-11-21 15:10:48 -05:00
1e4d15c4b6 ci: remove fedora 41 runners 2025-11-21 15:10:48 -05:00
322 changed files with 8382 additions and 5758 deletions

7
.github/CODEOWNERS vendored
View File

@ -1,2 +1,9 @@
# Apply to all files
* @nbolton @sithlord48
# Translators
translations/deskflow_es.ts @sithlord48
translations/deskflow_it.ts @sithlord48
translations/deskflow_ja.ts @ykasap
translations/deskflow_ru.ts @levpr1c
translations/deskflow_zh_CN.ts @sailordiary

18
.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@ -0,0 +1,18 @@
# Deskflow Code of Conduct
## Our Pledge
We want the Deskflow community to be one where everyone can work together. We pledge to keep our community focused on the project and the code around the project.
## Community Standards
* Keep interactions respectful and focused on the project
* Contributions are expected to follow the [contribution guide](https://github.com/deskflow/deskflow/wiki/Contributing).
## Enforcement
Enforcement will be done at the descression of the Deskflow Moderators.
1. Warning
2. Temporary ban
3. Permanent banning

View File

@ -25,10 +25,11 @@ TLS encryption is enabled by default. Wayland is supported. Clipboard sharing is
> [!NOTE]
> On Windows, you will need to install the
> [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version).
> Download latest: [`vc_redist.x64.exe`](https://aka.ms/vs/17/release/vc_redist.x64.exe) [`vc_redist.arm64.exe`](https://aka.ms/vs/17/release/vc_redist.arm64.exe)
> Download latest: [`vc_redist.x64.exe`](https://aka.ms/vc14/vc_redist.x64.exe) [`vc_redist.arm64.exe`](https://aka.ms/vc14/vc_redist.arm64.exe)
> [!TIP]
> For macOS users, the easiest way to install and stay up to date is to use [Homebrew](https://brew.sh) with our [homebrew-tap](https://github.com/deskflow/homebrew-tap).
> macOS reports unsigned apps as damaged. This occurs because we do not use an Apple certificate for notarization. Clear the quarantine attribute to run the app: `xattr -c Deskflow.app`
To use Deskflow, download one of our [packages](https://github.com/deskflow/deskflow/releases), install `deskflow` (from your package repository), or [build it](https://github.com/deskflow/deskflow/wiki/Building) from source.
@ -50,7 +51,7 @@ To use Deskflow, download one of our [packages](https://github.com/deskflow/desk
## Contribute
[![Good first issues](https://img.shields.io/github/issues/deskflow/deskflow/good%20first%20issue?label=good%20first%20issues&color=%2344cc11)](https://github.com/deskflow/deskflow/labels/good%20first%20issue) [![Open bounty issues](https://img.shields.io/github/issues/deskflow/deskflow/%F0%9F%92%8E%20bounty?label=💎%20open%20bounty%20issues&color=%2344cc11)](https://github.com/deskflow/deskflow/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22%F0%9F%92%8E%20bounty%22) [![Rewarded bounties](https://img.shields.io/github/issues-search/deskflow/deskflow?query=label%3A%22%F0%9F%92%B0%20rewarded%22&label=%F0%9F%92%B0%20rewarded%20bounties&color=yellow)](https://github.com/deskflow/deskflow/issues?q=label%3A%22%F0%9F%92%B0%20rewarded%22%20sort%3Aupdated-desc)
[![Good first issues](https://img.shields.io/github/issues/deskflow/deskflow/good%20first%20issue?label=good%20first%20issues&color=%2344cc11)](https://github.com/deskflow/deskflow/labels/good%20first%20issue)
There are many ways to contribute to the Deskflow project.
@ -64,9 +65,9 @@ For instructions on building Deskflow, use the wiki page: [Building](https://git
We support all major operating systems, including Windows, macOS, Linux, and Unix-like BSD-derived.
Windows 10 or higher is required.
Windows 10 v1809 or higher is required.
macOS 12 or higher is required.
macOS 13 or higher is required to use our CI builds for Apple Silicon machines. macOS 12 or higher is required for Intel macs or local builds.
Linux requires libei 1.3+ and libportal 0.8+ for the server/client. Additionally, Qt 6.7+ is required for the GUI.
Linux users with systems not meeting these requirements should use flatpak in place of a native package.
@ -80,8 +81,6 @@ versions across them and gathering other information.
[![Repology](https://repology.org/badge/vertical-allrepos/deskflow.svg?exclude_unsupported=1)](https://repology.org/project/deskflow/versions)
**Note:** We are working with package maintainers to have our new package name adopted.
## Installing on macOS
When you install Deskflow on macOS, you need to allow accessibility access (Privacy & Security) to both the `Deskflow` app and the `deskflow` process.
@ -94,12 +93,12 @@ on the allowed list you will need to manually remove them before accessibility a
macOS users who download directly from releases may need to run `xattr -c /Applications/Deskflow.app` after copying the app to the `Applications` dir.
It is recommend to install Deskflow using [Homebrew](https://brew.sh) from our [homebrew-tap](https://github.com/deskflow/homebrew-tap)
It is recommended to install Deskflow using [Homebrew](https://brew.sh) from our [homebrew-tap](https://github.com/deskflow/homebrew-tap)
To add our tap, run:
```
brew tap deskflow/homebrew-tap
brew tap deskflow/tap
```
Then install either:
@ -185,4 +184,4 @@ Deskflow is made by possible by these contributors.
## License
This project is licensed under [GPL-2.0](LICENSE) with an [OpenSSL exception](LICENSES/LicenseRef-OpenSSL-Exception.txt).
This project is licensed under [GPL-2.0](LICENSE) with an [OpenSSL exception](../LICENSES/LicenseRef-OpenSSL-Exception.txt).

View File

@ -1,34 +0,0 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
name: "Add Kitware repo"
description: "Add Kitware repo for Debian-like distros"
inputs:
distro:
description: "Ubuntu codename, Kitware uses: noble, jammy, focal"
required: true
runs:
using: "composite"
steps:
# This mirrors instructions at https://apt.kitware.com
- name: Add repo
run: |
apt update -y -qqq
apt install ca-certificates gpg wget -y -qqq
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \
| gpg --dearmor - \
> /usr/share/keyrings/kitware-archive-keyring.gpg
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${{ inputs.distro }} main' \
> /etc/apt/sources.list.d/kitware.list
apt update -y -qqq
env:
# Prevent apt prompting for input.
DEBIAN_FRONTEND: noninteractive
shell: bash

View File

@ -30,7 +30,7 @@ runs:
if: ${{ runner.os != 'Windows' }}
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
brew install googletest openssl --quiet
brew install googletest openssl doxygen --quiet
elif [ "$RUNNER_OS" == "Linux" ]; then
if [ ${{inputs.like}} == "debian" ]; then
apt update -qqq > /dev/null
@ -38,17 +38,17 @@ runs:
xorg-dev libx11-dev libxtst-dev libssl-dev \
libglib2.0-dev libxkbfile-dev qt6-base-dev qt6-tools-dev \
libgtk-3-dev libgtest-dev libgmock-dev \
libei-dev libportal-dev help2man -y >/dev/null
libei-dev libportal-dev help2man doxygen -y >/dev/null
elif [ ${{inputs.like}} == "fedora" ]; then
dnf install -y cmake make ninja-build gcc-c++ rpm-build openssl-devel \
glib2-devel libXtst-devel libxkbfile-devel qt6-qtbase-devel qt6-qttools-devel \
gtk3-devel gtest-devel gmock-devel libei-devel libportal-devel help2man
gtk3-devel gtest-devel gmock-devel libei-devel libportal-devel help2man doxygen
elif [ ${{inputs.like}} == "suse" ]; then
zypper refresh
zypper install -y --force-resolution \
cmake make ninja gcc-c++ rpm-build libopenssl-devel \
glib2-devel libXtst-devel libxkbfile-devel qt6-base-devel qt6-tools-devel \
qt6-linguist-devel gtk3-devel \
qt6-linguist-devel gtk3-devel doxygen \
googletest-devel googlemock-devel libei-devel libportal-devel help2man
elif [ ${{ inputs.like }} == "arch" ]; then
pacman -Syu --noconfirm base-devel cmake ninja \
@ -83,6 +83,22 @@ runs:
token: ${{ github.token }}
revision: master
- name: Cache Chocolatey
id: cache-choco
if: (runner.os == 'Windows')
uses: actions/cache@v4
with:
path: |
C:/ProgramData/chocolatey/bin/
C:/ProgramData/chocolatey/lib/doxygen.install
C:/Program*/doxygen/
key: cache-chocolatey${{ matrix.config.arch }}-doxygen
- name: Install doxygen (windows)
if: ((runner.os == 'Windows') && (steps.cache-choco.outputs.cache-hit != 'true'))
shell: bash
run: choco install doxygen.install
- name: Install Wix
if: ${{ runner.os == 'Windows' }}
run: |
@ -91,3 +107,4 @@ runs:
wix extension add --global WixToolset.Util.wixext/5.0.2
wix extension add --global WixToolset.Firewall.wixext/5.0.2
shell: pwsh

49
.github/actions/test-package/action.yml vendored Normal file
View File

@ -0,0 +1,49 @@
name: "Test Package"
description: "Installs the built package and verifies the installed binaries can run"
inputs:
like:
description: "Used only on linux distro type: debian, fedora, suse, arch"
required: false
default: ""
runs:
using: "composite"
steps:
- name: Test package
shell: bash
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
dmg=$(ls build/deskflow-*.dmg | head -1)
echo "Y" | hdiutil attach "$dmg" -nobrowse -mountpoint /tmp/deskflow-dmg
/tmp/deskflow-dmg/Deskflow.app/Contents/MacOS/deskflow-core --version
hdiutil detach /tmp/deskflow-dmg
elif [ "$RUNNER_OS" == "Windows" ]; then
7z x build/deskflow-*-portable.7z -otmp/deskflow-pkg
exe=$(find tmp/deskflow-pkg -name "deskflow-core.exe" -type f | head -1)
exe_dir=$(dirname "$exe")
pkg_root=$(dirname "$exe_dir")
export PATH="$exe_dir:$pkg_root:$pkg_root/lib:$PATH"
"$exe" --version
elif [ "$RUNNER_OS" == "Linux" ]; then
if [ "${{inputs.like}}" == "debian" ]; then
apt-get install -y ./build/deskflow-*.deb
elif [ "${{inputs.like}}" == "fedora" ]; then
dnf install -y build/deskflow-*.rpm
elif [ "${{inputs.like}}" == "suse" ]; then
zypper install -y --allow-unsigned-rpm build/deskflow-*.rpm
elif [ "${{inputs.like}}" == "arch" ]; then
pacman -U --noconfirm build/deskflow-*.pkg.tar.zst
else
echo "Unknown like: ${{inputs.like}}"
exit 1
fi
deskflow-core --version
else
echo "Unknown OS: $RUNNER_OS"
exit 1
fi

View File

@ -60,7 +60,7 @@ runs:
echo "$table" > $GITHUB_STEP_SUMMARY
count=$(echo "$table" | awk -v RS='' '{gsub(/[^❌]/, ""); print length}')
count=$(echo "$table" | { grep -o '❌' || true; } | wc -l)
# Keep at this indentation level for heredoc.
fail_summary=$(cat <<EOF

View File

@ -1,33 +0,0 @@
name: Winget Publish
description: A composite action to publish packages to the Windows Package Manager (Winget) repository
inputs:
release-version:
description: "Version to publish to Winget package manager (without 'v' prefix)"
required: true
token:
description: "GitHub token with public read permissions on the source repo"
required: true
runs:
using: "composite"
steps:
- name: Submit package to Windows Package Manager Community Repository
if: ${{ runner.os == 'Windows' }}
env:
GITHUB_TOKEN: ${{ inputs.token }}
run: |
# Download latest wingetcreate
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
$packageId = "Deskflow.Deskflow"
$x64Url = "https://github.com/deskflow/deskflow/releases/download/v${{ inputs.release-version }}/deskflow-${{ inputs.release-version }}-win-x64.msi"
$arm64Url = "https://github.com/deskflow/deskflow/releases/download/v${{ inputs.release-version }}/deskflow-${{ inputs.release-version }}-win-arm64.msi"
# Submit package update
.\wingetcreate.exe update "$packageId" `
--version "${{ inputs.release-version }}" `
--urls "$x64Url|x64" "$arm64Url|arm64"`
--submit `
--token "${{ inputs.token }}"
shell: pwsh

15
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,15 @@
## Description
<!--- Describe your what your changes do -->
## Disclosure of AI use
<!--- Disclouse your use of AI Tools used to make this pr -->
<!--- If any AI tools were used to crate the code let us know -->
## Related Issue
<!--- If fixing an issue you must add a `fixes` line for each issues fixed-->
<!--- Example, if fixing Issues #1234 you would add -->
<!--- fixes: #1234 -->
## How Has This Been Tested?
<!--- Please describe how you tested your changes -->
<!--- Include details of your testing environment -->

View File

@ -18,12 +18,15 @@ on:
jobs:
summary:
if: github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
runs-on: ubuntu-slim
steps:
# If the workflow fails before uploading summaries, no artifacts exist and this step fails.
# Allow failure so the "Delete PR comment" step still runs to clean up stale comments.
- name: Download summaries
id: download
uses: actions/download-artifact@v4
continue-on-error: true
with:
run-id: ${{ github.event.workflow_run.id }}
pattern: summary-*
@ -54,15 +57,16 @@ jobs:
console.log("Found PR:", pr.number);
return pr.number;
} else {
core.setFailed("PR not found");
core.warning("PR not found for SHA (maybe removed by force push)");
}
- name: Merge summaries
if: steps.get-pr-number.outputs.result
id: summary
run: |
ls -R
files=$(find $dir -type f)
files=$(find summaries -type f 2>/dev/null || true)
if [ -z "$files" ]; then
echo "No files found in dir: $dir"
exit 0
@ -85,7 +89,7 @@ jobs:
} >> $GITHUB_OUTPUT
- name: Set PR comment
if: steps.summary.outputs.message
if: steps.get-pr-number.outputs.result && steps.summary.outputs.message
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.get-pr-number.outputs.result }}
@ -93,7 +97,7 @@ jobs:
message: ${{ steps.summary.outputs.message }}
- name: Delete PR comment
if: ${{ !steps.summary.outputs.message }}
if: ${{ steps.get-pr-number.outputs.result && !steps.summary.outputs.message }}
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.get-pr-number.outputs.result }}

View File

@ -22,6 +22,10 @@ on:
- '!src/res/**'
- '!src/unittests/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
codeql:
runs-on: ubuntu-latest
@ -35,7 +39,7 @@ jobs:
apt install -qqq git > /dev/null
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- name: Install dependencies
uses: ./.github/actions/install-dependencies
@ -43,12 +47,12 @@ jobs:
like: "debian"
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: cpp
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4

View File

@ -11,6 +11,10 @@ on:
- "v*"
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
GIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
PACKAGE_PREFIX: "deskflow"
@ -21,10 +25,17 @@ jobs:
# Quality gate to allow PR merge, used in the branch protection rules.
ci-passed:
runs-on: ubuntu-latest
needs: [test-results, unix, flatpak]
needs: [main-build, test-results, unix, flatpak]
if: always()
steps:
- run: echo "✅ CI passed" > $GITHUB_STEP_SUMMARY
- name: Check all steps passed
run: |
if [[ ${{needs.main-build.result}} == 'success' && ${{needs.test-results.result}} == 'success' && ${{needs.unix.result}} == 'success' && ${{needs.flatpak.result}} == 'success' ]]; then
echo "✅ CI passed" > $GITHUB_STEP_SUMMARY
else
exit 1
fi
# Summary of test results, combined from test result artifacts.
# Runs even if the tests fail to provide a summary of the failures.
@ -32,7 +43,7 @@ jobs:
needs: main-build
if: always() && needs.main-build.result != 'skipped'
runs-on: ubuntu-latest
runs-on: ubuntu-slim
timeout-minutes: 5
steps:
@ -54,7 +65,7 @@ jobs:
lint-clang:
needs: [lint-reuse]
runs-on: ubuntu-latest
runs-on: ubuntu-slim
timeout-minutes: 5
steps:
@ -88,6 +99,7 @@ jobs:
config-args: "-G Ninja"
vcpkg-triplet: x64-windows-release
arch: "amd64"
qt-version: 6.10.2
- name: "windows-2022-arm64"
runs-on: "windows-11-arm"
@ -95,42 +107,45 @@ jobs:
config-args: "-G Ninja"
vcpkg-triplet: arm64-windows
arch: "arm64"
qt-version: 6.10.2
- name: "macos-arm64"
runs-on: macos-15
timeout: 10
qt-version: 6.10.2
config-args: '-DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET=14 -DCMAKE_OSX_SYSROOT=/Applications/Xcode_16.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk'
- name: "macos-x64"
runs-on: macos-15-intel
timeout: 20
qt-version: 6.9.3
config-args: '-DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_OSX_DEPLOYMENT_TARGET=12 -DCMAKE_OSX_SYSROOT=/Applications/Xcode_16.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk'
- name: "debian-13-x86_64"
- name: "debian-x86_64"
runs-on: ubuntu-latest
container: debian:trixie-slim
container: debian:stable-slim
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "debian-13-arm64"
- name: "debian-arm64"
runs-on: ubuntu-24.04-arm
container: debian:trixie-slim
container: debian:stable-slim
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "fedora-43-x86_64"
- name: "debian-testing-x86_64"
runs-on: ubuntu-latest
container: fedora:43
like: "fedora"
container: debian:testing-slim
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "fedora-43-arm64"
- name: "debian-testing-arm64"
runs-on: ubuntu-24.04-arm
container: fedora:43
like: "fedora"
container: debian:testing-slim
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
@ -148,16 +163,16 @@ jobs:
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "fedora-41-x86_64"
- name: "fedora-43-x86_64"
runs-on: ubuntu-latest
container: fedora:41
container: fedora:43
like: "fedora"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "fedora-41-arm64"
- name: "fedora-43-arm64"
runs-on: ubuntu-24.04-arm
container: fedora:41
container: fedora:43
like: "fedora"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
@ -183,20 +198,6 @@ jobs:
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_DEV_DOCS=ON"
- name: "ubuntu-25.04-x86_64"
runs-on: ubuntu-latest
container: ubuntu:25.04
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "ubuntu-25.04-arm64"
runs-on: ubuntu-24.04-arm
container: ubuntu:25.04
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "ubuntu-25.10-x86_64"
runs-on: ubuntu-latest
container: ubuntu:25.10
@ -211,6 +212,20 @@ jobs:
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "ubuntu-26.04-x86_64"
runs-on: ubuntu-latest
container: ubuntu:26.04
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
- name: "ubuntu-26.04-arm64"
runs-on: ubuntu-24.04-arm
container: ubuntu:26.04
like: "debian"
timeout: 20
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
steps:
# Make sure the container has git before we do anything else
- name: Install Git on Container
@ -232,7 +247,7 @@ jobs:
# Fancy checkout gets all the tags
# it also makes sure we can use git --describe correctly
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
# This effectively runs `vcvarsall.bat`, etc. It's not actually installing
# VC++ as that's already pre-installed on the Windows runner.
@ -246,13 +261,18 @@ jobs:
id: get-deps
uses: ./.github/actions/install-dependencies
with:
qt-version: 6.10.0
qt-version: ${{matrix.target.qt-version}}
vcpkg-triplet: ${{matrix.target.vcpkg-triplet}}
like: ${{ matrix.target.like }}
- name: Get version
uses: ./.github/actions/get-version
- name: Update Windows Paths
if: (runner.os == 'Windows')
shell: pwsh
run: echo "C:\Program Files\doxygen\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Configure
run: ${{env.CMAKE_CONFIGURE}} ${{ matrix.target.config-args }} ${{ steps.get-deps.outputs.vcpkg-cmake-config }} -DPACKAGE_VERSION_LABEL="${{env.DESKFLOW_PACKAGE_VERSION}}"
@ -260,7 +280,21 @@ jobs:
shell: bash
run: |
if [[ "${{matrix.target.like}}" != "arch" ]]; then
if [ "$RUNNER_OS" != "macOS" ]; then
cmake --build build --config Release -j8 --target package
else
cmake --build build --config Release -j8
for i in $(seq 1 5); do
cmake --build build --config Release -j8 --target package 2>&1
if [ $? -eq 0 ]; then
echo "Package successful"
break
else
echo "Package attempt $i failed"
sleep 1
fi
done
fi
else
cmake --build build --config Release -j8
useradd -m build
@ -273,18 +307,31 @@ jobs:
cd ..
fi
- name: Check for unexpected repo changes
shell: bash
run: |
if [[ `git status --porcelain` ]]; then
echo "Unexpected changes to the repo, Often caused by forgetting to commit the updated translation files"
exit 1
fi
- name: Tests
uses: ./.github/actions/run-tests
timeout-minutes: 2
with:
job: ${{ matrix.target.name }}
- name: Test package
uses: ./.github/actions/test-package
with:
like: ${{ matrix.target.like }}
- name: Update Development Documentation
if: matrix.target.like == 'arch' && github.ref == 'refs/heads/master'
uses: JamesIves/github-pages-deploy-action@v4.7.3
with:
branch: gh-pages
folder: build/doc/dev/html
folder: build/docs/dev/html
- name: Upload
uses: actions/upload-artifact@v4
@ -310,7 +357,7 @@ jobs:
# Fancy checkout gets all the tags
# it also makes sure we can use git --describe correctly
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- name: Build on FreeBSD
if: ${{ matrix.distro.name == 'freebsd' }}
uses: vmactions/freebsd-vm@v1
@ -318,8 +365,8 @@ jobs:
usesh: true
run: |
pkg install -y cmake ninja gmake gcc12 openssl glib \
libX11 libXtst libxkbfile qt6-base qt6-tools gtk3 googletest \
tomlplusplus cli11 pkgconf libei libportal
libX11 libXtst libxkbfile qt6-base qt6-tools gtk3 \
googletest pkgconf libei libportal doxygen
${{env.CMAKE_CONFIGURE}} -G Ninja
cmake --build build -j16
# Integration tests are flakey by nature, make them optional.
@ -331,7 +378,7 @@ jobs:
runs-on: ${{matrix.flatpak.runs-on}}
timeout-minutes: 60
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.8
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.10
options: --privileged
strategy:
fail-fast: false
@ -343,7 +390,7 @@ jobs:
arch: aarch64
steps:
- name: Check out repository
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- run: git config --global protocol.file.allow always
@ -381,7 +428,7 @@ jobs:
steps:
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- name: Get version
uses: ./.github/actions/get-version
@ -420,19 +467,12 @@ jobs:
deskflow-*
sums.txt
winget-publish:
needs: release
if: contains(github.ref, 'tags/v')
runs-on: windows-latest
steps:
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
- name: Get version
uses: ./.github/actions/get-version
- name: Submit
uses: ./.github/actions/winget-publish
with:
release-version: ${{env.DESKFLOW_PACKAGE_VERSION}}
token: ${{ secrets.WINGET_DEPLOY_TOKEN }}
- name: Update Homebrewtap
shell: bash
run: |
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.DF_TAP_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/deskflow/homebrew-tap/dispatches \
-d '{"event_type":"update_tap"}'

View File

@ -5,7 +5,7 @@ on:
jobs:
stale-issues:
runs-on: ubuntu-latest
runs-on: ubuntu-slim
timeout-minutes: 10
steps:

View File

@ -23,6 +23,10 @@ on:
- '!src/res/**'
- '!src/unittests/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
sonar:
# This job would fail for contributors who open PRs as the workflow runs outside of our repo
@ -43,7 +47,7 @@ jobs:
apt install -qqq git curl unzip gcovr > /dev/null
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- name: Install project dependencies
uses: ./.github/actions/install-dependencies

View File

@ -17,7 +17,7 @@ jobs:
apt install -qqq git valgrind > /dev/null
- name: Fancy Checkout
uses: sithlord48/fancy-checkout@v1
uses: sithlord48/fancy-checkout@v2
- name: Install dependencies
uses: ./.github/actions/install-dependencies

4
.gitignore vendored
View File

@ -45,3 +45,7 @@ CMakeFiles/*
# scripts folder
/scripts
# Ai helperfilers
**/[cC]laude.[mM][dD]
**/CLAUDE.[mM][dD]

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 - 2025 Deskflow Developers
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 - 2026 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.24)
@ -11,6 +11,11 @@ cmake_policy(SET CMP0003 NEW)
# Fix define escaping
cmake_policy(SET CMP0005 NEW)
# De-duplicate libraries on linker calls
if(POLICY CMP0156)
cmake_policy(SET CMP0156 NEW)
endif()
# Set CXX Requirements
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
@ -18,7 +23,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Fallback for when git can not be found
set(DESKFLOW_VERSION_MAJOR 1)
set(DESKFLOW_VERSION_MINOR 25)
set(DESKFLOW_VERSION_MINOR 26)
set(DESKFLOW_VERSION_PATCH 0)
set(DESKFLOW_VERSION_TWEAK 0)
@ -32,16 +37,6 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
OUTPUT_VARIABLE GIT_SHA_SHORT
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-list --tags --count
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_TAG_COUNT
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(${GIT_TAG_COUNT} EQUAL 0)
set(DESKFLOW_VERSION_TWEAK "9999")
else()
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --long --match v* --always
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
@ -61,10 +56,10 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
set(DESKFLOW_VERSION_MINOR ${MINOR})
set(DESKFLOW_VERSION_PATCH ${PATCH})
set(DESKFLOW_VERSION_TWEAK ${TWEAK})
elseif(NOT ${GITREV} STREQUAL "")
set(DESKFLOW_VERSION_TWEAK ${GITREV})
endif()
else()
set(DESKFLOW_VERSION_TWEAK "9999")
endif()
unset(GITREV)
endif()
endif()
@ -89,7 +84,7 @@ project(
# Define Additional "PROJECT" vars for packaging and metadata
set(CMAKE_PROJECT_PROPER_NAME "Deskflow")
set(CMAKE_PROJECT_VENDOR "${CMAKE_PROJECT_PROPER_NAME} Devs")
set(CMAKE_PROJECT_COPYRIGHT "(C) 2024-2025 ${CMAKE_PROJECT_VENDOR}")
set(CMAKE_PROJECT_COPYRIGHT "(C) 2024-2026 ${CMAKE_PROJECT_VENDOR}")
set(CMAKE_PROJECT_CONTACT "${CMAKE_PROJECT_PROPER_NAME} <maintainers@deskflow.org>")
set(CMAKE_PROJECT_REV_FQDN "org.deskflow.deskflow")
@ -104,11 +99,10 @@ message(STATUS "Building ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
# Set lib versions
set(REQUIRED_OPENSSL_VERSION 3.0)
set(REQUIRED_LIBEI_VERSION 1.3)
set(REQUIRED_LIBPORTAL_VERSION 0.8)
set(REQUIRED_LIBPORTAL_VERSION 0.9.1)
set(REQUIRED_QT_VERSION 6.7.0)
if (WIN32)
add_definitions(-DSYSAPI_WIN32 -DWINAPI_MSWINDOWS)
# VSCMD_ARG_TGT_ARCH is set on CI
if ("$ENV{VSCMD_ARG_TGT_ARCH}" STREQUAL "")
# NOT on CI
@ -167,11 +161,16 @@ endif()
include(cmake/Libraries.cmake)
configure_libs()
if(BUILD_OSX_BUNDLE AND APPLE_CODESIGN_DEV)
include(cmake/MacCodesign.cmake)
endif()
# setup install paths
include(GNUInstallDirs)
if (WIN32)
set(CMAKE_INSTALL_BINDIR .)
set(CMAKE_INSTALL_LIBDIR .)
set(CMAKE_INSTALL_DOCDIR docs)
set(CMAKE_INSTALL_LICENSE_DIR .)
set(CMAKE_INSTALL_I18N_DIR translations)
elseif(BUILD_OSX_BUNDLE)
@ -182,10 +181,13 @@ else()
set(CMAKE_INSTALL_I18N_DIR ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/translations)
endif()
add_subdirectory(doc)
add_subdirectory(src)
add_subdirectory(docs)
# build translations before source, I18N unit tests fail if they are missing
add_subdirectory(translations)
add_subdirectory(src)
option(BUILD_INSTALLER "Build installer" ON)
if(BUILD_INSTALLER)
add_subdirectory(deploy)

View File

@ -17,7 +17,7 @@ path = [
, "sonar-project.properties"
, "cmake/vcpkg.json.in"
, "**/*.md"
, "doc/**"
, "docs/**"
, "deploy/linux/flatpak/**"
, "deploy/linux/org.deskflow.deskflow.metainfo.xml"
, "deploy/windows/wix-patch.xml.in"

View File

@ -1,9 +1,9 @@
# SOURCE https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake
# SPDX-FileCopyrightText: 2020 Bob Apthrope
# SPDX-FileCopyrightText: 2019 Anatolii Kurotych
# SPDX-FileCopyrightText: 2019 - 2020 Frank Dana
# SPDX-FileCopyrightText: 2013 Joakim Söderberg
# SPDX-FileCopyrightText: 2012 - 2017 Lars Bilke
# SPDX-FileCopyrightText: (C) 2020 Bob Apthrope
# SPDX-FileCopyrightText: (C) 2019 Anatolii Kurotych
# SPDX-FileCopyrightText: (C) 2019 - 2020 Frank Dana
# SPDX-FileCopyrightText: (C) 2013 Joakim Söderberg
# SPDX-FileCopyrightText: (C) 2012 - 2017 Lars Bilke
# SPDX-License-Identifier: MIT
# USAGE:

View File

@ -1,5 +1,5 @@
# SPDX-FileCopyrightText: 2024 - 2025 Deskflow Developers
# SPDX-FileCopyrightText: 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2024 - 2025 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2024 Symless Ltd
# SPDX-License-Identifier: MIT
macro(configure_libs)
@ -141,8 +141,6 @@ macro(configure_unix_libs)
${lib_ScreenSaver} ${lib_IOKit} ${lib_ApplicationServices}
${lib_Foundation} ${lib_Carbon} ${lib_UserNotifications}
)
add_definitions(-DWINAPI_CARBON=1)
else()
if (BUILD_X11_SUPPORT)
@ -163,15 +161,6 @@ macro(configure_unix_libs)
message(WARNING "pkg-config not found, skipping wayland libraries")
endif()
endif()
# Unix only: For config.h, save the results based on a template (config.h.in).
# Note that this won't work on Windows because filenames are not case sensitive,
# and we have header files named "Config.h" (upper case 'C').
configure_file(${CMAKE_SOURCE_DIR}/src/lib/Config.h.in
${CMAKE_BINARY_DIR}/src/lib/Config.h @ONLY)
add_definitions(-DSYSAPI_UNIX=1 -DHAVE_CONFIG_H)
endmacro()
#

51
cmake/MacCodesign.cmake Normal file
View File

@ -0,0 +1,51 @@
# SPDX-FileCopyrightText: (C) 2025-2026 Deskflow Contributors
# SPDX-License-Identifier: MIT
# Warning: Do not use for CI/production, as the `entitlements-dev.plist` file adds special
# entitlements that are only appropriate for local development.
#
# macOS made TCC stricter so that if you don't sign your local dev builds properly, macOS will
# nag you to remove and re-approve the app every time you make a change to the binary which is
# extremely annoying during development.
#
# If you were to use ad-hoc signing (i.e. not specify a certificate), TCC would still nag you
# because the binary identity is anchored not on the app ID, but on the CD hash (which changes
# based on the binary contents).
#
# To use, simply generate a personal certificate for free with Xcode and pass the ID to CMake.
# Full instructions are in the docs.
function(configure_mac_codesign target)
set_property(GLOBAL APPEND PROPERTY _MAC_CODESIGN_DEPENDS $<TARGET_FILE:${target}>)
get_property(deferred GLOBAL PROPERTY _MAC_CODESIGN_DEFERRED)
if(NOT deferred)
set_property(GLOBAL PROPERTY _MAC_CODESIGN_DEFERRED TRUE)
message(STATUS "Apple codesign ID for development only: ${APPLE_CODESIGN_DEV}")
cmake_language(DEFER DIRECTORY ${CMAKE_SOURCE_DIR} CALL _finalize_mac_codesign)
endif()
endfunction()
function(_finalize_mac_codesign)
get_property(depends GLOBAL PROPERTY _MAC_CODESIGN_DEPENDS)
set(stamp_file "${CMAKE_BINARY_DIR}/CMakeFiles/codesign-dev.stamp")
# Use a stamp file because codesign modifies the binaries it signs.
add_custom_command(
OUTPUT ${stamp_file}
COMMAND /usr/bin/codesign
--force
--options runtime
--entitlements "${CMAKE_SOURCE_DIR}/src/apps/res/entitlements-dev.plist"
--sign "${APPLE_CODESIGN_DEV}"
"$<TARGET_BUNDLE_DIR:${CMAKE_PROJECT_PROPER_NAME}>"
COMMAND ${CMAKE_COMMAND} -E touch ${stamp_file}
DEPENDS ${depends}
COMMENT "Codesigning ${CMAKE_PROJECT_PROPER_NAME}"
VERBATIM
)
add_custom_target(codesign-dev ALL DEPENDS ${stamp_file})
endfunction()

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
# Copy License with txt ext for picky package creation tools
@ -8,7 +8,6 @@ file(COPY_FILE
ONLY_IF_DIFFERENT
)
# Generic Package Items
set(CPACK_STRIP_FILES TRUE)
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2024 Deskflow Developers
# SPDX-License-Identifier: MIT
# Maintainer: Deskflow Developers

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
# HACK This is set when the files is included so its the real path
@ -35,6 +35,7 @@ configure_file(
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "qt6-svg-plugins")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_PACKAGE_GROUP "Applications/System")

View File

@ -1,6 +1,6 @@
app-id: org.deskflow.deskflow
runtime: org.kde.Platform
runtime-version: "6.9"
runtime-version: "6.10"
sdk: org.kde.Sdk
command: deskflow
finish-args:
@ -29,8 +29,12 @@ modules:
--prefix=${FLATPAK_DEST} --no-build-isolation Jinja2
sources:
- type: file
url: https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl
sha256: 7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa
url: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl
sha256: 85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
x-checker-data:
type: pypi
name: Jinja2
packagetype: bdist_wheel
- type: file
url: https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz
sha256: d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b
@ -45,8 +49,11 @@ modules:
sources:
- type: git
url: https://gitlab.freedesktop.org/libinput/libei
tag: 1.4.1
commit: 9e0413cbc7d3ae6656266890425f152589ddf74d
tag: 1.5.0
commit: 19b64535408aa47abbc8151bc2c925afd6583851
x-checker-data:
type: git
tag-pattern: ^([\\d.]+)$
- name: libportal
buildsystem: meson
config-opts:
@ -67,8 +74,11 @@ modules:
sources:
- type: git
url: https://github.com/google/googletest.git
tag: v1.15.2
commit: b514bdc898e2951020cbdca1304b75f5950d1f59
tag: v1.17.0
commit: 52eb8108c5bdec04579160ae17225d66034bd723
x-checker-data:
type: git
tag-pattern: ^([\\d.]+)$
cleanup:
- '*'
- name: deskflow

View File

@ -17,3 +17,6 @@ Keywords[zh_CN]=键盘;鼠标;网络;共享;
Name[ru]=Deskflow
Comment[ru]=Приложения чтобы использовать одну мышку и клавиатуру с разными устройствами
Keywords[ru]=Передача;Трансляция;barrier;input-leap;
Name[ko]=Deskflow
Comment[ko]=마우스 및 키보드 공유 유틸리티
Keywords[ko]=키보드;마우스;공유;네트워크;

View File

@ -9,6 +9,7 @@
</developer>
<summary>Software Keyboard and mouse sharing</summary>
<summary xml:lang="zh_CN">用软件共享键鼠</summary>
<summary xml:lang="ko">키보드 및 마우스 공유 소프트웨어</summary>
<description>
<p>
Use the keyboard, mouse, or trackpad of one computer to control nearby computers, and work seamlessly between them.
@ -16,6 +17,9 @@
<p xml:lang="zh_CN">
使用一台计算机的键盘、鼠标或触控板来控制附近的其它计算机,并在它们之间无缝工作。
</p>
<p xml:lang="ko">
한 대의 컴퓨터에 연결된 키보드, 마우스 또는 트랙패드로 주변의 다른 컴퓨터를 제어하고, 컴퓨터 사이를 끊김 없이 오가며 작업할 수 있습니다.
</p>
</description>
<launchable type="desktop-id">org.deskflow.deskflow.desktop</launchable>
<url type="homepage">https://deskflow.org</url>
@ -57,8 +61,10 @@
<keywords>
<keyword>Input</keyword>
<keyword xml:lang="zh_CN">输入</keyword>
<keyword xml:lang="ko">입력</keyword>
<keyword>Sharing</keyword>
<keyword xml:lang="zh_CN">共享</keyword>
<keyword xml:lang="ko">공유</keyword>
<keyword translate="no">KVM</keyword>
<keyword translate="no">Synergy</keyword>
</keywords>
@ -68,6 +74,45 @@
</branding>
<content_rating type="oars-1.0" />
<releases>
<release version="1.26.0" date="2026-02-16" urgency="high">
<description>
<p>This stable release fixes known issues and adds a few new features, For the full changelog, see the release page.</p>
<ul>
<li>New: Korean(ko) translation</li>
<li>New: Option to start in the "locked to computer" state</li>
<li>New: Option to show the version in the windows title</li>
<li>New: Clients can now use a list hostnames or ips for the server address</li>
<li>New: Client options are in a new client configuration dialog</li>
<li>New: Provide a more accurate suggested IP, Update as network info changes if needed.</li>
<li>New: Add a simple search to the log</li>
<li>New: Lookup host name with IP4 or IP6</li>
<li>New: Replace broken scroll speed with a scroll scaling options</li>
<li>Fix: Horizontal scrolling is working again on all platforms</li>
<li>Fix: Key repeat events are now sent as repeat not press and release</li>
<li>Fix: Deskflow-core correctly blocks new instances when run without the `--new-instance` option</li>
<li>Fix: Server Mode, Only use the external config path if the option is enabled</li>
<li>Fix: Allow comma and semicolon to be used in the hotkey configuration</li>
<li>Fix: Gui can crash when clearing settings in debug mode</li>
<li>Fix: Mouse Back and Forward buttons are now working (again) on all platforms</li>
<li>Fix: macOS, crash when the log is opened and the gui minimized</li>
<li>Fix: macOS, restore Preferences menu entry when the application is using non english language</li>
<li>Fix: macOS, try icon was not showing when in `Colorful` mode</li>
<li>Fix: macOS, do not allow the os to kill deskflow for memory reasons</li>
<li>Fix: macOS, possible server crash when a client disconnects abruptly</li>
<li>Fix: macOS, possible crash on screen wake / screen saver activation</li>
<li>Fix: macOS, Wrong keys send when using "RIME" input method</li>
<li>Fix: Windows, possible crash when the daemon is started for the first time</li>
<li>Use `Computer` in place of `Screen` to indicate we work with Computers display layout and not individual screens attached</li>
<li>Clean and update the settings when starting up.</li>
<li>Do not show client connection error messages dialogs if the gui is hidden</li>
<li>Use Qt 6.9.3 for Intel Mac builds.</li>
<li>Windows: Use ICU dlls from the host system</li>
<li>Code continues to be cleaned of unused methods and updated to modern C++</li>
<li>Consolidate Debug levels to remove DEBUG3-5 levels</li>
</ul>
</description>
<url>https://github.com/deskflow/deskflow/releases/tag/v1.26.0</url>
</release>
<release version="1.25.0" date="2025-11-21" urgency="high">
<description>
<p>This stable release fixes known issues and adds a few new features. Most notable symbolic icon support, I18N support and experimental support for wl-clipboard to access clipboards on wayland. This release also continues our trend of cleaning up the codebase. For the full changelog, see the release page.</p>

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
# HACK This is set when the files is included so its the real path

View File

@ -1,4 +1,4 @@
#SPDX-FileCopyrightText: 2025 Chris Rizzitello <sithlord48@gmail.com>
#SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
#SPDX-License-Identifier: MIT
if(CPACK_GENERATOR MATCHES 7Z|ZIP)

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
# HACK This is set when the files is included so its the real path

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
if(CPACK_GENERATOR MATCHES 7Z|ZIP)

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2019 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2019 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
find_package(Doxygen QUIET)
@ -24,3 +24,12 @@ if (DOXYGEN_FOUND)
else()
message(STATUS "Doxygen not found, skipping docs build")
endif()
# Show our documents in the IDE
add_custom_target(docs
SOURCES
Readme.md
Security.md
)
install(FILES Security.md Readme.md DESTINATION ${CMAKE_INSTALL_DOCDIR})

18
docs/Readme.md Normal file
View File

@ -0,0 +1,18 @@
# Deskflow
Deskflow is a free and open source keyboard and mouse sharing app. Use the keyboard, mouse, or trackpad of one computer to control nearby computers, and work seamlessly between them.
[Homepage](https://deskflow.org) [Code](https://github.com/deskflow/deskflo)
## Getting help online
- View the [wiki](https://github.com/deskflow/deskflow/wiki) Online resource
### Chat with us
- Main discussion on Matrix: [`#deskflow:matrix.org`](https://matrix.to/#/#deskflow:matrix.org) ([Matrix clients](https://matrix.org/ecosystem/clients/))
- Discussion also happens on IRC: `#deskflow` or `#deskflow-dev` on [Libera Chat](https://libera.chat/)
- Start a [new discussion](https://github.com/deskflow/deskflow/discussions) on our GitHub project.
## Reporting security issues
Check [Security](Security.md) to find out how to report security issues.

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE mainpage.md)

View File

@ -4,7 +4,7 @@ To build Deskflow you will a minimum of:
- [cmake] 3.24+
- [Qt] 6.7.0+
- [openssl] 3.0+
- [libportal] 0.8+ (linux, bsd)
- [libportal] 0.9.1+ (linux, bsd)
- [libei] 1.3+ (linux, bsd)
- [google_test] ^

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-License-Identifier: MIT
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE mainpage.md)
@ -16,5 +16,4 @@ target_sources(user-docs PRIVATE
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html"
DESTINATION ${CMAKE_INSTALL_DOCDIR}
COMPONENT deskflow_user_docs
)

View File

@ -50,30 +50,37 @@ option=value
This section contains options used when in client mode.
It will begin with `[client]`
| Option | Valid Values | Description |
|:----------------------|:------------------:|:-----------|
| binary | Filename | The filename of the binary to call for client mode. This binary exists in the same path as the GUI |
| invertScrollDirection | `true` or `false` | Invert scroll on this client [default: false] |
|:------------------|:------------------:|:-----------|
| languageSync | `true` or `false` | Sync to server language [default: true] |
| remoteHost | `IP` or `hostname` | The remote host last connected to |
| remoteHost | `IP` or `hostname` | The remote host(s) to connect to. Use a comma separated list when you want to try several hosts |
| yScrollScale | Double 0.1 - 10.0 | Vertical mouse scrolling will be scaled by this amount on the client [default: 1.0] |
| xScrollScale | Double 0.1 - 10.0 | Horizontal mouse scrolling will be scaled by this amount on the client [default: 1.0] |
| invertYScroll | `true` or `false` | Invert vertical scroll on this client [default: false] |
| invertXScroll | `true` or `false` | Invert horizontal scroll on this client [default: false] |
| xdpRestoreToken | UUID | Restore token provided by XDG portals |
### Core
This section contains general options it will begin with `[core]`
|Option | Valid Values|Description|
|:--------------|:-----------:|:-----------|
| coreMode | `0` or `1` or `2` | The mode to start in 0: None, 1: Client, 2: Server [default: 0]|
| display | int | The XWindow display to use [default: autodetected] |
| interface | IP Address | Preferred IP to use for network communication. By default the server board casts on any available address |
| lastVersion | M.m.p.t | The version last run used for checking for updates |
| port | port # | Port to use when connecting [default: 24800 |
| preventSleep | `true` or `false` | Prevent sleep when Deskflow is active [default: false] |
| processMode | `1` or `0` | The mode we use to start the process Service or Desktop |
| screenName | string | Name used to identify the screen [default: machine's hostname] |
| startedBefore | `true` or `false `| Have we started client or server before. Used in logic when deciding to show some dialogs.
| updateUrl | URL | The URL to use when checking for a new version number, it should return a version [default: https://api.deskflow.org/version]|
| computerName | string | Name used to identify the computer [default: machine's hostname] |
| useHooks | `true` or `false` | If Windows uses hooks or not [default: true] |
| language | 639 language | The language to display the GUI in [default: en] |
| wlClipboard | `true` or `false` | When true the wl-clipboard backend will be enabled [default: false] |
| enableEnterCommand | `true` or `false` | Should the enter command be triggered when the screen is entered [defaut: false] |
| enterCommand | command | A command to run when the screen is entered. |
| enableExitCommand | `true` or `false` | Should the exit command be triggered when the screen is exited [defaut: false] |
| exitCommand | command | A command to run when the screen is exited. |
### Daemon
@ -91,24 +98,31 @@ This section contains options used by the daemon on windows it will begin with `
This section contains options used by the GUI it will begin with `[gui]`
|Option | Valid Values |Description|
|:------------------|:-----------------:|:-----------|
|:-------------------------------|:-----------------:|:-----------|
| autoHide | `true` or `false` | When true the app will hide itself on start up [default: false] |
| enableUpdateCheck | `true` or `false` | When true check the update URL to see if a new version was released on start up [default: false] |
| closeReminder | `true` or `false` | Used to track if we have shown the reminder that when you close the app it remain running in the background [default: true]|
| closeToTray | `true` or `false` | When `true` the gui will run in the systemTray when its closed [default: true] |
| logExpanded | `true` or `false` | Should the log section of the GUI be opened [default: false] |
| symbolicTrayIcon | `true` or `false` | When true use the monocolor (symbolic) icon false uses a colorful icon for the tray |
| symbolicTrayIcon | `true` or `false` | When true use the monocolor (symbolic) icon false uses a colorful icon for the tray [default: true] |
| windowGeometry | QRect | Geometry of the window used to restore the window geometry after exiting the app |
| showGenericClientFailureDialog | `true` or `false` | When `true` client connection errors will not show popup error messages [default: true] |
| shownFirstConnectedMessage | `true` or `false` | When `true` GUI has shown the user the message for connecting the first time [default: false] |
| shownServerFirstStartMessage | `true` or `false` | When `true` GUI has shown the user the Deskflow server is now running message [default: false] |
| shownVerionInTitle | `true` or `false` | When `true` GUI will include the version in the window title [default: false] |
| startCoreWithGui | `true` or `false` | When true the Core will be started with the GUI. It is set to the Core's state on exit. |
| updateCheckUrl | URL | The URL to use when checking for a new version number, it should return a version [default: https://api.deskflow.org/version]|
### Log
This section contains options used by the application logging it will begin with `[log]`
|Option | Valid Values |Description|
|:------|:-----------------:|:-----------|
|:---------|:-----------------:|:-----------|
| file | Filepath | The file to write the log into |
| level | Valid log level | Log level to use |
| toFile | `true` or `false` | When true the log will be written to the value of the `file` option |
| guiDebug | `true` or `false` | When true the log will show the Gui's internal debug messages |
### Security
@ -127,8 +141,6 @@ This section contains options used when in server mode it will begin with `[serv
|Option | Valid Values |Description|
|:-------------------|:-----------------:|:-----------|
| binary | Filename | The name of the binary to call for client mode. This binary exists in same path as the Deskflow GUI |
| configVisible | `true` or `false` | Used internally to track when the severs has a configuration dialog showing.|
| externalConfig | `true` or `false` | When true use the external config path |
| externalConfigFile | Filepath | Path the server config file if it does not exist the GUI will it generated based on the `internalConfig` section.|
@ -141,6 +153,7 @@ block of a server config file as seen below. This section is used by the GUI to
[internalConfig]
clipboardSharing=true
clipboardSharingSize=@Variant(\0\0\0\x84\0\0\0\0\0\0<\0)
defaultLockToScreenState=false
disableLockToScreen=false
hasHeartbeat=false
hasSwitchDelay=false
@ -290,7 +303,7 @@ The file is parsed top to bottom and names cannot be used before they've been de
### The screens section
''args'' is a list of screen names, one name per line, each followed by a colon. Names are arbitrary strings but they must be unique. The hostname of each computer is recommended. (This is the computer's network name on win32 and the name reported by the program hostname on Unix and OS X. Note that OS X may append .local to the name you gave your computer; e.g. somehost.local.) There must be a screen name for the server and each client. Each screen can specify a number of options. Options have the form name = value and are listed one per line after the screen name.
''args'' is a list of computer names, one name per line, each followed by a colon. Names are arbitrary strings but they must be unique. The hostname of each computer is recommended. (This is the computer's network name on win32 and the name reported by the program hostname on Unix and OS X. Note that OS X may append .local to the name you gave your computer; e.g. somehost.local.) There must be a computer name for the server and each client. Each computer can specify a number of options. Options have the form name = value and are listed one per line after the computer name.
```
section: screens
@ -303,29 +316,29 @@ section: screens
end
```
This declares three screens named ''moe'', ''larry'', and ''curly''. Screen ''larry'' has half-duplex ''Caps Lock'' and ''Num Lock'' keys (see below) and screen ''curly'' converts the ''Meta'' modifier key to the ''Alt'' modifier key.
This declares three computers named ''moe'', ''larry'', and ''curly''. Computer ''larry'' has half-duplex ''Caps Lock'' and ''Num Lock'' keys (see below) and computer ''curly'' converts the ''Meta'' modifier key to the ''Alt'' modifier key.
#### screen options
A screen can have the following options:
A computer can have the following options:
|Option | Valid Values| Description|
|:----------|:-----------:|:-----------|
|halfDuplexCapsLock| `true` or `false` | This computer has a ''Caps Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Caps Lock'' acts strangely on all screens then you may need to set this option to true on the server screen. If it acts strangely on one screen then that screen may need the option set to true.|
|halfDuplexNumLock | `true` or `false` | This computer has a ''Num Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Num Lock'' acts strangely on all screens then you may need to set this option to true on the server screen. If it acts strangely on one screen then that screen may need the option set to true.|
|halfDuplexScrollLock| `true` or `false`| This computer has a ''Scroll Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Scroll Lock'' acts strangely on all screens then you may need to set this option to true on the server screen. If it acts strangely on one screen then that screen may need the option set to true.|
|halfDuplexCapsLock| `true` or `false` | This computer has a ''Caps Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Caps Lock'' acts strangely on all computers then you may need to set this option to true on the server. If it acts strangely on one computer then that computer may need the option set to true.|
|halfDuplexNumLock | `true` or `false` | This computer has a ''Num Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Num Lock'' acts strangely on all computers then you may need to set this option to true on the server. If it acts strangely on one computer then that computer may need the option set to true.|
|halfDuplexScrollLock| `true` or `false`| This computer has a ''Scroll Lock'' key that doesn't report a press and a release event when the user presses it but instead reports a press event when it's turned on and a release event when it's turned off. If ''Scroll Lock'' acts strangely on all computers then you may need to set this option to true on the server. If it acts strangely on one computer then that computer may need the option set to true.|
|xtestIsXineramaUnaware| `true` or `false`| This option works around a bug in the XTest extension when used in combination with Xinerama. It affects X11 clients only. Not all versions of the XTest extension are aware of the Xinerama extension. As a result, they do not move the mouse correctly when using multiple Xinerama screens. This option is currently ''true'' by default. If you know your XTest extension is Xinerama aware then set this option to ''false''.|
|preserveFocus| `true` or `false` | When true don't drop focus when switching screens
|preserveFocus| `true` or `false` | When true don't drop focus when switching computers
|switchCorners| corners |See <a href="#switch-corners">switchCorners</a> below.|
|switchCornerSize | integer | see switchCornerSize below.|
|shift | shift ctrl alt meta super none | Map the server's shift modifer to different key on a client screen|
|ctrl | shift ctrl alt meta super none | Map the server's ctrl modifer to different key on a client screen|
|alt | shift ctrl alt meta super none | Map the server's alt modifer to different key on a client screen|
|meta| shift ctrl alt meta super none | Map the server's meta modifer to different key on a client screen|
|super| shift ctrl alt meta super none | Map the server's super modifer to different key on a client screen|
|shift | shift ctrl alt meta super none | Map the server's shift modifer to different key on a client computer|
|ctrl | shift ctrl alt meta super none | Map the server's ctrl modifer to different key on a client computer|
|alt | shift ctrl alt meta super none | Map the server's alt modifer to different key on a client computer|
|meta| shift ctrl alt meta super none | Map the server's meta modifer to different key on a client computer|
|super| shift ctrl alt meta super none | Map the server's super modifer to different key on a client computer|
### aliases section
''args'' is a list of screen names just like in the ''screens'' section except each screen is followed by a list of aliases, one per line, not followed by a colon. An ''alias'' is a screen name and must be unique. During screen name lookup each alias is equivalent to the screen name it aliases. So a client can connect using its canonical screen name or any of its aliases.
''args'' is a list of computer names just like in the ''screens'' section except each computer is followed by a list of aliases, one per line, not followed by a colon. An ''alias'' is a computer name and must be unique. When searching for computers each alias is equivalent to the computer name it aliases. So a client can connect using its canonical computer name or any of its aliases.
```
section: aliases
@ -336,18 +349,18 @@ section: aliases
end
```
Screen ''larry'' is also known as ''larry.stooges.com'' and can connect as either name. Screen ''curly'' is also known as ''shemp'' (hey, it's just an example).
Computer ''larry'' is also known as ''larry.stooges.com'' and can connect as either name. Computer ''curly'' is also known as ''shemp'' (hey, it's just an example).
### links secion
''args'' is a list of screen names just like in the ''screens'' section except each screen is followed by a list of links, one per line. Each link has the form:
''args'' is a list of computer names just like in the ''screens'' section except each computer is followed by a list of links, one per line. Each link has the form:
```
{left|right|up|down}[<range>] = name[<range>]
```
A link indicates which screen is adjacent in the given direction.
A link indicates which computer is adjacent in the given direction.
Each side of a link can specify a range which defines a portion of an edge. A range on the direction is the portion of edge you can leave from while a range on the screen is the portion of edge you'll enter into. Ranges are optional and default to the entire edge. All ranges on a particular direction of a particular screen must not overlap.
Each side of a link can specify a range which defines a portion of an edge. A range on the direction is the portion of edge you can leave from while a range on the computer is the portion of edge you'll enter into. Ranges are optional and default to the entire edge. All ranges on a particular direction of a particular computer must not overlap.
A ''range'' is written as <code>(start,end)</code>. Both ''start'' and ''end'' are percentages in the range 0 to 100, inclusive. The start must be less than the end. 0 is the left or top of an edge and 100 is the right or bottom.
@ -365,9 +378,9 @@ section: links
end
```
This indicates that screen ''larry'' is to the right of screen ''moe'' (so moving the cursor off the right edge of ''moe'' would make it appear at the left edge of ''larry''), the left half of curly is above the right half of ''moe'', ''moe'' is to the left of ''larry'' (edges are not necessarily symmetric so you have to provide both directions), the right half of curly is above the left half of ''larry'', all of ''moe'' is below the left half of ''curly'', and the left half of ''larry'' is below the right half of ''curly''.
This indicates that computer ''larry'' is to the right of computer ''moe'' (so moving the cursor off the right edge of ''moe'' would make it appear at the left edge of ''larry''), the left half of curly is above the right half of ''moe'', ''moe'' is to the left of ''larry'' (edges are not necessarily symmetric so you have to provide both directions), the right half of curly is above the left half of ''larry'', all of ''moe'' is below the left half of ''curly'', and the left half of ''larry'' is below the right half of ''curly''.
Note that links do not have to be symmetrical; for instance, here the edge between ''moe'' and ''curly'' maps to different ranges depending on if you're going up or down. In fact links don't have to be bidirectional. You can configure the right of ''moe'' to go to ''larry'' without a link from the left of ''larry'' to ''moe''. It's possible to configure a screen with no outgoing links; the cursor will get stuck on that screen unless you have a hot key configured to switch off of that screen.
Note that links do not have to be symmetrical; for instance, here the edge between ''moe'' and ''curly'' maps to different ranges depending on if you're going up or down. In fact links don't have to be bidirectional. You can configure the right of ''moe'' to go to ''larry'' without a link from the left of ''larry'' to ''moe''. It's possible to configure a computer with no outgoing links; the cursor will get stuck on that computer unless you have a hot key configured to switch off of that computer.
### options section
@ -387,17 +400,17 @@ end
|:--------|:-----------:|:-----------|
|protocol | barrier or synergy| The protocol to use when saying hello to clients. Can be set to barrier or synergy. If not set barrier is used as the default |
|heartbeat| integer (N) | The server will expect each client to send a message no less than every `N` milliseconds. If no message arrives from a client within `3N` seconds the server forces that client to disconnect. If deskflow fails to detect clients disconnecting while the server is sleeping or vice versa, try using this option. |
|switchCorners | none top-left top-right bottom-left bottom-right left right top bottom all | Deskflow won't switch screens when the mouse reaches the edge of the screen if it's in a listed corner. The size of all corners is given by the `switchCornerSize` option. The first name in the list is one of the above names and defines the initial set of corners. Subsequent names are prefixed with + or - to add the corner to or remove the corner from the set, respectively. For example: `all -left +top-left` starts will all corners, removes the left corners (top and bottom) then adds the top-left back in, resulting in the top-left, bottom-left and bottom-right corners.|
|switchCorners | none top-left top-right bottom-left bottom-right left right top bottom all | Deskflow won't switch computers when the mouse reaches the edge of the computer if it's in a listed corner. The size of all corners is given by the `switchCornerSize` option. The first name in the list is one of the above names and defines the initial set of corners. Subsequent names are prefixed with + or - to add the corner to or remove the corner from the set, respectively. For example: `all -left +top-left` starts will all corners, removes the left corners (top and bottom) then adds the top-left back in, resulting in the top-left, bottom-left and bottom-right corners.|
|switchCornerSize | integer (N) | Sets the size of all corners in pixels. The cursor must be within `N` pixels of the corner to be considered to be in the corner.|
|switchDelay | integer| Deskflow won't switch screens when the mouse reaches the edge of a screen unless it stays on the edge for `N` milliseconds. This helps prevent unintentional switching when working near the edge of a screen.|
|switchDoubleTap| integer(N) | Deskflow won't switch screens when the mouse reaches the edge of a screen unless it's moved away from the edge and then back to the edge within `N` milliseconds. With the option you have to quickly tap the edge twice to switch. This helps prevent unintentional switching when working near the edge of a screen.|
|screenSaverSync| `true` or `false`| ''Note: Removed in v1.14.1'' If set to ''false'' then Deskflow won't synchronize screen savers. Client screen savers will start according to their individual configurations. The server screen saver won't start if there is input, even if that input is directed toward a client screen.|
|relativeMouseMoves| `true` or `false`| If set to ''true'' then secondary screens move the mouse using relative rather than absolute mouse moves when and only when the cursor is locked to the screen (by ''Scroll Lock'' or a configured hot key). This is intended to make Deskflow work better with certain games. If set to ''false'' or not set then all mouse moves are absolute.|
|switchDelay | integer| Deskflow won't switch computers when the mouse reaches edge of a computer unless it stays on the edge for `N` milliseconds. This helps prevent unintentional switching when working near an edge.|
|switchDoubleTap| integer(N) | Deskflow won't switch computers when the mouse reaches the edge of a computer unless it's moved away from the edge and then back to the edge within `N` milliseconds. With the option you have to quickly tap the edge twice to switch. This helps prevent unintentional switching when working near the edge.|
|screenSaverSync| `true` or `false`| ''Note: Removed in v1.14.1'' If set to ''false'' then Deskflow won't synchronize screen savers. Client screen savers will start according to their individual configurations. The server screen saver won't start if there is input, even if that input is directed toward a client computer.|
|relativeMouseMoves| `true` or `false`| If set to ''true'' then secondary computers move the mouse using relative rather than absolute mouse moves when and only when the cursor is locked to the computer (by ''Scroll Lock'' or a configured hot key). This is intended to make Deskflow work better with certain games. If set to ''false'' or not set then all mouse moves are absolute.|
|clipboardSharing| `true` or `false`|If set to ''true'' then clipboard sharing will be enabled and the ''clipboardSharingSize'' setting will be used. If set to false, then clipboard sharing will be disabled and the the ''clipboardSharingSize'' setting will be ignored.|
|clipboardSharingSize| integer (N)| Deskflow will send a maximum of `N` kilobytes of clipboard data to another computer when the mouse transitions to that computer.|
|win32KeepForeground | `true` or `false`| If set to ''true'' (the default), Deskflow will grab the foreground focus on a Windows server (thereby putting all other windows in the background) upon switching to a client. If set to ''false'', it will leave the currently foreground window in the foreground. Deskflow grabs the focus to avoid issues with other apps interfering with Deskflow's ability to read the hardware inputs. |
|keystroke(key) | actions | Binds the ''key'' combination key to the given ''actions''. ''key'' is an optional list of modifiers (''shift'', ''control'', ''alt'', ''meta'' or ''super'') optionally followed by a character or a key name, all separated by + (plus signs). You must have either modifiers or a character/key name or both. See below for `valid key names` and `actions`. Keyboard hot keys are handled while the cursor is on the primary screen and secondary screens. Separate actions can be assigned to press and release.|
|mousebutton(button) | actions| Binds the modifier and mouse button combination ''button'' to the given ''actions''. ''button'' is an optional list of modifiers (''shift'', ''control'', ''alt'', ''meta'' or ''super'') followed by a button number. The primary button (the left button for right handed users) is button 1, the middle button is 2, etc. Actions can be found below. Mouse button actions are not handled while the cursor is on the primary screen. You cannot use these to perform an action while on the primary screen. Separate actions can be assigned to press and release.|
|keystroke(key) | actions | Binds the ''key'' combination key to the given ''actions''. ''key'' is an optional list of modifiers (''shift'', ''control'', ''alt'', ''meta'' or ''super'') optionally followed by a character or a key name, all separated by + (plus signs). You must have either modifiers or a character/key name or both. See below for `valid key names` and `actions`. Keyboard hot keys are handled while the cursor any computer. Separate actions can be assigned to press and release.|
|mousebutton(button) | actions| Binds the modifier and mouse button combination ''button'' to the given ''actions''. ''button'' is an optional list of modifiers (''shift'', ''control'', ''alt'', ''meta'' or ''super'') followed by a button number. The primary button (the left button for right handed users) is button 1, the middle button is 2, etc. Actions can be found below. Mouse button actions are not handled while the cursor is on the server. You cannot use these to perform an action while on the server. Separate actions can be assigned to press and release.|
You can use both the ''switchDelay'' and ''switchDoubleTap'' options at the same time. Deskflow will switch when either requirement is satisfied.
@ -406,16 +419,16 @@ You can use both the ''switchDelay'' and ''switchDoubleTap'' options at the same
Actions are two lists of individual actions separated by commas. The two lists are separated by a '';'' (semicolon). Either list can be empty and if the second list is empty then the semicolon is optional. The first list lists actions to take when the condition becomes true (e.g. the hot key or mouse button is pressed) and the second lists actions to take when the condition becomes false (e.g. the hot key or button is released). The condition becoming true is called activation and becoming false is called deactivation. Allowed individual actions are:
* `keystroke(key[,screens])`
* `keystroke(key[,computers])`
* `keyDown(key[,screens])`
* `keyDown(key[,computers])`
* `keyUp(key[,screens])`
* `keyUp(key[,computers])`
: Synthesizes the modifiers and key given in ''key'' which has the same form as described in the ''keystroke'' option. If given, ''screens'' lists the screen or screens to direct the event to, regardless of the active screen. If not given then the event is directed to the active screen only.
: Synthesizes the modifiers and key given in ''key'' which has the same form as described in the ''keystroke'' option. If given, ''computers'' lists the computer or computers to direct the event to, regardless of the active computer. If not given then the event is directed to the active computer only.
: ''keyDown'' synthesizes a key press and ''keyUp'' synthesizes a key release. ''keystroke'' synthesizes a key press on activation and a release on deactivation and is equivalent to a ''keyDown'' on activation and ''keyUp'' on deactivation.
: ''screens'' is either ''*'' (asterisk) to indicate all screens or a '':'' (colon) separated list of screen names. (Note that the screen name must have already been encountered in the configuration file so you'll probably want to put ''actions'' at the bottom of the file.)
: ''computers'' is either ''*'' (asterisk) to indicate all computers or a '':'' (colon) separated list of computer names. (Note that the computer name must have already been encountered in the configuration file so you'll probably want to put ''actions'' at the bottom of the file.)
* `mousebutton(button)`
* `mouseDown(button)`
@ -424,16 +437,16 @@ Actions are two lists of individual actions separated by commas. The two lists a
: ''mouseDown'' synthesizes a mouse press and ''mouseUp'' synthesizes a mouse release. ''mousebutton'' synthesizes a mouse press on activation and a release on deactivation and is equivalent to a ''mouseDown'' on activation and ''mouseUp'' on deactivation.
* `lockCursorToScreen(mode)`
: Locks the cursor to or unlocks the cursor from the active screen. ''mode'' can be ''off'' to unlock the cursor, ''on'' to lock the cursor, or ''toggle'' to toggle the current state. The default is ''toggle''. If the configuration has no ''lockCursorToScreen'' action and ''Scroll Lock'' is not used as a hot key then ''Scroll Lock'' toggles cursor locking.
: Locks the cursor to or unlocks the cursor from the active computer. ''mode'' can be ''off'' to unlock the cursor, ''on'' to lock the cursor, or ''toggle'' to toggle the current state. The default is ''toggle''. If the configuration has no ''lockCursorToScreen'' action and ''Scroll Lock'' is not used as a hot key then ''Scroll Lock'' toggles cursor locking.
* `switchToScreen(screen)`
: Jump to screen with name or alias ''screen''.
* `switchToScreen(computerName)`
: Jump to computer with name or alias ''computerName''.
* `switchInDirection(dir)`
: Switch to the screen in the direction ''dir'', which may be one of ''left'', ''right'', ''up'' or ''down''.
: Switch to the computer in the direction ''dir'', which may be one of ''left'', ''right'', ''up'' or ''down''.
* `switchToNextScreen()`
: Cycle to the next screen in the configuration order. If at the last screen, cycles back to the first screen.
: Cycle to the next computer in the configuration order. If at the last computer, cycles back to the first computer.
##### Keynames
Valid key names are:
@ -627,7 +640,7 @@ section: links
# iMac is to the right of Desktop1
# Laptop is to the left of Desktop1
Desktop1:
right(0,100) = iMac # the numbers in parentheses indicate the percentage of the screen's edge to be considered active for switching)
right(0,100) = iMac # the numbers in parentheses indicate the percentage of the computer's edge to be considered active for switching)
left = Laptop
shift = shift (shift, alt, super, meta can be mapped to any of the others)
# Desktop1 is to the right of Laptop
@ -648,7 +661,7 @@ end
#### Cursor Wrapping
The text config allows screens to be wrapped around. For example, with two machines (a server and a client), the mouse can go off the right of the server onto the left side of the client, then off the right side of the client back onto the left side of server. This config also uses ''Ctrl''+''Super''+(''left arrow''/''right arrow'') to switch between machines on keypress.
The text config allows computers to be wrapped around. For example, with two machines (a server and a client), the mouse can go off the right of the server onto the left side of the client, then off the right side of the client back onto the left side of server. This config also uses ''Ctrl''+''Super''+(''left arrow''/''right arrow'') to switch between machines on keypress.
```
# Physical monitor arrangement, with machine names as used by Deskflow.
@ -670,7 +683,7 @@ section: links
right = syn-serv # "wrapping"
end
section: options
keystroke(control+super+right) = switchInDirection(right) # Switch screens on keypress
keystroke(control+super+right) = switchInDirection(right) # Switch computers on keypress
<!-- keystroke(control+super+left) = switchInDirection(left) -->
end
```
@ -689,7 +702,7 @@ See also: the man page for ''deskflow-core''.
### Stacked Example
Stack one computer's screen on top of another's.
Stack one computer on top of another's.
```
# +-------+
@ -733,7 +746,7 @@ end
### Horizontal Example
Align all screens horizontally.
Align all computers horizontally.
```
# +-------+ +-------+ +-------+
@ -767,7 +780,7 @@ end
### Span Example
Span two screens on one computer across the screens of two computers.
Span one computer across the two other computers.
```
# +-------+ +-------+

View File

@ -1,10 +1,9 @@
# SPDX-FileCopyrightText: 2024 Deskflow Developers
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
include_directories(./lib)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/lib)
include_directories(./lib "${CMAKE_CURRENT_BINARY_DIR}/lib")
add_subdirectory(lib)
add_subdirectory(apps)

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 Deskflow Developers
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
if(UNIX AND NOT APPLE)
@ -28,6 +28,15 @@ function(generate_app_man TARGET NAME)
endif()
endfunction()
set(WIN32_PRE_EXCLUDE_REGEXES
"api-ms-win-.*"
"ext-ms-.*"
"^hvsifiletrust\\.dll$"
"^icu.*\\.dll$"
)
set(WIN32_POST_EXCLUDE_REGEXES ".*system32.*")
add_subdirectory(deskflow-core)
add_subdirectory(deskflow-daemon) #Only used on windows
add_subdirectory(deskflow-gui)

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
set(target ${CMAKE_PROJECT_NAME}-core)
@ -50,14 +50,13 @@ if(BUILD_OSX_BUNDLE)
INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks"
RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS
)
if (APPLE_CODESIGN_DEV)
configure_mac_codesign(${target})
endif()
elseif (WIN32)
install(RUNTIME_DEPENDENCY_SET coreDeps
PRE_EXCLUDE_REGEXES
"api-ms-win-.*"
"ext-ms-.*"
"^hvsifiletrust\\.dll$"
POST_EXCLUDE_REGEXES
".*system32.*"
PRE_EXCLUDE_REGEXES ${WIN32_PRE_EXCLUDE_REGEXES}
POST_EXCLUDE_REGEXES ${WIN32_POST_EXCLUDE_REGEXES}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()

View File

@ -6,11 +6,11 @@
#include "CoreArgParser.h"
#include "CoreArgs.h"
#include "VersionInfo.h"
#include "common/Constants.h"
#include "common/ExitCodes.h"
#include "common/Settings.h"
#include "common/VersionInfo.h"
#include "deskflow/ProtocolTypes.h"
const QString CoreArgParser::s_headerText = QStringLiteral("%1: %2\n").arg(kCoreBinName, kDisplayVersion);

View File

@ -16,7 +16,7 @@
#include "deskflow/ClientApp.h"
#include "deskflow/ServerApp.h"
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
#include "arch/win32/ArchMiscWindows.h"
#include <QCoreApplication>
#endif
@ -32,7 +32,7 @@ void showHelp(const CoreArgParser &parser)
int main(int argc, char **argv)
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// HACK to make sure settings gets the correct qApp path
QCoreApplication m(argc, argv);
m.deleteLater();
@ -66,7 +66,6 @@ int main(int argc, char **argv)
return s_exitSuccess;
}
if (parser.singleInstanceOnly()) {
// Before we check any more args we need to check for a duplicate process.
// Create a shared memory segment with a unique key
// This is to prevent a new instance from running if one is already running
@ -77,12 +76,10 @@ int main(int argc, char **argv)
if (sharedMemory.attach())
sharedMemory.detach();
// If we can create 1 byte of SHM we are the only instance
if (!sharedMemory.create(1)) {
if (!sharedMemory.create(1) && parser.singleInstanceOnly()) {
LOG_WARN("an instance of deskflow core is already running");
return s_exitDuplicate;
}
}
parser.parse();

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
# Daemon is only needed on Windows for elevating processes to deal with UAC.
@ -12,7 +12,12 @@ if(WIN32)
set(EXE_ICON "IDI_DESKFLOW ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"")
configure_file(${CMAKE_SOURCE_DIR}/src/apps/res/windows.rc.in ${target}.rc)
add_executable(${target} WIN32 ${target}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${target}.rc)
add_executable(
${target} WIN32
${target}.cpp
DaemonApp.cpp
DaemonApp.h
${CMAKE_CURRENT_BINARY_DIR}/${target}.rc)
target_link_libraries(
${target}
@ -29,16 +34,12 @@ if(WIN32)
install(
TARGETS ${target}
RUNTIME_DEPENDENCY_SET deamonDeps
RUNTIME_DEPENDENCY_SET daemonDeps
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(RUNTIME_DEPENDENCY_SET daemonDeps
PRE_EXCLUDE_REGEXES
"api-ms-win-.*"
"ext-ms-.*"
"^hvsifiletrust\\.dll$"
POST_EXCLUDE_REGEXES
".*system32.*"
PRE_EXCLUDE_REGEXES ${WIN32_PRE_EXCLUDE_REGEXES}
POST_EXCLUDE_REGEXES ${WIN32_POST_EXCLUDE_REGEXES}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()

View File

@ -1,10 +1,11 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd.
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "deskflow/DaemonApp.h"
#include "DaemonApp.h"
#include "arch/Arch.h"
#include "base/IEventQueue.h"
@ -12,12 +13,10 @@
#include "base/LogOutputters.h"
#include "common/ExitCodes.h"
#include "common/Settings.h"
#include "deskflow/App.h"
#include "deskflow/ipc/DaemonIpcServer.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h" // IWYU pragma: keep
#if defined(Q_OS_WIN)
#include "arch/win32/ArchDaemonWindows.h"
#include "deskflow/Screen.h"
#include "platform/MSWindowsDebugOutputter.h"
#include "platform/MSWindowsEventQueueBuffer.h"
@ -28,18 +27,10 @@
#endif
#include <filesystem>
#include <iostream>
#include <string>
using namespace deskflow::core;
void showHelp(int argc, char **argv) // NOSONAR - CLI args
{
const auto binName = argc > 0 ? std::filesystem::path(argv[0]).filename().string() : kDaemonBinName;
std::cout << "Usage: " << binName << " [-f|--foreground] [--install] [--uninstall]" << std::endl;
}
DaemonApp::DaemonApp(IEventQueue &events) : m_events(events)
{
// do nothing
@ -72,7 +63,7 @@ void DaemonApp::applyWatchdogCommand() const
{
LOG_DEBUG("applying watchdog command");
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
m_pWatchdog->setProcessConfig(m_command, m_elevate);
#else
LOG_ERR("applying watchdog command not implemented on this platform");
@ -86,7 +77,7 @@ void DaemonApp::clearWatchdogCommand()
// Clear the setting to prevent it from being next time the daemon starts.
setCommand("");
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
m_pWatchdog->setProcessConfig("", false);
#else
LOG_ERR("clearing watchdog command not implemented on this platform");
@ -96,10 +87,10 @@ void DaemonApp::clearWatchdogCommand()
void DaemonApp::clearSettings() const
{
LOG_INFO("clearing daemon settings");
Settings::setValue(Settings::Daemon::Command, QVariant());
Settings::setValue(Settings::Daemon::Elevate, QVariant());
Settings::setValue(Settings::Daemon::LogFile, QVariant());
Settings::setValue(Settings::Daemon::LogLevel, QVariant());
Settings::setValue(Settings::Daemon::Command);
Settings::setValue(Settings::Daemon::Elevate);
Settings::setValue(Settings::Daemon::LogFile);
Settings::setValue(Settings::Daemon::LogLevel);
}
void DaemonApp::connectIpcServer(const ipc::DaemonIpcServer *ipcServer) const
@ -145,7 +136,7 @@ void DaemonApp::run(QThread &daemonThread)
LOG_DEBUG("daemon thread finished");
});
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
m_pWatchdog = std::make_unique<MSWindowsWatchdog>(m_foreground, *m_pFileLogOutputter);
auto command = Settings::value(Settings::Daemon::Command).toString().toStdString();
@ -162,27 +153,26 @@ void DaemonApp::run(QThread &daemonThread)
int DaemonApp::daemonLoop()
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// Runs the daemon through the Windows service controller, which controls the program lifecycle.
return ArchMiscWindows::runDaemon([this]() { return mainLoop(); });
#elif SYSAPI_UNIX
return ArchDaemonWindows::runDaemon([this]() { return mainLoop(); });
#else
return mainLoop();
#endif
}
int DaemonApp::mainLoop()
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
if (m_pWatchdog == nullptr) {
LOG_ERR("watchdog not initialized");
return s_exitFailed;
}
ArchDaemonWindows::daemonRunning(true);
#endif
DAEMON_RUNNING(true);
try {
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// Install the platform event queue to handle service stop events.
// This must be done on the same thread as the event loop, otherwise the service stop
// request will not add the quit event to the event queue, and the service won't stop.
@ -202,7 +192,7 @@ int DaemonApp::mainLoop()
LOG_INFO("daemon is stopping");
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
try {
LOG_DEBUG("stopping process watchdog");
m_pWatchdog->stop();
@ -211,9 +201,9 @@ int DaemonApp::mainLoop()
} catch (...) { // NOSONAR - Catching remaining exceptions
LOG_CRIT("daemon stop watchdog unknown error");
}
ArchDaemonWindows::daemonRunning(false);
#endif
DAEMON_RUNNING(false);
return s_exitSuccess;
}
@ -230,7 +220,7 @@ void DaemonApp::setForeground()
void DaemonApp::initLogging()
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
if (!m_foreground) {
// Only use MS debug outputter when the process is daemonized, since stdout won't be accessible
// in that case, but is accessible when running in the foreground.
@ -244,7 +234,7 @@ void DaemonApp::initLogging()
void DaemonApp::showConsole()
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// The daemon bin is compiled using the Win32 subsystem which works best for Windows services,
// so when running as a foreground process we need to allocate a console (or we won't see output).
// It is important to do this inside the arg check loop so that we can attach console ahead

View File

@ -21,7 +21,7 @@ namespace deskflow::core::ipc {
class DaemonIpcServer;
}
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
class MSWindowsWatchdog;
#endif
@ -32,20 +32,9 @@ class DaemonApp : public QObject
Q_OBJECT
public:
enum class InitResult
{
Installed,
Uninstalled,
StartDaemon,
ShowHelp,
ArgsError,
FatalError,
};
explicit DaemonApp(IEventQueue &events);
~DaemonApp() override;
InitResult init(int argc, char **argv);
void run(QThread &daemonThread);
void setForeground();
void initLogging();
@ -67,7 +56,7 @@ private:
static void showConsole();
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
std::unique_ptr<MSWindowsWatchdog> m_pWatchdog;
#endif

View File

@ -5,22 +5,21 @@
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "VersionInfo.h"
#include "DaemonApp.h"
#include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#include "common/ExitCodes.h"
#include "common/Settings.h"
#include "deskflow/DaemonApp.h"
#include "common/VersionInfo.h"
#include "deskflow/ipc/DaemonIpcServer.h"
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
#include "arch/win32/ArchMiscWindows.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#include <QCommandLineParser>
@ -33,7 +32,7 @@ void handleError(const char *message = "Unrecognized error.");
int main(int argc, char **argv)
{
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
ArchMiscWindows::guardRuntimeVersion();
// Save window instance for later use, e.g. `GetModuleFileName` which is used when installing the daemon.
@ -84,7 +83,7 @@ int main(int argc, char **argv)
try {
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// Show warning if not running as admin as daemon will behave differently.
if (!ArchMiscWindows::isProcessElevated()) {
LOG_WARN("not running as admin, some features may not work");
@ -114,8 +113,7 @@ int main(int argc, char **argv)
}
}
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// Win32 subsystem entry point (simply forwards to main).
// We need this because using regular main under the Win32 subsystem results in empty args.
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
@ -130,7 +128,7 @@ void handleError(const char *message)
// Always print error to stdout in case run as CLI program.
LOG_ERR("%s", message);
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
// Show a message box for when run from MSI in Win32 subsystem.
MessageBoxA(nullptr, message, "Deskflow daemon error", MB_OK | MB_ICONERROR);
#endif

View File

@ -1,5 +1,5 @@
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2024 Symless Ltd
# SPDX-License-Identifier: MIT
if(APPLE)
@ -60,12 +60,8 @@ if(WIN32)
set_target_properties(${target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
install(RUNTIME_DEPENDENCY_SET guiDeps
PRE_EXCLUDE_REGEXES
"api-ms-win-.*"
"ext-ms-.*"
"^hvsifiletrust\\.dll$"
POST_EXCLUDE_REGEXES
".*system32.*"
PRE_EXCLUDE_REGEXES ${WIN32_PRE_EXCLUDE_REGEXES}
POST_EXCLUDE_REGEXES ${WIN32_POST_EXCLUDE_REGEXES}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
@ -90,6 +86,7 @@ if(WIN32)
DIRECTORY ${QT_DEPENDS_DIR}/
DESTINATION ${CMAKE_INSTALL_LIBDIR}
PATTERN "dx*.dll" EXCLUDE
PATTERN "icu*.dll" EXCLUDE
)
elseif(APPLE)
@ -98,32 +95,8 @@ elseif(APPLE)
INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/deskflow.plist"
)
# Warning: Do not use for CI/production, as the `entitlements-dev.plist` file adds special
# entitlements that are only appropriate for local development.
#
# macOS made TCC stricter so that if you don't sign your local dev builds properly, macOS will
# nag you to remove and re-approve the app every time you make a change to the binary which is
# extremely annoying during development.
#
# If you were to use ad-hoc signing (i.e. not specify a certificate), TCC would still nag you
# because the binary identity is anchored not on the app ID, but on the CD hash (which changes
# based on the binary contents).
#
# To use, simply generate a personal certificate for free with Xcode and pass the ID to CMake.
# Full instructions are in the docs.
if (NOT "${APPLE_CODESIGN_DEV}" STREQUAL "")
message(STATUS "Apple codesign ID for development only: ${APPLE_CODESIGN_DEV}")
add_custom_command(
TARGET ${target} POST_BUILD
COMMAND /usr/bin/codesign
--force
--options runtime
--entitlements "$<SHELL_PATH:${CMAKE_SOURCE_DIR}/src/apps/res/entitlements-dev.plist>"
--sign "${APPLE_CODESIGN_DEV}"
"$<TARGET_BUNDLE_DIR:${target}>"
VERBATIM
)
if (APPLE_CODESIGN_DEV)
configure_mac_codesign(${target})
endif()
else()
set_target_properties(${target} PROPERTIES MACOSX_BUNDLE FALSE)

View File

@ -6,12 +6,12 @@
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include "VersionInfo.h"
#include "common/Constants.h"
#include "common/ExitCodes.h"
#include "common/I18N.h"
#include "common/PlatformInfo.h"
#include "common/UrlConstants.h"
#include "common/VersionInfo.h"
#include "gui/Diagnostic.h"
#include "gui/MainWindow.h"
#include "gui/Messages.h"
@ -32,7 +32,7 @@
#include <QLoggingCategory>
#endif
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
#include "platform/XDGPortalRegistry.h"
#endif
@ -51,7 +51,7 @@ int main(int argc, char *argv[])
QLoggingCategory::setFilterRules(QStringLiteral("*.debug=true\nqt.*=false"));
#endif
#if defined(WINAPI_XWINDOWS) or defined(WINAPI_LIBEI)
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
deskflow::platform::setAppId();
#endif

View File

@ -30,8 +30,12 @@
<true/>
<key>NSHumanReadableCopyright</key>
<string>@BUNDLE_COPYRIGHT@</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<!-- Don't Allow Os to kill for memory -->
<!-- Prevent macOS from terminating during memory pressure -->
<key>NSSupportsAutomaticTermination</key>
<false/>
<key>NSSupportsSuddenTermination</key>
<false/>

View File

@ -5,11 +5,14 @@
<file>icons/deskflow-dark/actions/16/document-edit.svg</file>
<file>icons/deskflow-dark/actions/16/document-open.svg</file>
<file>icons/deskflow-dark/actions/16/document-save-as.svg</file>
<file>icons/deskflow-dark/actions/16/go-down.svg</file>
<file>icons/deskflow-dark/actions/16/go-up.svg</file>
<file>icons/deskflow-dark/actions/16/help-about.svg</file>
<file>icons/deskflow-dark/actions/16/network-connect.svg</file>
<file>icons/deskflow-dark/actions/16/network-disconnect.svg</file>
<file>icons/deskflow-dark/actions/16/process-stop.svg</file>
<file>icons/deskflow-dark/actions/16/system-run.svg</file>
<file>icons/deskflow-dark/actions/16/system-search.svg</file>
<file>icons/deskflow-dark/actions/16/tools-report-bug.svg</file>
<file>icons/deskflow-dark/actions/16/view-close.svg</file>
<file>icons/deskflow-dark/actions/16/view-refresh.svg</file>
@ -21,11 +24,14 @@
<file>icons/deskflow-dark/actions/22/document-open.svg</file>
<file>icons/deskflow-dark/actions/22/document-save-as.svg</file>
<file>icons/deskflow-dark/actions/22/fingerprint.svg</file>
<file>icons/deskflow-dark/actions/22/go-down.svg</file>
<file>icons/deskflow-dark/actions/22/go-up.svg</file>
<file>icons/deskflow-dark/actions/22/help-about.svg</file>
<file>icons/deskflow-dark/actions/22/network-connect.svg</file>
<file>icons/deskflow-dark/actions/22/network-disconnect.svg</file>
<file>icons/deskflow-dark/actions/22/process-stop.svg</file>
<file>icons/deskflow-dark/actions/22/system-run.svg</file>
<file>icons/deskflow-dark/actions/22/system-search.svg</file>
<file>icons/deskflow-dark/actions/22/tools-report-bug.svg</file>
<file>icons/deskflow-dark/actions/22/view-close.svg</file>
<file>icons/deskflow-dark/actions/22/view-refresh.svg</file>
@ -36,6 +42,8 @@
<file>icons/deskflow-dark/actions/24/document-edit.svg</file>
<file>icons/deskflow-dark/actions/24/document-open.svg</file>
<file>icons/deskflow-dark/actions/24/document-save-as.svg</file>
<file>icons/deskflow-dark/actions/24/go-down.svg</file>
<file>icons/deskflow-dark/actions/24/go-up.svg</file>
<file>icons/deskflow-dark/actions/24/edit-clear-all.svg</file>
<file>icons/deskflow-dark/actions/24/fingerprint.svg</file>
<file>icons/deskflow-dark/actions/24/help-about.svg</file>
@ -43,6 +51,7 @@
<file>icons/deskflow-dark/actions/24/network-disconnect.svg</file>
<file>icons/deskflow-dark/actions/24/process-stop.svg</file>
<file>icons/deskflow-dark/actions/24/system-run.svg</file>
<file>icons/deskflow-dark/actions/24/system-search.svg</file>
<file>icons/deskflow-dark/actions/24/tools-report-bug.svg</file>
<file>icons/deskflow-dark/actions/24/view-close.svg</file>
<file>icons/deskflow-dark/actions/24/view-refresh.svg</file>
@ -55,8 +64,11 @@
<file>icons/deskflow-dark/actions/32/dialog-ok-apply.svg</file>
<file>icons/deskflow-dark/actions/32/document-open.svg</file>
<file>icons/deskflow-dark/actions/32/document-save-as.svg</file>
<file>icons/deskflow-dark/actions/32/go-down.svg</file>
<file>icons/deskflow-dark/actions/32/go-up.svg</file>
<file>icons/deskflow-dark/actions/32/help-about.svg</file>
<file>icons/deskflow-dark/actions/32/view-refresh.svg</file>
<file>icons/deskflow-dark/actions/32/system-search.svg</file>
<file>icons/deskflow-dark/apps/64/org.deskflow.deskflow.svg</file>
<file>icons/deskflow-dark/apps/64/org.deskflow.deskflow-symbolic.svg</file>
<file>icons/deskflow-dark/devices/64/video-display.svg</file>
@ -77,11 +89,14 @@
<file>icons/deskflow-light/actions/16/document-edit.svg</file>
<file>icons/deskflow-light/actions/16/document-open.svg</file>
<file>icons/deskflow-light/actions/16/document-save-as.svg</file>
<file>icons/deskflow-light/actions/16/go-down.svg</file>
<file>icons/deskflow-light/actions/16/go-up.svg</file>
<file>icons/deskflow-light/actions/16/help-about.svg</file>
<file>icons/deskflow-light/actions/16/network-connect.svg</file>
<file>icons/deskflow-light/actions/16/network-disconnect.svg</file>
<file>icons/deskflow-light/actions/16/process-stop.svg</file>
<file>icons/deskflow-light/actions/16/system-run.svg</file>
<file>icons/deskflow-light/actions/16/system-search.svg</file>
<file>icons/deskflow-light/actions/16/tools-report-bug.svg</file>
<file>icons/deskflow-light/actions/16/view-close.svg</file>
<file>icons/deskflow-light/actions/16/view-refresh.svg</file>
@ -94,11 +109,14 @@
<file>icons/deskflow-light/actions/22/document-open.svg</file>
<file>icons/deskflow-light/actions/22/document-save-as.svg</file>
<file>icons/deskflow-light/actions/22/fingerprint.svg</file>
<file>icons/deskflow-light/actions/22/go-down.svg</file>
<file>icons/deskflow-light/actions/22/go-up.svg</file>
<file>icons/deskflow-light/actions/22/network-connect.svg</file>
<file>icons/deskflow-light/actions/22/network-disconnect.svg</file>
<file>icons/deskflow-light/actions/22/help-about.svg</file>
<file>icons/deskflow-light/actions/22/process-stop.svg</file>
<file>icons/deskflow-light/actions/22/system-run.svg</file>
<file>icons/deskflow-light/actions/22/system-search.svg</file>
<file>icons/deskflow-light/actions/22/tools-report-bug.svg</file>
<file>icons/deskflow-light/actions/22/view-close.svg</file>
<file>icons/deskflow-light/actions/22/view-refresh.svg</file>
@ -111,11 +129,14 @@
<file>icons/deskflow-light/actions/24/document-edit.svg</file>
<file>icons/deskflow-light/actions/24/document-open.svg</file>
<file>icons/deskflow-light/actions/24/document-save-as.svg</file>
<file>icons/deskflow-light/actions/24/go-down.svg</file>
<file>icons/deskflow-light/actions/24/go-up.svg</file>
<file>icons/deskflow-light/actions/24/help-about.svg</file>
<file>icons/deskflow-light/actions/24/network-connect.svg</file>
<file>icons/deskflow-light/actions/24/network-disconnect.svg</file>
<file>icons/deskflow-light/actions/24/process-stop.svg</file>
<file>icons/deskflow-light/actions/24/system-run.svg</file>
<file>icons/deskflow-light/actions/24/system-search.svg</file>
<file>icons/deskflow-light/actions/24/tools-report-bug.svg</file>
<file>icons/deskflow-light/actions/24/view-close.svg</file>
<file>icons/deskflow-light/actions/24/view-refresh.svg</file>
@ -128,8 +149,11 @@
<file>icons/deskflow-light/actions/32/dialog-ok-apply.svg</file>
<file>icons/deskflow-light/actions/32/document-open.svg</file>
<file>icons/deskflow-light/actions/32/document-save-as.svg</file>
<file>icons/deskflow-light/actions/32/go-down.svg</file>
<file>icons/deskflow-light/actions/32/go-up.svg</file>
<file>icons/deskflow-light/actions/32/help-about.svg</file>
<file>icons/deskflow-light/actions/32/view-refresh.svg</file>
<file>icons/deskflow-light/actions/32/system-search.svg</file>
<file>icons/deskflow-light/apps/64/org.deskflow.deskflow.svg</file>
<file>icons/deskflow-light/apps/64/org.deskflow.deskflow-symbolic.svg</file>
<file>icons/deskflow-light/devices/64/video-display.svg</file>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<path d="M8 11.707l-6-6L2.707 5 8 10.293 13.293 5l.707.707-6 6z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 323 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<path d="M8 4.293l-6 6 .707.707L8 5.707 13.293 11l.707-.707-6-6z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 324 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 6.5 2 C 4.007 2 2 4.01 2 6.5 C 2 8.993 4.01 11 6.5 11 C 7.5636432 11 8.5263409 10.618801 9.2949219 10.005859 L 13.292969 14.003906 L 14 13.296875 L 10.001953 9.2988281 C 10.617604 8.529048 11 7.565338 11 6.5 C 11 4.007 8.99 2 6.5 2 z M 6.5 3 C 8.439 3 10 4.561 10 6.5 C 10 8.439 8.439 10 6.5 10 C 4.561 10 3 8.439 3 6.5 C 3 4.561 4.561 3 6.5 3 z " class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 680 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="m3.707031 7l-.707031.707031 6.125 6.125 1.875 1.875 1.875-1.875 6.125-6.125-.707031-.707031-6.125 6.125-1.167969 1.167969-1.167969-1.167969-6.125-6.125" class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 485 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<path d="M3.707 15L3 14.293l6.125-6.125L11 6.293l1.875 1.875L19 14.293l-.707.707-6.125-6.125L11 7.707 9.832 8.875 3.707 15" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z " class="ColorScheme-Text"/>
</svg>

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="m3.707031 7l-.707031.707031 6.125 6.125 1.875 1.875 1.875-1.875 6.125-6.125-.707031-.707031-6.125 6.125-1.167969 1.167969-1.167969-1.167969-6.125-6.125" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 549 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<g transform="translate(1,1)">
<path d="M3.707 15L3 14.293l6.125-6.125L11 6.293l1.875 1.875L19 14.293l-.707.707-6.125-6.125L11 7.707 9.832 8.875 3.707 15" class="ColorScheme-Text" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 443 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z " class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 774 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<path d="M16 23.707l-14-14L2.707 9 16 22.293 29.293 9l.707.707z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 323 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<path d="M16 8.293l-14 14 .707.707L16 9.707 29.293 23l.707-.707z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 324 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="32" height="32">
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
<g id="system-search" transform="translate(0 -32) translate(-22,32)">
<path id="path66" class="ColorScheme-Text" d="m35 4a9 9 0 0 0-9 9 9 9 0 0 0 9 9 9 9 0 0 0 5.994141-2.298828l8.298828 8.298828 0.707031-0.707031-8.300781-8.300782a9 9 0 0 0 2.300781-5.992187 9 9 0 0 0-9-9zm0 1a8 8 0 0 1 8 8 8 8 0 0 1-8 8 8 8 0 0 1-8-8 8 8 0 0 1 8-8z" fill="currentColor"/>
<path id="path68" d="m22 0v32h32v-32z" fill="none"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 965 B

View File

@ -0,0 +1,10 @@
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<path d="M8 11.707l-6-6L2.707 5 8 10.293 13.293 5l.707.707-6 6z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

View File

@ -0,0 +1,10 @@
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<path d="M8 4.293l-6 6 .707.707L8 5.707 13.293 11l.707-.707-6-6z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 333 B

View File

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 6.5 2 C 4.007 2 2 4.01 2 6.5 C 2 8.993 4.01 11 6.5 11 C 7.5636432 11 8.5263409 10.618801 9.2949219 10.005859 L 13.292969 14.003906 L 14 13.296875 L 10.001953 9.2988281 C 10.617604 8.529048 11 7.565338 11 6.5 C 11 4.007 8.99 2 6.5 2 z M 6.5 3 C 8.439 3 10 4.561 10 6.5 C 10 8.439 8.439 10 6.5 10 C 4.561 10 3 8.439 3 6.5 C 3 4.561 4.561 3 6.5 3 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 684 B

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="m3.707031 7l-.707031.707031 6.125 6.125 1.875 1.875 1.875-1.875 6.125-6.125-.707031-.707031-6.125 6.125-1.167969 1.167969-1.167969-1.167969-6.125-6.125"
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 488 B

View File

@ -0,0 +1,10 @@
<svg viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<path d="M3.707 15L3 14.293l6.125-6.125L11 6.293l1.875 1.875L19 14.293l-.707.707-6.125-6.125L11 7.707 9.832 8.875 3.707 15" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 391 B

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<path
style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z "
class="ColorScheme-Text"
/>
</svg>

After

Width:  |  Height:  |  Size: 716 B

View File

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="m3.707031 7l-.707031.707031 6.125 6.125 1.875 1.875 1.875-1.875 6.125-6.125-.707031-.707031-6.125 6.125-1.167969 1.167969-1.167969-1.167969-6.125-6.125" class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 536 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<g transform="translate(1,1)">
<path d="M3.707 15L3 14.293l6.125-6.125L11 6.293l1.875 1.875L19 14.293l-.707.707-6.125-6.125L11 7.707 9.832 8.875 3.707 15" class="ColorScheme-Text" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 436 B

View File

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z " class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@ -0,0 +1,10 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<path d="M16 23.707l-14-14L2.707 9 16 22.293 29.293 9l.707.707z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 332 B

View File

@ -0,0 +1,10 @@
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style
type="text/css"
id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<path d="M16 8.293l-14 14 .707.707L16 9.707 29.293 23l.707-.707z" class="ColorScheme-Text" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 333 B

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="32" height="32">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
<g id="system-search" transform="translate(0 -32) translate(-22,32)">
<path id="path66" class="ColorScheme-Text" d="m35 4a9 9 0 0 0-9 9 9 9 0 0 0 9 9 9 9 0 0 0 5.994141-2.298828l8.298828 8.298828 0.707031-0.707031-8.300781-8.300782a9 9 0 0 0 2.300781-5.992187 9 9 0 0 0-9-9zm0 1a8 8 0 0 1 8 8 8 8 0 0 1-8 8 8 8 0 0 1-8-8 8 8 0 0 1 8-8z" fill="currentColor"/>
<path id="path68" d="m22 0v32h32v-32z" fill="none"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 997 B

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2025 Chris Rizzitello <sithlord48@gmail.com>
// SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
// SPDX-License-Identifier: MIT
// Generic Template for rc files in deskflow
#include <windows.h>

View File

@ -1,10 +1,8 @@
# SPDX-FileCopyrightText: 2024 Deskflow Developers
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 Deskflow Developers
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
configure_file(VersionInfo.h.in VersionInfo.h @ONLY)
add_subdirectory(arch)
add_subdirectory(base)
add_subdirectory(client)

View File

@ -10,7 +10,7 @@
#include <thread>
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
#include "arch/win32/ArchMiscWindows.h"
#endif
@ -26,7 +26,7 @@ Arch::Arch()
s_instance = this;
}
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
void Arch::init()
{
ARCH_NETWORK::init();

View File

@ -5,7 +5,7 @@
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
*/
#include <QtSystemDetection>
// Consider whether or not to use either encapsulation (as below)
// or inheritance (as it is now) for the ARCH stuff.
//
@ -25,20 +25,16 @@
#pragma once
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
#include "arch/win32/ArchDaemonWindows.h"
#include "arch/win32/ArchLogWindows.h"
#include "arch/win32/ArchMultithreadWindows.h"
#include "arch/win32/ArchNetworkWinsock.h"
#elif SYSAPI_UNIX
#else
#include "arch/ArchDaemonNone.h"
#include "arch/unix/ArchLogUnix.h"
#include "arch/unix/ArchMultithreadPosix.h"
#include "arch/unix/ArchNetworkBSD.h"
#endif
/*!
@ -63,7 +59,7 @@ public:
Arch();
~Arch() override = default;
#if SYSAPI_WIN32
#if defined(Q_OS_WIN)
//! Call init on other arch classes.
/*!
Some arch classes depend on others to exist first. When init is called

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
# Platform Specific Code

View File

@ -1,6 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@ -41,16 +41,16 @@ public:
Becomes a service. Argument 0 is the name of the service
and the rest are the arguments passed to StartService().
\c func is only called when the service is actually started.
\c func must call \c ArchMiscWindows::runDaemon() to finally
\c func must call \c ArchDaemonWindows::runDaemon() to finally
becoming a service. The \c runFunc function passed to \c runDaemon()
must call \c ArchMiscWindows::daemonRunning(true) when it
must call \c ArchDaemonWindows::daemonRunning(true) when it
enters the main loop (i.e. after initialization) and
\c ArchMiscWindows::daemonRunning(false) when it leaves
\c ArchDaemonWindows::daemonRunning(false) when it leaves
the main loop. The \c stopFunc function passed to \c runDaemon()
is called when the daemon must exit the main loop and it must cause
\c runFunc to return. \c func should return what \c runDaemon()
returns. \c func or \c runFunc can call
\c ArchMiscWindows::daemonFailed() to indicate startup failure.
\c ArchDaemonWindows::daemonFailed() to indicate startup failure.
</ul>
*/
virtual int daemonize(DaemonFunc const &func) = 0;

View File

@ -79,6 +79,10 @@ ArchSocket ArchNetworkBSD::newSocket(AddressFamily family, SocketType type)
}
try {
setBlockingOnSocket(fd, false);
#if defined(__APPLE__)
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
#endif
} catch (...) {
close(fd);
throw;
@ -196,6 +200,10 @@ ArchSocket ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress *addr)
try {
setBlockingOnSocket(fd, false);
#if defined(__APPLE__)
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
#endif
} catch (...) {
close(fd);
delete newSocket;

View File

@ -1,5 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 - 2016, 2024 - 2025 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@ -7,7 +8,6 @@
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/ArchDaemonWindows.h"
#include "arch/win32/XArchWindows.h"
#include "base/Log.h"
#include "base/String.h"
@ -17,6 +17,7 @@
#include <array>
#include <filesystem>
#include <stdexcept>
// Useful for debugging Windows specific bootstrapping code before the logging system is initialized.
// This output can be viewed by attaching a Microsoft debugger or by using the DebugView program.
@ -64,26 +65,6 @@ void ArchMiscWindows::init()
SetErrorMode(SEM_FAILCRITICALERRORS);
}
int ArchMiscWindows::runDaemon(RunFunc runFunc)
{
return ArchDaemonWindows::runDaemon(runFunc);
}
void ArchMiscWindows::daemonRunning(bool running)
{
ArchDaemonWindows::daemonRunning(running);
}
void ArchMiscWindows::daemonFailed(int result)
{
ArchDaemonWindows::daemonFailed(result);
}
UINT ArchMiscWindows::getDaemonQuitMessage()
{
return ArchDaemonWindows::getDaemonQuitMessage();
}
HKEY ArchMiscWindows::openKey(HKEY key, const TCHAR *keyName)
{
return openKey(key, keyName, false);
@ -178,20 +159,16 @@ ArchMiscWindows::EValueType ArchMiscWindows::typeOfValue(HKEY key, const TCHAR *
void ArchMiscWindows::setValue(HKEY key, const TCHAR *name, const std::string &value)
{
assert(key != nullptr);
if (key == nullptr) {
// TODO: throw exception
return;
throw std::invalid_argument("Registry key cannot be nullptr");
}
RegSetValueEx(key, name, 0, REG_SZ, reinterpret_cast<const BYTE *>(value.c_str()), (DWORD)value.size() + 1);
}
void ArchMiscWindows::setValue(HKEY key, const TCHAR *name, DWORD value)
{
assert(key != nullptr);
if (key == nullptr) {
// TODO: throw exception
return;
throw std::invalid_argument("Registry key cannot be nullptr");
}
RegSetValueEx(key, name, 0, REG_DWORD, reinterpret_cast<CONST BYTE *>(&value), sizeof(DWORD));
}

View File

@ -1,5 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2026 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@ -40,30 +41,6 @@ public:
//! Initialize
static void init();
//! Run the daemon
/*!
Delegates to ArchDaemonWindows.
*/
static int runDaemon(RunFunc runFunc);
//! Indicate daemon is in main loop
/*!
Delegates to ArchDaemonWindows.
*/
static void daemonRunning(bool running);
//! Indicate failure of running daemon
/*!
Delegates to ArchDaemonWindows.
*/
static void daemonFailed(int result);
//! Get daemon quit message
/*!
Delegates to ArchDaemonWindows.
*/
static UINT getDaemonQuitMessage();
//! Open and return a registry key, closing the parent key
static HKEY openKey(HKEY parent, const TCHAR *child);

View File

@ -135,7 +135,7 @@ void ArchNetworkWinsock::initModule(HMODULE module)
WSADATA data;
int err = startup(version, &data);
if (data.wVersion != version) {
throw ArchNetworkSupportException(winsockErrorToString(err));
throw ArchNetworkSupportException(windowsErrorToString(err));
}
if (err != 0) {
// some other initialization error
@ -819,12 +819,12 @@ bool ArchNetworkWinsock::isEqualAddr(ArchNetAddress a, ArchNetAddress b)
{
switch (err) {
case WSAEACCES:
throw ArchNetworkAccessException(winsockErrorToString(err));
throw ArchNetworkAccessException(windowsErrorToString(err));
case WSAEMFILE:
case WSAENOBUFS:
case WSAENETDOWN:
throw ArchNetworkResourceException(winsockErrorToString(err));
throw ArchNetworkResourceException(windowsErrorToString(err));
case WSAEPROTOTYPE:
case WSAEPROTONOSUPPORT:
@ -838,50 +838,50 @@ bool ArchNetworkWinsock::isEqualAddr(ArchNetAddress a, ArchNetAddress b)
case WSANOTINITIALISED:
case WSAVERNOTSUPPORTED:
case WSASYSNOTREADY:
throw ArchNetworkSupportException(winsockErrorToString(err));
throw ArchNetworkSupportException(windowsErrorToString(err));
case WSAEADDRNOTAVAIL:
throw ArchNetworkNoAddressException(winsockErrorToString(err));
throw ArchNetworkNoAddressException(windowsErrorToString(err));
case WSAEADDRINUSE:
throw ArchNetworkAddressInUseException(winsockErrorToString(err));
throw ArchNetworkAddressInUseException(windowsErrorToString(err));
case WSAEHOSTUNREACH:
case WSAENETUNREACH:
throw ArchNetworkNoRouteException(winsockErrorToString(err));
throw ArchNetworkNoRouteException(windowsErrorToString(err));
case WSAENOTCONN:
throw ArchNetworkNotConnectedException(winsockErrorToString(err));
throw ArchNetworkNotConnectedException(windowsErrorToString(err));
case WSAEDISCON:
throw ArchNetworkShutdownException(winsockErrorToString(err));
throw ArchNetworkShutdownException(windowsErrorToString(err));
case WSAENETRESET:
case WSAECONNABORTED:
case WSAECONNRESET:
throw ArchNetworkDisconnectedException(winsockErrorToString(err));
throw ArchNetworkDisconnectedException(windowsErrorToString(err));
case WSAECONNREFUSED:
throw ArchNetworkConnectionRefusedException(winsockErrorToString(err));
throw ArchNetworkConnectionRefusedException(windowsErrorToString(err));
case WSAEHOSTDOWN:
case WSAETIMEDOUT:
throw ArchNetworkTimedOutException(winsockErrorToString(err));
throw ArchNetworkTimedOutException(windowsErrorToString(err));
case WSAHOST_NOT_FOUND:
throw ArchNetworkNameUnknownException(winsockErrorToString(err));
throw ArchNetworkNameUnknownException(windowsErrorToString(err));
case WSANO_DATA:
throw ArchNetworkNameNoAddressException(winsockErrorToString(err));
throw ArchNetworkNameNoAddressException(windowsErrorToString(err));
case WSANO_RECOVERY:
throw ArchNetworkNameFailureException(winsockErrorToString(err));
throw ArchNetworkNameFailureException(windowsErrorToString(err));
case WSATRY_AGAIN:
throw ArchNetworkNameUnavailableException(winsockErrorToString(err));
throw ArchNetworkNameUnavailableException(windowsErrorToString(err));
default:
throw ArchNetworkException(winsockErrorToString(err));
throw ArchNetworkException(windowsErrorToString(err));
}
}
@ -889,18 +889,18 @@ bool ArchNetworkWinsock::isEqualAddr(ArchNetAddress a, ArchNetAddress b)
{
switch (err) {
case WSAHOST_NOT_FOUND:
throw ArchNetworkNameUnknownException(winsockErrorToString(err));
throw ArchNetworkNameUnknownException(windowsErrorToString(err));
case WSANO_DATA:
throw ArchNetworkNameNoAddressException(winsockErrorToString(err));
throw ArchNetworkNameNoAddressException(windowsErrorToString(err));
case WSANO_RECOVERY:
throw ArchNetworkNameFailureException(winsockErrorToString(err));
throw ArchNetworkNameFailureException(windowsErrorToString(err));
case WSATRY_AGAIN:
throw ArchNetworkNameUnavailableException(winsockErrorToString(err));
throw ArchNetworkNameUnavailableException(windowsErrorToString(err));
default:
throw ArchNetworkNameException(winsockErrorToString(err));
throw ArchNetworkNameException(windowsErrorToString(err));
}
}

View File

@ -30,192 +30,7 @@ QString windowsErrorToQString(DWORD error)
return QString("[%1] %2").arg(error).arg(message.trimmed());
}
QString winsockErrorToQString(int error)
{
// built-in windows function for looking up error message strings
// may not look up network error messages correctly. we'll have
// to do it ourself.
static const struct
{
int m_code;
const char *m_msg;
}
s_netErrorCodes[] = {
// 10004
{WSAEINTR, "The (blocking) call was canceled via WSACancelBlockingCall"},
// 10009
{WSAEBADF, "Bad file handle"},
// 10013
{WSAEACCES, "The requested address is a broadcast address, but the appropriate flag was not set"},
// 10014
{WSAEFAULT, "WSAEFAULT"},
// 10022
{WSAEINVAL, "WSAEINVAL"},
// 10024
{WSAEMFILE, "No more file descriptors available"},
// 10035
{WSAEWOULDBLOCK,
"Socket is marked as non-blocking and no connections are present or the receive operation would block"},
// 10036
{WSAEINPROGRESS, "A blocking Windows Sockets operation is in progress"},
// 10037
{WSAEALREADY, "The asynchronous routine being canceled has already completed"},
// 10038
{WSAENOTSOCK, "At least on descriptor is not a socket"},
// 10039
{WSAEDESTADDRREQ, "A destination address is required"},
// 10040
{WSAEMSGSIZE, "The datagram was too large to fit into the specified buffer and was truncated"},
// 10041
{WSAEPROTOTYPE, "The specified protocol is the wrong type for this socket"},
// 10042
{WSAENOPROTOOPT, "The option is unknown or unsupported"},
// 10043
{WSAEPROTONOSUPPORT, "The specified protocol is not supported"},
// 10044
{WSAESOCKTNOSUPPORT, "The specified socket type is not supported by this address family"},
// 10045
{WSAEOPNOTSUPP, "The referenced socket is not a type that supports that operation"},
// 10046
{WSAEPFNOSUPPORT, "BSD: Protocol family not supported"},
// 10047
{WSAEAFNOSUPPORT, "The specified address family is not supported"},
// 10048
{WSAEADDRINUSE, "The specified address is already in use"},
// 10049
{WSAEADDRNOTAVAIL, "The specified address is not available from the local machine"},
// 10050
{WSAENETDOWN, "The Windows Sockets implementation has detected that the network subsystem has failed"},
// 10051
{WSAENETUNREACH, "The network can't be reached from this host at this time"},
// 10052
{WSAENETRESET, "The connection must be reset because the Windows Sockets implementation dropped it"},
// 10053
{WSAECONNABORTED, "The virtual circuit was aborted due to timeout or other failure"},
// 10054
{WSAECONNRESET, "The virtual circuit was reset by the remote side"},
// 10055
{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occurred. The socket cannot be created"},
// 10056
{WSAEISCONN, "The socket is already connected"},
// 10057
{WSAENOTCONN, "The socket is not connected"},
// 10058
{WSAESHUTDOWN, "The socket has been shutdown"},
// 10059
{WSAETOOMANYREFS, "BSD: Too many references"},
// 10060
{WSAETIMEDOUT, "Attempt to connect timed out without establishing a connection"},
// 10061
{WSAECONNREFUSED, "Connection was refused"},
// 10062
{WSAELOOP, "Undocumented WinSock error code used in BSD"},
// 10063
{WSAENAMETOOLONG, "Undocumented WinSock error code used in BSD"},
// 10064
{WSAEHOSTDOWN, "Undocumented WinSock error code used in BSD"},
// 10065
{WSAEHOSTUNREACH, "No route to host"},
// 10066
{WSAENOTEMPTY, "Undocumented WinSock error code"},
// 10067
{WSAEPROCLIM, "Undocumented WinSock error code"},
// 10068
{WSAEUSERS, "Undocumented WinSock error code"},
// 10069
{WSAEDQUOT, "Undocumented WinSock error code"},
// 10070
{WSAESTALE, "Undocumented WinSock error code"},
// 10071
{WSAEREMOTE, "Undocumented WinSock error code"},
// 10091
{WSASYSNOTREADY, "Underlying network subsytem is not ready for network communication"},
// 10092
{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is not provided in this implementation"},
// 10093
{WSANOTINITIALISED, "WinSock subsystem not properly initialized"},
// 10101
{WSAEDISCON, "Virtual circuit has gracefully terminated connection"},
// 11001
{WSAHOST_NOT_FOUND, "The specified host is unknown"},
// 11002
{WSATRY_AGAIN, "A temporary error occurred on an authoritative name server"},
// 11003
{WSANO_RECOVERY, "A non-recoverable name server error occurred"},
// 11004
{WSANO_DATA, "The requested name is valid but does not have an IP address"},
// end
{0, nullptr}
};
for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) {
if (s_netErrorCodes[i].m_code == error) {
return QString("[%1] %2").arg(error).arg(s_netErrorCodes[i].m_msg);
}
}
return QString("Unknown Winsock error: %1").arg(error);
}
std::string windowsErrorToString(DWORD error)
{
return windowsErrorToQString(error).toStdString();
}
std::string winsockErrorToString(int error)
{
return winsockErrorToQString(error).toStdString();
}

View File

@ -14,7 +14,5 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
QString winsockErrorToQString(int error);
QString windowsErrorToQString(DWORD error);
std::string winsockErrorToString(int error);
std::string windowsErrorToString(DWORD error);

View File

@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
# SPDX-License-Identifier: MIT
add_library(base STATIC
@ -27,8 +27,6 @@ add_library(base STATIC
Log.h
LogLevel.h
NetworkProtocol.h
Path.cpp
Path.h
PriorityQueue.h
SimpleEventQueueBuffer.cpp
SimpleEventQueueBuffer.h

View File

@ -11,20 +11,20 @@
#include <cstdint>
/**
* @brief Screen edge directions for mouse movement
* @brief Computer edge directions for mouse movement
*
* Used to specify which edge of a screen the mouse cursor crosses
* when moving between primary and secondary screens.
* Used to specify which edge of a computer the mouse cursor crosses
* when moving between primary and secondary computers.
*
* @since Protocol version 1.0
*/
enum class Direction : uint8_t
{
NoDirection, ///< No specific direction
Left, ///< Left edge of screen
Right, ///< Right edge of screen
Top, ///< Top edge of screen
Bottom, ///< Bottom edge of screen
Left, ///< Left edge of computer
Right, ///< Right edge of computer
Top, ///< Top edge of computer
Bottom, ///< Bottom edge of computer
FirstDirection = Direction::Left, ///< First valid direction value
LastDirection = Direction::Bottom, ///< Last valid direction value
NumDirections = Direction::LastDirection - Direction::FirstDirection + 1 ///< Total number of directions

View File

@ -1,6 +1,6 @@
/*
* Deskflow -- mouse and keyboard sharing utility
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2025 - 2026 Deskflow Developers
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
@ -9,6 +9,7 @@
#include "base/EventQueue.h"
#include "arch/Arch.h"
#include "base/EventQueueTimer.h"
#include "base/Log.h"
#include "base/SimpleEventQueueBuffer.h"
#include "mt/Lock.h"
@ -213,7 +214,7 @@ EventQueueTimer *EventQueue::newTimer(double duration, void *target)
{
assert(duration > 0.0);
EventQueueTimer *timer = m_buffer->newTimer(duration, false);
auto timer = new EventQueueTimer;
if (target == nullptr) {
target = timer;
}
@ -230,7 +231,7 @@ EventQueueTimer *EventQueue::newOneShotTimer(double duration, void *target)
{
assert(duration > 0.0);
EventQueueTimer *timer = m_buffer->newTimer(duration, true);
auto timer = new EventQueueTimer;
if (target == nullptr) {
target = timer;
}
@ -255,7 +256,7 @@ void EventQueue::deleteTimer(EventQueueTimer *timer)
if (Timers::iterator index = m_timers.find(timer); index != m_timers.end()) {
m_timers.erase(index);
}
m_buffer->deleteTimer(timer);
delete timer;
}
void EventQueue::addHandler(EventTypes type, void *target, const EventHandler &handler)

View File

@ -91,6 +91,11 @@ enum class EventTypes : uint32_t
/// This event is sent whenever a server accepts a client.
ClientListenerAccepted,
/** This event is sent whenever a client disconnects/errors out before the connection
is fully accepted.
*/
ClientListenerDisconnectedOnAccept,
/** This event is sent when the client has completed the initial handshake. Until it is sent,
the client is not fully connected.
*/
@ -111,23 +116,23 @@ enum class EventTypes : uint32_t
*/
ClientProxyUnknownFailure,
/** This event is sent when a client screen has connected.
The event data is a pointer to ScreenConnectedInfo that indicates the connected screen.
/** This event is sent when a client computer has connected.
The event data is a pointer to ScreenConnectedInfo that indicates the connected computer.
*/
ServerConnected,
/// This is event sent when all the clients have disconnected.
ServerDisconnected,
/** This event is sent to inform the server to switch screens.
The event data is a pointer to SwitchToScreenInfo that indicates the target screen.
/** This event is sent to inform the server to switch computers.
The event data is a pointer to SwitchToScreenInfo that indicates the target computer.
*/
ServerSwitchToScreen,
/// This event is sent to inform the server to toggle screens. These is no event data.
/// This event is sent to inform the server to toggle computers. These is no event data.
ServerToggleScreen,
/** This event is sent to inform the server to switch screens.
/** This event is sent to inform the server to switch computers.
The event data is a pointer to SwitchInDirectionInfo that indicates the target direction.
*/
ServerSwitchInDirection,
@ -137,12 +142,12 @@ enum class EventTypes : uint32_t
*/
ServerKeyboardBroadcast,
/** This event is sent to inform the server to lock the cursor to the active screen or to
/** This event is sent to inform the server to lock the cursor to the active computer or to
unlock it. The event data is a pointer to LockCursorToScreenInfo.
*/
ServerLockCursorToScreen,
/// This event is sent when the screen has been switched to a client.
/// This event is sent when the computer has been switched to a client.
ServerScreenSwitched,
ServerAppReloadConfig,
@ -162,12 +167,12 @@ enum class EventTypes : uint32_t
/// This event is sent when button is up. Event data is a pointer to ButtonInfo
PrimaryScreenButtonUp,
/** This event is sent when mouse moves on primary screen.
/** This event is sent when mouse moves on the server.
Event data is a pointer to MotionInfo, the values are absolute position.
*/
PrimaryScreenMotionOnPrimary,
/** This event is sent when mouse moves on secondary screen.
/** This event is sent when mouse moves on a client.
Event data is a pointer to MotionInfo, the values are relative motion deltas.
*/
PrimaryScreenMotionOnSecondary,
@ -193,12 +198,12 @@ enum class EventTypes : uint32_t
/// This event is sent when fake input ends.
PrimaryScreenFakeInputEnd,
/** This event is sent whenever the screen has failed for some reason (e.g. the X Windows
/** This event is sent whenever the computer has failed for some reason (e.g. the X Windows
server died).
*/
ScreenError,
/// This event is sent whenever the screen's shape changes.
/// This event is sent whenever the computer's display shape changes.
ScreenShapeChanged,
/** This event is sent whenever the system goes to sleep or a user session is deactivated (fast
@ -224,9 +229,10 @@ enum class EventTypes : uint32_t
/// This event is sent whenever a clipboard chunk is transferred.
ClipboardSending,
/// Start libEI
/// Start libei
EIConnected,
/// Stop libEi
EISessionClosed
/// Stop libei
EISessionClosed,
};
} // namespace deskflow

View File

@ -65,29 +65,9 @@ public:
*/
virtual bool addEvent(uint32_t dataID) = 0;
//@}
//! @name accessors
//@{
//! Check if event queue buffer is empty
/*!
Return true iff the event queue buffer is empty.
*/
virtual bool isEmpty() const = 0;
//! Create a timer object
/*!
Create and return a timer object. The object is opaque and is
used only by the buffer but it must be a valid object (i.e.
not nullptr).
*/
virtual EventQueueTimer *newTimer(double duration, bool oneShot) const = 0;
//! Destroy a timer object
/*!
Destroy a timer object previously returned by \c newTimer().
*/
virtual void deleteTimer(EventQueueTimer *) const = 0;
//@}
};

View File

@ -24,11 +24,10 @@
const int kPriorityPrefixLength = 3;
// names of priorities
static const char *g_priority[] = {"FATAL", "ERROR", "WARNING", "NOTE", "INFO", "DEBUG",
"DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
static const char *g_priority[] = {"FATAL", "ERROR", "WARNING", "NOTE", "INFO", "DEBUG", "DEBUG1", "DEBUG2"};
// number of priorities
static const int g_numPriority = 11;
static const int g_numPriority = 8;
// if NDEBUG (not debug) is not specified, i.e. you're building in debug,
// then set default log level to DEBUG, otherwise the max level is INFO.

View File

@ -209,9 +209,6 @@ otherwise it expands to a call that doesn't.
#define CLOG_DEBUG CLOG_TRACE "%z\065"
#define CLOG_DEBUG1 CLOG_TRACE "%z\066"
#define CLOG_DEBUG2 CLOG_TRACE "%z\067"
#define CLOG_DEBUG3 CLOG_TRACE "%z\070"
#define CLOG_DEBUG4 CLOG_TRACE "%z\071" // char is '9'
#define CLOG_DEBUG5 CLOG_TRACE "%z\072" // char is ':'
#define LOG_IPC(...) LOG((CLOG_IPC __VA_ARGS__))
#define LOG_PRINT(...) LOG((CLOG_PRINT __VA_ARGS__))
@ -223,6 +220,3 @@ otherwise it expands to a call that doesn't.
#define LOG_DEBUG(...) LOG((CLOG_DEBUG __VA_ARGS__))
#define LOG_DEBUG1(...) LOG((CLOG_DEBUG1 __VA_ARGS__))
#define LOG_DEBUG2(...) LOG((CLOG_DEBUG2 __VA_ARGS__))
#define LOG_DEBUG3(...) LOG((CLOG_DEBUG3 __VA_ARGS__))
#define LOG_DEBUG4(...) LOG((CLOG_DEBUG4 __VA_ARGS__))
#define LOG_DEBUG5(...) LOG((CLOG_DEBUG5 __VA_ARGS__))

Some files were not shown because too many files have changed in this diff Show More