Compare commits
193 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ef5793beb | |||
| b64942e3a3 | |||
| 9de268d293 | |||
| 1f08cafffe | |||
| 9eeda33293 | |||
| 17bedb1072 | |||
| 8cca8440b7 | |||
| b2dadba6fa | |||
| 4f057d706f | |||
| 5e69657176 | |||
| 2638cce0c0 | |||
| 5eac984757 | |||
| 1bd3f5060e | |||
| 55b4cffd3f | |||
| 51ec36f23d | |||
| 58cb2b76de | |||
| 8d4a715b1c | |||
| 997d4a9473 | |||
| 0f11b61576 | |||
| 98aba612c0 | |||
| b0547f6713 | |||
| 40fefb9369 | |||
| 48e1c43a01 | |||
| d8d022e9fe | |||
| 84194cf5ef | |||
| cd5ba1382d | |||
| c84b4e3f00 | |||
| be8029deb6 | |||
| dbb9b3bf5a | |||
| 32bf9aa02a | |||
| 0891afdd63 | |||
| f7ab6aba58 | |||
| 74e8a63dcd | |||
| 475172597a | |||
| 8c30ed7a59 | |||
| 44f72a29e9 | |||
| 4db77ba2f7 | |||
| 5e29fa93ac | |||
| ce8c262a9c | |||
| 3b30065ec3 | |||
| 54483f26ba | |||
| 13ed447a93 | |||
| 74812fbf75 | |||
| bdf5a0f352 | |||
| b425b43801 | |||
| f0c60f5ca9 | |||
| b2ca9bc17b | |||
| f46474c9f2 | |||
| a99d408be1 | |||
| 19c41e2ac5 | |||
| 890fd61e6e | |||
| 1c42552b3b | |||
| a6956b9516 | |||
| 5a7f6bd1c0 | |||
| a3b0ec28fc | |||
| fa1ab27ee9 | |||
| e07a2efbcc | |||
| e967944c1e | |||
| 389028ccf9 | |||
| dc6383d593 | |||
| 1c7adf5add | |||
| 5743db3040 | |||
| 5733541b2a | |||
| 5980fb741b | |||
| 7c672b06d8 | |||
| 53038760de | |||
| d6228416a1 | |||
| 80cc323f5a | |||
| 90e63e2e9e | |||
| 24c57e46e2 | |||
| e72faf1446 | |||
| c1d7474700 | |||
| 0d2d9f385d | |||
| c0094554b1 | |||
| 95603c82ec | |||
| 8debc1ea7f | |||
| b4f703562d | |||
| 34b61cc8cd | |||
| 551e0211ac | |||
| 0fc5368253 | |||
| 383b39636e | |||
| f56a3ba305 | |||
| 0bca094fce | |||
| 220711c2d7 | |||
| 66acf9038b | |||
| aa5a704131 | |||
| bae494476b | |||
| 3ae2de52f4 | |||
| 088d69fec8 | |||
| 63744ddbd6 | |||
| 2d04e0be4d | |||
| 4f2ef7174a | |||
| 1003de21b5 | |||
| b3866b69b2 | |||
| 9bd7fce45c | |||
| f0d33ce9de | |||
| 07bf6de093 | |||
| 9c463a557a | |||
| 566d716feb | |||
| e7e518d76e | |||
| 08be9fa33f | |||
| 72d27c70e0 | |||
| 6de1920d88 | |||
| 2d3f64f662 | |||
| 193c28af53 | |||
| 5b54849fd6 | |||
| b7eb5c467b | |||
| f9b6bcc950 | |||
| 5d5e32a676 | |||
| d52939a3fc | |||
| 173e521004 | |||
| 038c8af949 | |||
| 9f68514577 | |||
| d5624ba65e | |||
| d5ee57f349 | |||
| 6a08305338 | |||
| 05ed47be2e | |||
| 29d04ea8e0 | |||
| ab118a3aa3 | |||
| 10e5a305bb | |||
| e9c8965066 | |||
| 53d2b3bd2e | |||
| d4cc66a9f9 | |||
| 18cc8565f9 | |||
| caee2b149a | |||
| e808eed413 | |||
| 16c57d7960 | |||
| 200d32db80 | |||
| 2322f312a9 | |||
| 09c157f9e1 | |||
| c9a360a144 | |||
| 3de2c1bcf0 | |||
| 73292f05c8 | |||
| 48407d7f8f | |||
| 83c190c385 | |||
| ad79ba907d | |||
| 9294f2a026 | |||
| bfb64f0653 | |||
| 6f66fe767f | |||
| 63846292ff | |||
| 2f8b78e2a6 | |||
| 8d0491f1ad | |||
| 79dc858446 | |||
| 0667f5de73 | |||
| e51956e2c7 | |||
| 60c7e512f2 | |||
| e996471e37 | |||
| 638349b48a | |||
| 3e7b14cbd4 | |||
| 3abf38aff9 | |||
| 12a56f4df0 | |||
| 9bd5fe9afb | |||
| 6ff5d2d5d3 | |||
| c04610c561 | |||
| 67e2f56724 | |||
| 5288546231 | |||
| d8e311fe59 | |||
| 500067a778 | |||
| 3c12915fd3 | |||
| eb19547b45 | |||
| 65eed64f04 | |||
| fbaa0a8433 | |||
| 743c3feef3 | |||
| d0d5182425 | |||
| 298b1047c4 | |||
| e257501072 | |||
| aaa64e986e | |||
| 7d79a4d729 | |||
| 2058519e57 | |||
| 5a71d63923 | |||
| fb32f141cc | |||
| 39da277ead | |||
| a98f2d745e | |||
| 524c3b0e7b | |||
| e420b9b986 | |||
| cb14d158cc | |||
| ac6809d40f | |||
| 92603df93d | |||
| a5f28616f4 | |||
| cad1243d75 | |||
| 610786ad2e | |||
| d093894743 | |||
| 942070950d | |||
| ddc24ffb22 | |||
| b14de6f9e2 | |||
| 10c50c9740 | |||
| 60577f00dc | |||
| fedd9d33c9 | |||
| ae30237f90 | |||
| 169422a0eb | |||
| 76fd40a3ec | |||
| 816d66b703 | |||
| 774f1fded9 |
20
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -22,12 +22,16 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
- type: textarea
|
||||
id: version
|
||||
attributes:
|
||||
label: Deskflow version number
|
||||
description: You can find the Deskflow version number on the about screen.
|
||||
placeholder: 1.2.3.4
|
||||
label: Deskflow version info
|
||||
description: You can find the Deskflow version number on the About screen.
|
||||
placeholder: |
|
||||
Deskflow: 1.2.3.4 (deadc0de)
|
||||
Qt: 3.2.1
|
||||
System: Hannah Montana Linux (Workstation Edition)
|
||||
Session: Unity (Compiz)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@ -51,7 +55,7 @@ body:
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating systems (OS)
|
||||
description: Which operating systems (OS) are you using?
|
||||
description: Operating systems (OS) in use for all servers and clients
|
||||
options:
|
||||
- label: Windows
|
||||
- label: macOS
|
||||
@ -110,8 +114,7 @@ body:
|
||||
label: Deskflow configuration
|
||||
description: |
|
||||
Please provide a very brief description of your configuration.
|
||||
Let us know the OS of the server/host/primary and the OS of the client/guest/secondary.
|
||||
This will help us understand how you're using Deskflow.
|
||||
Let us know what OS your server and client are running.
|
||||
placeholder: |
|
||||
- Windows 11 server, macOS 15 client
|
||||
- Each computer has a single monitor
|
||||
@ -122,9 +125,8 @@ body:
|
||||
attributes:
|
||||
label: What steps will reproduce the problem?
|
||||
description: |
|
||||
Please list the steps to reproduce the issue.
|
||||
Please list the _numbered steps_ to reproduce the issue.
|
||||
If you're not sure, please provide as much detail as possible.
|
||||
This will help us understand the problem.
|
||||
placeholder: |
|
||||
1. Start Deskflow
|
||||
2. Click 'Configure Server'
|
||||
|
||||
19
.github/actions/install-dependencies/action.yml
vendored
@ -9,8 +9,12 @@ inputs:
|
||||
description: "Used only on linux distro type: debian, fedora, suse, arch"
|
||||
required: false
|
||||
|
||||
mac-qt-version:
|
||||
description: "The verison of Qt to install on mac os"
|
||||
qt-version:
|
||||
description: "The version of Qt to install (Windows & macOS)"
|
||||
required: false
|
||||
|
||||
qt-install-dir:
|
||||
description: "The path to install Qt into (Windows & macOS)"
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
@ -67,13 +71,13 @@ runs:
|
||||
shell: bash
|
||||
|
||||
- name: Install Qt
|
||||
if: ${{runner.os == 'macOS' }}
|
||||
if: ${{runner.os != 'Linux' }}
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
dir: "/Users/runner"
|
||||
version: ${{inputs.mac-qt-version}}
|
||||
dir: ${{inputs.qt-install-dir}}
|
||||
version: ${{inputs.qt-version}}
|
||||
cache: true
|
||||
cache-key-prefix: ${{matrix.target.os}}-${{env.qt-version}}
|
||||
cache-key-prefix: ${{matrix.target.os}}-${{inputs.qt-version}}
|
||||
|
||||
# Install Ninja with an action instead of using Chocolatey, as it's more
|
||||
# reliable and faster. The Ninja install action is pretty good as it
|
||||
@ -87,7 +91,8 @@ runs:
|
||||
id: vcpkg
|
||||
uses: johnwason/vcpkg-action@v6
|
||||
with:
|
||||
manifest-dir: ${{ github.workspace }}
|
||||
pkgs: wintoast gtest pkgconf openssl
|
||||
extra-args: --classic
|
||||
triplet: x64-windows-release
|
||||
token: ${{ github.token }}
|
||||
github-binarycache: true
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
||||
apt install -qqq git > /dev/null
|
||||
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/install-dependencies
|
||||
|
||||
45
.github/workflows/continuous-integration.yml
vendored
@ -131,19 +131,22 @@ jobs:
|
||||
target:
|
||||
- name: "windows-2022-x64"
|
||||
runs-on: "windows-2022"
|
||||
timeout: 120 #Windows can take while if it has to build vcpkg cache
|
||||
timeout: 30
|
||||
config-args: "-G Ninja"
|
||||
qt-install-dir: "C:"
|
||||
|
||||
- name: "macos-14-arm64"
|
||||
runs-on: "macos-14"
|
||||
timeout: 10
|
||||
arch: arm64
|
||||
config-args: "-DCMAKE_OSX_ARCHITECTURES=\"arm64\""
|
||||
qt-install-dir: "/Users/runner"
|
||||
|
||||
- name: "macos-13-x64"
|
||||
runs-on: macos-13
|
||||
timeout: 20
|
||||
config-args: "-DCMAKE_OSX_ARCHITECTURES=\"x86_64\""
|
||||
qt-install-dir: "/Users/runner"
|
||||
|
||||
- name: "debian-13-x86_64"
|
||||
runs-on: ubuntu-latest
|
||||
@ -243,7 +246,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.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
# This effectively runs `vcvarsall.bat`, etc. It's not actually installing
|
||||
# VC++ as that's already pre-installed on the Windows runner.
|
||||
@ -255,7 +258,8 @@ jobs:
|
||||
id: get-deps
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
mac-qt-version: 6.7.3
|
||||
qt-version: 6.8.2
|
||||
qt-install-dir: ${{matrix.target.qt-install-dir}}
|
||||
like: ${{ matrix.target.like }}
|
||||
|
||||
- name: Get version
|
||||
@ -311,7 +315,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.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Build on FreeBSD
|
||||
if: ${{ matrix.distro.name == 'freebsd' }}
|
||||
@ -331,36 +335,45 @@ jobs:
|
||||
needs: lint-check
|
||||
name: flatpak-${{matrix.flatpak.arch}}
|
||||
runs-on: ${{matrix.flatpak.runs-on}}
|
||||
timeout-minutes: 60
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.8
|
||||
options: --privileged
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flatpak:
|
||||
- runs-on: ubuntu-latest
|
||||
arch: x86_64
|
||||
# TODO: Action does not yet provide arm image; re-enable when available
|
||||
# - runs-on: ubuntu-24.04-arm
|
||||
# arch: aarch64
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:kde-6.7
|
||||
options: --privileged
|
||||
- runs-on: ubuntu-24.04-arm
|
||||
arch: aarch64
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- run: git config --global protocol.file.allow always
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@master
|
||||
name: "Build"
|
||||
- name: Lint appsteam
|
||||
run: flatpak-builder-lint appstream deploy/linux/org.deskflow.deskflow.metainfo.xml
|
||||
|
||||
- name: Lint manifest
|
||||
run: flatpak-builder-lint manifest deploy/linux/flatpak/org.deskflow.deskflow.yml
|
||||
|
||||
- name: Build
|
||||
uses: flathub-infra/flatpak-github-actions/flatpak-builder@53987ffa5f687586936d85fdce3f440848bea04d
|
||||
with:
|
||||
bundle: deskflow-${{env.DESKFLOW_PACKAGE_VERSION}}-linux-${{matrix.flatpak.arch}}.flatpak
|
||||
manifest-path: deploy/linux/flatpak/org.deskflow.deskflow.yml
|
||||
cache-key: flatpak-builder-${{matrix.flatpak.arch}}-1.0
|
||||
cache-key: flatpak-builder-${{matrix.flatpak.arch}}-2.0
|
||||
arch: ${{matrix.flatpak.arch}}
|
||||
upload-artifact: false
|
||||
|
||||
- name: Validate build
|
||||
run: flatpak-builder-lint --exceptions --user-exceptions deploy/linux/flatpak/ci-build-lint-exceptions.json repo repo
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -374,7 +387,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
@ -419,7 +432,7 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
2
.github/workflows/sonarcloud-analysis.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
apt install -qqq git curl unzip gcovr > /dev/null
|
||||
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Install project dependencies
|
||||
uses: ./.github/actions/install-dependencies
|
||||
|
||||
2
.github/workflows/valgrind-analysis.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
apt install -qqq git valgrind > /dev/null
|
||||
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
uses: sithlord48/fancy-checkout@v1
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/install-dependencies
|
||||
|
||||
@ -18,7 +18,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Fallback for when git can not be found
|
||||
set(DESKFLOW_VERSION_MAJOR 1)
|
||||
set(DESKFLOW_VERSION_MINOR 19)
|
||||
set(DESKFLOW_VERSION_MINOR 20)
|
||||
set(DESKFLOW_VERSION_PATCH 0)
|
||||
set(DESKFLOW_VERSION_TWEAK 0)
|
||||
|
||||
|
||||
@ -167,6 +167,8 @@ who is the author of `libei`, a major contributor to `libportal`, and the author
|
||||
implementation in Deskflow. Others such as Olivier Fourdan and Povilas Kanapickas helped with the
|
||||
Wayland implementation.
|
||||
|
||||
Some features _may_ be unavailable or broken on Wayland. Please see the [known Wayland issues](https://github.com/deskflow/deskflow/discussions/7499).
|
||||
|
||||
### Where did it all start?
|
||||
|
||||
Deskflow was first created as Synergy in 2001 by Chris Schoeneman.
|
||||
|
||||
@ -48,6 +48,12 @@ precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "SECURITY.md"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "sonar-project.properties"
|
||||
precedence = "override"
|
||||
@ -91,7 +97,7 @@ SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "GPL-2.0-only"
|
||||
|
||||
[[annotations]]
|
||||
path = "deploy/linux/flatpak/org.deskflow.deskflow.yml"
|
||||
path = "deploy/linux/flatpak/**"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
11
SECURITY.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
The latest minor release is supported and receives security updates:
|
||||
https://github.com/deskflow/deskflow/releases
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report vulnerabilities on our issue tracker as bugs:
|
||||
https://github.com/deskflow/deskflow/issues
|
||||
@ -45,20 +45,6 @@ macro(configure_libs)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL ${REQUIRED_OPENSSL_VERSION} REQUIRED COMPONENTS SSL Crypto)
|
||||
if(WIN32) #Used for dev in TLS and WIX
|
||||
cmake_path(SET OPENSSL_ROOT_DIR NORMALIZE "${OPENSSL_INCLUDE_DIR}/..")
|
||||
message(VERBOSE "Set OPENSSL_ROOT_DIR: ${OPENSSL_ROOT_DIR}")
|
||||
set(OPENSSL_EXE_DIR "${OPENSSL_ROOT_DIR}/tools/openssl")
|
||||
add_definitions(-DOPENSSL_EXE_DIR="${OPENSSL_EXE_DIR}")
|
||||
# HACK Install a copy of openssl on windows
|
||||
install(
|
||||
FILES
|
||||
${OPENSSL_EXE_DIR}/openssl.exe
|
||||
${OPENSSL_EXE_DIR}/openssl.cnf
|
||||
DESTINATION .
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
option(ENABLE_COVERAGE "Enable test coverage" OFF)
|
||||
if(ENABLE_COVERAGE)
|
||||
|
||||
10
cspell.json
@ -11,9 +11,10 @@
|
||||
"codesigning",
|
||||
"Compat",
|
||||
"contribs",
|
||||
"daemonized",
|
||||
"Daun",
|
||||
"Devs",
|
||||
"Deskflow",
|
||||
"Devs",
|
||||
"distro",
|
||||
"distros",
|
||||
"dmgbuild",
|
||||
@ -24,6 +25,7 @@
|
||||
"gdrive",
|
||||
"Hadzhylov",
|
||||
"Hetu",
|
||||
"HINSTANCE",
|
||||
"hotspots",
|
||||
"Hutterer",
|
||||
"ifdef",
|
||||
@ -39,6 +41,7 @@
|
||||
"Libera",
|
||||
"libportal",
|
||||
"LLDB",
|
||||
"logonui",
|
||||
"Lysytsia",
|
||||
"macdeployqt",
|
||||
"msvc",
|
||||
@ -48,6 +51,8 @@
|
||||
"Oleksandr",
|
||||
"Olena",
|
||||
"outputdir",
|
||||
"outputter",
|
||||
"outputters",
|
||||
"pacman",
|
||||
"Petroules",
|
||||
"Pixmap",
|
||||
@ -57,6 +62,7 @@
|
||||
"Priddy",
|
||||
"psutil",
|
||||
"pyproject",
|
||||
"qobject",
|
||||
"qputenv",
|
||||
"readf",
|
||||
"Regen",
|
||||
@ -67,9 +73,11 @@
|
||||
"Schoeneman",
|
||||
"Serhii",
|
||||
"shemp",
|
||||
"SNAPPROCESS",
|
||||
"Sorin",
|
||||
"subproject",
|
||||
"subprojects",
|
||||
"Toolhelp",
|
||||
"trackpad",
|
||||
"Trixie",
|
||||
"unittests",
|
||||
|
||||
6
deploy/linux/flatpak/ci-build-lint-exceptions.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"org.deskflow.deskflow": [
|
||||
"appstream-external-screenshot-url",
|
||||
"appstream-screenshots-not-mirrored-in-ostree"
|
||||
]
|
||||
}
|
||||
@ -4,7 +4,9 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0+</project_license>
|
||||
<name>Deskflow</name>
|
||||
<developer_name>Deskflow Developers</developer_name>
|
||||
<developer id="org.deskflow">
|
||||
<name>Deskflow Developers</name>
|
||||
</developer>
|
||||
<summary>Software Keyboard and mouse sharing</summary>
|
||||
<description>
|
||||
<p>
|
||||
@ -16,7 +18,12 @@
|
||||
<url type="bugtracker">https://github.com/deskflow/deskflow/issues</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://github.com/user-attachments/assets/883660dc-f3f5-4b69-8821-a079a58d3882</image>
|
||||
<image>https://deskflow.org/screenshots/deskflow.png</image>
|
||||
<caption>Deskflow's mainwindow on KDE</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://deskflow.org/screenshots/deskflow-dark.png</image>
|
||||
<caption>Deskflow's mainwindow on KDE (dark mode)</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<provides> <id>org.deskflow.deskflow.desktop</id> </provides>
|
||||
@ -35,9 +42,25 @@
|
||||
</branding>
|
||||
<content_rating type="oars-1.0" />
|
||||
<releases>
|
||||
<release version="1.20.0" date="2025-3-03" urgency="high">
|
||||
<description>
|
||||
<p>This stable release fixes a few security issues, additionally fixes several bugs and adds a few new features. For the full changelog see the release page.</p>
|
||||
<ul>
|
||||
<li>Feature: Peer Id Checking - Fixes CVE-2021-42072 and CVE-2021-42073</li>
|
||||
<li>Feature: Use Sha256 fingerprints</li>
|
||||
<li>Feature: Gui cleanup and improvements</li>
|
||||
<li>Remove: Inverse connection option</li>
|
||||
<li>Fix: Screen Corner option</li>
|
||||
<li>Fix: Show new client dialog</li>
|
||||
<li>Win32: Daemon Improvements</li>
|
||||
<li>Win32: Fix clear settings</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.20.0</url>
|
||||
</release>
|
||||
<release version="1.19.0" date="2025-1-31" urgency="high">
|
||||
<description>
|
||||
<p>This stable Release fixes several bugs and adds a few new features. For the full changelog see the release page.</p>
|
||||
<p>This stable release fixes several bugs and adds a few new features. For the full changelog see the release page.</p>
|
||||
<ul>
|
||||
<li>Feature: New Fallback icon theme</li>
|
||||
<li>Feature: Allow only one gui instance</li>
|
||||
@ -57,7 +80,7 @@
|
||||
</release>
|
||||
<release version="1.18.0" date="2024-12-26" urgency="high">
|
||||
<description>
|
||||
<p>This stable Release Fixes a few security issues, additionally fixes several bugs and adds a few new features. For the full changelog see the release page.</p>
|
||||
<p>This stable release fixes a few security issues, additionally fixes several bugs and adds a few new features. For the full changelog see the release page.</p>
|
||||
<ul>
|
||||
<li>Fix CVE-2021-42075: Close connection on app-level handshake failure</li>
|
||||
<li>Fix CVE-2021-42074: Handle SSL race conditions and segmentation fault</li>
|
||||
@ -130,7 +153,7 @@
|
||||
</release>
|
||||
<release version="1.17.1" date="2024-11-7" urgency="high">
|
||||
<description>
|
||||
<p>This stable Release Has a very long chagelog some notable ones are.</p>
|
||||
<p>This stable release has a very long changelog some notable ones are.</p>
|
||||
<ul>
|
||||
<li>Remove word 'beta' from Wayland message</li>
|
||||
<li>docs: Update `README.md` with Matrix link</li>
|
||||
@ -247,7 +270,7 @@
|
||||
</release>
|
||||
<release version="1.17.0" date="2024-10-02" urgency="low">
|
||||
<description>
|
||||
<p>This is the first Deskflow Release.</p>
|
||||
<p>This is the first Deskflow release.</p>
|
||||
<ul>
|
||||
<li>Use Deskflow Name</li>
|
||||
<li>fix: windows build typos</li>
|
||||
|
||||
@ -6,7 +6,10 @@ sonar.exclusions=subprojects/**,build/**
|
||||
sonar.coverage.exclusions=subprojects/**,src/test/**,src/apps/deskflow-gui/**,src/apps/res/**
|
||||
sonar.cpd.exclusions=**/*Test*.cpp
|
||||
sonar.host.url=https://sonarcloud.io
|
||||
sonar.coverageReportPaths=${{ steps.coverage-paths.outputs.csv }}
|
||||
sonar.cfamily.compile-commands=build/compile_commands.json
|
||||
sonar.cfamily.threads=${{ env.CPU_CORE_COUNT }}
|
||||
sonar.python.version=3.10
|
||||
|
||||
# Allow use of `new` which is idiomatic for Qt code.
|
||||
sonar.issue.ignore.multicriteria=e1
|
||||
sonar.issue.ignore.multicriteria.e1.ruleKey=cpp:S5025
|
||||
sonar.issue.ignore.multicriteria.e1.resourceKey=**
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
|
||||
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
|
||||
# SPDX-License-Identifier: MIT
|
||||
@ -7,7 +7,7 @@ set(target ${CMAKE_PROJECT_NAME}-client)
|
||||
|
||||
if(WIN32)
|
||||
# Generate rc file
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n CLI client application")
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_PROPER_NAME} client application")
|
||||
|
||||
set(EXE_ICON "
|
||||
IDI_DESKFLOW ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
|
||||
@ -32,14 +32,17 @@ target_link_libraries(
|
||||
io
|
||||
mt
|
||||
net
|
||||
ipc
|
||||
platform
|
||||
server
|
||||
app
|
||||
${libs})
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks"
|
||||
RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS
|
||||
)
|
||||
elseif(UNIX)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
elseif(WIN32)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
|
||||
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
|
||||
# SPDX-License-Identifier: MIT
|
||||
@ -8,11 +8,13 @@ set(target ${CMAKE_PROJECT_NAME}-core)
|
||||
add_executable(${target} "${target}.cpp")
|
||||
if(WIN32)
|
||||
# Generate rc file
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n CLI combined server and client")
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_PROPER_NAME} combined server and client application")
|
||||
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)
|
||||
|
||||
target_sources(${target} PRIVATE
|
||||
"${target}.exe.manifest"
|
||||
${target}.exe.manifest
|
||||
${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${target}.rc
|
||||
)
|
||||
endif()
|
||||
@ -25,14 +27,17 @@ target_link_libraries(
|
||||
io
|
||||
mt
|
||||
net
|
||||
ipc
|
||||
platform
|
||||
server
|
||||
app
|
||||
${libs})
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks"
|
||||
RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS
|
||||
)
|
||||
elseif(UNIX)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
elseif(WIN32)
|
||||
|
||||
@ -11,17 +11,18 @@
|
||||
#include "base/Log.h"
|
||||
#include "deskflow/ClientApp.h"
|
||||
#include "deskflow/ServerApp.h"
|
||||
#include <iostream>
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void showHelp()
|
||||
{
|
||||
std::cout << "Usage: " CORE_BINARY_NAME " <server | client> [...options]" << std::endl;
|
||||
std::cout << "server - start as a server ( deskflow-server)" << std::endl;
|
||||
std::cout << "client - start as a client ( deslflow-client)" << std::endl;
|
||||
std::cout << "Usage: deskflow-core <server | client> [...options]" << std::endl;
|
||||
std::cout << "server - start as a server (deskflow-server)" << std::endl;
|
||||
std::cout << "client - start as a client (deskflow-client)" << std::endl;
|
||||
std::cout << "use deskflow-core <server|client> --help for more information." << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@ -8,22 +8,25 @@ if(WIN32)
|
||||
set(target ${CMAKE_PROJECT_NAME}-daemon)
|
||||
|
||||
# Generate rc file
|
||||
set(EXE_DESCRIPTION "This service runs in the background to help ${CMAKE_PROJECT_NAME} deal with UAC prompts")
|
||||
set(EXE_DESCRIPTION "Windows service to run ${CMAKE_PROJECT_NAME} in secure desktops (UAC prompts, login screen, etc)")
|
||||
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)
|
||||
|
||||
find_package(Qt6 COMPONENTS Core Network)
|
||||
|
||||
target_link_libraries(
|
||||
${target}
|
||||
arch
|
||||
base
|
||||
io
|
||||
ipc
|
||||
mt
|
||||
net
|
||||
platform
|
||||
app
|
||||
${libs})
|
||||
${libs}
|
||||
Qt6::Core)
|
||||
|
||||
install(
|
||||
TARGETS ${target}
|
||||
|
||||
@ -1,31 +1,143 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016, 2025 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2012 Nick Bolton
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
#include "deskflow/DaemonApp.h"
|
||||
#include "deskflow/ipc/DaemonIpcServer.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "arch/Arch.h"
|
||||
#include "base/EventQueue.h"
|
||||
#include "base/Log.h"
|
||||
|
||||
#ifdef SYSAPI_UNIX
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
DaemonApp app;
|
||||
return app.run(argc, argv);
|
||||
}
|
||||
|
||||
#elif SYSAPI_WIN32
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
using namespace deskflow::core;
|
||||
|
||||
void handleError(const char *message);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
// Save window instance for later use, e.g. `GetModuleFileName` which is used when installing the daemon.
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(nullptr));
|
||||
#endif
|
||||
|
||||
Arch arch;
|
||||
arch.init();
|
||||
|
||||
Log log;
|
||||
EventQueue events;
|
||||
|
||||
LOG((CLOG_PRINT "%s daemon (v%s)", kAppName, kVersion));
|
||||
|
||||
auto &daemon = DaemonApp::instance();
|
||||
DaemonApp::InitResult initResult;
|
||||
try {
|
||||
initResult = daemon.init(&events, argc, argv);
|
||||
} catch (std::exception &e) {
|
||||
handleError(e.what());
|
||||
return kExitFailed;
|
||||
} catch (...) {
|
||||
handleError("Unrecognized error.");
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
switch (initResult) {
|
||||
using enum DaemonApp::InitResult;
|
||||
|
||||
case StartDaemon: {
|
||||
LOG_INFO("starting daemon");
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
QThread daemonThread;
|
||||
daemon.moveToThread(&daemonThread);
|
||||
|
||||
QObject::connect(&daemonThread, &QThread::started, [&daemon, &daemonThread]() {
|
||||
LOG_DEBUG("daemon thread started");
|
||||
daemon.run();
|
||||
daemonThread.quit();
|
||||
LOG_DEBUG("daemon thread finished");
|
||||
});
|
||||
QObject::connect(&daemonThread, &QThread::finished, &app, &QCoreApplication::quit);
|
||||
|
||||
ipc::DaemonIpcServer ipcServer(&app, QString::fromStdString(daemon.logFilename()));
|
||||
|
||||
// Use direct connection as the daemon app is on it's own thread, and so is on a different event loop.
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::logLevelChanged, &daemon, &DaemonApp::saveLogLevel, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, &daemon, &DaemonApp::setElevate, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::commandChanged, &daemon, &DaemonApp::setCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::startProcessRequested, &daemon, &DaemonApp::applyWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::stopProcessRequested, &daemon, &DaemonApp::clearWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::clearSettingsRequested, &daemon, &DaemonApp::clearSettings, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
|
||||
daemonThread.start();
|
||||
const auto exitCode = QCoreApplication::exec();
|
||||
daemonThread.wait();
|
||||
|
||||
LOG_DEBUG("daemon exited, code: %d", exitCode);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
case FatalError:
|
||||
return kExitFailed;
|
||||
|
||||
default:
|
||||
return kExitSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
// 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)
|
||||
{
|
||||
DaemonApp app;
|
||||
return app.run(__argc, __argv);
|
||||
return main(__argc, __argv);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void handleError(const char *message)
|
||||
{
|
||||
// Always print error to stdout in case run as CLI program.
|
||||
LOG_ERR("%s", message);
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
// Show a message box for when run from MSI in Win32 subsystem.
|
||||
MessageBoxA(nullptr, message, "Deskflow daemon error", MB_OK | MB_ICONERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
if(WIN32)
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n Control and configure deskflow")
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_PROPER_NAME} GUI configuration tool")
|
||||
set(EXE_ICON "IDI_ICON1 ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\" ")
|
||||
configure_file(${CMAKE_SOURCE_DIR}/src/apps/res/windows.rc.in deskflow.rc)
|
||||
set(platform_extra deskflow.rc)
|
||||
@ -67,8 +67,6 @@ add_executable(${target} WIN32 MACOSX_BUNDLE
|
||||
ScreenSetupModel.h
|
||||
ServerConfig.cpp
|
||||
ServerConfig.h
|
||||
SetupWizard.cpp
|
||||
SetupWizard.h
|
||||
VersionChecker.cpp
|
||||
VersionChecker.h
|
||||
dialogs/AboutDialog.cpp
|
||||
@ -80,6 +78,8 @@ add_executable(${target} WIN32 MACOSX_BUNDLE
|
||||
dialogs/AddClientDialog.cpp
|
||||
dialogs/AddClientDialog.h
|
||||
dialogs/AddClientDialog.ui
|
||||
dialogs/FingerprintDialog.h
|
||||
dialogs/FingerprintDialog.cpp
|
||||
dialogs/HotkeyDialog.cpp
|
||||
dialogs/HotkeyDialog.h
|
||||
dialogs/HotkeyDialog.ui
|
||||
@ -92,16 +92,14 @@ add_executable(${target} WIN32 MACOSX_BUNDLE
|
||||
dialogs/SettingsDialog.cpp
|
||||
dialogs/SettingsDialog.h
|
||||
dialogs/SettingsDialog.ui
|
||||
widgets/ClientStateLabel.cpp
|
||||
widgets/ClientStateLabel.h
|
||||
widgets/FingerprintPreview.h
|
||||
widgets/FingerprintPreview.cpp
|
||||
widgets/KeySequenceWidget.cpp
|
||||
widgets/KeySequenceWidget.h
|
||||
widgets/NewScreenWidget.h
|
||||
widgets/NewScreenWidget.cpp
|
||||
widgets/ScreenSetupView.cpp
|
||||
widgets/ScreenSetupView.h
|
||||
widgets/ServerStateLabel.cpp
|
||||
widgets/ServerStateLabel.h
|
||||
widgets/TrashScreenWidget.cpp
|
||||
widgets/TrashScreenWidget.h
|
||||
)
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
#include <QMainWindow>
|
||||
#include <QMutex>
|
||||
#include <QProcess>
|
||||
#include <QRegularExpression>
|
||||
#include <QSettings>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QThread>
|
||||
|
||||
#include "ServerConfig.h"
|
||||
#include "VersionChecker.h"
|
||||
#include "common/ipc.h"
|
||||
#include "gui/config/AppConfig.h"
|
||||
#include "gui/config/ConfigScopes.h"
|
||||
#include "gui/config/ServerConfigDialogState.h"
|
||||
@ -33,12 +33,14 @@
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QGroupBox;
|
||||
class QPushButton;
|
||||
class QTextEdit;
|
||||
class QComboBox;
|
||||
class QTabWidget;
|
||||
class QToolButton;
|
||||
class QCheckBox;
|
||||
class QRadioButton;
|
||||
class QMessageBox;
|
||||
@ -46,12 +48,15 @@ class QAbstractButton;
|
||||
class QLocalServer;
|
||||
|
||||
class DeskflowApplication;
|
||||
class SetupWizard;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
namespace deskflow::gui::ipc {
|
||||
class DaemonIpcClient;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
using CoreMode = deskflow::gui::CoreProcess::Mode;
|
||||
@ -60,7 +65,6 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
|
||||
friend class DeskflowApplication;
|
||||
friend class SetupWizard;
|
||||
friend class SettingsDialog;
|
||||
|
||||
public:
|
||||
@ -76,13 +80,13 @@ public:
|
||||
|
||||
CoreMode coreMode() const
|
||||
{
|
||||
return m_CoreProcess.mode();
|
||||
return m_coreProcess.mode();
|
||||
}
|
||||
QString address() const;
|
||||
void open();
|
||||
ServerConfig &serverConfig()
|
||||
{
|
||||
return m_ServerConfig;
|
||||
return m_serverConfig;
|
||||
}
|
||||
void autoAddScreen(const QString name);
|
||||
|
||||
@ -91,28 +95,25 @@ public:
|
||||
signals:
|
||||
void shown();
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void toggleLogVisible(bool visible);
|
||||
//
|
||||
// Manual slots
|
||||
//
|
||||
void onShown();
|
||||
void onConfigScopesSaving();
|
||||
void onAppConfigTlsChanged();
|
||||
void onAppConfigScreenNameChanged();
|
||||
void onAppConfigInvertConnection();
|
||||
void onCoreProcessStarting();
|
||||
void onCoreProcessError(CoreProcess::Error error);
|
||||
void onCoreConnectionStateChanged(CoreProcess::ConnectionState state);
|
||||
void onCoreProcessStateChanged(CoreProcess::ProcessState state);
|
||||
void onCoreProcessSecureSocket(bool enabled);
|
||||
void onVersionCheckerUpdateFound(const QString &version);
|
||||
void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void onServerConnectionConfigureClient(const QString &clientName);
|
||||
|
||||
void firstShown();
|
||||
|
||||
void configScopesSaving();
|
||||
void appConfigTlsChanged();
|
||||
void coreProcessStarting();
|
||||
void coreProcessError(CoreProcess::Error error);
|
||||
void coreConnectionStateChanged(CoreProcess::ConnectionState state);
|
||||
void coreProcessStateChanged(CoreProcess::ProcessState state);
|
||||
void versionCheckerUpdateFound(const QString &version);
|
||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void serverConnectionConfigureClient(const QString &clientName);
|
||||
|
||||
void clearSettings();
|
||||
void openAboutDialog();
|
||||
void openHelpUrl() const;
|
||||
void openGetNewVersionUrl() const;
|
||||
void openSettings();
|
||||
void startCore();
|
||||
void stopCore();
|
||||
@ -122,20 +123,21 @@ private slots:
|
||||
void resetCore();
|
||||
|
||||
void showMyFingerprint();
|
||||
void setModeServer();
|
||||
void setModeClient();
|
||||
void updateSecurityIcon(bool visible);
|
||||
|
||||
void coreModeToggled();
|
||||
void updateModeControls(bool serverMode);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::MainWindow> ui;
|
||||
|
||||
void updateSize();
|
||||
AppConfig &appConfig()
|
||||
{
|
||||
return m_AppConfig;
|
||||
return m_appConfig;
|
||||
}
|
||||
AppConfig const &appConfig() const
|
||||
{
|
||||
return m_AppConfig;
|
||||
return m_appConfig;
|
||||
}
|
||||
void createMenuBar();
|
||||
void setupTrayIcon();
|
||||
@ -143,7 +145,6 @@ private:
|
||||
void setIcon();
|
||||
bool checkForApp(int which, QString &app);
|
||||
void setStatus(const QString &status);
|
||||
void sendIpcMessage(IpcMessageType type, const char *buffer, bool showErrors);
|
||||
void updateFromLogLine(const QString &line);
|
||||
QString getIPAddresses() const;
|
||||
void enableServer(bool enable);
|
||||
@ -168,26 +169,53 @@ private:
|
||||
void showFirstConnectedMessage();
|
||||
void updateStatus();
|
||||
void showAndActivate();
|
||||
void showHostNameEditor();
|
||||
void setHostName();
|
||||
|
||||
VersionChecker m_VersionChecker;
|
||||
QSystemTrayIcon *m_trayIcon = nullptr;
|
||||
QAbstractButton *m_pCancelButton = nullptr;
|
||||
bool m_SecureSocket = false;
|
||||
deskflow::gui::config::ServerConfigDialogState m_ServerConfigDialogState;
|
||||
bool m_SaveOnExit = true;
|
||||
deskflow::gui::core::WaylandWarnings m_WaylandWarnings;
|
||||
QString getTlsPath();
|
||||
|
||||
deskflow::gui::ConfigScopes &m_ConfigScopes;
|
||||
AppConfig &m_AppConfig;
|
||||
ServerConfig m_ServerConfig;
|
||||
deskflow::gui::CoreProcess m_CoreProcess;
|
||||
deskflow::gui::ServerConnection m_ServerConnection;
|
||||
deskflow::gui::ClientConnection m_ClientConnection;
|
||||
deskflow::gui::TlsUtility m_TlsUtility;
|
||||
QSize m_expandedSize = QSize();
|
||||
/**
|
||||
* @brief localFingerprintDb
|
||||
* @return The path to the local fingerprint file
|
||||
*/
|
||||
QString localFingerprintDb();
|
||||
|
||||
/**
|
||||
* @brief trustedFingerprintDb get the fingerprintDb for the trusted clients or trusted servers.
|
||||
* @return The path to the trusted fingerprint file
|
||||
*/
|
||||
QString trustedFingerprintDb();
|
||||
|
||||
// Generate prints if they are missing
|
||||
// Returns true if successful
|
||||
bool regenerateLocalFingerprints();
|
||||
|
||||
QLocalServer *m_guiDupeChecker = nullptr;
|
||||
inline static const auto m_guiSocketName = QStringLiteral("deskflow-gui");
|
||||
inline static const auto m_nameRegEx = QRegularExpression(QStringLiteral("^[\\w\\-_\\.]{0,255}$"));
|
||||
|
||||
VersionChecker m_versionChecker;
|
||||
bool m_secureSocket = false;
|
||||
deskflow::gui::config::ServerConfigDialogState m_serverConfigDialogState;
|
||||
bool m_saveOnExit = true;
|
||||
deskflow::gui::core::WaylandWarnings m_waylandWarnings;
|
||||
deskflow::gui::ConfigScopes &m_configScopes;
|
||||
AppConfig &m_appConfig;
|
||||
ServerConfig m_serverConfig;
|
||||
deskflow::gui::CoreProcess m_coreProcess;
|
||||
deskflow::gui::ServerConnection m_serverConnection;
|
||||
deskflow::gui::ClientConnection m_clientConnection;
|
||||
deskflow::gui::TlsUtility m_tlsUtility;
|
||||
QSize m_expandedSize = QSize();
|
||||
QStringList m_checkedClients;
|
||||
QStringList m_checkedServers;
|
||||
QSystemTrayIcon *m_trayIcon = nullptr;
|
||||
QLocalServer *m_guiDupeChecker = nullptr;
|
||||
deskflow::gui::ipc::DaemonIpcClient *m_daemonIpcClient = nullptr;
|
||||
|
||||
QLabel *m_lblSecurityStatus = nullptr;
|
||||
QLabel *m_lblStatus = nullptr;
|
||||
QToolButton *m_btnFingerprint = nullptr;
|
||||
QPushButton *m_btnUpdate = nullptr;
|
||||
|
||||
// Window Actions
|
||||
QAction *m_actionAbout = nullptr;
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>883</width>
|
||||
<height>690</height>
|
||||
<width>730</width>
|
||||
<height>520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -19,62 +19,129 @@
|
||||
<property name="windowTitle">
|
||||
<string>Deskflow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_pWidgetTopLevel">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<widget class="QWidget" name="topLevelWidget">
|
||||
<layout class="QVBoxLayout" name="_2">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="m_layoutName">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SizeConstraint::SetMinAndMaxSize</enum>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblComputerName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">This computer's name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="m_pSpacerUpdate">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelUpdate">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">m_pLabelUpdate</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelComputerName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">This computer's name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblComputerName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>lblName</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEditName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Name can't have have spaces or special characters</p><p>Use Enter to save the name change.</p></body></html></string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnEditName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Edit Computer Name</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="document-edit"/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelIpAddresses">
|
||||
<widget class="QLabel" name="lblIpAddresses">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -90,23 +157,176 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblMyFingerprint">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>TLS enabled (<a href="#"><span style=" text-decoration: underline; color:#4285f4;">fingerprint</span></a>)</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetModeSelection" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbModeServer">
|
||||
<property name="text">
|
||||
<string>Use this computer's keyboard and mouse
|
||||
(make this computer the server)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbModeClient">
|
||||
<property name="text">
|
||||
<string>Use another computer’s mouse and keyboard
|
||||
(make this computer the client)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetModeOptions" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QWidget" name="serverOptions" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConfigureServer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Configure Server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblNoMode">
|
||||
<property name="text">
|
||||
<string>You must select a mode</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="clientOptions" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelServerName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Server IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineHostname">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Hostname or IP address of the server computer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConnect">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetModes" native="true">
|
||||
<widget class="QWidget" name="widgetModes" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -129,308 +349,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupServer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetServerRadio" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbModeServer">
|
||||
<property name="text">
|
||||
<string>Use this computer's keyboard and mouse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>(make this computer the server)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetServer" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutServer">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetServerInput" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutServerInverse">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelClientIp">
|
||||
<property name="text">
|
||||
<string>Client IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineClientIp"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConnectToClient">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="deskflow::gui::widgets::ServerStateLabel" name="m_pLabelServerState">
|
||||
<property name="text">
|
||||
<string>No clients connected</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="spacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConfigureServer">
|
||||
<property name="text">
|
||||
<string>&Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupClient">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetClientRadio" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbModeClient">
|
||||
<property name="text">
|
||||
<string>Use another computer’s mouse and keyboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>(make this computer the client)</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||
<widget class="QWidget" name="m_pWidgetClientInput" native="true">
|
||||
<layout class="QVBoxLayout" name="m_pLayoutClient">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelServerName">
|
||||
<property name="text">
|
||||
<string>Server IP address or hostname:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineHostname">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Hostname or IP address of the server computer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConnect">
|
||||
<property name="text">
|
||||
<string>Connect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="deskflow::gui::widgets::ClientStateLabel" name="m_pLabelClientState">
|
||||
<property name="text">
|
||||
<string>Connected to server</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -443,22 +361,19 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
<enum>QFrame::Shadow::Plain</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="_4">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SizeConstraint::SetMinAndMaxSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnToggleLog">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -480,6 +395,39 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnApplySettings">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnToggleCore">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@ -496,9 +444,6 @@
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::LineWrapMode::NoWrap</enum>
|
||||
</property>
|
||||
@ -513,140 +458,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="m_pLayoutActions">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblConnectionSecurityStatus">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pStatusLabel">
|
||||
<property name="text">
|
||||
<string>Ready</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelNotice">
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">m_pLabelNotice</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnApplySettings">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnToggleCore">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>deskflow::gui::widgets::ServerStateLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/ServerStateLabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>deskflow::gui::widgets::ClientStateLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/ClientStateLabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>rbModeServer</tabstop>
|
||||
<tabstop>lineClientIp</tabstop>
|
||||
<tabstop>btnConnectToClient</tabstop>
|
||||
<tabstop>btnConfigureServer</tabstop>
|
||||
<tabstop>rbModeClient</tabstop>
|
||||
<tabstop>lineHostname</tabstop>
|
||||
<tabstop>btnConnect</tabstop>
|
||||
<tabstop>btnToggleLog</tabstop>
|
||||
<tabstop>textLog</tabstop>
|
||||
<tabstop>btnApplySettings</tabstop>
|
||||
<tabstop>btnToggleCore</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
@ -130,10 +131,6 @@ void ServerConfig::commit()
|
||||
settings().setValue("clipboardSharing", clipboardSharing());
|
||||
settings().setValue("clipboardSharingSize", QVariant::fromValue(clipboardSharingSize()));
|
||||
|
||||
if (!getClientAddress().isEmpty()) {
|
||||
settings().setValue("clientAddress", getClientAddress());
|
||||
}
|
||||
|
||||
writeSettings(settings(), switchCorners(), "switchCorner");
|
||||
|
||||
settings().beginWriteArray("screens");
|
||||
@ -186,9 +183,8 @@ void ServerConfig::recall()
|
||||
settings().value("clipboardSharingSize", (int)ServerConfig::defaultClipboardSharingSize()).toULongLong()
|
||||
);
|
||||
setClipboardSharing(settings().value("clipboardSharing", true).toBool());
|
||||
setClientAddress(settings().value("clientAddress", "").toString());
|
||||
|
||||
readSettings(settings(), switchCorners(), "switchCorner", 0, static_cast<int>(NumSwitchCorners));
|
||||
readSettings(settings(), switchCorners(), "switchCorner", false, static_cast<int>(NumSwitchCorners));
|
||||
|
||||
int numScreens = settings().beginReadArray("screens");
|
||||
Q_ASSERT(numScreens <= screens().size());
|
||||
@ -293,11 +289,6 @@ QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config)
|
||||
outStream << "\t"
|
||||
<< "clipboardSharingSize = " << config.clipboardSharingSize() << Qt::endl;
|
||||
|
||||
if (!config.getClientAddress().isEmpty()) {
|
||||
outStream << "\t"
|
||||
<< "clientAddress = " << config.getClientAddress() << Qt::endl;
|
||||
}
|
||||
|
||||
if (config.hasSwitchDelay())
|
||||
outStream << "\t"
|
||||
<< "switchDelay = " << config.switchDelay() << Qt::endl;
|
||||
@ -545,24 +536,6 @@ size_t ServerConfig::setClipboardSharingSize(size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
void ServerConfig::setClientAddress(const QString &address)
|
||||
{
|
||||
if (m_pAppConfig->invertConnection()) {
|
||||
m_ClientAddress = address;
|
||||
}
|
||||
}
|
||||
|
||||
QString ServerConfig::getClientAddress() const
|
||||
{
|
||||
QString clientAddress;
|
||||
|
||||
if (m_pAppConfig->invertConnection()) {
|
||||
clientAddress = m_ClientAddress.trimmed();
|
||||
}
|
||||
|
||||
return clientAddress;
|
||||
}
|
||||
|
||||
QSettingsProxy &ServerConfig::settings()
|
||||
{
|
||||
return m_pAppConfig->scopes().activeSettings();
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "SetupWizard.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "common/constants.h"
|
||||
#include "gui/config/AppConfig.h"
|
||||
#include "gui/styles.h"
|
||||
#include "gui/validators/ScreenNameValidator.h"
|
||||
#include "gui/validators/ValidationError.h"
|
||||
|
||||
SetupWizard::SetupWizard(AppConfig &appConfig)
|
||||
: m_appConfig{appConfig},
|
||||
m_lblError{new QLabel(this)},
|
||||
m_lineName{new QLineEdit(this)},
|
||||
m_btnApply{new QPushButton(tr("Continue"), this)}
|
||||
{
|
||||
setWindowTitle(tr("Setup %1").arg(kAppName));
|
||||
|
||||
setFixedSize(740, 550);
|
||||
|
||||
auto headerFont = QFont(QStringLiteral("Cantarell"), 18, 600);
|
||||
|
||||
auto labelTitle = new QLabel(this);
|
||||
labelTitle->setFont(headerFont);
|
||||
labelTitle->setText(tr("Name your computer"));
|
||||
labelTitle->setAlignment(Qt::AlignHCenter | Qt::AlignHCenter);
|
||||
|
||||
auto labelName = new QLabel(this);
|
||||
labelName->setText(tr("Computer Name"));
|
||||
|
||||
auto formLayout = new QFormLayout();
|
||||
formLayout->addRow(labelName, m_lineName);
|
||||
formLayout->addWidget(m_lblError);
|
||||
formLayout->addWidget(new QLabel(tr("Call your computer something short and meaningful, but it must have:"), this));
|
||||
formLayout->addWidget(new QLabel(tr("\t⬤ No spaces"), this));
|
||||
formLayout->addWidget(new QLabel(tr("\t⬤ Only these special characters: _ - ."), this));
|
||||
formLayout->addWidget(new QLabel(tr("\t⬤ Only English characters and numbers"), this));
|
||||
formLayout->addWidget(new QLabel(tr("\t⬤ A different name from other computers"), this));
|
||||
|
||||
auto labelImage = new QLabel(this);
|
||||
labelImage->setPixmap(QPixmap(QStringLiteral(":/image/welcome.png")));
|
||||
|
||||
auto mainLayout = new QVBoxLayout();
|
||||
mainLayout->setContentsMargins(9, 30, 9, 9);
|
||||
mainLayout->addWidget(labelImage, 0, Qt::AlignHCenter);
|
||||
mainLayout->addWidget(labelTitle);
|
||||
mainLayout->addLayout(formLayout);
|
||||
mainLayout->addSpacerItem(new QSpacerItem(0, 25, QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
mainLayout->addWidget(m_btnApply);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
m_lblError->setStyleSheet(deskflow::gui::kStyleErrorActiveLabel);
|
||||
|
||||
m_lineName->setText(appConfig.screenName());
|
||||
m_lineName->setValidator(
|
||||
new validators::ScreenNameValidator(m_lineName, new validators::ValidationError(this, m_lblError))
|
||||
);
|
||||
|
||||
connect(m_btnApply, &QPushButton::clicked, this, &SetupWizard::accept);
|
||||
connect(m_lineName, &QLineEdit::textChanged, this, &SetupWizard::nameChanged);
|
||||
}
|
||||
|
||||
void SetupWizard::accept()
|
||||
{
|
||||
m_appConfig.setWizardHasRun();
|
||||
m_appConfig.setScreenName(m_lineName->text());
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void SetupWizard::nameChanged(const QString &error)
|
||||
{
|
||||
m_btnApply->setEnabled(m_lineName->hasAcceptableInput());
|
||||
}
|
||||
|
||||
void SetupWizard::reject()
|
||||
{
|
||||
QDialog::reject();
|
||||
QApplication::exit();
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class AppConfig;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
|
||||
class SetupWizard : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SetupWizard(AppConfig &appConfig);
|
||||
~SetupWizard() = default;
|
||||
|
||||
protected:
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
||||
private:
|
||||
void nameChanged(const QString &error);
|
||||
|
||||
AppConfig &m_appConfig;
|
||||
QLabel *m_lblError = nullptr;
|
||||
QLineEdit *m_lineName = nullptr;
|
||||
QPushButton *m_btnApply = nullptr;
|
||||
};
|
||||
@ -47,7 +47,7 @@ void VersionChecker::replyFinished(QNetworkReply *reply)
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo("version check server success, http status: %d", httpStatus);
|
||||
qDebug("version check server success, http status: %d", httpStatus);
|
||||
|
||||
const auto newestVersion = QString(reply->readAll());
|
||||
qDebug("version check response: %s", qPrintable(newestVersion));
|
||||
|
||||
@ -49,8 +49,8 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui{std::make_unique
|
||||
ui->btnOk->setDefault(true);
|
||||
connect(ui->btnOk, &QPushButton::clicked, this, [this] { close(); });
|
||||
|
||||
setFixedWidth(600);
|
||||
adjustSize();
|
||||
resize(QSize(parent->width() * 0.65, height()));
|
||||
setMinimumSize(size());
|
||||
}
|
||||
|
||||
|
||||
@ -25,8 +25,6 @@ private:
|
||||
std::unique_ptr<Ui::AboutDialog> ui;
|
||||
void copyVersionText();
|
||||
|
||||
inline static const auto s_lightCopy = QStringLiteral(":/icons/64x64/copy-light.png");
|
||||
inline static const auto s_darkCopy = QStringLiteral(":/icons/64x64/copy-dark.png");
|
||||
inline static const auto s_awesomeDevs = QStringList{
|
||||
// Chris is the ultimate creator, and the one who started it all in 2001.
|
||||
QStringLiteral("Chris Schoeneman"),
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModality::ApplicationModal</enum>
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>493</width>
|
||||
<width>600</width>
|
||||
<height>475</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -67,7 +67,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item row="6" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@ -80,7 +80,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item row="0" column="1">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@ -105,7 +105,7 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignBottom|Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft</set>
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
@ -158,7 +158,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string>Version: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>0</number>
|
||||
@ -182,7 +182,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string>lbl_version</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="smaller_text" stdset="0">
|
||||
<bool>true</bool>
|
||||
@ -207,7 +207,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string>Copy version info</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../res/deskflow.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/64x64/copy-dark.png</normaloff>:/icons/64x64/copy-dark.png</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
@ -224,7 +224,7 @@ p, li { white-space: pre-wrap; }
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@ -272,7 +272,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string>lblDescription</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -292,10 +292,10 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
@ -306,49 +306,105 @@ p, li { white-space: pre-wrap; }
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_17">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Important developers</string>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8" stretch="0">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>574</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblImportantDevs">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>lblImportantDevs</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Icons from <a href="https://develop.kde.org/frameworks/breeze-icons/"><span style=" text-decoration: underline; color:#007af4;">KDE Breeze</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Important Developers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblImportantDevs">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>lblImportantDevs</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -375,8 +431,6 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../res/deskflow.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
77
src/apps/deskflow-gui/dialogs/FingerprintDialog.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "FingerprintDialog.h"
|
||||
|
||||
#include "widgets/FingerprintPreview.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
FingerprintDialog::FingerprintDialog(
|
||||
QWidget *parent, const QList<deskflow::FingerprintData> &fingerprints, FingerprintDialogMode mode
|
||||
)
|
||||
: QDialog(parent),
|
||||
m_lblHeader{new QLabel(this)},
|
||||
m_lblFooter{new QLabel(this)},
|
||||
m_fingerprintPreview{new FingerprintPreview(this, fingerprints)},
|
||||
m_buttonBox{new QDialogButtonBox(this)}
|
||||
{
|
||||
setWindowIcon(QIcon::fromTheme("fingerprint"));
|
||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
|
||||
m_lblHeader->setWordWrap(true);
|
||||
m_lblFooter->setWordWrap(true);
|
||||
m_lblFooter->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addWidget(m_lblHeader);
|
||||
layout->addSpacerItem(new QSpacerItem(0, 10, QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
layout->addWidget(m_fingerprintPreview, 0, Qt::AlignTop | Qt::AlignHCenter);
|
||||
layout->addWidget(m_lblFooter);
|
||||
layout->addWidget(m_buttonBox);
|
||||
setLayout(layout);
|
||||
|
||||
if (mode == Local) {
|
||||
setWindowTitle(tr("Local Fingerprints"));
|
||||
m_lblHeader->setText(tr("Local computer's fingerprints"));
|
||||
m_lblFooter->setVisible(false);
|
||||
m_buttonBox->setStandardButtons(QDialogButtonBox::Ok);
|
||||
connect(m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QDialog::accept);
|
||||
} else {
|
||||
setWindowTitle(tr("Security Question"));
|
||||
auto body = tr("Compare the fingerprints in this dialog to those on the %1.\n"
|
||||
"Only connect if they match!");
|
||||
|
||||
if (mode == FingerprintDialogMode::Server) {
|
||||
m_lblHeader->setText(tr("A new client is connecting.\n%1").arg(body.arg(tr("client"))));
|
||||
m_lblFooter->setText(tr("\nDo you want connect to and trust the client?\n"));
|
||||
} else {
|
||||
m_lblHeader->setText(tr("You are connecting to a new server.\n%1").arg(body.arg(tr("server"))));
|
||||
m_lblFooter->setText(tr("\nDo you want connect to the server?\n"));
|
||||
}
|
||||
|
||||
m_buttonBox->setStandardButtons(QDialogButtonBox::Help | QDialogButtonBox::Yes | QDialogButtonBox::No);
|
||||
|
||||
// Use help to request a dialog with the host prints
|
||||
// Help is used because its always to the furthest from the other buttons.
|
||||
m_buttonBox->button(QDialogButtonBox::Help)->setText(tr("View local fingerprints"));
|
||||
m_buttonBox->button(QDialogButtonBox::Help)->setIcon(QIcon::fromTheme("fingerprint"));
|
||||
m_buttonBox->button(QDialogButtonBox::Help)->setToolTip(tr("Show the local machines fingerprints"));
|
||||
connect(
|
||||
m_buttonBox->button(QDialogButtonBox::Help), &QPushButton::clicked, this,
|
||||
&FingerprintDialog::requestLocalPrintsDialog
|
||||
);
|
||||
|
||||
m_buttonBox->button(QDialogButtonBox::No)->setFocus();
|
||||
connect(m_buttonBox->button(QDialogButtonBox::No), &QPushButton::clicked, this, &QDialog::reject);
|
||||
connect(m_buttonBox->button(QDialogButtonBox::Yes), &QPushButton::clicked, this, &QDialog::accept);
|
||||
}
|
||||
adjustSize();
|
||||
setFixedSize(size());
|
||||
}
|
||||
43
src/apps/deskflow-gui/dialogs/FingerprintDialog.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/FingerprintData.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
enum FingerprintDialogMode
|
||||
{
|
||||
Local,
|
||||
Client,
|
||||
Server
|
||||
};
|
||||
|
||||
class QLabel;
|
||||
class FingerprintPreview;
|
||||
|
||||
class FingerprintDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FingerprintDialog(
|
||||
QWidget *parent = nullptr, const QList<deskflow::FingerprintData> &fingerprints = {},
|
||||
FingerprintDialogMode mode = FingerprintDialogMode::Local
|
||||
);
|
||||
~FingerprintDialog() = default;
|
||||
|
||||
signals:
|
||||
void requestLocalPrintsDialog();
|
||||
|
||||
private:
|
||||
QLabel *m_lblHeader = nullptr;
|
||||
QLabel *m_lblFooter = nullptr;
|
||||
FingerprintPreview *m_fingerprintPreview = nullptr;
|
||||
QDialogButtonBox *m_buttonBox = nullptr;
|
||||
};
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
@ -34,47 +35,115 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->m_pButtonBrowseConfigFile->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen));
|
||||
ui->m_pTrashScreenWidget->setPixmap(QIcon::fromTheme("user-trash").pixmap(QSize(64, 64)));
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &ServerConfigDialog::accept);
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &ServerConfigDialog::reject);
|
||||
|
||||
ui->lblRemoveScreen->setPixmap(QIcon::fromTheme("user-trash").pixmap(QSize(64, 64)));
|
||||
connect(ui->lblRemoveScreen, &TrashScreenWidget::screenRemoved, this, &ServerConfigDialog::onScreenRemoved);
|
||||
|
||||
ui->lblNewScreen->setEnabled(!model().isFull());
|
||||
ui->lblNewScreen->setPixmap(QIcon::fromTheme("video-display").pixmap(QSize(64, 64)));
|
||||
ui->lblNewScreen->setToolTip(tr("Drag to the grid to add a new computer."));
|
||||
|
||||
connect(ui->btnNewHotkey, &QPushButton::clicked, this, &ServerConfigDialog::addHotkey);
|
||||
connect(ui->btnEditHotkey, &QPushButton::clicked, this, &ServerConfigDialog::editHotkey);
|
||||
connect(ui->btnRemoveHotkey, &QPushButton::clicked, this, &ServerConfigDialog::removeHotkey);
|
||||
connect(ui->listHotkeys, &QListView::doubleClicked, this, &ServerConfigDialog::editHotkey);
|
||||
connect(
|
||||
ui->listHotkeys->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&ServerConfigDialog::listHotkeysSelectionChanged
|
||||
);
|
||||
|
||||
connect(ui->btnNewAction, &QPushButton::clicked, this, &ServerConfigDialog::addAction);
|
||||
connect(ui->btnEditAction, &QPushButton::clicked, this, &ServerConfigDialog::editAction);
|
||||
connect(ui->btnRemoveAction, &QPushButton::clicked, this, &ServerConfigDialog::removeAction);
|
||||
connect(ui->listActions, &QListView::doubleClicked, this, &ServerConfigDialog::editAction);
|
||||
connect(
|
||||
ui->listActions->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&ServerConfigDialog::listActionsSelectionChanged
|
||||
);
|
||||
|
||||
// force the first tab, since qt creator sets the active tab as the last one
|
||||
// the developer was looking at, and it's easy to accidentally save that.
|
||||
ui->m_pTabWidget->setCurrentIndex(0);
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
|
||||
ui->m_pEditConfigFile->setText(serverConfig().configFile());
|
||||
ui->m_pCheckBoxUseExternalConfig->setChecked(serverConfig().useExternalConfig());
|
||||
ui->m_pCheckBoxHeartbeat->setChecked(serverConfig().hasHeartbeat());
|
||||
ui->m_pRadioProtocolSynergy->setChecked(serverConfig().protocol() == ServerProtocol::kSynergy);
|
||||
ui->m_pRadioProtocolBarrier->setChecked(serverConfig().protocol() == ServerProtocol::kBarrier);
|
||||
ui->m_pSpinBoxHeartbeat->setValue(serverConfig().heartbeat());
|
||||
ui->btnBrowseConfigFile->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen));
|
||||
ui->lineConfigFile->setText(serverConfig().configFile());
|
||||
|
||||
ui->m_pCheckBoxRelativeMouseMoves->setChecked(serverConfig().relativeMouseMoves());
|
||||
ui->m_pCheckBoxWin32KeepForeground->setChecked(serverConfig().win32KeepForeground());
|
||||
ui->groupExternalConfig->setChecked(serverConfig().useExternalConfig());
|
||||
|
||||
ui->m_pCheckBoxSwitchDelay->setChecked(serverConfig().hasSwitchDelay());
|
||||
ui->m_pSpinBoxSwitchDelay->setValue(serverConfig().switchDelay());
|
||||
ui->rbProtocolSynergy->setChecked(serverConfig().protocol() == ServerProtocol::kSynergy);
|
||||
ui->rbProtocolBarrier->setChecked(serverConfig().protocol() == ServerProtocol::kBarrier);
|
||||
connect(ui->rbProtocolBarrier, &QRadioButton::toggled, this, &ServerConfigDialog::toggleProtocol);
|
||||
|
||||
ui->m_pCheckBoxSwitchDoubleTap->setChecked(serverConfig().hasSwitchDoubleTap());
|
||||
ui->m_pSpinBoxSwitchDoubleTap->setValue(serverConfig().switchDoubleTap());
|
||||
ui->cbHeartbeat->setChecked(serverConfig().hasHeartbeat());
|
||||
connect(ui->cbHeartbeat, &QCheckBox::toggled, this, &ServerConfigDialog::toggleHeartbeat);
|
||||
|
||||
ui->m_pCheckBoxCornerTopLeft->setChecked(serverConfig().switchCorner(static_cast<int>(TopLeft)));
|
||||
ui->m_pCheckBoxCornerTopRight->setChecked(serverConfig().switchCorner(static_cast<int>(TopRight)));
|
||||
ui->m_pCheckBoxCornerBottomLeft->setChecked(serverConfig().switchCorner(static_cast<int>(BottomLeft)));
|
||||
ui->m_pCheckBoxCornerBottomRight->setChecked(serverConfig().switchCorner(static_cast<int>(BottomRight)));
|
||||
ui->m_pSpinBoxSwitchCornerSize->setValue(serverConfig().switchCornerSize());
|
||||
ui->m_pCheckBoxDisableLockToScreen->setChecked(serverConfig().disableLockToScreen());
|
||||
ui->sbHeartbeat->setValue(serverConfig().heartbeat());
|
||||
connect(ui->sbHeartbeat, QOverload<int>::of(&QSpinBox::valueChanged), this, &ServerConfigDialog::setHeartbeat);
|
||||
|
||||
ui->m_pCheckBoxEnableClipboard->setChecked(serverConfig().clipboardSharing());
|
||||
ui->cbRelativeMouseMoves->setChecked(serverConfig().relativeMouseMoves());
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
ui->cbWin32KeepForeground->setVisible(false);
|
||||
#endif
|
||||
ui->cbWin32KeepForeground->setChecked(serverConfig().win32KeepForeground());
|
||||
connect(ui->cbWin32KeepForeground, &QCheckBox::toggled, this, &ServerConfigDialog::toggleWin32Foreground);
|
||||
|
||||
ui->cbSwitchDelay->setChecked(serverConfig().hasSwitchDelay());
|
||||
connect(ui->cbSwitchDelay, &QCheckBox::toggled, this, &ServerConfigDialog::toggleSwitchDelay);
|
||||
|
||||
ui->sbSwitchDelay->setValue(serverConfig().switchDelay());
|
||||
connect(ui->sbSwitchDelay, QOverload<int>::of(&QSpinBox::valueChanged), this, &ServerConfigDialog::setSwitchDelay);
|
||||
|
||||
ui->cbSwitchDoubleTap->setChecked(serverConfig().hasSwitchDoubleTap());
|
||||
connect(ui->cbSwitchDoubleTap, &QCheckBox::toggled, this, &ServerConfigDialog::toggleSwitchDoubleTap);
|
||||
|
||||
ui->sbSwitchDoubleTap->setValue(serverConfig().switchDoubleTap());
|
||||
connect(
|
||||
ui->sbSwitchDoubleTap, QOverload<int>::of(&QSpinBox::valueChanged), this, &ServerConfigDialog::setSwitchDoubleTap
|
||||
);
|
||||
|
||||
connect(ui->cbRelativeMouseMoves, &QCheckBox::toggled, this, &ServerConfigDialog::toggleRelativeMouseMoves);
|
||||
connect(ui->cbEnableClipboard, &QCheckBox::toggled, this, &ServerConfigDialog::toggleClipboard);
|
||||
|
||||
connect(ui->groupExternalConfig, &QGroupBox::toggled, this, &ServerConfigDialog::toggleExternalConfig);
|
||||
connect(ui->btnBrowseConfigFile, &QPushButton::clicked, this, &ServerConfigDialog::browseConfigFile);
|
||||
|
||||
connect(
|
||||
ui->sbSwitchCornerSize, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
&ServerConfigDialog::setSwitchCornerSize
|
||||
);
|
||||
connect(
|
||||
ui->sbClipboardSizeLimit, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
&ServerConfigDialog::setClipboardLimit
|
||||
);
|
||||
|
||||
ui->cbCornerTopLeft->setChecked(serverConfig().switchCorner(static_cast<int>(TopLeft)));
|
||||
connect(ui->cbCornerTopLeft, &QCheckBox::toggled, this, &ServerConfigDialog::toggleCornerTopLeft);
|
||||
|
||||
ui->cbCornerTopRight->setChecked(serverConfig().switchCorner(static_cast<int>(TopRight)));
|
||||
connect(ui->cbCornerTopRight, &QCheckBox::toggled, this, &ServerConfigDialog::toggleCornerTopRight);
|
||||
|
||||
ui->cbCornerBottomLeft->setChecked(serverConfig().switchCorner(static_cast<int>(BottomLeft)));
|
||||
connect(ui->cbCornerBottomLeft, &QCheckBox::toggled, this, &ServerConfigDialog::toggleCornerBottomLeft);
|
||||
|
||||
ui->cbCornerBottomRight->setChecked(serverConfig().switchCorner(static_cast<int>(BottomRight)));
|
||||
connect(ui->cbCornerBottomRight, &QCheckBox::toggled, this, &ServerConfigDialog::toggleCornerBottomRight);
|
||||
|
||||
ui->sbSwitchCornerSize->setValue(serverConfig().switchCornerSize());
|
||||
|
||||
ui->cbDisableLockToScreen->setChecked(serverConfig().disableLockToScreen());
|
||||
connect(ui->cbDisableLockToScreen, &QCheckBox::toggled, this, &ServerConfigDialog::toggleLockToScreen);
|
||||
|
||||
ui->cbEnableClipboard->setChecked(serverConfig().clipboardSharing());
|
||||
int clipboardSharingSizeM = static_cast<int>(serverConfig().clipboardSharingSize() / 1024);
|
||||
ui->m_pSpinBoxClipboardSizeLimit->setValue(clipboardSharingSizeM);
|
||||
ui->m_pSpinBoxClipboardSizeLimit->setEnabled(serverConfig().clipboardSharing());
|
||||
ui->sbClipboardSizeLimit->setValue(clipboardSharingSizeM);
|
||||
ui->sbClipboardSizeLimit->setEnabled(serverConfig().clipboardSharing());
|
||||
|
||||
for (const Hotkey &hotkey : std::as_const(serverConfig().hotkeys()))
|
||||
ui->m_pListHotkeys->addItem(hotkey.text());
|
||||
ui->listHotkeys->addItem(hotkey.text());
|
||||
|
||||
ui->m_pScreenSetupView->setModel(&m_ScreenSetupModel);
|
||||
ui->screenSetupView->setModel(&m_ScreenSetupModel);
|
||||
|
||||
auto &screens = serverConfig().screens();
|
||||
auto server = std::find_if(screens.begin(), screens.end(), [this](const Screen &screen) {
|
||||
@ -89,170 +158,10 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
|
||||
server->markAsServer();
|
||||
}
|
||||
|
||||
ui->lblNewScreen->setEnabled(!model().isFull());
|
||||
connect(ui->m_pTrashScreenWidget, &TrashScreenWidget::screenRemoved, this, &ServerConfigDialog::onScreenRemoved);
|
||||
|
||||
onChange();
|
||||
|
||||
// computers
|
||||
connect(&m_ScreenSetupModel, &ScreenSetupModel::screensChanged, this, &ServerConfigDialog::onChange);
|
||||
|
||||
// Above Qt 6.7 the checkbox signal signature has changed from int to Qt::CheckState
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(6, 7, 0)
|
||||
// advanced
|
||||
connect(ui->m_pCheckBoxSwitchDelay, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().haveSwitchDelay(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxSwitchDoubleTap, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().haveSwitchDoubleTap(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxEnableClipboard, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setClipboardSharing(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxHeartbeat, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().haveHeartbeat(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxRelativeMouseMoves, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setRelativeMouseMoves(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxWin32KeepForeground, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setWin32KeepForeground(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxDisableLockToScreen, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setDisableLockToScreen(v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerTopLeft, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopLeft), v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerTopRight, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopRight), v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerBottomLeft, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomLeft), v);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerBottomRight, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomRight), v);
|
||||
onChange();
|
||||
});
|
||||
// config
|
||||
connect(ui->m_pCheckBoxUseExternalConfig, &QCheckBox::stateChanged, this, [this](const int &v) {
|
||||
serverConfig().setUseExternalConfig(v);
|
||||
onChange();
|
||||
});
|
||||
#else
|
||||
connect(ui->m_pCheckBoxSwitchDelay, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().haveSwitchDelay(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxSwitchDoubleTap, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().haveSwitchDoubleTap(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxEnableClipboard, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setClipboardSharing(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxHeartbeat, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().haveHeartbeat(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxRelativeMouseMoves, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setRelativeMouseMoves(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxWin32KeepForeground, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setWin32KeepForeground(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxDisableLockToScreen, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setDisableLockToScreen(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerTopLeft, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopLeft), v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerTopRight, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopRight), v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerBottomLeft, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomLeft), v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
connect(ui->m_pCheckBoxCornerBottomRight, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomRight), v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
// config
|
||||
connect(ui->m_pCheckBoxUseExternalConfig, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
|
||||
serverConfig().setUseExternalConfig(v == Qt::Checked);
|
||||
onChange();
|
||||
});
|
||||
#endif
|
||||
|
||||
connect(
|
||||
ui->m_pSpinBoxSwitchDelay, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
[this](const int &v) {
|
||||
serverConfig().setSwitchDelay(v);
|
||||
onChange();
|
||||
}
|
||||
);
|
||||
connect(
|
||||
ui->m_pSpinBoxSwitchDoubleTap, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
[this](const int &v) {
|
||||
serverConfig().setSwitchDoubleTap(v);
|
||||
onChange();
|
||||
}
|
||||
);
|
||||
connect(
|
||||
ui->m_pSpinBoxClipboardSizeLimit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
[this](const int &v) {
|
||||
serverConfig().setClipboardSharingSize(v * 1024);
|
||||
onChange();
|
||||
}
|
||||
);
|
||||
connect(
|
||||
ui->m_pSpinBoxHeartbeat, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
[this](const int &v) {
|
||||
serverConfig().setHeartbeat(v);
|
||||
onChange();
|
||||
}
|
||||
);
|
||||
connect(
|
||||
ui->m_pSpinBoxSwitchCornerSize, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
[this](const int &v) {
|
||||
serverConfig().setSwitchCornerSize(v);
|
||||
onChange();
|
||||
}
|
||||
);
|
||||
connect(ui->m_pRadioProtocolSynergy, &QRadioButton::toggled, this, [this](const bool &v) {
|
||||
if (v) {
|
||||
serverConfig().setProtocol(ServerProtocol::kSynergy);
|
||||
onChange();
|
||||
}
|
||||
});
|
||||
connect(ui->m_pRadioProtocolBarrier, &QRadioButton::toggled, this, [this](const bool &v) {
|
||||
if (v) {
|
||||
serverConfig().setProtocol(ServerProtocol::kBarrier);
|
||||
onChange();
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->m_pEditConfigFile, &QLineEdit::textChanged, this, [this]() {
|
||||
serverConfig().setConfigFile(ui->m_pEditConfigFile->text());
|
||||
onChange();
|
||||
});
|
||||
}
|
||||
|
||||
ServerConfigDialog::~ServerConfigDialog() = default;
|
||||
@ -264,13 +173,13 @@ bool ServerConfigDialog::addClient(const QString &clientName)
|
||||
|
||||
void ServerConfigDialog::accept()
|
||||
{
|
||||
if (ui->m_pCheckBoxUseExternalConfig->isChecked() && !QFile::exists(ui->m_pEditConfigFile->text())) {
|
||||
if (ui->groupExternalConfig->isChecked() && !QFile::exists(ui->lineConfigFile->text())) {
|
||||
|
||||
auto selectedButton = QMessageBox::warning(
|
||||
this, "Filename invalid", "Please select a valid configuration file.", QMessageBox::Ok | QMessageBox::Ignore
|
||||
);
|
||||
|
||||
if (selectedButton != QMessageBox::Ok || !on_m_pButtonBrowseConfigFile_clicked()) {
|
||||
if (selectedButton != QMessageBox::Ok || !browseConfigFile()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -290,130 +199,242 @@ void ServerConfigDialog::reject()
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonNewHotkey_clicked()
|
||||
void ServerConfigDialog::addHotkey()
|
||||
{
|
||||
Hotkey hotkey;
|
||||
HotkeyDialog dlg(this, hotkey);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
serverConfig().hotkeys().append(hotkey);
|
||||
ui->m_pListHotkeys->addItem(hotkey.text());
|
||||
ui->listHotkeys->addItem(hotkey.text());
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonEditHotkey_clicked()
|
||||
void ServerConfigDialog::editHotkey()
|
||||
{
|
||||
int idx = ui->m_pListHotkeys->currentRow();
|
||||
Q_ASSERT(idx >= 0 && idx < serverConfig().hotkeys().size());
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[idx];
|
||||
int row = ui->listHotkeys->currentRow();
|
||||
if (row < 0 || row >= serverConfig().hotkeys().size()) {
|
||||
qDebug() << "Attempt to editing out of bounds hotkey row: " << row;
|
||||
return;
|
||||
}
|
||||
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[row];
|
||||
HotkeyDialog dlg(this, hotkey);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
ui->m_pListHotkeys->currentItem()->setText(hotkey.text());
|
||||
ui->listHotkeys->currentItem()->setText(hotkey.text());
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonRemoveHotkey_clicked()
|
||||
void ServerConfigDialog::removeHotkey()
|
||||
{
|
||||
int idx = ui->m_pListHotkeys->currentRow();
|
||||
Q_ASSERT(idx >= 0 && idx < serverConfig().hotkeys().size());
|
||||
serverConfig().hotkeys().removeAt(idx);
|
||||
ui->m_pListActions->clear();
|
||||
delete ui->m_pListHotkeys->item(idx);
|
||||
int row = ui->listHotkeys->currentRow();
|
||||
if (row < 0 || row >= serverConfig().hotkeys().size()) {
|
||||
qDebug() << "Attempt to remove out of bounds hotkey row: " << row;
|
||||
return;
|
||||
}
|
||||
|
||||
serverConfig().hotkeys().removeAt(row);
|
||||
ui->listActions->clear();
|
||||
delete ui->listHotkeys->item(row);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pListHotkeys_itemSelectionChanged()
|
||||
void ServerConfigDialog::listHotkeysSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
bool itemsSelected = !ui->m_pListHotkeys->selectedItems().isEmpty();
|
||||
ui->m_pButtonEditHotkey->setEnabled(itemsSelected);
|
||||
ui->m_pButtonRemoveHotkey->setEnabled(itemsSelected);
|
||||
ui->m_pButtonNewAction->setEnabled(itemsSelected);
|
||||
bool itemsSelected = !selected.isEmpty();
|
||||
ui->btnEditHotkey->setEnabled(itemsSelected);
|
||||
ui->btnRemoveHotkey->setEnabled(itemsSelected);
|
||||
ui->btnNewAction->setEnabled(itemsSelected);
|
||||
|
||||
if (itemsSelected && serverConfig().hotkeys().size() > 0) {
|
||||
ui->m_pListActions->clear();
|
||||
|
||||
int idx = ui->m_pListHotkeys->row(ui->m_pListHotkeys->selectedItems()[0]);
|
||||
|
||||
// There's a bug somewhere around here: We get idx == 1 right after we
|
||||
// deleted the next to last item, so idx can only possibly be 0. GDB shows
|
||||
// we got called indirectly from the delete line in
|
||||
// on_m_pButtonRemoveHotkey_clicked() above, but the delete is of course
|
||||
// necessary and seems correct. The while() is a generalized workaround for
|
||||
// all that and shouldn't be required.
|
||||
while (idx >= 0 && idx >= serverConfig().hotkeys().size())
|
||||
idx--;
|
||||
|
||||
Q_ASSERT(idx >= 0 && idx < serverConfig().hotkeys().size());
|
||||
|
||||
const Hotkey &hotkey = serverConfig().hotkeys()[idx];
|
||||
if (itemsSelected && !serverConfig().hotkeys().isEmpty()) {
|
||||
ui->listActions->clear();
|
||||
const Hotkey &hotkey = serverConfig().hotkeys().at(selected.indexes().first().row());
|
||||
for (const Action &action : hotkey.actions())
|
||||
ui->m_pListActions->addItem(action.text());
|
||||
ui->listActions->addItem(action.text());
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonNewAction_clicked()
|
||||
void ServerConfigDialog::addAction()
|
||||
{
|
||||
int idx = ui->m_pListHotkeys->currentRow();
|
||||
Q_ASSERT(idx >= 0 && idx < serverConfig().hotkeys().size());
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[idx];
|
||||
int row = ui->listHotkeys->currentRow();
|
||||
if (row < 0 || row >= serverConfig().hotkeys().size()) {
|
||||
qDebug() << "Attempt to add action to out of bounds hotkey row: " << row;
|
||||
return;
|
||||
}
|
||||
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[row];
|
||||
Action action;
|
||||
ActionDialog dlg(this, serverConfig(), hotkey, action);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
hotkey.actions().append(action);
|
||||
ui->m_pListActions->addItem(action.text());
|
||||
ui->listActions->addItem(action.text());
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonEditAction_clicked()
|
||||
void ServerConfigDialog::editAction()
|
||||
{
|
||||
int idxHotkey = ui->m_pListHotkeys->currentRow();
|
||||
Q_ASSERT(idxHotkey >= 0 && idxHotkey < serverConfig().hotkeys().size());
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[idxHotkey];
|
||||
int hotkeyRow = ui->listHotkeys->currentRow();
|
||||
if (hotkeyRow < 0 || hotkeyRow >= serverConfig().hotkeys().size()) {
|
||||
qDebug() << "Attempt to edit action from out of bounds hotkey row: " << hotkeyRow;
|
||||
return;
|
||||
}
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[hotkeyRow];
|
||||
|
||||
int idxAction = ui->m_pListActions->currentRow();
|
||||
Q_ASSERT(idxAction >= 0 && idxAction < hotkey.actions().size());
|
||||
Action &action = hotkey.actions()[idxAction];
|
||||
int actionRow = ui->listActions->currentRow();
|
||||
if (actionRow < 0 || actionRow >= hotkey.actions().size()) {
|
||||
qDebug() << "Attempt to remove out of bounds action row: " << actionRow;
|
||||
return;
|
||||
}
|
||||
Action &action = hotkey.actions()[actionRow];
|
||||
|
||||
ActionDialog dlg(this, serverConfig(), hotkey, action);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
ui->m_pListActions->currentItem()->setText(action.text());
|
||||
ui->listActions->currentItem()->setText(action.text());
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonRemoveAction_clicked()
|
||||
void ServerConfigDialog::removeAction()
|
||||
{
|
||||
int idxHotkey = ui->m_pListHotkeys->currentRow();
|
||||
Q_ASSERT(idxHotkey >= 0 && idxHotkey < serverConfig().hotkeys().size());
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[idxHotkey];
|
||||
int hotkeyRow = ui->listHotkeys->currentRow();
|
||||
if (hotkeyRow < 0 || hotkeyRow >= serverConfig().hotkeys().size()) {
|
||||
qDebug() << "Attempt to remove action from out of bounds hotkey row: " << hotkeyRow;
|
||||
return;
|
||||
}
|
||||
Hotkey &hotkey = serverConfig().hotkeys()[hotkeyRow];
|
||||
|
||||
int idxAction = ui->m_pListActions->currentRow();
|
||||
Q_ASSERT(idxAction >= 0 && idxAction < hotkey.actions().size());
|
||||
int actionRow = ui->listActions->currentRow();
|
||||
if (actionRow < 0 || actionRow >= hotkey.actions().size()) {
|
||||
qDebug() << "Attempt to remove out of bounds action row: " << actionRow;
|
||||
return;
|
||||
}
|
||||
|
||||
hotkey.actions().removeAt(idxAction);
|
||||
delete ui->m_pListActions->currentItem();
|
||||
hotkey.actions().removeAt(actionRow);
|
||||
delete ui->listActions->currentItem();
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pCheckBoxEnableClipboard_stateChanged(int const state)
|
||||
void ServerConfigDialog::toggleClipboard(bool enabled)
|
||||
{
|
||||
ui->m_pSpinBoxClipboardSizeLimit->setEnabled(state == Qt::Checked);
|
||||
if ((state == Qt::Checked) && (!ui->m_pSpinBoxClipboardSizeLimit->value())) {
|
||||
ui->sbClipboardSizeLimit->setEnabled(enabled);
|
||||
if (enabled && !ui->sbClipboardSizeLimit->value()) {
|
||||
int size = static_cast<int>((serverConfig().defaultClipboardSharingSize() + 512) / 1024);
|
||||
ui->m_pSpinBoxClipboardSizeLimit->setValue(size ? size : 1);
|
||||
ui->sbClipboardSizeLimit->setValue(size ? size : 1);
|
||||
}
|
||||
serverConfig().setClipboardSharing(enabled);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pListActions_itemSelectionChanged()
|
||||
void ServerConfigDialog::setClipboardLimit(int limit)
|
||||
{
|
||||
ui->m_pButtonEditAction->setEnabled(!ui->m_pListActions->selectedItems().isEmpty());
|
||||
ui->m_pButtonRemoveAction->setEnabled(!ui->m_pListActions->selectedItems().isEmpty());
|
||||
serverConfig().setClipboardSharingSize(limit * 1024);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pButtonAddComputer_clicked()
|
||||
void ServerConfigDialog::toggleHeartbeat(bool enabled)
|
||||
{
|
||||
ui->sbHeartbeat->setEnabled(enabled);
|
||||
serverConfig().haveHeartbeat(enabled);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::setHeartbeat(int rate)
|
||||
{
|
||||
serverConfig().setHeartbeat(rate);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleRelativeMouseMoves(bool enabled)
|
||||
{
|
||||
serverConfig().setRelativeMouseMoves(enabled);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleProtocol()
|
||||
{
|
||||
ServerProtocol proto = ui->rbProtocolBarrier->isChecked() ? ServerProtocol::kBarrier : ServerProtocol::kSynergy;
|
||||
serverConfig().setProtocol(proto);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::setSwitchCornerSize(int size)
|
||||
{
|
||||
serverConfig().setSwitchCornerSize(size);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleCornerBottomLeft(bool enable)
|
||||
{
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomLeft), enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleCornerTopLeft(bool enable)
|
||||
{
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopLeft), enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleCornerBottomRight(bool enable)
|
||||
{
|
||||
serverConfig().setSwitchCorner(static_cast<int>(BottomRight), enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleCornerTopRight(bool enable)
|
||||
{
|
||||
serverConfig().setSwitchCorner(static_cast<int>(TopRight), enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::listActionsSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
bool enabled = !selected.isEmpty();
|
||||
ui->btnEditAction->setEnabled(enabled);
|
||||
ui->btnRemoveAction->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleSwitchDoubleTap(bool enable)
|
||||
{
|
||||
ui->sbSwitchDoubleTap->setEnabled(enable);
|
||||
serverConfig().haveSwitchDoubleTap(enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::setSwitchDoubleTap(int within)
|
||||
{
|
||||
serverConfig().setSwitchDoubleTap(within);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleSwitchDelay(bool enable)
|
||||
{
|
||||
ui->sbSwitchDelay->setEnabled(enable);
|
||||
serverConfig().haveSwitchDelay(enable);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::setSwitchDelay(int delay)
|
||||
{
|
||||
serverConfig().setSwitchDelay(delay);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleLockToScreen(bool disabled)
|
||||
{
|
||||
serverConfig().setDisableLockToScreen(disabled);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::toggleWin32Foreground(bool enabled)
|
||||
{
|
||||
serverConfig().setWin32KeepForeground(enabled);
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::addClient()
|
||||
{
|
||||
addComputer("", false);
|
||||
}
|
||||
@ -424,18 +445,21 @@ void ServerConfigDialog::onScreenRemoved()
|
||||
onChange();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pCheckBoxUseExternalConfig_toggled(bool checked)
|
||||
void ServerConfigDialog::toggleExternalConfig(bool checked)
|
||||
{
|
||||
ui->m_pLabelConfigFile->setEnabled(checked);
|
||||
ui->m_pEditConfigFile->setEnabled(checked);
|
||||
ui->m_pButtonBrowseConfigFile->setEnabled(checked);
|
||||
ui->labelConfigFile->setEnabled(checked);
|
||||
ui->lineConfigFile->setEnabled(checked);
|
||||
ui->btnBrowseConfigFile->setEnabled(checked);
|
||||
|
||||
ui->m_pTabWidget->setTabEnabled(0, !checked);
|
||||
ui->m_pTabWidget->setTabEnabled(1, !checked);
|
||||
ui->m_pTabWidget->setTabEnabled(2, !checked);
|
||||
ui->tabWidget->setTabEnabled(0, !checked);
|
||||
ui->tabWidget->setTabEnabled(1, !checked);
|
||||
ui->tabWidget->setTabEnabled(2, !checked);
|
||||
|
||||
serverConfig().setUseExternalConfig(checked);
|
||||
onChange();
|
||||
}
|
||||
|
||||
bool ServerConfigDialog::on_m_pButtonBrowseConfigFile_clicked()
|
||||
bool ServerConfigDialog::browseConfigFile()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
static const auto configExt = QStringLiteral("sgc");
|
||||
@ -448,7 +472,9 @@ bool ServerConfigDialog::on_m_pButtonBrowseConfigFile_clicked()
|
||||
QFileDialog::getOpenFileName(this, "Browse for a config file", "", deskflowConfigFilter.arg(kAppName, configExt));
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->m_pEditConfigFile->setText(fileName);
|
||||
ui->lineConfigFile->setText(fileName);
|
||||
serverConfig().setConfigFile(ui->lineConfigFile->text());
|
||||
onChange();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -474,6 +500,6 @@ void ServerConfigDialog::onChange()
|
||||
{
|
||||
bool isAppConfigDataEqual = m_OriginalServerConfigIsExternal == serverConfig().useExternalConfig() &&
|
||||
m_OriginalServerConfigUsesExternalFile == serverConfig().configFile();
|
||||
ui->m_pButtonBox->button(QDialogButtonBox::Ok)
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(!isAppConfigDataEqual || !(m_OriginalServerConfig == m_ServerConfig));
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
@ -13,6 +14,8 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QItemSelection;
|
||||
|
||||
namespace Ui {
|
||||
class ServerConfigDialog;
|
||||
}
|
||||
@ -35,23 +38,49 @@ public slots:
|
||||
}
|
||||
|
||||
protected slots:
|
||||
void on_m_pButtonNewHotkey_clicked();
|
||||
void on_m_pListHotkeys_itemSelectionChanged();
|
||||
void on_m_pButtonEditHotkey_clicked();
|
||||
void on_m_pButtonRemoveHotkey_clicked();
|
||||
|
||||
void on_m_pButtonNewAction_clicked();
|
||||
void on_m_pListActions_itemSelectionChanged();
|
||||
void on_m_pButtonEditAction_clicked();
|
||||
void on_m_pButtonRemoveAction_clicked();
|
||||
void on_m_pCheckBoxEnableClipboard_stateChanged(int state);
|
||||
void on_m_pButtonAddComputer_clicked();
|
||||
void onScreenRemoved();
|
||||
void on_m_pCheckBoxUseExternalConfig_toggled(bool checked = false);
|
||||
bool on_m_pButtonBrowseConfigFile_clicked();
|
||||
|
||||
protected:
|
||||
void addClient();
|
||||
bool addComputer(const QString &clientName, bool doSilent);
|
||||
|
||||
void addHotkey();
|
||||
void editHotkey();
|
||||
void removeHotkey();
|
||||
void listHotkeysSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
|
||||
void addAction();
|
||||
void editAction();
|
||||
void removeAction();
|
||||
void listActionsSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
|
||||
void toggleSwitchDoubleTap(bool enable);
|
||||
void setSwitchDoubleTap(int within);
|
||||
|
||||
void toggleSwitchDelay(bool enable);
|
||||
void setSwitchDelay(int delay);
|
||||
|
||||
void toggleLockToScreen(bool disabled);
|
||||
void toggleWin32Foreground(bool enabled);
|
||||
|
||||
void toggleClipboard(bool enabled);
|
||||
void setClipboardLimit(int limit);
|
||||
|
||||
void toggleHeartbeat(bool enabled);
|
||||
void setHeartbeat(int rate);
|
||||
|
||||
void toggleRelativeMouseMoves(bool enabled);
|
||||
void toggleProtocol();
|
||||
|
||||
void setSwitchCornerSize(int size);
|
||||
void toggleCornerBottomLeft(bool enable);
|
||||
void toggleCornerTopLeft(bool enable);
|
||||
void toggleCornerBottomRight(bool enable);
|
||||
void toggleCornerTopRight(bool enable);
|
||||
|
||||
void toggleExternalConfig(bool enable = false);
|
||||
bool browseConfigFile();
|
||||
|
||||
ServerConfig &serverConfig()
|
||||
{
|
||||
return m_ServerConfig;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
@ -10,11 +11,8 @@
|
||||
|
||||
#include "gui/core/CoreProcess.h"
|
||||
#include "gui/messages.h"
|
||||
#include "gui/style_utils.h"
|
||||
#include "gui/tls/TlsCertificate.h"
|
||||
#include "gui/tls/TlsUtility.h"
|
||||
#include "gui/validators/ScreenNameValidator.h"
|
||||
#include "gui/validators/ValidationError.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
@ -35,99 +33,63 @@ SettingsDialog::SettingsDialog(
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->m_pComboBoxTlsKeyLength->setItemIcon(0, QIcon::fromTheme(QIcon::ThemeIcon::SecurityLow));
|
||||
ui->m_pComboBoxTlsKeyLength->setItemIcon(1, QIcon::fromTheme(QStringLiteral("security-medium")));
|
||||
ui->m_pComboBoxTlsKeyLength->setItemIcon(2, QIcon::fromTheme(QIcon::ThemeIcon::SecurityHigh));
|
||||
ui->comboTlsKeyLength->setItemIcon(0, QIcon::fromTheme(QIcon::ThemeIcon::SecurityLow));
|
||||
ui->comboTlsKeyLength->setItemIcon(1, QIcon::fromTheme(QStringLiteral("security-medium")));
|
||||
ui->comboTlsKeyLength->setItemIcon(2, QIcon::fromTheme(QIcon::ThemeIcon::SecurityHigh));
|
||||
|
||||
ui->m_pPushButtonTlsRegenCert->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::ViewRefresh));
|
||||
|
||||
ui->m_pPushButtonTlsCertPath->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen));
|
||||
ui->m_pButtonBrowseLog->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::DocumentOpen));
|
||||
|
||||
ui->rb_icon_mono->setIcon(QIcon::fromTheme(QStringLiteral("deskflow-symbolic")));
|
||||
ui->rb_icon_colorful->setIcon(QIcon::fromTheme(QStringLiteral("deskflow")));
|
||||
ui->rbIconMono->setIcon(QIcon::fromTheme(QStringLiteral("deskflow-symbolic")));
|
||||
ui->rbIconColorful->setIcon(QIcon::fromTheme(QStringLiteral("deskflow")));
|
||||
|
||||
// force the first tab, since qt creator sets the active tab as the last one
|
||||
// the developer was looking at, and it's easy to accidentally save that.
|
||||
ui->m_pTabWidget->setCurrentIndex(0);
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
|
||||
loadFromConfig();
|
||||
m_wasOriginallySystemScope = m_appConfig.isActiveScopeSystem();
|
||||
updateControls();
|
||||
|
||||
m_pScreenNameError = new validators::ValidationError(this);
|
||||
ui->m_pLineEditScreenName->setValidator(
|
||||
new validators::ScreenNameValidator(ui->m_pLineEditScreenName, m_pScreenNameError, &serverConfig.screens())
|
||||
);
|
||||
|
||||
connect(ui->m_pCheckBoxEnableTls, &QCheckBox::toggled, this, &SettingsDialog::updateTlsControlsEnabled);
|
||||
|
||||
connect(
|
||||
this, &SettingsDialog::shown, this,
|
||||
[this] {
|
||||
if (!m_appConfig.isActiveScopeWritable()) {
|
||||
showReadOnlyMessage();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
|
||||
adjustSize();
|
||||
QApplication::processEvents();
|
||||
setFixedHeight(height());
|
||||
setWindowFlags((windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMinMaxButtonsHint);
|
||||
|
||||
initConnections();
|
||||
}
|
||||
|
||||
//
|
||||
// Auto-connect slots
|
||||
//
|
||||
|
||||
void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i)
|
||||
void SettingsDialog::initConnections()
|
||||
{
|
||||
bool checked = i == 2;
|
||||
connect(this, &SettingsDialog::shown, this, &SettingsDialog::showReadOnlyMessage, Qt::QueuedConnection);
|
||||
|
||||
ui->m_pLabelLogPath->setEnabled(checked);
|
||||
ui->m_pLineEditLogFilename->setEnabled(checked);
|
||||
ui->m_pButtonBrowseLog->setEnabled(checked);
|
||||
}
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &SettingsDialog::accept);
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &SettingsDialog::reject);
|
||||
|
||||
void SettingsDialog::on_m_pButtonBrowseLog_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this, tr("Save log file to..."), ui->m_pLineEditLogFilename->text(), "Logs (*.log *.txt)"
|
||||
);
|
||||
connect(ui->groupSecurity, &QGroupBox::toggled, this, &SettingsDialog::updateTlsControlsEnabled);
|
||||
connect(ui->cbServiceEnabled, &QCheckBox::toggled, this, &SettingsDialog::updateControls);
|
||||
connect(ui->btnTlsRegenCert, &QPushButton::clicked, this, &SettingsDialog::regenCertificates);
|
||||
connect(ui->btnTlsCertPath, &QPushButton::clicked, this, &SettingsDialog::browseCertificatePath);
|
||||
connect(ui->btnBrowseLog, &QPushButton::clicked, this, &SettingsDialog::browseLogPath);
|
||||
connect(ui->cbLogToFile, &QCheckBox::toggled, this, &SettingsDialog::setLogToFile);
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->m_pLineEditLogFilename->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pCheckBoxEnableTls_clicked(bool)
|
||||
{
|
||||
updateTlsControlsEnabled();
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pRadioSystemScope_toggled(bool checked)
|
||||
{
|
||||
// We only need to test the System scoped Radio as they are connected
|
||||
m_appConfig.setLoadFromSystemScope(checked);
|
||||
loadFromConfig();
|
||||
updateControls();
|
||||
connect(ui->rbScopeSystem, &QRadioButton::toggled, this, &SettingsDialog::setSystemScope);
|
||||
}
|
||||
|
||||
if (isVisible() && !m_appConfig.isActiveScopeWritable()) {
|
||||
showReadOnlyMessage();
|
||||
void SettingsDialog::regenCertificates()
|
||||
{
|
||||
if (m_tlsUtility.generateCertificate()) {
|
||||
QMessageBox::information(this, tr("TLS Certificate Regenerated"), tr("TLS certificate regenerated successfully."));
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pPushButtonTlsCertPath_clicked()
|
||||
void SettingsDialog::browseCertificatePath()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this, tr("Select a TLS certificate to use..."), ui->m_pLineEditTlsCertPath->text(), "Cert (*.pem)", nullptr,
|
||||
this, tr("Select a TLS certificate to use..."), ui->lineTlsCertPath->text(), "Cert (*.pem)", nullptr,
|
||||
QFileDialog::DontConfirmOverwrite
|
||||
);
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->m_pLineEditTlsCertPath->setText(fileName);
|
||||
ui->lineTlsCertPath->setText(fileName);
|
||||
|
||||
if (QFile(fileName).exists()) {
|
||||
updateKeyLengthOnFile(fileName);
|
||||
@ -137,21 +99,31 @@ void SettingsDialog::on_m_pPushButtonTlsCertPath_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pPushButtonTlsRegenCert_clicked()
|
||||
void SettingsDialog::browseLogPath()
|
||||
{
|
||||
if (m_tlsUtility.generateCertificate()) {
|
||||
QMessageBox::information(this, tr("TLS Certificate Regenerated"), tr("TLS certificate regenerated successfully."));
|
||||
QString fileName =
|
||||
QFileDialog::getSaveFileName(this, tr("Save log file to..."), ui->lineLogFilename->text(), "Logs (*.log *.txt)");
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->lineLogFilename->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pCheckBoxServiceEnabled_toggled(bool)
|
||||
void SettingsDialog::setLogToFile(bool logToFile)
|
||||
{
|
||||
updateControls();
|
||||
ui->widgetLogFilename->setEnabled(logToFile);
|
||||
}
|
||||
|
||||
//
|
||||
// End of auto-connect slots
|
||||
//
|
||||
void SettingsDialog::setSystemScope(bool systemScope)
|
||||
{
|
||||
m_appConfig.setLoadFromSystemScope(systemScope);
|
||||
loadFromConfig();
|
||||
updateControls();
|
||||
|
||||
if (isVisible() && !m_appConfig.isActiveScopeWritable()) {
|
||||
showReadOnlyMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
@ -161,37 +133,33 @@ void SettingsDialog::showEvent(QShowEvent *event)
|
||||
|
||||
void SettingsDialog::showReadOnlyMessage()
|
||||
{
|
||||
if (m_appConfig.isActiveScopeWritable())
|
||||
return;
|
||||
const auto activeScopeFilename = m_appConfig.scopes().activeFilePath();
|
||||
messages::showReadOnlySettings(this, activeScopeFilename);
|
||||
}
|
||||
|
||||
void SettingsDialog::accept()
|
||||
{
|
||||
if (!ui->m_pLineEditScreenName->hasAcceptableInput()) {
|
||||
QMessageBox::warning(this, tr("Invalid screen name"), m_pScreenNameError->message());
|
||||
return;
|
||||
}
|
||||
|
||||
m_appConfig.setLoadFromSystemScope(ui->m_pRadioSystemScope->isChecked());
|
||||
m_appConfig.setScreenName(ui->m_pLineEditScreenName->text());
|
||||
m_appConfig.setPort(ui->m_pSpinBoxPort->value());
|
||||
m_appConfig.setNetworkInterface(ui->m_pLineEditInterface->text());
|
||||
m_appConfig.setLogLevel(ui->m_pComboLogLevel->currentIndex());
|
||||
m_appConfig.setLogToFile(ui->m_pCheckBoxLogToFile->isChecked());
|
||||
m_appConfig.setLogFilename(ui->m_pLineEditLogFilename->text());
|
||||
m_appConfig.setElevateMode(static_cast<ElevateMode>(ui->m_pComboElevate->currentIndex()));
|
||||
m_appConfig.setAutoHide(ui->m_pCheckBoxAutoHide->isChecked());
|
||||
m_appConfig.setEnableUpdateCheck(ui->m_pCheckBoxAutoUpdate->isChecked());
|
||||
m_appConfig.setPreventSleep(ui->m_pCheckBoxPreventSleep->isChecked());
|
||||
m_appConfig.setTlsCertPath(ui->m_pLineEditTlsCertPath->text());
|
||||
m_appConfig.setTlsKeyLength(ui->m_pComboBoxTlsKeyLength->currentText().toInt());
|
||||
m_appConfig.setTlsEnabled(ui->m_pCheckBoxEnableTls->isChecked());
|
||||
m_appConfig.setLanguageSync(ui->m_pCheckBoxLanguageSync->isChecked());
|
||||
m_appConfig.setInvertScrollDirection(ui->m_pCheckBoxScrollDirection->isChecked());
|
||||
m_appConfig.setEnableService(ui->m_pCheckBoxServiceEnabled->isChecked());
|
||||
m_appConfig.setCloseToTray(ui->m_pCheckBoxCloseToTray->isChecked());
|
||||
m_appConfig.setInvertConnection(ui->m_pInvertConnection->isChecked());
|
||||
m_appConfig.setColorfulTrayIcon(ui->rb_icon_colorful->isChecked());
|
||||
m_appConfig.setLoadFromSystemScope(ui->rbScopeSystem->isChecked());
|
||||
m_appConfig.setPort(ui->sbPort->value());
|
||||
m_appConfig.setNetworkInterface(ui->lineInterface->text());
|
||||
m_appConfig.setLogLevel(ui->comboLogLevel->currentIndex());
|
||||
m_appConfig.setLogToFile(ui->cbLogToFile->isChecked());
|
||||
m_appConfig.setLogFilename(ui->lineLogFilename->text());
|
||||
m_appConfig.setElevateMode(static_cast<ElevateMode>(ui->comboElevate->currentIndex()));
|
||||
m_appConfig.setAutoHide(ui->cbAutoHide->isChecked());
|
||||
m_appConfig.setEnableUpdateCheck(ui->cbAutoUpdate->isChecked());
|
||||
m_appConfig.setPreventSleep(ui->cbPreventSleep->isChecked());
|
||||
m_appConfig.setTlsCertPath(ui->lineTlsCertPath->text());
|
||||
m_appConfig.setTlsKeyLength(ui->comboTlsKeyLength->currentText().toInt());
|
||||
m_appConfig.setTlsEnabled(ui->groupSecurity->isChecked());
|
||||
m_appConfig.setLanguageSync(ui->cbLanguageSync->isChecked());
|
||||
m_appConfig.setInvertScrollDirection(ui->cbScrollDirection->isChecked());
|
||||
m_appConfig.setEnableService(ui->cbServiceEnabled->isChecked());
|
||||
m_appConfig.setCloseToTray(ui->cbCloseToTray->isChecked());
|
||||
m_appConfig.setColorfulTrayIcon(ui->rbIconColorful->isChecked());
|
||||
m_appConfig.setRequireClientCerts(ui->cbRequireClientCert->isChecked());
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
@ -209,39 +177,37 @@ void SettingsDialog::reject()
|
||||
void SettingsDialog::loadFromConfig()
|
||||
{
|
||||
|
||||
ui->m_pLineEditScreenName->setText(m_appConfig.screenName());
|
||||
ui->m_pSpinBoxPort->setValue(m_appConfig.port());
|
||||
ui->m_pLineEditInterface->setText(m_appConfig.networkInterface());
|
||||
ui->m_pComboLogLevel->setCurrentIndex(m_appConfig.logLevel());
|
||||
ui->m_pCheckBoxLogToFile->setChecked(m_appConfig.logToFile());
|
||||
ui->m_pLineEditLogFilename->setText(m_appConfig.logFilename());
|
||||
ui->m_pCheckBoxAutoHide->setChecked(m_appConfig.autoHide());
|
||||
ui->m_pCheckBoxPreventSleep->setChecked(m_appConfig.preventSleep());
|
||||
ui->m_pCheckBoxLanguageSync->setChecked(m_appConfig.languageSync());
|
||||
ui->m_pCheckBoxScrollDirection->setChecked(m_appConfig.invertScrollDirection());
|
||||
ui->m_pCheckBoxServiceEnabled->setChecked(m_appConfig.enableService());
|
||||
ui->m_pCheckBoxCloseToTray->setChecked(m_appConfig.closeToTray());
|
||||
ui->m_pComboElevate->setCurrentIndex(static_cast<int>(m_appConfig.elevateMode()));
|
||||
ui->sbPort->setValue(m_appConfig.port());
|
||||
ui->lineInterface->setText(m_appConfig.networkInterface());
|
||||
ui->comboLogLevel->setCurrentIndex(m_appConfig.logLevel());
|
||||
ui->cbLogToFile->setChecked(m_appConfig.logToFile());
|
||||
ui->lineLogFilename->setText(m_appConfig.logFilename());
|
||||
ui->cbAutoHide->setChecked(m_appConfig.autoHide());
|
||||
ui->cbPreventSleep->setChecked(m_appConfig.preventSleep());
|
||||
ui->cbLanguageSync->setChecked(m_appConfig.languageSync());
|
||||
ui->cbScrollDirection->setChecked(m_appConfig.invertScrollDirection());
|
||||
ui->cbServiceEnabled->setChecked(m_appConfig.enableService());
|
||||
ui->cbCloseToTray->setChecked(m_appConfig.closeToTray());
|
||||
ui->comboElevate->setCurrentIndex(static_cast<int>(m_appConfig.elevateMode()));
|
||||
|
||||
if (m_appConfig.enableUpdateCheck().has_value()) {
|
||||
ui->m_pCheckBoxAutoUpdate->setChecked(m_appConfig.enableUpdateCheck().value());
|
||||
ui->cbAutoUpdate->setChecked(m_appConfig.enableUpdateCheck().value());
|
||||
} else {
|
||||
ui->m_pCheckBoxAutoUpdate->setChecked(false);
|
||||
ui->cbAutoUpdate->setChecked(false);
|
||||
}
|
||||
|
||||
if (m_appConfig.isActiveScopeSystem()) {
|
||||
ui->m_pRadioSystemScope->setChecked(true);
|
||||
ui->rbScopeSystem->setChecked(true);
|
||||
} else {
|
||||
ui->m_pRadioUserScope->setChecked(true);
|
||||
ui->rbScopeUser->setChecked(true);
|
||||
}
|
||||
|
||||
ui->m_pInvertConnection->setChecked(m_appConfig.invertConnection());
|
||||
|
||||
if (m_appConfig.colorfulTrayIcon())
|
||||
ui->rb_icon_colorful->setChecked(true);
|
||||
ui->rbIconColorful->setChecked(true);
|
||||
else
|
||||
ui->rb_icon_mono->setChecked(true);
|
||||
ui->rbIconMono->setChecked(true);
|
||||
|
||||
qDebug() << "load from config done";
|
||||
updateTlsControls();
|
||||
}
|
||||
|
||||
@ -252,30 +218,38 @@ void SettingsDialog::updateTlsControls()
|
||||
updateKeyLengthOnFile(m_appConfig.tlsCertPath());
|
||||
} else {
|
||||
const auto keyLengthText = QString::number(m_appConfig.tlsKeyLength());
|
||||
ui->m_pComboBoxTlsKeyLength->setCurrentIndex(ui->m_pComboBoxTlsKeyLength->findText(keyLengthText));
|
||||
ui->comboTlsKeyLength->setCurrentIndex(ui->comboTlsKeyLength->findText(keyLengthText));
|
||||
}
|
||||
|
||||
const auto tlsEnabled = m_tlsUtility.isEnabled();
|
||||
const auto writable = m_appConfig.isActiveScopeWritable();
|
||||
const auto enabled = writable && tlsEnabled;
|
||||
|
||||
ui->m_pCheckBoxEnableTls->setEnabled(writable);
|
||||
ui->m_pCheckBoxEnableTls->setChecked(writable && tlsEnabled);
|
||||
ui->m_pLineEditTlsCertPath->setText(m_appConfig.tlsCertPath());
|
||||
ui->lineTlsCertPath->setText(m_appConfig.tlsCertPath());
|
||||
ui->cbRequireClientCert->setChecked(m_appConfig.requireClientCerts());
|
||||
ui->groupSecurity->setChecked(tlsEnabled);
|
||||
|
||||
ui->groupSecurity->setEnabled(writable);
|
||||
ui->comboTlsKeyLength->setEnabled(enabled);
|
||||
ui->widgetTlsCert->setEnabled(enabled);
|
||||
ui->lblTlsKeyLength->setEnabled(enabled);
|
||||
ui->btnTlsRegenCert->setEnabled(enabled);
|
||||
ui->cbRequireClientCert->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void SettingsDialog::updateTlsControlsEnabled()
|
||||
{
|
||||
const auto writable = m_appConfig.isActiveScopeWritable();
|
||||
const auto clientMode = m_appConfig.clientGroupChecked();
|
||||
const auto tlsChecked = ui->m_pCheckBoxEnableTls->isChecked();
|
||||
const auto tlsChecked = ui->groupSecurity->isChecked();
|
||||
|
||||
auto enabled = writable && tlsChecked && !clientMode;
|
||||
ui->m_pLabelTlsKeyLength->setEnabled(enabled);
|
||||
ui->m_pComboBoxTlsKeyLength->setEnabled(enabled);
|
||||
ui->m_pLabelTlsCert->setEnabled(enabled);
|
||||
ui->m_pLineEditTlsCertPath->setEnabled(enabled);
|
||||
ui->m_pPushButtonTlsCertPath->setEnabled(enabled);
|
||||
ui->m_pPushButtonTlsRegenCert->setEnabled(enabled);
|
||||
ui->lblTlsKeyLength->setEnabled(enabled);
|
||||
ui->comboTlsKeyLength->setEnabled(enabled);
|
||||
ui->lblTlsCert->setEnabled(enabled);
|
||||
ui->widgetTlsCert->setEnabled(enabled);
|
||||
ui->btnTlsRegenCert->setEnabled(enabled);
|
||||
ui->cbRequireClientCert->setEnabled(enabled);
|
||||
}
|
||||
|
||||
bool SettingsDialog::isClientMode() const
|
||||
@ -291,8 +265,8 @@ void SettingsDialog::updateKeyLengthOnFile(const QString &path)
|
||||
}
|
||||
|
||||
auto length = ssl.getCertKeyLength(path);
|
||||
auto index = ui->m_pComboBoxTlsKeyLength->findText(QString::number(length));
|
||||
ui->m_pComboBoxTlsKeyLength->setCurrentIndex(index);
|
||||
auto index = ui->comboTlsKeyLength->findText(QString::number(length));
|
||||
ui->comboTlsKeyLength->setCurrentIndex(index);
|
||||
m_appConfig.setTlsKeyLength(length);
|
||||
}
|
||||
|
||||
@ -304,35 +278,31 @@ void SettingsDialog::updateControls()
|
||||
#else
|
||||
// service not supported on unix yet, so always disable.
|
||||
const auto serviceAvailable = false;
|
||||
ui->m_pGroupService->setTitle("Service (Windows only)");
|
||||
ui->groupService->setTitle("Service (Windows only)");
|
||||
#endif
|
||||
|
||||
const bool writable = m_appConfig.isActiveScopeWritable();
|
||||
const bool serviceChecked = ui->m_pCheckBoxServiceEnabled->isChecked();
|
||||
const bool logToFile = ui->m_pCheckBoxLogToFile->isChecked();
|
||||
const bool serviceChecked = ui->cbServiceEnabled->isChecked();
|
||||
const bool logToFile = ui->cbLogToFile->isChecked();
|
||||
|
||||
ui->m_pLineEditScreenName->setEnabled(writable);
|
||||
ui->m_pSpinBoxPort->setEnabled(writable);
|
||||
ui->m_pLineEditInterface->setEnabled(writable);
|
||||
ui->m_pComboLogLevel->setEnabled(writable);
|
||||
ui->m_pCheckBoxLogToFile->setEnabled(writable);
|
||||
ui->m_pCheckBoxAutoHide->setEnabled(writable);
|
||||
ui->m_pCheckBoxAutoUpdate->setEnabled(writable);
|
||||
ui->m_pCheckBoxPreventSleep->setEnabled(writable);
|
||||
ui->m_pLineEditTlsCertPath->setEnabled(writable);
|
||||
ui->m_pComboBoxTlsKeyLength->setEnabled(writable);
|
||||
ui->m_pCheckBoxCloseToTray->setEnabled(writable);
|
||||
ui->sbPort->setEnabled(writable);
|
||||
ui->lineInterface->setEnabled(writable);
|
||||
ui->comboLogLevel->setEnabled(writable);
|
||||
ui->cbLogToFile->setEnabled(writable);
|
||||
ui->cbAutoHide->setEnabled(writable);
|
||||
ui->cbAutoUpdate->setEnabled(writable);
|
||||
ui->cbPreventSleep->setEnabled(writable);
|
||||
ui->lineTlsCertPath->setEnabled(writable);
|
||||
ui->comboTlsKeyLength->setEnabled(writable);
|
||||
ui->cbCloseToTray->setEnabled(writable);
|
||||
|
||||
ui->m_pCheckBoxServiceEnabled->setEnabled(writable && serviceAvailable);
|
||||
ui->m_pLabelElevate->setEnabled(writable && serviceChecked && serviceAvailable);
|
||||
ui->m_pComboElevate->setEnabled(writable && serviceChecked && serviceAvailable);
|
||||
ui->cbServiceEnabled->setEnabled(writable && serviceAvailable);
|
||||
ui->widgetElevate->setEnabled(writable && serviceChecked && serviceAvailable);
|
||||
|
||||
ui->m_pCheckBoxLanguageSync->setEnabled(writable && isClientMode());
|
||||
ui->m_pCheckBoxScrollDirection->setEnabled(writable && isClientMode());
|
||||
ui->cbLanguageSync->setEnabled(writable && isClientMode());
|
||||
ui->cbScrollDirection->setEnabled(writable && isClientMode());
|
||||
|
||||
ui->m_pLabelLogPath->setEnabled(writable && logToFile);
|
||||
ui->m_pLineEditLogFilename->setEnabled(writable && logToFile);
|
||||
ui->m_pButtonBrowseLog->setEnabled(writable && logToFile);
|
||||
ui->widgetLogFilename->setEnabled(writable && logToFile);
|
||||
|
||||
updateTlsControls();
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2012 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2008 Volker Lanz <vl@fidra.de>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
@ -35,16 +36,13 @@ public:
|
||||
signals:
|
||||
void shown();
|
||||
|
||||
private slots:
|
||||
void on_m_pCheckBoxEnableTls_clicked(bool checked);
|
||||
void on_m_pCheckBoxLogToFile_stateChanged(int);
|
||||
void on_m_pButtonBrowseLog_clicked();
|
||||
void on_m_pRadioSystemScope_toggled(bool checked);
|
||||
void on_m_pPushButtonTlsCertPath_clicked();
|
||||
void on_m_pPushButtonTlsRegenCert_clicked();
|
||||
void on_m_pCheckBoxServiceEnabled_toggled(bool checked);
|
||||
|
||||
private:
|
||||
void initConnections();
|
||||
void regenCertificates();
|
||||
void browseCertificatePath();
|
||||
void browseLogPath();
|
||||
void setLogToFile(bool logToFile);
|
||||
void setSystemScope(bool systemScope);
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void showEvent(QShowEvent *event) override;
|
||||
@ -65,8 +63,6 @@ private:
|
||||
/// @brief Enables controls when they should be.
|
||||
void updateControls();
|
||||
|
||||
validators::ValidationError *m_pScreenNameError;
|
||||
|
||||
/// @brief Stores settings scope at start of settings dialog
|
||||
/// This is necessary to restore state if user changes
|
||||
/// the scope and doesn't save changes
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "SetupWizard.h"
|
||||
#include "common/constants.h"
|
||||
#include "gui/Logger.h"
|
||||
#include "gui/config/AppConfig.h"
|
||||
@ -148,17 +147,6 @@ int main(int argc, char *argv[])
|
||||
&configScopes, &ConfigScopes::saving, &appConfig, [&appConfig]() { appConfig.commit(); }, Qt::DirectConnection
|
||||
);
|
||||
|
||||
if (appConfig.wizardShouldRun()) {
|
||||
SetupWizard wizard(appConfig);
|
||||
auto result = wizard.exec();
|
||||
if (result != QDialog::Accepted) {
|
||||
qInfo("wizard cancelled, exiting");
|
||||
return 0;
|
||||
}
|
||||
|
||||
configScopes.save();
|
||||
}
|
||||
|
||||
MainWindow mainWindow(configScopes, appConfig);
|
||||
mainWindow.open();
|
||||
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2021 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "ClientStateLabel.h"
|
||||
|
||||
namespace deskflow::gui::widgets {
|
||||
|
||||
ClientStateLabel::ClientStateLabel(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
void ClientStateLabel::updateClientState(const QString &line)
|
||||
{
|
||||
if (line.contains("connected to server")) {
|
||||
show();
|
||||
} else if (line.contains("disconnected from server") || line.contains("process exited")) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace deskflow::gui::widgets
|
||||
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2021 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
namespace deskflow::gui::widgets {
|
||||
|
||||
class ClientStateLabel : public QLabel
|
||||
{
|
||||
public:
|
||||
explicit ClientStateLabel(QWidget *parent = nullptr);
|
||||
void updateClientState(const QString &line);
|
||||
};
|
||||
|
||||
} // namespace deskflow::gui::widgets
|
||||
101
src/apps/deskflow-gui/widgets/FingerprintPreview.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "FingerprintPreview.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include <net/SecureUtils.h>
|
||||
|
||||
FingerprintPreview::FingerprintPreview(QWidget *parent, const QList<deskflow::FingerprintData> &fingerprints)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setFrameShape(QFrame::StyledPanel);
|
||||
setFrameStyle(QFrame::Sunken);
|
||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
|
||||
QString sha1String;
|
||||
QString sha256String;
|
||||
QString sha256Art;
|
||||
|
||||
for (const auto &fingerprint : fingerprints) {
|
||||
if (fingerprint.algorithm == "sha1") {
|
||||
sha1String = QString::fromStdString(deskflow::formatSSLFingerprint(fingerprint.data));
|
||||
}
|
||||
|
||||
if (fingerprint.algorithm == "sha256") {
|
||||
sha256String = QString::fromStdString(deskflow::formatSSLFingerprintColumns(fingerprint.data));
|
||||
sha256Art = QString::fromStdString(deskflow::generateFingerprintArt(fingerprint.data));
|
||||
}
|
||||
}
|
||||
|
||||
auto labelSha1 = new QLabel(QStringLiteral("SHA1:"), this);
|
||||
labelSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
|
||||
auto lblSha1 = new QLabel(sha1String, this);
|
||||
lblSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
lblSha1->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
auto sha1Layout = new QHBoxLayout();
|
||||
sha1Layout->addWidget(labelSha1);
|
||||
sha1Layout->addWidget(lblSha1);
|
||||
|
||||
auto frameSha1 = new QFrame(this);
|
||||
frameSha1->setFrameShape(QFrame::StyledPanel);
|
||||
frameSha1->setFrameStyle(QFrame::Sunken);
|
||||
frameSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
frameSha1->setLayout(sha1Layout);
|
||||
|
||||
auto labelSha256 = new QLabel(QStringLiteral("SHA256:"), this);
|
||||
labelSha256->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
|
||||
auto lblSha256String = new QLabel(sha256String, this);
|
||||
lblSha256String->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||
lblSha256String->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
auto lblSha256Art = new QLabel(sha256Art, this);
|
||||
lblSha256Art->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
|
||||
lblSha256Art->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
QFont f = font();
|
||||
f.setFamilies({"Hack", "Liberation Mono", "Monospace", "Andale Mono"});
|
||||
f.setStyleHint(QFont::Monospace);
|
||||
lblSha256Art->setFont(f);
|
||||
|
||||
auto innersha256Layout = new QHBoxLayout();
|
||||
innersha256Layout->setContentsMargins(0, 0, 0, 0);
|
||||
innersha256Layout->addWidget(lblSha256String);
|
||||
innersha256Layout->addWidget(lblSha256Art);
|
||||
|
||||
auto sha256Layout = new QVBoxLayout();
|
||||
sha256Layout->addWidget(labelSha256);
|
||||
sha256Layout->addLayout(innersha256Layout);
|
||||
|
||||
auto frameSha256 = new QFrame(this);
|
||||
frameSha256->setFrameShape(QFrame::StyledPanel);
|
||||
frameSha256->setFrameStyle(QFrame::Sunken);
|
||||
frameSha256->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
frameSha256->setLayout(sha256Layout);
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addWidget(frameSha1);
|
||||
layout->addWidget(frameSha256);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
if (sha1String.isEmpty()) {
|
||||
frameSha1->setVisible(false);
|
||||
}
|
||||
|
||||
if (sha256String.isEmpty()) {
|
||||
frameSha256->setVisible(false);
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
setFixedSize(size());
|
||||
}
|
||||
18
src/apps/deskflow-gui/widgets/FingerprintPreview.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include <net/FingerprintData.h>
|
||||
|
||||
class FingerprintPreview : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FingerprintPreview(QWidget *parent, const QList<deskflow::FingerprintData> &fingerprints = {});
|
||||
~FingerprintPreview() = default;
|
||||
};
|
||||
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2021 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "ServerStateLabel.h"
|
||||
|
||||
#include "gui/core/ServerMessage.h"
|
||||
|
||||
using namespace deskflow::gui;
|
||||
|
||||
namespace deskflow::gui::widgets {
|
||||
|
||||
ServerStateLabel::ServerStateLabel(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ServerStateLabel::updateServerState(const QString &line)
|
||||
{
|
||||
ServerMessage message(line);
|
||||
|
||||
if (message.isExitMessage()) {
|
||||
m_clients.clear();
|
||||
} else if (message.isConnectedMessage()) {
|
||||
m_clients.append(message.getClientName());
|
||||
} else if (message.isDisconnectedMessage()) {
|
||||
m_clients.removeAll(message.getClientName());
|
||||
}
|
||||
|
||||
if (m_clients.isEmpty()) {
|
||||
setText(tr("No clients connected"));
|
||||
} else {
|
||||
// unfortunately, we can't rely on the clients list because we don't always
|
||||
// catch the connect/disconnect messages. so clients tend to get stuck in
|
||||
// the list even though they're offline.
|
||||
// in order to properly show a list of clients, we would need the core to
|
||||
// print a list of connected clients on every connect/disconnect event,
|
||||
// which could be a bit noisy in the logs (perhaps an ipc message would be
|
||||
// needed).
|
||||
setText(tr("Client(s) are connected"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace deskflow::gui::widgets
|
||||
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2021 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStringList>
|
||||
|
||||
namespace deskflow::gui::widgets {
|
||||
|
||||
class ServerStateLabel : public QLabel
|
||||
{
|
||||
public:
|
||||
explicit ServerStateLabel(QWidget *parent = nullptr);
|
||||
void updateServerState(const QString &line);
|
||||
|
||||
private:
|
||||
QStringList m_clients;
|
||||
|
||||
void updateState();
|
||||
};
|
||||
|
||||
} // namespace deskflow::gui::widgets
|
||||
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd
|
||||
# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton
|
||||
# SPDX-License-Identifier: MIT
|
||||
@ -7,7 +7,7 @@ set(target ${CMAKE_PROJECT_NAME}-server)
|
||||
|
||||
if(WIN32)
|
||||
# Generate rc file
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_DESCRIPTION}\\n CLI server application")
|
||||
set(EXE_DESCRIPTION "${CMAKE_PROJECT_PROPER_NAME} server application")
|
||||
|
||||
set(EXE_ICON "
|
||||
IDI_DESKFLOW ICON DISCARDABLE \"${CMAKE_SOURCE_DIR}/src/apps/res/deskflow.ico\"
|
||||
@ -32,14 +32,17 @@ target_link_libraries(
|
||||
io
|
||||
mt
|
||||
net
|
||||
ipc
|
||||
platform
|
||||
server
|
||||
app
|
||||
${libs})
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH TRUE
|
||||
INSTALL_RPATH "@loader_path/../Libraries;@loader_path/../Frameworks"
|
||||
RUNTIME_OUTPUT_DIRECTORY $<TARGET_BUNDLE_CONTENT_DIR:${CMAKE_PROJECT_PROPER_NAME}>/MacOS
|
||||
)
|
||||
elseif(UNIX)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
elseif(WIN32)
|
||||
|
||||
@ -28,6 +28,30 @@ int main(int argc, char **argv)
|
||||
Log log;
|
||||
EventQueue events;
|
||||
|
||||
// HACK: the `--active-desktop` arg actually belongs in the `deskflow-core` binary,
|
||||
// but we are placing it here in the server binary temporarily until we are ready to
|
||||
// ship the `deskflow-core` binary. we are deliberately not integrating `--active-desktop`
|
||||
// into the existing `ServerApp` arg parsing code as that would be a waste of time.
|
||||
#if SYSAPI_WIN32
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::string arg(argv[i]);
|
||||
// This is called by the daemon (running in session 0) when it needs to know the name of the
|
||||
// interactive desktop.
|
||||
// It is necessary to run a utility process because the daemon runs in session 0, which does not
|
||||
// have access to the active desktop, and so cannot query it's name.
|
||||
if (arg == "--active-desktop") {
|
||||
const auto name = ArchMiscWindows::getActiveDesktopName();
|
||||
if (name.empty()) {
|
||||
LOG((CLOG_CRIT "failed to get active desktop name"));
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
LOG((CLOG_PRINT "%s", name.c_str()));
|
||||
return kExitSuccess;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ServerApp app(&events);
|
||||
return app.run(argc, argv);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
<qresource prefix="/">
|
||||
<file>icons/deskflow-dark/actions/16/configure.svg</file>
|
||||
<file>icons/deskflow-dark/actions/16/edit-copy.svg</file>
|
||||
<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/help-about.svg</file>
|
||||
@ -11,8 +12,10 @@
|
||||
<file>icons/deskflow-dark/actions/16/view-refresh.svg</file>
|
||||
<file>icons/deskflow-dark/actions/22/configure.svg</file>
|
||||
<file>icons/deskflow-dark/actions/22/edit-copy.svg</file>
|
||||
<file>icons/deskflow-dark/actions/22/document-edit.svg</file>
|
||||
<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/help-about.svg</file>
|
||||
<file>icons/deskflow-dark/actions/22/process-stop.svg</file>
|
||||
<file>icons/deskflow-dark/actions/22/system-run.svg</file>
|
||||
@ -20,9 +23,11 @@
|
||||
<file>icons/deskflow-dark/actions/22/view-refresh.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/configure.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/edit-copy.svg</file>
|
||||
<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/edit-clear-all.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/fingerprint.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/help-about.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/process-stop.svg</file>
|
||||
<file>icons/deskflow-dark/actions/24/system-run.svg</file>
|
||||
@ -41,6 +46,7 @@
|
||||
<file>icons/deskflow-dark/apps/64/deskflow-symbolic.svg</file>
|
||||
<file>icons/deskflow-dark/devices/64/video-display.svg</file>
|
||||
<file>icons/deskflow-dark/places/64/user-trash.svg</file>
|
||||
<file>icons/deskflow-dark/status/32/software-updates-release.svg</file>
|
||||
<file>icons/deskflow-dark/status/64/dialog-error.svg</file>
|
||||
<file>icons/deskflow-dark/status/64/dialog-information.svg</file>
|
||||
<file>icons/deskflow-dark/status/64/dialog-positive.svg</file>
|
||||
@ -53,6 +59,7 @@
|
||||
<file>icons/deskflow-light/actions/16/configure.svg</file>
|
||||
<file>icons/deskflow-light/actions/16/edit-clear-all.svg</file>
|
||||
<file>icons/deskflow-light/actions/16/edit-copy.svg</file>
|
||||
<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/help-about.svg</file>
|
||||
@ -63,8 +70,10 @@
|
||||
<file>icons/deskflow-light/actions/22/configure.svg</file>
|
||||
<file>icons/deskflow-light/actions/22/edit-clear-all.svg</file>
|
||||
<file>icons/deskflow-light/actions/22/edit-copy.svg</file>
|
||||
<file>icons/deskflow-light/actions/22/document-edit.svg</file>
|
||||
<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/help-about.svg</file>
|
||||
<file>icons/deskflow-light/actions/22/process-stop.svg</file>
|
||||
<file>icons/deskflow-light/actions/22/system-run.svg</file>
|
||||
@ -73,6 +82,8 @@
|
||||
<file>icons/deskflow-light/actions/24/configure.svg</file>
|
||||
<file>icons/deskflow-light/actions/24/edit-clear-all.svg</file>
|
||||
<file>icons/deskflow-light/actions/24/edit-copy.svg</file>
|
||||
<file>icons/deskflow-light/actions/24/fingerprint.svg</file>
|
||||
<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/help-about.svg</file>
|
||||
@ -92,6 +103,7 @@
|
||||
<file>icons/deskflow-light/apps/64/deskflow.svg</file>
|
||||
<file>icons/deskflow-light/apps/64/deskflow-symbolic.svg</file>
|
||||
<file>icons/deskflow-light/devices/64/video-display.svg</file>
|
||||
<file>icons/deskflow-light/status/32/software-updates-release.svg</file>
|
||||
<file>icons/deskflow-light/status/64/dialog-error.svg</file>
|
||||
<file>icons/deskflow-light/status/64/dialog-information.svg</file>
|
||||
<file>icons/deskflow-light/status/64/dialog-positive.svg</file>
|
||||
@ -101,6 +113,5 @@
|
||||
<file>icons/deskflow-light/status/64/security-low.svg</file>
|
||||
<file>icons/deskflow-light/status/64/security-medium.svg</file>
|
||||
<file>icons/deskflow-light/index.theme</file>
|
||||
<file>image/welcome.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -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 10.398438 2 L 5.2871094 7.1113281 L 2 10.398438 L 2 14 L 5.6015625 14 L 14 5.6015625 L 10.398438 2 z M 8.3496094 5.4902344 L 10.509766 7.6503906 L 7.3359375 10.826172 L 7.3359375 10.150391 L 6.3222656 10.171875 L 5.2871094 10.171875 L 5.2871094 9.1367188 L 5.2871094 8.5507812 L 6.7285156 7.1113281 L 8.3496094 5.4902344 z M 4.2734375 9.5644531 L 4.2734375 11.185547 L 5.3085938 11.185547 L 6.3007812 11.185547 L 6.3222656 11.837891 L 5.2421875 12.919922 L 3.8007812 12.919922 L 3.0800781 12.199219 L 3.0800781 10.757812 L 4.2734375 9.5644531 z " class="ColorScheme-Text"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 879 B |
7
src/apps/res/icons/deskflow-dark/actions/16/list-add.svg
Normal 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 7 3.0058594 L 7 8 L 2 8 L 2 8.9980469 L 7 8.9980469 L 7 14.007812 L 8 14.007812 L 8 8.9980469 L 13 8.9980469 L 13 8 L 8 8 L 8 3.0058594 L 7 3.0058594 z " class="ColorScheme-Text"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-NegativeText { color: #da4453; } </style>
|
||||
<path class="ColorScheme-NegativeText" d="M 2.6992188,2 2,2.6992188 7.3007812,8 2,13.300781 C 2,13.300781 2.7082187,13.995 2.6992188,14 L 8,8.6992188 13.300781,14 C 13.291781,13.995 14,13.300781 14,13.300781 L 8.6992188,8 14,2.6992188 13.300781,2 8,7.3007812 Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 517 B |
@ -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="m14.996094 3l-11.992188 11.992188h-.003906v4.00781h1 2 1.00781v-.003906l11.992188-11.992188-.001953-.001953.001953-.001953-4-4-.001953.001953-.001953-.001953m-1.998047 3.412109l2.589844 2.589844-7.587891 7.587891v-1.589844h-1-1v-1-.589844l6.998047-6.998047m-7.998047 7.998047v1.589844h1 1v1 .589844l-.410156.410156h-1.589844l-1-1v-1.589844l1-1" class="ColorScheme-Text"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 675 B |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="svg2" height="22" style="" viewBox="0 0 22 22" width="22" xmlns="http://www.w3.org/2000/svg" sodipodi:docname="fingerprint.svg" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
|
||||
</defs>
|
||||
<path id="path1" d="m 10.964844 2.9980469 c -1.5845236 -.0072353 -2.9422744 .2857394 -4.1777346 .9042969 c -.4112899 .2059109 -.4758434 .2776955 -.4492188 .5 c .0543735 .4537067 .2885593 .498883 .9824219 .1875 c 1.2899294 -.578856 1.9178453 -.7033109 3.5449215 -.7050782 c 1.867366 -.00153 2.554482 .1581718 4.085938 .9511719 c .263122 .1360571 1.097292 .7789323 1.408203 .4335937 c .307924 -.3078945 .144513 -.5609142 -.648437 -1.0117187 c -1.563801 -.8890431 -2.930512 -1.2511653 -4.746094 -1.2597656 z m -.046875 1.8320312 c -2.0906577 -.0015904 -4.1807664 .8256559 -5.7128909 2.4804688 c -.5926987 .640169 -1.2832031 1.689795 -1.2832031 1.9492187 c 0 .3024858 .1234451 .46875 .3496094 .46875 c .1772788 0 .3578489 -.190821 .7871094 -.8359375 c .9600458 -1.4427908 2.2051389 -2.4006204 3.8085937 -2.9296875 c 1.2435415 -.4058614 2.7001995 -.3588754 4.0996095 0 c 1.806888 .5938948 3.355915 1.916279 4.205078 3.5898438 c .184782 .3641515 .295572 .4765626 .476563 .4765626 c .311704 0 .495303 -.23344 .410156 -.5214845 c -.137293 -.4645988 -.869271 -1.5904919 -1.423828 -2.1894531 c -1.534258 -1.657146 -3.626141 -2.4866996 -5.716797 -2.4882813 z m .097656 1.8222657 c -.445604 -.00775 -.897825 .0344876 -1.3496094 .1289062 c -2.146845 .4487425 -3.9412221 2.1872289 -4.515625 4.375 c -.3048255 1.160984 -.1650506 3.057421 .3378906 4.574219 c .1503076 .453288 .223992 .547173 .4394532 .572265 c .4953707 .05757 .5425194 -.177958 .2460937 -1.203125 c -.8481973 -2.933423 -.117367 -5.4282751 1.9863281 -6.7890621 c 2.0798818 -1.3453843 4.9406298 -.948559 6.5683598 .9121093 c 1.020005 1.1659848 1.579872 3.1393058 1.134765 3.9999998 c -.294034 .568598 -1.009591 .909304 -1.597656 .761719 c -.429745 -.107851 -.940652 -.635832 -1.005859 -1.041016 c -.230123 -1.429844 -.554761 -1.988299 -1.376954 -2.371093 c -.701353 -.32655 -1.284385 -.317345 -1.9726558 .03125 c -.6413124 .324823 -1.1329202 .979024 -1.2324218 1.642578 c -.035906 .239115 -.0206307 .757671 .0351562 1.15039 c .3469606 2.446271 2.0965544 4.381247 4.5000004 4.976563 c .302262 .07484 .797346 .127554 1.099609 .117187 l .548828 -.017578 c .310632 -.157676 .327632 -.52228 0 -.701172 l -.777344 -.117187 c -.978866 -.149158 -1.383803 -.279437 -2.05664 -.658203 c -1.46318 -.823674 -2.511719 -2.609239 -2.511719 -4.277344 c 0 -.735113 .2787884 -1.164663 .927734 -1.433594 c .468905 -.194333 .474455 -.194333 .94336 0 c .593428 .24593 .879612 .658428 .953125 1.371094 c .134996 1.307917 1.042601 2.167969 2.287109 2.167969 c .998776 0 1.840549 -.647171 2.138672 -1.646485 c .291784 -.977992 -.101062 -2.621655 -.923828 -3.8710934 c -1.090395 -1.6558477 -2.895221 -2.6207549 -4.826172 -2.6542968 z m -.064453 1.8945312 c -.621891 .0078591 -1.2610341 .1220648 -1.7851564 .3261719 c -.8081421 .3957774 -1.5782434 1.1864461 -1.9765625 2.0273441 c -.3030937 .639832 -.3205007 .739905 -.3203125 1.826171 c .0002242 1.336431 .1608293 2.045939 .7363282 3.246094 c .4958946 1.034132 1.1835844 1.936783 1.9472656 2.554688 c .6619406 .535587 .7322516 .560867 1.0078126 .359375 c .282107 -.20626 .124685 -.56108 -.445313 -.998047 c -.6180212 -.473788 -1.2857839 -1.329765 -1.7363278 -2.228516 c -.7400486 -1.476217 -.9257648 -3.301198 -.4433593 -4.345703 c .3501094 -.758061 .8837753 -1.3239492 1.5644531 -1.658203 c .817809 -.4015966 2.012269 -.4015966 2.830078 0 c .976109 .479324 1.599333 1.353519 1.820313 2.550781 c .1319 .714664 .332068 .952234 .636718 .75586 c .141164 -.09099 .171337 -.242829 .158203 -.78711 c -.031914 -1.323089 -.957834 -2.6511972 -2.3125 -3.316406 c -.454743 -.2212609 -1.059749 -.3203662 -1.68164 -.3125 z m -.003906 3.615234 c -.072134 -.001465 -.153033 .023509 -.244141 .072266 c -.191281 .102402 -.208829 .174075 -.162109 .726563 c .147755 1.748088 1.464452 3.25256 3.171875 3.625 c .757301 .165124 .960616 .162423 1.142578 -.019532 c .363429 -.363416 .119519 -.652706 -.634766 -.755859 c -1.541693 -.21083 -2.687806 -1.387877 -2.871094 -2.947266 c -.054671 -.465046 -.185943 -.696776 -.402343 -.701172 z" class="ColorScheme-Text" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
7
src/apps/res/icons/deskflow-dark/actions/22/list-add.svg
Normal 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 10 4 L 10 11 L 3 11 L 3 12 L 10 12 L 10 19 L 11 19 L 11 12 L 18 12 L 18 11 L 11 11 L 11 4 L 10 4 z " class="ColorScheme-Text"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-NegativeText { color: #da4453; } </style>
|
||||
<path class="ColorScheme-NegativeText" d="M 3.6992188 3 L 3 3.6992188 L 10.300781 11 L 3 18.300781 C 3 18.300781 3.7112147 18.993333 3.6992188 19 L 11 11.699219 L 18.300781 19 C 18.288781 18.9933 19 18.300781 19 18.300781 L 11.699219 11.001953 L 19 3.6992188 L 18.300781 3 L 11 10.300781 L 3.6992188 3 z " fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 561 B |
@ -0,0 +1,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="m14.996094 3l-11.992188 11.992188h-.003906v4.00781h1 2 1.00781v-.003906l11.992188-11.992188-.001953-.001953.001953-.001953-4-4-.001953.001953-.001953-.001953m-1.998047 3.412109l2.589844 2.589844-7.587891 7.587891v-1.589844h-1-1v-1-.589844l6.998047-6.998047m-7.998047 7.998047v1.589844h1 1v1 .589844l-.410156.410156h-1.589844l-1-1v-1.589844l1-1" class="ColorScheme-Text"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 702 B |
@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" id="svg2" height="24" style="" viewBox="0 0 24 24" width="24" sodipodi:docname="fingerprint.svg" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-Text { color: #fcfcfc; } </style>
|
||||
</defs>
|
||||
<g transform="translate(1,1)">
|
||||
<path id="path1" d="m 10.964844 2.9980469 c -1.5845236 -.0072353 -2.9422744 .2857394 -4.1777346 .9042969 c -.4112899 .2059109 -.4758434 .2776955 -.4492188 .5 c .0543735 .4537067 .2885593 .498883 .9824219 .1875 c 1.2899294 -.578856 1.9178453 -.7033109 3.5449215 -.7050782 c 1.867366 -.00153 2.554482 .1581718 4.085938 .9511719 c .263122 .1360571 1.097292 .7789323 1.408203 .4335937 c .307924 -.3078945 .144513 -.5609142 -.648437 -1.0117187 c -1.563801 -.8890431 -2.930512 -1.2511653 -4.746094 -1.2597656 z m -.046875 1.8320312 c -2.0906577 -.0015904 -4.1807664 .8256559 -5.7128909 2.4804688 c -.5926987 .640169 -1.2832031 1.689795 -1.2832031 1.9492187 c 0 .3024858 .1234451 .46875 .3496094 .46875 c .1772788 0 .3578489 -.190821 .7871094 -.8359375 c .9600458 -1.4427908 2.2051389 -2.4006204 3.8085937 -2.9296875 c 1.2435415 -.4058614 2.7001995 -.3588754 4.0996095 0 c 1.806888 .5938948 3.355915 1.916279 4.205078 3.5898438 c .184782 .3641515 .295572 .4765626 .476563 .4765626 c .311704 0 .495303 -.23344 .410156 -.5214845 c -.137293 -.4645988 -.869271 -1.5904919 -1.423828 -2.1894531 c -1.534258 -1.657146 -3.626141 -2.4866996 -5.716797 -2.4882813 z m .097656 1.8222657 c -.445604 -.00775 -.897825 .0344876 -1.3496094 .1289062 c -2.146845 .4487425 -3.9412221 2.1872289 -4.515625 4.375 c -.3048255 1.160984 -.1650506 3.057421 .3378906 4.574219 c .1503076 .453288 .223992 .547173 .4394532 .572265 c .4953707 .05757 .5425194 -.177958 .2460937 -1.203125 c -.8481973 -2.933423 -.117367 -5.4282751 1.9863281 -6.7890621 c 2.0798818 -1.3453843 4.9406298 -.948559 6.5683598 .9121093 c 1.020005 1.1659848 1.579872 3.1393058 1.134765 3.9999998 c -.294034 .568598 -1.009591 .909304 -1.597656 .761719 c -.429745 -.107851 -.940652 -.635832 -1.005859 -1.041016 c -.230123 -1.429844 -.554761 -1.988299 -1.376954 -2.371093 c -.701353 -.32655 -1.284385 -.317345 -1.9726558 .03125 c -.6413124 .324823 -1.1329202 .979024 -1.2324218 1.642578 c -.035906 .239115 -.0206307 .757671 .0351562 1.15039 c .3469606 2.446271 2.0965544 4.381247 4.5000004 4.976563 c .302262 .07484 .797346 .127554 1.099609 .117187 l .548828 -.017578 c .310632 -.157676 .327632 -.52228 0 -.701172 l -.777344 -.117187 c -.978866 -.149158 -1.383803 -.279437 -2.05664 -.658203 c -1.46318 -.823674 -2.511719 -2.609239 -2.511719 -4.277344 c 0 -.735113 .2787884 -1.164663 .927734 -1.433594 c .468905 -.194333 .474455 -.194333 .94336 0 c .593428 .24593 .879612 .658428 .953125 1.371094 c .134996 1.307917 1.042601 2.167969 2.287109 2.167969 c .998776 0 1.840549 -.647171 2.138672 -1.646485 c .291784 -.977992 -.101062 -2.621655 -.923828 -3.8710934 c -1.090395 -1.6558477 -2.895221 -2.6207549 -4.826172 -2.6542968 z m -.064453 1.8945312 c -.621891 .0078591 -1.2610341 .1220648 -1.7851564 .3261719 c -.8081421 .3957774 -1.5782434 1.1864461 -1.9765625 2.0273441 c -.3030937 .639832 -.3205007 .739905 -.3203125 1.826171 c .0002242 1.336431 .1608293 2.045939 .7363282 3.246094 c .4958946 1.034132 1.1835844 1.936783 1.9472656 2.554688 c .6619406 .535587 .7322516 .560867 1.0078126 .359375 c .282107 -.20626 .124685 -.56108 -.445313 -.998047 c -.6180212 -.473788 -1.2857839 -1.329765 -1.7363278 -2.228516 c -.7400486 -1.476217 -.9257648 -3.301198 -.4433593 -4.345703 c .3501094 -.758061 .8837753 -1.3239492 1.5644531 -1.658203 c .817809 -.4015966 2.012269 -.4015966 2.830078 0 c .976109 .479324 1.599333 1.353519 1.820313 2.550781 c .1319 .714664 .332068 .952234 .636718 .75586 c .141164 -.09099 .171337 -.242829 .158203 -.78711 c -.031914 -1.323089 -.957834 -2.6511972 -2.3125 -3.316406 c -.454743 -.2212609 -1.059749 -.3203662 -1.68164 -.3125 z m -.003906 3.615234 c -.072134 -.001465 -.153033 .023509 -.244141 .072266 c -.191281 .102402 -.208829 .174075 -.162109 .726563 c .147755 1.748088 1.464452 3.25256 3.171875 3.625 c .757301 .165124 .960616 .162423 1.142578 -.019532 c .363429 -.363416 .119519 -.652706 -.634766 -.755859 c -1.541693 -.21083 -2.687806 -1.387877 -2.871094 -2.947266 c -.054671 -.465046 -.185943 -.696776 -.402343 -.701172 z" class="ColorScheme-Text" fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
8
src/apps/res/icons/deskflow-dark/actions/24/list-add.svg
Normal file
@ -0,0 +1,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 10 4 L 10 11 L 3 11 L 3 12 L 10 12 L 10 19 L 11 19 L 11 12 L 18 12 L 18 11 L 11 11 L 11 4 L 10 4 z " class="ColorScheme-Text"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 460 B |
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24" width="24" height="24">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-NegativeText { color: #da4453; } </style>
|
||||
<g transform="translate(1,1)">
|
||||
<path class="ColorScheme-NegativeText" d="M 3.6992188 3 L 3 3.6992188 L 10.300781 11 L 3 18.300781 C 3 18.300781 3.7112147 18.993333 3.6992188 19 L 11 11.699219 L 18.300781 19 C 18.288781 18.9933 19 18.300781 19 18.300781 L 11.699219 11.001953 L 19 3.6992188 L 18.300781 3 L 11 10.300781 L 3.6992188 3 z " fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 583 B |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<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="m22.27 4l-18.27 18.27v5.73h5.73c0 0 18.269-18.269 18.27-18.27zm-2.865 4.299l4.297 4.297-11.701 11.703v-2.299h-4v-2.299zm-12.404 12.402v2.299h4v2.299l-1.701 1.701h-2l-2.297-2.297v-2z" class="ColorScheme-Text"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 513 B |
@ -29,7 +29,7 @@ KDE-Extensions=.svg
|
||||
########## Directories
|
||||
########## ordered by category and alphabetically
|
||||
|
||||
Directories=actions/16,actions/22,actions/24,actions/32,apps/64,devices/64,places/64,status/16,status/22,status,24,status/64
|
||||
Directories=actions/16,actions/22,actions/24,actions/32,apps/64,devices/64,places/64,status/16,status/22,status,24,status/32,status/64
|
||||
ScaledDirectories=actions/16@2x,actions/16@3x,actions/22@2x,actions/22@3x,actions/24@2x,actions/24@3x,actions/32@2x,actions/32@3x
|
||||
|
||||
[apps/64]
|
||||
@ -156,6 +156,14 @@ Context=Places
|
||||
MinSize=48
|
||||
MaxSize=256
|
||||
|
||||
#32x32 - Fixed size - For dialog icons >!!!ONLY!!!< - DO_NOT_USE_ANYWHERE_ELSE - Color
|
||||
[status/32]
|
||||
Size=32
|
||||
Context=Status
|
||||
Type=Scalable
|
||||
MinSize=22
|
||||
MaxSize=256
|
||||
|
||||
#64x64 - Fixed size - For dialog icons >!!!ONLY!!!< - DO_NOT_USE_ANYWHERE_ELSE - Color
|
||||
[status/64]
|
||||
Size=64
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
<?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="22" height="22">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-Accent { color: #3daee9; } .ColorScheme-Background { color: #2a2e32; } .ColorScheme-ButtonText { color: #31363b; } .ColorScheme-Text { color: #fcfcfc; } </style>
|
||||
<g id="software-updates-release" transform="translate(0,22) translate(0,-22)">
|
||||
<path style="fill:#2ecc71;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 7,7 4,10 4,19 9.0996094,19 13,19 l 5.099609,0 0,-9 -3,-3 L 13,7 9.0996094,7 Z m 0.3,1 3.7,0 3.7,0 2,2 -11.4,0 z m 1.7,3 4,0 0,5 -1,-1 -1,1 -1,-1 -1,1 z" id="path4164" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccccccccccccccc"/>
|
||||
<path style="opacity:1;fill:#2ecc71;fill-opacity:1;stroke:none" d="M 16,3 A 3,3 0 0 0 13,6 3,3 0 0 0 16,9 3,3 0 0 0 19,6 3,3 0 0 0 16,3 Z" id="path4166" inkscape:connector-curvature="0"/>
|
||||
<path style="opacity:1;fill:currentColor;fill-opacity:1;stroke:none" d="m 16,4 2,2 -1,0 0,2 -2,0 0,-2 -1,0 1,-1 1,-1 z" id="path4168" inkscape:connector-curvature="0" class="ColorScheme-Background"/>
|
||||
<rect y="-2.6645353e-15" x="0" height="22" width="22" id="rect4170" style="opacity:1;fill:none;fill-opacity:0.59905659;stroke:none"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@ -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 10.398438 2 L 5.2871094 7.1113281 L 2 10.398438 L 2 14 L 5.6015625 14 L 14 5.6015625 L 10.398438 2 z M 8.3496094 5.4902344 L 10.509766 7.6503906 L 7.3359375 10.826172 L 7.3359375 10.150391 L 6.3222656 10.171875 L 5.2871094 10.171875 L 5.2871094 9.1367188 L 5.2871094 8.5507812 L 6.7285156 7.1113281 L 8.3496094 5.4902344 z M 4.2734375 9.5644531 L 4.2734375 11.185547 L 5.3085938 11.185547 L 6.3007812 11.185547 L 6.3222656 11.837891 L 5.2421875 12.919922 L 3.8007812 12.919922 L 3.0800781 12.199219 L 3.0800781 10.757812 L 4.2734375 9.5644531 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 883 B |
13
src/apps/res/icons/deskflow-light/actions/16/list-add.svg
Normal 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 7 3.0058594 L 7 8 L 2 8 L 2 8.9980469 L 7 8.9980469 L 7 14.007812 L 8 14.007812 L 8 8.9980469 L 13 8.9980469 L 13 8 L 8 8 L 8 3.0058594 L 7 3.0058594 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 490 B |
10
src/apps/res/icons/deskflow-light/actions/16/list-remove.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-NegativeText {
|
||||
color:#da4453;
|
||||
}
|
||||
</style>
|
||||
<path class="ColorScheme-NegativeText" d="M 2.6992188,2 2,2.6992188 7.3007812,8 2,13.300781 C 2,13.300781 2.7082187,13.995 2.6992188,14 L 8,8.6992188 13.300781,14 C 13.291781,13.995 14,13.300781 14,13.300781 L 8.6992188,8 14,2.6992188 13.300781,2 8,7.3007812 Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 526 B |
@ -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="m14.996094 3l-11.992188 11.992188h-.003906v4.00781h1 2 1.00781v-.003906l11.992188-11.992188-.001953-.001953.001953-.001953-4-4-.001953.001953-.001953-.001953m-1.998047 3.412109l2.589844 2.589844-7.587891 7.587891v-1.589844h-1-1v-1-.589844l6.998047-6.998047m-7.998047 7.998047v1.589844h1 1v1 .589844l-.410156.410156h-1.589844l-1-1v-1.589844l1-1"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 681 B |
10
src/apps/res/icons/deskflow-light/actions/22/fingerprint.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg id="svg2" height="22" style="" viewBox="0 0 22 22" width="22" xmlns="http://www.w3.org/2000/svg" sodipodi:docname="fingerprint.svg" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#232629;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path id="path1" d="m 10.964844 2.9980469 c -1.5845236 -.0072353 -2.9422744 .2857394 -4.1777346 .9042969 c -.4112899 .2059109 -.4758434 .2776955 -.4492188 .5 c .0543735 .4537067 .2885593 .498883 .9824219 .1875 c 1.2899294 -.578856 1.9178453 -.7033109 3.5449215 -.7050782 c 1.867366 -.00153 2.554482 .1581718 4.085938 .9511719 c .263122 .1360571 1.097292 .7789323 1.408203 .4335937 c .307924 -.3078945 .144513 -.5609142 -.648437 -1.0117187 c -1.563801 -.8890431 -2.930512 -1.2511653 -4.746094 -1.2597656 z m -.046875 1.8320312 c -2.0906577 -.0015904 -4.1807664 .8256559 -5.7128909 2.4804688 c -.5926987 .640169 -1.2832031 1.689795 -1.2832031 1.9492187 c 0 .3024858 .1234451 .46875 .3496094 .46875 c .1772788 0 .3578489 -.190821 .7871094 -.8359375 c .9600458 -1.4427908 2.2051389 -2.4006204 3.8085937 -2.9296875 c 1.2435415 -.4058614 2.7001995 -.3588754 4.0996095 0 c 1.806888 .5938948 3.355915 1.916279 4.205078 3.5898438 c .184782 .3641515 .295572 .4765626 .476563 .4765626 c .311704 0 .495303 -.23344 .410156 -.5214845 c -.137293 -.4645988 -.869271 -1.5904919 -1.423828 -2.1894531 c -1.534258 -1.657146 -3.626141 -2.4866996 -5.716797 -2.4882813 z m .097656 1.8222657 c -.445604 -.00775 -.897825 .0344876 -1.3496094 .1289062 c -2.146845 .4487425 -3.9412221 2.1872289 -4.515625 4.375 c -.3048255 1.160984 -.1650506 3.057421 .3378906 4.574219 c .1503076 .453288 .223992 .547173 .4394532 .572265 c .4953707 .05757 .5425194 -.177958 .2460937 -1.203125 c -.8481973 -2.933423 -.117367 -5.4282751 1.9863281 -6.7890621 c 2.0798818 -1.3453843 4.9406298 -.948559 6.5683598 .9121093 c 1.020005 1.1659848 1.579872 3.1393058 1.134765 3.9999998 c -.294034 .568598 -1.009591 .909304 -1.597656 .761719 c -.429745 -.107851 -.940652 -.635832 -1.005859 -1.041016 c -.230123 -1.429844 -.554761 -1.988299 -1.376954 -2.371093 c -.701353 -.32655 -1.284385 -.317345 -1.9726558 .03125 c -.6413124 .324823 -1.1329202 .979024 -1.2324218 1.642578 c -.035906 .239115 -.0206307 .757671 .0351562 1.15039 c .3469606 2.446271 2.0965544 4.381247 4.5000004 4.976563 c .302262 .07484 .797346 .127554 1.099609 .117187 l .548828 -.017578 c .310632 -.157676 .327632 -.52228 0 -.701172 l -.777344 -.117187 c -.978866 -.149158 -1.383803 -.279437 -2.05664 -.658203 c -1.46318 -.823674 -2.511719 -2.609239 -2.511719 -4.277344 c 0 -.735113 .2787884 -1.164663 .927734 -1.433594 c .468905 -.194333 .474455 -.194333 .94336 0 c .593428 .24593 .879612 .658428 .953125 1.371094 c .134996 1.307917 1.042601 2.167969 2.287109 2.167969 c .998776 0 1.840549 -.647171 2.138672 -1.646485 c .291784 -.977992 -.101062 -2.621655 -.923828 -3.8710934 c -1.090395 -1.6558477 -2.895221 -2.6207549 -4.826172 -2.6542968 z m -.064453 1.8945312 c -.621891 .0078591 -1.2610341 .1220648 -1.7851564 .3261719 c -.8081421 .3957774 -1.5782434 1.1864461 -1.9765625 2.0273441 c -.3030937 .639832 -.3205007 .739905 -.3203125 1.826171 c .0002242 1.336431 .1608293 2.045939 .7363282 3.246094 c .4958946 1.034132 1.1835844 1.936783 1.9472656 2.554688 c .6619406 .535587 .7322516 .560867 1.0078126 .359375 c .282107 -.20626 .124685 -.56108 -.445313 -.998047 c -.6180212 -.473788 -1.2857839 -1.329765 -1.7363278 -2.228516 c -.7400486 -1.476217 -.9257648 -3.301198 -.4433593 -4.345703 c .3501094 -.758061 .8837753 -1.3239492 1.5644531 -1.658203 c .817809 -.4015966 2.012269 -.4015966 2.830078 0 c .976109 .479324 1.599333 1.353519 1.820313 2.550781 c .1319 .714664 .332068 .952234 .636718 .75586 c .141164 -.09099 .171337 -.242829 .158203 -.78711 c -.031914 -1.323089 -.957834 -2.6511972 -2.3125 -3.316406 c -.454743 -.2212609 -1.059749 -.3203662 -1.68164 -.3125 z m -.003906 3.615234 c -.072134 -.001465 -.153033 .023509 -.244141 .072266 c -.191281 .102402 -.208829 .174075 -.162109 .726563 c .147755 1.748088 1.464452 3.25256 3.171875 3.625 c .757301 .165124 .960616 .162423 1.142578 -.019532 c .363429 -.363416 .119519 -.652706 -.634766 -.755859 c -1.541693 -.21083 -2.687806 -1.387877 -2.871094 -2.947266 c -.054671 -.465046 -.185943 -.696776 -.402343 -.701172 z" class="ColorScheme-Text" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
14
src/apps/res/icons/deskflow-light/actions/22/list-add.svg
Normal 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 10 4 L 10 11 L 3 11 L 3 12 L 10 12 L 10 19 L 11 19 L 11 12 L 18 12 L 18 11 L 11 11 L 11 4 L 10 4 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 441 B |
10
src/apps/res/icons/deskflow-light/actions/22/list-remove.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg version="1.1" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-NegativeText {
|
||||
color:#da4453;
|
||||
}
|
||||
</style>
|
||||
<path class="ColorScheme-NegativeText" d="M 3.6992188 3 L 3 3.6992188 L 10.300781 11 L 3 18.300781 C 3 18.300781 3.7112147 18.993333 3.6992188 19 L 11 11.699219 L 18.300781 19 C 18.288781 18.9933 19 18.300781 19 18.300781 L 11.699219 11.001953 L 19 3.6992188 L 18.300781 3 L 11 10.300781 L 3.6992188 3 z " fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 570 B |
@ -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="m14.996094 3l-11.992188 11.992188h-.003906v4.00781h1 2 1.00781v-.003906l11.992188-11.992188-.001953-.001953.001953-.001953-4-4-.001953.001953-.001953-.001953m-1.998047 3.412109l2.589844 2.589844-7.587891 7.587891v-1.589844h-1-1v-1-.589844l6.998047-6.998047m-7.998047 7.998047v1.589844h1 1v1 .589844l-.410156.410156h-1.589844l-1-1v-1.589844l1-1" class="ColorScheme-Text"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 728 B |
12
src/apps/res/icons/deskflow-light/actions/24/fingerprint.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" id="svg2" height="24" style="" viewBox="0 0 24 24" width="24" sodipodi:docname="fingerprint.svg" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#232629;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g transform="translate(1,1)">
|
||||
<path id="path1" d="m 10.964844 2.9980469 c -1.5845236 -.0072353 -2.9422744 .2857394 -4.1777346 .9042969 c -.4112899 .2059109 -.4758434 .2776955 -.4492188 .5 c .0543735 .4537067 .2885593 .498883 .9824219 .1875 c 1.2899294 -.578856 1.9178453 -.7033109 3.5449215 -.7050782 c 1.867366 -.00153 2.554482 .1581718 4.085938 .9511719 c .263122 .1360571 1.097292 .7789323 1.408203 .4335937 c .307924 -.3078945 .144513 -.5609142 -.648437 -1.0117187 c -1.563801 -.8890431 -2.930512 -1.2511653 -4.746094 -1.2597656 z m -.046875 1.8320312 c -2.0906577 -.0015904 -4.1807664 .8256559 -5.7128909 2.4804688 c -.5926987 .640169 -1.2832031 1.689795 -1.2832031 1.9492187 c 0 .3024858 .1234451 .46875 .3496094 .46875 c .1772788 0 .3578489 -.190821 .7871094 -.8359375 c .9600458 -1.4427908 2.2051389 -2.4006204 3.8085937 -2.9296875 c 1.2435415 -.4058614 2.7001995 -.3588754 4.0996095 0 c 1.806888 .5938948 3.355915 1.916279 4.205078 3.5898438 c .184782 .3641515 .295572 .4765626 .476563 .4765626 c .311704 0 .495303 -.23344 .410156 -.5214845 c -.137293 -.4645988 -.869271 -1.5904919 -1.423828 -2.1894531 c -1.534258 -1.657146 -3.626141 -2.4866996 -5.716797 -2.4882813 z m .097656 1.8222657 c -.445604 -.00775 -.897825 .0344876 -1.3496094 .1289062 c -2.146845 .4487425 -3.9412221 2.1872289 -4.515625 4.375 c -.3048255 1.160984 -.1650506 3.057421 .3378906 4.574219 c .1503076 .453288 .223992 .547173 .4394532 .572265 c .4953707 .05757 .5425194 -.177958 .2460937 -1.203125 c -.8481973 -2.933423 -.117367 -5.4282751 1.9863281 -6.7890621 c 2.0798818 -1.3453843 4.9406298 -.948559 6.5683598 .9121093 c 1.020005 1.1659848 1.579872 3.1393058 1.134765 3.9999998 c -.294034 .568598 -1.009591 .909304 -1.597656 .761719 c -.429745 -.107851 -.940652 -.635832 -1.005859 -1.041016 c -.230123 -1.429844 -.554761 -1.988299 -1.376954 -2.371093 c -.701353 -.32655 -1.284385 -.317345 -1.9726558 .03125 c -.6413124 .324823 -1.1329202 .979024 -1.2324218 1.642578 c -.035906 .239115 -.0206307 .757671 .0351562 1.15039 c .3469606 2.446271 2.0965544 4.381247 4.5000004 4.976563 c .302262 .07484 .797346 .127554 1.099609 .117187 l .548828 -.017578 c .310632 -.157676 .327632 -.52228 0 -.701172 l -.777344 -.117187 c -.978866 -.149158 -1.383803 -.279437 -2.05664 -.658203 c -1.46318 -.823674 -2.511719 -2.609239 -2.511719 -4.277344 c 0 -.735113 .2787884 -1.164663 .927734 -1.433594 c .468905 -.194333 .474455 -.194333 .94336 0 c .593428 .24593 .879612 .658428 .953125 1.371094 c .134996 1.307917 1.042601 2.167969 2.287109 2.167969 c .998776 0 1.840549 -.647171 2.138672 -1.646485 c .291784 -.977992 -.101062 -2.621655 -.923828 -3.8710934 c -1.090395 -1.6558477 -2.895221 -2.6207549 -4.826172 -2.6542968 z m -.064453 1.8945312 c -.621891 .0078591 -1.2610341 .1220648 -1.7851564 .3261719 c -.8081421 .3957774 -1.5782434 1.1864461 -1.9765625 2.0273441 c -.3030937 .639832 -.3205007 .739905 -.3203125 1.826171 c .0002242 1.336431 .1608293 2.045939 .7363282 3.246094 c .4958946 1.034132 1.1835844 1.936783 1.9472656 2.554688 c .6619406 .535587 .7322516 .560867 1.0078126 .359375 c .282107 -.20626 .124685 -.56108 -.445313 -.998047 c -.6180212 -.473788 -1.2857839 -1.329765 -1.7363278 -2.228516 c -.7400486 -1.476217 -.9257648 -3.301198 -.4433593 -4.345703 c .3501094 -.758061 .8837753 -1.3239492 1.5644531 -1.658203 c .817809 -.4015966 2.012269 -.4015966 2.830078 0 c .976109 .479324 1.599333 1.353519 1.820313 2.550781 c .1319 .714664 .332068 .952234 .636718 .75586 c .141164 -.09099 .171337 -.242829 .158203 -.78711 c -.031914 -1.323089 -.957834 -2.6511972 -2.3125 -3.316406 c -.454743 -.2212609 -1.059749 -.3203662 -1.68164 -.3125 z m -.003906 3.615234 c -.072134 -.001465 -.153033 .023509 -.244141 .072266 c -.191281 .102402 -.208829 .174075 -.162109 .726563 c .147755 1.748088 1.464452 3.25256 3.171875 3.625 c .757301 .165124 .960616 .162423 1.142578 -.019532 c .363429 -.363416 .119519 -.652706 -.634766 -.755859 c -1.541693 -.21083 -2.687806 -1.387877 -2.871094 -2.947266 c -.054671 -.465046 -.185943 -.696776 -.402343 -.701172 z" class="ColorScheme-Text" fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
12
src/apps/res/icons/deskflow-light/actions/24/list-add.svg
Normal 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 10 4 L 10 11 L 3 11 L 3 12 L 10 12 L 10 19 L 11 19 L 11 12 L 18 12 L 18 11 L 11 11 L 11 4 L 10 4 z " class="ColorScheme-Text"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
10
src/apps/res/icons/deskflow-light/actions/24/list-remove.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24" width="24" height="24">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-NegativeText {
|
||||
color:#da4453;
|
||||
}
|
||||
</style>
|
||||
<g transform="translate(1,1)">
|
||||
<path class="ColorScheme-NegativeText" d="M 3.6992188 3 L 3 3.6992188 L 10.300781 11 L 3 18.300781 C 3 18.300781 3.7112147 18.993333 3.6992188 19 L 11 11.699219 L 18.300781 19 C 18.288781 18.9933 19 18.300781 19 18.300781 L 11.699219 11.001953 L 19 3.6992188 L 18.300781 3 L 11 10.300781 L 3.6992188 3 z " fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 615 B |
@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<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="m22.27 4l-18.27 18.27v5.73h5.73c0 0 18.269-18.269 18.27-18.27zm-2.865 4.299l4.297 4.297-11.701 11.703v-2.299h-4v-2.299zm-12.404 12.402v2.299h4v2.299l-1.701 1.701h-2l-2.297-2.297v-2z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 523 B |
@ -29,7 +29,7 @@ KDE-Extensions=.svg
|
||||
########## Directories
|
||||
########## ordered by category and alphabetically
|
||||
|
||||
Directories=actions/16,actions/22,actions/24,actions/32,apps/64,devices/64,places/64,status/16,status/22,status,24,status/64
|
||||
Directories=actions/16,actions/22,actions/24,actions/32,apps/64,devices/64,places/64,status/16,status/22,status,24,status/32,status/64
|
||||
ScaledDirectories=actions/16@2x,actions/16@3x,actions/22@2x,actions/22@3x,actions/24@2x,actions/24@3x,actions/32@2x,actions/32@3x
|
||||
|
||||
[apps/64]
|
||||
@ -157,6 +157,14 @@ Context=Places
|
||||
MinSize=48
|
||||
MaxSize=256
|
||||
|
||||
#32x32 - Fixed size - For dialog icons >!!!ONLY!!!< - DO_NOT_USE_ANYWHERE_ELSE - Color
|
||||
[status/32]
|
||||
Size=32
|
||||
Context=Status
|
||||
Type=Scalable
|
||||
MinSize=22
|
||||
MaxSize=256
|
||||
|
||||
#64x64 - Fixed size - For dialog icons >!!!ONLY!!!< - DO_NOT_USE_ANYWHERE_ELSE - Color
|
||||
[status/64]
|
||||
Size=64
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
<?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="22" height="22">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#31363b;
|
||||
}
|
||||
.ColorScheme-Background {
|
||||
color:#eff0f1;
|
||||
}
|
||||
.ColorScheme-Accent {
|
||||
color:#3daee9;
|
||||
}
|
||||
.ColorScheme-ButtonText {
|
||||
color:#31363b;
|
||||
}
|
||||
</style>
|
||||
<g id="software-updates-release" transform="translate(0,22) translate(0,-22)">
|
||||
<path style="fill:#2ecc71;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 7,7 4,10 4,19 9.0996094,19 13,19 l 5.099609,0 0,-9 -3,-3 L 13,7 9.0996094,7 Z m 0.3,1 3.7,0 3.7,0 2,2 -11.4,0 z m 1.7,3 4,0 0,5 -1,-1 -1,1 -1,-1 -1,1 z" id="path4164" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccccccccccccccc"/>
|
||||
<path style="opacity:1;fill:#2ecc71;fill-opacity:1;stroke:none" d="M 16,3 A 3,3 0 0 0 13,6 3,3 0 0 0 16,9 3,3 0 0 0 19,6 3,3 0 0 0 16,3 Z" id="path4166" inkscape:connector-curvature="0"/>
|
||||
<path style="opacity:1;fill:currentColor;fill-opacity:1;stroke:none" d="m 16,4 2,2 -1,0 0,2 -2,0 0,-2 -1,0 1,-1 1,-1 z" id="path4168" inkscape:connector-curvature="0" class="ColorScheme-Background"/>
|
||||
<rect y="-2.6645353e-15" x="0" height="22" width="22" id="rect4170" style="opacity:1;fill:none;fill-opacity:0.59905659;stroke:none"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@ -9,7 +9,6 @@ add_subdirectory(client)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(deskflow)
|
||||
add_subdirectory(io)
|
||||
add_subdirectory(ipc)
|
||||
add_subdirectory(mt)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(platform)
|
||||
|
||||
@ -46,4 +46,11 @@ public:
|
||||
*/
|
||||
virtual void setting(const std::string &valueName, const std::string &valueString) const = 0;
|
||||
//@}
|
||||
|
||||
//! Delete settings
|
||||
/*!
|
||||
Deletes all Core settings from the system.
|
||||
*/
|
||||
virtual void clearSettings() const = 0;
|
||||
//@}
|
||||
};
|
||||
|
||||
@ -67,6 +67,11 @@ void ArchSystemUnix::setting(const std::string &, const std::string &) const
|
||||
{
|
||||
}
|
||||
|
||||
void ArchSystemUnix::clearSettings() const
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
std::string ArchSystemUnix::getLibsUsed(void) const
|
||||
{
|
||||
return "not implemented.\nuse lsof on shell";
|
||||
|
||||
@ -24,6 +24,7 @@ public:
|
||||
virtual std::string setting(const std::string &) const;
|
||||
virtual void setting(const std::string &, const std::string &) const;
|
||||
virtual std::string getLibsUsed(void) const;
|
||||
virtual void clearSettings() const;
|
||||
|
||||
#ifndef __APPLE__
|
||||
enum class InhibitScreenServices
|
||||
|
||||
@ -6,12 +6,11 @@
|
||||
*/
|
||||
|
||||
#include "arch/win32/ArchDaemonWindows.h"
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#include "arch/win32/XArchWindows.h"
|
||||
#include "common/stdvector.h"
|
||||
|
||||
#include <sstream>
|
||||
#include "base/Log.h"
|
||||
|
||||
//
|
||||
// ArchDaemonWindows
|
||||
@ -61,6 +60,8 @@ void ArchDaemonWindows::installDaemon(
|
||||
const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies
|
||||
)
|
||||
{
|
||||
LOG_DEBUG("installing windows service: %s", name);
|
||||
|
||||
// open service manager
|
||||
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
|
||||
if (mgr == NULL) {
|
||||
@ -127,6 +128,8 @@ void ArchDaemonWindows::installDaemon(
|
||||
|
||||
void ArchDaemonWindows::uninstallDaemon(const char *name)
|
||||
{
|
||||
LOG_DEBUG("uninstalling windows service: %s", name);
|
||||
|
||||
// remove parameters for this service. ignore failures.
|
||||
HKEY key = openNTServicesKey();
|
||||
key = ArchMiscWindows::openKey(key, name);
|
||||
@ -165,9 +168,10 @@ void ArchDaemonWindows::uninstallDaemon(const char *name)
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(mgr);
|
||||
|
||||
// give windows a chance to remove the service before
|
||||
// we check if it still exists.
|
||||
ARCH->sleep(1);
|
||||
// give windows a chance to remove the service before we check if it still exists.
|
||||
// 100ms should be plenty of time.
|
||||
LOG_DEBUG("waiting for service to be removed");
|
||||
ARCH->sleep(0.1);
|
||||
|
||||
// handle failure. ignore error if service isn't installed anymore.
|
||||
if (!okay && isDaemonInstalled(name)) {
|
||||
@ -603,16 +607,13 @@ void ArchDaemonWindows::installDaemon()
|
||||
{
|
||||
// install default daemon if not already installed.
|
||||
if (!isDaemonInstalled(DEFAULT_DAEMON_NAME)) {
|
||||
char path[MAX_PATH];
|
||||
GetModuleFileName(ArchMiscWindows::instanceWin32(), path, MAX_PATH);
|
||||
char binPath[MAX_PATH];
|
||||
GetModuleFileName(ArchMiscWindows::instanceWin32(), binPath, MAX_PATH);
|
||||
|
||||
// wrap in quotes so a malicious user can't start \Program.exe as admin.
|
||||
std::stringstream ss;
|
||||
ss << '"';
|
||||
ss << path;
|
||||
ss << '"';
|
||||
const auto command = "\"" + std::string(binPath) + "\"";
|
||||
|
||||
installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, ss.str().c_str(), "", "");
|
||||
installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, command.c_str(), "", "");
|
||||
}
|
||||
|
||||
start(DEFAULT_DAEMON_NAME);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#include "arch/win32/ArchDaemonWindows.h"
|
||||
#include "arch/win32/XArchWindows.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
|
||||
@ -164,6 +165,15 @@ void ArchMiscWindows::deleteValue(HKEY key, const TCHAR *name)
|
||||
RegDeleteValue(key, name);
|
||||
}
|
||||
|
||||
void ArchMiscWindows::deleteKeyTree(HKEY key, const TCHAR *name)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(name != NULL);
|
||||
if (key == NULL || name == NULL)
|
||||
return;
|
||||
RegDeleteTree(key, name);
|
||||
}
|
||||
|
||||
bool ArchMiscWindows::hasValue(HKEY key, const TCHAR *name)
|
||||
{
|
||||
DWORD type;
|
||||
@ -457,3 +467,19 @@ void ArchMiscWindows::setInstanceWin32(HINSTANCE instance)
|
||||
assert(instance != NULL);
|
||||
s_instanceWin32 = instance;
|
||||
}
|
||||
|
||||
std::string ArchMiscWindows::getActiveDesktopName()
|
||||
{
|
||||
HDESK desk = OpenInputDesktop(0, TRUE, GENERIC_READ);
|
||||
if (desk == nullptr) {
|
||||
LOG((CLOG_ERR "could not open input desktop"));
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
DWORD size;
|
||||
GetUserObjectInformation(desk, UOI_NAME, nullptr, 0, &size);
|
||||
auto *name = (TCHAR *)alloca(size + sizeof(TCHAR));
|
||||
GetUserObjectInformation(desk, UOI_NAME, name, size, &size);
|
||||
CloseDesktop(desk);
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -99,6 +99,9 @@ public:
|
||||
//! Delete a value
|
||||
static void deleteValue(HKEY parent, const TCHAR *name);
|
||||
|
||||
//! Delete a tree of keys from the registry
|
||||
static void deleteKeyTree(HKEY parent, const TCHAR *name);
|
||||
|
||||
//! Test if a value exists
|
||||
static bool hasValue(HKEY key, const TCHAR *name);
|
||||
|
||||
@ -155,12 +158,11 @@ public:
|
||||
static bool getParentProcessName(std::string &name);
|
||||
|
||||
static HINSTANCE instanceWin32();
|
||||
|
||||
static void setInstanceWin32(HINSTANCE instance);
|
||||
|
||||
static BOOL WINAPI getProcessEntry(PROCESSENTRY32 &entry, DWORD processID);
|
||||
static BOOL WINAPI getSelfProcessEntry(PROCESSENTRY32 &entry);
|
||||
static BOOL WINAPI getParentProcessEntry(PROCESSENTRY32 &entry);
|
||||
static std::string getActiveDesktopName();
|
||||
|
||||
private:
|
||||
//! Open and return a registry key, closing the parent key
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
|
||||
#include "arch/XArch.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
|
||||
#include "tchar.h"
|
||||
@ -17,7 +18,7 @@
|
||||
#include <psapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
static const char *s_settingsKeyNames[] = {_T("SOFTWARE"), _T(kAppName), NULL};
|
||||
static const TCHAR *s_settingsKeyNames[] = {_T("SOFTWARE"), _T(kAppName), NULL};
|
||||
|
||||
//
|
||||
// ArchSystemWindows
|
||||
@ -86,6 +87,11 @@ void ArchSystemWindows::setting(const std::string &valueName, const std::string
|
||||
ArchMiscWindows::setValue(key, valueName.c_str(), valueString.c_str());
|
||||
}
|
||||
|
||||
void ArchSystemWindows::clearSettings() const
|
||||
{
|
||||
ArchMiscWindows::deleteKeyTree(HKEY_LOCAL_MACHINE, kWindowsRegistryKey);
|
||||
}
|
||||
|
||||
bool ArchSystemWindows::isWOW64() const
|
||||
{
|
||||
#if WINVER >= _WIN32_WINNT_WINXP
|
||||
|
||||
@ -23,6 +23,7 @@ public:
|
||||
virtual std::string getPlatformName() const;
|
||||
virtual std::string setting(const std::string &valueName) const;
|
||||
virtual void setting(const std::string &valueName, const std::string &valueString) const;
|
||||
virtual void clearSettings() const;
|
||||
|
||||
bool isWOW64() const;
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ add_library(base STATIC
|
||||
EventQueue.h
|
||||
EventTypes.cpp
|
||||
EventTypes.h
|
||||
finally.h
|
||||
FunctionEventJob.cpp
|
||||
FunctionEventJob.h
|
||||
FunctionJob.cpp
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include "base/Event.h"
|
||||
#include "base/EventQueue.h"
|
||||
|
||||
//
|
||||
// Event
|
||||
|
||||
@ -8,21 +8,17 @@
|
||||
#include "base/EventQueue.h"
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "base/IEventJob.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/SimpleEventQueueBuffer.h"
|
||||
#include "base/Stopwatch.h"
|
||||
#include "base/XBase.h"
|
||||
#include "mt/Lock.h"
|
||||
#include "mt/Mutex.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
EVENT_TYPE_ACCESSOR(Client)
|
||||
EVENT_TYPE_ACCESSOR(IStream)
|
||||
EVENT_TYPE_ACCESSOR(IpcClient)
|
||||
EVENT_TYPE_ACCESSOR(IpcClientProxy)
|
||||
EVENT_TYPE_ACCESSOR(IpcServer)
|
||||
EVENT_TYPE_ACCESSOR(IpcServerProxy)
|
||||
EVENT_TYPE_ACCESSOR(IDataSocket)
|
||||
EVENT_TYPE_ACCESSOR(IListenSocket)
|
||||
EVENT_TYPE_ACCESSOR(ISocket)
|
||||
@ -55,10 +51,6 @@ EventQueue::EventQueue()
|
||||
m_nextType(Event::kLast),
|
||||
m_typesForClient(NULL),
|
||||
m_typesForIStream(NULL),
|
||||
m_typesForIpcClient(NULL),
|
||||
m_typesForIpcClientProxy(NULL),
|
||||
m_typesForIpcServer(NULL),
|
||||
m_typesForIpcServerProxy(NULL),
|
||||
m_typesForIDataSocket(NULL),
|
||||
m_typesForIListenSocket(NULL),
|
||||
m_typesForISocket(NULL),
|
||||
|
||||
@ -130,10 +130,6 @@ public:
|
||||
//
|
||||
ClientEvents &forClient();
|
||||
IStreamEvents &forIStream();
|
||||
IpcClientEvents &forIpcClient();
|
||||
IpcClientProxyEvents &forIpcClientProxy();
|
||||
IpcServerEvents &forIpcServer();
|
||||
IpcServerProxyEvents &forIpcServerProxy();
|
||||
IDataSocketEvents &forIDataSocket();
|
||||
IListenSocketEvents &forIListenSocket();
|
||||
ISocketEvents &forISocket();
|
||||
@ -153,10 +149,6 @@ public:
|
||||
private:
|
||||
ClientEvents *m_typesForClient;
|
||||
IStreamEvents *m_typesForIStream;
|
||||
IpcClientEvents *m_typesForIpcClient;
|
||||
IpcClientProxyEvents *m_typesForIpcClientProxy;
|
||||
IpcServerEvents *m_typesForIpcServer;
|
||||
IpcServerProxyEvents *m_typesForIpcServerProxy;
|
||||
IDataSocketEvents *m_typesForIDataSocket;
|
||||
IListenSocketEvents *m_typesForIListenSocket;
|
||||
ISocketEvents *m_typesForISocket;
|
||||
|
||||
@ -45,26 +45,6 @@ REGISTER_EVENT(IStream, inputShutdown)
|
||||
REGISTER_EVENT(IStream, outputShutdown)
|
||||
REGISTER_EVENT(IStream, inputFormatError)
|
||||
|
||||
//
|
||||
// IpcClient
|
||||
//
|
||||
|
||||
REGISTER_EVENT(IpcClient, connected)
|
||||
REGISTER_EVENT(IpcClient, messageReceived)
|
||||
|
||||
//
|
||||
// IpcClientProxy
|
||||
//
|
||||
|
||||
REGISTER_EVENT(IpcClientProxy, messageReceived)
|
||||
REGISTER_EVENT(IpcClientProxy, disconnected)
|
||||
|
||||
//
|
||||
// IpcServerProxy
|
||||
//
|
||||
|
||||
REGISTER_EVENT(IpcServerProxy, messageReceived)
|
||||
|
||||
//
|
||||
// IDataSocket
|
||||
//
|
||||
@ -167,13 +147,6 @@ REGISTER_EVENT(IScreen, shapeChanged)
|
||||
REGISTER_EVENT(IScreen, suspend)
|
||||
REGISTER_EVENT(IScreen, resume)
|
||||
|
||||
//
|
||||
// IpcServer
|
||||
//
|
||||
|
||||
REGISTER_EVENT(IpcServer, clientConnected)
|
||||
REGISTER_EVENT(IpcServer, messageReceived)
|
||||
|
||||
//
|
||||
// Clipboard
|
||||
//
|
||||
|
||||
@ -145,94 +145,6 @@ private:
|
||||
Event::Type m_inputFormatError;
|
||||
};
|
||||
|
||||
class IpcClientEvents : public EventTypes
|
||||
{
|
||||
public:
|
||||
IpcClientEvents() : m_connected(Event::kUnknown), m_messageReceived(Event::kUnknown)
|
||||
{
|
||||
}
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Raised when the socket is connected.
|
||||
Event::Type connected();
|
||||
|
||||
//! Raised when a message is received.
|
||||
Event::Type messageReceived();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
Event::Type m_connected;
|
||||
Event::Type m_messageReceived;
|
||||
};
|
||||
|
||||
class IpcClientProxyEvents : public EventTypes
|
||||
{
|
||||
public:
|
||||
IpcClientProxyEvents() : m_messageReceived(Event::kUnknown), m_disconnected(Event::kUnknown)
|
||||
{
|
||||
}
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Raised when the server receives a message from a client.
|
||||
Event::Type messageReceived();
|
||||
|
||||
//! Raised when the client disconnects from the server.
|
||||
Event::Type disconnected();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
Event::Type m_messageReceived;
|
||||
Event::Type m_disconnected;
|
||||
};
|
||||
|
||||
class IpcServerEvents : public EventTypes
|
||||
{
|
||||
public:
|
||||
IpcServerEvents() : m_clientConnected(Event::kUnknown), m_messageReceived(Event::kUnknown)
|
||||
{
|
||||
}
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Raised when we have created the client proxy.
|
||||
Event::Type clientConnected();
|
||||
|
||||
//! Raised when a message is received through a client proxy.
|
||||
Event::Type messageReceived();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
Event::Type m_clientConnected;
|
||||
Event::Type m_messageReceived;
|
||||
};
|
||||
|
||||
class IpcServerProxyEvents : public EventTypes
|
||||
{
|
||||
public:
|
||||
IpcServerProxyEvents() : m_messageReceived(Event::kUnknown)
|
||||
{
|
||||
}
|
||||
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Raised when the client receives a message from the server.
|
||||
Event::Type messageReceived();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
Event::Type m_messageReceived;
|
||||
};
|
||||
|
||||
class IDataSocketEvents : public EventTypes
|
||||
{
|
||||
public:
|
||||
|
||||
@ -21,10 +21,6 @@ class EventQueueTimer;
|
||||
// Event type registration classes.
|
||||
class ClientEvents;
|
||||
class IStreamEvents;
|
||||
class IpcClientEvents;
|
||||
class IpcClientProxyEvents;
|
||||
class IpcServerEvents;
|
||||
class IpcServerProxyEvents;
|
||||
class IDataSocketEvents;
|
||||
class IListenSocketEvents;
|
||||
class ISocketEvents;
|
||||
@ -216,10 +212,6 @@ public:
|
||||
|
||||
virtual ClientEvents &forClient() = 0;
|
||||
virtual IStreamEvents &forIStream() = 0;
|
||||
virtual IpcClientEvents &forIpcClient() = 0;
|
||||
virtual IpcClientProxyEvents &forIpcClientProxy() = 0;
|
||||
virtual IpcServerEvents &forIpcServer() = 0;
|
||||
virtual IpcServerProxyEvents &forIpcServerProxy() = 0;
|
||||
virtual IDataSocketEvents &forIDataSocket() = 0;
|
||||
virtual IListenSocketEvents &forIListenSocket() = 0;
|
||||
virtual ISocketEvents &forISocket() = 0;
|
||||
|
||||
@ -128,7 +128,7 @@ Log::Log(bool singleton)
|
||||
|
||||
// other initalization
|
||||
m_maxPriority = g_defaultMaxPriority;
|
||||
insert(new ConsoleLogOutputter);
|
||||
insert(new ConsoleLogOutputter); // NOSONAR - Adopted by `Log`
|
||||
|
||||
if (singleton) {
|
||||
s_log = this;
|
||||
@ -208,27 +208,18 @@ void Log::print(const char *file, int line, const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
void Log::insert(ILogOutputter *outputter, bool alwaysAtHead)
|
||||
void Log::insert(ILogOutputter *adoptedOutputter, bool alwaysAtHead)
|
||||
{
|
||||
assert(outputter != NULL);
|
||||
assert(adoptedOutputter != NULL);
|
||||
|
||||
ArchMutexLock lock(m_mutex);
|
||||
if (alwaysAtHead) {
|
||||
m_alwaysOutputters.push_front(outputter);
|
||||
m_alwaysOutputters.push_front(adoptedOutputter);
|
||||
} else {
|
||||
m_outputters.push_front(outputter);
|
||||
m_outputters.push_front(adoptedOutputter);
|
||||
}
|
||||
|
||||
outputter->open(kAppName);
|
||||
|
||||
// Issue 41
|
||||
// don't show log unless user requests it, as some users find this
|
||||
// feature irritating (i.e. when they lose network connectivity).
|
||||
// in windows the log window can be displayed by selecting "show log"
|
||||
// from the deskflow system tray icon.
|
||||
// if this causes problems for other architectures, then a different
|
||||
// work around should be attempted.
|
||||
// outputter->show(false);
|
||||
adoptedOutputter->open(kAppName);
|
||||
}
|
||||
|
||||
void Log::remove(ILogOutputter *outputter)
|
||||
|
||||
@ -42,10 +42,12 @@ public:
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Add an outputter to the head of the list
|
||||
//! Add an outputter to the head of the list and adopts it.
|
||||
/*!
|
||||
Inserts an outputter to the head of the outputter list. When the
|
||||
logger writes a message, it goes to the outputter at the head of
|
||||
Inserts an outputter to the head of the outputter list. The outputter
|
||||
is deleted when Log destructor is called.
|
||||
|
||||
When the logger writes a message, it goes to the outputter at the head of
|
||||
the outputter list. If that outputter's \c write() method returns
|
||||
true then it also goes to the next outputter, as so on until an
|
||||
outputter returns false or there are no more outputters. Outputters
|
||||
@ -57,7 +59,7 @@ public:
|
||||
By default, the logger has one outputter installed which writes to
|
||||
the console.
|
||||
*/
|
||||
void insert(ILogOutputter *adopted, bool alwaysAtHead = false);
|
||||
void insert(ILogOutputter *adoptedOutputter, bool alwaysAtHead = false);
|
||||
|
||||
//! Remove an outputter from the list
|
||||
/*!
|
||||
|
||||
@ -178,6 +178,17 @@ std::string toHex(const std::string &subject, int width, const char fill)
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string toHex(const std::vector<uint8_t> &input, int width, const char fill)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex;
|
||||
for (unsigned int i = 0; i < input.size(); i++) {
|
||||
ss << std::setw(width) << std::setfill(fill) << static_cast<int>(input[i]);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
int fromHexChar(char c)
|
||||
{
|
||||
|
||||
@ -65,6 +65,15 @@ Return a new hexString
|
||||
*/
|
||||
std::string toHex(const std::string &subject, int width, const char fill = '0');
|
||||
|
||||
/**
|
||||
* @brief toHex Convert each value in input into a hex string
|
||||
* @param input vector of uint8_t
|
||||
* @param width
|
||||
* @param fill fill character 0 is default
|
||||
* @return a hex string
|
||||
*/
|
||||
std::string toHex(const std::vector<uint8_t> &input, int width, const char fill = '0');
|
||||
|
||||
/**
|
||||
* @brief fromHexChar Convert a single char to its hexidecmal value
|
||||
* @param c input char 0-F
|
||||
|
||||
53
src/lib/base/finally.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
||||
* SPDX-FileCopyrightText: (C) 2021 Barrier Contributors
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace deskflow {
|
||||
|
||||
/**
|
||||
* @brief The `FinalAction` class implements a common pattern for calling an action at the end of a function.
|
||||
*/
|
||||
template <class Callable> class FinalAction
|
||||
{
|
||||
public:
|
||||
FinalAction() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
FinalAction(Callable callable) noexcept : m_callable{callable}
|
||||
{
|
||||
}
|
||||
|
||||
~FinalAction() noexcept
|
||||
{
|
||||
if (!m_invoked) {
|
||||
m_callable();
|
||||
}
|
||||
}
|
||||
|
||||
FinalAction(FinalAction &&other) noexcept : m_callable{std::move(other.m_callable)}
|
||||
{
|
||||
std::swap(m_invoked, other.m_invoked);
|
||||
}
|
||||
|
||||
FinalAction(const FinalAction &) = delete;
|
||||
FinalAction &operator=(const FinalAction &) = delete;
|
||||
|
||||
private:
|
||||
bool m_invoked = false;
|
||||
Callable m_callable;
|
||||
};
|
||||
|
||||
template <class Callable> inline FinalAction<Callable> finally(Callable &&callable) noexcept
|
||||
{
|
||||
return FinalAction<Callable>(std::forward<Callable>(callable));
|
||||
}
|
||||
|
||||
} // namespace deskflow
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 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
|
||||
@ -132,10 +133,10 @@ SystemLogger::SystemLogger(const char *title, bool blockConsole) : m_stop(NULL)
|
||||
{
|
||||
// redirect log messages
|
||||
if (blockConsole) {
|
||||
m_stop = new StopLogOutputter;
|
||||
m_stop = new StopLogOutputter; // NOSONAR - Adopted by `Log`
|
||||
CLOG->insert(m_stop);
|
||||
}
|
||||
m_syslog = new SystemLogOutputter;
|
||||
m_syslog = new SystemLogOutputter; // NOSONAR - Adopted by `Log`
|
||||
m_syslog->open(title);
|
||||
CLOG->insert(m_syslog);
|
||||
}
|
||||
@ -150,55 +151,6 @@ SystemLogger::~SystemLogger()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// BufferedLogOutputter
|
||||
//
|
||||
|
||||
BufferedLogOutputter::BufferedLogOutputter(uint32_t maxBufferSize) : m_maxBufferSize(maxBufferSize)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
BufferedLogOutputter::~BufferedLogOutputter()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
BufferedLogOutputter::const_iterator BufferedLogOutputter::begin() const
|
||||
{
|
||||
return m_buffer.begin();
|
||||
}
|
||||
|
||||
BufferedLogOutputter::const_iterator BufferedLogOutputter::end() const
|
||||
{
|
||||
return m_buffer.end();
|
||||
}
|
||||
|
||||
void BufferedLogOutputter::open(const char *)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void BufferedLogOutputter::close()
|
||||
{
|
||||
// remove all elements from the buffer
|
||||
m_buffer.clear();
|
||||
}
|
||||
|
||||
void BufferedLogOutputter::show(bool)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
bool BufferedLogOutputter::write(ELevel, const char *message)
|
||||
{
|
||||
while (m_buffer.size() >= m_maxBufferSize) {
|
||||
m_buffer.pop_front();
|
||||
}
|
||||
m_buffer.push_back(std::string(message));
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// FileLogOutputter
|
||||
//
|
||||
|
||||