Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 12 additions & 66 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,64 +19,27 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeR

project(Projecteur LANGUAGES CXX)

add_compile_options(-Wall -Wextra -Werror)
add_compile_options(-Wall -Wextra)
#set(CMAKE_CXX_CLANG_TIDY clang-tidy-12)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
include(GitVersion)
include(Translation)

set(QtVersionOptions "Auto" "5" "6")
set(PROJECTEUR_QT_VERSION "Auto" CACHE STRING "Choose the Qt version")
set_property(CACHE PROJECTEUR_QT_VERSION PROPERTY STRINGS ${QtVersionOptions})

list(FIND QtVersionOptions ${PROJECTEUR_QT_VERSION} index)
if(index EQUAL -1)
message(FATAL_ERROR "PROJECTEUR_QT_VERSION must be one of ${QtVersionOptions}")
endif()

if ("${PROJECTEUR_QT_VERSION}" STREQUAL "Auto")
find_package(QT NAMES Qt6 Qt5 RCOMPONENTS Core REQUIRED)
else()
set(QT_VERSION_MAJOR ${PROJECTEUR_QT_VERSION})
endif()

find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
set(QT_PACKAGE_NAME Qt${QT_VERSION_MAJOR})
find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick Widgets)

message(STATUS "Using Qt version: ${Qt${QT_VERSION_MAJOR}_VERSION}")

if(${QT_PACKAGE_NAME}_VERSION VERSION_LESS "6.0")
set(CMAKE_CXX_STANDARD 14)
else()
set(CMAKE_CXX_STANDARD 17)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_AUTOMOC ON)

find_package(${QT_PACKAGE_NAME} 5.7 REQUIRED COMPONENTS Core Gui Quick Widgets)
set(HAS_Qt_X11Extras 0)

if(${QT_PACKAGE_NAME}_VERSION VERSION_LESS "6.0")
find_package(${QT_PACKAGE_NAME} QUIET COMPONENTS X11Extras)
set(HAS_Qt_X11Extras ${${QT_PACKAGE_NAME}_FOUND})
else()
set(HAS_Qt_X11Extras 0)
endif()

find_package(${QT_PACKAGE_NAME} QUIET COMPONENTS DBus)
set(HAS_Qt_DBus ${${QT_PACKAGE_NAME}_FOUND})
find_package(${QT_PACKAGE_NAME} QUIET COMPONENTS QuickCompiler)
set(HAS_Qt_QuickCompiler ${${QT_PACKAGE_NAME}_FOUND})

# Qt 5.8 seems to have issues with the way Projecteur shows the full screen overlay window,
# let's warn the user about it.
if(Qt5_VERSION VERSION_EQUAL "5.8"
OR (Qt5_VERSION VERSION_GREATER "5.8" AND Qt5_VERSION VERSION_LESS "5.9"))
message(WARNING "There are known issues when using Projecteur with Qt Version 5.8, "
"please use a different Qt Version.")
endif()
find_package(Qt6DBus QUIET)
set(HAS_Qt_DBus Qt6DBus_FOUND})
find_package(Qt6QuickCompiler QUIET)
set(HAS_Qt_QuickCompiler Qt6QuickCompiler_FOUND})

if (HAS_Qt_QuickCompiler)
# Off by default, since this ties the application strictly to the Qt version
Expand All @@ -94,18 +57,10 @@ if (USE_QTQUICK_COMPILER)
set_property(SOURCE "${resfile}" PROPERTY SKIP_AUTOMOC ON)
endforeach()
else()
if(${QT_PACKAGE_NAME}_VERSION VERSION_LESS "6.0")
qt5_add_resources(RESOURCES qml/qml.qrc)
else()
qt6_add_resources(RESOURCES qml/qml-qt6.qrc)
endif()
qt6_add_resources(RESOURCES qml/qml-qt6.qrc)
endif()

if(${QT_PACKAGE_NAME}_VERSION VERSION_LESS "6.0")
qt5_add_resources(RESOURCES resources.qrc)
else()
qt6_add_resources(RESOURCES resources.qrc)
endif()
qt6_add_resources(RESOURCES resources.qrc)

add_executable(projecteur
src/main.cc src/enum-helper.h
Expand Down Expand Up @@ -140,20 +95,11 @@ add_executable(projecteur
target_include_directories(projecteur PRIVATE src)

target_link_libraries(projecteur
PRIVATE ${QT_PACKAGE_NAME}::Core ${QT_PACKAGE_NAME}::Quick ${QT_PACKAGE_NAME}::Widgets
PRIVATE Qt6::Core Qt6::Quick Qt6::Widgets
)

if(HAS_Qt_X11Extras)
if(${QT_PACKAGE_NAME}_VERSION VERSION_LESS "6.0")
target_link_libraries(projecteur PRIVATE ${QT_PACKAGE_NAME}::X11Extras)
endif()
target_compile_definitions(projecteur PRIVATE HAS_Qt_X11Extras=1)
else()
message(STATUS "Compiling without Qt5::X11Extras.")
endif()

if(HAS_Qt_DBus)
target_link_libraries(projecteur PRIVATE ${QT_PACKAGE_NAME}::DBus)
target_link_libraries(projecteur PRIVATE Qt6::DBus)
target_compile_definitions(projecteur PRIVATE HAS_Qt_DBus=1)
else()
message(STATUS "Compiling without Qt5::DBus.")
Expand Down
30 changes: 15 additions & 15 deletions cmake/modules/Translation.cmake
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
find_package(Qt5 REQUIRED COMPONENTS Core)
find_package(Qt6 REQUIRED COMPONENTS Core)

# Extract the qmake executable location
get_target_property(Qt5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
get_target_property(Qt6_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)

# Find Qts own translations dir (containing qt_*.qm, qtbase_*.qm ...)
if(NOT QT_TRANSLATIONS_DIR)
# Ask Qt5 where to put the translations
execute_process(COMMAND ${Qt5_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
# Ask Qt6 where to put the translations
execute_process(COMMAND ${Qt6_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
OUTPUT_VARIABLE qt_translations_dir OUTPUT_STRIP_TRAILING_WHITESPACE)
# For windows systems: replace \ with / in directory path
file(TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir)
set(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The location of the Qt translations" FORCE)
endif()

find_package(Qt5LinguistTools QUIET)
if(NOT Qt5_LRELEASE_EXECUTABLE)
execute_process(COMMAND ${Qt5_QMAKE_EXECUTABLE} -query QT_INSTALL_BINS
find_package(Qt6LinguistTools QUIET)
if(NOT Qt6_LRELEASE_EXECUTABLE)
execute_process(COMMAND ${Qt6_QMAKE_EXECUTABLE} -query QT_INSTALL_BINS
OUTPUT_VARIABLE _qt_bin_dir OUTPUT_STRIP_TRAILING_WHITESPACE)
# For windows systems: replace \ with / in directory path
file(TO_CMAKE_PATH "${_qt_bin_dir}" _qt_bin_dir)
set(Qt5_LRELEASE_EXECUTABLE ${_qt_bin_dir}/lrelease)
set(Qt5_LCONVERT_EXECUTABLE ${_qt_bin_dir}/lconvert)
set(Qt5_LUPDATE_EXECUTABLE ${_qt_bin_dir}/lupdate)
set(Qt6_LRELEASE_EXECUTABLE ${_qt_bin_dir}/lrelease)
set(Qt6_LCONVERT_EXECUTABLE ${_qt_bin_dir}/lconvert)
set(Qt6_LUPDATE_EXECUTABLE ${_qt_bin_dir}/lupdate)
else()
get_target_property(Qt5_LCONVERT_EXECUTABLE Qt5::lconvert IMPORTED_LOCATION)
get_target_property(Qt6_LCONVERT_EXECUTABLE Qt6::lconvert IMPORTED_LOCATION)
endif()

# Helper function, takes the .qm file to be generated and a variable list of .ts files
Expand All @@ -37,7 +37,7 @@ function(add_qm_translation_file _qm_file)
SET(tsfiles_blank_sep "${tsfiles_blank_sep} ${tsfile}")
endforeach()
add_custom_command(OUTPUT ${_qm_file}
COMMAND ${Qt5_LRELEASE_EXECUTABLE}
COMMAND ${Qt6_LRELEASE_EXECUTABLE}
ARGS ${_ts_files} -qm ${_qm_file}
DEPENDS ${_ts_files} VERBATIM
COMMENT "Executing: lrelease -silent ${tsfiles_blank_sep} -qm ${_qm_file}"
Expand Down Expand Up @@ -67,10 +67,10 @@ function(add_combined_qm_translation_file _combined_qm_file)
endforeach()
list(REMOVE_DUPLICATES _single_qm_files)
add_custom_command(OUTPUT ${_combined_qm_file}
COMMAND ${Qt5_LCONVERT_EXECUTABLE}
COMMAND ${Qt6_LCONVERT_EXECUTABLE}
ARGS -o ${_combined_qm_file} ${_single_qm_files}
DEPENDS ${_single_qm_files} VERBATIM
COMMENT "Executing: ${Qt5_LCONVERT_EXECUTABLE} -o ${_combined_qm_file} ${_single_qm_files}"
COMMENT "Executing: ${Qt6_LCONVERT_EXECUTABLE} -o ${_combined_qm_file} ${_single_qm_files}"
)
endfunction()

Expand All @@ -94,7 +94,7 @@ function(add_translation_update_task _prefix _input_dirs _output_dir _languages)
set_target_properties(${_ts_files_tgt} PROPERTIES FOLDER "translation")
set_target_properties(${_ts_files_tgt} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
add_custom_command(TARGET ${_ts_files_tgt} PRE_BUILD
COMMAND ${Qt5_LUPDATE_EXECUTABLE}
COMMAND ${Qt6_LUPDATE_EXECUTABLE}
ARGS ${_input_dirs}
ARGS -locations relative
ARGS -ts
Expand Down
24 changes: 12 additions & 12 deletions src/actiondelegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,12 @@ void ActionTypeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& op

const auto symbol = [&item]() -> QChar {
switch(item.action->type()) {
case Action::Type::KeySequence: return QChar(Font::Icon::keyboard_4);
case Action::Type::CyclePresets: return QChar(Font::Icon::connection_8);
case Action::Type::ToggleSpotlight: return QChar(Font::Icon::power_on_off_11);
case Action::Type::ScrollHorizontal: return QChar(Font::Icon::cursor_21_rotated);
case Action::Type::ScrollVertical: return QChar(Font::Icon::cursor_21);
case Action::Type::VolumeControl: return QChar(Font::Icon::audio_6);
case Action::Type::KeySequence: return QChar(static_cast<quint32>(Font::Icon::keyboard_4));
case Action::Type::CyclePresets: return QChar(static_cast<quint32>(Font::Icon::connection_8));
case Action::Type::ToggleSpotlight: return QChar(static_cast<quint32>(Font::Icon::power_on_off_11));
case Action::Type::ScrollHorizontal: return QChar(static_cast<quint32>(Font::Icon::cursor_21_rotated));
case Action::Type::ScrollVertical: return QChar(static_cast<quint32>(Font::Icon::cursor_21));
case Action::Type::VolumeControl: return QChar(static_cast<quint32>(Font::Icon::audio_6));
}
return QChar(0);
}();
Expand Down Expand Up @@ -352,12 +352,12 @@ void ActionTypeDelegate::actionContextMenu(QWidget* parent, InputMapConfigModel*
};

static std::vector<actionEntry> items {
{Action::Type::KeySequence, QChar(Font::Icon::keyboard_4), tr("Key Sequence"), false},
{Action::Type::CyclePresets, QChar(Font::Icon::connection_8), tr("Cycle Presets"), false},
{Action::Type::ToggleSpotlight, QChar(Font::Icon::power_on_off_11), tr("Toggle Spotlight"), false},
{Action::Type::ScrollHorizontal, QChar(Font::Icon::cursor_21_rotated), tr("Scroll Horizontal"), true},
{Action::Type::ScrollVertical, QChar(Font::Icon::cursor_21), tr("Scroll Vertical"), true},
{Action::Type::VolumeControl, QChar(Font::Icon::audio_6), tr("Volume Control"), true},
{Action::Type::KeySequence, QChar(static_cast<quint32>(Font::Icon::keyboard_4)), tr("Key Sequence"), false},
{Action::Type::CyclePresets, QChar(static_cast<quint32>(Font::Icon::connection_8)), tr("Cycle Presets"), false},
{Action::Type::ToggleSpotlight, QChar(static_cast<quint32>(Font::Icon::power_on_off_11)), tr("Toggle Spotlight"), false},
{Action::Type::ScrollHorizontal, QChar(static_cast<quint32>(Font::Icon::cursor_21_rotated)), tr("Scroll Horizontal"), true},
{Action::Type::ScrollVertical, QChar(static_cast<quint32>(Font::Icon::cursor_21)), tr("Scroll Vertical"), true},
{Action::Type::VolumeControl, QChar(static_cast<quint32>(Font::Icon::audio_6)), tr("Volume Control"), true},
};

static bool initIcons = []()
Expand Down
34 changes: 26 additions & 8 deletions src/asynchronous.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,32 @@ auto capture_call(Lambda&& lambda, Args&& ... args){
capture_args = std::make_tuple(std::forward<Args>(args) ...)
](auto&& ... original_args)mutable{
return async::apply([&lambda](auto&& ... args){
lambda(std::forward<decltype(args)>(args) ...);
},
std::tuple_cat(
std::forward_as_tuple(original_args ...),
async::apply([](auto&& ... args){
return std::forward_as_tuple<Args ...>(
std::move(args) ...);
}, std::move(capture_args))

// Handle the Qt6 return argument placeholder conditionally inside the body.
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
// Check if the tuple size is greater than the expected arguments (i.e., Qt6 inserted the return placeholder).
if constexpr (std::tuple_size<decltype(std::make_tuple(std::forward<decltype(args)>(args)...))>::value > sizeof...(Args))
{
// Unpack the arguments, skip the first one (the return value placeholder), and call the user-provided lambda.
auto tuple = std::make_tuple(std::forward<decltype(args)>(args)...);

// std::apply applies a tuple to a function. We use a nested lambda here to skip the first element.
std::apply([&lambda](auto&& /* retArg */, auto&& ... actual_args){
lambda(std::forward<decltype(actual_args)>(actual_args)...);
}, std::move(tuple));
} else
#endif
{
// Qt5 or Qt6 without the return placeholder: pass arguments directly to the user-provided lambda.
lambda(std::forward<decltype(args)>(args) ...);
}
},
std::tuple_cat(
std::forward_as_tuple(original_args ...),
async::apply([](auto&& ... args){
return std::forward_as_tuple<Args ...>(
std::move(args) ...);
}, std::move(capture_args))
));
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/device-vibration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ struct TimerWidget::Impl
btnStartStop->setCheckable(true);
QObject::connect(btnStartStop, &IconButton::toggled, parent, [this](bool checked) {
stack->setCurrentWidget(checked ? overlay : editor);
btnStartStop->setText(checked ? QChar(Font::Icon::media_control_50)
: QChar(Font::Icon::media_control_48));
btnStartStop->setText(checked ? QChar(static_cast<quint32>(Font::Icon::media_control_50))
: QChar(static_cast<quint32>(Font::Icon::media_control_48)));
if (checked) {
secondsLeft = valueSeconds();
updateOverlayLabel(secondsLeft);
Expand Down
1 change: 1 addition & 0 deletions src/hidpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <tuple>

#include <QString>
#include <QtCore/QObject>

// Hidpp specific functionality
// - code is heavily inspired by this library: https://github.com/cvuchener/hidpp
Expand Down
4 changes: 2 additions & 2 deletions src/iconwidgets.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ IconButton::IconButton(Font::Icon symbol, QWidget* parent)
iconFont.setPointSizeF(font().pointSizeF());

setFont(iconFont);
setText(QChar(symbol));
setText(QChar(static_cast<quint32>(symbol)));

auto p = palette();
p.setColor(QPalette::ColorGroup::Normal, QPalette::ButtonText,
Expand All @@ -33,7 +33,7 @@ IconButton::IconButton(Font::Icon symbol, QWidget* parent)

// -------------------------------------------------------------------------------------------------
IconLabel::IconLabel(Font::Icon symbol, QWidget* parent)
: QLabel(QChar(symbol), parent)
: QLabel(QChar(static_cast<quint32>(symbol)), parent)
{
QFont iconFont("projecteur-icons");
iconFont.setPixelSize(defaultIconLabelSize);
Expand Down
Loading