mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-22 10:42:29 +01:00
Change ScreenPlayWallpaperLib to win32 only for now
Format documents Remove sysinfo from logging for now because it is windows only
This commit is contained in:
parent
e84e5d250e
commit
33c222da5d
@ -45,7 +45,6 @@ list(APPEND CMAKE_MODULE_PATH "${THIRD_PARTY_PATH}/ecm/find-modules")
|
|||||||
list(APPEND CMAKE_MODULE_PATH "${THIRD_PARTY_PATH}/ecm/kde-modules")
|
list(APPEND CMAKE_MODULE_PATH "${THIRD_PARTY_PATH}/ecm/kde-modules")
|
||||||
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
||||||
|
|
||||||
|
|
||||||
option(OSX_BUNDLE "Enable distribution macOS bundle" OFF)
|
option(OSX_BUNDLE "Enable distribution macOS bundle" OFF)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
|
||||||
|
|
||||||
@ -103,14 +102,12 @@ else()
|
|||||||
set(DATE_ARG "")
|
set(DATE_ARG "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
# Fixes QWebEngine linker errors on Ubuntu 22.04
|
# Fixes QWebEngine linker errors on Ubuntu 22.04
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${DATE_COMMAND} ${DATE_ARG}
|
COMMAND ${DATE_COMMAND} ${DATE_ARG}
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
|
@ -101,7 +101,6 @@ public slots:
|
|||||||
void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine);
|
void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine);
|
||||||
void setWizards(Wizards* wizards);
|
void setWizards(Wizards* wizards);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QNetworkAccessManager m_networkAccessManager;
|
QNetworkAccessManager m_networkAccessManager;
|
||||||
std::unique_ptr<QQmlApplicationEngine> m_mainWindowEngine;
|
std::unique_ptr<QQmlApplicationEngine> m_mainWindowEngine;
|
||||||
|
@ -40,7 +40,6 @@ public:
|
|||||||
int activeWidgetsCounter() const { return m_activeWidgetsCounter; }
|
int activeWidgetsCounter() const { return m_activeWidgetsCounter; }
|
||||||
bool isAnotherScreenPlayInstanceRunning() { return m_isAnotherScreenPlayInstanceRunning; }
|
bool isAnotherScreenPlayInstanceRunning() { return m_isAnotherScreenPlayInstanceRunning; }
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void activeWallpaperCounterChanged(int activeWallpaperCounter);
|
void activeWallpaperCounterChanged(int activeWallpaperCounter);
|
||||||
void activeWidgetsCounterChanged(int activeWidgetsCounter);
|
void activeWidgetsCounterChanged(int activeWidgetsCounter);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
|
|
||||||
#include "ScreenPlay/app.h"
|
#include "ScreenPlay/app.h"
|
||||||
|
#include "ScreenPlayUtil/logginghandler.h"
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
#include "ScreenPlayUtil/logginghandler.h"
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <sentry.h>
|
#include <sentry.h>
|
||||||
|
@ -483,8 +483,8 @@ Item {
|
|||||||
description: qsTr("If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime.")
|
description: qsTr("If your ScreenPlay missbehaves this is a good way to look for answers. This shows all logs and warning during runtime.")
|
||||||
buttonText: qsTr("Show Logs")
|
buttonText: qsTr("Show Logs")
|
||||||
onButtonPressed: {
|
onButtonPressed: {
|
||||||
const logsPath = StandardPaths.writableLocation(StandardPaths.GenericDataLocation) + "/ScreenPlay/Logs"
|
const logsPath = StandardPaths.writableLocation(StandardPaths.GenericDataLocation) + "/ScreenPlay/Logs";
|
||||||
App.util.openFolderInExplorer(logsPath)
|
App.util.openFolderInExplorer(logsPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +255,6 @@ bool Util::fileExists(const QString& filePath) const
|
|||||||
return file.isFile();
|
return file.isFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Takes ownership of \a obj and \a name. Tries to save into a text file
|
\brief Takes ownership of \a obj and \a name. Tries to save into a text file
|
||||||
with of name.
|
with of name.
|
||||||
|
@ -55,11 +55,11 @@ set(HEADER
|
|||||||
inc/public/ScreenPlayUtil/HelpersCommon.h
|
inc/public/ScreenPlayUtil/HelpersCommon.h
|
||||||
inc/public/ScreenPlayUtil/httpfileserver.h
|
inc/public/ScreenPlayUtil/httpfileserver.h
|
||||||
inc/public/ScreenPlayUtil/ListPropertyHelper.h
|
inc/public/ScreenPlayUtil/ListPropertyHelper.h
|
||||||
|
inc/public/ScreenPlayUtil/logginghandler.h
|
||||||
inc/public/ScreenPlayUtil/projectfile.h
|
inc/public/ScreenPlayUtil/projectfile.h
|
||||||
inc/public/ScreenPlayUtil/PropertyHelpers.h
|
inc/public/ScreenPlayUtil/PropertyHelpers.h
|
||||||
inc/public/ScreenPlayUtil/PtrPropertyHelpers.h
|
inc/public/ScreenPlayUtil/PtrPropertyHelpers.h
|
||||||
inc/public/ScreenPlayUtil/SingletonHelper.h
|
inc/public/ScreenPlayUtil/SingletonHelper.h
|
||||||
inc/public/ScreenPlayUtil/logginghandler.h
|
|
||||||
inc/public/ScreenPlayUtil/util.h)
|
inc/public/ScreenPlayUtil/util.h)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
@ -98,7 +98,10 @@ target_include_directories(
|
|||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
PUBLIC inc/public/
|
PUBLIC inc/public/
|
||||||
PRIVATE src/)
|
PRIVATE src/)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick PUBLIC fmt::fmt-header-only ScreenPlaySysInfo)
|
target_link_libraries(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PRIVATE Qt6::Core Qt6::Quick
|
||||||
|
PUBLIC fmt::fmt-header-only)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# Used for query windows monitor data
|
# Used for query windows monitor data
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ScreenPlayUtil/contenttypes.h"
|
#include "ScreenPlayUtil/contenttypes.h"
|
||||||
#include <QtGlobal>
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVersionNumber>
|
#include <QVersionNumber>
|
||||||
|
#include <QtGlobal>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
namespace ScreenPlayUtil {
|
namespace ScreenPlayUtil {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "ScreenPlayUtil/logginghandler.h"
|
#include "ScreenPlayUtil/logginghandler.h"
|
||||||
#include "sysinfo.h"
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -9,10 +8,15 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <fmt/color.h>
|
#include <fmt/color.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class ScreenPlayUtil::LoggingHandler
|
\class ScreenPlayUtil::LoggingHandler
|
||||||
\inmodule core
|
|
||||||
\brief The LoggingHandler class writes logs to the console and a log file.
|
\brief The LoggingHandler class writes logs to the console and a log file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -48,7 +52,6 @@ void LoggingHandler::start()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(!m_logFileName.isEmpty());
|
Q_ASSERT(!m_logFileName.isEmpty());
|
||||||
|
|
||||||
// Use hardcoded path for now because QStandardpaths gives us: 'C:/ProgramData/K3000'
|
|
||||||
QDir directory;
|
QDir directory;
|
||||||
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
|
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
|
||||||
directory = QDir(cacheDir + "/ScreenPlay/Logs");
|
directory = QDir(cacheDir + "/ScreenPlay/Logs");
|
||||||
@ -78,29 +81,6 @@ void LoggingHandler::start()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SysInfo sysInfo;
|
|
||||||
QTextStream stream(&logFile());
|
|
||||||
stream << "Start ScreenPlay logging " << QDateTime::currentDateTime().toString("dd.MM.yyyy-hh:mm:ss.zzz") << "\n";
|
|
||||||
stream << "version: 1.0\n";
|
|
||||||
stream << "buildAbi: " << QSysInfo::buildAbi() << "\n";
|
|
||||||
stream << "buildCpuArchitecture: " << QSysInfo::buildCpuArchitecture() << "\n";
|
|
||||||
stream << "currentCpuArchitecture: " << QSysInfo::currentCpuArchitecture() << "\n";
|
|
||||||
stream << "kernelType: " << QSysInfo::kernelType() << "\n";
|
|
||||||
stream << "kernelVersion: " << QSysInfo::kernelVersion() << "\n";
|
|
||||||
stream << "machineHostName: " << QSysInfo::machineHostName() << "\n";
|
|
||||||
stream << "machineUniqueId: " << QSysInfo::machineUniqueId() << "\n";
|
|
||||||
stream << "prettyProductName: " << QSysInfo::prettyProductName() << "\n";
|
|
||||||
stream << "productType: " << QSysInfo::productType() << "\n";
|
|
||||||
stream << "productVersion: " << QSysInfo::productVersion() << "\n";
|
|
||||||
stream << "GPU Name: " << sysInfo.gpu()->name() << "\n";
|
|
||||||
stream << "GPU Vendor: " << sysInfo.gpu()->vendor() << "\n";
|
|
||||||
stream << "GPU ramSize: " << QString::number(sysInfo.gpu()->ramSize()) << "\n";
|
|
||||||
stream << "GPU cacheSize: " << QString::number(sysInfo.gpu()->cacheSize()) << "\n";
|
|
||||||
stream << "GPU maxFrequency: " << QString::number(sysInfo.gpu()->maxFrequency()) << "\n";
|
|
||||||
stream << QString("Uptime: %1 days %2 hours %3 minutes %4 seconds").arg(sysInfo.uptime()->days()).arg(sysInfo.uptime()->hours()).arg(sysInfo.uptime()->minutes()).arg(sysInfo.uptime()->seconds()) << "\n";
|
|
||||||
|
|
||||||
|
|
||||||
const auto now = QLocale().toString(QDateTime::currentDateTime(), QLocale::FormatType::ShortFormat);
|
const auto now = QLocale().toString(QDateTime::currentDateTime(), QLocale::FormatType::ShortFormat);
|
||||||
const auto message = QString { "[%1] Start logging\n" }.arg(now);
|
const auto message = QString { "[%1] Start logging\n" }.arg(now);
|
||||||
logFile().write(message.toStdString().c_str());
|
logFile().write(message.toStdString().c_str());
|
||||||
|
@ -7,8 +7,7 @@ set(CMAKE_AUTOMOC ON)
|
|||||||
|
|
||||||
find_package(
|
find_package(
|
||||||
Qt6
|
Qt6
|
||||||
COMPONENTS
|
COMPONENTS Core
|
||||||
Core
|
|
||||||
Quick
|
Quick
|
||||||
Gui
|
Gui
|
||||||
Widgets
|
Widgets
|
||||||
@ -55,25 +54,18 @@ set(LIB_HEADER)
|
|||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(LIB_SOURCES src/windowsintegration.cpp)
|
set(LIB_SOURCES src/windowsintegration.cpp)
|
||||||
set(LIB_HEADER src/windowsintegration.h)
|
set(LIB_HEADER src/windowsintegration.h)
|
||||||
elseif(APPLE)
|
add_library(ScreenPlayWallpaperLib STATIC ${LIB_SOURCES} ${LIB_HEADER})
|
||||||
set(LIB_SOURCES src/macintegration.cpp)
|
target_include_directories(ScreenPlayWallpaperLib PUBLIC src)
|
||||||
set(LIB_HEADER src/macintegration.h)
|
|
||||||
elseif(UNIX)
|
|
||||||
#set(LIB_SOURCES src/waylandintegration.cpp)
|
|
||||||
#set(LIB_HEADER src/waylandintegration.h)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(ScreenPlayWallpaperLib STATIC ${LIB_SOURCES} ${LIB_HEADER})
|
|
||||||
target_include_directories(ScreenPlayWallpaperLib PUBLIC src)
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
# Used for query windows monitor data
|
# Used for query windows monitor data
|
||||||
target_link_libraries(ScreenPlayWallpaperLib PUBLIC shcore.lib)
|
target_link_libraries(ScreenPlayWallpaperLib PUBLIC shcore.lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_executable(
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADER}
|
${PROJECT_NAME}
|
||||||
src/windowsintegration.h src/windowsintegration.cpp)
|
${SOURCES}
|
||||||
|
${HEADER}
|
||||||
|
src/windowsintegration.h
|
||||||
|
src/windowsintegration.cpp)
|
||||||
|
|
||||||
qt_add_qml_module(
|
qt_add_qml_module(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
@ -92,9 +84,7 @@ qt_add_qml_module(
|
|||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE ScreenPlaySDK
|
||||||
ScreenPlaySDK
|
|
||||||
ScreenPlayWallpaperLib
|
|
||||||
ScreenPlayUtil
|
ScreenPlayUtil
|
||||||
ScreenPlayWeatherplugin
|
ScreenPlayWeatherplugin
|
||||||
Qt6::Quick
|
Qt6::Quick
|
||||||
@ -108,18 +98,20 @@ target_link_libraries(
|
|||||||
Qt6::WebEngineQuick)
|
Qt6::WebEngineQuick)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin)
|
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin ScreenPlayWallpaperLib)
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE X11)
|
target_link_libraries(${PROJECT_NAME} PRIVATE X11)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
find_package(ECM CONFIG REQUIRED NO_MODULE)
|
find_package(
|
||||||
|
ECM
|
||||||
|
CONFIG
|
||||||
|
REQUIRED
|
||||||
|
NO_MODULE)
|
||||||
set(LayerShellQt "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/layer-shell-qt/")
|
set(LayerShellQt "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/layer-shell-qt/")
|
||||||
find_package(LayerShellQt REQUIRED)
|
find_package(LayerShellQt REQUIRED)
|
||||||
target_link_libraries(
|
target_link_libraries(${PROJECT_NAME} PRIVATE LayerShellQtInterface)
|
||||||
${PROJECT_NAME}
|
|
||||||
PRIVATE LayerShellQtInterface)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
@ -20,37 +20,31 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
|||||||
# Output compile commands to compile_commands.json (for debugging CMake issues)
|
# Output compile commands to compile_commands.json (for debugging CMake issues)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
# Build universal lib on macOS
|
# Build universal lib on macOS Note that CMAKE_OSX_ARCHITECTURES must be set before project().
|
||||||
# Note that CMAKE_OSX_ARCHITECTURES must be set before project().
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
set(CMAKE_OSX_ARCHITECTURES
|
||||||
|
"x86_64;arm64"
|
||||||
|
CACHE STRING "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Main project information
|
# Main project information
|
||||||
project(ScreenPlayGodotWallpaper
|
project(ScreenPlayGodotWallpaper LANGUAGES CXX)
|
||||||
LANGUAGES
|
|
||||||
CXX
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create our library
|
# Create our library
|
||||||
add_library(${PROJECT_NAME} SHARED)
|
add_library(${PROJECT_NAME} SHARED)
|
||||||
|
|
||||||
target_compile_features(${PROJECT_NAME}
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
||||||
PRIVATE
|
|
||||||
cxx_std_17
|
|
||||||
)
|
|
||||||
|
|
||||||
# LIB_ARCH is the architecture being built. It is set to the build system's architecture.
|
# LIB_ARCH is the architecture being built. It is set to the build system's architecture. For macOS, we build a universal library (both
|
||||||
# For macOS, we build a universal library (both arm64 and x86_64).
|
# arm64 and x86_64).
|
||||||
set(LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
set(LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(LIB_ARCH "universal")
|
set(LIB_ARCH "universal")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# LIB_DIR is where the actual library ends up. This is used in both the build directory and the
|
# LIB_DIR is where the actual library ends up. This is used in both the build directory and the install directory and needs to be consistent
|
||||||
# install directory and needs to be consistent with the paths in the gdextension file.
|
# with the paths in the gdextension file. e.g. linux.release.x86_64 = "lib/Linux-x86_64/libGDExtensionTemplate.so"
|
||||||
# e.g. linux.release.x86_64 = "lib/Linux-x86_64/libGDExtensionTemplate.so"
|
|
||||||
set(LIB_DIR "lib/${CMAKE_SYSTEM_NAME}-${LIB_ARCH}")
|
set(LIB_DIR "lib/${CMAKE_SYSTEM_NAME}-${LIB_ARCH}")
|
||||||
|
|
||||||
message(STATUS "Building ${PROJECT_NAME} for ${LIB_ARCH} on ${CMAKE_SYSTEM_NAME}")
|
message(STATUS "Building ${PROJECT_NAME} for ${LIB_ARCH} on ${CMAKE_SYSTEM_NAME}")
|
||||||
@ -60,19 +54,15 @@ set(BUILD_OUTPUT_DIR "${PROJECT_BINARY_DIR}/${PROJECT_NAME}/")
|
|||||||
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlayGodot/${PROJECT_NAME}/)
|
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||||
|
|
||||||
# Compile directly into our Godot project
|
# Compile directly into our Godot project
|
||||||
set_target_properties(${PROJECT_NAME}
|
set_target_properties(
|
||||||
PROPERTIES
|
${PROJECT_NAME}
|
||||||
CXX_VISIBILITY_PRESET hidden
|
PROPERTIES CXX_VISIBILITY_PRESET hidden
|
||||||
VISIBILITY_INLINES_HIDDEN true
|
VISIBILITY_INLINES_HIDDEN true
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
LIBRARY_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}")
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||||
set_target_properties(${PROJECT_NAME}
|
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "-d")
|
||||||
PROPERTIES
|
|
||||||
DEBUG_POSTFIX "-d"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Warnings
|
# Warnings
|
||||||
@ -88,16 +78,13 @@ set(INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/")
|
|||||||
|
|
||||||
add_subdirectory(templates)
|
add_subdirectory(templates)
|
||||||
|
|
||||||
# ccache
|
# ccache Turns on ccache if found
|
||||||
# Turns on ccache if found
|
|
||||||
include(ccache)
|
include(ccache)
|
||||||
|
|
||||||
# Formatting
|
# Formatting Adds a custom target to format all the code at once
|
||||||
# Adds a custom target to format all the code at once
|
|
||||||
include(ClangFormat)
|
include(ClangFormat)
|
||||||
|
|
||||||
# godot-cpp
|
# godot-cpp From here: https://github.com/godotengine/godot-cpp
|
||||||
# From here: https://github.com/godotengine/godot-cpp
|
|
||||||
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/extern/godot-cpp/Makefile")
|
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/extern/godot-cpp/Makefile")
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR
|
FATAL_ERROR
|
||||||
@ -105,17 +92,13 @@ if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/extern/godot-cpp/Makefile")
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GODOT_CPP_SYSTEM_HEADERS ON CACHE BOOL "" FORCE)
|
set(GODOT_CPP_SYSTEM_HEADERS
|
||||||
|
ON
|
||||||
|
CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
add_subdirectory(extern/godot-cpp)
|
add_subdirectory(extern/godot-cpp)
|
||||||
|
|
||||||
set_target_properties(godot-cpp
|
set_target_properties(godot-cpp PROPERTIES CXX_VISIBILITY_PRESET hidden # visibility needs to be the same as the main library
|
||||||
PROPERTIES
|
|
||||||
CXX_VISIBILITY_PRESET hidden # visibility needs to be the same as the main library
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME} PRIVATE godot-cpp ScreenPlayWallpaperLib)
|
||||||
PRIVATE
|
|
||||||
godot-cpp
|
|
||||||
ScreenPlayWallpaperLib
|
|
||||||
)
|
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
target_sources(
|
||||||
PRIVATE
|
${PROJECT_NAME}
|
||||||
ScreenPlayGodotWallpaper.h
|
PRIVATE ScreenPlayGodotWallpaper.h
|
||||||
ScreenPlayGodotWallpaper.cpp
|
ScreenPlayGodotWallpaper.cpp
|
||||||
WindowsPipe.h
|
WindowsPipe.h
|
||||||
WindowsPipe.cpp
|
WindowsPipe.cpp
|
||||||
RegisterExtension.cpp
|
RegisterExtension.cpp)
|
||||||
)
|
|
||||||
find_package(Catch2 CONFIG REQUIRED)
|
find_package(Catch2 CONFIG REQUIRED)
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME} PRIVATE "src")
|
||||||
PRIVATE
|
|
||||||
"src"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test app. Start WindowsPipeTestServer.py!
|
# Test app. Start WindowsPipeTestServer.py!
|
||||||
add_executable(WindowsPipeTest WindowsPipeTest.cpp WindowsPipe.h WindowsPipe.cpp)
|
add_executable(WindowsPipeTest WindowsPipe.cpp WindowsPipe.h WindowsPipeTest.cpp)
|
||||||
target_link_libraries(WindowsPipeTest PRIVATE Catch2::Catch2 Catch2::Catch2WithMain)
|
target_link_libraries(WindowsPipeTest PRIVATE Catch2::Catch2 Catch2::Catch2WithMain)
|
||||||
target_include_directories(WindowsPipeTest PRIVATE "src")
|
target_include_directories(WindowsPipeTest PRIVATE "src")
|
@ -82,10 +82,10 @@ bool ScreenPlayGodotWallpaper::init(int activeScreen)
|
|||||||
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
||||||
|
|
||||||
WindowsIntegration windowsIntegration;
|
WindowsIntegration windowsIntegration;
|
||||||
auto updateWindowSize = [this, &displayServer](const int width, const int height){
|
auto updateWindowSize = [this, &displayServer](const int width, const int height) {
|
||||||
displayServer->window_set_size(godot::Vector2((real_t)width, (real_t)height));
|
displayServer->window_set_size(godot::Vector2((real_t)width, (real_t)height));
|
||||||
};
|
};
|
||||||
std::optional<Monitor> monitor = windowsIntegration.setupWallpaperForOneScreen(activeScreen,m_hook->windowHandle,m_hook->windowHandleWorker,updateWindowSize);
|
std::optional<Monitor> monitor = windowsIntegration.setupWallpaperForOneScreen(activeScreen, m_hook->windowHandle, m_hook->windowHandleWorker, updateWindowSize);
|
||||||
|
|
||||||
const std::string windowTitle = "ScreenPlayWallpaperGodot";
|
const std::string windowTitle = "ScreenPlayWallpaperGodot";
|
||||||
SetWindowText(hwnd, windowTitle.c_str());
|
SetWindowText(hwnd, windowTitle.c_str());
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "godot_cpp/classes/control.hpp"
|
#include "godot_cpp/classes/control.hpp"
|
||||||
#include "godot_cpp/classes/global_constants.hpp"
|
#include "godot_cpp/classes/global_constants.hpp"
|
||||||
#include "godot_cpp/classes/timer.hpp"
|
#include "godot_cpp/classes/timer.hpp"
|
||||||
@ -14,8 +18,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ScreenPlayGodotWallpaper.h"
|
#include "ScreenPlayGodotWallpaper.h"
|
||||||
#include "windowsintegration.h"
|
|
||||||
#include "WindowsPipe.h"
|
#include "WindowsPipe.h"
|
||||||
|
#include "windowsintegration.h"
|
||||||
|
|
||||||
class ScreenPlayGodotWallpaper : public godot::Node {
|
class ScreenPlayGodotWallpaper : public godot::Node {
|
||||||
GDCLASS(ScreenPlayGodotWallpaper, Node)
|
GDCLASS(ScreenPlayGodotWallpaper, Node)
|
||||||
@ -54,7 +58,6 @@ private:
|
|||||||
void hideFromTaskbar(HWND hwnd);
|
void hideFromTaskbar(HWND hwnd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
OVERLAPPED overlappedRead = {};
|
OVERLAPPED overlappedRead = {};
|
||||||
OVERLAPPED overlappedWrite = {};
|
OVERLAPPED overlappedWrite = {};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "WindowsPipe.h"
|
#include "WindowsPipe.h"
|
||||||
|
|
||||||
bool WindowsPipe::connectToPipe() {
|
bool WindowsPipe::connectToPipe()
|
||||||
|
{
|
||||||
if (m_pipeName.empty()) {
|
if (m_pipeName.empty()) {
|
||||||
std::cerr << "Pipe name not set." << std::endl;
|
std::cerr << "Pipe name not set." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
@ -25,7 +26,8 @@ bool WindowsPipe::connectToPipe() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsPipe::readFromPipe(std::string& outMessage) {
|
bool WindowsPipe::readFromPipe(std::string& outMessage)
|
||||||
|
{
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
DWORD bytesRead;
|
DWORD bytesRead;
|
||||||
|
|
||||||
@ -52,8 +54,8 @@ bool WindowsPipe::readFromPipe(std::string& outMessage) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WindowsPipe::writeToPipe(const std::string& message)
|
||||||
bool WindowsPipe::writeToPipe(const std::string& message) {
|
{
|
||||||
DWORD bytesWritten;
|
DWORD bytesWritten;
|
||||||
|
|
||||||
if (!WriteFile(m_hPipe, message.c_str(), static_cast<DWORD>(message.size()), &bytesWritten, &m_overlapped)) {
|
if (!WriteFile(m_hPipe, message.c_str(), static_cast<DWORD>(message.size()), &bytesWritten, &m_overlapped)) {
|
||||||
|
@ -21,7 +21,7 @@ TEST_CASE("Test WindowsPipe with Python echo server", "[WindowsPipe]")
|
|||||||
std::string response;
|
std::string response;
|
||||||
REQUIRE(client.readFromPipe(response));
|
REQUIRE(client.readFromPipe(response));
|
||||||
REQUIRE(response == "pong;");
|
REQUIRE(response == "pong;");
|
||||||
std::cout << response <<"ok\n";
|
std::cout << response << "ok\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
# SPDX-License-Identifier: Unlicense
|
# SPDX-License-Identifier: Unlicense
|
||||||
|
|
||||||
add_custom_target(templates
|
add_custom_target(templates SOURCES template.debug.gdextension.in template.release.gdextension.in)
|
||||||
SOURCES
|
|
||||||
template.debug.gdextension.in
|
|
||||||
template.release.gdextension.in
|
|
||||||
)
|
|
||||||
|
|
||||||
add_dependencies(${PROJECT_NAME} templates)
|
add_dependencies(${PROJECT_NAME} templates)
|
||||||
|
|
||||||
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25)
|
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25) But until we fix it here and
|
||||||
# But until we fix it here and in godot-cpp, ensure it's one we expect.
|
# in godot-cpp, ensure it's one we expect.
|
||||||
set(ALLOWED_BUILDS "Debug;Release;debug;release")
|
set(ALLOWED_BUILDS "Debug;Release;debug;release")
|
||||||
|
|
||||||
if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST ALLOWED_BUILDS)
|
if(NOT
|
||||||
|
"${CMAKE_BUILD_TYPE}"
|
||||||
|
IN_LIST
|
||||||
|
ALLOWED_BUILDS)
|
||||||
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release")
|
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ endif()
|
|||||||
# Generate our project's .gdextension file from the template
|
# Generate our project's .gdextension file from the template
|
||||||
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../ScreenPlayGodot/${PROJECT_NAME}/)
|
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||||
set(GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension)
|
set(GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension)
|
||||||
#configure_file(${GD_EXTENSION_FILE_INPUT} ${OUT_PATH}/${GD_EXTENSION_FILE})
|
# configure_file(${GD_EXTENSION_FILE_INPUT} ${OUT_PATH}/${GD_EXTENSION_FILE})
|
||||||
|
|
||||||
unset(ALLOWED_BUILDS)
|
unset(ALLOWED_BUILDS)
|
||||||
unset(BUILD_TYPE)
|
unset(BUILD_TYPE)
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
#include "ScreenPlayWallpaper/CMakeVariables.h"
|
#include "ScreenPlayWallpaper/CMakeVariables.h"
|
||||||
|
|
||||||
#include "ScreenPlayUtil/exitcodes.h"
|
#include "ScreenPlayUtil/exitcodes.h"
|
||||||
#include "ScreenPlayUtil/util.h"
|
|
||||||
#include "ScreenPlayUtil/logginghandler.h"
|
#include "ScreenPlayUtil/logginghandler.h"
|
||||||
|
#include "ScreenPlayUtil/util.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include "src/winwindow.h"
|
#include "src/winwindow.h"
|
||||||
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
#include "src/linuxx11window.h"
|
|
||||||
#include "src/linuxwaylandwindow.h"
|
#include "src/linuxwaylandwindow.h"
|
||||||
|
#include "src/linuxx11window.h"
|
||||||
#elif defined(Q_OS_OSX)
|
#elif defined(Q_OS_OSX)
|
||||||
#include "src/macwindow.h"
|
#include "src/macwindow.h"
|
||||||
#endif
|
#endif
|
||||||
@ -44,9 +44,9 @@ int main(int argc, char* argv[])
|
|||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
window = std::make_unique<WinWindow>();
|
window = std::make_unique<WinWindow>();
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
if(platformName == "xcb"){
|
if (platformName == "xcb") {
|
||||||
window = std::make_unique<LinuxX11Window>();
|
window = std::make_unique<LinuxX11Window>();
|
||||||
} else if(platformName == "wayland"){
|
} else if (platformName == "wayland") {
|
||||||
window = std::make_unique<LinuxWaylandWindow>();
|
window = std::make_unique<LinuxWaylandWindow>();
|
||||||
}
|
}
|
||||||
#elif defined(Q_OS_OSX)
|
#elif defined(Q_OS_OSX)
|
||||||
|
@ -35,7 +35,6 @@ BaseWindow::BaseWindow()
|
|||||||
"VideoCodec",
|
"VideoCodec",
|
||||||
"Error: only enums");
|
"Error: only enums");
|
||||||
|
|
||||||
|
|
||||||
setOSVersion(QSysInfo::productVersion());
|
setOSVersion(QSysInfo::productVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
#include "linuxwaylandwindow.h"
|
#include "linuxwaylandwindow.h"
|
||||||
#include <QScreen>
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
#include <LayerShellQt/Window>
|
|
||||||
#include <LayerShellQt/Shell>
|
#include <LayerShellQt/Shell>
|
||||||
|
#include <LayerShellQt/Window>
|
||||||
|
|
||||||
ScreenPlay::WallpaperExitCode LinuxWaylandWindow::start()
|
ScreenPlay::WallpaperExitCode LinuxWaylandWindow::start()
|
||||||
{
|
{
|
||||||
@ -22,20 +22,12 @@ ScreenPlay::WallpaperExitCode LinuxWaylandWindow::start()
|
|||||||
|
|
||||||
// Get the Wayland display
|
// Get the Wayland display
|
||||||
if (QGuiApplication::platformName() == "wayland") {
|
if (QGuiApplication::platformName() == "wayland") {
|
||||||
QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface();
|
QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
|
||||||
|
|
||||||
|
auto* layerShell = LayerShellQt::Window::get(&m_window);
|
||||||
auto *layerShell = LayerShellQt::Window::get(&m_window);
|
|
||||||
layerShell->setLayer(LayerShellQt::Window::LayerBackground);
|
layerShell->setLayer(LayerShellQt::Window::LayerBackground);
|
||||||
layerShell->setAnchors(static_cast<QFlags<LayerShellQt::Window::Anchor>>(
|
layerShell->setAnchors(static_cast<QFlags<LayerShellQt::Window::Anchor>>(
|
||||||
LayerShellQt::Window::Anchor::AnchorTop |
|
LayerShellQt::Window::Anchor::AnchorTop | LayerShellQt::Window::Anchor::AnchorBottom | LayerShellQt::Window::Anchor::AnchorLeft | LayerShellQt::Window::Anchor::AnchorRight));
|
||||||
LayerShellQt::Window::Anchor::AnchorBottom |
|
|
||||||
LayerShellQt::Window::Anchor::AnchorLeft |
|
|
||||||
LayerShellQt::Window::Anchor::AnchorRight
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_window.show();
|
m_window.show();
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include "windowsintegration.h"
|
#include "windowsintegration.h"
|
||||||
|
|
||||||
|
|
||||||
bool WindowsIntegration::searchWorkerWindowToParentTo()
|
bool WindowsIntegration::searchWorkerWindowToParentTo()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -91,7 +89,8 @@ BOOL SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Monitor> WindowsIntegration::GetAllMonitors() {
|
std::vector<Monitor> WindowsIntegration::GetAllMonitors()
|
||||||
|
{
|
||||||
std::vector<Monitor> monitors;
|
std::vector<Monitor> monitors;
|
||||||
|
|
||||||
// Use the static MonitorEnumProc callback for EnumDisplayMonitors
|
// Use the static MonitorEnumProc callback for EnumDisplayMonitors
|
||||||
@ -100,6 +99,234 @@ std::vector<Monitor> WindowsIntegration::GetAllMonitors() {
|
|||||||
return monitors;
|
return monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WindowsIntegration::GetMonitorIndex(HMONITOR hMonitor)
|
||||||
|
{
|
||||||
|
sEnumInfo info;
|
||||||
|
info.hMonitor = hMonitor;
|
||||||
|
|
||||||
|
if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM)&info))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return info.iIndex;
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
\brief This method is called via a fixed interval to detect if a window completely
|
||||||
|
covers a monitor. If then sets visualPaused for QML to pause the content.
|
||||||
|
*/
|
||||||
|
bool WindowsIntegration::checkForFullScreenWindow(HWND windowHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
HWND hFoundWnd = nullptr;
|
||||||
|
EnumWindows(&FindTheDesiredWnd, reinterpret_cast<LPARAM>(&hFoundWnd));
|
||||||
|
|
||||||
|
// True if one window has WS_MAXIMIZE
|
||||||
|
if (hFoundWnd != nullptr) {
|
||||||
|
DWORD dwFlags = 0;
|
||||||
|
HMONITOR monitor = MonitorFromWindow(hFoundWnd, dwFlags);
|
||||||
|
HMONITOR wallpaper = MonitorFromWindow(windowHandle, dwFlags);
|
||||||
|
int monitorIndex = GetMonitorIndex(monitor);
|
||||||
|
int wallpaperIndex = GetMonitorIndex(wallpaper);
|
||||||
|
// qDebug() << monitorIndex << wallpaperIndex;
|
||||||
|
|
||||||
|
// If the window that has WS_MAXIMIZE is at the same monitor as this wallpaper
|
||||||
|
return monitorIndex == wallpaperIndex;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Adjusting a Window's Position and Size for Different Monitor DPI Scale Factors:
|
||||||
|
* * Windows allows users to set different DPI (dots per inch) scale factors for each monitor. This DPI scaling can lead to
|
||||||
|
* discrepancies in the positioning and size of windows, especially if we want to place a window on a monitor with a different
|
||||||
|
* scale factor than the one it was originally on.
|
||||||
|
* * In our scenario, we want to move and resize a window (`windowHwnd`) to fit perfectly within a target monitor. However,
|
||||||
|
* both the window and the target monitor can have different DPI scale factors, so we need to account for these when calculating
|
||||||
|
* the window's new position and size.
|
||||||
|
* * Steps:
|
||||||
|
* * 1. Retrieve the DPI scale factor for the window:
|
||||||
|
* - This gives us the current scale factor of the window based on its original monitor.
|
||||||
|
* * 2. Retrieve the DPI scale factor for the target monitor:
|
||||||
|
* - This gives us the scale factor of the monitor where we want to place the window.
|
||||||
|
* * 3. Calculate the window's new position:
|
||||||
|
* - The new position should be relative to the `WorkerW` window's coordinates.
|
||||||
|
* - Adjust the position based on the ratio of the window's DPI scale factor to the target monitor's DPI scale factor.
|
||||||
|
* This ensures that the window is positioned correctly on the monitor regardless of any differences in scale factors.
|
||||||
|
* * 4. Calculate the window's new size:
|
||||||
|
* - Adjust the size of the window based on the ratio of the window's DPI scale factor to the target monitor's DPI scale factor.
|
||||||
|
* This ensures that the window fits perfectly within the monitor, taking into account any differences in scale factors.
|
||||||
|
* * By following this approach, we can accurately position and resize the window on any monitor, regardless of differences in DPI
|
||||||
|
* scale factors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::optional<Monitor> WindowsIntegration::setupWallpaperForOneScreen(const int activeScreen, HWND windowHwnd, HWND parentWindowHwnd, std::function<void(int, int)> updateWindowSize)
|
||||||
|
{
|
||||||
|
std::vector<Monitor> monitors = GetAllMonitors();
|
||||||
|
for (const auto& monitor : monitors) {
|
||||||
|
monitor.print();
|
||||||
|
if (monitor.index != activeScreen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SetWindowPos(windowHwnd, HWND_TOP,
|
||||||
|
monitor.position.left, monitor.position.top,
|
||||||
|
monitor.size.cx, monitor.size.cy,
|
||||||
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
|
||||||
|
// Must be called here to fix window positions!
|
||||||
|
updateWindowSize(monitor.size.cx, monitor.size.cy);
|
||||||
|
|
||||||
|
RECT oldRect;
|
||||||
|
GetWindowRect(windowHwnd, &oldRect);
|
||||||
|
std::cout << "Old Window Position: (" << oldRect.left << ", " << oldRect.top << ")" << std::endl;
|
||||||
|
|
||||||
|
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
||||||
|
float targetMonitorDpiScaleFactor = monitor.scaleFactor;
|
||||||
|
std::cout << "Window DPI Scale Factor: " << windowDpiScaleFactor << std::endl;
|
||||||
|
std::cout << "Target Monitor DPI Scale Factor: " << targetMonitorDpiScaleFactor << std::endl;
|
||||||
|
|
||||||
|
SetParent(windowHwnd, parentWindowHwnd);
|
||||||
|
RECT parentRect;
|
||||||
|
GetWindowRect(parentWindowHwnd, &parentRect);
|
||||||
|
std::cout << "WorkerW Window Position: (" << parentRect.left << ", " << parentRect.top << ")" << std::endl;
|
||||||
|
|
||||||
|
int newX = static_cast<int>((oldRect.left - parentRect.left) * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
||||||
|
int newY = static_cast<int>((oldRect.top - parentRect.top) * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
||||||
|
std::cout << "Calculated New Position: (" << newX << ", " << newY << ")" << std::endl;
|
||||||
|
|
||||||
|
int newWidth = static_cast<int>(monitor.size.cx * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
||||||
|
int newHeight = static_cast<int>(monitor.size.cy * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
||||||
|
std::cout << "Calculated New Size: (" << newWidth << "x" << newHeight << ")" << std::endl;
|
||||||
|
|
||||||
|
SetWindowPos(windowHwnd, NULL, newX, newY, newWidth, newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
return { monitor };
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Spans the window across multiple monitors.
|
||||||
|
* * This function takes a vector of monitor indices and adjusts the window's
|
||||||
|
* size and position to span across the specified monitors. It determines the
|
||||||
|
* window's new size by finding the bounding rectangle that covers all selected
|
||||||
|
* monitors. The window's new position is set to the top-left corner of this
|
||||||
|
* bounding rectangle.
|
||||||
|
* * Note: This function assumes that all monitors have the same DPI scaling. If
|
||||||
|
* they don't, the window may not fit perfectly across the monitors.
|
||||||
|
* * @param activeScreens A vector containing the indices of monitors across
|
||||||
|
* which the window should span.
|
||||||
|
* * Usage:
|
||||||
|
* setupWallpaperForMultipleScreens({0, 1}); // Spans the window across monitors 0 and 1.
|
||||||
|
* * Internals:
|
||||||
|
* 1. For each monitor in `activeScreens`, determine its bounding rectangle.
|
||||||
|
* 2. Compute the window's new width as `rightmost - leftmost` and its new
|
||||||
|
* height as `bottommost - topmost`.
|
||||||
|
* 3. Adjust the window's position and size to fit this bounding rectangle.
|
||||||
|
*/
|
||||||
|
WindowsIntegration::SpanResult WindowsIntegration::setupWallpaperForMultipleScreens(const std::vector<int>& activeScreens, HWND windowHwnd, HWND parentWindowHwnd)
|
||||||
|
{
|
||||||
|
std::vector<Monitor> monitors = GetAllMonitors();
|
||||||
|
|
||||||
|
int leftmost = INT_MAX;
|
||||||
|
int topmost = INT_MAX;
|
||||||
|
int rightmost = INT_MIN;
|
||||||
|
int bottommost = INT_MIN;
|
||||||
|
|
||||||
|
for (const auto& monitorIndex : activeScreens) {
|
||||||
|
if (monitorIndex < monitors.size()) {
|
||||||
|
const Monitor& monitor = monitors[monitorIndex];
|
||||||
|
leftmost = (std::min)(leftmost, static_cast<int>(monitor.position.left));
|
||||||
|
topmost = (std::min)(topmost, static_cast<int>(monitor.position.top));
|
||||||
|
rightmost = (std::max)(rightmost, static_cast<int>(monitor.position.right));
|
||||||
|
bottommost = (std::max)(bottommost, static_cast<int>(monitor.position.bottom));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int newWidth = rightmost - leftmost;
|
||||||
|
int newHeight = bottommost - topmost;
|
||||||
|
|
||||||
|
RECT oldRect;
|
||||||
|
GetWindowRect(windowHwnd, &oldRect);
|
||||||
|
|
||||||
|
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
||||||
|
|
||||||
|
SetParent(windowHwnd, parentWindowHwnd);
|
||||||
|
RECT parentRect;
|
||||||
|
GetWindowRect(parentWindowHwnd, &parentRect);
|
||||||
|
|
||||||
|
int newX = static_cast<int>((leftmost - parentRect.left) * windowDpiScaleFactor);
|
||||||
|
int newY = static_cast<int>((topmost - parentRect.top) * windowDpiScaleFactor);
|
||||||
|
|
||||||
|
SetWindowPos(windowHwnd, NULL, newX, newY, newWidth, newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
SpanResult result;
|
||||||
|
result.width = rightmost - leftmost;
|
||||||
|
result.height = bottommost - topmost;
|
||||||
|
result.success = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets up the wallpaper to span across all connected screens.
|
||||||
|
* * This function retrieves information about all connected monitors, including their positions, dimensions, and scale factors.
|
||||||
|
* It then calculates the combined dimensions needed to span the window across all these monitors, taking into account
|
||||||
|
* the scale factors. The function also handles reparenting the window to the WorkerW window, ensuring it remains below
|
||||||
|
* other desktop icons. The calculated position and dimensions are adjusted to account for any potential scaling differences
|
||||||
|
* between the window and the combined monitor setup.
|
||||||
|
* * @note This function assumes that the window's DPI scale factor is based on a default of 96 DPI. Adjustments are made
|
||||||
|
* based on this assumption.
|
||||||
|
* * @note The function currently multiplies the scale factors of all monitors to get an overall scale factor. This may need
|
||||||
|
* adjustments based on specific application needs.
|
||||||
|
* * @return SpanResult A structure containing the combined width and height of the monitors, and a success flag indicating
|
||||||
|
* whether the operation was successful.
|
||||||
|
* * @retval SpanResult::width The combined width of all monitors after scaling.
|
||||||
|
* @retval SpanResult::height The combined height of all monitors after scaling.
|
||||||
|
* @retval SpanResult::success A boolean flag indicating the success of the operation. Currently, it always returns `true`
|
||||||
|
* assuming all operations are successful. This can be adjusted based on error checks as needed.
|
||||||
|
*/
|
||||||
|
WindowsIntegration::SpanResult WindowsIntegration::setupWallpaperForAllScreens(HWND windowHwnd, HWND parentWindowHwnd)
|
||||||
|
{
|
||||||
|
std::vector<Monitor> monitors = GetAllMonitors();
|
||||||
|
|
||||||
|
int leftmost = INT_MAX;
|
||||||
|
int topmost = INT_MAX;
|
||||||
|
int rightmost = INT_MIN;
|
||||||
|
int bottommost = INT_MIN;
|
||||||
|
float overallScaleFactor = 1.0f; // assuming default is no scaling
|
||||||
|
|
||||||
|
// Calculate the combined dimensions of all monitors
|
||||||
|
for (const auto& monitor : monitors) {
|
||||||
|
leftmost = (std::min)(leftmost, static_cast<int>(monitor.position.left));
|
||||||
|
topmost = (std::min)(topmost, static_cast<int>(monitor.position.top));
|
||||||
|
rightmost = (std::max)(rightmost, static_cast<int>(monitor.position.right));
|
||||||
|
bottommost = (std::max)(bottommost, static_cast<int>(monitor.position.bottom));
|
||||||
|
overallScaleFactor *= monitor.scaleFactor; // Adjust as per your scaling needs
|
||||||
|
}
|
||||||
|
|
||||||
|
int scaledWidth = static_cast<int>((rightmost - leftmost) * overallScaleFactor);
|
||||||
|
int scaledHeight = static_cast<int>((bottommost - topmost) * overallScaleFactor);
|
||||||
|
|
||||||
|
// Set the position and size of the window to span all monitors
|
||||||
|
SetWindowPos(windowHwnd, HWND_TOP, leftmost, topmost, scaledWidth, scaledHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
|
||||||
|
// Reparenting and scaling logic
|
||||||
|
RECT oldRect;
|
||||||
|
GetWindowRect(windowHwnd, &oldRect);
|
||||||
|
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
||||||
|
SetParent(windowHwnd, parentWindowHwnd);
|
||||||
|
RECT parentRect;
|
||||||
|
GetWindowRect(parentWindowHwnd, &parentRect);
|
||||||
|
int newX = static_cast<int>((oldRect.left - parentRect.left) * (windowDpiScaleFactor / overallScaleFactor));
|
||||||
|
int newY = static_cast<int>((oldRect.top - parentRect.top) * (windowDpiScaleFactor / overallScaleFactor));
|
||||||
|
|
||||||
|
SetWindowPos(windowHwnd, NULL, newX, newY, scaledWidth, scaledHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
|
||||||
|
// Return the combined span of all monitors
|
||||||
|
SpanResult result;
|
||||||
|
result.width = scaledWidth;
|
||||||
|
result.height = scaledHeight;
|
||||||
|
result.success = true; // Assuming the operations are successful; adjust as needed
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
|
BOOL GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -120,7 +347,8 @@ BOOL FindTheDesiredWnd(HWND hWnd, LPARAM lParam)
|
|||||||
return true; // keep enumerating
|
return true; // keep enumerating
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
|
BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
|
||||||
|
{
|
||||||
std::vector<Monitor>* pMonitors = reinterpret_cast<std::vector<Monitor>*>(dwData);
|
std::vector<Monitor>* pMonitors = reinterpret_cast<std::vector<Monitor>*>(dwData);
|
||||||
|
|
||||||
MONITORINFOEX info;
|
MONITORINFOEX info;
|
||||||
|
@ -22,7 +22,8 @@ struct Monitor {
|
|||||||
SIZE size; // Monitor's width and height
|
SIZE size; // Monitor's width and height
|
||||||
float scaleFactor; // Scale factor (DPI scaling as a factor, e.g., 1.5 for 150% scaling)
|
float scaleFactor; // Scale factor (DPI scaling as a factor, e.g., 1.5 for 150% scaling)
|
||||||
|
|
||||||
void print() const {
|
void print() const
|
||||||
|
{
|
||||||
std::cout << "Monitor Info:" << std::endl;
|
std::cout << "Monitor Info:" << std::endl;
|
||||||
std::cout << "Monitor ID: " << monitorID << std::endl;
|
std::cout << "Monitor ID: " << monitorID << std::endl;
|
||||||
std::cout << "Index: " << index << std::endl;
|
std::cout << "Index: " << index << std::endl;
|
||||||
@ -41,13 +42,11 @@ BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam);
|
|||||||
|
|
||||||
struct WinMonitorStats {
|
struct WinMonitorStats {
|
||||||
|
|
||||||
|
|
||||||
WinMonitorStats()
|
WinMonitorStats()
|
||||||
{
|
{
|
||||||
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
|
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
|
||||||
{
|
{
|
||||||
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
|
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
|
||||||
@ -66,7 +65,7 @@ struct WinMonitorStats {
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
std::vector<int> iMonitors;
|
std::vector<size_t> iMonitors;
|
||||||
std::vector<HMONITOR> hMonitors;
|
std::vector<HMONITOR> hMonitors;
|
||||||
std::vector<HDC> hdcMonitors;
|
std::vector<HDC> hdcMonitors;
|
||||||
std::vector<RECT> rcMonitors;
|
std::vector<RECT> rcMonitors;
|
||||||
@ -84,262 +83,24 @@ struct sEnumInfo {
|
|||||||
HMONITOR hMonitor;
|
HMONITOR hMonitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WindowsIntegration {
|
||||||
|
|
||||||
class WindowsIntegration {
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool searchWorkerWindowToParentTo();
|
|
||||||
float getScaling(const int monitorIndex) const;
|
|
||||||
bool hasWindowScaling() const;
|
|
||||||
HWND windowHandle {};
|
HWND windowHandle {};
|
||||||
HWND windowHandleWorker {};
|
HWND windowHandleWorker {};
|
||||||
Point zeroPoint;
|
|
||||||
std::vector<Monitor> GetAllMonitors();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int GetMonitorIndex(HMONITOR hMonitor)
|
|
||||||
{
|
|
||||||
sEnumInfo info;
|
|
||||||
info.hMonitor = hMonitor;
|
|
||||||
|
|
||||||
if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM)&info))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return info.iIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief This method is called via a fixed interval to detect if a window completely
|
|
||||||
covers a monitor. If then sets visualPaused for QML to pause the content.
|
|
||||||
*/
|
|
||||||
bool checkForFullScreenWindow(HWND windowHandle)
|
|
||||||
{
|
|
||||||
|
|
||||||
HWND hFoundWnd = nullptr;
|
|
||||||
EnumWindows(&FindTheDesiredWnd, reinterpret_cast<LPARAM>(&hFoundWnd));
|
|
||||||
|
|
||||||
// True if one window has WS_MAXIMIZE
|
|
||||||
if (hFoundWnd != nullptr) {
|
|
||||||
DWORD dwFlags = 0;
|
|
||||||
HMONITOR monitor = MonitorFromWindow(hFoundWnd, dwFlags);
|
|
||||||
HMONITOR wallpaper = MonitorFromWindow(windowHandle, dwFlags);
|
|
||||||
int monitorIndex = GetMonitorIndex(monitor);
|
|
||||||
int wallpaperIndex = GetMonitorIndex(wallpaper);
|
|
||||||
// qDebug() << monitorIndex << wallpaperIndex;
|
|
||||||
|
|
||||||
// If the window that has WS_MAXIMIZE is at the same monitor as this wallpaper
|
|
||||||
return monitorIndex == wallpaperIndex;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the result structure
|
|
||||||
struct SpanResult {
|
struct SpanResult {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
bool searchWorkerWindowToParentTo();
|
||||||
* Adjusting a Window's Position and Size for Different Monitor DPI Scale Factors:
|
float getScaling(const int monitorIndex) const;
|
||||||
* * Windows allows users to set different DPI (dots per inch) scale factors for each monitor. This DPI scaling can lead to
|
bool hasWindowScaling() const;
|
||||||
* discrepancies in the positioning and size of windows, especially if we want to place a window on a monitor with a different
|
std::vector<Monitor> GetAllMonitors();
|
||||||
* scale factor than the one it was originally on.
|
int GetMonitorIndex(HMONITOR hMonitor);
|
||||||
* * In our scenario, we want to move and resize a window (`windowHwnd`) to fit perfectly within a target monitor. However,
|
bool checkForFullScreenWindow(HWND windowHandle);
|
||||||
* both the window and the target monitor can have different DPI scale factors, so we need to account for these when calculating
|
std::optional<Monitor> setupWallpaperForOneScreen(const int activeScreen, HWND windowHwnd, HWND parentWindowHwnd, std::function<void(int, int)> updateWindowSize);
|
||||||
* the window's new position and size.
|
SpanResult setupWallpaperForMultipleScreens(const std::vector<int>& activeScreens, HWND windowHwnd, HWND parentWindowHwnd);
|
||||||
* * Steps:
|
SpanResult setupWallpaperForAllScreens(HWND windowHwnd, HWND parentWindowHwnd);
|
||||||
* * 1. Retrieve the DPI scale factor for the window:
|
|
||||||
* - This gives us the current scale factor of the window based on its original monitor.
|
|
||||||
* * 2. Retrieve the DPI scale factor for the target monitor:
|
|
||||||
* - This gives us the scale factor of the monitor where we want to place the window.
|
|
||||||
* * 3. Calculate the window's new position:
|
|
||||||
* - The new position should be relative to the `WorkerW` window's coordinates.
|
|
||||||
* - Adjust the position based on the ratio of the window's DPI scale factor to the target monitor's DPI scale factor.
|
|
||||||
* This ensures that the window is positioned correctly on the monitor regardless of any differences in scale factors.
|
|
||||||
* * 4. Calculate the window's new size:
|
|
||||||
* - Adjust the size of the window based on the ratio of the window's DPI scale factor to the target monitor's DPI scale factor.
|
|
||||||
* This ensures that the window fits perfectly within the monitor, taking into account any differences in scale factors.
|
|
||||||
* * By following this approach, we can accurately position and resize the window on any monitor, regardless of differences in DPI
|
|
||||||
* scale factors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::optional<Monitor> setupWallpaperForOneScreen(const int activeScreen, HWND windowHwnd, HWND parentWindowHwnd, std::function<void(int,int)>updateWindowSize)
|
|
||||||
{
|
|
||||||
std::vector<Monitor> monitors = GetAllMonitors();
|
|
||||||
for (const auto& monitor : monitors) {
|
|
||||||
monitor.print();
|
|
||||||
if (monitor.index != activeScreen)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SetWindowPos(windowHwnd, HWND_TOP,
|
|
||||||
monitor.position.left, monitor.position.top,
|
|
||||||
monitor.size.cx, monitor.size.cy,
|
|
||||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
// Must be called here to fix window positions!
|
|
||||||
updateWindowSize(monitor.size.cx, monitor.size.cy);
|
|
||||||
|
|
||||||
RECT oldRect;
|
|
||||||
GetWindowRect(windowHwnd, &oldRect);
|
|
||||||
std::cout << "Old Window Position: (" << oldRect.left << ", " << oldRect.top << ")" << std::endl;
|
|
||||||
|
|
||||||
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
|
||||||
float targetMonitorDpiScaleFactor = monitor.scaleFactor;
|
|
||||||
std::cout << "Window DPI Scale Factor: " << windowDpiScaleFactor << std::endl;
|
|
||||||
std::cout << "Target Monitor DPI Scale Factor: " << targetMonitorDpiScaleFactor << std::endl;
|
|
||||||
|
|
||||||
SetParent(windowHwnd, parentWindowHwnd);
|
|
||||||
RECT parentRect;
|
|
||||||
GetWindowRect(parentWindowHwnd, &parentRect);
|
|
||||||
std::cout << "WorkerW Window Position: (" << parentRect.left << ", " << parentRect.top << ")" << std::endl;
|
|
||||||
|
|
||||||
int newX = static_cast<int>((oldRect.left - parentRect.left) * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
|
||||||
int newY = static_cast<int>((oldRect.top - parentRect.top) * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
|
||||||
std::cout << "Calculated New Position: (" << newX << ", " << newY << ")" << std::endl;
|
|
||||||
|
|
||||||
int newWidth = static_cast<int>(monitor.size.cx * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
|
||||||
int newHeight = static_cast<int>(monitor.size.cy * (windowDpiScaleFactor / targetMonitorDpiScaleFactor));
|
|
||||||
std::cout << "Calculated New Size: (" << newWidth << "x" << newHeight << ")" << std::endl;
|
|
||||||
|
|
||||||
SetWindowPos(windowHwnd, NULL, newX, newY, newWidth, newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
return {monitor};
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Spans the window across multiple monitors.
|
|
||||||
*
|
|
||||||
* This function takes a vector of monitor indices and adjusts the window's
|
|
||||||
* size and position to span across the specified monitors. It determines the
|
|
||||||
* window's new size by finding the bounding rectangle that covers all selected
|
|
||||||
* monitors. The window's new position is set to the top-left corner of this
|
|
||||||
* bounding rectangle.
|
|
||||||
*
|
|
||||||
* Note: This function assumes that all monitors have the same DPI scaling. If
|
|
||||||
* they don't, the window may not fit perfectly across the monitors.
|
|
||||||
*
|
|
||||||
* @param activeScreens A vector containing the indices of monitors across
|
|
||||||
* which the window should span.
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* setupWallpaperForMultipleScreens({0, 1}); // Spans the window across monitors 0 and 1.
|
|
||||||
*
|
|
||||||
* Internals:
|
|
||||||
* 1. For each monitor in `activeScreens`, determine its bounding rectangle.
|
|
||||||
* 2. Compute the window's new width as `rightmost - leftmost` and its new
|
|
||||||
* height as `bottommost - topmost`.
|
|
||||||
* 3. Adjust the window's position and size to fit this bounding rectangle.
|
|
||||||
*/
|
|
||||||
SpanResult setupWallpaperForMultipleScreens(const std::vector<int>& activeScreens, HWND windowHwnd, HWND parentWindowHwnd)
|
|
||||||
{
|
|
||||||
std::vector<Monitor> monitors = GetAllMonitors();
|
|
||||||
|
|
||||||
int leftmost = INT_MAX;
|
|
||||||
int topmost = INT_MAX;
|
|
||||||
int rightmost = INT_MIN;
|
|
||||||
int bottommost = INT_MIN;
|
|
||||||
|
|
||||||
for (const auto& monitorIndex : activeScreens) {
|
|
||||||
if (monitorIndex < monitors.size()) {
|
|
||||||
const Monitor& monitor = monitors[monitorIndex];
|
|
||||||
leftmost = std::min(leftmost, static_cast<int>(monitor.position.left));
|
|
||||||
topmost = std::min(topmost, static_cast<int>(monitor.position.top));
|
|
||||||
rightmost = std::max(rightmost, static_cast<int>(monitor.position.right));
|
|
||||||
bottommost = std::max(bottommost, static_cast<int>(monitor.position.bottom));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int newWidth = rightmost - leftmost;
|
|
||||||
int newHeight = bottommost - topmost;
|
|
||||||
|
|
||||||
RECT oldRect;
|
|
||||||
GetWindowRect(windowHwnd, &oldRect);
|
|
||||||
|
|
||||||
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
|
||||||
|
|
||||||
SetParent(windowHwnd, parentWindowHwnd);
|
|
||||||
RECT parentRect;
|
|
||||||
GetWindowRect(parentWindowHwnd, &parentRect);
|
|
||||||
|
|
||||||
int newX = static_cast<int>((leftmost - parentRect.left) * windowDpiScaleFactor);
|
|
||||||
int newY = static_cast<int>((topmost - parentRect.top) * windowDpiScaleFactor);
|
|
||||||
|
|
||||||
SetWindowPos(windowHwnd, NULL, newX, newY, newWidth, newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
SpanResult result;
|
|
||||||
result.width = rightmost - leftmost;
|
|
||||||
result.height = bottommost - topmost;
|
|
||||||
result.success = true;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sets up the wallpaper to span across all connected screens.
|
|
||||||
* * This function retrieves information about all connected monitors, including their positions, dimensions, and scale factors.
|
|
||||||
* It then calculates the combined dimensions needed to span the window across all these monitors, taking into account
|
|
||||||
* the scale factors. The function also handles reparenting the window to the WorkerW window, ensuring it remains below
|
|
||||||
* other desktop icons. The calculated position and dimensions are adjusted to account for any potential scaling differences
|
|
||||||
* between the window and the combined monitor setup.
|
|
||||||
* * @note This function assumes that the window's DPI scale factor is based on a default of 96 DPI. Adjustments are made
|
|
||||||
* based on this assumption.
|
|
||||||
* * @note The function currently multiplies the scale factors of all monitors to get an overall scale factor. This may need
|
|
||||||
* adjustments based on specific application needs.
|
|
||||||
* * @return SpanResult A structure containing the combined width and height of the monitors, and a success flag indicating
|
|
||||||
* whether the operation was successful.
|
|
||||||
*
|
|
||||||
* @retval SpanResult::width The combined width of all monitors after scaling.
|
|
||||||
* @retval SpanResult::height The combined height of all monitors after scaling.
|
|
||||||
* @retval SpanResult::success A boolean flag indicating the success of the operation. Currently, it always returns `true`
|
|
||||||
* assuming all operations are successful. This can be adjusted based on error checks as needed.
|
|
||||||
*/
|
|
||||||
SpanResult setupWallpaperForAllScreens( HWND windowHwnd, HWND parentWindowHwnd) {
|
|
||||||
std::vector<Monitor> monitors = GetAllMonitors();
|
|
||||||
|
|
||||||
int leftmost = INT_MAX;
|
|
||||||
int topmost = INT_MAX;
|
|
||||||
int rightmost = INT_MIN;
|
|
||||||
int bottommost = INT_MIN;
|
|
||||||
float overallScaleFactor = 1.0f; // assuming default is no scaling
|
|
||||||
|
|
||||||
// Calculate the combined dimensions of all monitors
|
|
||||||
for (const auto& monitor : monitors) {
|
|
||||||
leftmost = std::min(leftmost, static_cast<int>(monitor.position.left));
|
|
||||||
topmost = std::min(topmost, static_cast<int>(monitor.position.top));
|
|
||||||
rightmost = std::max(rightmost, static_cast<int>(monitor.position.right));
|
|
||||||
bottommost = std::max(bottommost, static_cast<int>(monitor.position.bottom));
|
|
||||||
overallScaleFactor *= monitor.scaleFactor; // Adjust as per your scaling needs
|
|
||||||
}
|
|
||||||
|
|
||||||
int scaledWidth = static_cast<int>((rightmost - leftmost) * overallScaleFactor);
|
|
||||||
int scaledHeight = static_cast<int>((bottommost - topmost) * overallScaleFactor);
|
|
||||||
|
|
||||||
// Set the position and size of the window to span all monitors
|
|
||||||
SetWindowPos(windowHwnd, HWND_TOP, leftmost, topmost, scaledWidth, scaledHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
// Reparenting and scaling logic
|
|
||||||
RECT oldRect;
|
|
||||||
GetWindowRect(windowHwnd, &oldRect);
|
|
||||||
float windowDpiScaleFactor = static_cast<float>(GetDpiForWindow(windowHwnd)) / 96.0f;
|
|
||||||
SetParent(windowHwnd, parentWindowHwnd);
|
|
||||||
RECT parentRect;
|
|
||||||
GetWindowRect(parentWindowHwnd, &parentRect);
|
|
||||||
int newX = static_cast<int>((oldRect.left - parentRect.left) * (windowDpiScaleFactor / overallScaleFactor));
|
|
||||||
int newY = static_cast<int>((oldRect.top - parentRect.top) * (windowDpiScaleFactor / overallScaleFactor));
|
|
||||||
|
|
||||||
SetWindowPos(windowHwnd, NULL, newX, newY, scaledWidth, scaledHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
// Return the combined span of all monitors
|
|
||||||
SpanResult result;
|
|
||||||
result.width = scaledWidth;
|
|
||||||
result.height = scaledHeight;
|
|
||||||
result.success = true; // Assuming the operations are successful; adjust as needed
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||||
#include "winwindow.h"
|
#include "winwindow.h"
|
||||||
#include "windowsintegration.h"
|
|
||||||
#include "ScreenPlayUtil/projectfile.h"
|
#include "ScreenPlayUtil/projectfile.h"
|
||||||
|
#include "windowsintegration.h"
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtQml>
|
#include <QtQml>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -16,7 +16,6 @@
|
|||||||
\brief ScreenPlayWindow used for the Windows implementation.
|
\brief ScreenPlayWindow used for the Windows implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
HHOOK g_mouseHook;
|
HHOOK g_mouseHook;
|
||||||
QPoint g_LastMousePosition { 0, 0 };
|
QPoint g_LastMousePosition { 0, 0 };
|
||||||
QPoint g_globalOffset { 0, 0 };
|
QPoint g_globalOffset { 0, 0 };
|
||||||
@ -182,18 +181,16 @@ void WinWindow::destroyThis()
|
|||||||
emit qmlExit();
|
emit qmlExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WinWindow::setupWallpaperForOneScreen(int activeScreen)
|
void WinWindow::setupWallpaperForOneScreen(int activeScreen)
|
||||||
{
|
{
|
||||||
WindowsIntegration windowsIntegration;
|
WindowsIntegration windowsIntegration;
|
||||||
auto updateWindowSize = [this](const int width, const int height){
|
auto updateWindowSize = [this](const int width, const int height) {
|
||||||
setWidth(width);
|
setWidth(width);
|
||||||
setHeight(height);
|
setHeight(height);
|
||||||
m_window.setWidth(width);
|
m_window.setWidth(width);
|
||||||
m_window.setHeight(height);
|
m_window.setHeight(height);
|
||||||
};
|
};
|
||||||
std::optional<Monitor> monitor = windowsIntegration.setupWallpaperForOneScreen(activeScreen,m_windowHandle,m_windowHandleWorker,updateWindowSize);
|
std::optional<Monitor> monitor = windowsIntegration.setupWallpaperForOneScreen(activeScreen, m_windowHandle, m_windowHandleWorker, updateWindowSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -202,7 +199,7 @@ void WinWindow::setupWallpaperForOneScreen(int activeScreen)
|
|||||||
void WinWindow::setupWallpaperForAllScreens()
|
void WinWindow::setupWallpaperForAllScreens()
|
||||||
{
|
{
|
||||||
WindowsIntegration windowsIntegration;
|
WindowsIntegration windowsIntegration;
|
||||||
WindowsIntegration::SpanResult span = windowsIntegration.setupWallpaperForAllScreens(m_windowHandle,m_windowHandleWorker);
|
WindowsIntegration::SpanResult span = windowsIntegration.setupWallpaperForAllScreens(m_windowHandle, m_windowHandleWorker);
|
||||||
setWidth(span.width);
|
setWidth(span.width);
|
||||||
setHeight(span.height);
|
setHeight(span.height);
|
||||||
m_window.setWidth(width());
|
m_window.setWidth(width());
|
||||||
@ -216,7 +213,7 @@ void WinWindow::setupWallpaperForMultipleScreens(const QVector<int>& activeScree
|
|||||||
{
|
{
|
||||||
std::vector<int> activeScreens(activeScreensList.begin(), activeScreensList.end());
|
std::vector<int> activeScreens(activeScreensList.begin(), activeScreensList.end());
|
||||||
WindowsIntegration windowsIntegration;
|
WindowsIntegration windowsIntegration;
|
||||||
WindowsIntegration::SpanResult span = windowsIntegration.setupWallpaperForMultipleScreens(activeScreens,m_windowHandle,m_windowHandleWorker);
|
WindowsIntegration::SpanResult span = windowsIntegration.setupWallpaperForMultipleScreens(activeScreens, m_windowHandle, m_windowHandleWorker);
|
||||||
setWidth(span.width);
|
setWidth(span.width);
|
||||||
setHeight(span.height);
|
setHeight(span.height);
|
||||||
m_window.setWidth(width());
|
m_window.setWidth(width());
|
||||||
@ -290,7 +287,8 @@ void WinWindow::clearComponentCache()
|
|||||||
m_window.engine()->clearComponentCache();
|
m_window.engine()->clearComponentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinWindow::checkForFullScreenWindow(){
|
void WinWindow::checkForFullScreenWindow()
|
||||||
|
{
|
||||||
bool hasFullscreenWindow = WindowsIntegration().checkForFullScreenWindow(m_windowHandle);
|
bool hasFullscreenWindow = WindowsIntegration().checkForFullScreenWindow(m_windowHandle);
|
||||||
|
|
||||||
setVisualsPaused(hasFullscreenWindow);
|
setVisualsPaused(hasFullscreenWindow);
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QtWebEngineQuick>
|
#include <QtWebEngineQuick>
|
||||||
|
|
||||||
#include "src/widgetwindow.h"
|
|
||||||
#include "ScreenPlayUtil/logginghandler.h"
|
#include "ScreenPlayUtil/logginghandler.h"
|
||||||
|
#include "src/widgetwindow.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
||||||
@ -95,7 +95,7 @@ int main(int argc, char* argv[])
|
|||||||
#if defined(Q_OS_OSX)
|
#if defined(Q_OS_OSX)
|
||||||
MacUtils::showDockIcon(false);
|
MacUtils::showDockIcon(false);
|
||||||
#endif
|
#endif
|
||||||
logging = std::make_unique<const ScreenPlayUtil::LoggingHandler>("ScreenPlayWidget_"+ appID);
|
logging = std::make_unique<const ScreenPlayUtil::LoggingHandler>("ScreenPlayWidget_" + appID);
|
||||||
const int status = app.exec();
|
const int status = app.exec();
|
||||||
logging.reset();
|
logging.reset();
|
||||||
return status;
|
return status;
|
||||||
|
4
ThirdParty/CMakeLists.txt
vendored
4
ThirdParty/CMakeLists.txt
vendored
@ -16,13 +16,11 @@ FetchContent_Populate(
|
|||||||
# https://bugreports.qt.io/browse/QTCREATORBUG-27083
|
# https://bugreports.qt.io/browse/QTCREATORBUG-27083
|
||||||
SOURCE_DIR ${THIRD_PARTY_PATH}/qml-plausible)
|
SOURCE_DIR ${THIRD_PARTY_PATH}/qml-plausible)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(qml-plausible)
|
add_subdirectory(qml-plausible)
|
||||||
add_subdirectory(QArchive)
|
add_subdirectory(QArchive)
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
FetchContent_Populate(
|
FetchContent_Populate(
|
||||||
qt-layer-shell
|
qt-layer-shell
|
||||||
GIT_REPOSITORY https://github.com/KDE/layer-shell-qt.git
|
GIT_REPOSITORY https://github.com/KDE/layer-shell-qt.git
|
||||||
GIT_TAG 721c0ae334554eb2396a2d4d3358f896b8c77412
|
GIT_TAG 721c0ae334554eb2396a2d4d3358f896b8c77412
|
||||||
|
Loading…
Reference in New Issue
Block a user