diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 251be85..1116bac 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,10 +1,13 @@ -name: Ubuntu Linux (x86_64) +# Build check workflow +# Used to check if projectMSDL compiles with upstream master of libprojectM. +# The resulting binaries are not considered for public use though. +name: Build Check on: [ push, pull_request ] jobs: - build: - name: Static libprojectM + build-linux: + name: Ubuntu Linux, x86_64 runs-on: ubuntu-latest steps: @@ -12,7 +15,16 @@ jobs: - name: Install Build Dependencies run: | sudo apt update - sudo apt install build-essential libgl1-mesa-dev mesa-common-dev libsdl2-dev libpoco-dev ninja-build + sudo apt install build-essential libgl1-mesa-dev mesa-common-dev libsdl2-dev libpoco-dev ninja-build libssl-dev + + # We need to build/link Poco ourselves as static libraries, because Ubuntu Jammy ships with a broken Poco 1.11.0 + - name: Checkout Poco Sources + uses: actions/checkout@v3 + with: + repository: pocoproject/poco + path: poco + ref: 'poco-1.12.2' + submodules: recursive - name: Checkout libprojectM Sources uses: actions/checkout@v3 @@ -21,11 +33,18 @@ jobs: path: projectm submodules: recursive + - name: Build Poco + run: | + mkdir cmake-build-poco + cmake -G Ninja -S poco -B cmake-build-poco -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install-poco -DENABLE_MONGODB=OFF -DENABLE_REDIS=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=OFF -DENABLE_ACTIVERECORD=OFF -DENABLE_ACTIVERECORD_COMPILER=OFF -DENABLE_DATA_ODBC=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_DATA_MYSQL=OFF + cmake --build cmake-build-poco --parallel --target install + - name: Build/Install libprojectM run: | mkdir cmake-build-libprojectm - cmake -G Ninja -S projectm -B cmake-build-libprojectm -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install-libprojectm - cmake --build cmake-build-libprojectm --parallel --target install + cmake -G Ninja -S projectm -B cmake-build-libprojectm -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install-poco -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install-libprojectm + cmake --build cmake-build-libprojectm --parallel + cmake --install "${{ github.workspace }}/cmake-build-libprojectm" - name: Checkout frontend-sdl2 Sources uses: actions/checkout@v3 @@ -38,3 +57,74 @@ jobs: mkdir cmake-build-frontend-sdl2 cmake -G Ninja -S frontend-sdl2 -B cmake-build-frontend-sdl2 -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install-libprojectm -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install-frontend-sdl2 cmake --build cmake-build-frontend-sdl2 --parallel + cmake --install "${{ github.workspace }}/cmake-build-frontend-sdl2" + + build-windows: + name: Windows, x64 + runs-on: windows-latest + + steps: + - name: Install Build Dependencies + run: vcpkg --triplet=x64-windows-static install glew gtest sdl2 poco + + - name: Checkout libprojectM Sources + uses: actions/checkout@v3 + with: + repository: projectM-visualizer/projectm + path: projectm + submodules: recursive + + - name: Build/Install libprojectM + run: | + mkdir cmake-build-libprojectm + cmake -G "Visual Studio 17 2022" -A "X64" -S "${{ github.workspace }}/projectm" -B "${{ github.workspace }}/cmake-build-libprojectm" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}/install-libprojectm" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$:Debug>" -DCMAKE_VERBOSE_MAKEFILE=YES -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=NO + cmake --build "${{ github.workspace }}/cmake-build-libprojectm" --config Release --parallel + cmake --install "${{ github.workspace }}/cmake-build-libprojectm" --config Release + + - name: Checkout projectMSDL Sources + uses: actions/checkout@v3 + with: + path: frontend-sdl2 + submodules: recursive + + - name: Build projectMSDL + run: | + mkdir cmake-build-frontend-sdl2 + cmake -G "Visual Studio 17 2022" -A "X64" -S "${{ github.workspace }}/frontend-sdl2" -B "${{ github.workspace }}/cmake-build-frontend-sdl2" -DCMAKE_TOOLCHAIN_FILE="${Env:VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install-libprojectm" -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install-frontend-sdl2" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$:Debug>" -DCMAKE_VERBOSE_MAKEFILE=YES -DSDL2_LINKAGE=static -DBUILD_TESTING=YES + cmake --build "${{ github.workspace }}/cmake-build-frontend-sdl2" --parallel --config Release + cmake --install "${{ github.workspace }}/cmake-build-frontend-sdl2" --config Release + + build-darwin: + name: macOS, x86_64 + runs-on: macos-latest + + steps: + - name: Install Build Dependencies + run: brew install sdl2 ninja googletest poco + + - name: Checkout libprojectM Sources + uses: actions/checkout@v3 + with: + repository: projectM-visualizer/projectm + path: projectm + submodules: recursive + + - name: Build/Install libprojectM + run: | + mkdir cmake-build-libprojectm + cmake -G Ninja -S "${{ github.workspace }}/projectm" -B "${{ github.workspace }}/cmake-build-libprojectm" -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}//install-libprojectm" + cmake --build "${{ github.workspace }}/cmake-build-libprojectm" --parallel + cmake --install "${{ github.workspace }}/cmake-build-libprojectm" + + - name: Checkout projectMSDL Sources + uses: actions/checkout@v3 + with: + path: frontend-sdl2 + submodules: recursive + + - name: Build projectMSDL + run: | + mkdir cmake-build-frontend-sdl2 + cmake -G Ninja -S "${{ github.workspace }}/frontend-sdl2" -B "${{ github.workspace }}/cmake-build-frontend-sdl2" -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install-libprojectm" -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}//install-frontend-sdl2" + cmake --build "${{ github.workspace }}/cmake-build-frontend-sdl2" --parallel + cmake --install "${{ github.workspace }}/cmake-build-frontend-sdl2" diff --git a/CMakeLists.txt b/CMakeLists.txt index 95c2185..e251ce2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,18 +6,64 @@ set(CMAKE_POSITION_INDEPENDENT_CODE YES) set_property(GLOBAL PROPERTY USE_FOLDERS ON) -project(projectM-SDL +project(projectMSDL LANGUAGES C CXX VERSION 2.0.0 ) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +# Default install layouts. +option(ENABLE_FLAT_PACKAGE "Creates a \"flat\" install layout with files and preset/texture dirs directly in the main dir." OFF) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE) + include(GNUInstallDirs) + + set(PROJECTMSDL_BIN_DIR "${CMAKE_INSTALL_BINDIR}" CACHE STRING "Directory to install executables in, relative to the install prefix.") + set(PROJECTMSDL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.") + set(PROJECTMSDL_DATA_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.") + set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.") + set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.") + + # Additional options for desktop integration + option(ENABLE_DESKTOP_ICON "Install a .desktop file and icons" ON) + set(PROJECTMSDL_DESKTOP_DIR "${CMAKE_INSTALL_DATAROOTDIR}/applications" CACHE STRING "Directory to install the .desktop file in, relative to the install prefix.") + set(PROJECTMSDL_ICONS_DIR "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor" CACHE STRING "Directory to install the icons in, relative to the install prefix.") + + GNUInstallDirs_get_absolute_install_dir(_config_dir_abs_init PROJECTMSDL_CONFIG_DIR DATAROOTDIR) + set(DEFAULT_CONFIG_PATH "${_config_dir_abs_init}" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.") + set(DEFAULT_PRESETS_PATH "${_config_dir_abs_init}/presets" CACHE STRING "Default presets path in the configuration file.") + set(DEFAULT_TEXTURES_PATH "${_config_dir_abs_init}/textures" CACHE STRING "Default textures path in the configuration file.") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_FLAT_PACKAGE) + # Package as .app bundle on macOS + set(BUNDLE_BASE_DIR "projectM.app/Contents") + set(PROJECTMSDL_BIN_DIR "${BUNDLE_BASE_DIR}/MacOS" CACHE STRING "Directory to install executables in, relative to the install prefix.") + set(PROJECTMSDL_LIB_DIR "${BUNDLE_BASE_DIR}/PlugIns" CACHE STRING "Directory to install additional libraries in, relative to the install prefix.") + set(PROJECTMSDL_DATA_DIR "{BUNDLE_BASE_DIR}/Resources" CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.") + set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/Presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.") + set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/Textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.") + + set(DEFAULT_CONFIG_PATH "\${application.dir}/../Resources" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.") + set(DEFAULT_PRESETS_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default presets path in the configuration file.") + set(DEFAULT_TEXTURES_PATH "\${application.dir}/../Resources/Presets" CACHE STRING "Default textures path in the configuration file.") +else() + # Windows and others: use flat layout. + set(PROJECTMSDL_BIN_DIR "." CACHE STRING "Directory to install executables in, relative to the install prefix.") + set(PROJECTMSDL_LIB_DIR "." CACHE STRING "Directory to install additional libraries in, relative to the install prefix.") + set(PROJECTMSDL_DATA_DIR "." CACHE STRING "Directory to install the config file, presets and texture, relative to the install prefix.") + set(PROJECTMSDL_PRESETS_DIR "${PROJECTMSDL_DATA_DIR}/presets" CACHE STRING "Directory to install optional preset files, relative to the install prefix.") + set(PROJECTMSDL_TEXTURES_DIR "${PROJECTMSDL_DATA_DIR}/textures" CACHE STRING "Directory to install optional texture files, relative to the install prefix.") + + set(DEFAULT_CONFIG_PATH "" CACHE STRING "Optional path to look for the configuration file in addition to PROJECTMSDL_BIN_DIR.") + set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.") + set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.") +endif() + set(SDL2_LINKAGE "shared" CACHE STRING "Set to either shared or static to specify how libSDL2 should be linked. Defaults to shared.") option(ENABLE_FREETYPE "Use the Freetype font rendering library instead of the built-in stb_truetype if available" ON) -set(DEFAULT_PRESETS_PATH "\${application.dir}/presets" CACHE STRING "Default presets path in the configuration file.") -set(DEFAULT_TEXTURES_PATH "\${application.dir}/textures" CACHE STRING "Default textures path in the configuration file.") + +set(PRESET_DIRS "" CACHE STRING "List of paths with presets. Will be installed in \"presets\" ") +set(TEXTURE_DIRS "" CACHE STRING "List of paths with presets.") if(NOT SDL2_LINKAGE STREQUAL "shared" AND NOT SDL2_LINKAGE STREQUAL "static") message(FATAL_ERROR "Invalid libSDL2 linkage provided in SDL2_LINKAGE: \"${SDL2_LINKAGE}\".\n" diff --git a/README.md b/README.md index 5134062..15c69d5 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,14 @@ and `sudo make install` [libprojectM](https://github.com/projectM-visualizer/pro ### Dependencies -This project requires two third-party libraries in addition to libprojectM's core library dependencies: +This project requires third-party libraries in addition to libprojectM's core library dependencies: - SDL2 (version 2.0.16 or higher) -- POCO (version 1.12 or higher) +- POCO (recommended version 1.12 or higher, minimum is 1.9.x) +- Freetype 2 (optional, will provide better looking UI text) + +**Important**: projectMSDL will _not compile_ against Poco versions from 1.10.0 up to 1.11.1, as these versions of Poco +include a serious issue that causes the application to crash. Either use Poco 1.9.x, or upgrade to 1.11.2 or higher. Depending on your needs, you can either build them yourself or install them using your favorite package manager. Here are some examples for the three major desktop platforms: diff --git a/install.cmake b/install.cmake index 40c2ce6..7dab564 100644 --- a/install.cmake +++ b/install.cmake @@ -1,8 +1,57 @@ -# ToDo: Make directory structure configurable install(TARGETS projectMSDL - RUNTIME DESTINATION . + RUNTIME DESTINATION ${PROJECTMSDL_BIN_DIR} + COMPONENT projectMSDL ) install(FILES ${PROJECTM_CONFIGURATION_FILE} - DESTINATION . + DESTINATION ${PROJECTMSDL_DATA_DIR} + COMPONENT projectMSDL ) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT ENABLE_FLAT_PACKAGE) + if(ENABLE_DESKTOP_ICON) + install(FILES src/resources/projectMSDL.desktop + DESTINATION ${PROJECTMSDL_DESKTOP_DIR} + COMPONENT projectMSDL + ) + + macro(INSTALL_ICON size) + install(FILES src/resources/icons/icon_${size}x${size}.png + DESTINATION ${PROJECTMSDL_ICONS_DIR}/${size}x${size}/apps + RENAME projectMSDL.png + COMPONENT projectMSDL + ) + endmacro() + + foreach(size 16 32 48 64 72 96 128 256) + install_icon(${size}) + endforeach() + + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_FLAT_PACKAGE) + set(ICNS_FILE ${CMAKE_BINARY_DIR}/projectMSDL.icns) + execute_process(COMMAND iconutil -c icns -o "${ICNS_FILE}" "${CMAKE_SOURCE_DIR}/src/resources/icons") + + install(FILES ${ICNS_FILE} + DESTINATION ${PROJECTMSDL_DATA_DIR} + COMPONENT projectMSDL + ) +endif() + +# Install optional presets +foreach(preset_dir ${PRESET_DIRS}) + install(DIRECTORY ${preset_dir} + DESTINATION "${PROJECTMSDL_PRESETS_DIR}" + COMPONENT projectMSDL + PATTERN *.md EXCLUDE + ) +endforeach() + +# Install optional textures +foreach(texture_dir ${TEXTURE_DIRS}) + install(DIRECTORY ${texture_dir} + DESTINATION "${PROJECTMSDL_TEXTURES_DIR}" + COMPONENT projectMSDL + PATTERN *.md EXCLUDE + ) +endforeach() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e454fb2..3fb61fd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,6 +43,10 @@ else() ) endif() +set_source_files_properties(ProjectMSDLApplication.cpp PROPERTIES + COMPILE_DEFINITIONS PROJECTMSDL_CONFIG_LOCATION=\"${DEFAULT_CONFIG_PATH}\" + ) + target_compile_definitions(projectMSDL PRIVATE PROJECTMSDL_VERSION="${PROJECT_VERSION}" diff --git a/src/ProjectMSDLApplication.cpp b/src/ProjectMSDLApplication.cpp index 4c7a16d..e8714df 100644 --- a/src/ProjectMSDLApplication.cpp +++ b/src/ProjectMSDLApplication.cpp @@ -45,26 +45,24 @@ void ProjectMSDLApplication::initialize(Poco::Util::Application& self) try { - if (loadConfiguration(PRIO_DEFAULT) == 0) + //if (loadConfiguration(PRIO_DEFAULT) == 0) { -#ifdef POCO_OS_FAMILY_UNIX - // In macOS bundles, the file may be located in the ../Resources dir, relative to the exe location. - Poco::Path configPath = config().getString("application.dir"); - configPath.makeDirectory().makeParent().append("Resources/").setFileName(configFileName); - if (Poco::File(configPath).exists()) + // The file may be located in the ../Resources bundle dir on macOS, elsewhere relative + // to the executable or within an absolute path. + // By setting and retrieving the compiled-in default, we can make use of POCO's variable replacement. + // This allows using ${application.dir} etc. in the path. + config().setString("application.defaultConfigurationFile", PROJECTMSDL_CONFIG_LOCATION); + std::string configPath = config().getString("application.defaultConfigurationFile", ""); + if (!configPath.empty()) { - loadConfiguration(configPath.toString(), PRIO_DEFAULT); - } - else - { - // On Linux, system-installed packages often put default configs in /usr/share - configPath.assign("/usr/share/projectM/").setFileName(configFileName); - if (Poco::File(configPath).exists()) + Poco::Path configFilePath(configPath); + configFilePath.makeDirectory().setFileName(configFileName); + if (Poco::File(configFilePath).exists()) { - loadConfiguration(configPath.toString(), PRIO_DEFAULT); + loadConfiguration(configFilePath.toString(), PRIO_DEFAULT); } + } -#endif } } catch (Poco::Exception& ex) diff --git a/src/ProjectMWrapper.cpp b/src/ProjectMWrapper.cpp index a2e5293..48211e4 100644 --- a/src/ProjectMWrapper.cpp +++ b/src/ProjectMWrapper.cpp @@ -4,6 +4,7 @@ #include "notifications/DisplayToastNotification.h" +#include #include #include @@ -66,7 +67,18 @@ void ProjectMWrapper::initialize(Poco::Util::Application& app) for (const auto& presetPath : presetPaths) { - projectm_playlist_add_path(_playlist, presetPath.c_str(), true, false); + Poco::File file(presetPath); + if (file.exists() && file.isFile()) + { + projectm_playlist_add_preset(_playlist, presetPath.c_str(), false); + } + else + { + // Symbolic links also fall under this. Without complex resolving, we can't + // be sure what the link exactly points to, especially if a trailing slash is missing. + projectm_playlist_add_path(_playlist, presetPath.c_str(), true, false); + } + } projectm_playlist_sort(_playlist, 0, projectm_playlist_size(_playlist), SORT_PREDICATE_FILENAME_ONLY, SORT_ORDER_ASCENDING); @@ -114,6 +126,15 @@ void ProjectMWrapper::RenderFrame() const glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + size_t currentMeshX{0}; + size_t currentMeshY{0}; + projectm_get_mesh_size(_projectM, ¤tMeshX, ¤tMeshY); + if (currentMeshX != _config->getInt("meshX", 220) || + currentMeshY != _config->getInt("meshY", 125)) + { + projectm_set_mesh_size(_projectM, _config->getInt("meshX", 220), _config->getInt("meshY", 125)); + } + projectm_opengl_render_frame(_projectM); } @@ -144,7 +165,7 @@ void ProjectMWrapper::PresetSwitchedEvent(bool isHardCut, unsigned int index, vo auto that = reinterpret_cast(context); auto presetName = projectm_playlist_item(that->_playlist, index); poco_information_f1(that->_logger, "Displaying preset: %s", std::string(presetName)); - projectm_free_string(presetName); + projectm_playlist_free_string(presetName); Poco::NotificationCenter::defaultCenter().postNotification(new UpdateWindowTitleNotification); } @@ -202,7 +223,11 @@ std::vector ProjectMWrapper::GetPathListWithDefault(const std::stri _config->keys(baseKey, subKeys); for (const auto& key : subKeys) { - pathList.push_back(_config->getString(baseKey + "." + key, "")); + auto path = _config->getString(baseKey + "." + key, ""); + if (!path.empty()) + { + pathList.push_back(std::move(path)); + } } return pathList; } diff --git a/src/SDLRenderingWindow.cpp b/src/SDLRenderingWindow.cpp index 294690e..3513245 100644 --- a/src/SDLRenderingWindow.cpp +++ b/src/SDLRenderingWindow.cpp @@ -313,10 +313,13 @@ void SDLRenderingWindow::UpdateWindowTitleNotificationHandler(POCO_UNUSED const auto presetName = projectm_playlist_item(projectMWrapper.Playlist(), projectm_playlist_get_position(projectMWrapper.Playlist())); - Poco::Path presetFile(presetName); - projectm_free_string(presetName); + if (presetName) + { + Poco::Path presetFile(presetName); + projectm_playlist_free_string(presetName); - newTitle += " ➫ " + presetFile.getBaseName(); + newTitle += " ➫ " + presetFile.getBaseName(); + } if (projectm_get_preset_locked(projectMWrapper.ProjectM())) { diff --git a/src/gui/SettingsWindow.cpp b/src/gui/SettingsWindow.cpp index 131ed3d..6b9d6c1 100644 --- a/src/gui/SettingsWindow.cpp +++ b/src/gui/SettingsWindow.cpp @@ -82,7 +82,7 @@ void SettingsWindow::Draw() ImGui::TableNextRow(); LabelWithTooltip("Per-Point Mesh Size X/Y", "Size of the per-point transformation grid.\nHigher values produce better quality, but require more CPU time to calculate."); - IntegerSettingVec("projectM.meshX", "projectM.meshY", 200, 125, 8, 250); + IntegerSettingVec("projectM.meshX", "projectM.meshY", 64, 48, 8, 300); ImGui::EndTable(); } diff --git a/src/resources/projectMSDL.desktop b/src/resources/projectMSDL.desktop new file mode 100644 index 0000000..7211a4b --- /dev/null +++ b/src/resources/projectMSDL.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Name=projectM +GenericName=Milkdrop-compatible Music Visualizer +Icon=projectMSDL +TryExec=projectMSDL +Exec=projectMSDL +Terminal=false +Categories=Audio;Video;AudioVideo +StartupWMClass=projectMSDL