diff --git a/.env.example b/.env.example
index ffce9a2df..372078633 100644
--- a/.env.example
+++ b/.env.example
@@ -6,9 +6,6 @@
# App
#
-# Serial key value to pre-fill the activation dialog
-# DESKFLOW_TEST_SERIAL_KEY="DEADBEEF"
-
# Shows the test menu in the GUI (on by default in debug mode)
# DESKFLOW_TEST_MENU=true
@@ -24,12 +21,6 @@
# Reset all settings and delete all data on startup
# DESKFLOW_RESET_ALL=true
-# Enable the activation dialog (used for testing)
-# DESKFLOW_ENABLE_ACTIVATION=true
-
-# Show licensed product menu items, etc (used for testing)
-# DESKFLOW_LICENSED_PRODUCT=true
-
#
# Build
#
diff --git a/.github/actions/dist-upload/action.yml b/.github/actions/dist-upload/action.yml
deleted file mode 100644
index 3365d3569..000000000
--- a/.github/actions/dist-upload/action.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-name: "Distribute upload"
-description: "Uploads the package from the dist dir to GitHub artifacts or Google Drive"
-inputs:
- use-github:
- description: "Whether to upload to GitHub artifacts"
- required: true
-
- use_gdrive:
- description: "Whether to upload to Google Drive"
- required: true
-
- github-target-filename:
- description: "Filename to upload (GitHub artifacts)"
- required: true
-
- gdrive-target-base-dir:
- description: "Base directory to upload (Google Drive)"
- required: true
-
- gdrive-secret-key:
- description: "Google Drive secret key"
- required: true
-
- gdrive-parent-folder-id:
- description: "Google Drive parent folder ID"
- required: true
-
- package-version:
- description: "Package version appended to the Google Drive dir"
- required: true
-
-runs:
- using: "composite"
-
- steps:
- - if: ${{ inputs.use_gdrive == inputs.use-github }}
- run: |
- echo "Either 'use-github' or 'use_gdrive' must be true (and not both)"
- exit 1
- shell: bash
-
- - if: ${{ inputs.use_gdrive == 'true' && !inputs.package-version }}
- run: |
- echo "Input 'package-version' is required when uploading to Google Drive"
- exit 1
- shell: bash
-
- - if: ${{ inputs.use_gdrive == 'true' }}
- run: |
- SHORT_VERSION=$(echo "${{ inputs.package-version }}" | cut -d'-' -f1 | cut -d'+' -f1)
- echo "SHORT_VERSION=$SHORT_VERSION" >> $GITHUB_ENV
- shell: bash
-
- - name: Upload to GitHub
- if: ${{ inputs.use-github == 'true' }}
- uses: actions/upload-artifact@v4
- with:
- name: ${{ inputs.github-target-filename }}
- path: ./dist
- retention-days: 3
-
- - name: Upload to Google Drive
- if: ${{ inputs.use_gdrive == 'true' }}
- uses: symless/gdrive-upload@target-glob
- with:
- credentials: ${{ inputs.gdrive-secret-key }}
- target: "./dist/*"
- parent_folder_id: ${{ inputs.gdrive-parent-folder-id }}
- child_folder: Packages/${{ inputs.gdrive-target-base-dir }}/${{ env.SHORT_VERSION }}/${{ inputs.package-version }}
diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml
index 60086df21..b1a4546fc 100644
--- a/.github/actions/run-tests/action.yml
+++ b/.github/actions/run-tests/action.yml
@@ -4,8 +4,13 @@ description: "Runs both unit tests and integration tests and appends to a PR com
inputs:
job:
description: "The job name to append to the PR comment"
+ required: true
default: "unknown"
+ bin-dir:
+ description: "The directory containing the test binaries"
+ default: "build/bin"
+
runs:
using: "composite"
@@ -15,7 +20,7 @@ runs:
env:
QT_QPA_PLATFORM: offscreen
run: |
- ./build/bin/unittests
+ ./${{ inputs.bin-dir }}/unittests
result=$?
if [ $result -ne 0 ]; then
@@ -29,7 +34,7 @@ runs:
env:
QT_QPA_PLATFORM: offscreen
run: |
- ./build/bin/integtests
+ ./${{ inputs.bin-dir }}/integtests
result=$?
if [ $result -ne 0 ]; then
diff --git a/.github/workflows/ci-linux.json b/.github/workflows/ci-linux.json
index a2ae4f938..99b814c8a 100644
--- a/.github/workflows/ci-linux.json
+++ b/.github/workflows/ci-linux.json
@@ -9,7 +9,7 @@
{
"name": "debian-12-arm64",
"container": "deskflow/deskflow:debian-12-arm64",
- "runs-on": "ubuntu-24.04-2-core-arm64",
+ "runs-on": "ubuntu-24.04-4-core-arm64",
"extra-packages": true
},
{
@@ -33,7 +33,7 @@
{
"name": "fedora-40-arm64",
"container": "deskflow/deskflow:fedora-40-arm64",
- "runs-on": "ubuntu-24.04-2-core-arm64"
+ "runs-on": "ubuntu-24.04-4-core-arm64"
},
{
"name": "fedora-40-amd64",
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1e6f575cf..bb97ef960 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,20 +19,42 @@ on:
- cron: "0 5 * * *" # 5am UTC
env:
- GIT_SHA: ${{ github.sha }}
- DESKFLOW_PRODUCT_NAME: ${{ vars.DESKFLOW_PRODUCT_NAME }}
- DESKFLOW_PACKAGE_PREFIX: ${{ vars.DESKFLOW_PACKAGE_PREFIX || 'deskflow' }}
- PACKAGE_BUILD: ${{ !github.event.pull_request.draft }}
- PACKAGE_UPLOAD: ${{ !github.event.pull_request.draft }}
+ GIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+ PACKAGE_PREFIX: "deskflow"
+ PACKAGE_PATH: ./dist
jobs:
+ pr-comment-flags:
+ runs-on: ubuntu-latest
+ if: ${{ github.event_name == 'pull_request' }}
+
+ outputs:
+ no-sonar: ${{ steps.check.outputs.no-sonar }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Check PR comment for flags
+ id: check
+ run: |
+ pr_body="${{ github.event.pull_request.body }}"
+ no_sonar="{no-sonar}"
+
+ if echo $pr_body | grep -q "$no_sonar"; then
+ echo "Flag $no_sonar found in PR body."
+ echo "no-sonar=true" >> $GITHUB_OUTPUT
+ else
+ echo "No $no_sonar flag found in PR body."
+ fi
+
# Quality gate to allow PR merge, used in the branch protection rules.
ci-passed:
runs-on: ubuntu-latest
needs: [lint-cmake, lint-clang, windows, macos, linux, unix]
steps:
- - run: echo "CI passed" > $GITHUB_STEP_SUMMARY
+ - run: echo "✅ CI passed" > $GITHUB_STEP_SUMMARY
# Summary of test results, combined from test result artifacts.
# Runs even if the tests fail to provide a summary of the failures.
@@ -67,7 +89,8 @@ jobs:
uses: ./.github/workflows/codeql-analysis.yml
analyse-sonarcloud:
- if: ${{ github.event_name == 'pull_request' }}
+ needs: pr-comment-flags
+ if: ${{ github.event_name == 'pull_request' && needs.pr-comment-flags.outputs.no-sonar != 'true' }}
uses: ./.github/workflows/sonarcloud-analysis.yml
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
@@ -98,9 +121,12 @@ jobs:
- name: Cache vcpkg dir
uses: actions/cache@v4
with:
+ # We also need to cache the `LOCALAPPDATA` dir; without doing so, openssl
+ # rebuilds (after it is detected in cache) every time, which takes around 10 mins.
path: |
vcpkg
vcpkg_installed
+ ${{ env.LOCALAPPDATA }}/vcpkg
key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json') }}
# Should only restore the .venv directory from cache.
@@ -145,19 +171,16 @@ jobs:
job: ${{ matrix.target.name }}
- name: Package
- if: ${{ env.PACKAGE_BUILD == 'true' }}
run: python ./scripts/package.py
env:
WINDOWS_PFX_CERTIFICATE: ${{ secrets.WINDOWS_PFX }}
WINDOWS_PFX_PASSWORD: ${{ secrets.WINDOWS_PFX_PASS }}
- name: Upload
- if: ${{ env.PACKAGE_UPLOAD == 'true' }}
- uses: ./.github/actions/dist-upload
+ uses: actions/upload-artifact@v4
with:
- use-github: true
- github-target-filename: "${{ env.DESKFLOW_PACKAGE_PREFIX }}-${{ matrix.target.name }}"
- package-version: ${{ env.DESKFLOW_VERSION }}
+ name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.target.name }}
+ path: ${{ env.PACKAGE_PATH }}
macos:
name: ${{ matrix.target.name }}
@@ -223,7 +246,6 @@ jobs:
job: ${{ matrix.target.name }}
- name: Package
- if: ${{ env.PACKAGE_BUILD == 'true' }}
run: ./scripts/package.py
env:
APPLE_CODESIGN_ID: ${{ secrets.APPLE_CODESIGN_ID }}
@@ -234,12 +256,10 @@ jobs:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Upload
- if: ${{ env.PACKAGE_UPLOAD == 'true' }}
- uses: ./.github/actions/dist-upload
+ uses: actions/upload-artifact@v4
with:
- use-github: true
- github-target-filename: "${{ env.DESKFLOW_PACKAGE_PREFIX }}-${{ matrix.target.name }}"
- package-version: ${{ env.DESKFLOW_VERSION }}
+ name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.target.name }}
+ path: ${{ env.PACKAGE_PATH }}
linux-matrix:
runs-on: ubuntu-latest
@@ -308,19 +328,16 @@ jobs:
job: linux-${{ matrix.distro.name }}
- name: Package
- if: ${{ env.PACKAGE_BUILD == 'true' }}
env:
LINUX_EXTRA_PACKAGES: ${{ matrix.distro.extra-packages }}
LINUX_PACKAGE_USER: ${{ matrix.distro.package-user }}
run: ./scripts/package.py
- name: Upload
- if: ${{ env.PACKAGE_UPLOAD == 'true' }}
- uses: ./.github/actions/dist-upload
+ uses: actions/upload-artifact@v4
with:
- use-github: true
- github-target-filename: "${{ env.DESKFLOW_PACKAGE_PREFIX }}-${{ matrix.distro.name }}"
- package-version: ${{ env.DESKFLOW_VERSION }}
+ name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.distro.name }}
+ path: ${{ env.PACKAGE_PATH }}
# Technically, "unix" is a misnomer, but we use it here to mean "Unix-like BSD-derived".
unix:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 1f207a1d4..c8a78f27d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -39,7 +39,7 @@
"type": "lldb",
"cwd": "${workspaceRoot}",
"request": "launch",
- "program": "${workspaceFolder}/build/bin/deskflowc",
+ "program": "${workspaceFolder}/build/bin/deskflow-client",
"args": ["--config-toml", "deskflow-config.toml"],
"preLaunchTask": "kill-build"
},
@@ -81,7 +81,7 @@
"type": "cppvsdbg",
"cwd": "${workspaceRoot}",
"request": "launch",
- "program": "${workspaceFolder}/build/bin/deskflows",
+ "program": "${workspaceFolder}/build/bin/deskflow-server",
"args": ["--config-toml", "deskflow-config.toml"],
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "kill-build"
@@ -91,7 +91,7 @@
"type": "cppvsdbg",
"cwd": "${workspaceRoot}",
"request": "launch",
- "program": "${workspaceFolder}/build/bin/deskflowc",
+ "program": "${workspaceFolder}/build/bin/deskflow-client",
"args": ["--config-toml", "deskflow-config.toml"],
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "kill-build"
@@ -101,7 +101,7 @@
"type": "cppvsdbg",
"cwd": "${workspaceRoot}",
"request": "launch",
- "program": "${workspaceFolder}/build/bin/deskflowd",
+ "program": "${workspaceFolder}/build/bin/deskflow-daemon",
"args": ["-f"],
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "build"
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 0ebcf63bd..55639351e 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -67,9 +67,9 @@
{
"label": "kill",
"type": "shell",
- "command": "killall deskflow; killall deskflowc; killall deskflows || true",
+ "command": "killall deskflow; killall deskflow-client; killall deskflow-server || true",
"windows": {
- "command": "taskkill /F /IM deskflow.exe /IM deskflowc.exe /IM deskflows.exe; $true"
+ "command": "taskkill /F /IM deskflow.exe /IM deskflow-client.exe /IM deskflow-client.exe; $true"
},
"presentation": {
"reveal": "silent"
diff --git a/Doxyfile b/Doxyfile
index e319e8c57..d24bcca6e 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -51,7 +51,7 @@ PROJECT_BRIEF =
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
-PROJECT_LOGO = res/deskflow.svg
+PROJECT_LOGO = res/app.svg
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
diff --git a/cmake/Build.cmake b/cmake/Build.cmake
index e0947df7f..0b1340cbc 100644
--- a/cmake/Build.cmake
+++ b/cmake/Build.cmake
@@ -14,8 +14,22 @@
# along with this program. If not, see .
macro(configure_build)
+
+ set(CMAKE_CXX_STANDARD 20)
+ set(CMAKE_CXX_EXTENSIONS OFF)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
+ if(APPLE)
+ message(STATUS "Configuring for Apple")
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
+ endif()
+
warnings_as_errors()
set_build_date()
+ configure_file_shared()
+
endmacro()
macro(warnings_as_errors)
@@ -37,6 +51,11 @@ macro(set_build_date)
add_definitions(-DBUILD_DATE="${BUILD_DATE}")
endmacro()
+macro(configure_file_shared)
+ configure_file(${PROJECT_SOURCE_DIR}/src/lib/gui/gui_config.h.in
+ ${PROJECT_BINARY_DIR}/config/gui_config.h)
+endmacro()
+
macro(post_config)
# Build to a temp bin dir on Windows and then copy to the final bin dir
@@ -58,28 +77,39 @@ endmacro()
macro(post_config_all)
- # Always try to copy the files to the bin directory after every build, even if
- # there was nothing to do. This is because the copy may have failed last time
- # due to the file being in use, and we'll usually want to try again.
if(WIN32)
-
- if(NOT EXISTS ${PYTHON_BIN})
- message(FATAL_ERROR "Python not found at: ${PYTHON_BIN}")
- endif()
-
+ # Always try to copy the files to the bin directory after every build and deliberatly ignore
+ # copy errors, usually the error is because a running process has locked the file.
+ #
+ # It is useful to copy every time because the copy may have failed last time due to the file
+ # being in use, and we'll usually want to try again (after killing the process).
+ #
+ # Yes, this looks like a ridiculous thing to do, but it really is necessary to
+ # use a Python script to copy files on Windows. Why? Two reasons:
+ #
+ # 1. Windows file locks (on running processes) creates a very painful development
+ # experience; you can't overwrite the binary you're running it.
+ # Why not just stop the process? Windows services are an abject PITA to manage,
+ # and we don't always care about overwriting all binaries.
+ #
+ # 2. The Windows copy command is limited and gives vague/misleading errors.
+ # The CMake copy command also has similar shortfalls.
+ #
+ # Patches welcome! :)
add_custom_target(
run_post_build ALL
- COMMAND ${PYTHON_BIN} ${CMAKE_SOURCE_DIR}/scripts/fancy_copy.py
- ${BIN_TEMP_DIR} ${CMAKE_BINARY_DIR}/bin --ignore-errors
+ COMMAND ${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/fancy_copy.py
+ ${BIN_TEMP_DIR} ${PROJECT_BINARY_DIR}/bin --ignore-errors
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
VERBATIM
COMMENT "Copying files to bin dir")
add_dependencies(
run_post_build
- deskflow
- deskflowc
- deskflows
- deskflowd)
+ ${GUI_BINARY_NAME}
+ ${CLIENT_BINARY_NAME}
+ ${SERVER_BINARY_NAME}
+ ${DAEMON_BINARY_NAME})
endif()
endmacro()
diff --git a/cmake/Definitions.cmake b/cmake/Definitions.cmake
index fe95d05a5..b9e918efc 100644
--- a/cmake/Definitions.cmake
+++ b/cmake/Definitions.cmake
@@ -16,28 +16,13 @@
macro(configure_definitions)
- set(CMAKE_CXX_STANDARD 20)
- set(CMAKE_CXX_EXTENSIONS OFF)
- set(CMAKE_CXX_STANDARD_REQUIRED ON)
- set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
-
- if(APPLE)
- set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
- endif()
-
+ configure_meta()
configure_ninja()
configure_options()
- configure_python()
set(INTEG_TESTS_BIN integtests)
set(UNIT_TESTS_BIN unittests)
- if("${VERSION_URL}" STREQUAL "")
- set(VERSION_URL "https://api.deskflow.org/version")
- endif()
- add_definitions(-DDESKFLOW_VERSION_URL="${VERSION_URL}")
-
if(NOT "$ENV{GIT_SHA}" STREQUAL "")
# Shorten the Git SHA to 8 chars for readability
string(SUBSTRING "$ENV{GIT_SHA}" 0 8 GIT_SHA_SHORT)
@@ -45,17 +30,6 @@ macro(configure_definitions)
add_definitions(-DGIT_SHA_SHORT="${GIT_SHA_SHORT}")
endif()
- if(NOT "$ENV{DESKFLOW_PRODUCT_NAME}" STREQUAL "")
- set(PRODUCT_NAME $ENV{DESKFLOW_PRODUCT_NAME})
- endif()
-
- if("${PRODUCT_NAME}" STREQUAL "")
- set(PRODUCT_NAME "Deskflow")
- endif()
-
- message(STATUS "Product name: ${PRODUCT_NAME}")
- add_definitions(-DDESKFLOW_PRODUCT_NAME="${PRODUCT_NAME}")
-
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Disabling debug build")
add_definitions(-DNDEBUG)
@@ -74,7 +48,130 @@ macro(configure_definitions)
set(ADD_HEADERS_TO_SOURCES TRUE)
endif()
- set(BIN_TEMP_DIR ${CMAKE_BINARY_DIR}/temp/bin)
+ set(BIN_TEMP_DIR ${PROJECT_BINARY_DIR}/temp/bin)
+
+endmacro()
+
+macro(configure_meta)
+
+ set(DESKFLOW_APP_ID
+ "deskflow"
+ CACHE STRING "ID of the app for filenames, etc")
+
+ set(DESKFLOW_DOMAIN
+ "deskflow.org"
+ CACHE STRING "Domain of the app maintainer (not a URL)")
+
+ set(DESKFLOW_APP_NAME
+ "Deskflow"
+ CACHE STRING "App name (used in GUI title bar, etc)")
+
+ set(DESKFLOW_AUTHOR_NAME
+ "Deskflow"
+ CACHE STRING "Author name (also used as organization name)")
+
+ set(DESKFLOW_MAINTAINER
+ "Deskflow "
+ CACHE STRING "Maintainer email address in RFC 5322 mailbox format")
+
+ set(DESKFLOW_WEBSITE_URL
+ "https://deskflow.org"
+ CACHE STRING "URL of the app website")
+
+ set(DESKFLOW_VERSION_URL
+ "https://api.deskflow.org/version"
+ CACHE STRING "URL to get the latest version")
+
+ set(DESKFLOW_HELP_TEXT
+ "Report a bug"
+ CACHE STRING "Text label for the help menu item")
+
+ set(DESKFLOW_RES_DIR
+ "${PROJECT_SOURCE_DIR}/res"
+ CACHE STRING "Resource directory for images, etc")
+
+ set(DESKFLOW_MAC_BUNDLE_CODE
+ "DFLW"
+ CACHE STRING "Mac bundle code (4 characters)")
+
+ set(DESKFLOW_SHOW_DEV_THANKS
+ true
+ CACHE BOOL "Show developer thanks message")
+
+ message(VERBOSE "App ID: ${DESKFLOW_APP_ID}")
+ message(VERBOSE "App domain: ${DESKFLOW_DOMAIN}")
+ message(VERBOSE "App name: ${DESKFLOW_APP_NAME}")
+ message(VERBOSE "Author name: ${DESKFLOW_AUTHOR_NAME}")
+ message(VERBOSE "Maintainer: ${DESKFLOW_MAINTAINER}")
+ message(VERBOSE "Website URL: ${DESKFLOW_WEBSITE_URL}")
+ message(VERBOSE "Version URL: ${DESKFLOW_VERSION_URL}")
+ message(VERBOSE "Help text: ${DESKFLOW_HELP_TEXT}")
+ message(VERBOSE "Res dir: ${DESKFLOW_RES_DIR}")
+ message(VERBOSE "Mac bundle code: ${DESKFLOW_MAC_BUNDLE_CODE}")
+ message(VERBOSE "Show dev thanks: ${DESKFLOW_SHOW_DEV_THANKS}")
+
+ # TODO: We need to move this to configure_file() in the future, which is much cleaner.
+ add_definitions(-DDESKFLOW_APP_ID="${DESKFLOW_APP_ID}")
+ add_definitions(-DDESKFLOW_DOMAIN="${DESKFLOW_DOMAIN}")
+ add_definitions(-DDESKFLOW_APP_NAME="${DESKFLOW_APP_NAME}")
+ add_definitions(-DDESKFLOW_AUTHOR_NAME="${DESKFLOW_AUTHOR_NAME}")
+ add_definitions(-DDESKFLOW_MAINTAINER="${DESKFLOW_MAINTAINER}")
+ add_definitions(-DDESKFLOW_WEBSITE_URL="${DESKFLOW_WEBSITE_URL}")
+ add_definitions(-DDESKFLOW_VERSION_URL="${DESKFLOW_VERSION_URL}")
+ add_definitions(-DDESKFLOW_HELP_TEXT="${DESKFLOW_HELP_TEXT}")
+ add_definitions(-DDESKFLOW_RES_DIR="${DESKFLOW_RES_DIR}")
+
+ if(DESKFLOW_SHOW_DEV_THANKS)
+ message(VERBOSE "Showing developer thanks message")
+ add_definitions(-DDESKFLOW_SHOW_DEV_THANKS)
+ else()
+ message(VERBOSE "Not showing developer thanks message")
+ endif()
+
+ configure_bin_names()
+
+endmacro()
+
+macro(configure_bin_names)
+
+ set(GUI_BINARY_NAME
+ "deskflow"
+ CACHE STRING "Filename of the GUI binary")
+
+ set(SERVER_BINARY_NAME
+ "deskflow-server"
+ CACHE STRING "Filename of the server binary")
+
+ set(CLIENT_BINARY_NAME
+ "deskflow-client"
+ CACHE STRING "Filename of the client binary")
+
+ set(CORE_BINARY_NAME
+ "deskflow-core"
+ CACHE STRING "Filename of the core binary")
+
+ set(DAEMON_BINARY_NAME
+ "deskflow-daemon"
+ CACHE STRING "Filename of the daemon binary")
+
+ set(LEGACY_BINARY_NAME
+ "deskflow-legacy"
+ CACHE STRING "Filename of the legacy binary")
+
+ message(VERBOSE "GUI binary: ${GUI_BINARY_NAME}")
+ message(VERBOSE "Server binary: ${SERVER_BINARY_NAME}")
+ message(VERBOSE "Client binary: ${CLIENT_BINARY_NAME}")
+ message(VERBOSE "Core binary: ${CORE_BINARY_NAME}")
+ message(VERBOSE "Daemon binary: ${DAEMON_BINARY_NAME}")
+ message(VERBOSE "Legacy binary: ${LEGACY_BINARY_NAME}")
+
+ add_definitions(-DGUI_BINARY_NAME="${GUI_BINARY_NAME}")
+ add_definitions(-DSERVER_BINARY_NAME="${SERVER_BINARY_NAME}")
+ add_definitions(-DCLIENT_BINARY_NAME="${CLIENT_BINARY_NAME}")
+ add_definitions(-DCORE_BINARY_NAME="${CORE_BINARY_NAME}")
+ add_definitions(-DDAEMON_BINARY_NAME="${DAEMON_BINARY_NAME}")
+ add_definitions(-DLEGACY_BINARY_NAME="${LEGACY_BINARY_NAME}")
+
endmacro()
macro(configure_ninja)
@@ -101,15 +198,6 @@ macro(configure_options)
# coverage is off by default because it's GCC only and a developer preference.
set(DEFAULT_ENABLE_COVERAGE OFF)
- # licensed product is off by default to show links to github, etc.
- set(DEFAULT_LICENSED_PRODUCT OFF)
-
- # activation is off by default to make life easier for contributors.
- set(DEFAULT_ENABLE_ACTIVATION OFF)
-
- # by default, show the dev thanks message, guides contributions, etc.
- set(DEFAULT_SHOW_DEV_THANKS ON)
-
if("$ENV{DESKFLOW_BUILD_MINIMAL}" STREQUAL "true")
set(DEFAULT_BUILD_GUI OFF)
set(DEFAULT_BUILD_INSTALLER OFF)
@@ -123,14 +211,6 @@ macro(configure_options)
set(DEFAULT_BUILD_UNIFIED ON)
endif()
- if("$ENV{DESKFLOW_ENABLE_ACTIVATION}" STREQUAL "true")
- set(DEFAULT_ENABLE_ACTIVATION ON)
- endif()
-
- if("$ENV{DESKFLOW_LICENSED_PRODUCT}" STREQUAL "true")
- set(DEFAULT_LICENSED_PRODUCT ON)
- endif()
-
if("$ENV{DESKFLOW_ENABLE_COVERAGE}" STREQUAL "true")
set(DEFAULT_ENABLE_COVERAGE ON)
endif()
@@ -139,8 +219,6 @@ macro(configure_options)
option(BUILD_INSTALLER "Build installer" ${DEFAULT_BUILD_INSTALLER})
option(BUILD_TESTS "Build tests" ${DEFAULT_BUILD_TESTS})
option(BUILD_UNIFIED "Build unified binary" ${DEFAULT_BUILD_UNIFIED})
- option(ENABLE_ACTIVATION "Enable activation" ${DEFAULT_ENABLE_ACTIVATION})
- option(LICENSED_PRODUCT "Show licensing info" ${DEFAULT_LICENSED_PRODUCT})
option(ENABLE_COVERAGE "Enable test coverage" ${DEFAULT_ENABLE_COVERAGE})
endmacro()
diff --git a/cmake/Libraries.cmake b/cmake/Libraries.cmake
index b05cc05d6..545b49e0b 100644
--- a/cmake/Libraries.cmake
+++ b/cmake/Libraries.cmake
@@ -1,3 +1,18 @@
+# Deskflow -- mouse and keyboard sharing utility
+# Copyright (C) 2024 Symless Ltd.
+#
+# This package is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# found in the file LICENSE that should have accompanied this file.
+#
+# This package is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
set(LIBEI_MIN_VERSION 1.2.1)
set(LIBPORTAL_MIN_VERSION 0.6)
@@ -10,6 +25,7 @@ macro(configure_libs)
configure_windows_libs()
endif()
+ configure_python()
configure_qt()
configure_openssl()
configure_coverage()
@@ -215,8 +231,8 @@ macro(configure_libei)
message(WARNING "libei >= ${LIBEI_MIN_VERSION} not found")
endif()
else()
- set(libei_bin_dir ${CMAKE_BINARY_DIR}/meson/subprojects/libei/src)
- set(libei_src_dir ${CMAKE_SOURCE_DIR}/subprojects/libei)
+ set(libei_bin_dir ${PROJECT_BINARY_DIR}/meson/subprojects/libei/src)
+ set(libei_src_dir ${PROJECT_SOURCE_DIR}/subprojects/libei)
find_library(
LIBEI_LINK_LIBRARIES
NAMES ei
@@ -246,8 +262,8 @@ macro(configure_libportal)
endif()
else()
set(libportal_bin_dir
- ${CMAKE_BINARY_DIR}/meson/subprojects/libportal/libportal)
- set(libportal_src_dir ${CMAKE_SOURCE_DIR}/subprojects/libportal)
+ ${PROJECT_BINARY_DIR}/meson/subprojects/libportal/libportal)
+ set(libportal_src_dir ${PROJECT_SOURCE_DIR}/subprojects/libportal)
option(LIBPORTAL_STATIC "Use the static libportal binary" OFF)
if(LIBPORTAL_STATIC)
@@ -466,31 +482,39 @@ macro(configure_windows_libs)
/DDESKFLOW_VERSION=\"${DESKFLOW_VERSION}\"
/D_XKEYCHECK_H)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/res/win/version.rc.in
- ${CMAKE_BINARY_DIR}/src/version.rc @ONLY)
+ configure_file(${PROJECT_SOURCE_DIR}/res/win/version.rc.in
+ ${PROJECT_BINARY_DIR}/src/version.rc @ONLY)
configure_windows_openssl()
endmacro()
macro(configure_windows_openssl)
- set(OPENSSL_ROOT_DIR ${CMAKE_SOURCE_DIR}/vcpkg_installed/x64-windows)
+ set(OPENSSL_ROOT_DIR ${PROJECT_SOURCE_DIR}/vcpkg_installed/x64-windows)
set(OPENSSL_EXE_DIR ${OPENSSL_ROOT_DIR}/tools/openssl)
if(EXISTS ${OPENSSL_EXE_DIR})
- message(STATUS "OpenSSL exe dir: ${OPENSSL_EXE_DIR}")
+ message(VERBOSE "OpenSSL exe dir: ${OPENSSL_EXE_DIR}")
add_definitions(-DOPENSSL_EXE_DIR="${OPENSSL_EXE_DIR}")
else()
message(FATAL_ERROR "OpenSSL exe dir not found: ${OPENSSL_EXE_DIR}")
endif()
if(EXISTS ${OPENSSL_ROOT_DIR})
- message(STATUS "OpenSSL root dir: ${OPENSSL_ROOT_DIR}")
+ message(VERBOSE "OpenSSL root dir: ${OPENSSL_ROOT_DIR}")
else()
message(FATAL_ERROR "OpenSSL root dir not found: ${OPENSSL_ROOT_DIR}")
endif()
endmacro()
+macro(configure_python)
+ if(WIN32)
+ find_package(Python REQUIRED QUIET)
+ else()
+ find_package(Python3 REQUIRED QUIET)
+ endif()
+endmacro()
+
macro(configure_qt)
find_package(
@@ -500,6 +524,9 @@ macro(configure_qt)
message(STATUS "Qt version: ${Qt6_VERSION}")
+ set(GUI_RES_DIR ${DESKFLOW_RES_DIR}/gui)
+ set(GUI_QRC_FILE ${GUI_RES_DIR}/app.qrc)
+
endmacro()
macro(configure_openssl)
@@ -553,7 +580,7 @@ macro(configure_gtest)
)
endif()
- message(STATUS "Building GoogleTest")
+ message(VERBOSE "Using local GoogleTest")
set(gtest_dir ${gtest_base_dir}/googletest)
set(gmock_dir ${gtest_base_dir}/googlemock)
include_directories(${gtest_dir} ${gmock_dir} ${gtest_dir}/include
@@ -613,19 +640,10 @@ macro(configure_coverage)
endif()
endmacro()
-macro(configure_python)
- set(python_venv_dir ${CMAKE_SOURCE_DIR}/.venv)
- if(WIN32)
- set(PYTHON_BIN ${python_venv_dir}/Scripts/python.exe)
- else()
- set(PYTHON_BIN ${python_venv_dir}/bin/python)
- endif()
-endmacro()
-
macro(configure_wintoast)
# WinToast is a pretty niche library, and there doesn't seem to be an installable package,
# so we rely on building from source.
- file(GLOB WINTOAST_DIR ${CMAKE_SOURCE_DIR}/subprojects/WinToast-*)
+ file(GLOB WINTOAST_DIR ${PROJECT_SOURCE_DIR}/subprojects/WinToast-*)
if(WINTOAST_DIR)
set(HAVE_WINTOAST true)
add_definitions(-DHAVE_WINTOAST=1)
@@ -637,7 +655,7 @@ macro(configure_wintoast)
endmacro()
macro(configure_tomlplusplus)
- file(GLOB tomlplusplus_dir ${CMAKE_SOURCE_DIR}/subprojects/tomlplusplus-*)
+ file(GLOB tomlplusplus_dir ${PROJECT_SOURCE_DIR}/subprojects/tomlplusplus-*)
if(tomlplusplus_dir)
set(DEFAULT_SYSTEM_TOMLPLUSPLUS OFF)
@@ -657,6 +675,7 @@ macro(configure_tomlplusplus)
endif()
else()
if(EXISTS ${tomlplusplus_dir})
+ message(VERBOSE "Using local tomlplusplus")
set(HAVE_TOMLPLUSPLUS true)
add_definitions(-DHAVE_TOMLPLUSPLUS=1)
include_directories(${tomlplusplus_dir}/include)
@@ -667,7 +686,7 @@ macro(configure_tomlplusplus)
endmacro()
macro(configure_cli11)
- file(GLOB cli11_dir ${CMAKE_SOURCE_DIR}/subprojects/CLI11-*)
+ file(GLOB cli11_dir ${PROJECT_SOURCE_DIR}/subprojects/CLI11-*)
if(cli11_dir)
set(DEFAULT_SYSTEM_CLI11 OFF)
@@ -685,12 +704,13 @@ macro(configure_cli11)
message(WARNING "System CLI11 not found")
endif()
else()
- if(EXISTS ${CLI11_dir})
+ if(EXISTS ${cli11_dir})
+ message(VERBOSE "Using local CLI11")
set(HAVE_CLI11 true)
add_definitions(-DHAVE_CLI11=1)
include_directories(${cli11_dir}/include)
else()
- message(WARNING "Local CLI11 subproject not found")
+ message(WARNING "Local CLI11 subproject not found at: ${cli11_dir}")
endif()
endif()
diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake
index cd50b1937..57706204f 100644
--- a/cmake/Packaging.cmake
+++ b/cmake/Packaging.cmake
@@ -19,17 +19,19 @@
#
macro(configure_packaging)
+ set(DESKFLOW_PROJECT_RES_DIR ${PROJECT_SOURCE_DIR}/res)
+
if(${BUILD_INSTALLER})
- set(CPACK_PACKAGE_NAME "deskflow")
- set(CPACK_PACKAGE_CONTACT "Deskflow ")
+ set(CPACK_PACKAGE_NAME ${DESKFLOW_APP_ID})
+ set(CPACK_PACKAGE_CONTACT ${DESKFLOW_MAINTAINER})
set(CPACK_PACKAGE_DESCRIPTION "Mouse and keyboard sharing utility")
- set(CPACK_PACKAGE_VENDOR "Symless")
- set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+ set(CPACK_PACKAGE_VENDOR ${DESKFLOW_AUTHOR_NAME})
+ set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE)
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
configure_windows_packaging()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
- configure_macos_packaging()
+ configure_mac_packaging()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
configure_linux_packaging()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "|.*BSD")
@@ -48,35 +50,46 @@ endmacro()
#
macro(configure_windows_packaging)
- message(STATUS "Configuring Windows installer")
+ message(VERBOSE "Configuring Windows installer")
set(CPACK_PACKAGE_VERSION ${DESKFLOW_VERSION_MS})
set(QT_PATH $ENV{CMAKE_PREFIX_PATH})
- configure_files(${CMAKE_CURRENT_SOURCE_DIR}/res/dist/wix
- ${CMAKE_BINARY_DIR}/installer)
+ set(DESKFLOW_MSI_64_GUID
+ "027D1C8A-E7A5-4754-BB93-B2D45BFDBDC8"
+ CACHE STRING "GUID for 64-bit MSI installer")
+
+ set(DESKFLOW_MSI_32_GUID
+ "8F57C657-BC87-45E6-840E-41242A93511C"
+ CACHE STRING "GUID for 32-bit MSI installer")
+
+ configure_files(${PROJECT_SOURCE_DIR}/res/dist/wix
+ ${PROJECT_BINARY_DIR}/installer)
endmacro()
#
# macOS app bundle
#
-macro(configure_macos_packaging)
+macro(configure_mac_packaging)
- message(STATUS "Configuring macOS app bundle")
+ message(VERBOSE "Configuring macOS app bundle")
set(CPACK_PACKAGE_VERSION ${DESKFLOW_VERSION})
set(CMAKE_INSTALL_RPATH
"@loader_path/../Libraries;@loader_path/../Frameworks")
set(DESKFLOW_BUNDLE_SOURCE_DIR
- ${CMAKE_CURRENT_SOURCE_DIR}/res/dist/macos/bundle)
- set(DESKFLOW_BUNDLE_DIR ${CMAKE_BINARY_DIR}/bundle)
- set(DESKFLOW_BUNDLE_APP_DIR ${DESKFLOW_BUNDLE_DIR}/Deskflow.app)
- set(DESKFLOW_BUNDLE_BINARY_DIR ${DESKFLOW_BUNDLE_APP_DIR}/Contents/MacOS)
+ ${PROJECT_SOURCE_DIR}/res/dist/mac/bundle
+ CACHE PATH "Path to the macOS app bundle")
+ set(DESKFLOW_BUNDLE_DIR ${PROJECT_BINARY_DIR}/bundle/${DESKFLOW_APP_NAME}.app)
+ set(DESKFLOW_BUNDLE_BINARY_DIR ${DESKFLOW_BUNDLE_DIR}/Contents/MacOS)
configure_files(${DESKFLOW_BUNDLE_SOURCE_DIR} ${DESKFLOW_BUNDLE_DIR})
+ file(RENAME ${DESKFLOW_BUNDLE_DIR}/Contents/Resources/App.icns
+ ${DESKFLOW_BUNDLE_DIR}/Contents/Resources/${DESKFLOW_APP_NAME}.icns)
+
endmacro()
#
@@ -84,12 +97,12 @@ endmacro()
#
macro(configure_linux_packaging)
- message(STATUS "Configuring Linux packaging")
+ message(VERBOSE "Configuring Linux packaging")
set(CPACK_PACKAGE_VERSION ${DESKFLOW_VERSION_LINUX})
set(CPACK_GENERATOR "DEB;RPM;TGZ")
- set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Deskflow ")
+ set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${DESKFLOW_MAINTAINER})
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
@@ -108,11 +121,25 @@ macro(configure_linux_packaging)
# apps install to.
set(CMAKE_INSTALL_PREFIX /usr)
- install(FILES res/dist/linux/deskflow.desktop DESTINATION share/applications)
- install(FILES res/deskflow.png DESTINATION share/pixmaps)
+ set(source_desktop_file ${DESKFLOW_PROJECT_RES_DIR}/dist/linux/app.desktop.in)
+ set(configured_desktop_file ${PROJECT_BINARY_DIR}/app.desktop)
+ set(install_desktop_file ${DESKFLOW_APP_ID}.desktop)
+
+ configure_file(${source_desktop_file} ${configured_desktop_file} @ONLY)
+
+ install(
+ FILES ${configured_desktop_file}
+ DESTINATION share/applications
+ RENAME ${install_desktop_file})
+
+ install(
+ FILES ${DESKFLOW_RES_DIR}/app.png
+ DESTINATION share/pixmaps
+ RENAME ${DESKFLOW_APP_ID}.png)
# Prepare PKGBUILD for Arch Linux
- configure_file(res/dist/arch/PKGBUILD.in ${CMAKE_BINARY_DIR}/PKGBUILD @ONLY)
+ configure_file(${DESKFLOW_PROJECT_RES_DIR}/dist/arch/PKGBUILD.in
+ ${CMAKE_BINARY_DIR}/PKGBUILD @ONLY)
endmacro()
diff --git a/cmake/Version.cmake b/cmake/Version.cmake
index bd5f678be..5d477d0c9 100644
--- a/cmake/Version.cmake
+++ b/cmake/Version.cmake
@@ -22,7 +22,7 @@ macro(set_version)
string(STRIP "${DESKFLOW_VERSION}" DESKFLOW_VERSION)
if(NOT DESKFLOW_VERSION)
- file(READ "${CMAKE_SOURCE_DIR}/VERSION" DESKFLOW_VERSION)
+ file(READ "${PROJECT_SOURCE_DIR}/VERSION" DESKFLOW_VERSION)
string(STRIP "${DESKFLOW_VERSION}" DESKFLOW_VERSION)
endif()
@@ -67,14 +67,14 @@ macro(set_windows_version)
# Dot-separated version number for MSI and Windows version .rc file.
set(DESKFLOW_VERSION_MS ${DESKFLOW_VERSION_FOUR_PART})
- message(STATUS "Version number for (Microsoft 4-part): "
- ${DESKFLOW_VERSION_MS})
+ message(VERBOSE "Version number for (Microsoft 4-part): "
+ ${DESKFLOW_VERSION_MS})
# CSV version number for Windows version .rc file.
set(DESKFLOW_VERSION_MS_CSV
"${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}")
- message(STATUS "Version number for (Microsoft CSV): "
- ${DESKFLOW_VERSION_MS_CSV})
+ message(VERBOSE "Version number for (Microsoft CSV): "
+ ${DESKFLOW_VERSION_MS_CSV})
endmacro()
macro(set_linux_version)
diff --git a/cspell.json b/cspell.json
index 71e72cf7e..5ba583724 100644
--- a/cspell.json
+++ b/cspell.json
@@ -52,6 +52,7 @@
"Poschta",
"Povilas",
"Priddy",
+ "psutil",
"pyproject",
"qputenv",
"Regen",
diff --git a/res/deskflow.ico b/res/app.ico
similarity index 100%
rename from res/deskflow.ico
rename to res/app.ico
diff --git a/res/deskflow.png b/res/app.png
similarity index 100%
rename from res/deskflow.png
rename to res/app.png
diff --git a/res/deskflow.svg b/res/app.svg
similarity index 100%
rename from res/deskflow.svg
rename to res/app.svg
diff --git a/res/config.h.in b/res/config.h.in
index 9e5420a8f..3d03273ef 100644
--- a/res/config.h.in
+++ b/res/config.h.in
@@ -1,3 +1,22 @@
+/*
+ * Deskflow -- mouse and keyboard sharing utility
+ * Copyright (C) 2009 Symless Ltd.
+ *
+ * This package is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * found in the file LICENSE that should have accompanied this file.
+ *
+ * This package is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+// clang-format off
+
/* Define version here for Unix, but using /D for Windows. */
#cmakedefine DESKFLOW_VERSION "${DESKFLOW_VERSION}"
@@ -177,3 +196,5 @@
/* Define if libportal has input capture support */
#cmakedefine HAVE_LIBPORTAL_INPUTCAPTURE ${HAVE_LIBPORTAL_INPUTCAPTURE}
+
+// clang-format on
diff --git a/res/dist/arch/PKGBUILD.in b/res/dist/arch/PKGBUILD.in
index 6bd3814e0..b3a413d3d 100644
--- a/res/dist/arch/PKGBUILD.in
+++ b/res/dist/arch/PKGBUILD.in
@@ -1,10 +1,10 @@
-# Maintainer: Deskflow
+# Maintainer: @DESKFLOW_MAINTAINER@
-pkgname=deskflow
+pkgname=@DESKFLOW_APP_ID@
pkgver=@DESKFLOW_VERSION_FOUR_PART@
pkgrel=1
pkgdesc="Mouse and keyboard sharing utility"
-url='https://deskflow.org/'
+url='@DESKFLOW_WEBSITE_URL@'
arch=('x86_64')
license=('GPL-2.0-only')
depends=(
diff --git a/res/dist/flatpak/deskflow.yml b/res/dist/flatpak/deskflow.yml
index 0f5271ca9..b3686f290 100644
--- a/res/dist/flatpak/deskflow.yml
+++ b/res/dist/flatpak/deskflow.yml
@@ -1,4 +1,4 @@
-app-id: com.symless.Deskflow
+app-id: org.deskflow.Deskflow
runtime: org.kde.Platform
runtime-version: "5.15-21.08"
sdk: org.kde.Sdk
diff --git a/res/dist/linux/deskflow.desktop b/res/dist/linux/app.desktop.in
similarity index 69%
rename from res/dist/linux/deskflow.desktop
rename to res/dist/linux/app.desktop.in
index 3142bc974..15b9a7ecf 100644
--- a/res/dist/linux/deskflow.desktop
+++ b/res/dist/linux/app.desktop.in
@@ -1,12 +1,11 @@
[Desktop Entry]
Type=Application
Version=1.0
-Name=Deskflow
+Name=@DESKFLOW_APP_NAME@
Comment=Mouse and keyboard sharing utility
Path=/usr/bin
-Exec=/usr/bin/deskflow
-Icon=deskflow
+Exec=/usr/bin/@GUI_BINARY_NAME@
+Icon=@DESKFLOW_APP_ID@
Terminal=false
Categories=Utility;
Keywords=keyboard;mouse;sharing;network;share;
-
diff --git a/res/dist/macos/bundle/Deskflow.app/Contents/Info.plist.in b/res/dist/mac/bundle/Contents/Info.plist.in
similarity index 77%
rename from res/dist/macos/bundle/Deskflow.app/Contents/Info.plist.in
rename to res/dist/mac/bundle/Contents/Info.plist.in
index 7f7298a59..1c9dedb12 100644
--- a/res/dist/macos/bundle/Deskflow.app/Contents/Info.plist.in
+++ b/res/dist/mac/bundle/Contents/Info.plist.in
@@ -4,21 +4,21 @@
CFBundleDevelopmentRegion
English
CFBundleDisplayName
- Deskflow
+ @DESKFLOW_APP_NAME@
CFBundleExecutable
- deskflow
+ @DESKFLOW_APP_ID@
CFBundleIconFile
- Deskflow.icns
+ @DESKFLOW_APP_NAME@.icns
CFBundleIdentifier
- deskflow
+ @DESKFLOW_APP_ID@
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- Deskflow
+ @DESKFLOW_APP_NAME@
CFBundlePackageType
APPL
CFBundleSignature
- SYN1
+ @DESKFLOW_MAC_BUNDLE_CODE@
CFBundleShortVersionString
@DESKFLOW_VERSION@
CFBundleVersion
diff --git a/res/dist/mac/bundle/Contents/PkgInfo.in b/res/dist/mac/bundle/Contents/PkgInfo.in
new file mode 100644
index 000000000..c50e7b961
--- /dev/null
+++ b/res/dist/mac/bundle/Contents/PkgInfo.in
@@ -0,0 +1 @@
+APPL@DESKFLOW_MAC_BUNDLE_CODE@
\ No newline at end of file
diff --git a/res/dist/mac/bundle/Contents/Resources/App.icns b/res/dist/mac/bundle/Contents/Resources/App.icns
new file mode 100644
index 000000000..72bfe6246
Binary files /dev/null and b/res/dist/mac/bundle/Contents/Resources/App.icns differ
diff --git a/res/dist/mac/bundle/Contents/Resources/Background.tiff b/res/dist/mac/bundle/Contents/Resources/Background.tiff
new file mode 100644
index 000000000..4a1be13e8
Binary files /dev/null and b/res/dist/mac/bundle/Contents/Resources/Background.tiff differ
diff --git a/res/dist/mac/bundle/Contents/Resources/Volume.icns b/res/dist/mac/bundle/Contents/Resources/Volume.icns
new file mode 100644
index 000000000..8273301fd
Binary files /dev/null and b/res/dist/mac/bundle/Contents/Resources/Volume.icns differ
diff --git a/res/dist/mac/dmgbuild/settings.py b/res/dist/mac/dmgbuild/settings.py
new file mode 100644
index 000000000..16ff4b8ad
--- /dev/null
+++ b/res/dist/mac/dmgbuild/settings.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# Example: https://dmgbuild.readthedocs.io/en/latest/example.html
+
+from __future__ import unicode_literals
+
+import os.path
+
+app = defines.get("app")
+app_basename = os.path.basename(app)
+format = defines.get("format", "UDBZ")
+size = defines.get("size", None)
+files = [app]
+symlinks = {"Applications": "/Applications"}
+icon = os.path.join(app, "Contents/Resources/Volume.icns")
+icon_locations = {
+ app_basename: (144, 190),
+ "Applications": (455, 190),
+}
+background = os.path.join(app, "Contents/Resources/Background.tiff")
+show_status_bar = False
+show_tab_view = False
+show_toolbar = False
+show_pathbar = False
+show_sidebar = False
+sidebar_width = 180
+window_rect = ((200, 120), (620, 420))
+default_view = "icon-view"
+show_icon_preview = False
+include_icon_view_settings = "auto"
+include_list_view_settings = "auto"
+arrange_by = None
+grid_offset = (0, 0)
+grid_spacing = 100
+scroll_position = (0, 0)
+label_pos = "bottom"
+text_size = 16
+icon_size = 100
+list_icon_size = 16
+list_text_size = 12
+list_scroll_position = (0, 0)
+list_sort_by = "name"
+list_use_relative_dates = True
+list_calculate_all_sizes = (False,)
+list_columns = ("name", "date-modified", "size", "kind", "date-added")
+list_column_widths = {
+ "name": 300,
+ "date-modified": 181,
+ "date-created": 181,
+ "date-added": 181,
+ "date-last-opened": 181,
+ "size": 97,
+ "kind": 115,
+ "label": 100,
+ "version": 75,
+ "comments": 300,
+}
+list_column_sort_directions = {
+ "name": "ascending",
+ "date-modified": "descending",
+ "date-created": "descending",
+ "date-added": "descending",
+ "date-last-opened": "descending",
+ "size": "descending",
+ "kind": "ascending",
+ "label": "ascending",
+ "version": "ascending",
+ "comments": "ascending",
+}
diff --git a/res/dist/macos/bundle/Deskflow.app/Contents/PkgInfo b/res/dist/macos/bundle/Deskflow.app/Contents/PkgInfo
deleted file mode 100644
index 8a95e2b34..000000000
--- a/res/dist/macos/bundle/Deskflow.app/Contents/PkgInfo
+++ /dev/null
@@ -1 +0,0 @@
-APPLDFLW
\ No newline at end of file
diff --git a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/.background.tiff b/res/dist/macos/bundle/Deskflow.app/Contents/Resources/.background.tiff
deleted file mode 100644
index e13ab35b3..000000000
Binary files a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/.background.tiff and /dev/null differ
diff --git a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/Deskflow.icns b/res/dist/macos/bundle/Deskflow.app/Contents/Resources/Deskflow.icns
deleted file mode 100644
index 8fc714750..000000000
Binary files a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/Deskflow.icns and /dev/null differ
diff --git a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/VolumeIcon.icns b/res/dist/macos/bundle/Deskflow.app/Contents/Resources/VolumeIcon.icns
deleted file mode 100644
index 0e165618f..000000000
Binary files a/res/dist/macos/bundle/Deskflow.app/Contents/Resources/VolumeIcon.icns and /dev/null differ
diff --git a/res/dist/macos/dmgbuild/settings.py b/res/dist/macos/dmgbuild/settings.py
deleted file mode 100644
index 3b282dfa3..000000000
--- a/res/dist/macos/dmgbuild/settings.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-import os.path
-
-# Use like this: dmgbuild -s settings.py "Test Volume" test.dmg
-# dmgbuild -s settings.py -D app=/path/to/My.app "My Application" MyApp.dmg
-
-# .. Useful stuff ..............................................................
-
-app = defines.get("app")
-app_basename = os.path.basename(app)
-
-# .. Basics ....................................................................
-
-# Volume format (see hdiutil create -help)
-format = defines.get("format", "UDBZ")
-
-# Volume size
-size = defines.get("size", None)
-
-# Files to include
-files = [app]
-
-# Symlinks to create
-symlinks = {"Applications": "/Applications"}
-
-# Volume icon
-#
-# You can either define icon, in which case that icon file will be copied to the
-# image, *or* you can define badge_icon, in which case the icon file you specify
-# will be used to badge the system's Removable Disk icon
-#
-icon = os.path.join(app, "Contents/Resources/VolumeIcon.icns")
-
-# Where to put the icons
-icon_locations = {
- app_basename: (144, 190),
- "Applications": (455, 190),
- ".background.tiff": (150, 450),
- ".VolumeIcon.icns": (455, 450),
-}
-
-# .. Window configuration ......................................................
-
-# Background
-#
-# This is a STRING containing any of the following:
-#
-# #3344ff - web-style RGB color
-# #34f - web-style RGB color, short form (#34f == #3344ff)
-# rgb(1,0,0) - RGB color, each value is between 0 and 1
-# hsl(120,1,.5) - HSL (hue saturation lightness) color
-# hwb(300,0,0) - HWB (hue whiteness blackness) color
-# cmyk(0,1,0,0) - CMYK color
-# goldenrod - X11/SVG named color
-# builtin-arrow - A simple built-in background with a blue arrow
-# /foo/bar/baz.png - The path to an image file
-#
-# The hue component in hsl() and hwb() may include a unit; it defaults to
-# degrees ('deg'), but also supports radians ('rad') and gradians ('grad'
-# or 'gon').
-#
-# Other color components may be expressed either in the range 0 to 1, or
-# as percentages (e.g. 60% is equivalent to 0.6).
-background = os.path.join(app, "Contents/Resources/.background.tiff")
-
-show_status_bar = False
-show_tab_view = False
-show_toolbar = False
-show_pathbar = False
-show_sidebar = False
-sidebar_width = 180
-
-# Window position in ((x, y), (w, h)) format
-window_rect = ((200, 120), (620, 420))
-
-# Select the default view; must be one of
-#
-# 'icon-view'
-# 'list-view'
-# 'column-view'
-# 'coverflow'
-#
-default_view = "icon-view"
-
-# General view configuration
-show_icon_preview = False
-
-# Set these to True to force inclusion of icon/list view settings (otherwise
-# we only include settings for the default view)
-include_icon_view_settings = "auto"
-include_list_view_settings = "auto"
-
-# .. Icon view configuration ...................................................
-
-arrange_by = None
-grid_offset = (0, 0)
-grid_spacing = 100
-scroll_position = (0, 0)
-label_pos = "bottom" # or 'right'
-text_size = 16
-icon_size = 100
-
-# .. List view configuration ...................................................
-
-# Column names are as follows:
-#
-# name
-# date-modified
-# date-created
-# date-added
-# date-last-opened
-# size
-# kind
-# label
-# version
-# comments
-#
-list_icon_size = 16
-list_text_size = 12
-list_scroll_position = (0, 0)
-list_sort_by = "name"
-list_use_relative_dates = True
-list_calculate_all_sizes = (False,)
-list_columns = ("name", "date-modified", "size", "kind", "date-added")
-list_column_widths = {
- "name": 300,
- "date-modified": 181,
- "date-created": 181,
- "date-added": 181,
- "date-last-opened": 181,
- "size": 97,
- "kind": 115,
- "label": 100,
- "version": 75,
- "comments": 300,
-}
-list_column_sort_directions = {
- "name": "ascending",
- "date-modified": "descending",
- "date-created": "descending",
- "date-added": "descending",
- "date-last-opened": "descending",
- "size": "descending",
- "kind": "ascending",
- "label": "ascending",
- "version": "ascending",
- "comments": "ascending",
-}
diff --git a/res/dist/wix/DeskflowBrowseDlg.wxs b/res/dist/wix/AppBrowseDlg.wxs
similarity index 96%
rename from res/dist/wix/DeskflowBrowseDlg.wxs
rename to res/dist/wix/AppBrowseDlg.wxs
index 1b3664b7d..9497816e6 100644
--- a/res/dist/wix/DeskflowBrowseDlg.wxs
+++ b/res/dist/wix/AppBrowseDlg.wxs
@@ -2,7 +2,7 @@
-
")
+ .arg(kUrlGnomeTrayFix, kStyleLink, kAppName);
#endif
QMessageBox::information(parent, "Notification area icon", message);
@@ -159,16 +152,17 @@ void showCloseReminder(QWidget *parent) {
void showFirstServerStartMessage(QWidget *parent) {
QMessageBox::information(
parent, "Server is running",
- "Great, the server is now running.
"
- "Now you can connect your other computers to this server. "
- "You should see a prompt here on the server when a new client tries to "
- "connect.
");
+ QString("Great, the %1 server is now running.
"
+ "Now you can connect your client computers to this server. "
+ "You should see a prompt here on the server when a new client "
+ "tries to connect.
")
+ .arg(kAppName));
}
void showFirstConnectedMessage(
QWidget *parent, bool closeToTray, bool enableService, bool isServer) {
- auto message = QString("Deskflow is now connected!
");
+ auto message = QString("%1 is now connected!
").arg(kAppName);
if (isServer) {
message +=
@@ -181,13 +175,17 @@ void showFirstConnectedMessage(
if (!closeToTray && !enableService) {
message +=
- "As you do not have the setting enabled to keep Deskflow running in "
- "the background, you'll need to keep this window open or minimized to "
- "keep Deskflow running.
";
+ QString(
+ "As you do not have the setting enabled to keep %1 running in "
+ "the background, you'll need to keep this window open or minimized "
+ "to keep %1 running.
")
+ .arg(kAppName);
} else {
message +=
- "You can now close this window and Deskflow will continue to run in "
- "the background. This setting can be disabled.
";
+ QString(
+ "You can now close this window and %1 will continue to run in "
+ "the background. This setting can be disabled.
")
+ .arg(kAppName);
}
QMessageBox::information(parent, "Connected", message);
@@ -201,16 +199,11 @@ void showDevThanks(QWidget *parent, const QString &productName) {
QMessageBox::information(
parent, "Thank you!",
QString("Thanks for using %1.
"
- "If you enjoy using this app, you can support the
"
- "developers by "
- R"(purchasing a license)"
- " or "
- R"(contributing code.)"
- "
"
+ "If you enjoy using this tool, visit our website:
"
+ R"(%2
)"
+ "Please report bugs and consider contributing code.
"
"This message will only appear once.
")
- .arg(
- productName, kUrlPurchase, kColorSecondary, kUrlGitHub,
- kColorSecondary));
+ .arg(productName, kUrlApp, kColorSecondary));
}
void showClientConnectError(
@@ -274,8 +267,10 @@ bool showClearSettings(QWidget *parent) {
const auto clear =
message.addButton(QObject::tr("Clear settings"), QMessageBox::AcceptRole);
message.setText(
- "Are you sure you want to clear all settings and restart Deskflow?
"
- "This action cannot be undone.
");
+ QString(
+ "Are you sure you want to clear all settings and restart %1?
"
+ "This action cannot be undone.
")
+ .arg(kAppName));
message.exec();
return message.clickedButton() == clear;
@@ -298,27 +293,27 @@ void showWaylandExperimental(QWidget *parent) {
"Wayland support is experimental and contains bugs.
"
R"(Please report bugs to us if you find any.
)"
"Happy testing!
")
- .arg(kUrlBugReport, kColorSecondary));
+ .arg(kUrlHelp, kColorSecondary));
}
void showWaylandLibraryError(QWidget *parent) {
QMessageBox::critical(
parent, "Library problem",
QString(
- "Sorry, while this version of Deskflow does support Wayland, "
+ "
Sorry, while this version of %1 does support Wayland, "
"this build was not linked with one or more of the required "
"libraries.
"
"Please either switch to X from your login screen or use a build "
"that uses the correct libraries.
"
"If you think this is incorrect, please "
- R"(report a bug.
)"
+ R"(report a bug.)"
"Please check the logs for more information.
")
- .arg(kUrlBugReport, kColorSecondary));
+ .arg(kAppName, kUrlHelp, kColorSecondary));
}
bool showUpdateCheckOption(QWidget *parent) {
QMessageBox message(parent);
- message.addButton(QObject::tr("Close"), QMessageBox::RejectRole);
+ message.addButton(QObject::tr("No thanks"), QMessageBox::RejectRole);
const auto checkButton = message.addButton(
QObject::tr("Check for updates"), QMessageBox::AcceptRole);
message.setText(
diff --git a/src/lib/gui/paths.h b/src/lib/gui/paths.h
index 73612d201..b36ec2051 100644
--- a/src/lib/gui/paths.h
+++ b/src/lib/gui/paths.h
@@ -23,7 +23,7 @@
#include
#include
-const auto kCertificateFilename = "Deskflow.pem";
+const auto kCertificateFilename = QString("%1.pem").arg(DESKFLOW_APP_NAME);
const auto kSslDir = "SSL";
namespace deskflow::gui::paths {
diff --git a/src/lib/gui/tls/TlsCertificate.cpp b/src/lib/gui/tls/TlsCertificate.cpp
index 77d5625ef..9e58c3755 100644
--- a/src/lib/gui/tls/TlsCertificate.cpp
+++ b/src/lib/gui/tls/TlsCertificate.cpp
@@ -26,7 +26,7 @@
static const char *const kCertificateKeyLength = "rsa:";
static const char *const kCertificateHashAlgorithm = "-sha256";
static const char *const kCertificateLifetime = "365";
-static const char *const kCertificateSubjectInfo = "/CN=Deskflow";
+static const char *const kCertificateSubjectInfo = "/CN=" DESKFLOW_APP_NAME;
#if defined(Q_OS_WIN)
static const char *const kWinOpenSslDir = "OpenSSL";
@@ -94,6 +94,12 @@ bool TlsCertificate::runTool(const QStringList &args) {
#endif
QStringList environment;
+
+// Windows is special! :)
+// For OpenSSL, it's very common to bundle the openssl.exe and openssl.cnf files
+// with the application. This is made a little more complex in the Windows dev
+// env, because vcpkg can't find the openssl.cnf file by default, so we need to
+// give it a bit of guidance by setting the `OPENSSL_CONF` env var.
#if defined(Q_OS_WIN)
const auto openSslDir = QDir(openSslWindowsDir());
const auto config = QDir::cleanPath(openSslDir.filePath(kConfigFile));
diff --git a/src/lib/gui/tls/TlsUtility.cpp b/src/lib/gui/tls/TlsUtility.cpp
index e21031564..c2ff57375 100644
--- a/src/lib/gui/tls/TlsUtility.cpp
+++ b/src/lib/gui/tls/TlsUtility.cpp
@@ -18,34 +18,24 @@
#include "TlsUtility.h"
#include "TlsCertificate.h"
-#include "gui/license/license_utils.h"
#include
#include
-using namespace deskflow::license;
-using namespace deskflow::gui::license;
-
namespace deskflow::gui {
-TlsUtility::TlsUtility(const IAppConfig &appConfig, const ILicense &license)
- : m_appConfig(appConfig),
- m_license(license) {}
+TlsUtility::TlsUtility(const IAppConfig &appConfig) : m_appConfig(appConfig) {}
-bool TlsUtility::isAvailable() const {
- return !isActivationEnabled() || m_license.isTlsAvailable();
-}
-
-bool TlsUtility::isAvailableAndEnabled() const {
+bool TlsUtility::isEnabled() const {
const auto &config = m_appConfig;
- return isAvailable() && config.tlsEnabled();
+ return config.tlsEnabled();
}
bool TlsUtility::generateCertificate() {
qDebug("generating tls certificate, "
"all clients must trust the new fingerprint");
- if (!isAvailableAndEnabled()) {
+ if (!isEnabled()) {
qCritical("unable to generate tls certificate, "
"tls is either not available or not enabled");
return false;
diff --git a/src/lib/gui/tls/TlsUtility.h b/src/lib/gui/tls/TlsUtility.h
index 202a87939..6619dfcb3 100644
--- a/src/lib/gui/tls/TlsUtility.h
+++ b/src/lib/gui/tls/TlsUtility.h
@@ -20,18 +20,16 @@
#include "gui/config/IAppConfig.h"
#include "TlsCertificate.h"
-#include "license/ILicense.h"
#include
namespace deskflow::gui {
class TlsUtility : public QObject {
- using ILicense = deskflow::license::ILicense;
Q_OBJECT
public:
- explicit TlsUtility(const IAppConfig &appConfig, const ILicense &license);
+ explicit TlsUtility(const IAppConfig &appConfig);
bool generateCertificate();
bool persistCertificate();
@@ -43,16 +41,10 @@ public:
* If licensing is enabled, it checks whether the product has TLS
* available, and if licensing is not enabled, true is returned.
*/
- bool isAvailableAndEnabled() const;
-
- /**
- * @return true if TLS is available, regardless of whether it is enabled.
- */
- bool isAvailable() const;
+ bool isEnabled() const;
private:
const IAppConfig &m_appConfig;
- const ILicense &m_license;
TlsCertificate m_certificate;
};
diff --git a/src/lib/license/CMakeLists.txt b/src/lib/license/CMakeLists.txt
deleted file mode 100644
index 79e8e7ebd..000000000
--- a/src/lib/license/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-# Deskflow -- mouse and keyboard sharing utility
-# Copyright (C) 2012-2024 Symless Ltd.
-# Copyright (C) 2009-2012 Nick Bolton
-#
-# This package is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# found in the file LICENSE that should have accompanied this file.
-#
-# This package is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-file(GLOB headers "*.h")
-file(GLOB sources "*.cpp")
-
-if(ADD_HEADERS_TO_SOURCES)
- list(APPEND sources ${headers})
-endif()
-
-add_library(license STATIC ${sources})
-
-target_link_libraries(license arch base)
diff --git a/src/lib/license/ILicense.h b/src/lib/license/ILicense.h
deleted file mode 100644
index ee34c06dc..000000000
--- a/src/lib/license/ILicense.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Deskflow -- mouse and keyboard sharing utility
- * Copyright (C) 2016 Symless Ltd.
- *
- * This package is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * found in the file LICENSE that should have accompanied this file.
- *
- * This package is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#pragma once
-
-class Server;
-class LicenseHandler;
-class LicenseTests;
-
-namespace deskflow::license {
-
-class ILicense {
-public:
- virtual ~ILicense() = default;
- virtual bool isTlsAvailable() const = 0;
-};
-
-} // namespace deskflow::license
diff --git a/src/lib/license/License.cpp b/src/lib/license/License.cpp
deleted file mode 100644
index 3eceb7d4b..000000000
--- a/src/lib/license/License.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Deskflow -- mouse and keyboard sharing utility
- * Copyright (C) 2016 Symless Ltd.
- *
- * This package is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * found in the file LICENSE that should have accompanied this file.
- *
- * This package is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include "License.h"
-
-#include "Product.h"
-#include "license/SerialKey.h"
-#include "license/parse_serial_key.h"
-
-#include
-#include
-
-using namespace std::chrono;
-
-namespace deskflow::license {
-
-License::License(const std::string &hexString)
- : m_serialKey(parseSerialKey(hexString)) {}
-
-License::License(const SerialKey &serialKey) : m_serialKey(serialKey) {
- if (!m_serialKey.isValid) {
- throw InvalidSerialKey();
- }
-}
-
-bool License::isTrial() const { return m_serialKey.type.isTrial(); }
-
-bool License::isSubscription() const {
- return m_serialKey.type.isSubscription();
-}
-
-bool License::isTimeLimited() const {
- return m_serialKey.type.isSubscription() || m_serialKey.type.isTrial();
-}
-
-bool License::isTlsAvailable() const {
- return m_serialKey.product.isTlsAvailable();
-}
-
-Edition License::productEdition() const {
- return m_serialKey.product.edition();
-}
-
-bool License::isExpiringSoon() const {
- if (!isTimeLimited()) {
- return false;
- }
-
- if (!m_serialKey.warnTime.has_value()) {
- throw NoTimeLimitError();
- }
-
- return m_nowFunc() >= m_serialKey.warnTime.value();
-}
-
-bool License::isExpired() const {
- if (!isTimeLimited()) {
- return false;
- }
-
- if (!m_serialKey.expireTime.has_value()) {
- throw NoTimeLimitError();
- }
-
- return m_nowFunc() >= m_serialKey.expireTime.value();
-}
-
-days License::daysLeft() const {
- if (!m_serialKey.expireTime.has_value()) {
- throw NoTimeLimitError();
- }
-
- auto expireTime = m_serialKey.expireTime.value();
-
- auto timeLeft = expireTime - m_nowFunc();
- return duration_cast(timeLeft);
-}
-
-std::string License::productName() const {
- auto name = m_serialKey.product.name();
- if (m_serialKey.type.isTrial()) {
- name += " (Trial)";
- }
- return name;
-}
-
-} // namespace deskflow::license
diff --git a/src/lib/license/License.h b/src/lib/license/License.h
deleted file mode 100644
index 05743ddee..000000000
--- a/src/lib/license/License.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Deskflow -- mouse and keyboard sharing utility
- * Copyright (C) 2016 Symless Ltd.
- *
- * This package is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * found in the file LICENSE that should have accompanied this file.
- *
- * This package is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#pragma once
-
-#include "ILicense.h"
-#include "SerialKey.h"
-
-#include
-#include
-#include
-#include
-
-class Server;
-class LicenseHandler;
-class LicenseTests;
-
-namespace deskflow::license {
-
-class License : public ILicense {
- friend class ::Server;
- friend class ::LicenseHandler;
- friend class ::LicenseTests;
-
- using days = std::chrono::days;
- using system_clock = std::chrono::system_clock;
- using time_point = system_clock::time_point;
- using NowFunc = std::function;
- using LicenseError = std::runtime_error;
-
-public:
- explicit License(const SerialKey &serialKey);
- explicit License(const std::string &hexString);
- ~License() override = default;
-
- friend bool operator==(License const &lhs, License const &rhs) {
- return lhs.m_serialKey == rhs.m_serialKey;
- }
-
- bool isTlsAvailable() const override;
-
- bool isValid() const { return m_serialKey.isValid; }
- bool isExpiringSoon() const;
- bool isExpired() const;
- bool isTrial() const;
- bool isSubscription() const;
- bool isTimeLimited() const;
- days daysLeft() const;
- Edition productEdition() const;
- std::string productName() const;
- const SerialKey &serialKey() const { return m_serialKey; }
- void invalidate() { m_serialKey = SerialKey::invalid(); }
-
- class InvalidSerialKey : public LicenseError {
- public:
- explicit InvalidSerialKey() : LicenseError("invalid serial key") {}
- };
-
- class NoTimeLimitError : public LicenseError {
- public:
- explicit NoTimeLimitError()
- : LicenseError("serial key has no time limit") {}
- };
-
-protected:
- void setNowFunc(const NowFunc &nowFunc) { m_nowFunc = nowFunc; }
-
-private:
- // for intentionality, force use of `invalid()` static function.
- License() = default;
-
- // prevent copy, so that changes can be reflected in one instance.
- License(const License &) = default;
- License &operator=(const License &) = default;
-
- static License invalid() { return License(); }
-
- SerialKey m_serialKey = SerialKey::invalid();
- NowFunc m_nowFunc = []() { return system_clock::now(); };
-};
-
-} // namespace deskflow::license
diff --git a/src/lib/license/Product.cpp b/src/lib/license/Product.cpp
deleted file mode 100644
index a82e9f7df..000000000
--- a/src/lib/license/Product.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Deskflow -- mouse and keyboard sharing utility
- * Copyright (C) 2016 Symless Ltd.
- *
- * This package is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * found in the file LICENSE that should have accompanied this file.
- *
- * This package is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include