diff --git a/.gitmodules b/.gitmodules index 6cbf29c..5d1e6f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ +[submodule "third-party/doxygen-awesome-css"] + path = third-party/doxygen-awesome-css + url = https://github.com/jothepro/doxygen-awesome-css.git + branch = main [submodule "third-party/googletest"] path = third-party/googletest url = https://github.com/google/googletest.git diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..75bed11 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,32 @@ +--- +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "miniconda-latest" + commands: + # because we are overriding the build commands, we need to setup the environment ourselves + - cat docs/environment.yml + - conda env create --quiet --name ${READTHEDOCS_VERSION} --file docs/environment.yml + - mkdir -p ${READTHEDOCS_OUTPUT} + - | + wget "https://raw.githubusercontent.com/LizardByte/.github/master/branding/logos/favicon.ico" \ + -O ${READTHEDOCS_OUTPUT}lizardbyte.ico + - | + wget "https://raw.githubusercontent.com/LizardByte/.github/master/branding/logos/logo-128x128.png" \ + -O ${READTHEDOCS_OUTPUT}lizardbyte.png + - cd docs && doxygen Doxyfile + +# using conda, we can get newer doxygen and graphviz than ubuntu provide +# https://github.com/readthedocs/readthedocs.org/issues/8151#issuecomment-890359661 +conda: + environment: docs/environment.yml + +submodules: + include: all + recursive: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 1df79fe..e13e7a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,11 @@ +# +# Project configuration +# cmake_minimum_required(VERSION 3.13 FATAL_ERROR) # target_link_directories - -project(tray - LANGUAGES C - DESCRIPTION "A cross-platform system tray library") +project(tray VERSION 0.0.0 + DESCRIPTION "A cross-platform system tray library" + HOMEPAGE_URL "https://app.lizardbyte.dev" + LANGUAGES C) set(PROJECT_LICENSE "MIT") @@ -11,11 +14,22 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) endif() +# Add our custom CMake modules to the global path set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -# options +# +# Project optional configuration +# +option(BUILD_DOCS "Build documentation" ON) option(BUILD_TESTS "Build tests" ON) +# +# Documentation +# +if(BUILD_DOCS) + add_subdirectory(docs) +endif() + # Generate 'compile_commands.json' for clang_complete set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/README.md b/README.md index 7359deb..a5c5769 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,70 @@ -# Cross-platform Linux/macOS/Windows Tray +# Overview -[![codecov](https://img.shields.io/codecov/c/gh/LizardByte/tray?token=HSX66JNEOL&style=for-the-badge&logo=codecov&label=codecov)](https://codecov.io/gh/LizardByte/tray) +[![GitHub Workflow Status (CI)](https://img.shields.io/github/actions/workflow/status/lizardbyte/tray/ci.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/tray/actions/workflows/ci.yml?query=branch%3Amaster) +[![Codecov](https://img.shields.io/codecov/c/gh/LizardByte/tray?token=HSX66JNEOL&style=for-the-badge&logo=codecov&label=codecov)](https://codecov.io/gh/LizardByte/tray) +[![GitHub stars](https://img.shields.io/github/stars/lizardbyte/tray.svg?logo=github&style=for-the-badge)](https://github.com/LizardByte/tray) - +## About - +Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu and notifications. - +The code is C++ friendly and will compile fine in C++98 and up. This is a fork of +[dmikushin/tray](https://github.com/dmikushin/tray) and is intended to add additional features required for our own +[Sunshine](https://github.com/LizardByte/Sunshine) project. -Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu. +This fork adds the following features: -Works well on: +- system tray notifications +- support for both linux appindicator versions +- unit tests +- code coverage +- refactored code, e.g. moved source code into the `src` directory +- doxygen documentation, and readthedocs configuration + +## Screenshots + +
+ +- Linux![linux](docs/images/screenshot_linux.png) +- macOS![macOS](docs/images/screenshot_macos.png) +- Windows![windows](docs/images/screenshot_windows.png) + +
+ +## Supported platforms * Linux/Gtk (libayatana-appindicator3 or libappindicator3) * Windows XP or newer (shellapi.h) * MacOS (Cocoa/AppKit) -The code is C++ friendly and will compile fine in C++98 and up. +## Prerequisites + +* CMake +* [Ninja](https://ninja-build.org/), in order to have the same build commands on all platforms -This fork is intended to bring together the [original work of Serge Zaitsev](https://github.com/zserge/tray) and the most interesting forks and PRs of respectable contributors: +### Linux Dependencies -* [Only process messages coming from the tray window on Windows](https://github.com/zserge/tray/pull/18) -* [Become C++-friendly](https://github.com/zserge/tray/pull/16) -* [Fix all menu items have a check box](https://github.com/zserge/tray/pull/11) -* [Add support for tooltip](https://github.com/zserge/tray/pull/11) -* Darwin implementation translated from C to Objective C adapted from [@trevex fork](https://github.com/trevex/tray) +
-## Prerequisites +- Arch + ```bash + sudo pacman -S libayatana-appindicator + ``` -* CMake -* [Ninja](https://ninja-build.org/), in order to have the same build commands on all platforms -* AppIndicator on Linux: +- Debian/Ubuntu + ```bash + sudo apt install libappindicator3-dev + ``` -``` -sudo apt install libappindicator3-dev -``` +- Fedora + ```bash + sudo dnf install libappindicator-gtk3-devel + ``` +
## Building -``` +```bash mkdir build cd build cmake -G Ninja .. @@ -49,7 +75,7 @@ ninja Execute the `tray_example` application: -``` +```bash ./tray_example ``` @@ -91,4 +117,4 @@ array must have text field set to NULL. ## License This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php), - so feel free to integrate it in your commercial products. +so feel free to integrate it in your commercial products. diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt new file mode 100644 index 0000000..7f93e1d --- /dev/null +++ b/docs/CMakeLists.txt @@ -0,0 +1,41 @@ +# find doxygen and graphviz +find_package(Doxygen + REQUIRED dot) + +# define variables based on whether we are building on readthedocs +if(DEFINED ENV{READTHEDOCS}) + set(DOXYGEN_BUILD_DIR_CMAKE $ENV{READTHEDOCS_OUTPUT}) + set(DOXYGEN_PROJECT_VERSION $ENV{READTHEDOCS_VERSION}) +else() + set(DOXYGEN_BUILD_DIR_CMAKE "${CMAKE_CURRENT_BINARY_DIR}/build") + set(DOXYGEN_PROJECT_VERSION ${PROJECT_VERSION}) +endif() +message(STATUS "DOXYGEN_BUILD_DIR_CMAKE: ${DOXYGEN_BUILD_DIR_CMAKE}") + +# download icon and logo +file(DOWNLOAD + "https://raw.githubusercontent.com/LizardByte/.github/master/branding/logos/favicon.ico" + "${DOXYGEN_BUILD_DIR_CMAKE}/lizardbyte.ico" +) +file(DOWNLOAD + "https://raw.githubusercontent.com/LizardByte/.github/master/branding/logos/logo-128x128.png" + "${DOXYGEN_BUILD_DIR_CMAKE}/lizardbyte.png" +) + +# create build directories, as doxygen fails to create it in some cases? +file(MAKE_DIRECTORY "${DOXYGEN_BUILD_DIR_CMAKE}/html") + +# convert to relative path, so doxygen doesn't get confused on Windows +file(RELATIVE_PATH DOXYGEN_BUILD_DIR_RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${DOXYGEN_BUILD_DIR_CMAKE}") +message(STATUS "DOXYGEN_BUILD_DIR_RELATIVE: ${DOXYGEN_BUILD_DIR_RELATIVE}") + +# build docs +add_custom_target(docs ALL + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Building Doxygen documentation" + COMMAND ${CMAKE_COMMAND} -E env + READTHEDOCS_OUTPUT=${DOXYGEN_BUILD_DIR_RELATIVE} + READTHEDOCS_VERSION=${DOXYGEN_PROJECT_VERSION} + ${DOXYGEN_EXECUTABLE} Doxyfile + VERBATIM +) diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 0000000..bea85df --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,111 @@ +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +# must be first +DOXYFILE_ENCODING = UTF-8 + +# project metadata +DOCSET_BUNDLE_ID = dev.lizardbyte.tray +DOCSET_PUBLISHER_ID = dev.lizardbyte.tray.documentation +DOCSET_PUBLISHER_NAME = LizardByte +PROJECT_BRIEF = "Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu and notifications." +PROJECT_ICON = $(READTHEDOCS_OUTPUT)/lizardbyte.ico +PROJECT_LOGO = $(READTHEDOCS_OUTPUT)/lizardbyte.png +PROJECT_NAME = tray + +# project specific settings +DOT_GRAPH_MAX_NODES = 50 +IMAGE_PATH = ../docs/images +INCLUDE_PATH = +PREDEFINED = DOXYGEN +PREDEFINED += __APPLE__ +PREDEFINED += linux +PREDEFINED += __linux +PREDEFINED += __linux__ +PREDEFINED += __MACH__ +PREDEFINED += _WIN32 + +# TODO: Enable this when we have complete documentation +WARN_IF_UNDOCUMENTED = NO + +# files and directories to process +INPUT = ../README.md \ + ../src + +# +# Common LizardByte settings +# + +# doxygen-awesome-css +HTML_COLORSTYLE = LIGHT # required with Doxygen >= 1.9.5 +HTML_COPY_CLIPBOARD = NO # required for Doxygen >= 1.10.0 +HTML_EXTRA_FILES = ../third-party/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js +HTML_EXTRA_FILES += ../third-party/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js +HTML_EXTRA_FILES += ../third-party/doxygen-awesome-css/doxygen-awesome-paragraph-link.js +HTML_EXTRA_FILES += ../third-party/doxygen-awesome-css/doxygen-awesome-interactive-toc.js +HTML_EXTRA_STYLESHEET = ../third-party/doxygen-awesome-css/doxygen-awesome.css +HTML_HEADER = header.html + +# custom aliases +ALIASES = "" +ALIASES += "examples=^^**Examples**^^@code{.cpp}" +ALIASES += "examples_end=@endcode^^" +ALIASES += "rst=^^\verbatim embed:rst:leading-asterisk^^" +ALIASES += "rst_end=\endverbatim" + +# general settings +CASE_SENSE_NAMES = YES +CREATE_SUBDIRS = NO +DISABLE_INDEX = NO +DOCBOOK_OUTPUT = docbook +DOT_IMAGE_FORMAT = svg +DOT_NUM_THREADS = 1 +EXTRACT_ALL = NO +FULL_SIDEBAR = NO +GENERATE_HTML = YES +GENERATE_LATEX = NO +GENERATE_TREEVIEW = YES +GENERATE_XML = NO +HAVE_DOT = YES +HTML_OUTPUT = html +INTERACTIVE_SVG = YES +LATEX_OUTPUT = latex +MACRO_EXPANSION = YES +MAN_OUTPUT = man +MARKDOWN_ID_STYLE = GITHUB +MARKDOWN_SUPPORT = YES +NUM_PROC_THREADS = 1 +PROJECT_NUMBER = $(READTHEDOCS_VERSION) +OUTPUT_DIRECTORY = $(READTHEDOCS_OUTPUT) +RECURSIVE = YES +RTF_OUTPUT = rtf +SORT_BRIEF_DOCS = YES +STRIP_FROM_INC_PATH = ../ +STRIP_FROM_PATH = ../ +WARN_AS_ERROR = FAIL_ON_WARNINGS +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_IF_UNDOC_ENUM_VAL = YES +WARN_NO_PARAMDOC = YES +WARNINGS = YES +XML_OUTPUT = xml diff --git a/docs/environment.yml b/docs/environment.yml new file mode 100644 index 0000000..8670795 --- /dev/null +++ b/docs/environment.yml @@ -0,0 +1,8 @@ +--- +name: RTD +channels: + - conda-forge + - defaults +dependencies: + - doxygen=1.10.0 + - graphviz=11.0.0 diff --git a/docs/header.html b/docs/header.html new file mode 100644 index 0000000..849a882 --- /dev/null +++ b/docs/header.html @@ -0,0 +1,99 @@ + + + + + + + + +$projectname: $title +$title + + + + + + + + + + +$treeview +$search +$mathjax +$darkmode + +$extrastylesheet + + + + + + + + + + + + + + + + + +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
$projectname $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
$searchbox
+
+ + diff --git a/docs/images/screenshot_macosx.png b/docs/images/screenshot_macos.png similarity index 100% rename from docs/images/screenshot_macosx.png rename to docs/images/screenshot_macos.png diff --git a/src/example.c b/src/example.c index 9d7958d..16f817b 100644 --- a/src/example.c +++ b/src/example.c @@ -1,3 +1,7 @@ +/** + * @file src/example.c + * @brief Example usage of the tray library. + */ #include #include diff --git a/src/tray.h b/src/tray.h index c94854e..fd3166d 100644 --- a/src/tray.h +++ b/src/tray.h @@ -1,3 +1,7 @@ +/** + * @file src/tray.h + * @brief Definition of the tray API. + */ #ifndef TRAY_H #define TRAY_H diff --git a/src/tray_darwin.m b/src/tray_darwin.m index 9865bd6..2327ae3 100644 --- a/src/tray_darwin.m +++ b/src/tray_darwin.m @@ -1,7 +1,16 @@ +/** + * @file src/tray_darwin.m + * @brief System tray implementation for macOS. + */ +// header include #include "tray.h" -#include + +// system includes #include +// lib includes +#include + @interface AppDelegate: NSObject - (IBAction)menuCallback:(id)sender; @end diff --git a/src/tray_linux.c b/src/tray_linux.c index 7faa3a2..969c17d 100644 --- a/src/tray_linux.c +++ b/src/tray_linux.c @@ -1,7 +1,16 @@ +/** + * @file src/tray_linux.c + * @brief System tray implementation for Linux. + */ +// header include #include "tray.h" + +// system includes #include #include #include + +// lib includes #ifdef TRAY_AYATANA_APPINDICATOR #include #elif TRAY_LEGACY_APPINDICATOR @@ -10,7 +19,6 @@ #ifndef IS_APP_INDICATOR #define IS_APP_INDICATOR APP_IS_INDICATOR #endif - #include #define TRAY_APPINDICATOR_ID "tray-id" diff --git a/src/tray_windows.c b/src/tray_windows.c index cf92da7..c5c269c 100644 --- a/src/tray_windows.c +++ b/src/tray_windows.c @@ -1,6 +1,13 @@ +/** + * @file src/tray_windows.c + * @brief System tray implementation for Windows. + */ +// header include +#include "tray.h" + +// system includes #include #include -#include "tray.h" #define WM_TRAY_CALLBACK_MESSAGE (WM_USER + 1) #define WC_TRAY_CLASS_NAME "TRAY" @@ -14,9 +21,9 @@ struct icon_info { }; enum IconType { - REGULAR = 1, - LARGE, - NOTIFICATION + REGULAR = 1, ///< Regular icon + LARGE, ///< Large icon + NOTIFICATION ///< Notification icon }; static WNDCLASSEX wc; diff --git a/third-party/doxygen-awesome-css b/third-party/doxygen-awesome-css new file mode 160000 index 0000000..40e9b25 --- /dev/null +++ b/third-party/doxygen-awesome-css @@ -0,0 +1 @@ +Subproject commit 40e9b25b6174dd3b472d8868f63323a870dfeeb8