Compare commits
200 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a80cea3ca7 | |||
| 9929b09088 | |||
| 226c835ee9 | |||
| fbda5b4053 | |||
| f31cb26e0b | |||
| 1bbc581037 | |||
| ce45d74806 | |||
| 916f1e6144 | |||
| 4f4261a237 | |||
| e06741e62e | |||
| 585a895b4a | |||
| dc5c2b9422 | |||
| 3822336db2 | |||
| 5ca9afc3f7 | |||
| 8273c0e70b | |||
| fa9b2d91d5 | |||
| 170b4251f3 | |||
| ddf6450486 | |||
| 4a769e6a7f | |||
| 07fb3a9a7a | |||
| 155e4d6b32 | |||
| f87b4bc0c2 | |||
| f66a0219f6 | |||
| 3a53149a48 | |||
| 45f328cd80 | |||
| 1e3d332002 | |||
| 3359a2a9d9 | |||
| e369af9d74 | |||
| afab39e7f8 | |||
| e33405bef8 | |||
| 9875bc6613 | |||
| 16a1ba8f45 | |||
| 37889e5659 | |||
| 1835a2cab6 | |||
| 8c314ad82c | |||
| da64ca577c | |||
| 232e8fafee | |||
| fb686ede21 | |||
| ce784ab383 | |||
| 946a2b778e | |||
| 45bde73810 | |||
| 8b62f5b083 | |||
| f74cce32a4 | |||
| 170d6f4889 | |||
| 48a8111fc5 | |||
| 656601f2ba | |||
| 1880a157b6 | |||
| 3cb1980af3 | |||
| c24444c77e | |||
| 675e10d7b1 | |||
| 915760b899 | |||
| 077412f7ec | |||
| 968037b85b | |||
| 08d3347740 | |||
| ad6551262c | |||
| 337d236f54 | |||
| 04d6895990 | |||
| 1b13c843aa | |||
| 9e2880f714 | |||
| e8010eea60 | |||
| 75c0b53113 | |||
| bf96a641bf | |||
| 7db781b9bf | |||
| 8bfe0c18bc | |||
| 10f7b05a73 | |||
| ba97d63403 | |||
| da4b85b3fb | |||
| 5657152c58 | |||
| 9b4635b6d2 | |||
| 1aa6e8c6bb | |||
| 6846a97eec | |||
| f26581f20a | |||
| 01565ba9a9 | |||
| 32b84f0a4b | |||
| d5a8dd7927 | |||
| dfbd612e2f | |||
| a406b51f96 | |||
| b2532c81b9 | |||
| a362174e73 | |||
| 7b7ff81a9f | |||
| 2136af68b5 | |||
| df91d845f7 | |||
| f967b9ed46 | |||
| 5d183c98e9 | |||
| f3657edc80 | |||
| 2a8a43a689 | |||
| 498e3aa015 | |||
| 58323f515f | |||
| 560345cf4f | |||
| 90d27a174d | |||
| 8b54b84880 | |||
| 45050d3d36 | |||
| f0a946a0f1 | |||
| db6b6b9386 | |||
| b10eb3baa8 | |||
| 9ea143c1df | |||
| a6b5879df3 | |||
| 1b904e7c02 | |||
| f7ca548ee2 | |||
| 7c74b90620 | |||
| 46915bff94 | |||
| 949e1c0d71 | |||
| b1fa9eadd9 | |||
| a786cdf972 | |||
| a5cd0fab9e | |||
| 512faeea28 | |||
| 47366f1272 | |||
| 199f682e27 | |||
| afff2eb6ac | |||
| 9167bf04f6 | |||
| 0298a132c1 | |||
| 7b3d8c3dc3 | |||
| 06aa41e8f5 | |||
| bf4a762124 | |||
| 7199e5f170 | |||
| 3d2883ad02 | |||
| 6395630964 | |||
| a32463586c | |||
| 9c9feba565 | |||
| 37fcec2554 | |||
| 246f5d59ab | |||
| 710c1dd353 | |||
| add8d5370a | |||
| 33b14ccc5c | |||
| ba5eaa4c90 | |||
| 4ce81b59fb | |||
| 71e74735c0 | |||
| 99251ad867 | |||
| 9b9ecb0d05 | |||
| 3f2bb2531a | |||
| 01d67e4614 | |||
| 219958898e | |||
| ae3bcfc809 | |||
| dc9a5c0f12 | |||
| 1dc449fe0a | |||
| 52f616a15d | |||
| da6b3942ae | |||
| 9a5c1a3212 | |||
| 8424ffa438 | |||
| e2a0a97705 | |||
| 78d086369b | |||
| 5f78d175c9 | |||
| 2b930a7b03 | |||
| 28c8aae9af | |||
| 3cc43bf1ce | |||
| c78dccca71 | |||
| 0a6f79fb31 | |||
| 5925d42dbd | |||
| 6af331bd93 | |||
| 87b4e3b7fe | |||
| 23c4cadf17 | |||
| 6dcfcd50a2 | |||
| f70528d082 | |||
| f2f75ae7b9 | |||
| 572cc80577 | |||
| 636e3eab96 | |||
| 9c4f6e6d0b | |||
| 3525b8a686 | |||
| 9b7cd1e250 | |||
| 26926a4a6a | |||
| 3991fc0d25 | |||
| 5cff026d7e | |||
| e4b348c183 | |||
| 24db09b023 | |||
| 181c34e662 | |||
| ccfff7015a | |||
| 6b641a432a | |||
| 10873eddcd | |||
| 5b76982093 | |||
| c498e148b8 | |||
| abe8146631 | |||
| c630ad0952 | |||
| ce35234f18 | |||
| c5247a15c7 | |||
| c03e3f56a7 | |||
| 821a9599ba | |||
| 0361f850eb | |||
| c66d7a6942 | |||
| 8340f106e7 | |||
| b3775eb6fd | |||
| e940b8526b | |||
| 9604a9e747 | |||
| fe67b92cdc | |||
| 4500e7a1aa | |||
| 78a8bba7a4 | |||
| 14dfcb672d | |||
| 6c3b2b3e6b | |||
| f6b9a5f204 | |||
| 38631193b5 | |||
| c959e641cb | |||
| 02c5418b9e | |||
| eedb3ad1c3 | |||
| 159f49c5ee | |||
| 80503cd2c6 | |||
| 132e1975d3 | |||
| 932ca44d75 | |||
| e3ed711b98 | |||
| 32d36ab0be | |||
| 0c28a38d90 | |||
| 049e34f7a5 |
@ -13,16 +13,40 @@ BasedOnStyle: LLVM
|
||||
# Turn off LLVM default alignment of params with the opening bracket,
|
||||
# which can be less readable in some cases in our code base.
|
||||
#
|
||||
# Using `AlwaysBreak` will result in:
|
||||
# Using `BlockIndent` will result in:
|
||||
# void fooBarBazQuxHelloWorld(
|
||||
# int a,
|
||||
# int b);
|
||||
# int b
|
||||
# );
|
||||
#
|
||||
# Instead of:
|
||||
# void fooBarBazQuxHelloWorld(int a,
|
||||
# int b);
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
|
||||
# Turn off LLVM default packing of ctor initializers.
|
||||
# This makes it easier to see which members were initialized and in what order.
|
||||
PackConstructorInitializers: CurrentLine
|
||||
|
||||
# up our limit to 120
|
||||
ColumnLimit: 120
|
||||
|
||||
# Custom Breaking rules
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
|
||||
# no single line functions
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[{*.yml,*.yaml,*.json,CMakeLists.txt,*.cmake}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
65
.env.example
@ -1,65 +0,0 @@
|
||||
#
|
||||
# Usage: Copy this .env.example file to .env
|
||||
#
|
||||
|
||||
#
|
||||
# App
|
||||
#
|
||||
|
||||
# Shows the test menu in the GUI (on by default in debug mode)
|
||||
# DESKFLOW_TEST_MENU=true
|
||||
|
||||
# Version checker URL to use (useful for testing)
|
||||
# DESKFLOW_VERSION_URL="https://api.deskflow.org/version?fake=1.100.0"
|
||||
|
||||
# Enable debug logging in the GUI (on by default in debug mode)
|
||||
# DESKFLOW_GUI_DEBUG=true
|
||||
|
||||
# Enable verbose logging in the GUI (always off by default)
|
||||
# DESKFLOW_GUI_VERBOSE=true
|
||||
|
||||
# Reset all settings and delete all data on startup
|
||||
# DESKFLOW_RESET_ALL=true
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
# [Windows] The version of Qt to build against (overrides the value in the config.yml file)
|
||||
# QT_VERSION=1.2.3
|
||||
|
||||
#
|
||||
# Packaging (optional)
|
||||
#
|
||||
|
||||
# [Linux] Build extra packages (self-extracting tar.gz and tar.gz)
|
||||
# LINUX_EXTRA_PACKAGES=true
|
||||
|
||||
# [Linux] Run the package command as a different user (requires sudo)
|
||||
# LINUX_PACKAGE_USER=build
|
||||
|
||||
# [Windows] Base64 encoded PFX code signing certificate
|
||||
# WINDOWS_PFX_CERTIFICATE="very-long-base64-encoded-string"
|
||||
|
||||
# [Windows] Password for the PFX code signing certificate
|
||||
# WINDOWS_PFX_PASSWORD="super-secret-password"
|
||||
|
||||
# [macOS] Certificate ID for the Developer ID Application code signing certificate
|
||||
# APPLE_CODESIGN_ID="Developer ID Application: Acme Inc (ABC123XYZ9)"
|
||||
|
||||
# [macOS] Base64 encoded P12 code signing certificate
|
||||
# APPLE_P12_CERTIFICATE="very-long-base64-encoded-string"
|
||||
|
||||
# [macOS] Password for the P12 code signing certificate
|
||||
# APPLE_P12_PASSWORD="super-secret-password"
|
||||
|
||||
# [macOS] Apple Team ID
|
||||
# https://developer.apple.com/account/#/membership
|
||||
# APPLE_TEAM_ID="ABC123XYZ9"
|
||||
|
||||
# [macOS] Apple ID used to notarize the app
|
||||
# APPLE_NOTARY_USER="example@example.com"
|
||||
|
||||
# [macOS] App-specific password for the Apple ID
|
||||
# https://support.apple.com/en-gb/102654
|
||||
# APPLE_NOTARY_PASSWORD="super-secret-password"
|
||||
9
.gitattributes
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-FileCopyrightText: Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
#auto handle line feed
|
||||
* text=auto eol=lf
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.github* export-ignore
|
||||
43
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -27,7 +27,7 @@ body:
|
||||
attributes:
|
||||
label: Deskflow version number
|
||||
description: You can find the Deskflow version number on the about screen.
|
||||
placeholder: 1.2.3
|
||||
placeholder: 1.2.3.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@ -39,9 +39,10 @@ body:
|
||||
options:
|
||||
# Empty option to force selection
|
||||
-
|
||||
- Local developer build (built it yourself)
|
||||
- Deskflow package (downloaded from Deskflow)
|
||||
- Community package (apt, dnf, brew, etc.)
|
||||
- Deskflow package (downloaded from us)
|
||||
- Local developer build (built it myself)
|
||||
- Other (please specify)
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
@ -54,12 +55,40 @@ body:
|
||||
options:
|
||||
- label: Windows
|
||||
- label: macOS
|
||||
- label: Linux
|
||||
- label: Linux (X11)
|
||||
- label: Linux (Wayland)
|
||||
- label: BSD-derived
|
||||
- label: Other
|
||||
- label: Other (please specify)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: linux-wayland
|
||||
attributes:
|
||||
label: Wayland on Linux
|
||||
description: If using Wayland on Linux, please review the [known issues](https://github.com/deskflow/deskflow/discussions/7499) before reporting.
|
||||
options:
|
||||
- label: I have reviewed the Wayland [known issues](https://github.com/deskflow/deskflow/discussions/7499) and my issue is new
|
||||
- label: I am not using Wayland on Linux
|
||||
|
||||
- type: checkboxes
|
||||
id: mac-signing
|
||||
attributes:
|
||||
label: Signing on macOS
|
||||
description: If using macOS and the app crashes, try [Apple's solution](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unknown-developer-mh40616/mac) before reporting.
|
||||
options:
|
||||
- label: I have authorized the app to run on my Mac
|
||||
- label: I am not using macOS
|
||||
|
||||
- type: checkboxes
|
||||
id: continuous-build
|
||||
attributes:
|
||||
label: Continuous build
|
||||
description: Please try the latest [continuous build](https://github.com/deskflow/deskflow/releases) of Deskflow. It may have a fix for your issue.
|
||||
options:
|
||||
- label: I have tried the latest continuous build and the issue persists
|
||||
- label: I am unable to try the latest continuous build
|
||||
|
||||
- type: textarea
|
||||
id: os-version
|
||||
attributes:
|
||||
@ -87,8 +116,6 @@ body:
|
||||
- Windows 11 server, macOS 15 client
|
||||
- Each computer has a single monitor
|
||||
- Windows is on the left, macOS is on the right
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: repro-steps
|
||||
@ -102,8 +129,6 @@ body:
|
||||
1. Start Deskflow
|
||||
2. Click 'Configure Server'
|
||||
3. Click 'Apply'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
|
||||
80
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -6,85 +6,11 @@ body:
|
||||
attributes:
|
||||
value: Thanks for taking the time to help us improve Deskflow.
|
||||
|
||||
- type: dropdown
|
||||
id: project
|
||||
attributes:
|
||||
label: Project
|
||||
description: Are you using Deskflow or a fork/derivative?
|
||||
options:
|
||||
# Empty option to force selection
|
||||
-
|
||||
- Deskflow
|
||||
- Barrier
|
||||
- Input Leap
|
||||
- Synergy
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating systems (OS)
|
||||
description: Which operating systems (OS) are you using?
|
||||
options:
|
||||
- label: Windows
|
||||
- label: macOS
|
||||
- label: Linux
|
||||
- label: BSD-derived
|
||||
- label: Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: os-version
|
||||
id: request
|
||||
attributes:
|
||||
label: OS versions/distros
|
||||
label: Feature Request
|
||||
description: |
|
||||
Please provide the version number of your operating system (OS).
|
||||
If you're using Linux, please provide the name of the distribution.
|
||||
placeholder: |
|
||||
- Windows 11
|
||||
- macOS 15
|
||||
- Ubuntu 24.04
|
||||
- FreeBSD 14.0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
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.
|
||||
placeholder: |
|
||||
- Windows 11 server, macOS 15 client
|
||||
- Each computer has a single monitor
|
||||
- Windows is on the left, macOS is on the right
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What problem are you trying to solve?
|
||||
description: |
|
||||
The most important part of problem solving is understanding the problem.
|
||||
The more detail you provide, the better we can understand your idea.
|
||||
“If I had only one hour to save the world,
|
||||
I would spend fifty-five minutes defining the problem,
|
||||
and only five minutes finding the solution.”
|
||||
— Albert Einstein
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: What solution do you propose?
|
||||
description: |
|
||||
Please describe the solution you have in mind.
|
||||
Please describe the feature you have in mind.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
34
.github/actions/add-kitware-repo/action.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: "Add Kitware repo"
|
||||
description: "Add Kitware repo for Debian-like distros"
|
||||
|
||||
inputs:
|
||||
distro:
|
||||
description: "Ubuntu codename, Kitware uses: noble, jammy, focal"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
|
||||
# This mirrors instructions at https://apt.kitware.com
|
||||
- name: Add repo
|
||||
run: |
|
||||
apt update -y -qqq
|
||||
apt install ca-certificates gpg wget -y -qqq
|
||||
|
||||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \
|
||||
| gpg --dearmor - \
|
||||
> /usr/share/keyrings/kitware-archive-keyring.gpg
|
||||
|
||||
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${{ inputs.distro }} main' \
|
||||
> /etc/apt/sources.list.d/kitware.list
|
||||
|
||||
apt update -y -qqq
|
||||
env:
|
||||
# Prevent apt prompting for input.
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
shell: bash
|
||||
10
.github/actions/get-version/action.yml
vendored
@ -6,10 +6,10 @@ runs:
|
||||
|
||||
steps:
|
||||
- run: |
|
||||
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||
echo "DESKFLOW_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
if [[ "${{ github.event.inputs.version }}" != "" ]]; then
|
||||
echo "DESKFLOW_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||
echo "DESKFLOW_VERSION=$(git describe --long | sed 's/-/./g;s/v//g' | grep -o '^[0-9]*.[0-9]*.[0-9]*.[0-9]*')">> $GITHUB_ENV
|
||||
if [[ "$GITHUB_REF" == *"tags/v"* ]]; then
|
||||
echo "DESKFLOW_PACKAGE_VERSION=$(echo $GITHUB_REF | sed 's,refs/tags/v,,g')">> $GITHUB_ENV
|
||||
else
|
||||
echo "DESKFLOW_PACKAGE_VERSION=continuous">> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
51
.github/actions/init-python/action.yml
vendored
@ -1,50 +1,23 @@
|
||||
# Important: Do not be tempted to cache the .venv dir (Python virtual environment).
|
||||
# When the runner environment changes (e.g. Python is upgraded), the venv will need to be
|
||||
# re-created. Trying to upgrade a venv can be complex and it's usually more practical re-create it.
|
||||
# We don't save much time anyway by caching the venv so it's not worth the added complexity.
|
||||
|
||||
name: "Setup Python venv"
|
||||
description: "Creates and caches a Python virtual environment"
|
||||
|
||||
inputs:
|
||||
cache:
|
||||
description: "Cache Python venv"
|
||||
default: true
|
||||
|
||||
setup:
|
||||
description: "Setup Python venv"
|
||||
default: true
|
||||
|
||||
python-bin:
|
||||
description: "Python binary to use"
|
||||
default: "python3"
|
||||
|
||||
cache-key:
|
||||
description: "Cache key (note: hash is appended)"
|
||||
required: true
|
||||
description: "Creates a Python virtual environment (venv)"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
- name: Check cache key
|
||||
if: ${{ inputs.cache }}
|
||||
run: |
|
||||
if [ -z "${{ inputs.cache-key }}" ]; then
|
||||
echo "Cache key is required"
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Cache Python venv
|
||||
if: ${{ inputs.cache }}
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .venv
|
||||
key: python-venv-${{ inputs.cache-key }}-${{ hashFiles('scripts/pyproject.toml') }}
|
||||
|
||||
# Use bash if to make output clearer in case of skipping.
|
||||
- name: Setup Python venv
|
||||
run: |
|
||||
if [ "${{ inputs.setup }}" = "true" ]; then
|
||||
echo "Setting up Python venv"
|
||||
${{ inputs.python-bin }} -m venv .venv
|
||||
if [ "${{ runner.os }}" == "Windows" ]; then
|
||||
python=python
|
||||
else
|
||||
echo "Skipping Python venv setup"
|
||||
python=python3
|
||||
fi
|
||||
|
||||
echo "Setting up Python venv, bin=$python"
|
||||
$python -m venv .venv
|
||||
shell: bash
|
||||
|
||||
100
.github/actions/install-dependencies/action.yml
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
# SPDX-FileCopyrightText: 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: "Install dependencies for deskflow"
|
||||
description: "Install the dependencies needed to build deskflow"
|
||||
|
||||
inputs:
|
||||
like:
|
||||
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"
|
||||
required: false
|
||||
|
||||
outputs:
|
||||
vcpkg-cmake-config:
|
||||
description: "windows vcpkg output for cmaket"
|
||||
value: ${{ steps.vcpkg.outputs.vcpkg-cmake-config }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
- name: Install Depends
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
echo "Window not supported yet"
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
brew install cmake googletest ninja openssl --quiet
|
||||
elif [ "$RUNNER_OS" == "Linux" ]; then
|
||||
if [ ${{inputs.like}} == "debian" ]; then
|
||||
apt update -qqq > /dev/null
|
||||
apt install -qqq cmake build-essential ninja-build \
|
||||
xorg-dev libx11-dev libxtst-dev libssl-dev \
|
||||
libglib2.0-dev libgdk-pixbuf-2.0-dev libnotify-dev \
|
||||
libxkbfile-dev qt6-base-dev qt6-tools-dev \
|
||||
libgtk-3-dev libgtest-dev libgmock-dev libpugixml-dev \
|
||||
libei-dev libportal-dev libtomlplusplus-dev libcli11-dev -y >/dev/null
|
||||
elif [ ${{inputs.like}} == "fedora" ]; then
|
||||
dnf install -y cmake make ninja-build gcc-c++ \
|
||||
rpm-build openssl-devel glib2-devel \
|
||||
gdk-pixbuf2-devel libXtst-devel libnotify-devel \
|
||||
libxkbfile-devel qt6-qtbase-devel qt6-qttools-devel \
|
||||
gtk3-devel gtest-devel gmock-devel pugixml-devel \
|
||||
libei-devel libportal-devel tomlplusplus-devel \
|
||||
cli11-devel
|
||||
elif [ ${{inputs.like}} == "suse" ]; then
|
||||
zypper refresh
|
||||
zypper install -y --force-resolution \
|
||||
cmake make ninja gcc-c++ rpm-build libopenssl-devel \
|
||||
glib2-devel gdk-pixbuf-devel libXtst-devel libnotify-devel \
|
||||
libxkbfile-devel qt6-base-devel qt6-tools-devel gtk3-devel \
|
||||
googletest-devel googlemock-devel pugixml-devel libei-devel \
|
||||
libportal-devel tomlplusplus-devel cli11-devel
|
||||
elif [ ${{ inputs.like }} == "arch" ]; then
|
||||
pacman -Syu --noconfirm base-devel cmake ninja \
|
||||
gcc openssl glib2 gdk-pixbuf2 libxtst libnotify \
|
||||
libxkbfile gtest pugixml libei libportal \
|
||||
qt6-base qt6-tools gtk3 tomlplusplus cli11
|
||||
else
|
||||
echo "Unknown like"
|
||||
fi
|
||||
else
|
||||
echo "Unknown OS: $RUNNER_OS"
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: Install Qt
|
||||
if: ${{runner.os == 'macOS' }}
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
dir: "/Users/runner"
|
||||
version: ${{inputs.mac-qt-version}}
|
||||
cache: true
|
||||
cache-key-prefix: ${{matrix.target.os}}-${{env.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
|
||||
# downloads directly from the `ninja-build` GitHub project releases.
|
||||
- name: Install Ninja
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
uses: seanmiddleditch/gha-setup-ninja@master
|
||||
|
||||
- name: Build and cache vcpkg
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
id: vcpkg
|
||||
uses: johnwason/vcpkg-action@v6
|
||||
with:
|
||||
manifest-dir: ${{ github.workspace }}
|
||||
triplet: x64-windows-release
|
||||
token: ${{ github.token }}
|
||||
github-binarycache: true
|
||||
|
||||
- name: Install Wix
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
run: |
|
||||
dotnet tool install --global wix --version 4.0.4
|
||||
wix extension add --global WixToolset.UI.wixext/4.0.4
|
||||
shell: pwsh
|
||||
21
.github/actions/lint-clang/action.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: "Lint clang"
|
||||
description: "Lint with Clang formatter"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
steps:
|
||||
- name: Setup Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
pip install pyyaml clang_format
|
||||
|
||||
- name: Linting with Clang formatter
|
||||
uses: ./.github/actions/lint-error
|
||||
with:
|
||||
format-command: ./scripts/lint_clang.py -f
|
||||
format-tool: "clang-format"
|
||||
29
.github/actions/test-summary/action.yml
vendored
@ -1,13 +1,24 @@
|
||||
name: "Test Summary"
|
||||
description: "Creates a markdown table from test results and uploads a summary file"
|
||||
|
||||
inputs:
|
||||
download-pattern:
|
||||
description: "The pattern to download test result rows"
|
||||
required: false
|
||||
default: test-result-*
|
||||
|
||||
upload-name:
|
||||
description: "The artifact upload name for the summary"
|
||||
required: false
|
||||
default: summary-tests
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Download test result rows
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: test-result-*
|
||||
pattern: ${{ inputs.download-pattern }}
|
||||
merge-multiple: true
|
||||
path: rows
|
||||
|
||||
@ -44,24 +55,30 @@ runs:
|
||||
|
||||
table="${{ steps.markdown-table.outputs.markdown }}"
|
||||
if [ -z "$table" ]; then
|
||||
echo "No test results found" > $GITHUB_STEP_SUMMARY
|
||||
echo "No test results found" | tee $GITHUB_STEP_SUMMARY >&2
|
||||
exit 1
|
||||
else
|
||||
echo "$table" > $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
count=$(echo -n "$table" | grep -o "❌" | wc -l || echo 0)
|
||||
count=$(echo "$table" | awk -v RS='' '{gsub(/[^❌]/, ""); print length}')
|
||||
file="ci-summary.md"
|
||||
|
||||
if [ $count -gt 0 ]; then
|
||||
file="ci-summary.md"
|
||||
echo "❌🔬 Tests failed: $count" > $file
|
||||
echo "❌🔬 Tests failed: $count" | tee $file
|
||||
echo "file=$file" >> $GITHUB_OUTPUT
|
||||
else
|
||||
# For debugging; don't send success to CI summary (reduce noise).
|
||||
echo > $file
|
||||
echo "✅🔬 All tests passed"
|
||||
fi
|
||||
|
||||
shell: bash
|
||||
|
||||
- name: Upload CI summary
|
||||
if: steps.summary.outputs.file
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: summary-tests
|
||||
name: ${{ inputs.upload-name }}
|
||||
path: ${{ steps.summary.outputs.file }}
|
||||
if-no-files-found: error
|
||||
|
||||
32
.github/actions/winget-publish/action.yaml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Winget Publish
|
||||
description: A composite action to publish packages to the Windows Package Manager (Winget) repository
|
||||
|
||||
inputs:
|
||||
release-version:
|
||||
description: "Version to publish to Winget package manager (without 'v' prefix)"
|
||||
required: true
|
||||
token:
|
||||
description: "GitHub token with public read permissions on the source repo"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Submit package to Windows Package Manager Community Repository
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ inputs.token }}
|
||||
run: |
|
||||
# Download latest wingetcreate
|
||||
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
|
||||
$packageId = "Deskflow.Deskflow"
|
||||
$installerUrl = "https://github.com/deskflow/deskflow/releases/download/v${{ inputs.release-version }}/deskflow-${{ inputs.release-version }}.0_win64.msi"
|
||||
|
||||
# Submit package update
|
||||
.\wingetcreate.exe update "$packageId" `
|
||||
--version "${{ inputs.release-version }}" `
|
||||
--urls "$installerUrl" `
|
||||
--submit `
|
||||
--token "${{ inputs.token }}"
|
||||
shell: pwsh
|
||||
17
.github/docker/archlinux/Dockerfile
vendored
@ -1,17 +0,0 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG BASE_IMAGE
|
||||
FROM $BASE_IMAGE AS base
|
||||
|
||||
FROM base AS deps
|
||||
|
||||
RUN pacman -Syu --noconfirm git python sudo && \
|
||||
pacman -Scc --noconfirm
|
||||
|
||||
RUN useradd -m build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=bind,target=/app,rw \
|
||||
./scripts/install_deps.py && \
|
||||
pacman -Scc --noconfirm
|
||||
17
.github/docker/debian/Dockerfile
vendored
@ -1,17 +0,0 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG BASE_IMAGE
|
||||
FROM $BASE_IMAGE AS base
|
||||
|
||||
FROM base AS deps
|
||||
|
||||
RUN apt update && \
|
||||
apt dist-upgrade -y && \
|
||||
apt install -y git python3 && \
|
||||
apt clean
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=bind,target=/app,rw \
|
||||
./scripts/install_deps.py && \
|
||||
apt clean
|
||||
16
.github/docker/fedora/Dockerfile
vendored
@ -1,16 +0,0 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG BASE_IMAGE
|
||||
FROM $BASE_IMAGE AS base
|
||||
|
||||
FROM base AS deps
|
||||
|
||||
RUN dnf upgrade -y && \
|
||||
dnf install -y git python3 && \
|
||||
dnf clean all
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=bind,target=/app,rw \
|
||||
./scripts/install_deps.py && \
|
||||
dnf clean all
|
||||
17
.github/docker/opensuse/Dockerfile
vendored
@ -1,17 +0,0 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG BASE_IMAGE
|
||||
FROM $BASE_IMAGE AS base
|
||||
|
||||
FROM base AS deps
|
||||
|
||||
RUN zypper refresh && \
|
||||
zypper update -y && \
|
||||
zypper install -y git python3 && \
|
||||
zypper clean --all
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN --mount=type=bind,target=/app,rw \
|
||||
./scripts/install_deps.py && \
|
||||
zypper clean --all
|
||||
128
.github/workflows/build-containers.yml
vendored
@ -1,128 +0,0 @@
|
||||
# Weekly build of the Linux Docker containers.
|
||||
#
|
||||
# The objective is to reduce the problem where package updates often break the build process
|
||||
# due to transient network errors.
|
||||
#
|
||||
# We use Docker Buildx instead of Docker Automated Builds so that we can create an image that is
|
||||
# always at most a week out of date (instead of the last time a Dockerfile change was pushed).
|
||||
|
||||
name: Build containers
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 5 * * 0"
|
||||
|
||||
jobs:
|
||||
build-containers:
|
||||
name: ${{ matrix.os.name }}
|
||||
runs-on: ${{ matrix.os.runs-on }}
|
||||
if: ${{ vars.BUILD_CONTAINERS }}
|
||||
timeout-minutes: 10
|
||||
|
||||
strategy:
|
||||
# Build all images even if some fail.
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
os:
|
||||
- name: debian-13-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: debian
|
||||
base-image: debian:trixie-slim
|
||||
platform: amd64
|
||||
|
||||
- name: debian-12-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: debian
|
||||
base-image: debian:12-slim
|
||||
platform: amd64
|
||||
|
||||
- name: debian-12-arm64
|
||||
runs-on: ubuntu-24.04-2-core-arm64
|
||||
config-dir: debian
|
||||
base-image: arm64v8/debian:12-slim
|
||||
platform: arm64
|
||||
|
||||
- name: ubuntu-24.04-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: debian
|
||||
base-image: ubuntu:24.04
|
||||
platform: amd64
|
||||
|
||||
- name: ubuntu-22.04-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: debian
|
||||
base-image: ubuntu:22.04
|
||||
platform: amd64
|
||||
|
||||
- name: fedora-40-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: fedora
|
||||
base-image: fedora:40
|
||||
platform: amd64
|
||||
|
||||
- name: fedora-40-arm64
|
||||
runs-on: ubuntu-24.04-2-core-arm64
|
||||
config-dir: fedora
|
||||
base-image: arm64v8/fedora:40
|
||||
platform: arm64
|
||||
|
||||
- name: fedora-39-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: fedora
|
||||
base-image: fedora:39
|
||||
platform: amd64
|
||||
|
||||
- name: rockylinux-9-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: fedora
|
||||
base-image: rockylinux:9
|
||||
platform: amd64
|
||||
|
||||
- name: almalinux-9-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: fedora
|
||||
base-image: almalinux:9
|
||||
platform: amd64
|
||||
|
||||
- name: opensuse-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: opensuse
|
||||
base-image: opensuse/tumbleweed:latest
|
||||
platform: amd64
|
||||
|
||||
- name: archlinux-amd64
|
||||
runs-on: ubuntu-latest
|
||||
config-dir: archlinux
|
||||
base-image: archlinux:latest
|
||||
platform: amd64
|
||||
|
||||
- name: manjaro-amd64
|
||||
config-dir: archlinux
|
||||
runs-on: ubuntu-latest
|
||||
base-image: manjarolinux/base:latest
|
||||
platform: amd64
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
context: .
|
||||
file: ./.github/docker/${{ matrix.os.config-dir }}/Dockerfile
|
||||
tags: deskflow/deskflow:${{ matrix.os.name }}
|
||||
build-args: BASE_IMAGE=${{ matrix.os.base-image }}
|
||||
platforms: linux/${{ matrix.os.platform }}
|
||||
76
.github/workflows/ci-linux.json
vendored
@ -1,76 +0,0 @@
|
||||
{
|
||||
"distro": [
|
||||
{
|
||||
"name": "debian-13-amd64",
|
||||
"container": "deskflow/deskflow:debian-13-amd64",
|
||||
"runs-on": "ubuntu-latest",
|
||||
"extra-packages": true
|
||||
},
|
||||
{
|
||||
"name": "debian-12-arm64",
|
||||
"container": "deskflow/deskflow:debian-12-arm64",
|
||||
"runs-on": "ubuntu-24.04-4-core-arm64",
|
||||
"extra-packages": true
|
||||
},
|
||||
{
|
||||
"name": "debian-12-amd64",
|
||||
"container": "deskflow/deskflow:debian-12-amd64",
|
||||
"runs-on": "ubuntu-latest",
|
||||
"extra-packages": true
|
||||
},
|
||||
{
|
||||
"name": "ubuntu-24.04-amd64",
|
||||
"container": "deskflow/deskflow:ubuntu-24.04-amd64",
|
||||
"runs-on": "ubuntu-latest",
|
||||
"extra-dep-args": "--meson-no-system libportal --meson-static libportal --subprojects",
|
||||
"extra-cmake-args": "-DSYSTEM_LIBPORTAL=OFF -DSTATIC_LIBPORTAL=ON"
|
||||
},
|
||||
{
|
||||
"name": "ubuntu-22.04-amd64",
|
||||
"container": "deskflow/deskflow:ubuntu-22.04-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "fedora-40-arm64",
|
||||
"container": "deskflow/deskflow:fedora-40-arm64",
|
||||
"runs-on": "ubuntu-24.04-4-core-arm64"
|
||||
},
|
||||
{
|
||||
"name": "fedora-40-amd64",
|
||||
"container": "deskflow/deskflow:fedora-40-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "fedora-39-amd64",
|
||||
"container": "deskflow/deskflow:fedora-39-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "opensuse-amd64",
|
||||
"container": "deskflow/deskflow:opensuse-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "rockylinux-9-amd64",
|
||||
"container": "deskflow/deskflow:rockylinux-9-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "almalinux-9-amd64",
|
||||
"container": "deskflow/deskflow:almalinux-9-amd64",
|
||||
"runs-on": "ubuntu-latest"
|
||||
},
|
||||
{
|
||||
"name": "archlinux-amd64",
|
||||
"container": "deskflow/deskflow:archlinux-amd64",
|
||||
"runs-on": "ubuntu-latest",
|
||||
"package-user": "build"
|
||||
},
|
||||
{
|
||||
"name": "manjaro-amd64",
|
||||
"container": "deskflow/deskflow:manjaro-amd64",
|
||||
"runs-on": "ubuntu-latest",
|
||||
"package-user": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
447
.github/workflows/ci.yml
vendored
@ -5,28 +5,36 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: Deskflow version number
|
||||
push:
|
||||
branches: [master]
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
schedule:
|
||||
- cron: "0 5 * * *" # 5am UTC
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.editorconfig'
|
||||
- '.env-example'
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- 'cspell.json'
|
||||
|
||||
env:
|
||||
GIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
PACKAGE_PREFIX: "deskflow"
|
||||
PACKAGE_PATH: ./dist
|
||||
CMAKE_CONFIGURE: "cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=ON"
|
||||
|
||||
jobs:
|
||||
# Always run this job, even if not on PR, since other jobs need it.
|
||||
pr-comment-flags:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
needs: lint-clang
|
||||
|
||||
outputs:
|
||||
no-sonar: ${{ steps.check.outputs.no-sonar }}
|
||||
@ -36,6 +44,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check PR comment for flags
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: check
|
||||
env:
|
||||
PR_BODY: ${{ github.event.pull_request.body }}
|
||||
@ -52,7 +61,7 @@ jobs:
|
||||
# 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]
|
||||
needs: [test-results, unix]
|
||||
|
||||
steps:
|
||||
- run: echo "✅ CI passed" > $GITHUB_STEP_SUMMARY
|
||||
@ -60,8 +69,8 @@ jobs:
|
||||
# Summary of test results, combined from test result artifacts.
|
||||
# Runs even if the tests fail to provide a summary of the failures.
|
||||
test-results:
|
||||
needs: [windows, macos, linux]
|
||||
if: always()
|
||||
needs: main-build
|
||||
if: always() && needs.main-build.result != 'skipped'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
@ -73,35 +82,35 @@ jobs:
|
||||
- name: Test summary
|
||||
uses: ./.github/actions/test-summary
|
||||
|
||||
lint-cmake:
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: ./.github/workflows/lint-cmake.yml
|
||||
|
||||
lint-clang:
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: ./.github/workflows/lint-clang.yml
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Linting Clang
|
||||
uses: ./.github/actions/lint-clang
|
||||
|
||||
analyse-valgrind:
|
||||
needs: lint-clang
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: ./.github/workflows/valgrind-analysis.yml
|
||||
|
||||
analyse-codeql:
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: ./.github/workflows/codeql-analysis.yml
|
||||
|
||||
analyse-sonarcloud:
|
||||
needs: pr-comment-flags
|
||||
if: ${{ github.event_name == 'pull_request' && needs.pr-comment-flags.outputs.no-sonar != 'true' }}
|
||||
if: ${{ needs.pr-comment-flags.outputs.no-sonar != 'true' }}
|
||||
uses: ./.github/workflows/sonarcloud-analysis.yml
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
||||
windows:
|
||||
main-build:
|
||||
needs: lint-clang
|
||||
name: ${{ matrix.target.name }}
|
||||
runs-on: ${{ matrix.target.runs-on }}
|
||||
container: ${{ matrix.target.container }}
|
||||
timeout-minutes: 20
|
||||
|
||||
timeout-minutes: ${{ matrix.target.timeout }}
|
||||
strategy:
|
||||
# Normally, we want to fail fast, but in this case we shouldn't since one target may
|
||||
# fail due to transient issues unrelated to the build.
|
||||
@ -109,136 +118,122 @@ jobs:
|
||||
|
||||
matrix:
|
||||
target:
|
||||
- name: windows-2022-x64
|
||||
runs-on: ${{ vars.CI_WINDOWS_RUNNER || 'windows-2022' }}
|
||||
- name: "windows-2022-x64"
|
||||
runs-on: "windows-2022"
|
||||
timeout: 120 #Windows can take while if it has to build vcpkg cache
|
||||
config-args: "-G Ninja"
|
||||
|
||||
- name: "macos-14-arm64"
|
||||
runs-on: "macos-14"
|
||||
timeout: 10
|
||||
arch: arm64
|
||||
config-args: "-DCMAKE_OSX_ARCHITECTURES=\"arm64\" -DMACOSX_DEPLOYMENT_TARGET=12"
|
||||
|
||||
- name: "macos-13-x64"
|
||||
runs-on: macos-13
|
||||
timeout: 20
|
||||
config-args: "-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" -DMACOSX_DEPLOYMENT_TARGET=12"
|
||||
|
||||
- name: "debian-13-amd64"
|
||||
runs-on: ubuntu-latest
|
||||
container: debian:trixie-slim
|
||||
like: "debian"
|
||||
timeout: 20
|
||||
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
|
||||
|
||||
- name: "fedora-41-amd64"
|
||||
runs-on: ubuntu-latest
|
||||
container: fedora:41
|
||||
like: "fedora"
|
||||
timeout: 20
|
||||
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
|
||||
|
||||
- name: "fedora-40-amd64"
|
||||
runs-on: ubuntu-latest
|
||||
container: fedora:40
|
||||
like: "fedora"
|
||||
timeout: 20
|
||||
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
|
||||
|
||||
- name: "opensuse-amd64"
|
||||
runs-on: ubuntu-latest
|
||||
container: opensuse/tumbleweed:latest
|
||||
like: "suse"
|
||||
timeout: 20
|
||||
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
|
||||
|
||||
- name: "archlinux-amd64"
|
||||
runs-on: ubuntu-latest
|
||||
container: archlinux:latest
|
||||
like: "arch"
|
||||
timeout: 20
|
||||
config-args: "-G Ninja -DCMAKE_INSTALL_PREFIX=/usr"
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
- 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.
|
||||
- name: Init Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: ci-${{ matrix.target.name }}
|
||||
setup: false
|
||||
|
||||
- name: Cache deps dir
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./deps
|
||||
key: ${{ runner.os }}-deps-${{ hashFiles('config.yaml') }}
|
||||
# Make sure the container has git before we do anything else
|
||||
- name: Install Git on Container
|
||||
if: ${{ matrix.target.container }}
|
||||
shell: bash
|
||||
run : |
|
||||
if [ "${{matrix.target.like}}" == "debian" ]; then
|
||||
apt update -qqq > /dev/null && apt install -qqq git devscripts > /dev/null
|
||||
elif [ "${{matrix.target.like}}" == "fedora" ]; then
|
||||
dnf install -y git
|
||||
elif [ "${{matrix.target.like}}" == "suse" ]; then
|
||||
zypper refresh
|
||||
zypper install -y --force-resolution git
|
||||
elif [ "${{matrix.target.like}}" == "arch" ]; then
|
||||
pacman -Syu --noconfirm git
|
||||
else
|
||||
echo "Unknown: ${{matrix.target.like}}"
|
||||
fi
|
||||
# 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
|
||||
|
||||
# This effectively runs `vcvarsall.bat`, etc. It's not actually installing
|
||||
# VC++ as that's already pre-installed on the Windows runner.
|
||||
- name: Setup VC++ environment
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
# 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
|
||||
# downloads directly from the `ninja-build` GitHub project releases.
|
||||
- name: Install Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@master
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
VCPKG_ROOT: "" # Unset deliberately to suppress 'already installed' warning.
|
||||
run: python ./scripts/install_deps.py
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build --preset=windows-release
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build -j8
|
||||
|
||||
- name: Tests
|
||||
uses: ./.github/actions/run-tests
|
||||
timeout-minutes: 2
|
||||
id: get-deps
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
job: ${{ matrix.target.name }}
|
||||
mac-qt-version: 6.7.2
|
||||
like: ${{ matrix.target.like }}
|
||||
|
||||
- name: Package
|
||||
run: python ./scripts/package.py
|
||||
env:
|
||||
WINDOWS_PFX_CERTIFICATE: ${{ secrets.WINDOWS_PFX }}
|
||||
WINDOWS_PFX_PASSWORD: ${{ secrets.WINDOWS_PFX_PASS }}
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.target.name }}
|
||||
path: ${{ env.PACKAGE_PATH }}
|
||||
|
||||
macos:
|
||||
name: ${{ matrix.target.name }}
|
||||
runs-on: ${{ matrix.target.os }}
|
||||
timeout-minutes: ${{ matrix.target.timeout }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.target.shell }}
|
||||
|
||||
strategy:
|
||||
# Normally, we want to fail fast, but in this case we shouldn't since one target may
|
||||
# fail due to transient issues unrelated to the build.
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
target:
|
||||
- name: "macos-14-arm64"
|
||||
timeout: 10
|
||||
os: "macos-14"
|
||||
arch: arm64
|
||||
shell: "/usr/bin/arch -arch arm64e /bin/bash --noprofile --norc -eo pipefail {0}"
|
||||
|
||||
- name: ${{ vars.CI_MAC_INTEL_NAME || 'macos-13-x64' }}
|
||||
timeout: 20
|
||||
os: ${{ vars.CI_MAC_INTEL_RUNNER || 'macos-13' }}
|
||||
arch: x64
|
||||
shell: "bash"
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Python
|
||||
if: ${{runner.os != 'Linux' }}
|
||||
run: python ./scripts/setup_venv.py
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
# Should only restore the .venv directory from cache.
|
||||
- name: Setup Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: ci-${{ matrix.target.name }}
|
||||
setup: false
|
||||
|
||||
- name: Cache deps dir
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ./deps
|
||||
key: ${{ runner.os }}-deps-${{ hashFiles('config.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: ./scripts/install_deps.py
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build --preset=macos-release
|
||||
run: ${{env.CMAKE_CONFIGURE}} ${{ matrix.target.config-args }} ${{ steps.get-deps.outputs.vcpkg-cmake-config }} -DPACKAGE_VERSION_LABEL=${{env.DESKFLOW_PACKAGE_VERSION}}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build -j8
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "$RUNNER_OS" == "Linux" && "${{matrix.target.like}}" != "arch" ]]; then
|
||||
cmake --build build -j8 --target package
|
||||
else
|
||||
cmake --build build -j8
|
||||
fi
|
||||
|
||||
if [ ${{ matrix.target.like }} == "arch" ];then
|
||||
useradd -m build
|
||||
sudo chown -R build build
|
||||
cd build
|
||||
sudo -u build makepkg -s
|
||||
export OSNAME=$(cat /etc/os-release | grep ^ID= | sed 's/ID=//g')
|
||||
export ARCH=$(uname -m)
|
||||
mv *.pkg.tar.zst deskflow-${{env.DESKFLOW_PACKAGE_VERSION}}-${OSNAME}-${ARCH}.pkg.tar.zst
|
||||
cd ..
|
||||
fi
|
||||
|
||||
- name: Tests
|
||||
uses: ./.github/actions/run-tests
|
||||
@ -246,9 +241,16 @@ jobs:
|
||||
with:
|
||||
job: ${{ matrix.target.name }}
|
||||
|
||||
|
||||
- name: Package
|
||||
run: ./scripts/package.py
|
||||
if: ${{ runner.os != 'Linux' }}
|
||||
shell: bash
|
||||
run: |
|
||||
python ./scripts/package.py --package-version ${{env.DESKFLOW_PACKAGE_VERSION}}
|
||||
mv dist/deskflow* build/
|
||||
env:
|
||||
WINDOWS_PFX_CERTIFICATE: ${{ secrets.WINDOWS_PFX }}
|
||||
WINDOWS_PFX_PASSWORD: ${{ secrets.WINDOWS_PFX_PASS }}
|
||||
APPLE_CODESIGN_ID: ${{ secrets.APPLE_CODESIGN_ID }}
|
||||
APPLE_P12_CERTIFICATE: ${{ secrets.APPLE_P12_CERTIFICATE }}
|
||||
APPLE_P12_PASSWORD: ${{ secrets.APPLE_P12_PASSWORD }}
|
||||
@ -259,102 +261,16 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.target.name }}
|
||||
path: ${{ env.PACKAGE_PATH }}
|
||||
|
||||
linux-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
json-matrix: ${{ steps.filter.outputs.json }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Filter JSON
|
||||
uses: ./.github/actions/filter-json
|
||||
id: filter
|
||||
with:
|
||||
json-file: .github/workflows/ci-linux.json
|
||||
condition: '"${{ vars.CI_USE_LINUX_ARM_RUNNER }}" != "true"'
|
||||
jq-filter: .distro |= map(select(.["runs-on"] | contains("arm64") | not))
|
||||
|
||||
linux:
|
||||
needs: linux-matrix
|
||||
name: linux-${{ matrix.distro.name }}
|
||||
runs-on: ${{ matrix.distro.runs-on }}
|
||||
container: ${{ matrix.distro.container }}
|
||||
timeout-minutes: 20
|
||||
|
||||
strategy:
|
||||
# Normally, we want to fail fast, but in this case we shouldn't since one distro may
|
||||
# fail due to transient issues unrelated to the build.
|
||||
fail-fast: false
|
||||
matrix: ${{fromJson(needs.linux-matrix.outputs.json-matrix)}}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Should only restore the .venv directory from cache.
|
||||
- name: Setup Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: ci-${{ matrix.distro.name }}
|
||||
setup: false
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
- name: Config Git safe dir
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
- name: Install dependencies
|
||||
run: ./scripts/install_deps.py ${{ matrix.distro.extra-dep-args }}
|
||||
env:
|
||||
# Prevent apt prompting for input.
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build --preset=linux-release ${{ matrix.distro.extra-cmake-args }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build -j8
|
||||
|
||||
- name: Tests
|
||||
uses: ./.github/actions/run-tests
|
||||
timeout-minutes: 2
|
||||
with:
|
||||
job: linux-${{ matrix.distro.name }}
|
||||
|
||||
- name: Package
|
||||
env:
|
||||
LINUX_EXTRA_PACKAGES: ${{ matrix.distro.extra-packages }}
|
||||
LINUX_PACKAGE_USER: ${{ matrix.distro.package-user }}
|
||||
run: ./scripts/package.py
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.PACKAGE_PREFIX }}-${{ matrix.distro.name }}
|
||||
path: ${{ env.PACKAGE_PATH }}
|
||||
name: package-${{ env.PACKAGE_PREFIX }}-${{ matrix.target.name }}
|
||||
path: ${{github.workspace}}/build/deskflow[-_]*.*
|
||||
|
||||
# Technically, "unix" is a misnomer, but we use it here to mean "Unix-like BSD-derived".
|
||||
unix:
|
||||
needs: lint-clang
|
||||
name: unix-${{ matrix.distro.name }}
|
||||
runs-on: ${{ vars.CI_UNIX_RUNNER || 'ubuntu-24.04' }}
|
||||
timeout-minutes: 20
|
||||
|
||||
env:
|
||||
DESKFLOW_BUILD_CMD: |
|
||||
./scripts/install_deps.sh;
|
||||
cmake -B build;
|
||||
cmake --build build -j16;
|
||||
export QT_QPA_PLATFORM=offscreen;
|
||||
./build/bin/unittests
|
||||
./build/bin/integtests
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
@ -363,12 +279,85 @@ jobs:
|
||||
- name: freebsd
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
# 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
|
||||
|
||||
- name: Build on FreeBSD
|
||||
if: ${{ matrix.distro.name == 'freebsd' }}
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
run: ${{ env.DESKFLOW_BUILD_CMD }}
|
||||
run: |
|
||||
./scripts/install_deps.sh
|
||||
${{env.CMAKE_CONFIGURE}} -G Ninja
|
||||
cmake --build build -j16
|
||||
|
||||
# Integration tests are flakey by nature, make them optional.
|
||||
export QT_QPA_PLATFORM=offscreen
|
||||
./build/bin/unittests
|
||||
./build/bin/integtests || true
|
||||
|
||||
release:
|
||||
needs: ci-passed
|
||||
if: (github.ref == 'refs/heads/master') || (contains(github.ref, '/tags/v'))
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Generate package checksums
|
||||
id: generate_notes
|
||||
shell: bash
|
||||
run: |
|
||||
mv $GITHUB_WORKSPACE/package-*/deskflow-* .
|
||||
rm -rf $GITHUB_WORKSPACE/package-*
|
||||
echo "Build: ${{env.DESKFLOW_VERSION }}" > sums.txt
|
||||
sha256sum deskflow-* >> sums.txt
|
||||
|
||||
- name: Deploy continuous
|
||||
if: (github.ref == 'refs/heads/master') && !(contains(github.ref, '/tags/v'))
|
||||
uses: crowbarmaster/GH-Automatic-Releases@latest
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
automatic_release_tag: "continuous"
|
||||
prerelease: true
|
||||
title: 'Continuous Build'
|
||||
files: |
|
||||
deskflow-*
|
||||
sums.txt
|
||||
|
||||
- name: Deploy release
|
||||
if: contains(github.ref, '/tags/v')
|
||||
uses: crowbarmaster/GH-Automatic-Releases@latest
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
prerelease: false
|
||||
files: |
|
||||
deskflow-*
|
||||
sums.txt
|
||||
|
||||
winget-publish:
|
||||
needs: release
|
||||
if: contains(github.ref, 'tags/v')
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
|
||||
- name: Get version
|
||||
uses: ./.github/actions/get-version
|
||||
|
||||
- name: Submit
|
||||
uses: ./.github/actions/winget-publish
|
||||
with:
|
||||
release-version: ${{env.DESKFLOW_PACKAGE_VERSION}}
|
||||
token: ${{ secrets.WINGET_DEPLOY_TOKEN }}
|
||||
|
||||
47
.github/workflows/codeql-analysis.yml
vendored
@ -1,8 +1,25 @@
|
||||
name: "CodeQL Analysis"
|
||||
|
||||
# According to the docs, the CodeQL workflow should be triggered directly by push to master
|
||||
# and by pull requests (we only run this on open PRs as it's very slow). We also use the
|
||||
# `workflow_dispatch` event is also enabled to allow manual triggering of the workflow for testing.
|
||||
#
|
||||
# We should not trigger this workflow with `workflow_call` as this causes the error:
|
||||
# "1 configuration present on `master` was not found"
|
||||
#
|
||||
# Sadly, this means we can't roll it into our monolithic CI workflow.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.editorconfig'
|
||||
- '.env-example'
|
||||
- '.gitignore'
|
||||
- '.gitattributes'
|
||||
- 'cspell.json'
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
@ -11,8 +28,8 @@ jobs:
|
||||
if: ${{ !github.event.pull_request.draft }}
|
||||
|
||||
name: Analyze
|
||||
runs-on: ${{ vars.CODEQL_RUNNER || 'ubuntu-24.04' }}
|
||||
container: deskflow/deskflow:ubuntu-24.04-amd64
|
||||
runs-on: ubuntu-latest
|
||||
container: debian:trixie-slim
|
||||
timeout-minutes: 20
|
||||
|
||||
strategy:
|
||||
@ -21,24 +38,18 @@ jobs:
|
||||
language: ["cpp"]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install container dependencies
|
||||
run: |
|
||||
apt update -qqq > /dev/null
|
||||
apt install -qqq git > /dev/null
|
||||
|
||||
- name: Config Git safe dir
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
# Should only restore the .venv directory from cache.
|
||||
- name: Init Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: "codeql"
|
||||
setup: false
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: ./scripts/install_deps.py
|
||||
env:
|
||||
# Prevent apt prompting for input.
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
like: "debian"
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
|
||||
53
.github/workflows/create-tag.yml
vendored
@ -1,53 +0,0 @@
|
||||
name: Create tag
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release/**
|
||||
|
||||
jobs:
|
||||
create-tag:
|
||||
if: ${{ vars.CREATE_TAGS }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Fetch all tags
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Read version file
|
||||
run: echo "CURRENT_VERSION=$(cat VERSION)" >> $GITHUB_ENV
|
||||
|
||||
- name: Override stage
|
||||
if: ${{ !startsWith(github.ref, 'refs/heads/release') }}
|
||||
run: echo "OVERRIDE_STAGE=snapshot" >> $GITHUB_ENV
|
||||
|
||||
- name: Get next version
|
||||
id: next-version
|
||||
uses: symless/actions/next-version@master
|
||||
with:
|
||||
current-version: ${{ env.CURRENT_VERSION }}
|
||||
override-stage: ${{ env.OVERRIDE_STAGE }}
|
||||
|
||||
- name: Create and push Git tag
|
||||
run: |
|
||||
git tag ${{ steps.next-version.outputs.next-version }}
|
||||
git push origin ${{ steps.next-version.outputs.next-version }}
|
||||
shell: bash
|
||||
|
||||
- name: Trigger CI workflow
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: 'ci.yml',
|
||||
ref: '${{ steps.next-version.outputs.next-version }}'
|
||||
});
|
||||
31
.github/workflows/lint-clang.yml
vendored
@ -1,31 +0,0 @@
|
||||
name: "Lint Clang"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
lint-clang:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: "lint-clang"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
pip install pyyaml clang_format
|
||||
|
||||
- name: Linting with Clang format
|
||||
id: lint-clang
|
||||
uses: ./.github/actions/lint-error
|
||||
with:
|
||||
format-command: ./scripts/lint_clang.py -f
|
||||
format-tool: "clang-format"
|
||||
31
.github/workflows/lint-cmake.yml
vendored
@ -1,31 +0,0 @@
|
||||
name: "Lint CMake"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
lint-cmake:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: "lint-cmake"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
pip install pyyaml cmake_format
|
||||
|
||||
- name: Linting with CMake formatter
|
||||
id: lint-cmake
|
||||
uses: ./.github/actions/lint-error
|
||||
with:
|
||||
format-command: ./scripts/lint_cmake.py -f
|
||||
format-tool: "cmake-format"
|
||||
47
.github/workflows/sonarcloud-analysis.yml
vendored
@ -6,15 +6,13 @@ on:
|
||||
secrets:
|
||||
SONAR_TOKEN:
|
||||
required: true
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
sonarcloud-analysis:
|
||||
if: ${{ vars.SONAR_SCANNER_ENABLED }}
|
||||
|
||||
runs-on: ${{ vars.SONAR_SCANNER_RUNNER || 'ubuntu-24.04' }}
|
||||
container: deskflow/deskflow:ubuntu-22.04-amd64
|
||||
runs-on: ubuntu-latest
|
||||
container: debian:trixie-slim
|
||||
timeout-minutes: 20
|
||||
|
||||
env:
|
||||
@ -24,36 +22,29 @@ jobs:
|
||||
CPU_CORE_COUNT: ${{ vars.SONAR_SCANNER_CPU_COUNT || 4 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# Fetch all history for SonarScanner blame data
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Config Git safe dir
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
# Should only restore the .venv directory from cache.
|
||||
- name: Init Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: "sonarcloud"
|
||||
setup: false
|
||||
|
||||
- name: Install dependencies
|
||||
- name: Install container dependencies
|
||||
run: |
|
||||
./scripts/install_deps.py &&
|
||||
apt install curl unzip -y &&
|
||||
pip install gcovr
|
||||
env:
|
||||
# Prevent apt prompting for input.
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
apt update -qqq > /dev/null
|
||||
apt install -qqq git curl unzip gcovr > /dev/null
|
||||
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
|
||||
- name: Install project dependencies
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
like: "debian"
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: sonarsource/sonarcloud-github-c-cpp@v3
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build --preset=linux-debug -DENABLE_COVERAGE=ON
|
||||
run: |
|
||||
cmake -B build \
|
||||
-G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE="Debug" \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DENABLE_COVERAGE=ON
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
41
.github/workflows/test-actions.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
name: Test actions
|
||||
|
||||
# Intended to only be run manually for testing actions in isolation.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-summary:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test summary (${{ matrix.message.name }})
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
message:
|
||||
- name: success
|
||||
text: "|Success|✅|✅|"
|
||||
expect: ""
|
||||
- name: failure
|
||||
text: "|Failure|❌|❌|"
|
||||
expect: "❌🔬 Tests failed: 2"
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Generate
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ matrix.message.text }}" > test-result.md
|
||||
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: test-result.md
|
||||
name: test-result-${{ matrix.message.name }}
|
||||
|
||||
- name: Test
|
||||
uses: ./.github/actions/test-summary
|
||||
with:
|
||||
download-pattern: test-result-${{ matrix.message.name }}
|
||||
upload-name: summary-${{ matrix.message.name }}
|
||||
38
.github/workflows/test-dist-upload.yml
vendored
@ -1,38 +0,0 @@
|
||||
# Used only for testing the `dist-upload` action.
|
||||
# Triggered using 'Run workflow' in the Actions tab.
|
||||
|
||||
name: Test dist upload
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Make test dist
|
||||
run: |
|
||||
mkdir dist
|
||||
echo "test" > dist/test
|
||||
|
||||
- name: Upload to GitHub
|
||||
if:
|
||||
uses: ./.github/actions/dist-upload
|
||||
with:
|
||||
use-github: true
|
||||
github-target-filename: "test"
|
||||
|
||||
- name: Upload to Google Drive
|
||||
if:
|
||||
uses: ./.github/actions/dist-upload
|
||||
with:
|
||||
use_gdrive: true
|
||||
gdrive-target-base-dir: "test"
|
||||
gdrive-secret-key: ${{ secrets.GOOGLE_DRIVE_KEY }}
|
||||
gdrive-parent-folder-id: ${{ secrets.GOOGLE_DRIVE_TECH_DRIVE }}
|
||||
package-version: 1.0.0-test
|
||||
30
.github/workflows/valgrind-analysis.yml
vendored
@ -7,33 +7,25 @@ on:
|
||||
jobs:
|
||||
valgrind-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
container: deskflow/deskflow:ubuntu-22.04-amd64
|
||||
container: debian:trixie-slim
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install container dependencies
|
||||
run: |
|
||||
apt update -qqq > /dev/null
|
||||
apt install -qqq git valgrind > /dev/null
|
||||
|
||||
- name: Config Git safe dir
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
|
||||
# Should only restore the .venv directory from cache.
|
||||
- name: Init Python venv
|
||||
uses: ./.github/actions/init-python
|
||||
with:
|
||||
cache-key: "valgrind"
|
||||
setup: false
|
||||
- name: Fancy Checkout
|
||||
uses: sithlord48/fancy-checkout@v1.0.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
./scripts/install_deps.py &&
|
||||
apt install valgrind -y
|
||||
env:
|
||||
# Prevent apt prompting for input.
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
like: "debian"
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B build --preset=linux-release
|
||||
run: cmake -B build -G "Ninja"
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build -j8
|
||||
|
||||
14
.gitignore
vendored
@ -1,3 +1,8 @@
|
||||
# SPDX-FileCopyrightText: Copyright (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: Copyright (C) 2011 Symless Ltd.
|
||||
# SPDX-FileCopyrightText: Copyright (C) 2010 Jason Axelson <BostonVaulter@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# temp dirs created during build
|
||||
/build
|
||||
/dist
|
||||
@ -20,3 +25,12 @@ deskflow-config.toml
|
||||
/scripts/*.egg-info
|
||||
/*.user
|
||||
*.ui.autosave
|
||||
|
||||
#Generic linux files
|
||||
**/*.directory
|
||||
|
||||
#CMake ignores
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeUserPresets.json
|
||||
CMakeFiles/*
|
||||
|
||||
16
.vscode/launch.json
vendored
@ -15,6 +15,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/unittests",
|
||||
"args": [ "${input:gtest-args}" ],
|
||||
"preLaunchTask": "build"
|
||||
},
|
||||
{
|
||||
@ -23,14 +24,15 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/integtests",
|
||||
"preLaunchTask": "build"
|
||||
"args": [ "${input:gtest-args}" ],
|
||||
"preLaunchTask": "build",
|
||||
},
|
||||
{
|
||||
"name": "unix - server",
|
||||
"type": "lldb",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/deskflows",
|
||||
"program": "${workspaceFolder}/build/bin/deskflow-server",
|
||||
"args": ["--config-toml", "deskflow-config.toml"],
|
||||
"preLaunchTask": "kill-build"
|
||||
},
|
||||
@ -64,6 +66,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/unittests",
|
||||
"args": [ "${input:gtest-args}" ],
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"preLaunchTask": "build"
|
||||
},
|
||||
@ -73,6 +76,7 @@
|
||||
"cwd": "${workspaceRoot}",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/integtests",
|
||||
"args": [ "${input:gtest-args}" ],
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"preLaunchTask": "build"
|
||||
},
|
||||
@ -119,5 +123,13 @@
|
||||
"program": "scripts/install_deps.py",
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "gtest-args",
|
||||
"type": "promptString",
|
||||
"description": "Test arguments",
|
||||
"default": "--gtest_filter=*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
3
.vscode/tasks.json
vendored
@ -14,9 +14,6 @@
|
||||
"problemMatcher": {
|
||||
"base": "$gcc",
|
||||
"fileLocation": ["absolute"]
|
||||
},
|
||||
"presentation": {
|
||||
"revealProblems": "onProblem"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
50
BUILD.md
@ -1,50 +0,0 @@
|
||||
# Build Deskflow
|
||||
|
||||
## Developer Quick Start
|
||||
|
||||
Deskflow is free and open source software, and anyone is welcome to build it,
|
||||
run it, tinker with it, redistribute it as part of their own app, etc.
|
||||
|
||||
These instructions will build Deskflow, which doesn't require a license
|
||||
or serial key. Check the [Build Guide](https://github.com/deskflow/deskflow/wiki/Build-Guide)
|
||||
wiki page if you have problems.
|
||||
|
||||
**1. Dependencies:**
|
||||
|
||||
*Linux, macOS, or BSD-derived:*
|
||||
```
|
||||
./scripts/install_deps.sh
|
||||
```
|
||||
|
||||
*Windows:*
|
||||
```
|
||||
python scripts/install_deps.py
|
||||
```
|
||||
|
||||
**2. Configure:**
|
||||
|
||||
*Linux, macOS, or BSD-derived:*
|
||||
```
|
||||
cmake -B build
|
||||
```
|
||||
|
||||
*Windows:*
|
||||
```
|
||||
cmake -B build --preset=windows-release
|
||||
```
|
||||
|
||||
**3. Build:**
|
||||
```
|
||||
cmake --build build -j8
|
||||
```
|
||||
|
||||
**4. Test:**
|
||||
```
|
||||
./build/bin/unittests
|
||||
./build/bin/integtests
|
||||
```
|
||||
|
||||
**5. Run**
|
||||
```
|
||||
./build/bin/deskflow
|
||||
```
|
||||
7
Brewfile
@ -1,7 +0,0 @@
|
||||
brew 'make'
|
||||
brew 'cmake'
|
||||
brew 'openssl'
|
||||
brew 'ninja'
|
||||
brew 'googletest'
|
||||
brew 'tomlplusplus'
|
||||
brew 'cli11'
|
||||
@ -19,22 +19,75 @@
|
||||
# > New in version 3.8: If the SOURCE_DATE_EPOCH environment variable is set,
|
||||
# > its value will be used instead of the current time.
|
||||
# > See https://reproducible-builds.org/specs/source-date-epoch/ for details.
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
project(deskflow C CXX)
|
||||
# Fallback for when git can not be found
|
||||
set(DESKFLOW_VERSION_MAJOR 1)
|
||||
set(DESKFLOW_VERSION_MINOR 17)
|
||||
set(DESKFLOW_VERSION_PATCH 1)
|
||||
set(DESKFLOW_VERSION_TWEAK 0)
|
||||
|
||||
# Get the version from git if it's a git repository
|
||||
# cmake-format: off
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --long --match v* --always
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GITREV
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(FIND ${GITREV} "v" isRev)
|
||||
if(NOT ifRev EQUAL -1)
|
||||
string(REGEX MATCH [0-9]+ MAJOR ${GITREV})
|
||||
string(REGEX MATCH \\.[0-9]+ MINOR ${GITREV})
|
||||
string(REPLACE "." "" MINOR "${MINOR}")
|
||||
string(REGEX MATCH [0-9]+\- PATCH ${GITREV})
|
||||
string(REPLACE "-" "" PATCH "${PATCH}")
|
||||
string(REGEX MATCH \-[0-9]+\- TWEAK ${GITREV})
|
||||
string(REPLACE "-" "" TWEAK "${TWEAK}")
|
||||
set(DESKFLOW_VERSION_MAJOR ${MAJOR})
|
||||
set(DESKFLOW_VERSION_MINOR ${MINOR})
|
||||
set(DESKFLOW_VERSION_PATCH ${PATCH})
|
||||
set(DESKFLOW_VERSION_TWEAK ${TWEAK})
|
||||
elseif(NOT ${GITREV} STREQUAL "")
|
||||
set(DESKFLOW_VERSION_TWEAK ${GITREV})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
# cmake-format: on
|
||||
|
||||
set(DESKFLOW_VERSION
|
||||
"${DESKFLOW_VERSION_MAJOR}.${DESKFLOW_VERSION_MINOR}.${DESKFLOW_VERSION_PATCH}.${DESKFLOW_VERSION_TWEAK}"
|
||||
)
|
||||
set(DESKFLOW_VERSION_MS_CSV
|
||||
"${DESKFLOW_VERSION_MAJOR},${DESKFLOW_VERSION_MINOR},${DESKFLOW_VERSION_PATCH},${DESKFLOW_VERSION_TWEAK}"
|
||||
)
|
||||
|
||||
add_definitions(-DDESKFLOW_VERSION="${DESKFLOW_VERSION}")
|
||||
|
||||
#Define our project
|
||||
project(
|
||||
deskflow
|
||||
VERSION ${DESKFLOW_VERSION}
|
||||
DESCRIPTION "Mouse and keyboard sharing utility"
|
||||
LANGUAGES C CXX)
|
||||
|
||||
message(STATUS "Building ${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}")
|
||||
|
||||
include(cmake/Version.cmake)
|
||||
include(cmake/Definitions.cmake)
|
||||
include(cmake/Build.cmake)
|
||||
include(cmake/Libraries.cmake)
|
||||
include(cmake/Packaging.cmake)
|
||||
|
||||
set_version()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
configure_definitions()
|
||||
configure_build()
|
||||
configure_libs()
|
||||
configure_packaging()
|
||||
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(src)
|
||||
|
||||
post_config_all()
|
||||
|
||||
@ -1,134 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "base",
|
||||
"hidden": true,
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minimal",
|
||||
"hidden": true,
|
||||
"environment": {
|
||||
"DESKFLOW_BUILD_MINIMAL": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows",
|
||||
"inherits": "base",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe"
|
||||
},
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"toolset": {
|
||||
"value": "host=x64",
|
||||
"strategy": "external"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux",
|
||||
"hidden": true,
|
||||
"inherits": "base",
|
||||
"generator": "Unix Makefiles"
|
||||
},
|
||||
{
|
||||
"name": "macos",
|
||||
"hidden": true,
|
||||
"inherits": "base",
|
||||
"generator": "Unix Makefiles"
|
||||
},
|
||||
{
|
||||
"name": "windows-debug",
|
||||
"inherits": "windows",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-release",
|
||||
"inherits": "windows",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-debug",
|
||||
"inherits": "linux",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-release",
|
||||
"inherits": "linux",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-debug",
|
||||
"inherits": "macos",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-release",
|
||||
"inherits": "macos",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-debug-min",
|
||||
"inherits": ["windows", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-release-min",
|
||||
"inherits": ["windows", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-debug-min",
|
||||
"inherits": ["linux", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-release-min",
|
||||
"inherits": ["linux", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-debug-min",
|
||||
"inherits": ["macos", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-release-min",
|
||||
"inherits": ["macos", "minimal"],
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
# Contributing to Deskflow
|
||||
|
||||
Hello future community member!
|
||||
|
||||
Deskflow is free and open source software, and anyone is welcome to build it,
|
||||
run it, tinker with it, redistribute it as part of their own app, etc.
|
||||
|
||||
See our wiki page on [contributing](https://github.com/deskflow/deskflow/wiki/Contributing) for more
|
||||
information. We look forward to reviewing your PR!
|
||||
|
||||
Thanks,
|
||||
The Deskflow community
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- install with: choco install Chocolatey.config -y -->
|
||||
<packages>
|
||||
<package id="wixtoolset" />
|
||||
<package id="visualstudio2022buildtools"
|
||||
packageParameters="--includeRecommended --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Workload.VCTools " />
|
||||
</packages>
|
||||
225
README.md
@ -1,59 +1,55 @@
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> We're on Libera Chat IRC network (`#deskflow` or `#deskflow-dev`).
|
||||
>
|
||||
> Or if you want to stay on GitHub, you can [start a new discussion](https://github.com/deskflow/deskflow/discussions).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 🚀 Deskflow is now the upstream project for Synergy.
|
||||
> [!NOTE]
|
||||
> **Deskflow** is the official upstream project for [Synergy](https://symless.com/synergy).
|
||||
> Purchasing a Synergy license is one way to support Deskflow’s growth and sustainability.
|
||||
>
|
||||
> The project has been renamed to draw a line between the community-run project (now Deskflow),
|
||||
> and the commercially licensed product, Synergy.
|
||||
> The Deskflow project was established to cultivate community-driven development where everyone can collaborate.
|
||||
> Synergy sponsors the Deskflow project by contributing code and providing financial support.
|
||||
>
|
||||
> We are currently in the process of renaming the project to Deskflow and moving all licensing code
|
||||
> downstream.
|
||||
>
|
||||
> Hold on to your butts, this is going to be a hell of a ride.
|
||||
>
|
||||
> [Join the discussion](https://github.com/deskflow/deskflow/discussions/7517)
|
||||
|
||||
[](https://github.com/deskflow/deskflow/wiki/Relationship-with-Synergy)
|
||||
|
||||
[](https://github.com/deskflow/deskflow/releases)
|
||||
[](https://github.com/deskflow/deskflow/commits/master/)
|
||||

|
||||
[](LICENSE)
|
||||
[](https://sonarcloud.io/summary/new_code?id=deskflow_deskflow)
|
||||
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/ci.yml)
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/codeql-analysis.yml)
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/sonarcloud-analysis.yml)
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/build-containers.yml)
|
||||
> More info: [Relationship with Synergy](https://github.com/deskflow/deskflow/wiki/Relationship-with-Synergy)
|
||||
|
||||
**Deskflow** is a free and open source keyboard and mouse sharing app.
|
||||
Use the keyboard, mouse, or trackpad of one computer to control nearby computers,
|
||||
and work seamlessly between them.
|
||||
It's like a software KVM (but without the video).
|
||||
TLS encryption is enabled by default. Wayland is supported. Clipboard sharing is supported.
|
||||
|
||||
**Wayland support:** Experimental support in
|
||||
[Deskflow v1.16](https://github.com/deskflow/deskflow/releases/tag/1.16.0-beta%2Br2)
|
||||
(required >= GNOME 46 or KDE Plasma 6.1).
|
||||
[](https://github.com/deskflow/deskflow/releases/tag/v1.17.0) [](https://github.com/deskflow/deskflow/releases)
|
||||
|
||||

|
||||
To use Deskflow you can use one of our [packages](https://github.com/deskflow/deskflow/releases), install `deskflow` (if available in your package repository), or [build it](#build-quick-start) yourself from source.
|
||||
|
||||
To use Deskflow you can follow the [Build Quick Start](#build-quick-start),
|
||||
use one of our packages, or if it's available by your favorite package repository,
|
||||
install `deskflow` (see: [installing packages](#how-to-install-packages)).
|
||||
> [!TIP]
|
||||
> For macOS users, the easiest way to install and stay up to date is to use [Homebrew](https://brew.sh) with our [homebrew-tap](https://github.com/deskflow/homebrew-tap).
|
||||
|
||||
## Project values
|
||||
[](https://github.com/deskflow/deskflow/commits/master/)
|
||||
[](https://github.com/deskflow/deskflow/commits/master/)
|
||||
[](LICENSE)
|
||||
|
||||
[](https://sonarcloud.io/summary/new_code?id=deskflow_deskflow)
|
||||
[](https://sonarcloud.io/summary/new_code?id=deskflow_deskflow)
|
||||
[](https://sonarcloud.io/summary/new_code?id=deskflow_deskflow)
|
||||
[](https://sonarcloud.io/summary/new_code?id=deskflow_deskflow)
|
||||
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/ci.yml)
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/codeql-analysis.yml)
|
||||
[](https://github.com/deskflow/deskflow/actions/workflows/sonarcloud-analysis.yml)
|
||||
|
||||
## Project Values
|
||||
|
||||
- Motivated by the community interests (not business-driven)
|
||||
- Privacy by default (no update check or phone home on by default)
|
||||
- Nothing customer-related (this is all moved downstream to Synergy)
|
||||
- Privacy by default (e.g. update check is off by default)
|
||||
- Leading edge releases (we don't focus on supporting older systems)
|
||||
- Decisions are discussed and documented publicly with majority rule
|
||||
- Have fun; we don't need to worry about impressing anyone
|
||||
|
||||
## Ways to get involved
|
||||
|
||||
> [!TIP]
|
||||
> Join us! Real-time discussion on Matrix: [`#deskflow:matrix.org`](https://matrix.to/#/#deskflow:matrix.org)
|
||||
>
|
||||
> Alternatively, we have [other ways](https://github.com/deskflow/deskflow/wiki/Chat-with-us) to communicate.
|
||||
>
|
||||
Here are a few ways to join in with the project and get involved:
|
||||
* Build the latest `master` version (see below) and [report a bug](https://github.com/deskflow/deskflow/issues)
|
||||
* [Submit a PR](https://github.com/deskflow/deskflow/wiki/Contributing) (pull request) with a bug fix or improvement
|
||||
@ -61,85 +57,7 @@ Here are a few ways to join in with the project and get involved:
|
||||
|
||||
## Build Quick Start
|
||||
|
||||
> [!TIP]
|
||||
> Check the [Build Guide](https://github.com/deskflow/deskflow/wiki/Build-Guide)
|
||||
> wiki page if you have problems.
|
||||
|
||||
**1. Dependencies:**
|
||||
|
||||
You can either copy/paste the commands for your OS from [`config.yaml`](config.yaml) or use the deps script.
|
||||
|
||||
*Linux, macOS, or BSD-derived:*
|
||||
```
|
||||
./scripts/install_deps.sh
|
||||
```
|
||||
|
||||
*Windows:*
|
||||
```
|
||||
python scripts/install_deps.py
|
||||
```
|
||||
|
||||
**2. Configure:**
|
||||
|
||||
*Linux, macOS, or BSD-derived:*
|
||||
```
|
||||
cmake -B build
|
||||
```
|
||||
|
||||
*Windows:*
|
||||
```
|
||||
cmake -B build --preset=windows-release
|
||||
```
|
||||
|
||||
**3. Build:**
|
||||
```
|
||||
cmake --build build -j8
|
||||
```
|
||||
|
||||
**4. Test:**
|
||||
```
|
||||
./build/bin/unittests
|
||||
./build/bin/integtests
|
||||
```
|
||||
|
||||
**5. Run**
|
||||
```
|
||||
./build/bin/deskflow
|
||||
```
|
||||
|
||||
## How to install (packages)
|
||||
|
||||
*macOS:*
|
||||
*(coming soon)*
|
||||
```
|
||||
brew install deskflow
|
||||
```
|
||||
|
||||
*Fedora, Red Hat, etc:*
|
||||
*(coming soon)*
|
||||
```
|
||||
sudo dnf install deskflow
|
||||
```
|
||||
|
||||
*Debian, Ubuntu, etc:*
|
||||
*(coming soon)*
|
||||
```
|
||||
sudo apt install deskflow
|
||||
```
|
||||
|
||||
*Arch, Manjaro, etc:*
|
||||
*(coming soon)*
|
||||
```
|
||||
sudo pacman -S deskflow
|
||||
```
|
||||
|
||||
*Windows:*
|
||||
*(coming soon)*
|
||||
```
|
||||
choco install deskflow
|
||||
```
|
||||
|
||||
**Note:** We are working with package maintainers to have our new package name adopted.
|
||||
For instructions on building Deskflow, use the wiki page: [Building](https://github.com/deskflow/deskflow/wiki/Building)
|
||||
|
||||
## Operating Systems
|
||||
|
||||
@ -150,9 +68,42 @@ Debian, Ubuntu, Linux Mint, Fedora, RHEL, AlmaLinux, Rocky Linux, Arch Linux, op
|
||||
|
||||
We officially support FreeBSD, and would also like to support: OpenBSD, NetBSD, DragonFly, Solaris.
|
||||
|
||||
## Repology
|
||||
|
||||
Repology monitors a huge number of package repositories and other sources comparing package
|
||||
versions across them and gathering other information.
|
||||
|
||||
[](https://repology.org/project/deskflow/versions)
|
||||
|
||||
**Note:** We are working with package maintainers to have our new package name adopted.
|
||||
|
||||
## Installing on macOS
|
||||
|
||||
When you install Deskflow on macOS, you need to allow accessibility access (Privacy & Security) to both the `Deskflow` app and the `deskflow` process.
|
||||
|
||||
If using Sequoia, you may also need to allow `Deskflow` under Local Network settings (Privacy & Security).
|
||||
When prompted by the OS, go to the settings and enable the access.
|
||||
|
||||
If you are upgrading and you already have `Deskflow` or `deskflow`
|
||||
on the allowed list you will need to manually remove them before accessibility access can be granted to the new version.
|
||||
|
||||
macOS users who download directly from releases may need to run `xattr -c /Applications/Deskflow.app` after copying the app to the `Applications` dir.
|
||||
|
||||
It is recommend to install Deskflow using [Homebrew](https://brew.sh) from our [homebrew-tap](https://github.com/deskflow/homebrew-tap)
|
||||
|
||||
To add our tap, run:
|
||||
```
|
||||
brew tap deskflow/homebrew-tap
|
||||
```
|
||||
Then install either:
|
||||
- Stable: `brew instal deskflow`
|
||||
- Continuous: `brew install deskflow-dev`
|
||||
|
||||
|
||||
|
||||
## Collaborative Projects
|
||||
|
||||
In the open source developer community, similar projects collaborate for the betterment of all
|
||||
In the open source developer community, similar projects collaborate for the improvement of all
|
||||
mouse and keyboard sharing tools. We aim for idea sharing and interoperability.
|
||||
|
||||
* [**Lan Mouse**](https://github.com/feschber/lan-mouse) -
|
||||
@ -162,16 +113,30 @@ mouse and keyboard sharing tools. We aim for idea sharing and interoperability.
|
||||
Deskflow/Synergy-derivative with the goal of continuing what Barrier started, after Barrier
|
||||
became a dead fork.
|
||||
* [**Synergy**](https://github.com/deskflow/deskflow/wiki/Relationship-with-Synergy) -
|
||||
Downstream commercial fork and Deskflow sponsor, geared toward adapting upstream to customer
|
||||
Downstream commercial fork and Deskflow sponsor, geared toward adapting to customer
|
||||
needs, offering business and enterprise licensing.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Is Deskflow compatible with Lan Mouse or Input Leap?
|
||||
### What is the relationship with Synergy?
|
||||
|
||||
We would love to see compatibility between our fellow open source projects, Lan Mouse and
|
||||
Input Leap. This idea is discussed from time in the communities for all of our projects,
|
||||
so it may happen in the not-too-distant future.
|
||||
[](https://github.com/deskflow/deskflow/wiki/Relationship-with-Synergy)
|
||||
|
||||
Synergy sponsors the Deskflow project by contributing code and providing financial support while maintaining its customer-oriented code downstream.
|
||||
|
||||
Learn more: [Relationship with Synergy](https://github.com/deskflow/deskflow/wiki/Relationship-with-Synergy)
|
||||
|
||||
### Is Deskflow compatible with Synergy, Input Leap, or Barrier?
|
||||
|
||||
Yes, Deskflow has network compatibility with all forks:
|
||||
- Requires Deskflow >= v1.17.0.96
|
||||
- Deskflow will *just work* with Input Leap and Barrier (server or client).
|
||||
- Connecting a Deskflow client to a Synergy server will also *just work*.
|
||||
- To connect a Synergy client, you need to select the Synergy protocol in the Deskflow server settings.
|
||||
|
||||
### Is Deskflow compatible with Lan Mouse?
|
||||
|
||||
We would love to see compatibility with Lan Mouse. This maybe quite an effort as currently they way they handle the generated input is very different.
|
||||
|
||||
### If I want to solve issues in Deskflow do I need to contribute to a fork?
|
||||
|
||||
@ -201,12 +166,18 @@ Deskflow was first created as Synergy in 2001 by Chris Schoeneman.
|
||||
Read about the [history of the project](https://github.com/deskflow/deskflow/wiki/History) on our
|
||||
wiki.
|
||||
|
||||
## Repology
|
||||
## Meow'Dib (our mascot)
|
||||
|
||||
Repology monitors a huge number of package repositories and other sources comparing package
|
||||
versions across them and gathering other information.
|
||||

|
||||
|
||||
[](https://repology.org/project/deskflow/versions)
|
||||
|
||||
## Deskflow Contributors
|
||||
|
||||
Deskflow is made by possible by these contributors.
|
||||
|
||||
<a href = "https://github.com/deskflow/deskflow/graphs/contributors">
|
||||
<img src = "https://contrib.rocks/image?repo=deskflow/deskflow"/>
|
||||
</a>
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
format:
|
||||
# Solves line ending issues on Windows.
|
||||
line_ending: "auto"
|
||||
|
||||
# Any more than 4 args, and function calls become hard to read.
|
||||
max_pargs_hwrap: 4
|
||||
|
||||
markup:
|
||||
# Disable formatting of comments entirely, as this is annoying.
|
||||
enable_markup: false
|
||||
@ -26,22 +26,11 @@ macro(configure_build)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
|
||||
endif()
|
||||
|
||||
warnings_as_errors()
|
||||
set_build_date()
|
||||
configure_file_shared()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(warnings_as_errors)
|
||||
if(WIN32)
|
||||
message(STATUS "Enabling warnings as errors (MSVC)")
|
||||
add_compile_options(/WX)
|
||||
elseif(UNIX)
|
||||
message(STATUS "Enabling warnings as errors (GNU/Clang)")
|
||||
add_compile_options(-Werror)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(set_build_date)
|
||||
# Since CMake 3.8.0, `string(TIMESTAMP ...)` respects `SOURCE_DATE_EPOCH` env var if set,
|
||||
# which allows package maintainers to create reproducible builds.
|
||||
|
||||
@ -154,23 +154,19 @@ macro(configure_bin_names)
|
||||
"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()
|
||||
|
||||
|
||||
@ -23,18 +23,12 @@ macro(configure_libs)
|
||||
configure_unix_libs()
|
||||
elseif(WIN32)
|
||||
configure_windows_libs()
|
||||
find_package(Python REQUIRED QUIET)
|
||||
endif()
|
||||
|
||||
configure_python()
|
||||
configure_qt()
|
||||
configure_openssl()
|
||||
configure_coverage()
|
||||
configure_tomlplusplus()
|
||||
configure_cli11()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
configure_gtest()
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
@ -163,7 +157,8 @@ macro(configure_unix_libs)
|
||||
# Unix only: For config.h, save the results based on a template (config.h.in).
|
||||
# Note that this won't work on Windows because filenames are not case sensitive,
|
||||
# and we have header files named "Config.h" (upper case 'C').
|
||||
configure_file(res/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/lib/config.h)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/src/lib/config.h.in
|
||||
${CMAKE_BINARY_DIR}/src/lib/config.h @ONLY)
|
||||
|
||||
add_definitions(-DSYSAPI_UNIX=1 -DHAVE_CONFIG_H)
|
||||
|
||||
@ -205,9 +200,6 @@ macro(configure_wayland_libs)
|
||||
include(FindPkgConfig)
|
||||
|
||||
if(PKG_CONFIG_FOUND)
|
||||
configure_libei()
|
||||
configure_libportal()
|
||||
|
||||
pkg_check_modules(LIBXKBCOMMON REQUIRED xkbcommon)
|
||||
pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
|
||||
find_library(LIBM m)
|
||||
@ -219,140 +211,6 @@ macro(configure_wayland_libs)
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configure_libei)
|
||||
option(SYSTEM_LIBEI "Use system libei" ON)
|
||||
if(SYSTEM_LIBEI)
|
||||
pkg_check_modules(LIBEI QUIET "libei-1.0 >= ${LIBEI_MIN_VERSION}")
|
||||
if(LIBEI_FOUND)
|
||||
message(STATUS "libei version: ${LIBEI_VERSION}")
|
||||
add_definitions(-DWINAPI_LIBEI=1)
|
||||
include_directories(${LIBEI_INCLUDE_DIRS})
|
||||
else()
|
||||
message(WARNING "libei >= ${LIBEI_MIN_VERSION} not found")
|
||||
endif()
|
||||
else()
|
||||
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
|
||||
PATHS ${libei_bin_dir}
|
||||
NO_DEFAULT_PATH)
|
||||
if(LIBEI_LINK_LIBRARIES)
|
||||
message(STATUS "Using local subproject libei")
|
||||
set(LIBEI_FOUND true)
|
||||
add_definitions(-DWINAPI_LIBEI=1)
|
||||
set(LIBEI_INCLUDE_DIRS ${libei_src_dir}/src)
|
||||
include_directories(${LIBEI_INCLUDE_DIRS})
|
||||
else()
|
||||
message(WARNING "Local libei not found")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(configure_libportal)
|
||||
option(SYSTEM_LIBPORTAL "Use system libportal" ON)
|
||||
if(SYSTEM_LIBPORTAL)
|
||||
pkg_check_modules(LIBPORTAL QUIET "libportal >= ${LIBPORTAL_MIN_VERSION}")
|
||||
if(LIBPORTAL_FOUND)
|
||||
message(STATUS "libportal version: ${LIBPORTAL_VERSION}")
|
||||
check_libportal()
|
||||
else()
|
||||
message(WARNING "libportal >= ${LIBPORTAL_MIN_VERSION} not found")
|
||||
endif()
|
||||
else()
|
||||
set(libportal_bin_dir
|
||||
${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)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif()
|
||||
|
||||
find_library(
|
||||
LIBPORTAL_LINK_LIBRARIES
|
||||
NAMES portal
|
||||
PATHS ${libportal_bin_dir}
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
if(LIBPORTAL_LINK_LIBRARIES)
|
||||
message(STATUS "Using local subproject libportal")
|
||||
set(LIBPORTAL_FOUND true)
|
||||
set(LIBPORTAL_INCLUDE_DIRS ${libportal_src_dir})
|
||||
|
||||
message(STATUS "libportal library file: ${LIBPORTAL_LINK_LIBRARIES}")
|
||||
|
||||
# HACK: Somehow `check_symbol_exists` doesn't pick up on the symbols even though
|
||||
# they are actually there. Since we use master branch of libportal, for now we'll
|
||||
# assume that the symbols are there.
|
||||
set(HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS true)
|
||||
set(HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL true)
|
||||
set(HAVE_LIBPORTAL_INPUTCAPTURE true)
|
||||
set(HAVE_LIBPORTAL_OUTPUT_NONE true)
|
||||
else()
|
||||
message(WARNING "Local libportal not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBPORTAL_FOUND)
|
||||
add_definitions(-DWINAPI_LIBPORTAL=1)
|
||||
include_directories(${LIBPORTAL_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# libportal 0.7 has xdp_session_connect_to_eis but it doesn't have remote desktop session restore or
|
||||
# the inputcapture code, so let's check for explicit functions that bits depending on what we have
|
||||
macro(check_libportal)
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
cmake_push_check_state(RESET)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES
|
||||
"${CMAKE_REQUIRED_INCLUDES};${LIBPORTAL_INCLUDE_DIRS};${GLIB2_INCLUDE_DIRS}"
|
||||
)
|
||||
set(CMAKE_REQUIRED_LIBRARIES
|
||||
"${CMAKE_REQUIRED_LIBRARIES};${LIBPORTAL_LINK_LIBRARIES};${GLIB2_LINK_LIBRARIES}"
|
||||
)
|
||||
|
||||
check_symbol_exists(xdp_session_connect_to_eis "libportal/portal.h"
|
||||
HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS)
|
||||
|
||||
check_symbol_exists(
|
||||
xdp_portal_create_remote_desktop_session_full "libportal/portal.h"
|
||||
HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL)
|
||||
|
||||
check_symbol_exists(xdp_input_capture_session_connect_to_eis
|
||||
"libportal/inputcapture.h" HAVE_LIBPORTAL_INPUTCAPTURE)
|
||||
|
||||
# check_symbol_exists can’t check for enum values
|
||||
check_cxx_source_compiles(
|
||||
"#include <libportal/portal.h>
|
||||
int main() { XdpOutputType out = XDP_OUTPUT_NONE; }
|
||||
" HAVE_LIBPORTAL_OUTPUT_NONE)
|
||||
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(NOT HAVE_LIBPORTAL_SESSION_CONNECT_TO_EIS)
|
||||
message(WARNING "xdp_session_connect_to_eis not found")
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_LIBPORTAL_CREATE_REMOTE_DESKTOP_SESSION_FULL)
|
||||
message(WARNING "xdp_portal_create_remote_desktop_session_full not found")
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_LIBPORTAL_INPUTCAPTURE)
|
||||
message(WARNING "xdp_input_capture_session_connect_to_eis not found")
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_LIBPORTAL_OUTPUT_NONE)
|
||||
message(WARNING "XDP_OUTPUT_NONE not found")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# X.org/X11 for Linux, BSD, etc
|
||||
#
|
||||
@ -460,8 +318,6 @@ endmacro()
|
||||
#
|
||||
macro(configure_windows_libs)
|
||||
|
||||
configure_wintoast()
|
||||
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} /MP /D _BIND_TO_CURRENT_VCLIBS_VERSION=1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2 /Ob2")
|
||||
@ -485,36 +341,10 @@ macro(configure_windows_libs)
|
||||
configure_file(${PROJECT_SOURCE_DIR}/res/win/version.rc.in
|
||||
${PROJECT_BINARY_DIR}/src/version.rc @ONLY)
|
||||
|
||||
configure_windows_openssl()
|
||||
configure_openssl()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configure_windows_openssl)
|
||||
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(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(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(
|
||||
@ -538,65 +368,12 @@ macro(configure_openssl)
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
endmacro()
|
||||
|
||||
macro(configure_gtest)
|
||||
|
||||
file(GLOB gtest_base_dir ${PROJECT_SOURCE_DIR}/subprojects/googletest-*)
|
||||
if(gtest_base_dir)
|
||||
set(DEFAULT_SYSTEM_GTEST OFF)
|
||||
else()
|
||||
set(DEFAULT_SYSTEM_GTEST ON)
|
||||
endif()
|
||||
|
||||
# Arch Linux package maintainers:
|
||||
# We do care about not bundling libs and didn't mean to cause upset. We made some mistakes
|
||||
# and we're trying to put that right.
|
||||
# The comment "They BUNDLE a fucking zip for cryptopp" in deskflow.git/PKGBUILD is only
|
||||
# relevant to a very version of old the code, so the comment should probably be removed.
|
||||
# If there are any problems like this in future, please do feel free send us a patch! :)
|
||||
option(SYSTEM_GTEST "Use system GoogleTest" ${DEFAULT_SYSTEM_GTEST})
|
||||
if(SYSTEM_GTEST)
|
||||
message(VERBOSE "Using system GoogleTest")
|
||||
find_package(GTest)
|
||||
if(GTEST_FOUND)
|
||||
# Ordinarily, we'd use GTEST_LIBRARIES, but it seems that these do not always export
|
||||
# the required libraries (e.g. gmock) on some OS (e.g macOS with brew).
|
||||
set(GTEST_LIB GTest::gtest)
|
||||
set(GMOCK_LIB GTest::gmock)
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Google Test not found, re-configure with -DBUILD_TESTS=OFF or -DSYSTEM_GTEST=OFF"
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
if(NOT EXISTS ${gtest_base_dir})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Google Test subproject not found, reconfigure with -DBUILD_TESTS=OFF"
|
||||
)
|
||||
endif()
|
||||
|
||||
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
|
||||
${gmock_dir}/include)
|
||||
|
||||
add_library(gtest STATIC ${gtest_dir}/src/gtest-all.cc)
|
||||
add_library(gmock STATIC ${gmock_dir}/src/gmock-all.cc)
|
||||
|
||||
if(UNIX)
|
||||
# Ignore noisy GoogleTest warnings
|
||||
set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w")
|
||||
set_target_properties(gmock PROPERTIES COMPILE_FLAGS "-w")
|
||||
endif()
|
||||
|
||||
set(GTEST_LIB gtest)
|
||||
set(GMOCK_LIB gmock)
|
||||
find_package(OpenSSL 3.0 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}")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
@ -639,80 +416,3 @@ macro(configure_coverage)
|
||||
message(STATUS "Code coverage is disabled")
|
||||
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 ${PROJECT_SOURCE_DIR}/subprojects/WinToast-*)
|
||||
if(WINTOAST_DIR)
|
||||
set(HAVE_WINTOAST true)
|
||||
add_definitions(-DHAVE_WINTOAST=1)
|
||||
include_directories(${WINTOAST_DIR}/include)
|
||||
else()
|
||||
message(WARNING "Subproject 'WinToast' not found")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configure_tomlplusplus)
|
||||
file(GLOB tomlplusplus_dir ${PROJECT_SOURCE_DIR}/subprojects/tomlplusplus-*)
|
||||
|
||||
if(tomlplusplus_dir)
|
||||
set(DEFAULT_SYSTEM_TOMLPLUSPLUS OFF)
|
||||
else()
|
||||
set(DEFAULT_SYSTEM_TOMLPLUSPLUS ON)
|
||||
endif()
|
||||
|
||||
option(SYSTEM_TOMLPLUSPLUS "Use system tomlplusplus"
|
||||
${DEFAULT_SYSTEM_TOMLPLUSPLUS})
|
||||
if(SYSTEM_TOMLPLUSPLUS)
|
||||
message(VERBOSE "Using system tomlplusplus")
|
||||
find_package(tomlplusplus)
|
||||
if(tomlplusplus_FOUND)
|
||||
message(STATUS "tomlplusplus version: ${tomlplusplus_VERSION}")
|
||||
else()
|
||||
message(WARNING "System tomlplusplus not found")
|
||||
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)
|
||||
else()
|
||||
message(WARNING "Local tomlplusplus subproject not found")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(configure_cli11)
|
||||
file(GLOB cli11_dir ${PROJECT_SOURCE_DIR}/subprojects/CLI11-*)
|
||||
|
||||
if(cli11_dir)
|
||||
set(DEFAULT_SYSTEM_CLI11 OFF)
|
||||
else()
|
||||
set(DEFAULT_SYSTEM_CLI11 ON)
|
||||
endif()
|
||||
|
||||
option(SYSTEM_CLI11 "Use system CLI11" ${DEFAULT_SYSTEM_CLI11})
|
||||
if(SYSTEM_CLI11)
|
||||
message(VERBOSE "Using system CLI11")
|
||||
find_package(CLI11)
|
||||
if(CLI11_FOUND)
|
||||
message(STATUS "CLI11 version: ${CLI11_VERSION}")
|
||||
else()
|
||||
message(WARNING "System CLI11 not found")
|
||||
endif()
|
||||
else()
|
||||
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 at: ${cli11_dir}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
@ -1,33 +1,31 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
# SPDX-FileCopyrightText: (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-FileCopyrightText: (C) 2012 - 2024 Symless Ltd.
|
||||
# SPDX-FileCopyrightText: (C) 2009 - 2012 Nick Bolton
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
|
||||
#
|
||||
# If enabled, configure packaging based on OS.
|
||||
#
|
||||
macro(configure_packaging)
|
||||
|
||||
message(VERBOSE "Configuring Packaging")
|
||||
set(DESKFLOW_PROJECT_RES_DIR ${PROJECT_SOURCE_DIR}/res)
|
||||
|
||||
if(${BUILD_INSTALLER})
|
||||
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_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION})
|
||||
set(CPACK_PACKAGE_VENDOR ${DESKFLOW_AUTHOR_NAME})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE)
|
||||
|
||||
set(CPACK_PACKAGE_VERSION ${CMAKE_PROJECT_VERSION})
|
||||
|
||||
#Prevent this override from being written in the package
|
||||
if(NOT PACKAGE_VERSION_LABEL)
|
||||
set (PACKAGE_VERSION_LABEL "${CPACK_PACKAGE_VERSION}")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
configure_windows_packaging()
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@ -36,8 +34,12 @@ macro(configure_packaging)
|
||||
configure_linux_packaging()
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "|.*BSD")
|
||||
message(STATUS "BSD packaging not yet supported")
|
||||
set(OS_STRING ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PACKAGE_VERSION_LABEL}-${OS_STRING}")
|
||||
message(STATUS "Package Basename: ${CPACK_PACKAGE_FILE_NAME}")
|
||||
|
||||
include(CPack)
|
||||
else()
|
||||
message(STATUS "Not configuring installer")
|
||||
@ -50,10 +52,7 @@ endmacro()
|
||||
#
|
||||
macro(configure_windows_packaging)
|
||||
|
||||
message(VERBOSE "Configuring Windows installer")
|
||||
|
||||
set(CPACK_PACKAGE_VERSION ${DESKFLOW_VERSION_MS})
|
||||
set(QT_PATH $ENV{CMAKE_PREFIX_PATH})
|
||||
cmake_path(SET QT_PATH NORMALIZE "${Qt6_DIR}../../")
|
||||
|
||||
set(DESKFLOW_MSI_64_GUID
|
||||
"027D1C8A-E7A5-4754-BB93-B2D45BFDBDC8"
|
||||
@ -66,6 +65,14 @@ macro(configure_windows_packaging)
|
||||
configure_files(${PROJECT_SOURCE_DIR}/res/dist/wix
|
||||
${PROJECT_BINARY_DIR}/installer)
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES AMD64)
|
||||
set(OS_STRING "win-x64")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES ARM64)
|
||||
set(OS_STRING "win-arm64")
|
||||
else()
|
||||
set(OS_STRING "win-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
#
|
||||
@ -73,10 +80,6 @@ endmacro()
|
||||
#
|
||||
macro(configure_mac_packaging)
|
||||
|
||||
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
|
||||
@ -87,6 +90,8 @@ macro(configure_mac_packaging)
|
||||
|
||||
configure_files(${DESKFLOW_BUNDLE_SOURCE_DIR} ${DESKFLOW_BUNDLE_DIR})
|
||||
|
||||
set(OS_STRING "macos-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
file(RENAME ${DESKFLOW_BUNDLE_DIR}/Contents/Resources/App.icns
|
||||
${DESKFLOW_BUNDLE_DIR}/Contents/Resources/${DESKFLOW_APP_NAME}.icns)
|
||||
|
||||
@ -95,12 +100,81 @@ endmacro()
|
||||
#
|
||||
# Linux packages
|
||||
#
|
||||
|
||||
macro(configure_linux_package_name)
|
||||
# Get Distro name information
|
||||
execute_process(
|
||||
COMMAND bash "-c" "cat /etc/os-release | grep ^ID= | sed 's/ID=//g'"
|
||||
OUTPUT_VARIABLE _DISTRO_NAME
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE "\"" "" DISTRO_NAME "${_DISTRO_NAME}")
|
||||
message(STATUS "Distro Name: ${DISTRO_NAME}")
|
||||
|
||||
execute_process(
|
||||
COMMAND bash "-c"
|
||||
"cat /etc/os-release | grep ^ID_LIKE= | sed 's/ID_LIKE=//g'"
|
||||
OUTPUT_VARIABLE _DISTRO_LIKE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE "\"" "" DISTRO_LIKE "${_DISTRO_LIKE}")
|
||||
message(STATUS "Distro Like: ${DISTRO_LIKE}")
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
bash "-c"
|
||||
"cat /etc/os-release | grep ^VERSION_CODENAME= | sed 's/VERSION_CODENAME=//g'"
|
||||
OUTPUT_VARIABLE _DISTRO_CODENAME
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE "\"" "" DISTRO_CODENAME "${_DISTRO_CODENAME}")
|
||||
message(STATUS "Distro Codename: ${DISTRO_CODENAME}")
|
||||
|
||||
execute_process(
|
||||
COMMAND bash "-c"
|
||||
"cat /etc/os-release | grep ^VERSION_ID= | sed 's/VERSION_ID=//g'"
|
||||
OUTPUT_VARIABLE _DISTRO_VERSION_ID
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE "\"" "" DISTRO_VERSION_ID "${_DISTRO_VERSION_ID}")
|
||||
message(STATUS "Distro ID: ${DISTRO_VERSION_ID}")
|
||||
|
||||
# Check if Debian-link
|
||||
string(REGEX MATCH debian|buntu DEBTYPE "${DISTRO_LIKE}")
|
||||
if((NOT ("${DEBTYPE}" STREQUAL "")) OR ("${DISTRO_NAME}" STREQUAL "debian"))
|
||||
set(CPACK_GENERATOR "DEB")
|
||||
endif()
|
||||
|
||||
# Check if Rpm-like
|
||||
string(REGEX MATCH suse|fedora|rhel RPMTYPE "${DISTRO_LIKE}")
|
||||
string(REGEX MATCH fedora|suse|rhel RPMNAME "${DISTRO_NAME}")
|
||||
if((NOT ("${RPMTYPE}" STREQUAL "")) OR (NOT ("${RPMNAME}" STREQUAL "")))
|
||||
set(CPACK_GENERATOR "RPM")
|
||||
endif()
|
||||
|
||||
# Disto specific name adjustments
|
||||
if("${DISTRO_NAME}" STREQUAL "opensuse-tumbleweed")
|
||||
set(DISTRO_NAME "opensuse")
|
||||
set(DISTRO_CODENAME "tumbleweed")
|
||||
elseif("${DISTRO_NAME}" STREQUAL "arch")
|
||||
# Arch linux is rolling the version id reported is the date of last iso.
|
||||
set(DISTRO_VERSION_ID "")
|
||||
endif()
|
||||
|
||||
# Determain the code name to be used if any
|
||||
if(NOT "${DISTRO_VERSION_ID}" STREQUAL "")
|
||||
set(CN_STRING "${DISTRO_VERSION_ID}-")
|
||||
endif()
|
||||
|
||||
if(NOT "${DISTRO_CODENAME}" STREQUAL "")
|
||||
set(CN_STRING "${DISTRO_CODENAME}-")
|
||||
endif()
|
||||
|
||||
set(OS_STRING "${DISTRO_NAME}-${CN_STRING}${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configure_linux_packaging)
|
||||
|
||||
message(VERBOSE "Configuring Linux packaging")
|
||||
|
||||
set(CPACK_PACKAGE_VERSION ${DESKFLOW_VERSION_LINUX})
|
||||
set(CPACK_GENERATOR "DEB;RPM;TGZ")
|
||||
# Gather distro info
|
||||
# This is used in package names
|
||||
configure_linux_package_name()
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${DESKFLOW_MAINTAINER})
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
|
||||
@ -114,13 +188,6 @@ macro(configure_linux_packaging)
|
||||
# 12), so we must add it manually.
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "qt6-qpa-plugins")
|
||||
|
||||
# The default for CMake seems to be /usr/local, which seems uncommon. While
|
||||
# the default /usr/local prefix causes the app to appear on Debian and Fedora,
|
||||
# it doesn't seem to appear on Arch Linux. Setting the prefix to /usr seems to
|
||||
# work on a wider variety of distros, and that also seems to be where most
|
||||
# apps install to.
|
||||
set(CMAKE_INSTALL_PREFIX /usr)
|
||||
|
||||
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)
|
||||
@ -184,3 +251,9 @@ macro(configure_files srcDir destDir)
|
||||
endforeach(templateFile)
|
||||
|
||||
endmacro(configure_files)
|
||||
|
||||
macro(check_is_rpm)
|
||||
# Check if RPM-like.
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
@ -1,94 +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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Either get the version number from the environment or from the VERSION file.
|
||||
# On Windows, we also set a special 4-digit MSI version number.
|
||||
macro(set_version)
|
||||
|
||||
set(DESKFLOW_VERSION $ENV{DESKFLOW_VERSION})
|
||||
string(STRIP "${DESKFLOW_VERSION}" DESKFLOW_VERSION)
|
||||
|
||||
if(NOT DESKFLOW_VERSION)
|
||||
file(READ "${PROJECT_SOURCE_DIR}/VERSION" DESKFLOW_VERSION)
|
||||
string(STRIP "${DESKFLOW_VERSION}" DESKFLOW_VERSION)
|
||||
endif()
|
||||
|
||||
message(STATUS "Version number (semver): " ${DESKFLOW_VERSION})
|
||||
add_definitions(-DDESKFLOW_VERSION="${DESKFLOW_VERSION}")
|
||||
|
||||
# Useful for copyright (e.g. in macOS bundle .plist.in and Windows version .rc
|
||||
# file)
|
||||
string(TIMESTAMP DESKFLOW_BUILD_YEAR "%Y")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set_windows_version()
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set_linux_version()
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(set_four_part_version)
|
||||
|
||||
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ "${DESKFLOW_VERSION}")
|
||||
set(VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
set(VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
set(VERSION_PATCH "${CMAKE_MATCH_3}")
|
||||
|
||||
# Find the revision number, which is the number after the 'r'.
|
||||
string(REGEX MATCH "r([0-9]+)$" _ "${DESKFLOW_VERSION}")
|
||||
set(VERSION_REVISION "${CMAKE_MATCH_1}")
|
||||
if(NOT VERSION_REVISION)
|
||||
set(VERSION_REVISION "0")
|
||||
endif()
|
||||
|
||||
set(DESKFLOW_VERSION_FOUR_PART
|
||||
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_REVISION}")
|
||||
|
||||
endmacro()
|
||||
|
||||
# MSI requires a 4-digit number and doesn't accept semver.
|
||||
macro(set_windows_version)
|
||||
|
||||
set_four_part_version()
|
||||
|
||||
# Dot-separated version number for MSI and Windows version .rc file.
|
||||
set(DESKFLOW_VERSION_MS ${DESKFLOW_VERSION_FOUR_PART})
|
||||
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(VERBOSE "Version number for (Microsoft CSV): "
|
||||
${DESKFLOW_VERSION_MS_CSV})
|
||||
endmacro()
|
||||
|
||||
macro(set_linux_version)
|
||||
|
||||
# Replace the first occurrence of '-' with '~' for Linux versioning; the '-'
|
||||
# char is reserved for use at at the end of the version string to indicate a
|
||||
# package revision. Debian has always used this convention, but support for
|
||||
# this was also introduced in RPM 4.10.0.
|
||||
string(REGEX REPLACE "-" "~" DESKFLOW_VERSION_LINUX "${DESKFLOW_VERSION}")
|
||||
message(STATUS "Version number (DEB/RPM): ${DESKFLOW_VERSION_LINUX}")
|
||||
|
||||
# Arch does not support SemVer or DEB/RPM version format, so use the four-part
|
||||
# version format which funnily enough is what Microsoft requires for MSI.
|
||||
set_four_part_version()
|
||||
message(STATUS "Version number (4-part): ${DESKFLOW_VERSION_FOUR_PART}")
|
||||
|
||||
endmacro()
|
||||
205
config.yaml
@ -1,205 +0,0 @@
|
||||
config:
|
||||
windows:
|
||||
dependencies:
|
||||
# We only run `choco` when not in CI env because it's pretty unreliable and slow.
|
||||
# The Chocolatey mirror cannot be 100% reliable (according to docs) so it will often fail
|
||||
# with an error `503 (Service Unavailable: Back-end server is at capacity)` which causes
|
||||
# the nightly CI to fail intermittently.
|
||||
command-elevated: if not defined CI (choco install Chocolatey.config -y)
|
||||
|
||||
# We only run `winget` when not in CI env; it's not available on the GitHub Windows runner.
|
||||
# It's simpler to solve dependencies like Ninja with a GitHub workflow action, and cmake is
|
||||
# already installed on the Windows runner.
|
||||
command: if not defined CI (winget install ninja-build.ninja cmake)
|
||||
qt:
|
||||
version: 6.7.2
|
||||
mirror: https://qt.mirror.constant.com/
|
||||
base-dir: ./deps/qt
|
||||
|
||||
mac:
|
||||
dependencies:
|
||||
command: brew bundle --file=Brewfile
|
||||
qt:
|
||||
version: 6.7.2
|
||||
mirror: https://qt.mirror.constant.com/
|
||||
base-dir: ./deps/qt
|
||||
|
||||
linux:
|
||||
debian: &debian
|
||||
dependencies:
|
||||
command-pre: sudo apt-get update
|
||||
command: |
|
||||
sudo apt-get install -y \
|
||||
cmake \
|
||||
make \
|
||||
ninja-build \
|
||||
g++ \
|
||||
file \
|
||||
xorg-dev \
|
||||
libx11-dev \
|
||||
libxtst-dev \
|
||||
libssl-dev \
|
||||
libglib2.0-dev \
|
||||
libgdk-pixbuf-2.0-dev \
|
||||
libnotify-dev \
|
||||
libxkbfile-dev \
|
||||
qt6-base-dev \
|
||||
qt6-tools-dev \
|
||||
libgtk-3-dev \
|
||||
libgtest-dev \
|
||||
libgmock-dev \
|
||||
libpugixml-dev \
|
||||
libei-dev \
|
||||
libportal-dev \
|
||||
libtomlplusplus-dev \
|
||||
libcli11-dev
|
||||
optional: [libei-dev, libportal-dev, libtomlplusplus-dev]
|
||||
|
||||
linuxmint:
|
||||
<<: *debian
|
||||
|
||||
ubuntu:
|
||||
<<: *debian
|
||||
|
||||
fedora: &fedora
|
||||
dependencies: &fedora_deps
|
||||
command-pre: sudo dnf check-update
|
||||
command: |
|
||||
sudo dnf install -y \
|
||||
cmake \
|
||||
make \
|
||||
ninja-build \
|
||||
gcc-c++ \
|
||||
rpm-build \
|
||||
openssl-devel \
|
||||
glib2-devel \
|
||||
gdk-pixbuf2-devel \
|
||||
libXtst-devel \
|
||||
libnotify-devel \
|
||||
libxkbfile-devel \
|
||||
qt6-qtbase-devel \
|
||||
qt6-qttools-devel \
|
||||
gtk3-devel \
|
||||
gtest-devel \
|
||||
gmock-devel \
|
||||
pugixml-devel \
|
||||
libei-devel \
|
||||
libportal-devel \
|
||||
tomlplusplus-devel \
|
||||
cli11-devel
|
||||
optional: [libei-devel, libportal-devel]
|
||||
|
||||
# RHEL is not actually supported yet, since it doesn't have Qt6 libs.
|
||||
# We simply use it as a base for Alma Linux and Rocky Linux.
|
||||
rhel: &rhel
|
||||
<<: *fedora
|
||||
dependencies: &rhel_deps
|
||||
<<: *fedora_deps
|
||||
command-pre: |
|
||||
sudo dnf check-update;
|
||||
sudo dnf install -y epel-release;
|
||||
dnf config-manager --set-enabled crb
|
||||
|
||||
rocky:
|
||||
<<: *rhel
|
||||
dependencies:
|
||||
<<: *rhel_deps
|
||||
|
||||
almalinux:
|
||||
<<: *rhel
|
||||
dependencies:
|
||||
<<: *rhel_deps
|
||||
|
||||
opensuse-tumbleweed: &opensuse-tumbleweed
|
||||
dependencies:
|
||||
command-pre: sudo zypper refresh
|
||||
command: sudo zypper install -y --force-resolution \
|
||||
cmake \
|
||||
make \
|
||||
ninja \
|
||||
gcc-c++ \
|
||||
rpm-build \
|
||||
libopenssl-devel \
|
||||
glib2-devel \
|
||||
gdk-pixbuf-devel \
|
||||
libXtst-devel \
|
||||
libnotify-devel \
|
||||
libxkbfile-devel \
|
||||
qt6-base-devel \
|
||||
qt6-tools-devel \
|
||||
gtk3-devel \
|
||||
googletest-devel \
|
||||
googlemock-devel \
|
||||
pugixml-devel \
|
||||
libei-devel \
|
||||
libportal-devel \
|
||||
tomlplusplus-devel \
|
||||
cli11-devel
|
||||
|
||||
arch: &arch
|
||||
dependencies:
|
||||
command: sudo pacman -Syu --noconfirm \
|
||||
base-devel \
|
||||
cmake \
|
||||
ninja \
|
||||
gcc \
|
||||
openssl \
|
||||
glib2 \
|
||||
gdk-pixbuf2 \
|
||||
libxtst \
|
||||
libnotify \
|
||||
libxkbfile \
|
||||
gtest \
|
||||
pugixml \
|
||||
libei \
|
||||
libportal \
|
||||
qt6-base \
|
||||
qt6-tools \
|
||||
gtk3 \
|
||||
tomlplusplus \
|
||||
cli11
|
||||
|
||||
manjaro:
|
||||
<<: *arch
|
||||
|
||||
subprojects:
|
||||
libei:
|
||||
dependencies:
|
||||
debian: &debian_libei |
|
||||
sudo apt-get install -y \
|
||||
python3-attr \
|
||||
python3-jinja2 \
|
||||
libsystemd-dev &&
|
||||
pip install attrs jinja2
|
||||
|
||||
ubuntu: *debian_libei
|
||||
linuxmint: *debian_libei
|
||||
|
||||
fedora: &fedora_libei |
|
||||
sudo dnf install -y \
|
||||
python3-attrs \
|
||||
python3-jinja2 \
|
||||
systemd-devel &&
|
||||
pip install attrs jinja2
|
||||
|
||||
rhel: *fedora_libei
|
||||
rocky: *fedora_libei
|
||||
almalinux: *fedora_libei
|
||||
|
||||
libportal:
|
||||
dependencies:
|
||||
debian: &debian_libportal |
|
||||
sudo apt-get install -y \
|
||||
python3-dbusmock \
|
||||
python3-pytest \
|
||||
valac \
|
||||
protobuf-c-compiler \
|
||||
protobuf-compiler \
|
||||
libglib2.0 \
|
||||
libgtk-3-dev \
|
||||
libprotobuf-c-dev \
|
||||
libsystemd-dev \
|
||||
libgirepository1.0-dev
|
||||
|
||||
ubuntu: *debian_libportal
|
||||
linuxmint: *debian_libportal
|
||||
10
cspell.json
@ -7,13 +7,14 @@
|
||||
"aqtinstall",
|
||||
"Axelson",
|
||||
"Breen",
|
||||
"cmakelang",
|
||||
"codesign",
|
||||
"codesigning",
|
||||
"Compat",
|
||||
"contribs",
|
||||
"Daun",
|
||||
"Devs",
|
||||
"Deskflow",
|
||||
"distro",
|
||||
"distros",
|
||||
"dmgbuild",
|
||||
"dotenv",
|
||||
@ -31,6 +32,7 @@
|
||||
"Kanapickas",
|
||||
"keychain",
|
||||
"Keychains",
|
||||
"Kitware",
|
||||
"Kutytska",
|
||||
"Lanz",
|
||||
"libei",
|
||||
@ -49,18 +51,22 @@
|
||||
"pacman",
|
||||
"Petroules",
|
||||
"Pixmap",
|
||||
"Pointee",
|
||||
"Poschta",
|
||||
"Povilas",
|
||||
"Priddy",
|
||||
"psutil",
|
||||
"pyproject",
|
||||
"qputenv",
|
||||
"readf",
|
||||
"Regen",
|
||||
"Repology",
|
||||
"Rizzitello",
|
||||
"runas",
|
||||
"Sbârnea",
|
||||
"Schoeneman",
|
||||
"Serhii",
|
||||
"shemp",
|
||||
"Sorin",
|
||||
"subproject",
|
||||
"subprojects",
|
||||
@ -68,12 +74,14 @@
|
||||
"Trixie",
|
||||
"unittests",
|
||||
"Valgrind",
|
||||
"vbuffer",
|
||||
"vcpkg",
|
||||
"venv",
|
||||
"vmactions",
|
||||
"Volker",
|
||||
"whot",
|
||||
"winget",
|
||||
"writef",
|
||||
"XWINDOWS"
|
||||
],
|
||||
"ignoreWords": [],
|
||||
|
||||
31
doc/CMakeLists.txt
Normal file
@ -0,0 +1,31 @@
|
||||
# SPDX-FileCopyrightText: 2019 - 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
find_package(Doxygen QUIET)
|
||||
option(BUILD_DOCS "Build and install documents" ${DOXYGEN_FOUND})
|
||||
|
||||
if (BUILD_DOCS AND DOXYGEN_FOUND)
|
||||
|
||||
set(DOXYGEN_EXTRACT_ALL YES)
|
||||
set(DOXYGEN_STRIP_FROM_PATH ${CMAKE_SOURCE_DIR})
|
||||
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE mainpage.md)
|
||||
set(DOXYGEN_QUIET YES)
|
||||
|
||||
# Files used to make our documents
|
||||
# User facing documents will not include doxy comments in source code
|
||||
doxygen_add_docs(user-docs ${CMAKE_SOURCE_DIR}/doc COMMENT "Generating user documentation" ALL)
|
||||
|
||||
# HACK Only these will show in your IDE
|
||||
target_sources(user-docs PRIVATE
|
||||
mainpage.md
|
||||
configuration.md
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html"
|
||||
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||
COMPONENT deskflow_docs)
|
||||
|
||||
else()
|
||||
message(STATUS "Doxygen not found, skipping docs build")
|
||||
endif()
|
||||
168
doc/configuration.md
Normal file
@ -0,0 +1,168 @@
|
||||
# Server Config Examples
|
||||
|
||||
The `deskflow-server` command accepts the `-c` or `--config` option, which takes one argument,
|
||||
the path to a server configuration file. The format is non-standard but similar to YAML.
|
||||
|
||||
Comments begin with the `#` character and continue to the end of line.
|
||||
Comments may appear anywhere the syntax permits.
|
||||
|
||||
Each `section` element must have a matching `end` element.
|
||||
|
||||
## Stacked Example
|
||||
|
||||
Stack one computer's screen on top of another's.
|
||||
|
||||
```
|
||||
# +-------+
|
||||
# | curly |
|
||||
# | |
|
||||
# +-------+
|
||||
# +-------+ +-------+
|
||||
# | moe | | larry |
|
||||
# | | | |
|
||||
# +-------+ +-------+
|
||||
|
||||
section: screens
|
||||
# three hosts named: moe, larry, and curly
|
||||
moe:
|
||||
larry:
|
||||
curly:
|
||||
end
|
||||
|
||||
section: links
|
||||
# larry is to the right of moe and curly is above moe.
|
||||
moe:
|
||||
right = larry
|
||||
up = curly
|
||||
|
||||
# moe is to the left of larry and curly is above larry.
|
||||
larry:
|
||||
left = moe
|
||||
up = curly
|
||||
|
||||
# larry is below curly.
|
||||
curly:
|
||||
down = larry
|
||||
end
|
||||
|
||||
section: aliases
|
||||
# curly is also known as shemp
|
||||
curly:
|
||||
shemp
|
||||
end
|
||||
```
|
||||
|
||||
## Horizontal Example
|
||||
|
||||
Align all screens horizontally.
|
||||
|
||||
```
|
||||
# +-------+ +-------+ +-------+
|
||||
# | moe | | larry | | curly |
|
||||
# | | | | | |
|
||||
# +-------+ +-------+ +-------+
|
||||
|
||||
section: screens
|
||||
# three hosts named: moe, larry, and curly
|
||||
moe:
|
||||
larry:
|
||||
curly:
|
||||
end
|
||||
|
||||
section: links
|
||||
# curly is to the right of larry and moe is to the left of larry.
|
||||
larry:
|
||||
right = curly
|
||||
left = moe
|
||||
|
||||
# larry is to the right of moe.
|
||||
moe:
|
||||
right = larry
|
||||
|
||||
# larry is to the left of curly.
|
||||
curly:
|
||||
left = larry
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
## Span Example
|
||||
|
||||
Span two screens on one computer across the screens of two computers.
|
||||
|
||||
```
|
||||
# +-------+ +-------+
|
||||
# | curly | | curly |
|
||||
# | | | |
|
||||
# +-------+ +-------+
|
||||
# +-------+ +-------+
|
||||
# | moe | | larry |
|
||||
# | | | |
|
||||
# +-------+ +-------+
|
||||
|
||||
section: screens
|
||||
# three hosts named: moe, larry, and curly
|
||||
moe:
|
||||
larry:
|
||||
curly:
|
||||
end
|
||||
|
||||
section: links
|
||||
# larry is to the right of moe and curly is above moe.
|
||||
moe:
|
||||
right = larry
|
||||
up = curly
|
||||
|
||||
# moe is to the left of larry and curly is above larry.
|
||||
larry:
|
||||
left = moe
|
||||
up = curly
|
||||
|
||||
# larry is below curly.
|
||||
curly:
|
||||
down = larry
|
||||
end
|
||||
```
|
||||
|
||||
# Example file for `--config-toml` arg
|
||||
|
||||
```
|
||||
[server.args]
|
||||
no-daemon = true
|
||||
no-tray = true
|
||||
debug = "DEBUG"
|
||||
name = "moe"
|
||||
address = ":24800"
|
||||
|
||||
[client.args]
|
||||
no-daemon = true
|
||||
no-tray = true
|
||||
debug = "DEBUG2"
|
||||
name = "larry"
|
||||
_last = "moe:24800"
|
||||
```
|
||||
|
||||
|
||||
# Example `.env` file
|
||||
|
||||
|
||||
```
|
||||
#
|
||||
# App
|
||||
#
|
||||
|
||||
# Shows the test menu in the GUI (on by default in debug mode)
|
||||
# DESKFLOW_TEST_MENU=true
|
||||
|
||||
# Version checker URL to use (useful for testing)
|
||||
# DESKFLOW_VERSION_URL="https://api.deskflow.org/version?fake=1.100.0"
|
||||
|
||||
# Enable debug logging in the GUI (on by default in debug mode)
|
||||
# DESKFLOW_GUI_DEBUG=true
|
||||
|
||||
# Enable verbose logging in the GUI (always off by default)
|
||||
# DESKFLOW_GUI_VERBOSE=true
|
||||
|
||||
# Reset all settings and delete all data on startup
|
||||
# DESKFLOW_RESET_ALL=true
|
||||
```
|
||||
@ -1,37 +0,0 @@
|
||||
# sample deskflow configuration file
|
||||
#
|
||||
# comments begin with the # character and continue to the end of
|
||||
# line. comments may appear anywhere the syntax permits.
|
||||
|
||||
section: screens
|
||||
# three hosts named: moe, larry, and curly
|
||||
moe:
|
||||
larry:
|
||||
curly:
|
||||
end
|
||||
|
||||
section: links
|
||||
# larry is to the right of moe and curly is above moe
|
||||
moe:
|
||||
right = larry
|
||||
up = curly
|
||||
|
||||
# moe is to the left of larry and curly is above larry.
|
||||
# note that curly is above both moe and larry and moe
|
||||
# and larry have a symmetric connection (they're in
|
||||
# opposite directions of each other).
|
||||
larry:
|
||||
left = moe
|
||||
up = curly
|
||||
|
||||
# larry is below curly. if you move up from moe and then
|
||||
# down, you'll end up on larry.
|
||||
curly:
|
||||
down = larry
|
||||
end
|
||||
|
||||
section: aliases
|
||||
# curly is also known as shemp
|
||||
curly:
|
||||
shemp
|
||||
end
|
||||
@ -1,55 +0,0 @@
|
||||
# sample deskflow configuration file
|
||||
#
|
||||
# comments begin with the # character and continue to the end of
|
||||
# line. comments may appear anywhere the syntax permits.
|
||||
|
||||
# This example uses 3 computers. A laptop and two desktops (one a mac)
|
||||
# They are arranged in the following configuration with Desktop1 acting as the server
|
||||
# Desktop 2 has 3 screens arranged around desktop1
|
||||
#
|
||||
# +--------+ +---------+
|
||||
# |Desktop2| |Desktop2 |
|
||||
# | | | |
|
||||
# +--------+ +---------+
|
||||
# +-------+ +--------+ +---------+
|
||||
# |Laptop | |Desktop1| |Desktop2 |
|
||||
# | | | | | |
|
||||
# +-------+ +--------+ +---------+
|
||||
#
|
||||
# The laptop comes and goes but that doesn't really affect this configuration
|
||||
|
||||
# The screens section is for the logical or short name of the computers
|
||||
section: screens
|
||||
# three computers that are logically named: desktop1, desktop2, and laptop
|
||||
desktop1:
|
||||
desktop2:
|
||||
laptop:
|
||||
end
|
||||
|
||||
section: links
|
||||
# larry is to the right of moe and curly is above moe
|
||||
moe:
|
||||
right = larry
|
||||
up = curly
|
||||
|
||||
# moe is to the left of larry and curly is above larry.
|
||||
# note that curly is above both moe and larry and moe
|
||||
# and larry have a symmetric connection (they're in
|
||||
# opposite directions of each other).
|
||||
larry:
|
||||
left = moe
|
||||
up = curly
|
||||
|
||||
# larry is below curly. if you move up from moe and then
|
||||
# down, you'll end up on larry.
|
||||
curly:
|
||||
down = larry
|
||||
end
|
||||
|
||||
# The aliases section is to map the full names of the computers to their logical names used in the screens section
|
||||
# One way to find the actual name of a comptuer is to run hostname from a command window
|
||||
section: aliases
|
||||
# Laptop is actually known as John-Smiths-MacBook-3.local
|
||||
desktop2:
|
||||
John-Smiths-MacBook-3.local
|
||||
end
|
||||
@ -1,39 +0,0 @@
|
||||
# sample deskflow configuration file
|
||||
#
|
||||
# comments begin with the # character and continue to the end of
|
||||
# line. comments may appear anywhere the syntax permits.
|
||||
# +-------+ +--------+ +---------+
|
||||
# |Laptop | |Desktop1| |iMac |
|
||||
# | | | | | |
|
||||
# +-------+ +--------+ +---------+
|
||||
|
||||
section: screens
|
||||
# three hosts named: Laptop, Desktop1, and iMac
|
||||
# These are the nice names of the hosts to make it easy to write the config file
|
||||
# The aliases section below contain the "actual" names of the hosts (their hostnames)
|
||||
Laptop:
|
||||
Desktop1:
|
||||
iMac:
|
||||
end
|
||||
|
||||
section: links
|
||||
# iMac is to the right of Desktop1
|
||||
# Laptop is to the left of Desktop1
|
||||
Desktop1:
|
||||
right = iMac
|
||||
left = Laptop
|
||||
|
||||
# Desktop1 is to the right of Laptop
|
||||
Laptop:
|
||||
right = Desktop1
|
||||
|
||||
# Desktop1 is to the left of iMac
|
||||
iMac:
|
||||
left = Desktop1
|
||||
end
|
||||
|
||||
section: aliases
|
||||
# The "real" name of iMac is John-Smiths-iMac-3.local. If we wanted we could remove this alias and instead use John-Smiths-iMac-3.local everywhere iMac is above. Hopefully it should be easy to see why using an alias is nicer
|
||||
iMac:
|
||||
John-Smiths-iMac-3.local
|
||||
end
|
||||
16
doc/mainpage.md
Normal file
@ -0,0 +1,16 @@
|
||||

|
||||
|
||||
**Deskflow** is a free and open source keyboard and mouse sharing app.
|
||||
Use the keyboard, mouse, or trackpad of one computer to control nearby computers,
|
||||
and work seamlessly between them.
|
||||
|
||||
|
||||
## Configuration
|
||||
Our [Configuration] page has example configurations
|
||||
|
||||
|
||||
## More info
|
||||
|
||||
For more info, see our [Wiki](https://github.com/deskflow/deskflow/wiki).
|
||||
|
||||
[Configuration]:configuration.md
|
||||
56
meson.build
@ -1,56 +0,0 @@
|
||||
# For now, we're only using Meson to resolve dependencies. CMake is called separately.
|
||||
# In future, we may completely replace CMake with Meson.
|
||||
# Where available, we use system packages, otherwise we use subprojects.
|
||||
# Subprojects are also used to get the latest version during development.
|
||||
|
||||
project('deskflow', 'cpp')
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
subproject('wintoast')
|
||||
endif
|
||||
|
||||
system_tomlplusplus = get_option('system-tomlplusplus')
|
||||
if system_tomlplusplus
|
||||
dependency('tomlplusplus', required: false)
|
||||
else
|
||||
subproject('tomlplusplus')
|
||||
endif
|
||||
|
||||
system_cli11 = get_option('system-cli11')
|
||||
if system_cli11
|
||||
dependency('cli11', required: false)
|
||||
else
|
||||
subproject('cli11')
|
||||
endif
|
||||
|
||||
system_gtest = get_option('system-gtest')
|
||||
if system_gtest
|
||||
dependency('gtest', required: false)
|
||||
else
|
||||
subproject('gtest')
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'linux'
|
||||
|
||||
system_libei = get_option('system-libei')
|
||||
if system_libei
|
||||
dependency('libei-1.0', required: false)
|
||||
else
|
||||
# Using the subproject is only useful for development; it's not intended for normal use.
|
||||
# GNOME46 or above is required as this has the required bits for libei.
|
||||
# Building on anything older is pointless as you won't be able to actually connect to anything.
|
||||
subproject('libei', default_options: ['tests=disabled', 'liboeffis=disabled'])
|
||||
endif
|
||||
|
||||
system_libportal = get_option('system-libportal')
|
||||
if system_libportal
|
||||
dependency('libportal', required: false)
|
||||
else
|
||||
# Using the subproject is only useful for development; it's not intended for normal use.
|
||||
subproject('libportal', default_options: [
|
||||
'docs=false',
|
||||
'backend-gtk3=enabled',
|
||||
'backend-qt6=disabled'
|
||||
])
|
||||
endif
|
||||
endif
|
||||
@ -1,5 +0,0 @@
|
||||
option('system-gtest', type: 'boolean', value: true, description: 'Use system gtest')
|
||||
option('system-libportal', type: 'boolean', value: true, description: 'Use system libportal')
|
||||
option('system-libei', type: 'boolean', value: true, description: 'Use system libei')
|
||||
option('system-tomlplusplus', type: 'boolean', value: true, description: 'Use system tomlplusplus')
|
||||
option('system-cli11', type: 'boolean', value: true, description: 'Use system cli11')
|
||||
11
res/dist/arch/PKGBUILD.in
vendored
@ -1,11 +1,11 @@
|
||||
# Maintainer: @DESKFLOW_MAINTAINER@
|
||||
|
||||
pkgname=@DESKFLOW_APP_ID@
|
||||
pkgver=@DESKFLOW_VERSION_FOUR_PART@
|
||||
pkgver=@DESKFLOW_VERSION@
|
||||
pkgrel=1
|
||||
pkgdesc="Mouse and keyboard sharing utility"
|
||||
url='@DESKFLOW_WEBSITE_URL@'
|
||||
arch=('x86_64')
|
||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h' 'aarch64')
|
||||
license=('GPL-2.0-only')
|
||||
depends=(
|
||||
'gcc-libs'
|
||||
@ -20,10 +20,13 @@ depends=(
|
||||
'libxkbcommon-x11'
|
||||
'libnotify'
|
||||
'hicolor-icon-theme'
|
||||
'pugixml'
|
||||
'qt6-base'
|
||||
'qt6-tools'
|
||||
'libei'
|
||||
'libportal'
|
||||
'tomlplusplus'
|
||||
'cli11'
|
||||
)
|
||||
conflicts=('synergy-git' 'synergy1-bin' 'synergy2-bin' 'synergy3-bin')
|
||||
options=('!debug')
|
||||
@ -31,7 +34,7 @@ options=('!debug')
|
||||
package() {
|
||||
# By default, `makepkg` will run from the `src` directory, which would
|
||||
# only install the binaries, and not the .desktop file, etc. To install
|
||||
# everything, we need to run `make install` with the root Makefile.
|
||||
# everything, we need to set DESTDIR.
|
||||
cd $startdir
|
||||
make install DESTDIR=$pkgdir
|
||||
DESTDIR=$pkgdir cmake --install .
|
||||
}
|
||||
|
||||
2
res/dist/mac/bundle/Contents/Info.plist.in
vendored
@ -24,7 +24,7 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>@DESKFLOW_VERSION@</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 2012-@DESKFLOW_BUILD_YEAR@ Symless Ltd</string>
|
||||
<string>© 2024 Deskflow Developers</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.9.0</string>
|
||||
</dict>
|
||||
|
||||
59
res/dist/wix/Include.wxi.in
vendored
@ -1,30 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Include>
|
||||
<?define AppId="@DESKFLOW_APP_ID@"?>
|
||||
<?define Name="@DESKFLOW_APP_NAME@"?>
|
||||
<?define Version="@DESKFLOW_VERSION_MS@"?>
|
||||
<?define Author="@DESKFLOW_AUTHOR_NAME@"?>
|
||||
<?define BinDir="@CMAKE_RUNTIME_OUTPUT_DIRECTORY@"?>
|
||||
<?define ProjectResDir="@DESKFLOW_PROJECT_RES_DIR@"?>
|
||||
<?define ResDir="@DESKFLOW_RES_DIR@"?>
|
||||
<?define QtDir="@QT_PATH@"?>
|
||||
<?define QtBinDir="$(var.QtDir)\bin"?>
|
||||
<?if $(var.Platform) = "x64"?>
|
||||
<?define ProgramFilesFolder="ProgramFiles64Folder"?>
|
||||
<?define PlatformSimpleName="64-bit"?>
|
||||
<?define UpgradeGuid="@DESKFLOW_MSI_64_GUID@"?>
|
||||
<?else?>
|
||||
<?define ProgramFilesFolder="ProgramFilesFolder"?>
|
||||
<?define PlatformSimpleName="32-bit"?>
|
||||
<?define UpgradeGuid="@DESKFLOW_MSI_32_GUID@"?>
|
||||
<?endif?>
|
||||
<?define QtPluginsPath="$(var.QtDir)\plugins"?>
|
||||
<?define OpenSslExeDir="@OPENSSL_EXE_DIR@"?>
|
||||
<?define OpenSslDllDir="@OPENSSL_ROOT_DIR@/bin"?>
|
||||
<?define GuiBin="@GUI_BINARY_NAME@.exe"?>
|
||||
<?define ServerBin="@SERVER_BINARY_NAME@.exe"?>
|
||||
<?define ClientBin="@CLIENT_BINARY_NAME@.exe"?>
|
||||
<?define CoreBin="@CORE_BINARY_NAME@.exe"?>
|
||||
<?define DaemonBin="@DAEMON_BINARY_NAME@.exe"?>
|
||||
<?define LegacyBin="@LEGACY_BINARY_NAME@.exe"?>
|
||||
</Include>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Include>
|
||||
<?define AppId="@DESKFLOW_APP_ID@"?>
|
||||
<?define Name="@DESKFLOW_APP_NAME@"?>
|
||||
<?define Version="@DESKFLOW_VERSION@"?>
|
||||
<?define Author="@DESKFLOW_AUTHOR_NAME@"?>
|
||||
<?define BinDir="@CMAKE_RUNTIME_OUTPUT_DIRECTORY@"?>
|
||||
<?define ProjectResDir="@DESKFLOW_PROJECT_RES_DIR@"?>
|
||||
<?define ResDir="@DESKFLOW_RES_DIR@"?>
|
||||
<?define QtDir="@QT_PATH@"?>
|
||||
<?define QtBinDir="$(var.QtDir)\bin"?>
|
||||
<?if $(var.Platform) = "x64"?>
|
||||
<?define ProgramFilesFolder="ProgramFiles64Folder"?>
|
||||
<?define PlatformSimpleName="64-bit"?>
|
||||
<?define UpgradeGuid="@DESKFLOW_MSI_64_GUID@"?>
|
||||
<?else?>
|
||||
<?define ProgramFilesFolder="ProgramFilesFolder"?>
|
||||
<?define PlatformSimpleName="32-bit"?>
|
||||
<?define UpgradeGuid="@DESKFLOW_MSI_32_GUID@"?>
|
||||
<?endif?>
|
||||
<?define QtPluginsPath="$(var.QtDir)\plugins"?>
|
||||
<?define OpenSslExeDir="@OPENSSL_EXE_DIR@"?>
|
||||
<?define OpenSslDllDir="@OPENSSL_ROOT_DIR@/bin"?>
|
||||
<?define GuiBin="@GUI_BINARY_NAME@.exe"?>
|
||||
<?define ServerBin="@SERVER_BINARY_NAME@.exe"?>
|
||||
<?define ClientBin="@CLIENT_BINARY_NAME@.exe"?>
|
||||
<?define CoreBin="@CORE_BINARY_NAME@.exe"?>
|
||||
<?define DaemonBin="@DAEMON_BINARY_NAME@.exe"?>
|
||||
</Include>
|
||||
|
||||
320
res/dist/wix/Product.wxs
vendored
@ -1,154 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<?include Include.wxi?>
|
||||
<Product Id="*" Language="1033" Manufacturer="$(var.Author)" Name="$(var.Name) ($(var.PlatformSimpleName))" UpgradeCode="$(var.UpgradeGuid)" Version="$(var.Version)">
|
||||
<Package Compressed="yes" InstallScope="perMachine" InstallerVersion="301"/>
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of $(var.Name) is already installed."/>
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
<!-- causes ICE61 warning, but stops user from installing many instances from nightly builds. -->
|
||||
<Upgrade Id="$(var.UpgradeGuid)">
|
||||
<UpgradeVersion Minimum="0.0.0.0" Property="UPGRADE"/>
|
||||
</Upgrade>
|
||||
<Feature Id="ProductFeature" Title="$(var.Name)">
|
||||
<ComponentGroupRef Id="ProductComponents"/>
|
||||
<ComponentGroupRef Id="OpenSSLComponents"/>
|
||||
<ComponentGroupRef Id="ProductQtStylesComponents"/>
|
||||
<ComponentGroupRef Id="ProductQtPluginComponents"/>
|
||||
<ComponentRef Id="RegistryEntries"/>
|
||||
<MergeRef Id="VC_Redist"/>
|
||||
</Feature>
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Component Guid="7CF3564D-1F8E-4D3D-9781-E1EE22D5BD67" Id="RegistryEntries">
|
||||
<RegistryKey Id="$(var.AppId)_server" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Root="HKLM">
|
||||
<RegistryValue Name="[INSTALLFOLDER]$(var.ServerBin)" Type="string" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="$(var.AppId)_client" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]$(var.ClientBin)" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="$(var.AppId)" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]$(var.GuiBin)" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
<!-- Windows 8 and later only -->
|
||||
<Condition><![CDATA[Installed OR (VersionNT >= 602)]]></Condition>
|
||||
</Component>
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<Merge Id="VC_Redist" SourceFile="$(var.ProjectResDir)\dist\wix\msm\Microsoft_VC142_CRT_x64.msm" DiskId="1" Language="0"/>
|
||||
<?else ?>
|
||||
<Merge Id="VC_Redist" SourceFile="$(var.ProjectResDir)\dist\wix\msm\Microsoft_VC142_CRT_x86.msm" DiskId="1" Language="0"/>
|
||||
<?endif ?>
|
||||
</DirectoryRef>
|
||||
<Property Id="CommonBackground">CommonBackground</Property>
|
||||
<Binary Id="CommonBackground" SourceFile="$(var.ResDir)\dist\wix\images\common_background.png"/>
|
||||
<Icon Id="AppIcon" SourceFile="$(var.ResDir)/app.ico"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="$(var.ResDir)\dist\wix\images\banner.png"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="$(var.ResDir)\dist\wix\images\dialog.png"/>
|
||||
<Property Id="ARPPRODUCTICON" Value="AppIcon"/>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
|
||||
<Property Id="LEGACY_UNINSTALL_EXISTS">
|
||||
<RegistrySearch Id="LegacyRegistrySearch" Key="SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$(var.Name)" Name="UninstallString" Root="HKLM" Type="file" Win64="no">
|
||||
<FileSearch Id="LegacyFileSearch" Name="uninstall.exe"/>
|
||||
</RegistrySearch>
|
||||
</Property>
|
||||
<Condition Message="An existing installation of $(var.Name) was detected, please uninstall it before continuing.">NOT LEGACY_UNINSTALL_EXISTS
|
||||
</Condition>
|
||||
<CustomAction ExeCommand="" FileKey="GuiProgram" Id="StartGui" Return="asyncNoWait"/>
|
||||
<UI>
|
||||
<UIRef Id="AppDlgSequence" />
|
||||
</UI>
|
||||
</Product>
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="$(var.ProgramFilesFolder)">
|
||||
<Directory Id="INSTALLFOLDER" Name="$(var.Name)">
|
||||
<Directory Id="OpenSSLDir" Name="OpenSSL"/>
|
||||
<Directory Id="PlatformsDir" Name="Platforms"/>
|
||||
<Directory Id="QTStylesDir" Name="styles"/>
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Directory Id="ProgramMenuFolder"/>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<ComponentGroup Directory="INSTALLFOLDER" Id="ProductComponents">
|
||||
<Component Guid="EC9AD3B0-277C-4157-B5C8-5FD5B6A5F4AD" Id="Core">
|
||||
<File KeyPath="yes" Source="$(var.BinDir)/$(var.DaemonBin)"/>
|
||||
<ServiceInstall Description="Controls the $(var.Name) foreground processes." DisplayName="$(var.Name)" ErrorControl="normal" Id="ServiceInstall" Name="$(var.Name)" Start="auto" Type="ownProcess">
|
||||
<util:ServiceConfig FirstFailureActionType="restart" ResetPeriodInDays="1" RestartServiceDelayInSeconds="1" SecondFailureActionType="restart" ThirdFailureActionType="restart"/>
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceControl" Name="$(var.Name)" Remove="uninstall" Start="install" Stop="both"/>
|
||||
<File Source="$(var.BinDir)/$(var.ServerBin)">
|
||||
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name) Server" Scope="any"/>
|
||||
</File>
|
||||
<File Source="$(var.BinDir)/$(var.ClientBin)">
|
||||
<fire:FirewallException Id="ClientFirewallException" IgnoreFailure="yes" Name="$(var.Name) Client" Scope="any"/>
|
||||
</File>
|
||||
<File Source="$(var.BinDir)/$(var.LegacyBin)" />
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<File Source="$(var.OpenSslDllDir)/libssl-3-x64.dll"/>
|
||||
<File Source="$(var.OpenSslDllDir)/libcrypto-3-x64.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.OpenSslDllDir)/libssl-3.dll"/>
|
||||
<File Source="$(var.OpenSslDllDir)/libcrypto-3.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
<Component Guid="BAC8149B-6287-45BF-9C27-43D71ED40214" Id="Gui">
|
||||
<File Id="GuiProgram" KeyPath="yes" Source="$(var.BinDir)/$(var.GuiBin)">
|
||||
<Shortcut Advertise="yes" Directory="ProgramMenuFolder" Icon="$(var.GuiBin)" Id="GuiShortcut" Name="$(var.Name)">
|
||||
<Icon Id="$(var.GuiBin)" SourceFile="$(var.ResDir)/app.ico"/>
|
||||
</Shortcut>
|
||||
<fire:FirewallException Id="GuiFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
|
||||
</File>
|
||||
<?if $(var.Configuration) = "Debug" ?>
|
||||
<File Source="$(var.BinDir)\Qt6Cored.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Guid.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Networkd.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Svgd.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Widgetsd.dll"/>
|
||||
<File Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
<!-- HACK: Normally the C++ redistributable solves this dependency, including it can cause problems -->
|
||||
<File Source="C:\Program Files (x86)\Windows Kits\10\bin\$(var.Platform)\ucrt\ucrtbased.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.BinDir)\Qt6Core.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Gui.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Network.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Svg.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Widgets.dll"/>
|
||||
<File Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="QTStylesDir" Id="ProductQtStylesComponents">
|
||||
<Component Guid="96E0F8D8-64FD-4CE8-94D1-F6EDCBBB4995" Id="Styles">
|
||||
<File Id="qmodernwindowsstyle" Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="PlatformsDir" Id="ProductQtPluginComponents">
|
||||
<Component Guid="684EFA14-856B-440E-A5E6-E90E04E36B41" Id="QtPlatformPlugin">
|
||||
<?if $(var.Configuration) = "Debug" ?>
|
||||
<File Source="$(var.BinDir)\platforms\qwindowsd.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.BinDir)\platforms\qwindows.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="OpenSSLDir" Id="OpenSSLComponents">
|
||||
<Component Guid="92648F77-65A6-4B16-AC59-A1F37BD341B1" Id="OpenSSL">
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<File Id="OpenSSLDll1" Source="$(var.OpenSslDllDir)/libcrypto-3-x64.dll"/>
|
||||
<File Id="OpenSSLDll2" Source="$(var.OpenSslDllDir)/libssl-3-x64.dll"/>
|
||||
<?else ?>
|
||||
<File Id="OpenSSLDll1" Source="$(var.OpenSslDllDir)/libcrypto-3.dll"/>
|
||||
<File Id="OpenSSLDll2" Source="$(var.OpenSslDllDir)/libssl-3.dll"/>
|
||||
<?endif ?>
|
||||
<File Source="$(var.OpenSslExeDir)/openssl.exe"/>
|
||||
<File Source="$(var.OpenSslExeDir)/openssl.cnf"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<?include Include.wxi?>
|
||||
<Product Id="*" Language="1033" Manufacturer="$(var.Author)" Name="$(var.Name) ($(var.PlatformSimpleName))" UpgradeCode="$(var.UpgradeGuid)" Version="$(var.Version)">
|
||||
<Package Compressed="yes" InstallScope="perMachine" InstallerVersion="301"/>
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of $(var.Name) is already installed."/>
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
<!-- causes ICE61 warning, but stops user from installing many instances from nightly builds. -->
|
||||
<Upgrade Id="$(var.UpgradeGuid)">
|
||||
<UpgradeVersion Minimum="0.0.0.0" Property="UPGRADE"/>
|
||||
</Upgrade>
|
||||
<Feature Id="ProductFeature" Title="$(var.Name)">
|
||||
<ComponentGroupRef Id="ProductComponents"/>
|
||||
<ComponentGroupRef Id="OpenSSLComponents"/>
|
||||
<ComponentGroupRef Id="ProductQtStylesComponents"/>
|
||||
<ComponentGroupRef Id="ProductQtPluginComponents"/>
|
||||
<ComponentRef Id="RegistryEntries"/>
|
||||
<MergeRef Id="VC_Redist"/>
|
||||
</Feature>
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Component Guid="7CF3564D-1F8E-4D3D-9781-E1EE22D5BD67" Id="RegistryEntries">
|
||||
<RegistryKey Id="$(var.AppId)_server" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Root="HKLM">
|
||||
<RegistryValue Name="[INSTALLFOLDER]$(var.ServerBin)" Type="string" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="$(var.AppId)_client" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]$(var.ClientBin)" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="$(var.AppId)" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]$(var.GuiBin)" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
<!-- Windows 8 and later only -->
|
||||
<Condition><![CDATA[Installed OR (VersionNT >= 602)]]></Condition>
|
||||
</Component>
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<Merge Id="VC_Redist" SourceFile="$(var.ProjectResDir)\dist\wix\msm\Microsoft_VC142_CRT_x64.msm" DiskId="1" Language="0"/>
|
||||
<?else ?>
|
||||
<Merge Id="VC_Redist" SourceFile="$(var.ProjectResDir)\dist\wix\msm\Microsoft_VC142_CRT_x86.msm" DiskId="1" Language="0"/>
|
||||
<?endif ?>
|
||||
</DirectoryRef>
|
||||
<Property Id="CommonBackground">CommonBackground</Property>
|
||||
<Binary Id="CommonBackground" SourceFile="$(var.ResDir)\dist\wix\images\common_background.png"/>
|
||||
<Icon Id="AppIcon" SourceFile="$(var.ResDir)/app.ico"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="$(var.ResDir)\dist\wix\images\banner.png"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="$(var.ResDir)\dist\wix\images\dialog.png"/>
|
||||
<Property Id="ARPPRODUCTICON" Value="AppIcon"/>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
|
||||
<Property Id="LEGACY_UNINSTALL_EXISTS">
|
||||
<RegistrySearch Id="LegacyRegistrySearch" Key="SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$(var.Name)" Name="UninstallString" Root="HKLM" Type="file" Win64="no">
|
||||
<FileSearch Id="LegacyFileSearch" Name="uninstall.exe"/>
|
||||
</RegistrySearch>
|
||||
</Property>
|
||||
<Condition Message="An existing installation of $(var.Name) was detected, please uninstall it before continuing.">NOT LEGACY_UNINSTALL_EXISTS
|
||||
</Condition>
|
||||
<CustomAction ExeCommand="" FileKey="GuiProgram" Id="StartGui" Return="asyncNoWait"/>
|
||||
<UI>
|
||||
<UIRef Id="AppDlgSequence" />
|
||||
</UI>
|
||||
</Product>
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="$(var.ProgramFilesFolder)">
|
||||
<Directory Id="INSTALLFOLDER" Name="$(var.Name)">
|
||||
<Directory Id="OpenSSLDir" Name="OpenSSL"/>
|
||||
<Directory Id="PlatformsDir" Name="Platforms"/>
|
||||
<Directory Id="QTStylesDir" Name="styles"/>
|
||||
</Directory>
|
||||
</Directory>
|
||||
<Directory Id="ProgramMenuFolder"/>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<ComponentGroup Directory="INSTALLFOLDER" Id="ProductComponents">
|
||||
<Component Guid="EC9AD3B0-277C-4157-B5C8-5FD5B6A5F4AD" Id="Core">
|
||||
<File KeyPath="yes" Source="$(var.BinDir)/$(var.DaemonBin)"/>
|
||||
<ServiceInstall Description="Controls the $(var.Name) foreground processes." DisplayName="$(var.Name)" ErrorControl="normal" Id="ServiceInstall" Name="$(var.Name)" Start="auto" Type="ownProcess">
|
||||
<util:ServiceConfig FirstFailureActionType="restart" ResetPeriodInDays="1" RestartServiceDelayInSeconds="1" SecondFailureActionType="restart" ThirdFailureActionType="restart"/>
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="ServiceControl" Name="$(var.Name)" Remove="uninstall" Start="install" Stop="both"/>
|
||||
<File Source="$(var.BinDir)/$(var.ServerBin)">
|
||||
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name) Server" Scope="any"/>
|
||||
</File>
|
||||
<File Source="$(var.BinDir)/$(var.ClientBin)">
|
||||
<fire:FirewallException Id="ClientFirewallException" IgnoreFailure="yes" Name="$(var.Name) Client" Scope="any"/>
|
||||
</File>
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<File Source="$(var.OpenSslDllDir)/libssl-3-x64.dll"/>
|
||||
<File Source="$(var.OpenSslDllDir)/libcrypto-3-x64.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.OpenSslDllDir)/libssl-3.dll"/>
|
||||
<File Source="$(var.OpenSslDllDir)/libcrypto-3.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
<Component Guid="BAC8149B-6287-45BF-9C27-43D71ED40214" Id="Gui">
|
||||
<File Id="GuiProgram" KeyPath="yes" Source="$(var.BinDir)/$(var.GuiBin)">
|
||||
<Shortcut Advertise="yes" Directory="ProgramMenuFolder" Icon="$(var.GuiBin)" Id="GuiShortcut" Name="$(var.Name)">
|
||||
<Icon Id="$(var.GuiBin)" SourceFile="$(var.ResDir)/app.ico"/>
|
||||
</Shortcut>
|
||||
<fire:FirewallException Id="GuiFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
|
||||
</File>
|
||||
<?if $(var.Configuration) = "Debug" ?>
|
||||
<File Source="$(var.BinDir)\Qt6Cored.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Guid.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Networkd.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Svgd.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Widgetsd.dll"/>
|
||||
<File Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
<!-- HACK: Normally the C++ redistributable solves this dependency, including it can cause problems -->
|
||||
<File Source="C:\Program Files (x86)\Windows Kits\10\bin\$(var.Platform)\ucrt\ucrtbased.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.BinDir)\brotlicommon.dll"/>
|
||||
<File Source="$(var.BinDir)\brotlidec.dll"/>
|
||||
<File Source="$(var.BinDir)\bz2.dll"/>
|
||||
<File Source="$(var.BinDir)\double-conversion.dll"/>
|
||||
<File Source="$(var.BinDir)\freetype.dll"/>
|
||||
<File Source="$(var.BinDir)\harfbuzz.dll"/>
|
||||
<File Source="$(var.BinDir)\icudt74.dll"/>
|
||||
<File Source="$(var.BinDir)\icuin74.dll"/>
|
||||
<File Source="$(var.BinDir)\icuuc74.dll"/>
|
||||
<File Source="$(var.BinDir)\libpng16.dll"/>
|
||||
<File Source="$(var.BinDir)\pcre2-16.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Core.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Gui.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Network.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Svg.dll"/>
|
||||
<File Source="$(var.BinDir)\Qt6Widgets.dll"/>
|
||||
<File Source="$(var.BinDir)\zlib1.dll"/>
|
||||
<File Source="$(var.BinDir)\zstd.dll"/>
|
||||
<File Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="QTStylesDir" Id="ProductQtStylesComponents">
|
||||
<Component Guid="96E0F8D8-64FD-4CE8-94D1-F6EDCBBB4995" Id="Styles">
|
||||
<File Id="qmodernwindowsstyle" Source="$(var.BinDir)\styles\qmodernwindowsstyle.dll"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="PlatformsDir" Id="ProductQtPluginComponents">
|
||||
<Component Guid="684EFA14-856B-440E-A5E6-E90E04E36B41" Id="QtPlatformPlugin">
|
||||
<?if $(var.Configuration) = "Debug" ?>
|
||||
<File Source="$(var.BinDir)\platforms\qwindowsd.dll"/>
|
||||
<?else ?>
|
||||
<File Source="$(var.BinDir)\platforms\qwindows.dll"/>
|
||||
<?endif ?>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Directory="OpenSSLDir" Id="OpenSSLComponents">
|
||||
<Component Guid="92648F77-65A6-4B16-AC59-A1F37BD341B1" Id="OpenSSL">
|
||||
<?if $(var.Platform) = x64 ?>
|
||||
<File Id="OpenSSLDll1" Source="$(var.OpenSslDllDir)/libcrypto-3-x64.dll"/>
|
||||
<File Id="OpenSSLDll2" Source="$(var.OpenSslDllDir)/libssl-3-x64.dll"/>
|
||||
<?else ?>
|
||||
<File Id="OpenSSLDll1" Source="$(var.OpenSslDllDir)/libcrypto-3.dll"/>
|
||||
<File Id="OpenSSLDll2" Source="$(var.OpenSslDllDir)/libssl-3.dll"/>
|
||||
<?endif ?>
|
||||
<File Source="$(var.OpenSslExeDir)/openssl.exe"/>
|
||||
<File Source="$(var.OpenSslExeDir)/openssl.cnf"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/16x16/tray.png</file>
|
||||
<file>icons/64x64/video-display.png</file>
|
||||
<file>icons/64x64/user-trash.png</file>
|
||||
<file>icons/16x16/warning.png</file>
|
||||
<file>icons/256x256/app.ico</file>
|
||||
<file>image/logo-light.png</file>
|
||||
<file>image/logo-dark.png</file>
|
||||
<file>icons/16x16/padlock.png</file>
|
||||
<file>icons/64x64/tray-dark.png</file>
|
||||
<file>icons/64x64/tray-light.png</file>
|
||||
<file>icons/64x64/padlock.png</file>
|
||||
<file>icons/128x128/tray-dark.png</file>
|
||||
<file>icons/128x128/tray-light.png</file>
|
||||
<file>icons/128x128/tray.png</file>
|
||||
<file>image/welcome.png</file>
|
||||
<file>icons/64x64/folder.png</file>
|
||||
<file>icons/64x64/copy-light.png</file>
|
||||
<file>icons/64x64/copy-dark.png</file>
|
||||
<file>image/placeholder.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
BIN
res/gui/icons/128x128/tray-dark.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
res/gui/icons/128x128/tray-light.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
res/gui/icons/128x128/tray.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 926 B |
|
Before Width: | Height: | Size: 693 B |
|
Before Width: | Height: | Size: 56 KiB |
BIN
res/gui/icons/64x64/copy-dark.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
res/gui/icons/64x64/copy-light.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
res/gui/icons/64x64/padlock.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
@ -1 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "../icons/256x256/app.ico"
|
||||
IDI_ICON1 ICON DISCARDABLE "../../app.ico"
|
||||
|
||||
@ -10,12 +10,12 @@ https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource?redi
|
||||
#define VER_FILEVERSION_STR "@DESKFLOW_VERSION_MS@\0"
|
||||
|
||||
#define VER_PRODUCTVERSION @DESKFLOW_VERSION_MS_CSV@
|
||||
#define VER_PRODUCTVERSION_STR "@DESKFLOW_VERSION_MS@\0"
|
||||
#define VER_PRODUCTVERSION_STR "@DESKFLOW_VERSION@\0"
|
||||
|
||||
#define VER_COMPANYNAME_STR "@DESKFLOW_AUTHOR_NAME@\0"
|
||||
#define VER_FILEDESCRIPTION_STR "@DESKFLOW_APP_NAME@\0"
|
||||
#define VER_INTERNALNAME_STR "@DESKFLOW_APP_NAME@\0"
|
||||
#define VER_LEGALCOPYRIGHT_STR "Copyright (C) Symless Ltd. @DESKFLOW_BUILD_YEAR@\0"
|
||||
#define VER_LEGALCOPYRIGHT_STR "© 2024 Deskflow Developers\0"
|
||||
#define VER_LEGALTRADEMARKS1_STR "All Rights Reserved\0"
|
||||
#define VER_LEGALTRADEMARKS2_STR "\0"
|
||||
#define VER_ORIGINALFILENAME_STR "\0"
|
||||
|
||||
@ -1,355 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, sys, argparse, traceback
|
||||
import lib.env as env
|
||||
import lib.cmd_utils as cmd_utils
|
||||
import lib.qt_utils as qt_utils
|
||||
import lib.github as github
|
||||
import lib.meson as meson
|
||||
|
||||
path_env_var = "PATH"
|
||||
cmake_prefix_env_var = "CMAKE_PREFIX_PATH"
|
||||
|
||||
|
||||
def main():
|
||||
is_ci = os.getenv("CI") is not None
|
||||
if is_ci:
|
||||
print("CI environment detected")
|
||||
|
||||
args = parse_args(is_ci)
|
||||
if args.lock_file:
|
||||
env.persist_lock_file(args.lock_file)
|
||||
|
||||
try:
|
||||
run(args)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
finally:
|
||||
if env.is_windows() and args.pause_on_exit:
|
||||
# Allow the rest of the install to continue while sitting at the pause.
|
||||
if args.lock_file:
|
||||
env.remove_lock_file(args.lock_file)
|
||||
|
||||
# Useful on Windows, when elevated, Python is opened in a new window and closes
|
||||
# immediately after the script finishes. This keeps the script window open so that
|
||||
# the user can see the output.
|
||||
print()
|
||||
input("Press enter to continue...")
|
||||
|
||||
|
||||
def parse_args(is_ci):
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--ci-env",
|
||||
action="store_true",
|
||||
help="Useful for faking CI env (defaults to true in CI env)",
|
||||
default=is_ci,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lock-file",
|
||||
type=str,
|
||||
help="Create a file to indicate script is running",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--only-python", action="store_true", help="Only install Python dependencies"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-python",
|
||||
action="store_true",
|
||||
help="Do not install Python dependencies",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-system",
|
||||
action="store_true",
|
||||
help="Do not install system dependencies (apt, dnf, etc)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-meson", action="store_true", help="Do not setup and compile with Meson"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--subprojects",
|
||||
action="store_true",
|
||||
help="Install dependencies for Meson subprojects (use with --meson-no-system)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--meson-install",
|
||||
action="store_true",
|
||||
help="Install built Meson subprojects to system",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--meson-no-system",
|
||||
nargs="+",
|
||||
help="Specify which Meson subprojects to use instead of system dependencies",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--meson-static",
|
||||
nargs="+",
|
||||
help="Specify which Meson subprojects to build as static libraries",
|
||||
)
|
||||
|
||||
if env.is_windows():
|
||||
parser.add_argument(
|
||||
"--skip-vcpkg",
|
||||
action="store_true",
|
||||
help="Windows only: Do not install vcpkg dependencies",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--skip-elevated",
|
||||
action="store_true",
|
||||
help="Windows only: Do not run elevated command",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--only-elevated",
|
||||
action="store_true",
|
||||
help="Windows only: Only run elevated command",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pause-on-exit",
|
||||
action="store_true",
|
||||
help="Windows only: Useful to prevent elevated window from closing",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def run(args):
|
||||
env.ensure_dependencies()
|
||||
env.ensure_in_venv(__file__, create_venv=True)
|
||||
|
||||
if not args.skip_python:
|
||||
env.install_requirements()
|
||||
|
||||
colors = env.import_colors()
|
||||
|
||||
if args.only_python:
|
||||
print()
|
||||
print(colors.SUCCESS_TEXT + " Only Python dependencies installed")
|
||||
return
|
||||
|
||||
try:
|
||||
install(args)
|
||||
|
||||
print()
|
||||
print(f"\n{colors.SUCCESS_TEXT} Dependencies installed")
|
||||
|
||||
# On Windows and macOS, we set env vars for cmake, but for them to be picked up,
|
||||
# either the shell needs to be restarted or the env vars need to be re-sourced.
|
||||
# Restarting the shell is easier for most people.
|
||||
if not env.is_linux():
|
||||
print(
|
||||
f"{colors.WARNING_TEXT} You may need to restart your terminal "
|
||||
"or IDE to use new env vars"
|
||||
)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
print()
|
||||
print(f"\n{colors.ERROR_TEXT} Failed to install dependencies")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def install(args):
|
||||
if not args.skip_system:
|
||||
deps = Dependencies(args)
|
||||
deps.install()
|
||||
|
||||
# Only install vcpkg dependencies on Windows, since on other OS it's not needed (yet).
|
||||
# We probably won't ever need this on macOS and Linux since brew and apt/dnf/etc do a
|
||||
# good job of providing dependencies. Where they don't, we can use Meson.
|
||||
if env.is_windows() and not args.skip_vcpkg:
|
||||
import lib.vcpkg as vcpkg
|
||||
|
||||
vcpkg.install(args.ci_env)
|
||||
|
||||
if not args.skip_meson:
|
||||
if args.subprojects:
|
||||
for subproject in args.meson_no_system or []:
|
||||
deps = SubprojectDependencies(subproject)
|
||||
deps.install()
|
||||
|
||||
run_meson(args.meson_install, args.meson_no_system, args.meson_static)
|
||||
|
||||
|
||||
# It's a bit weird to use Meson just for installing deps, but it's a stopgap until
|
||||
# we fully switch from CMake to Meson. For the meantime, Meson will install the deps
|
||||
# so that CMake can find them easily. Once we switch to Meson, it might be possible for
|
||||
# Meson handle the deps resolution, so that we won't need to install them on the system.
|
||||
def run_meson(install, no_system_list, static_list):
|
||||
meson.setup(no_system_list, static_list)
|
||||
|
||||
# Only compile and install on Linux for now, since we're only using Meson to fetch
|
||||
# the deps on Windows and macOS.
|
||||
if env.is_linux():
|
||||
meson.compile()
|
||||
|
||||
if install:
|
||||
meson.install()
|
||||
|
||||
|
||||
class Dependencies:
|
||||
|
||||
def __init__(self, args):
|
||||
from lib.config import Config
|
||||
|
||||
self.config = Config()
|
||||
self.args = args
|
||||
self.ci_env = args.ci_env
|
||||
|
||||
def install(self):
|
||||
"""Installs dependencies for the current platform."""
|
||||
|
||||
if env.is_windows():
|
||||
self.windows()
|
||||
elif env.is_mac():
|
||||
self.mac()
|
||||
elif env.is_linux():
|
||||
self.linux()
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported platform: {os}")
|
||||
|
||||
def windows(self):
|
||||
"""Installs dependencies on Windows."""
|
||||
import lib.windows as windows
|
||||
|
||||
if not self.args.skip_elevated:
|
||||
if windows.is_admin():
|
||||
|
||||
# The choco command should run from the elevated command.
|
||||
choco = windows.WindowsChoco()
|
||||
choco.ensure_choco_installed()
|
||||
command_elevated = self.config.get_os_deps_command("command-elevated")
|
||||
cmd_utils.run(command_elevated, shell=True, print_cmd=True)
|
||||
|
||||
if self.args.only_elevated:
|
||||
sys.exit(0)
|
||||
else:
|
||||
windows.run_elevated(
|
||||
__file__, "--only-elevated --skip-python", wait_for_exit=True
|
||||
)
|
||||
|
||||
qt = qt_utils.WindowsQt(*self.config.get_qt_config())
|
||||
qt.install()
|
||||
|
||||
if self.ci_env:
|
||||
github.set_env_var(cmake_prefix_env_var, qt.get_install_dir())
|
||||
else:
|
||||
windows.set_env_var(cmake_prefix_env_var, qt.get_install_dir())
|
||||
|
||||
command = self.config.get_os_deps_command()
|
||||
|
||||
cmd_utils.run(command, shell=True, print_cmd=True)
|
||||
|
||||
def mac(self):
|
||||
"""Installs dependencies on macOS."""
|
||||
import lib.mac as mac
|
||||
|
||||
# On macOS, brew does have a Qt package available, but it is always built against the
|
||||
# current macOS version and the brew version also does some really weird stuff with the
|
||||
# library symbols, which confuses the heck out of `macqtdeploy`. So, using the official
|
||||
# Qt library binaries seems to be the most reliable option for distribution.
|
||||
qt = qt_utils.MacQt(*self.config.get_qt_config())
|
||||
qt.install()
|
||||
|
||||
qt_dir = qt.get_install_dir()
|
||||
qt_bin_dir = os.path.join(qt_dir, "bin")
|
||||
env_vars_set = 0
|
||||
if self.ci_env:
|
||||
github.set_env_var(cmake_prefix_env_var, qt_dir)
|
||||
github.add_to_path(qt_bin_dir)
|
||||
else:
|
||||
env_vars_set += mac.set_env_var(cmake_prefix_env_var, qt_dir)
|
||||
env_vars_set += mac.set_env_var(path_env_var, qt_bin_dir)
|
||||
|
||||
command = self.config.get_os_deps_command()
|
||||
cmd_utils.run(command, shell=True, print_cmd=True)
|
||||
|
||||
if env_vars_set:
|
||||
print(f"To load env vars, run: source {mac.SHELL_RC}")
|
||||
|
||||
def linux(self):
|
||||
"""Installs dependencies on Linux."""
|
||||
import lib.linux as linux
|
||||
|
||||
distro, distro_like, _distro_version = env.get_linux_distro()
|
||||
if not distro:
|
||||
raise RuntimeError("Unable to detect Linux distro")
|
||||
|
||||
command_pre = self.config.get_os_deps_command_pre(
|
||||
linux_distro=distro, required=False
|
||||
)
|
||||
if command_pre:
|
||||
print("Running dependencies prerequisites command")
|
||||
|
||||
check = True
|
||||
if distro == "fedora" or (distro_like and "fedora" in distro_like):
|
||||
print(
|
||||
"Fedora-like detected, "
|
||||
"ignoring return code on dependencies prerequisites command"
|
||||
)
|
||||
# On Fedora-like, dnf update returns code 100 when updates are available.
|
||||
check = False
|
||||
|
||||
linux.run_command(command_pre, check)
|
||||
|
||||
command = self.config.get_os_deps_command(linux_distro=distro)
|
||||
optional = self.config.get_os_deps_value(
|
||||
"optional", linux_distro=distro, required=False
|
||||
)
|
||||
for optional_package in optional or []:
|
||||
if not linux.is_package_available(optional_package):
|
||||
print(f"Optional package not found, stripping: {optional_package}")
|
||||
command = command.replace(optional_package, "")
|
||||
|
||||
linux.run_command(command, check=True)
|
||||
|
||||
subprojects = self.config.get_os_subprojects()
|
||||
if subprojects:
|
||||
for subproject in subprojects:
|
||||
deps = SubprojectDependencies(subproject)
|
||||
deps.install()
|
||||
|
||||
|
||||
class SubprojectDependencies:
|
||||
|
||||
def __init__(self, subproject):
|
||||
from lib.config import Config
|
||||
|
||||
self.subproject = subproject
|
||||
self.config = Config()
|
||||
|
||||
def install(self):
|
||||
"""Installs dependencies for the current platform."""
|
||||
|
||||
print(f"Installing dependencies for sub-project: {self.subproject}")
|
||||
|
||||
if env.is_linux():
|
||||
self.linux()
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported platform: {os}")
|
||||
|
||||
def linux(self):
|
||||
"""Installs dependencies on Linux."""
|
||||
import lib.linux as linux
|
||||
|
||||
command = self.config.get_subproject_deps_command(self.subproject)
|
||||
linux.run_command(command, check=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,78 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
SUDO=$(which sudo > /dev/null 2>&1 && echo "sudo" || echo "")
|
||||
|
||||
install_deps() {
|
||||
uname_out="$(uname -s)"
|
||||
case "${uname_out}" in
|
||||
FreeBSD*) install_freebsd ;;
|
||||
OpenBSD*) install_openbsd ;;
|
||||
NetBSD*) install_netbsd ;;
|
||||
DragonFly*) install_dragonfly ;;
|
||||
SunOS*) install_solaris ;;
|
||||
*) install_other $@ ;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_freebsd() {
|
||||
run_cmd pkg install -y \
|
||||
cmake \
|
||||
ninja \
|
||||
gmake \
|
||||
gcc10 \
|
||||
openssl \
|
||||
glib \
|
||||
gdk-pixbuf2 \
|
||||
libX11 \
|
||||
libXtst \
|
||||
libnotify \
|
||||
libxkbfile \
|
||||
qt6-base \
|
||||
qt6-tools \
|
||||
gtk3 \
|
||||
googletest \
|
||||
pugixml \
|
||||
tomlplusplus \
|
||||
cli11
|
||||
}
|
||||
|
||||
install_openbsd() {
|
||||
# Patches welcome!
|
||||
# pkg_add error:
|
||||
# Can't find libX11
|
||||
# Can't find libXtst
|
||||
echo "Sorry, OpenBSD is not supported yet."
|
||||
}
|
||||
|
||||
install_netbsd() {
|
||||
# Patches welcome!
|
||||
# pkg_add error:
|
||||
# pkg_add: no pkg found for 'libX11', sorry.
|
||||
# pkg_add: no pkg found for 'libXtst', sorry.
|
||||
echo "Sorry, NetBSD is not supported yet."
|
||||
}
|
||||
|
||||
install_dragonfly() {
|
||||
# Patches welcome!
|
||||
# The C++ version on DragonFly BSD seems to be too old.
|
||||
echo "Sorry, DragonFly BSD is not supported yet."
|
||||
}
|
||||
|
||||
install_solaris() {
|
||||
# Patches welcome!
|
||||
echo "Sorry, Solaris is not supported yet."
|
||||
}
|
||||
|
||||
install_other() {
|
||||
# TODO: Port the .py script to shell script to make the deps installation lighter on
|
||||
# Linux and macOS. The .py script is probably only really needed to deal with Windows.
|
||||
./scripts/install_deps.py $@
|
||||
}
|
||||
|
||||
run_cmd() {
|
||||
cmd="${SUDO:+$SUDO }$@"
|
||||
echo "Running: $cmd"
|
||||
$cmd
|
||||
}
|
||||
|
||||
install_deps $@
|
||||
@ -1,129 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import yaml
|
||||
import lib.env as env
|
||||
import lib.cmd_utils as cmd_utils
|
||||
|
||||
config_file = "config.yaml"
|
||||
root_key = "config"
|
||||
deps_key = "dependencies"
|
||||
command_key = "command"
|
||||
command_pre_key = "command-pre"
|
||||
subprojects_key = "subprojects"
|
||||
arrow = " ➤ "
|
||||
|
||||
|
||||
class ConfigKeyError(RuntimeError):
|
||||
def __init__(self, config_file, key):
|
||||
self.config_file = config_file
|
||||
self.key = key
|
||||
|
||||
def __str__(self):
|
||||
return f"Not found in {self.config_file}: {self.key}"
|
||||
|
||||
|
||||
def _get(dict, key, key_parent=None, required=True):
|
||||
value = dict.get(key)
|
||||
|
||||
if required and not value:
|
||||
key_path = f"{root_key}{arrow}{key_parent}{arrow}{key}" if key_parent else key
|
||||
raise ConfigKeyError(config_file, key_path)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class Config:
|
||||
"""Reads the project configuration YAML file."""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
with open(config_file, "r") as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
self.os_name = env.get_os()
|
||||
|
||||
print("Config for OS:", self.os_name)
|
||||
self.root = _get(data, root_key)
|
||||
self.os = _get(self.root, self.os_name)
|
||||
|
||||
def get_os_value(self, key, required=True, linux_distro=None):
|
||||
if linux_distro:
|
||||
# recurse with the linux distro as the key parameter to get the base distro key.
|
||||
distro = self.get_os_value(key=linux_distro)
|
||||
return _get(distro, key, f"{self.os_name}{arrow}{linux_distro}", required)
|
||||
else:
|
||||
return _get(self.os, key, self.os_name, required)
|
||||
|
||||
def get_qt_config(self):
|
||||
qt_key = "qt"
|
||||
qt = self.get_os_deps_value(qt_key)
|
||||
|
||||
parent_key = f"{self.os_name}{arrow}{deps_key}"
|
||||
mirror_url = _get(qt, "mirror", parent_key)
|
||||
version = _get(qt, "version", parent_key)
|
||||
base_dir = _get(qt, "base-dir", parent_key)
|
||||
modules = _get(qt, "modules", parent_key, required=False)
|
||||
|
||||
return mirror_url, version, base_dir, modules
|
||||
|
||||
def get_os_deps_value(self, key, required=True, linux_distro=None):
|
||||
deps = self.get_os_value(deps_key, required, linux_distro)
|
||||
if linux_distro:
|
||||
key_parent = f"{self.os_name}{arrow}{linux_distro}{arrow}{deps_key}"
|
||||
else:
|
||||
key_parent = f"{self.os_name}{arrow}{deps_key}"
|
||||
return _get(deps, key, key_parent, required)
|
||||
|
||||
def get_os_deps_command(self, key=command_key, required=True, linux_distro=None):
|
||||
command = self.get_os_deps_value(key, required, linux_distro)
|
||||
if command:
|
||||
return cmd_utils.strip_continuation_sequences(command)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_os_subprojects(self):
|
||||
distro, _distro_like, _distro_version = env.get_linux_distro()
|
||||
return self.get_os_value(subprojects_key, linux_distro=distro, required=False)
|
||||
|
||||
def get_subproject_deps_command(self, subproject_name):
|
||||
subprojects = _get(self.root, subprojects_key)
|
||||
subproject = _get(subprojects, subproject_name, subprojects_key)
|
||||
deps_parent = f"{subprojects_key}{arrow}{subproject_name}"
|
||||
deps = _get(subproject, deps_key, deps_parent)
|
||||
|
||||
if env.is_linux():
|
||||
distro, _distro_like, _distro_version = env.get_linux_distro()
|
||||
if not distro:
|
||||
raise RuntimeError("Unable to detect Linux distro")
|
||||
|
||||
command = _get(deps, distro, f"{deps_parent}{arrow}{deps_key}")
|
||||
else:
|
||||
command = _get(deps, self.os_name, f"{deps_parent}{arrow}{deps_key}")
|
||||
|
||||
return cmd_utils.strip_continuation_sequences(command)
|
||||
|
||||
def get_os_deps_command_pre(self, required=True, linux_distro=None):
|
||||
return self.get_os_deps_command(command_pre_key, required, linux_distro)
|
||||
|
||||
def get_windows_ci_config(self):
|
||||
choco_ci_key = "ci"
|
||||
choco_ci = self.get_os_deps_value(choco_ci_key)
|
||||
|
||||
choco_ci_path = f"{self.os_name}{arrow}{deps_key}{arrow}{choco_ci_key}"
|
||||
edit_config = _get(choco_ci, "edit-config", choco_ci_path)
|
||||
skip_packages = _get(choco_ci, "skip-packages", choco_ci_path)
|
||||
|
||||
return edit_config, skip_packages
|
||||
@ -1,68 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
|
||||
github_env_key = "GITHUB_ENV"
|
||||
github_path_key = "GITHUB_PATH"
|
||||
github_output_key = "GITHUB_OUTPUT"
|
||||
|
||||
|
||||
def set_env_var(key, value):
|
||||
"""
|
||||
Appends the key=value pair to the GitHub environment file.
|
||||
"""
|
||||
env_file = os.getenv(github_env_key)
|
||||
if not env_file:
|
||||
raise RuntimeError(f"Env var {github_env_key} not set")
|
||||
|
||||
if not os.path.exists(env_file):
|
||||
raise RuntimeError(f"Env file not found: {env_file}")
|
||||
|
||||
print(f"Setting GitHub env var: {key}={value}")
|
||||
with open(env_file, "a") as env_file:
|
||||
env_file.write(f"{key}={value}\n")
|
||||
|
||||
|
||||
def add_to_path(value):
|
||||
"""
|
||||
Appends the value to the GitHub path.
|
||||
"""
|
||||
path_file = os.getenv(github_path_key)
|
||||
if not path_file:
|
||||
raise RuntimeError(f"Env var {github_path_key} not set")
|
||||
|
||||
if not os.path.exists(path_file):
|
||||
raise RuntimeError(f"Path file not found: {path_file}")
|
||||
|
||||
print(f"Adding to GitHub path: {value}")
|
||||
with open(path_file, "a") as path_file:
|
||||
path_file.write(f"{value}\n")
|
||||
|
||||
|
||||
def set_output(name, value):
|
||||
"""
|
||||
Sets the output parameter for the GitHub action.
|
||||
"""
|
||||
output_file = os.getenv(github_output_key)
|
||||
if not output_file:
|
||||
raise RuntimeError(f"Env var {github_output_key} not set")
|
||||
|
||||
if not os.path.exists(output_file):
|
||||
raise RuntimeError(f"Output file not found: {output_file}")
|
||||
|
||||
print(f"Setting GitHub output: {name}={value}")
|
||||
with open(output_file, "a") as output_file:
|
||||
output_file.write(f"{name}={value}\n")
|
||||
@ -1,218 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, shutil, glob, sys
|
||||
import lib.cmd_utils as cmd_utils
|
||||
import lib.env as env
|
||||
from enum import Enum, auto
|
||||
|
||||
BUILD_ROOT_DIR = "build"
|
||||
|
||||
|
||||
class PackageType(Enum):
|
||||
DISTRO = auto()
|
||||
TGZ = auto()
|
||||
|
||||
|
||||
def run_command(command, check=True):
|
||||
|
||||
has_sudo = cmd_utils.has_command("sudo")
|
||||
if "sudo" in command and not has_sudo:
|
||||
# assume we're running as root if sudo is not found (common on older distros).
|
||||
# a space char is intentionally added after "sudo" for intentionality.
|
||||
# possible limitation with stripping "sudo" is that if any packages with "sudo" in the
|
||||
# name are added to the list (probably very unlikely), this will have undefined behavior.
|
||||
print("The 'sudo' command was not found, stripping sudo from command")
|
||||
command = command.replace("sudo ", "").strip()
|
||||
|
||||
cmd_utils.run(command, check, shell=True, print_cmd=True)
|
||||
|
||||
|
||||
def package(
|
||||
filename_base,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
package_name,
|
||||
package_type: PackageType,
|
||||
leave_test_installed=False,
|
||||
):
|
||||
working_dir = BUILD_ROOT_DIR
|
||||
extension, cmd = get_package_build_info(
|
||||
package_type,
|
||||
)
|
||||
run_package_cmd(cmd, working_dir)
|
||||
|
||||
package_filename = get_package_filename(extension, working_dir)
|
||||
target_file = f"{filename_base}.{extension}"
|
||||
target_path = copy_to_dist_dir(package_filename, dist_dir, target_file)
|
||||
|
||||
if package_type == PackageType.DISTRO:
|
||||
test_install(
|
||||
target_path, package_name, test_cmd, remove_test=not leave_test_installed
|
||||
)
|
||||
|
||||
|
||||
def get_package_build_info(package_type: PackageType):
|
||||
|
||||
command = None
|
||||
cpack_generator = None
|
||||
file_extension = None
|
||||
|
||||
if package_type == PackageType.TGZ:
|
||||
cpack_generator = "TGZ"
|
||||
file_extension = "tar.gz"
|
||||
|
||||
elif package_type == PackageType.DISTRO:
|
||||
|
||||
distro, distro_like, _distro_version = env.get_linux_distro()
|
||||
if not distro_like:
|
||||
distro_like = distro
|
||||
|
||||
if "debian" in distro_like:
|
||||
cpack_generator = "DEB"
|
||||
file_extension = "deb"
|
||||
elif "fedora" in distro_like or "opensuse" in distro_like:
|
||||
cpack_generator = "RPM"
|
||||
file_extension = "rpm"
|
||||
elif "arch" in distro_like:
|
||||
command = ["makepkg", "-s"]
|
||||
file_extension = "pkg.tar.zst"
|
||||
else:
|
||||
raise RuntimeError(f"Linux distro not yet supported: {distro}")
|
||||
|
||||
if not cpack_generator and not command:
|
||||
raise RuntimeError("No package generator or command found")
|
||||
|
||||
if cpack_generator:
|
||||
command = ["cpack", "-G", cpack_generator]
|
||||
|
||||
return file_extension, command
|
||||
|
||||
|
||||
def run_package_cmd(command, working_dir):
|
||||
package_user = env.get_env("LINUX_PACKAGE_USER", required=False)
|
||||
if package_user:
|
||||
cmd_utils.run(
|
||||
["sudo", "chown", "-R", package_user, working_dir],
|
||||
check=True,
|
||||
print_cmd=True,
|
||||
)
|
||||
command = ["sudo", "-u", package_user] + command
|
||||
|
||||
cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(working_dir)
|
||||
cmd_utils.run(command, check=True, print_cmd=True)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
def get_package_filename(extension, working_dir):
|
||||
files = glob.glob(f"{working_dir}/*.{extension}")
|
||||
|
||||
if not files:
|
||||
raise ValueError(
|
||||
f"No .{extension} file found in build directory: {working_dir}"
|
||||
)
|
||||
|
||||
return files[0]
|
||||
|
||||
|
||||
def copy_to_dist_dir(source_file, dist_dir, target_file):
|
||||
os.makedirs(dist_dir, exist_ok=True)
|
||||
|
||||
target_path = f"{dist_dir}/{target_file}"
|
||||
print(f"Copying to: {target_path}")
|
||||
shutil.copy(source_file, target_path)
|
||||
|
||||
return target_path
|
||||
|
||||
|
||||
def test_install(package_file, package_name, test_cmd, remove_test=True):
|
||||
|
||||
distro, distro_like, _distro_version = env.get_linux_distro()
|
||||
if not distro_like:
|
||||
distro_like = distro
|
||||
|
||||
install_base = None
|
||||
list_cmd = None
|
||||
remove_base = None
|
||||
if "debian" in distro_like:
|
||||
install_base = ["apt", "install", "-f", "-y"]
|
||||
remove_base = ["apt", "remove", "-y"]
|
||||
list_cmd = ["dpkg", "-L", package_name]
|
||||
elif "fedora" in distro_like:
|
||||
install_base = ["dnf", "install", "-y"]
|
||||
remove_base = ["dnf", "remove", "-y"]
|
||||
list_cmd = ["rpm", "-ql", package_name]
|
||||
elif "opensuse" in distro_like:
|
||||
install_base = ["zypper", "--no-gpg-checks", "install", "-y"]
|
||||
remove_base = ["zypper", "remove", "-y"]
|
||||
list_cmd = ["rpm", "-ql", package_name]
|
||||
elif "arch" in distro_like:
|
||||
install_base = ["pacman", "-U", "--noconfirm"]
|
||||
remove_base = ["pacman", "-R", "--noconfirm"]
|
||||
list_cmd = ["pacman", "-Ql", package_name]
|
||||
else:
|
||||
raise RuntimeError(f"Linux distro not yet supported: {distro}")
|
||||
|
||||
has_sudo = cmd_utils.has_command("sudo")
|
||||
sudo = ["sudo"] if has_sudo else []
|
||||
|
||||
print("Testing installation...")
|
||||
cmd_utils.run(
|
||||
sudo + install_base + [f"./{package_file}"],
|
||||
check=True,
|
||||
print_cmd=True,
|
||||
)
|
||||
|
||||
print("Listing installed files...")
|
||||
cmd_utils.run(sudo + list_cmd, check=True, print_cmd=True)
|
||||
|
||||
try:
|
||||
cmd_utils.run(test_cmd, shell=True, check=True, print_cmd=True)
|
||||
except Exception:
|
||||
raise RuntimeError("Unable to verify version")
|
||||
finally:
|
||||
if remove_test:
|
||||
cmd_utils.run(
|
||||
sudo + remove_base + [package_name], check=True, print_cmd=True
|
||||
)
|
||||
else:
|
||||
print("Leaving test package installed")
|
||||
|
||||
print("Installation test passed")
|
||||
|
||||
|
||||
def is_package_available(package):
|
||||
distro, distro_like, _distro_version = env.get_linux_distro()
|
||||
if not distro_like:
|
||||
distro_like = distro
|
||||
|
||||
if "debian" in distro_like:
|
||||
command = ["apt-cache", "show", package]
|
||||
elif "fedora" in distro_like:
|
||||
command = ["dnf", "info", package]
|
||||
elif "opensuse" in distro_like:
|
||||
command = ["zypper", "info", package]
|
||||
elif "arch" in distro_like:
|
||||
command = ["pacman", "-Si", package]
|
||||
else:
|
||||
raise RuntimeError(f"Linux distro not yet supported: {distro}")
|
||||
|
||||
result = cmd_utils.run(command, check=False, print_cmd=True, get_output=True)
|
||||
if result.stderr:
|
||||
print(result.stderr, file=sys.stderr)
|
||||
return result.returncode == 0
|
||||
@ -1,91 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, sys
|
||||
import lib.cmd_utils as cmd_utils
|
||||
import lib.env as env
|
||||
|
||||
build_dir = "build/meson"
|
||||
|
||||
|
||||
def meson_venv_bin():
|
||||
if not env.in_venv():
|
||||
raise RuntimeError("Not in a virtual environment")
|
||||
|
||||
return os.path.join(os.path.dirname(sys.executable), "meson")
|
||||
|
||||
|
||||
def setup(no_system_list, static_list):
|
||||
cmd = [meson_venv_bin(), "setup", build_dir]
|
||||
|
||||
# TODO: These special Windows exceptions should probably be in Meson
|
||||
# or somewhere other than this script, as it's a bit hacky.
|
||||
if env.is_windows():
|
||||
cmd.append("-Dsystem-gtest=false")
|
||||
cmd.append("-Dsystem-tomlplusplus=false")
|
||||
cmd.append("-Dsystem-cli11=false")
|
||||
|
||||
for subproject in no_system_list or []:
|
||||
cmd.append(f"-Dsystem-{subproject}=false")
|
||||
|
||||
# This might be a bit rude, but Meson seems to cache a lot (like CMake),
|
||||
# so wiping every time is the easiest way to ensure that the build is clean.
|
||||
# Plus, the way we're using Meson (at the moment) is just for satisfying
|
||||
# dependencies, so this script is run infrequently enough to not matter.
|
||||
if os.path.exists(build_dir):
|
||||
cmd.append("--wipe")
|
||||
|
||||
cmd_utils.run(cmd, print_cmd=True)
|
||||
|
||||
for subproject in static_list or []:
|
||||
static_subproject(subproject)
|
||||
|
||||
|
||||
def static_subproject(subproject):
|
||||
if subproject == "libportal":
|
||||
# HACK: This is a bit horrible. Ideally, Meson would take care of applying this patch,
|
||||
# but it only seems to copy the .diff over and not apply the patch.
|
||||
#
|
||||
# Important: Static linking is not intended for package maintainers, only for beta testers.
|
||||
# Static linking is also pretty horrible, but many distros will be slow to pick up 0.8.x
|
||||
# which has input capture support. The sooner we can remove this patching code the better.
|
||||
cmd_utils.run(
|
||||
[
|
||||
"patch",
|
||||
"-d",
|
||||
"subprojects/libportal",
|
||||
"-p1",
|
||||
"-i",
|
||||
"static-lib.diff",
|
||||
],
|
||||
print_cmd=True,
|
||||
check=False,
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(f"Unknown subproject: {subproject}")
|
||||
|
||||
|
||||
def compile():
|
||||
cmd_utils.run([meson_venv_bin(), "compile", "-C", build_dir], print_cmd=True)
|
||||
|
||||
|
||||
def install():
|
||||
cmd = [meson_venv_bin(), "install", "-C", build_dir]
|
||||
|
||||
has_sudo = cmd_utils.has_command("sudo")
|
||||
if has_sudo:
|
||||
cmd.insert(0, "sudo")
|
||||
|
||||
cmd_utils.run(cmd, print_cmd=True)
|
||||
@ -1,88 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, sys
|
||||
import lib.cmd_utils as cmd_utils
|
||||
import glob
|
||||
|
||||
|
||||
class Qt:
|
||||
def __init__(
|
||||
self, mirror_url, version, base_dir, modules, os_name, compiler, tool_dir
|
||||
):
|
||||
self.mirror_url = mirror_url
|
||||
self.version = version
|
||||
self.base_dir = base_dir
|
||||
self.modules = modules
|
||||
self.os_name = os_name
|
||||
self.compiler = compiler
|
||||
self.tool_dir = tool_dir
|
||||
self.dir_pattern = f"{self.base_dir}{os.sep}{self.version}*/{self.tool_dir}"
|
||||
|
||||
def get_install_dir(self):
|
||||
match = glob.glob(self.dir_pattern)
|
||||
return os.path.abspath(match[0]) if match else None
|
||||
|
||||
def install(self):
|
||||
"""Install Qt."""
|
||||
|
||||
if self.get_install_dir():
|
||||
print(f"Skipping Qt, already installed at: {self.dir_pattern}")
|
||||
return
|
||||
|
||||
args = [sys.executable, "-m", "aqt", "install-qt"]
|
||||
args.extend(["--outputdir", self.base_dir])
|
||||
args.extend(["--base", self.mirror_url])
|
||||
args.extend([self.os_name, "desktop", str(self.version), self.compiler])
|
||||
|
||||
if self.modules:
|
||||
args.extend(["-m"] + self.modules)
|
||||
|
||||
print(args)
|
||||
cmd_utils.run(
|
||||
args,
|
||||
print_cmd=True,
|
||||
)
|
||||
|
||||
if not self.get_install_dir():
|
||||
raise RuntimeError(
|
||||
f"Qt was not installed, path not found: {self.dir_pattern}"
|
||||
)
|
||||
|
||||
|
||||
class WindowsQt(Qt):
|
||||
def __init__(self, mirror_url, version, base_dir, modules):
|
||||
super().__init__(
|
||||
mirror_url,
|
||||
version,
|
||||
base_dir,
|
||||
modules,
|
||||
"windows",
|
||||
"win64_msvc2019_64",
|
||||
"msvc2019_64",
|
||||
)
|
||||
|
||||
|
||||
class MacQt(Qt):
|
||||
def __init__(self, mirror_url, version, base_dir, modules):
|
||||
super().__init__(
|
||||
mirror_url,
|
||||
version,
|
||||
base_dir,
|
||||
modules,
|
||||
"mac",
|
||||
"clang_64",
|
||||
"macos",
|
||||
)
|
||||
@ -1,65 +0,0 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import git # type: ignore
|
||||
import lib.env as env
|
||||
import lib.cmd_utils as cmd_utils
|
||||
|
||||
GIT_REPO = "https://github.com/microsoft/vcpkg.git"
|
||||
|
||||
|
||||
def install(ci_env):
|
||||
vcpkg_bin = ensure_vcpkg(ci_env)
|
||||
|
||||
cmd_utils.run([vcpkg_bin, "install"], print_cmd=True)
|
||||
|
||||
|
||||
def ensure_vcpkg(ci_env):
|
||||
# Don't use the local vcpkg if we're in CI, since this makes caching complicated.
|
||||
if not ci_env and cmd_utils.has_command("vcpkg"):
|
||||
print("Using system vcpkg")
|
||||
return "vcpkg"
|
||||
|
||||
if not os.path.exists("vcpkg"):
|
||||
get_vcpkg()
|
||||
else:
|
||||
print("Updating vcpkg...")
|
||||
repo = git.Repo("vcpkg")
|
||||
repo.remotes.origin.pull()
|
||||
|
||||
if env.is_windows():
|
||||
vcpkg_bin = "vcpkg/vcpkg.exe"
|
||||
else:
|
||||
vcpkg_bin = "vcpkg/vcpkg"
|
||||
|
||||
if not os.path.exists(vcpkg_bin):
|
||||
raise RuntimeError(f"Path not found: {vcpkg_bin}")
|
||||
|
||||
return vcpkg_bin
|
||||
|
||||
|
||||
def get_vcpkg():
|
||||
print("Downloading vcpkg...")
|
||||
git.Repo.clone_from(GIT_REPO, "vcpkg")
|
||||
|
||||
os.chdir("vcpkg")
|
||||
try:
|
||||
if env.is_windows():
|
||||
cmd_utils.run("bootstrap-vcpkg.bat", shell=True, print_cmd=True)
|
||||
else:
|
||||
cmd_utils.run("./bootstrap-vcpkg.sh", shell=True, print_cmd=True)
|
||||
finally:
|
||||
os.chdir("..")
|
||||
@ -196,36 +196,6 @@ class WindowsPackager:
|
||||
run_codesign(path, cert_base64, cert_password)
|
||||
|
||||
|
||||
class WindowsChoco:
|
||||
"""Chocolatey for Windows."""
|
||||
|
||||
def ensure_choco_installed(self):
|
||||
if cmd_utils.has_command("choco"):
|
||||
return
|
||||
|
||||
if not cmd_utils.has_command("winget"):
|
||||
print(
|
||||
"The winget command was not found, please install Chocolatey manually",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
print("The choco command was not found, installing Chocolatey...")
|
||||
cmd_utils.run(
|
||||
"winget install chocolatey",
|
||||
check=False,
|
||||
shell=True,
|
||||
print_cmd=True,
|
||||
)
|
||||
|
||||
if not cmd_utils.has_command("choco"):
|
||||
print(
|
||||
"The choco command was still not found, please re-run this script...",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class WindowsService:
|
||||
def __init__(self, script, args):
|
||||
self.script = script
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import lib.env as env
|
||||
|
||||
env.ensure_in_venv(__file__)
|
||||
|
||||
import sys, argparse
|
||||
import lib.fs as fs
|
||||
from cmakelang.format.__main__ import main as cmake_format_main # type: ignore
|
||||
|
||||
INCLUDE_FILES = [
|
||||
"*.cmake",
|
||||
"CMakeLists.txt",
|
||||
]
|
||||
|
||||
EXCLUDE_DIRS = [
|
||||
"build",
|
||||
".venv",
|
||||
"deps",
|
||||
"subprojects",
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Cross-platform equivalent of using find and xargs with cmake-format.
|
||||
Lints by performing a dry run (--check) which fails when formatting is needed.
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--format",
|
||||
action="store_true",
|
||||
help="In-place format all files",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
cmd_args = ["--in-place"] if args.format else ["--check"]
|
||||
files_recursive = fs.find_files(".", INCLUDE_FILES, EXCLUDE_DIRS)
|
||||
|
||||
if args.format:
|
||||
print("Formatting files with CMake formatter:")
|
||||
else:
|
||||
print("Checking files with CMake formatter:")
|
||||
|
||||
for file in files_recursive:
|
||||
print(file)
|
||||
|
||||
if files_recursive:
|
||||
sys.argv = [""] + cmd_args + files_recursive
|
||||
|
||||
result = cmake_format_main()
|
||||
if result == 0:
|
||||
print("CMake lint passed")
|
||||
|
||||
sys.exit(result)
|
||||
else:
|
||||
print("No CMake files found to process.", file=sys.stderr)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -21,7 +21,6 @@ env.ensure_in_venv(__file__)
|
||||
|
||||
import argparse
|
||||
import platform
|
||||
from lib.linux import PackageType
|
||||
from dotenv import load_dotenv # type: ignore
|
||||
|
||||
ENV_FILE = ".env"
|
||||
@ -29,13 +28,15 @@ DEFAULT_PRODUCT_NAME = "Deskflow"
|
||||
DEFAULT_FILENAME_BASE = "deskflow"
|
||||
DEFAULT_PROJECT_BUILD_DIR = "build"
|
||||
DEFAULT_DIST_DIR = "dist"
|
||||
DEFAULT_TEST_CMD = "deskflow-server --version"
|
||||
DEFAULT_PACKAGE_NAME = "deskflow"
|
||||
VERSION_FILE = "VERSION"
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--package-version",
|
||||
help="Set the Package Version",
|
||||
required=True)
|
||||
parser.add_argument(
|
||||
"--leave-test-installed",
|
||||
action="store_true",
|
||||
@ -47,38 +48,19 @@ def main():
|
||||
|
||||
package(
|
||||
DEFAULT_FILENAME_BASE,
|
||||
get_app_version(VERSION_FILE),
|
||||
DEFAULT_PROJECT_BUILD_DIR,
|
||||
DEFAULT_DIST_DIR,
|
||||
DEFAULT_TEST_CMD,
|
||||
DEFAULT_PRODUCT_NAME,
|
||||
DEFAULT_PACKAGE_NAME,
|
||||
leave_test_installed=args.leave_test_installed,
|
||||
version=args.package_version,
|
||||
)
|
||||
|
||||
|
||||
def get_app_version(filename):
|
||||
"""
|
||||
Returns the version either from the env var, or from the version file.
|
||||
"""
|
||||
version = env.get_env("DESKFLOW_VERSION", required=False)
|
||||
if version:
|
||||
return version
|
||||
|
||||
with open(filename, "r") as f:
|
||||
return f.read().strip()
|
||||
|
||||
|
||||
def package(
|
||||
filename_prefix,
|
||||
version,
|
||||
project_build_dir,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
product_name,
|
||||
package_name,
|
||||
version,
|
||||
source_dir=None,
|
||||
leave_test_installed=False,
|
||||
):
|
||||
filename_base = get_filename_base(version, filename_prefix)
|
||||
print(f"Package filename base: {filename_base}")
|
||||
@ -89,50 +71,27 @@ def package(
|
||||
mac_package(
|
||||
filename_base, source_dir, project_build_dir, dist_dir, product_name
|
||||
)
|
||||
elif env.is_linux():
|
||||
linux_package(
|
||||
filename_base,
|
||||
filename_prefix,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
package_name,
|
||||
version,
|
||||
leave_test_installed,
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported platform: {env.get_os()}")
|
||||
|
||||
|
||||
def get_filename_base(version, prefix, use_linux_distro=True):
|
||||
def get_filename_base(version, prefix):
|
||||
os = env.get_os()
|
||||
machine = platform.machine().lower()
|
||||
os_part = os
|
||||
|
||||
if os == "linux" and use_linux_distro:
|
||||
distro_name, _distro_like, distro_version = env.get_linux_distro()
|
||||
if not distro_name:
|
||||
raise RuntimeError("Failed to detect Linux distro")
|
||||
|
||||
if distro_version:
|
||||
version_for_filename = distro_version.replace(".", "-")
|
||||
os_part = f"{distro_name}-{version_for_filename}"
|
||||
else:
|
||||
os_part = distro_name
|
||||
|
||||
# For consistency with existing filenames, we'll use 'amd64' instead of 'x86_64'.
|
||||
# Also, that's what Linux distros tend to call that architecture anyway.
|
||||
if machine == "x86_64":
|
||||
machine = "amd64"
|
||||
else:
|
||||
if os == "windows":
|
||||
# Some Windows users get confused by 'amd64' and think it's 'arm64',
|
||||
# so we'll use Intel's 'x64' branding (even though it's wrong).
|
||||
# Also replace 'x86_64' with 'x64' for consistency.
|
||||
os_part= "win"
|
||||
if machine == "amd64" or machine == "x86_64":
|
||||
machine = "x64"
|
||||
elif os == "mac":
|
||||
os_part = "macos"
|
||||
# Add '-' between our name parts we do not want spaces in the filename
|
||||
return f"{prefix}-{version}-{os_part}-{machine}"
|
||||
|
||||
# Underscore is used to delimit different parts of the filename (e.g. version, OS, etc).
|
||||
# Dashes are used to delimit spaces, e.g. "debian-trixie" for "Debian Trixie".
|
||||
return f"{prefix}_{version}_{os_part}_{machine}"
|
||||
|
||||
|
||||
def windows_package(filename_base, project_build_dir, dist_dir):
|
||||
@ -146,41 +105,5 @@ def mac_package(filename_base, source_dir, project_build_dir, dist_dir, product_
|
||||
|
||||
mac.package(filename_base, source_dir, project_build_dir, dist_dir, product_name)
|
||||
|
||||
|
||||
def linux_package(
|
||||
filename_base,
|
||||
filename_prefix,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
package_name,
|
||||
version,
|
||||
leave_test_installed,
|
||||
):
|
||||
import lib.linux as linux
|
||||
|
||||
extra_packages = env.get_env_bool("LINUX_EXTRA_PACKAGES", False)
|
||||
|
||||
linux.package(
|
||||
filename_base,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
package_name,
|
||||
PackageType.DISTRO,
|
||||
leave_test_installed,
|
||||
)
|
||||
|
||||
if extra_packages:
|
||||
filename_base = get_filename_base(
|
||||
version, filename_base, use_linux_distro=False
|
||||
)
|
||||
linux.package(
|
||||
filename_prefix,
|
||||
dist_dir,
|
||||
test_cmd,
|
||||
package_name,
|
||||
PackageType.TGZ,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@ -4,13 +4,11 @@ version = "0.0.1"
|
||||
description = "Scripts to assist with development of Deskflow"
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"cmake_format",
|
||||
"clang-format",
|
||||
"python-dotenv",
|
||||
"pyyaml",
|
||||
"dmgbuild; sys_platform == 'darwin'",
|
||||
"aqtinstall; sys_platform == 'win32' or sys_platform == 'darwin'",
|
||||
"colorama",
|
||||
"meson",
|
||||
"gitpython",
|
||||
"psutil",
|
||||
]
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import lib.env as env
|
||||
|
||||
env.ensure_in_venv(__file__)
|
||||
|
||||
import argparse, os, sys
|
||||
import lib.cmd_utils as cmd_utils
|
||||
import lib.colors as colors
|
||||
|
||||
valgrind_bin = "valgrind"
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--unit-tests", action="store_true")
|
||||
parser.add_argument("--integ-tests", action="store_true")
|
||||
parser.add_argument(
|
||||
"--filter-file",
|
||||
type=str,
|
||||
help="Takes the base filename without extension and uses it as a filter",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-return-code",
|
||||
action="store_true",
|
||||
help="Ignore the return code of the test command",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--valgrind",
|
||||
action="store_true",
|
||||
help="Run the test command with valgrind",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
binary = get_binary_path(args)
|
||||
|
||||
if args.filter_file:
|
||||
file_base = os.path.basename(args.filter_file)
|
||||
without_ext = os.path.splitext(file_base)[0]
|
||||
command = [binary, f"--gtest_filter={without_ext}*"]
|
||||
else:
|
||||
command = [binary]
|
||||
|
||||
if args.valgrind:
|
||||
if not cmd_utils.has_command(valgrind_bin):
|
||||
print(f"{colors.ERROR_TEXT} {valgrind_bin} not found")
|
||||
sys.exit(1)
|
||||
|
||||
command = [valgrind_bin] + command
|
||||
|
||||
result = cmd_utils.run(command, print_cmd=True, check=False)
|
||||
if not args.ignore_return_code:
|
||||
sys.exit(result.returncode)
|
||||
|
||||
|
||||
def get_binary_path(args):
|
||||
base_dir = "./build/bin"
|
||||
if args.unit_tests:
|
||||
return f"{base_dir}/unittests"
|
||||
elif args.integ_tests:
|
||||
return f"{base_dir}/integtests"
|
||||
else:
|
||||
raise RuntimeError("No test type specified")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -3,7 +3,7 @@ sonar.projectKey=deskflow_deskflow
|
||||
sonar.sources=scripts,src/cmd,src/gui,src/lib
|
||||
sonar.tests=src/test
|
||||
sonar.exclusions=subprojects/**,build/**
|
||||
sonar.coverage.exclusions=subprojects/**,scripts/**,src/test/**
|
||||
sonar.coverage.exclusions=subprojects/**,scripts/**,src/test/**,src/gui/**
|
||||
sonar.cpd.exclusions=**/*Test*.cpp
|
||||
sonar.host.url=https://sonarcloud.io
|
||||
sonar.coverageReportPaths=${{ steps.coverage-paths.outputs.csv }}
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(deskflowd)
|
||||
|
||||
if(BUILD_UNIFIED)
|
||||
add_subdirectory(deskflow-core)
|
||||
@ -23,4 +22,5 @@ else()
|
||||
add_subdirectory(deskflows)
|
||||
endif(BUILD_UNIFIED)
|
||||
|
||||
add_subdirectory(deskflow-legacy)
|
||||
## Only used on windows
|
||||
add_subdirectory(deskflowd)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
# Deskflow -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# Copyright (C) 2012-2024 Symless Ltd.
|
||||
# Copyright (C) 2009-2012 Nick Bolton
|
||||
#
|
||||
@ -15,14 +16,15 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(target ${CORE_BINARY_NAME})
|
||||
set(sources ${target}.cpp)
|
||||
|
||||
add_executable(${target} "${target}.cpp")
|
||||
if(WIN32)
|
||||
list(APPEND sources ${target}.exe.manifest
|
||||
${PROJECT_BINARY_DIR}/src/version.rc)
|
||||
target_sources(${target} PRIVATE
|
||||
"${target}.exe.manifest"
|
||||
"${PROJECT_BINARY_DIR}/src/version.rc"
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(${target} ${sources})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
arch
|
||||
|
||||
@ -26,27 +26,26 @@
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#endif
|
||||
|
||||
void showHelp() {
|
||||
std::cout << "Usage: " CORE_BINARY_NAME " <server | client> [...options]"
|
||||
<< std::endl;
|
||||
std::cout << "server - start as a server (" << SERVER_BINARY_NAME << ")"
|
||||
<< std::endl;
|
||||
std::cout << "client - start as a client (" << CLIENT_BINARY_NAME << ")"
|
||||
<< std::endl;
|
||||
std::cout << "use " CORE_BINARY_NAME
|
||||
" <server|client> --help for more information."
|
||||
<< std::endl;
|
||||
void showHelp()
|
||||
{
|
||||
std::cout << "Usage: " CORE_BINARY_NAME " <server | client> [...options]" << std::endl;
|
||||
std::cout << "server - start as a server (" << SERVER_BINARY_NAME << ")" << std::endl;
|
||||
std::cout << "client - start as a client (" << CLIENT_BINARY_NAME << ")" << std::endl;
|
||||
std::cout << "use " CORE_BINARY_NAME " <server|client> --help for more information." << std::endl;
|
||||
}
|
||||
|
||||
bool isServer(int argc, char **argv) {
|
||||
bool isServer(int argc, char **argv)
|
||||
{
|
||||
return (argc > 1 && argv[1] == std::string("server"));
|
||||
}
|
||||
|
||||
bool isClient(int argc, char **argv) {
|
||||
bool isClient(int argc, char **argv)
|
||||
{
|
||||
return (argc > 1 && argv[1] == std::string("client"));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
||||
#endif
|
||||
|
||||
@ -1,45 +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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(target ${LEGACY_BINARY_NAME})
|
||||
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND sources ${PROJECT_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
add_executable(${target} ${sources})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
app
|
||||
arch
|
||||
base
|
||||
client
|
||||
io
|
||||
ipc
|
||||
mt
|
||||
net
|
||||
platform
|
||||
server
|
||||
${libs})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
install(TARGETS ${target} DESTINATION ${DESKFLOW_BUNDLE_BINARY_DIR})
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
endif()
|
||||
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "deskflow/ToolApp.h"
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#if SYSAPI_WIN32
|
||||
// record window instance for tray icon, etc
|
||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
||||
#endif
|
||||
|
||||
ToolApp app;
|
||||
return app.run(argc, argv);
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
# Deskflow -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2024 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# Copyright (C) 2012-2024 Symless Ltd.
|
||||
# Copyright (C) 2009-2012 Nick Bolton
|
||||
#
|
||||
@ -16,39 +17,35 @@
|
||||
|
||||
set(client_source_name "deskflowc")
|
||||
set(target ${CLIENT_BINARY_NAME})
|
||||
set(sources ${client_source_name}.cpp)
|
||||
|
||||
if(WIN32)
|
||||
file(GLOB arch_headers "MSWindows*.h")
|
||||
file(GLOB arch_sources "MSWindows*.cpp")
|
||||
list(
|
||||
APPEND
|
||||
sources
|
||||
resource.h
|
||||
set(PLATFORM_SOURCES
|
||||
${client_source_name}.exe.manifest
|
||||
${client_source_name}.ico
|
||||
${client_source_name}.rc
|
||||
MSWindowsClientTaskBarReceiver.cpp
|
||||
MSWindowsClientTaskBarReceiver.h
|
||||
resource.h
|
||||
tb_error.ico
|
||||
tb_idle.ico
|
||||
tb_run.ico
|
||||
tb_wait.ico
|
||||
${client_source_name}.exe.manifest
|
||||
${PROJECT_BINARY_DIR}/src/version.rc)
|
||||
${PROJECT_BINARY_DIR}/src/version.rc
|
||||
)
|
||||
elseif(APPLE)
|
||||
file(GLOB arch_headers "OSX*.h")
|
||||
file(GLOB arch_sources "OSX*.cpp")
|
||||
set(PLATFORM_SOURCES
|
||||
OSXClientTaskBarReceiver.cpp
|
||||
OSXClientTaskBarReceiver.h
|
||||
)
|
||||
elseif(UNIX)
|
||||
file(GLOB arch_headers "XWindows*.h")
|
||||
file(GLOB arch_sources "XWindows*.cpp")
|
||||
set(PLATFORM_SOURCES
|
||||
XWindowsClientTaskBarReceiver.cpp
|
||||
XWindowsClientTaskBarReceiver.h
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${arch_sources})
|
||||
list(APPEND headers ${arch_headers})
|
||||
add_executable(${target} ${PLATFORM_SOURCES} "${client_source_name}.cpp")
|
||||
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
add_executable(${target} ${sources})
|
||||
target_link_libraries(
|
||||
${target}
|
||||
arch
|
||||
|
||||
@ -34,16 +34,18 @@
|
||||
//
|
||||
|
||||
const UINT MSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] = {
|
||||
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED,
|
||||
IDI_TASKBAR_NOT_CONNECTED, IDI_TASKBAR_CONNECTED};
|
||||
IDI_TASKBAR_NOT_RUNNING, IDI_TASKBAR_NOT_WORKING, IDI_TASKBAR_NOT_CONNECTED, IDI_TASKBAR_NOT_CONNECTED,
|
||||
IDI_TASKBAR_CONNECTED
|
||||
};
|
||||
|
||||
MSWindowsClientTaskBarReceiver::MSWindowsClientTaskBarReceiver(
|
||||
HINSTANCE appInstance, const BufferedLogOutputter *logBuffer,
|
||||
IEventQueue *events)
|
||||
HINSTANCE appInstance, const BufferedLogOutputter *logBuffer, IEventQueue *events
|
||||
)
|
||||
: ClientTaskBarReceiver(events),
|
||||
m_appInstance(appInstance),
|
||||
m_window(NULL),
|
||||
m_logBuffer(logBuffer) {
|
||||
m_logBuffer(logBuffer)
|
||||
{
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
m_icon[i] = loadIcon(s_stateToIconID[i]);
|
||||
}
|
||||
@ -58,9 +60,13 @@ MSWindowsClientTaskBarReceiver::MSWindowsClientTaskBarReceiver(
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
MSWindowsClientTaskBarReceiver::~MSWindowsClientTaskBarReceiver() { cleanup(); }
|
||||
MSWindowsClientTaskBarReceiver::~MSWindowsClientTaskBarReceiver()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::cleanup() {
|
||||
void MSWindowsClientTaskBarReceiver::cleanup()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
deleteIcon(m_icon[i]);
|
||||
@ -69,7 +75,8 @@ void MSWindowsClientTaskBarReceiver::cleanup() {
|
||||
destroyWindow();
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::showStatus() {
|
||||
void MSWindowsClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// create the window
|
||||
createWindow();
|
||||
|
||||
@ -126,7 +133,8 @@ void MSWindowsClientTaskBarReceiver::showStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::runMenu(int x, int y) {
|
||||
void MSWindowsClientTaskBarReceiver::runMenu(int x, int y)
|
||||
{
|
||||
// do popup menu. we need a window to pass to TrackPopupMenu().
|
||||
// the SetForegroundWindow() and SendMessage() calls around
|
||||
// TrackPopupMenu() are to get the menu to be dismissed when
|
||||
@ -137,11 +145,9 @@ void MSWindowsClientTaskBarReceiver::runMenu(int x, int y) {
|
||||
HMENU menu = GetSubMenu(m_menu, 0);
|
||||
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
|
||||
HMENU logLevelMenu = GetSubMenu(menu, 3);
|
||||
CheckMenuRadioItem(
|
||||
logLevelMenu, 0, 6, CLOG->getFilter() - kERROR, MF_BYPOSITION);
|
||||
int n = TrackPopupMenu(
|
||||
menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x,
|
||||
y, 0, m_window, NULL);
|
||||
CheckMenuRadioItem(logLevelMenu, 0, 6, CLOG->getFilter() - kERROR, MF_BYPOSITION);
|
||||
int n =
|
||||
TrackPopupMenu(menu, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, 0, m_window, NULL);
|
||||
SendMessage(m_window, WM_NULL, 0, 0);
|
||||
|
||||
// perform the requested operation
|
||||
@ -192,19 +198,22 @@ void MSWindowsClientTaskBarReceiver::runMenu(int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::primaryAction() { showStatus(); }
|
||||
void MSWindowsClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
showStatus();
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
MSWindowsClientTaskBarReceiver::getIcon() const {
|
||||
const IArchTaskBarReceiver::Icon MSWindowsClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return static_cast<Icon>(m_icon[getStatus()]);
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::copyLog() const {
|
||||
void MSWindowsClientTaskBarReceiver::copyLog() const
|
||||
{
|
||||
if (m_logBuffer != NULL) {
|
||||
// collect log buffer
|
||||
String data;
|
||||
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin();
|
||||
index != m_logBuffer->end(); ++index) {
|
||||
for (BufferedLogOutputter::const_iterator index = m_logBuffer->begin(); index != m_logBuffer->end(); ++index) {
|
||||
data += *index;
|
||||
data += "\n";
|
||||
}
|
||||
@ -220,26 +229,29 @@ void MSWindowsClientTaskBarReceiver::copyLog() const {
|
||||
}
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::onStatusChanged() {
|
||||
void MSWindowsClientTaskBarReceiver::onStatusChanged()
|
||||
{
|
||||
if (IsWindowVisible(m_window)) {
|
||||
showStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HICON
|
||||
MSWindowsClientTaskBarReceiver::loadIcon(UINT id) {
|
||||
HANDLE icon = LoadImage(
|
||||
m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
MSWindowsClientTaskBarReceiver::loadIcon(UINT id)
|
||||
{
|
||||
HANDLE icon = LoadImage(m_appInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
return static_cast<HICON>(icon);
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::deleteIcon(HICON icon) {
|
||||
void MSWindowsClientTaskBarReceiver::deleteIcon(HICON icon)
|
||||
{
|
||||
if (icon != NULL) {
|
||||
DestroyIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::createWindow() {
|
||||
void MSWindowsClientTaskBarReceiver::createWindow()
|
||||
{
|
||||
// ignore if already created
|
||||
if (m_window != NULL) {
|
||||
return;
|
||||
@ -247,9 +259,9 @@ void MSWindowsClientTaskBarReceiver::createWindow() {
|
||||
|
||||
// get the status dialog
|
||||
m_window = CreateDialogParam(
|
||||
m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL,
|
||||
(DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc,
|
||||
reinterpret_cast<LPARAM>(static_cast<void *>(this)));
|
||||
m_appInstance, MAKEINTRESOURCE(IDD_TASKBAR_STATUS), NULL, (DLGPROC)&MSWindowsClientTaskBarReceiver::staticDlgProc,
|
||||
reinterpret_cast<LPARAM>(static_cast<void *>(this))
|
||||
);
|
||||
|
||||
// window should appear on top of everything, including (especially)
|
||||
// the task bar.
|
||||
@ -261,7 +273,8 @@ void MSWindowsClientTaskBarReceiver::createWindow() {
|
||||
ArchTaskBarWindows::addDialog(m_window);
|
||||
}
|
||||
|
||||
void MSWindowsClientTaskBarReceiver::destroyWindow() {
|
||||
void MSWindowsClientTaskBarReceiver::destroyWindow()
|
||||
{
|
||||
if (m_window != NULL) {
|
||||
ArchTaskBarWindows::removeDialog(m_window);
|
||||
DestroyWindow(m_window);
|
||||
@ -269,8 +282,8 @@ void MSWindowsClientTaskBarReceiver::destroyWindow() {
|
||||
}
|
||||
}
|
||||
|
||||
BOOL MSWindowsClientTaskBarReceiver::dlgProc(
|
||||
HWND hwnd, UINT msg, WPARAM wParam, LPARAM) {
|
||||
BOOL MSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
// use default focus
|
||||
@ -286,14 +299,13 @@ BOOL MSWindowsClientTaskBarReceiver::dlgProc(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK MSWindowsClientTaskBarReceiver::staticDlgProc(
|
||||
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
BOOL CALLBACK MSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// if msg is WM_INITDIALOG, extract the MSWindowsClientTaskBarReceiver*
|
||||
// and put it in the extra window data then forward the call.
|
||||
MSWindowsClientTaskBarReceiver *self = NULL;
|
||||
if (msg == WM_INITDIALOG) {
|
||||
self = static_cast<MSWindowsClientTaskBarReceiver *>(
|
||||
reinterpret_cast<void *>(lParam));
|
||||
self = static_cast<MSWindowsClientTaskBarReceiver *>(reinterpret_cast<void *>(lParam));
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam);
|
||||
} else {
|
||||
// get the extra window data and forward the call
|
||||
@ -311,16 +323,12 @@ BOOL CALLBACK MSWindowsClientTaskBarReceiver::staticDlgProc(
|
||||
}
|
||||
}
|
||||
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(
|
||||
const BufferedLogOutputter *logBuffer, IEventQueue *events) {
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
|
||||
{
|
||||
ArchMiscWindows::setIcons(
|
||||
(HICON)LoadImage(
|
||||
ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW),
|
||||
IMAGE_ICON, 32, 32, LR_SHARED),
|
||||
(HICON)LoadImage(
|
||||
ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW),
|
||||
IMAGE_ICON, 16, 16, LR_SHARED));
|
||||
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 32, 32, LR_SHARED),
|
||||
(HICON)LoadImage(ArchMiscWindows::instanceWin32(), MAKEINTRESOURCE(IDI_DESKFLOW), IMAGE_ICON, 16, 16, LR_SHARED)
|
||||
);
|
||||
|
||||
return new MSWindowsClientTaskBarReceiver(
|
||||
MSWindowsScreen::getWindowInstance(), logBuffer, events);
|
||||
return new MSWindowsClientTaskBarReceiver(MSWindowsScreen::getWindowInstance(), logBuffer, events);
|
||||
}
|
||||
|
||||
@ -27,10 +27,10 @@ class BufferedLogOutputter;
|
||||
class IEventQueue;
|
||||
|
||||
//! Implementation of ClientTaskBarReceiver for Microsoft Windows
|
||||
class MSWindowsClientTaskBarReceiver : public ClientTaskBarReceiver {
|
||||
class MSWindowsClientTaskBarReceiver : public ClientTaskBarReceiver
|
||||
{
|
||||
public:
|
||||
MSWindowsClientTaskBarReceiver(
|
||||
HINSTANCE, const BufferedLogOutputter *, IEventQueue *events);
|
||||
MSWindowsClientTaskBarReceiver(HINSTANCE, const BufferedLogOutputter *, IEventQueue *events);
|
||||
virtual ~MSWindowsClientTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
@ -53,8 +53,7 @@ private:
|
||||
void destroyWindow();
|
||||
|
||||
BOOL dlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static BOOL CALLBACK
|
||||
staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static BOOL CALLBACK staticDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
HINSTANCE m_appInstance;
|
||||
|
||||
@ -23,34 +23,39 @@
|
||||
// OSXClientTaskBarReceiver
|
||||
//
|
||||
|
||||
OSXClientTaskBarReceiver::OSXClientTaskBarReceiver(
|
||||
const BufferedLogOutputter *, IEventQueue *events)
|
||||
: ClientTaskBarReceiver(events) {
|
||||
OSXClientTaskBarReceiver::OSXClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
|
||||
: ClientTaskBarReceiver(events)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
OSXClientTaskBarReceiver::~OSXClientTaskBarReceiver() {
|
||||
OSXClientTaskBarReceiver::~OSXClientTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void OSXClientTaskBarReceiver::showStatus() {
|
||||
void OSXClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void OSXClientTaskBarReceiver::runMenu(int, int) {
|
||||
void OSXClientTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void OSXClientTaskBarReceiver::primaryAction() {
|
||||
void OSXClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon OSXClientTaskBarReceiver::getIcon() const {
|
||||
const IArchTaskBarReceiver::Icon OSXClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(
|
||||
const BufferedLogOutputter *logBuffer, IEventQueue *events) {
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
|
||||
{
|
||||
return new OSXClientTaskBarReceiver(logBuffer, events);
|
||||
}
|
||||
|
||||
@ -24,7 +24,8 @@ class BufferedLogOutputter;
|
||||
class IEventQueue;
|
||||
|
||||
//! Implementation of ClientTaskBarReceiver for OS X
|
||||
class OSXClientTaskBarReceiver : public ClientTaskBarReceiver {
|
||||
class OSXClientTaskBarReceiver : public ClientTaskBarReceiver
|
||||
{
|
||||
public:
|
||||
OSXClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events);
|
||||
virtual ~OSXClientTaskBarReceiver();
|
||||
|
||||
@ -23,35 +23,39 @@
|
||||
// CXWindowsClientTaskBarReceiver
|
||||
//
|
||||
|
||||
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(
|
||||
const BufferedLogOutputter *, IEventQueue *events)
|
||||
: ClientTaskBarReceiver(events) {
|
||||
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(const BufferedLogOutputter *, IEventQueue *events)
|
||||
: ClientTaskBarReceiver(events)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver() {
|
||||
CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void CXWindowsClientTaskBarReceiver::showStatus() {
|
||||
void CXWindowsClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void CXWindowsClientTaskBarReceiver::runMenu(int, int) {
|
||||
void CXWindowsClientTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void CXWindowsClientTaskBarReceiver::primaryAction() {
|
||||
void CXWindowsClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CXWindowsClientTaskBarReceiver::getIcon() const {
|
||||
const IArchTaskBarReceiver::Icon CXWindowsClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(
|
||||
const BufferedLogOutputter *logBuffer, IEventQueue *events) {
|
||||
IArchTaskBarReceiver *createTaskBarReceiver(const BufferedLogOutputter *logBuffer, IEventQueue *events)
|
||||
{
|
||||
return new CXWindowsClientTaskBarReceiver(logBuffer, events);
|
||||
}
|
||||
|
||||