Skip to content

Commit 7ee861c

Browse files
feat: unify backends with QT (#145)
1 parent 6f97db2 commit 7ee861c

28 files changed

Lines changed: 1200 additions & 1549 deletions

.github/workflows/ci.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
include:
5353
- os: macos-latest
5454
shell: "bash"
55-
qt_version: ''
55+
qt_version: '6'
5656
- os: ubuntu-latest
5757
shell: "bash"
5858
qt_version: '5'
@@ -61,7 +61,7 @@ jobs:
6161
qt_version: '6'
6262
- os: windows-latest
6363
shell: "msys2 {0}"
64-
qt_version: ''
64+
qt_version: '6'
6565
steps:
6666
- name: Checkout
6767
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -118,6 +118,8 @@ jobs:
118118
"imagemagick"
119119
"ninja"
120120
"node"
121+
"qtbase"
122+
"qtsvg"
121123
)
122124
brew install "${dependencies[@]}"
123125
@@ -171,6 +173,8 @@ jobs:
171173
mingw-w64-ucrt-x86_64-ninja
172174
mingw-w64-ucrt-x86_64-nodejs
173175
mingw-w64-ucrt-x86_64-toolchain
176+
mingw-w64-ucrt-x86_64-qt6-base
177+
mingw-w64-ucrt-x86_64-qt6-svg
174178
175179
- name: Setup python
176180
id: setup-python
@@ -250,7 +254,6 @@ jobs:
250254
251255
- name: Run tests
252256
id: test
253-
# TODO: tests randomly hang on Linux, https://github.com/LizardByte/tray/issues/45
254257
timeout-minutes: 3
255258
working-directory: build/tests
256259
env:
File renamed without changes.

CMakeLists.txt

Lines changed: 65 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -33,67 +33,63 @@ option(BUILD_EXAMPLE "Build example app" ${TRAY_IS_TOP_LEVEL})
3333
set(CMAKE_COLOR_MAKEFILE ON)
3434
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
3535

36-
find_package(PkgConfig)
37-
3836
file(GLOB TRAY_SOURCES
3937
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.h"
4038
)
4139

42-
set(TRAY_ICON_ICO "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.ico")
43-
set(TRAY_ICON_PNG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.png")
44-
set(TRAY_ICON_SVG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.svg")
45-
set(TRAY_ICON_FILES
46-
"${TRAY_ICON_ICO}"
47-
"${TRAY_ICON_PNG}"
48-
"${TRAY_ICON_SVG}"
49-
)
50-
51-
set(_TRAY_ICON_ICO "${TRAY_ICON_ICO}" CACHE INTERNAL "Default tray ICO icon path")
52-
set(_TRAY_ICON_PNG "${TRAY_ICON_PNG}" CACHE INTERNAL "Default tray PNG icon path")
53-
set(_TRAY_ICON_SVG "${TRAY_ICON_SVG}" CACHE INTERNAL "Default tray SVG icon path")
54-
55-
# Copy default tray icon files into the output directory of the specified target.
56-
function(tray_copy_default_icons target_name)
57-
if(NOT TARGET "${target_name}")
58-
message(FATAL_ERROR "tray_copy_default_icons expected an existing target: ${target_name}")
59-
endif()
40+
if(TRAY_IS_TOP_LEVEL)
41+
set(TRAY_ICON_ICO "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.ico")
42+
set(TRAY_ICON_PNG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.png")
43+
set(TRAY_ICON_SVG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon.svg")
44+
set(TRAY_ICON2_ICO "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon2.ico")
45+
set(TRAY_ICON2_PNG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon2.png")
46+
set(TRAY_ICON2_SVG "${CMAKE_CURRENT_SOURCE_DIR}/icons/icon2.svg")
47+
set(TRAY_ICON_FILES
48+
"${TRAY_ICON_ICO}"
49+
"${TRAY_ICON_PNG}"
50+
"${TRAY_ICON_SVG}"
51+
"${TRAY_ICON2_ICO}"
52+
"${TRAY_ICON2_PNG}"
53+
"${TRAY_ICON2_SVG}"
54+
)
55+
56+
set(_TRAY_ICON_ICO "${TRAY_ICON_ICO}" CACHE INTERNAL "Default tray ICO icon path")
57+
set(_TRAY_ICON_PNG "${TRAY_ICON_PNG}" CACHE INTERNAL "Default tray PNG icon path")
58+
set(_TRAY_ICON_SVG "${TRAY_ICON_SVG}" CACHE INTERNAL "Default tray SVG icon path")
59+
60+
# Copy default tray icon files into the output directory of the specified target.
61+
function(tray_copy_default_icons target_name)
62+
if(NOT TARGET "${target_name}")
63+
message(FATAL_ERROR "tray_copy_default_icons expected an existing target: ${target_name}")
64+
endif()
6065

61-
foreach(icon_file IN LISTS TRAY_ICON_FILES)
62-
add_custom_command(TARGET "${target_name}" POST_BUILD
63-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
64-
"${icon_file}"
65-
"$<TARGET_FILE_DIR:${target_name}>"
66-
COMMENT "Copying ${icon_file} to $<TARGET_FILE_DIR:${target_name}>")
67-
endforeach()
68-
endfunction()
66+
foreach(icon_file IN LISTS TRAY_ICON_FILES)
67+
add_custom_command(TARGET "${target_name}" POST_BUILD
68+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
69+
"${icon_file}"
70+
"$<TARGET_FILE_DIR:${target_name}>"
71+
COMMENT "Copying ${icon_file} to $<TARGET_FILE_DIR:${target_name}>")
72+
endforeach()
73+
endfunction()
74+
endif()
6975

70-
if(WIN32)
71-
list(APPEND TRAY_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/tray_windows.c")
76+
find_package(Qt6 COMPONENTS Widgets Svg)
77+
if(Qt6_FOUND)
78+
set(TRAY_QT_VERSION 6)
7279
else()
73-
if(UNIX)
74-
if(APPLE)
75-
find_library(COCOA Cocoa REQUIRED)
76-
list(APPEND TRAY_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/tray_darwin.m")
77-
else()
78-
find_package(LibNotify REQUIRED)
79-
find_package(Qt6 COMPONENTS Widgets Svg)
80-
if(Qt6_FOUND)
81-
set(TRAY_QT_VERSION 6)
82-
else()
83-
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg)
84-
set(TRAY_QT_VERSION 5)
85-
endif()
86-
set(TRAY_QT_VERSION # cmake-lint: disable=C0103
87-
"${TRAY_QT_VERSION}"
88-
CACHE INTERNAL "Qt major version selected by tray"
89-
)
90-
set(CMAKE_AUTOMOC ON)
91-
list(APPEND TRAY_SOURCES
92-
"${CMAKE_CURRENT_SOURCE_DIR}/src/tray_linux.cpp"
93-
"${CMAKE_CURRENT_SOURCE_DIR}/src/QtTrayMenu.cpp"
94-
)
95-
endif()
96-
endif()
80+
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg)
81+
set(TRAY_QT_VERSION 5)
82+
endif()
83+
set(CMAKE_AUTOMOC ON)
84+
list(APPEND TRAY_SOURCES
85+
"${CMAKE_CURRENT_SOURCE_DIR}/src/tray_qt.cpp"
86+
"${CMAKE_CURRENT_SOURCE_DIR}/src/QtTrayMenu.cpp"
87+
)
88+
if(WIN32)
89+
list(APPEND TRAY_SOURCES
90+
"${CMAKE_CURRENT_SOURCE_DIR}/src/WindowsAppearance.cpp"
91+
"${CMAKE_CURRENT_SOURCE_DIR}/src/WindowsAppearance.h"
92+
)
9793
endif()
9894

9995
add_library(${PROJECT_NAME} STATIC ${TRAY_SOURCES})
@@ -104,32 +100,26 @@ target_include_directories(${PROJECT_NAME}
104100
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
105101
$<INSTALL_INTERFACE:include>)
106102

107-
if(WIN32)
108-
if(MSVC)
109-
list(APPEND TRAY_COMPILE_OPTIONS "/MT$<$<CONFIG:Debug>:d>")
110-
endif()
103+
if(WIN32 AND MSVC)
104+
list(APPEND TRAY_COMPILE_OPTIONS "/MT$<$<CONFIG:Debug>:d>")
105+
endif()
106+
107+
if(TRAY_QT_VERSION EQUAL 6)
108+
list(APPEND TRAY_EXTERNAL_LIBRARIES Qt6::Widgets Qt6::Svg)
111109
else()
112-
if(UNIX)
113-
if(APPLE)
114-
list(APPEND TRAY_EXTERNAL_LIBRARIES ${COCOA})
115-
else()
116-
if(TRAY_QT_VERSION EQUAL 6)
117-
list(APPEND TRAY_EXTERNAL_LIBRARIES Qt6::Widgets Qt6::Svg)
118-
else()
119-
list(APPEND TRAY_EXTERNAL_LIBRARIES Qt5::Widgets Qt5::Svg)
120-
endif()
121-
list(APPEND TRAY_LIBNOTIFY=1)
122-
list(APPEND TRAY_EXTERNAL_LIBRARIES ${LIBNOTIFY_LIBRARIES})
123-
124-
include_directories(SYSTEM ${LIBNOTIFY_INCLUDE_DIRS})
125-
link_directories(${LIBNOTIFY_LIBRARY_DIRS})
126-
endif()
127-
endif()
110+
list(APPEND TRAY_EXTERNAL_LIBRARIES Qt5::Widgets Qt5::Svg)
111+
endif()
112+
if(WIN32)
113+
list(APPEND TRAY_EXTERNAL_LIBRARIES advapi32 Wtsapi32)
114+
endif()
115+
116+
if(TRAY_COMPILE_DEFINITIONS)
117+
target_compile_definitions(${PROJECT_NAME} PRIVATE ${TRAY_COMPILE_DEFINITIONS})
128118
endif()
129119

130120
add_library(tray::tray ALIAS ${PROJECT_NAME})
131121

132-
if(BUILD_EXAMPLE)
122+
if(TRAY_IS_TOP_LEVEL AND BUILD_EXAMPLE)
133123
add_executable(tray_example "${CMAKE_CURRENT_SOURCE_DIR}/src/example.c")
134124
target_link_libraries(tray_example tray::tray)
135125
tray_copy_default_icons(tray_example)
@@ -142,7 +132,6 @@ if(TRAY_IS_TOP_LEVEL)
142132
endif()
143133

144134
target_compile_options(${PROJECT_NAME} PRIVATE ${TRAY_COMPILE_OPTIONS})
145-
target_link_directories(${PROJECT_NAME} PRIVATE ${TRAY_EXTERNAL_DIRECTORIES})
146135
target_link_libraries(${PROJECT_NAME} PRIVATE ${TRAY_EXTERNAL_LIBRARIES})
147136

148137
#

README.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020
## ℹ️ About
2121

22-
Cross-platform, super tiny C99 implementation of a system tray icon with a popup menu and notifications.
22+
Cross-platform C++17 Qt-backed system tray icon with a popup menu and notifications.
2323

24-
The code is C++ friendly and will compile fine in C++98 and up. This is a fork of
24+
This is a fork of
2525
[dmikushin/tray](https://github.com/dmikushin/tray) and is intended to add additional features required for our own
2626
[Sunshine](https://github.com/LizardByte/Sunshine) project.
2727

@@ -32,6 +32,7 @@ This fork adds the following features:
3232
- code coverage
3333
- refactored code, e.g., moved source code into the `src` directory
3434
- doxygen documentation and readthedocs configuration
35+
- all platforms use QT-based implementation
3536

3637
## 🖼️ Screenshots
3738

@@ -51,46 +52,62 @@ This fork adds the following features:
5152

5253
## 🖥️ Supported platforms
5354

54-
* Linux/Qt (Qt5 or Qt6 Widgets)
55-
* Windows XP or newer (shellapi.h)
56-
* MacOS (Cocoa/AppKit)
55+
* Linux
56+
* macOS
57+
* Windows
5758

5859
## 📋 Prerequisites
5960

6061
* CMake
6162
* [Ninja](https://ninja-build.org/), to have the same build commands on all platforms.
63+
* C++17 compiler
64+
* Qt5 or Qt6 Widgets and Svg modules
6265

63-
### Linux Dependencies
66+
### Platform Dependencies
6467

65-
Install either Qt6 _or_ Qt5 as well as libnotify development packages. The Linux backend requires libnotify and Qt Widgets+Svg modules.
68+
Install either Qt6 _or_ Qt5.
6669

6770
<div class="tabbed">
6871

6972
- <b class="tab-title">Arch</b>
7073
```bash
7174
# Qt6
72-
sudo pacman -S qt6-base qt6-svg libnotify
75+
sudo pacman -S qt6-base qt6-svg
7376

7477
# Qt5
75-
sudo pacman -S qt5-base qt5-svg libnotify
78+
sudo pacman -S qt5-base qt5-svg
7679
```
7780

7881
- <b class="tab-title">Debian/Ubuntu</b>
7982
```bash
8083
# Qt6
81-
sudo apt install qt6-base-dev qt6-svg-dev libnotify-dev
84+
sudo apt install qt6-base-dev qt6-svg-dev
8285
8386
# Qt5
84-
sudo apt install qtbase5-dev libqt5svg5-dev libnotify-dev
87+
sudo apt install qtbase5-dev libqt5svg5-dev
8588
```
8689

8790
- <b class="tab-title">Fedora</b>
8891
```bash
8992
# Qt6
90-
sudo dnf install qt6-qtbase-devel qt6-qtsvg-devel libnotify-devel
93+
sudo dnf install qt6-qtbase-devel qt6-qtsvg-devel
9194
9295
# Qt5
93-
sudo dnf install qt5-qtbase-devel qt5-qtsvg-devel libnotify-devel
96+
sudo dnf install qt5-qtbase-devel qt5-qtsvg-devel
97+
```
98+
99+
- <b class="tab-title">macOS</b>
100+
```bash
101+
brew install cmake ninja qtbase qtsvg
102+
```
103+
104+
- <b class="tab-title">Windows (MSYS2 UCRT64)</b>
105+
```bash
106+
pacman -S mingw-w64-ucrt-x86_64-cmake \
107+
mingw-w64-ucrt-x86_64-ninja \
108+
mingw-w64-ucrt-x86_64-toolchain \
109+
mingw-w64-ucrt-x86_64-qt6-base \
110+
mingw-w64-ucrt-x86_64-qt6-svg
94111
```
95112

96113
</div>
@@ -129,6 +146,18 @@ Execute the `tests` application:
129146
./build/tests/test_tray
130147
```
131148

149+
## 📘 Icon formats
150+
151+
The `icon` and `notification_icon` fields can be a path to an image file or an icon theme name. Relative file paths
152+
are resolved from the process working directory, so applications should copy or install icon files where the running
153+
process can find them.
154+
155+
SVG, ICO, PNG, and Qt theme icon names are supported.
156+
157+
For the most predictable cross-platform behavior, use SVG or PNG files for both tray and notification icons. ICO is
158+
supported by the Qt-backed paths tested by this project.
159+
Qt theme icons should be passed as icon name strings, such as `mail-message-new`.
160+
132161
## 📚 API
133162

134163
Tray structure defines an icon and a menu.

cmake/FindLibNotify.cmake

Lines changed: 0 additions & 55 deletions
This file was deleted.

docs/Doxyfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ PROJECT_NAME = tray
3333
DOT_GRAPH_MAX_NODES = 50
3434
IMAGE_PATH = ../docs/images
3535
INCLUDE_PATH =
36-
PREDEFINED += TRAY_WINAPI
3736

3837
# files and directories to process
3938
USE_MDFILE_AS_MAINPAGE = ../README.md

icons/icon.ico

-353 KB
Binary file not shown.

icons/icon.png

-360 KB
Loading

icons/icon2.ico

11.3 KB
Binary file not shown.

icons/icon2.png

1.29 KB
Loading

0 commit comments

Comments
 (0)