Compare commits
222 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bc96ddebdd | |||
| 80606ef040 | |||
| 836d9b9a2b | |||
| f2063f9e05 | |||
| a74d792b5b | |||
| 256ba2411b | |||
| 0a23e62093 | |||
| e38a8e6b15 | |||
| 6f022ff700 | |||
| 265c2c2a2c | |||
| 1594b8e760 | |||
| 029cb8fc0b | |||
| 8e236e7e5c | |||
| 38b2798bb7 | |||
| d580dfba57 | |||
| da4237f349 | |||
| a78d1acc71 | |||
| 24d5b26da2 | |||
| 9c81f1c045 | |||
| 899a49d09a | |||
| 3a4bf35e22 | |||
| 495331108b | |||
| a7ce936d68 | |||
| f6ccd2a25b | |||
| 5d310be807 | |||
| bd674f546b | |||
| cc821f750d | |||
| 2485e993a4 | |||
| b5d12b8aa5 | |||
| 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,8 +18,8 @@ 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_PATCH 0)
|
||||
set(DESKFLOW_VERSION_MINOR 20)
|
||||
set(DESKFLOW_VERSION_PATCH 1)
|
||||
set(DESKFLOW_VERSION_TWEAK 0)
|
||||
|
||||
# Get the version from git if it's a git repository
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
MICROSOFT SOFTWARE LICENSE TERMS
|
||||
|
||||
MICROSOFT VISUAL C++ 2015 - 2022 RUNTIME
|
||||
|
||||
These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
|
||||
|
||||
IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
|
||||
|
||||
1. INSTALLATION AND USE RIGHTS.
|
||||
|
||||
You may install and use any number of copies of the software.
|
||||
|
||||
2. TERMS FOR SPECIFIC COMPONENTS.
|
||||
|
||||
a. Microsoft Platforms. The software may include components from Microsoft Windows; Microsoft Windows Server; Microsoft SQL Server; Microsoft Exchange; Microsoft Office; and Microsoft SharePoint. These components are governed by separate agreements and their own product support policies, as described in the Microsoft “Licenses” folder accompanying the software, except that, if license terms for those components are also included in the associated installation directory, those license terms control.
|
||||
|
||||
b. Third Party Components. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the notices file(s) accompanying the software.
|
||||
|
||||
3. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not
|
||||
|
||||
· work around any technical limitations in the software;
|
||||
|
||||
· reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
|
||||
|
||||
· remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
|
||||
|
||||
· use the software in any way that is against the law;
|
||||
|
||||
· share, publish, rent or lease the software; or
|
||||
|
||||
· provide the software as a stand-alone offering or combined with any of your applications for others to use, or transfer the software or this agreement to any third party.
|
||||
|
||||
4. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
|
||||
|
||||
5. SUPPORT SERVICES. Because this software is “as is,” we may not provide support services for it.
|
||||
|
||||
6. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
|
||||
|
||||
7. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
|
||||
|
||||
8. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
|
||||
|
||||
a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
|
||||
|
||||
b. Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
|
||||
|
||||
c. Germany and Austria.
|
||||
|
||||
(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
|
||||
|
||||
(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
|
||||
|
||||
Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
|
||||
|
||||
9. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
|
||||
10. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
|
||||
|
||||
This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
|
||||
|
||||
It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
|
||||
@ -64,7 +64,12 @@ For instructions on building Deskflow, use the wiki page: [Building](https://git
|
||||
|
||||
We support all major operating systems, including Windows, macOS, Linux, and Unix-like BSD-derived.
|
||||
|
||||
Windows 10 or higher is required.
|
||||
> [!NOTE]
|
||||
> On Windows, you will need to install the
|
||||
> [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version).
|
||||
> Download latest: [`vc_redist.x64.exe`](https://aka.ms/vs/17/release/vc_redist.x64.exe)
|
||||
|
||||
Windows 10 or higher is required.
|
||||
|
||||
macOS 12 or higher is required.
|
||||
|
||||
@ -167,6 +172,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.
|
||||
|
||||
14
REUSE.toml
@ -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"
|
||||
@ -121,12 +127,6 @@ precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "deploy/windows/Microsoft_VC142_CRT_x64.msm"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Microsoft"
|
||||
SPDX-License-Identifier = "LicenseRef-Microsoft-vc-redist"
|
||||
|
||||
[[annotations]]
|
||||
path = "src/apps/deskflow-client/deskflow-client.exe.manifest"
|
||||
precedence = "override"
|
||||
|
||||
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
|
||||
@ -8,10 +8,9 @@ macro(configure_libs)
|
||||
if(UNIX)
|
||||
configure_unix_libs()
|
||||
elseif(WIN32)
|
||||
find_package(Python REQUIRED QUIET)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /D _BIND_TO_CURRENT_VCLIBS_VERSION=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2 /Ob2")
|
||||
list(APPEND libs Wtsapi32 Userenv Wininet comsuppw Shlwapi)
|
||||
list(APPEND libs Wtsapi32 Userenv Wininet comsuppw Shlwapi version)
|
||||
add_definitions(
|
||||
/DWIN32
|
||||
/D_WINDOWS
|
||||
@ -21,6 +20,9 @@ macro(configure_libs)
|
||||
endif()
|
||||
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core Widgets Network)
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS DBus)
|
||||
endif()
|
||||
|
||||
# Define the location of Qt deployment tool
|
||||
if(WIN32)
|
||||
@ -33,33 +35,12 @@ macro(configure_libs)
|
||||
find_program(DEPLOYQT macdeployqt)
|
||||
endif()
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
message(STATUS "Qt version: ${Qt6_VERSION}")
|
||||
|
||||
# TODO SSL check can happen in lib/net when don't have to deploy it any longer on windows
|
||||
|
||||
# Apple has to use static libraries because "Use of the Apple-provided OpenSSL
|
||||
# libraries by apps is strongly discouraged."
|
||||
# https://developer.apple.com/library/archive/documentation/Security/Conceptual/cryptoservices/SecureNetworkCommunicationAPIs/SecureNetworkCommunicationAPIs.html
|
||||
if(APPLE)
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
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)
|
||||
message(STATUS "Enabling code 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,36 @@
|
||||
</branding>
|
||||
<content_rating type="oars-1.0" />
|
||||
<releases>
|
||||
<release version="1.19.0" date="2025-1-31" urgency="high">
|
||||
<release version="1.20.1" date="2025-03-07" urgency="low">
|
||||
<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 introduces a Windows dependency requirement and fixes a macOS bug.</p>
|
||||
<ul>
|
||||
<li>Fix: macOS menu bar icon invisible when menu bar is light</li>
|
||||
<li>Feature: Add Windows installer check for Visual C++ Redistributable</li>
|
||||
<li>Feature: Prevent Windows binaries running if MSVC runtime too old</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.20.1</url>
|
||||
</release>
|
||||
<release version="1.20.0" date="2025-03-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-01-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>
|
||||
<ul>
|
||||
<li>Feature: New Fallback icon theme</li>
|
||||
<li>Feature: Allow only one gui instance</li>
|
||||
@ -53,11 +87,11 @@
|
||||
<li>Lots of Internal Cleanup</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.19.0</url>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.19.0</url>
|
||||
</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>
|
||||
@ -72,7 +106,7 @@
|
||||
<li>Update the windows clipboard format listener to monitor the clipboard</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.18.0</url>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.18.0</url>
|
||||
</release>
|
||||
<release version="1.17.2" date="2024-11-20" urgency="medium">
|
||||
<description>
|
||||
@ -126,11 +160,11 @@
|
||||
<li>ci: build flatpaks</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.2</url>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.2</url>
|
||||
</release>
|
||||
<release version="1.17.1" date="2024-11-7" urgency="high">
|
||||
<release version="1.17.1" date="2024-11-07" 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>
|
||||
@ -243,11 +277,11 @@
|
||||
<li>ci: adjust pacakge script to use the names we would like when in cpack</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.1</url>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.1</url>
|
||||
</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>
|
||||
@ -293,7 +327,7 @@
|
||||
<li>Use sonarsource/sonarcloud-github-c-cpp</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.0</url>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.17.0</url>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
|
||||
@ -46,7 +46,6 @@ list(APPEND CPACK_WIX_EXTENSIONS "WixToolset.Util.wixext" "WixToolset.Firewall.w
|
||||
list(APPEND CPACK_WIX_CUSTOM_XMLNS "util=http://wixtoolset.org/schemas/v4/wxs/util" "firewall=http://wixtoolset.org/schemas/v4/wxs/firewall")
|
||||
|
||||
# The patch has to know the full path of our msm file
|
||||
set(CPACK_WIX_MSM_FILE "${MY_DIR}/Microsoft_VC142_CRT_x64.msm")
|
||||
configure_file(
|
||||
${MY_DIR}/wix-patch.xml.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wix-patch.xml @ONLY
|
||||
|
||||
@ -1,25 +1,50 @@
|
||||
<CPackWiXPatch>
|
||||
<CPackWiXFragment Id="CM_CP_deskflow_daemon.exe">
|
||||
<ServiceInstall Description="Controls the Deskflow foreground processes." DisplayName="Deskflow" ErrorControl="normal" Id="ServiceInstall" Name="Deskflow" Start="auto" Type="ownProcess">
|
||||
<util:ServiceConfig FirstFailureActionType="restart" ResetPeriodInDays="1" RestartServiceDelayInSeconds="1" SecondFailureActionType="restart" ThirdFailureActionType="restart"/>
|
||||
<ServiceInstall
|
||||
Id="ServiceInstall"
|
||||
Name="Deskflow"
|
||||
DisplayName="Deskflow"
|
||||
Description="Runs the Core process on secure desktops (UAC prompts, login screen, etc)."
|
||||
ErrorControl="normal"
|
||||
Start="auto"
|
||||
Type="ownProcess">
|
||||
<util:ServiceConfig
|
||||
ResetPeriodInDays="1"
|
||||
RestartServiceDelayInSeconds="1"
|
||||
FirstFailureActionType="restart"
|
||||
SecondFailureActionType="restart"
|
||||
ThirdFailureActionType="none"
|
||||
/>
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceControl" Name="Deskflow" Remove="uninstall" Start="install" Stop="both"/>
|
||||
</CPackWiXFragment>
|
||||
|
||||
<CPackWiXFragment Id="CM_CP_deskflow_server.exe">
|
||||
<firewall:FirewallException Id="ServerFirewallException" Name="Deskflow Server" Program="[INSTALL_ROOT]deskflow-server.exe" Scope="any"/>
|
||||
</CPackWiXFragment>
|
||||
|
||||
<CPackWiXFragment Id="CM_CP_deskflow_client.exe">
|
||||
<firewall:FirewallException Id="ClientFirewallException" Name="Deskflow Client" Program="[INSTALL_ROOT]deskflow-client.exe" Scope="any"/>
|
||||
</CPackWiXFragment>
|
||||
|
||||
<CPackWiXFragment Id="#PRODUCT">
|
||||
<StandardDirectory Id="TARGETDIR">
|
||||
<Merge Id="VCRedist" SourceFile="@CPACK_WIX_MSM_FILE@" DiskId="1" Language="0"/>
|
||||
</StandardDirectory >
|
||||
<Feature Id="VCRedist" Title="Visual C++ Runtime" AllowAbsent="no" AllowAdvertise="yes" Display="hidden" InstallDefault="local" TypicalDefault="install">
|
||||
<MergeRef Id="VCRedist" Primary="yes"/>
|
||||
</Feature>
|
||||
<Property Id="VC_REDIST_INSTALLED">
|
||||
<RegistrySearch
|
||||
Id="FindVCRedist"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64"
|
||||
Name="Installed"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
|
||||
<CustomAction Id="Run_Deskflow" ExeCommand="Deskflow" FileRef="CM_FP_deskflow.exe" Return="asyncNoWait"/>
|
||||
|
||||
<CustomAction
|
||||
Id="ShowVCRedistError"
|
||||
Error="Latest Microsoft Visual C++ Redistributable is required. Please install it before proceeding."/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="ShowVCRedistError" Before="InstallServices" Condition="NOT Installed AND NOT VC_REDIST_INSTALLED"/>
|
||||
<Custom Action="Run_Deskflow" OnExit="success" Condition="NOT Installed"/>
|
||||
</InstallExecuteSequence>
|
||||
</CPackWiXFragment>
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
ArchMiscWindows::guardRuntimeVersion();
|
||||
|
||||
// record window instance for tray icon, etc
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
||||
#endif
|
||||
|
||||
@ -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,7 +8,8 @@ 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 "${CMAKE_PROJECT_PROPER_NAME} Daemon for handling 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)
|
||||
@ -18,12 +19,13 @@ if(WIN32)
|
||||
arch
|
||||
base
|
||||
io
|
||||
ipc
|
||||
mt
|
||||
net
|
||||
platform
|
||||
app
|
||||
${libs})
|
||||
common
|
||||
${libs}
|
||||
Qt6::Core)
|
||||
|
||||
install(
|
||||
TARGETS ${target}
|
||||
|
||||
@ -1,31 +1,147 @@
|
||||
/*
|
||||
* 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/EventQueue.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
#include "deskflow/DaemonApp.h"
|
||||
#include "deskflow/ipc/DaemonIpcServer.h"
|
||||
|
||||
#include <iostream>
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
#ifdef SYSAPI_UNIX
|
||||
|
||||
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
|
||||
ArchMiscWindows::guardRuntimeVersion();
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Important: Log the app name and version number to the log file after the daemon app init
|
||||
// because the file log outputter is created there. Logging before would only log to stdout
|
||||
// which is not useful for troubleshooting Windows services.
|
||||
// It's important to write the version number to the log file so we can be certain the old daemon
|
||||
// was uninstalled, since sometimes Windows services can get stuck and fail to be removed.
|
||||
LOG_PRINT("%s Daemon v%s", kAppName, kDisplayVersion);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -8,14 +8,10 @@ else()
|
||||
set(target deskflow)
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
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 +63,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 +74,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 +88,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
|
||||
)
|
||||
@ -109,6 +103,7 @@ add_executable(${target} WIN32 MACOSX_BUNDLE
|
||||
target_link_libraries(
|
||||
${target}
|
||||
gui
|
||||
common
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network)
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#include "ui_AboutDialog.h"
|
||||
|
||||
#include "common/constants.h"
|
||||
#include "gui/style_utils.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QDateTime>
|
||||
@ -32,15 +31,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui{std::make_unique
|
||||
ui->btnCopyVersion->setIcon(QIcon::fromTheme(QIcon::ThemeIcon::EditCopy));
|
||||
connect(ui->btnCopyVersion, &QPushButton::clicked, this, &AboutDialog::copyVersionText);
|
||||
|
||||
// Set up the displayed version number
|
||||
auto versionString = QString(kVersion);
|
||||
if (versionString.endsWith(QStringLiteral(".0"))) {
|
||||
versionString.chop(2);
|
||||
} else {
|
||||
versionString.append(QStringLiteral(" (%1)").arg(kVersionGitSha));
|
||||
}
|
||||
|
||||
ui->lblVersion->setText(versionString);
|
||||
ui->lblVersion->setText(kDisplayVersion);
|
||||
|
||||
ui->lblDescription->setText(kAppDescription);
|
||||
ui->lblCopyright->setText(kCopyright);
|
||||
@ -49,8 +40,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)
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
ArchMiscWindows::guardRuntimeVersion();
|
||||
|
||||
// record window instance for tray icon, etc
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
||||
#endif
|
||||
@ -28,6 +30,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)
|
||||
|
||||
@ -82,9 +82,8 @@ add_library(arch STATIC ${PLATFORM_CODE}
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(arch ${CMAKE_DL_LIBS} ${libs})
|
||||
target_link_libraries(arch ${libs})
|
||||
if(NOT APPLE)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS DBus)
|
||||
target_link_libraries(arch Qt6::DBus)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -135,7 +135,7 @@ private:
|
||||
};
|
||||
|
||||
#define DEFAULT_DAEMON_NAME _T(kAppName)
|
||||
#define DEFAULT_DAEMON_INFO _T("Manages the Deskflow foreground processes.")
|
||||
#define DEFAULT_DAEMON_INFO _T("Runs the Core process on secure desktops (UAC prompts, login screen, etc).")
|
||||
|
||||
#define LEGACY_SERVER_DAEMON_NAME _T("Deskflow Server")
|
||||
#define LEGACY_CLIENT_DAEMON_NAME _T("Deskflow Client")
|
||||
|
||||
@ -6,15 +6,48 @@
|
||||
*/
|
||||
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
|
||||
#include "arch/win32/ArchDaemonWindows.h"
|
||||
#include "arch/win32/XArchWindows.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
#include "base/String.h"
|
||||
|
||||
#include <Wtsapi32.h>
|
||||
#pragma warning(disable : 4099)
|
||||
#include <Userenv.h>
|
||||
#pragma warning(default : 4099)
|
||||
|
||||
#include <array>
|
||||
|
||||
// Welcome to DLL hell! :)
|
||||
//
|
||||
// Microsoft lets you run a program with an old runtime DLL, as long as the name matches.
|
||||
// Unfortunately if you compile on VS2022 and then use the VS2019 runtime, which both have the
|
||||
// same runtime DLL name, the app will randomly crash (e.g. access violation) or break in strange
|
||||
// and unpredictable ways due to ABI differences.
|
||||
//
|
||||
// In Windows, there is no concept of requiring a minimum version of the runtime DLL, so we have
|
||||
// to check the version ourselves.
|
||||
//
|
||||
// Our CI is set up to build with the latest compiler, so in this case we should insist on the
|
||||
// latest runtime DLL.
|
||||
//
|
||||
// As a developer convenience, we also allow builds on older compilers such as the minimum
|
||||
// requirements for the current Qt version we support.
|
||||
//
|
||||
// See table of the compiler versions and the matching runtime DLL versions:
|
||||
// https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd
|
||||
#if _MSC_VER >= 1942 // Visual Studio 2022 Update 12 (v17.12.4)
|
||||
const auto kRequiredMajor = 14;
|
||||
const auto kRequiredMinor = 42;
|
||||
#elif _MSC_VER >= 1920 // Visual Studio 2019 Update 7 (v16.7)
|
||||
const auto kRequiredMajor = 14;
|
||||
const auto kRequiredMinor = 27;
|
||||
#else
|
||||
#pragma message("MSC version: " STRINGIFY(_MSC_VER))
|
||||
#error "Unsupported MSC version"
|
||||
#endif
|
||||
|
||||
// parent process name for services in Vista
|
||||
#define SERVICE_LAUNCHER "services.exe"
|
||||
|
||||
@ -29,6 +62,11 @@
|
||||
#endif
|
||||
using EXECUTION_STATE = DWORD;
|
||||
|
||||
void errorMessageBox(const char *message, const char *title = "Fatal Error")
|
||||
{
|
||||
MessageBoxA(nullptr, message, title, MB_ICONERROR | MB_OK);
|
||||
}
|
||||
|
||||
//
|
||||
// ArchMiscWindows
|
||||
//
|
||||
@ -164,6 +202,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 +504,72 @@ 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;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::guardRuntimeVersion() // NOSONAR - `noreturn` is not available
|
||||
{
|
||||
const auto kRuntimeDll = "vcruntime140.dll";
|
||||
|
||||
HMODULE hModule = nullptr;
|
||||
if (!GetModuleHandleEx(0, kRuntimeDll, &hModule) && hModule) {
|
||||
errorMessageBox("Microsoft Visual C++ Runtime is not installed.");
|
||||
abort();
|
||||
}
|
||||
|
||||
std::array<char, MAX_PATH> pathBuffer;
|
||||
const auto path = pathBuffer.data();
|
||||
if (!GetModuleFileNameA(hModule, path, MAX_PATH)) {
|
||||
errorMessageBox("Failed to get the path of Microsoft Visual C++ Runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
DWORD handle;
|
||||
DWORD size = GetFileVersionInfoSizeA(path, &handle);
|
||||
if (size <= 0) {
|
||||
errorMessageBox("Failed to get the version info size for Microsoft Visual C++ Runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
std::vector<BYTE> versionInfo(size);
|
||||
if (!GetFileVersionInfoA(path, handle, size, versionInfo.data())) {
|
||||
errorMessageBox("Failed to get the file version info for Microsoft Visual C++ Runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
VS_FIXEDFILEINFO *fileInfo = nullptr;
|
||||
const auto lplpFileInfo = reinterpret_cast<void **>(&fileInfo); // NOSONAR - Idiomatic Win32
|
||||
if (UINT len = 0; !VerQueryValueA(versionInfo.data(), "\\", lplpFileInfo, &len)) {
|
||||
errorMessageBox("Failed to get the version information for Microsoft Visual C++ Runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
const auto currentMajor = HIWORD(fileInfo->dwFileVersionMS);
|
||||
const auto currentMinor = LOWORD(fileInfo->dwFileVersionMS);
|
||||
const auto currentBuild = HIWORD(fileInfo->dwFileVersionLS);
|
||||
|
||||
if (currentMajor < kRequiredMajor || currentMinor < kRequiredMinor) {
|
||||
const auto message = deskflow::string::sprintf(
|
||||
"Installed Microsoft Visual C++ Runtime v%d.%d.%d is outdated.\n\n"
|
||||
"Minimum required version: v%d.%d\n\n"
|
||||
"Please update to the latest Microsoft Visual C++ Redistributable.",
|
||||
currentMajor, currentMinor, currentBuild, kRequiredMajor, kRequiredMinor
|
||||
);
|
||||
MessageBoxA(nullptr, message.c_str(), "Dependency Error", MB_ICONERROR | MB_OK);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -154,13 +157,15 @@ public:
|
||||
//! Returns true if we got the parent process name.
|
||||
static bool getParentProcessName(std::string &name);
|
||||
|
||||
//! Prevent hard to troubleshoot errors, e.g. access violations.
|
||||
static void guardRuntimeVersion();
|
||||
|
||||
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:
|
||||
|
||||