mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-09-01 16:19:47 +02: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")
|
||||
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
||||
|
||||
|
||||
option(OSX_BUNDLE "Enable distribution macOS bundle" OFF)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
|
||||
|
||||
@ -103,14 +102,12 @@ else()
|
||||
set(DATE_ARG "")
|
||||
endif()
|
||||
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
# Fixes QWebEngine linker errors on Ubuntu 22.04
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold")
|
||||
endif()
|
||||
|
||||
|
||||
execute_process(
|
||||
COMMAND ${DATE_COMMAND} ${DATE_ARG}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
|
@ -101,7 +101,6 @@ public slots:
|
||||
void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine);
|
||||
void setWizards(Wizards* wizards);
|
||||
|
||||
|
||||
private:
|
||||
QNetworkAccessManager m_networkAccessManager;
|
||||
std::unique_ptr<QQmlApplicationEngine> m_mainWindowEngine;
|
||||
|
@ -40,7 +40,6 @@ public:
|
||||
int activeWidgetsCounter() const { return m_activeWidgetsCounter; }
|
||||
bool isAnotherScreenPlayInstanceRunning() { return m_isAnotherScreenPlayInstanceRunning; }
|
||||
|
||||
|
||||
signals:
|
||||
void activeWallpaperCounterChanged(int activeWallpaperCounter);
|
||||
void activeWidgetsCounterChanged(int activeWidgetsCounter);
|
||||
|
@ -1,11 +1,11 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
|
||||
#include "ScreenPlay/app.h"
|
||||
#include "ScreenPlayUtil/logginghandler.h"
|
||||
#include <QCommandLineParser>
|
||||
#include <QDebug>
|
||||
#include <QGuiApplication>
|
||||
#include <QStyleFactory>
|
||||
#include "ScreenPlayUtil/logginghandler.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#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.")
|
||||
buttonText: qsTr("Show Logs")
|
||||
onButtonPressed: {
|
||||
const logsPath = StandardPaths.writableLocation(StandardPaths.GenericDataLocation) + "/ScreenPlay/Logs"
|
||||
App.util.openFolderInExplorer(logsPath)
|
||||
const logsPath = StandardPaths.writableLocation(StandardPaths.GenericDataLocation) + "/ScreenPlay/Logs";
|
||||
App.util.openFolderInExplorer(logsPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,6 @@ bool Util::fileExists(const QString& filePath) const
|
||||
return file.isFile();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Takes ownership of \a obj and \a name. Tries to save into a text file
|
||||
with of name.
|
||||
|
@ -55,11 +55,11 @@ set(HEADER
|
||||
inc/public/ScreenPlayUtil/HelpersCommon.h
|
||||
inc/public/ScreenPlayUtil/httpfileserver.h
|
||||
inc/public/ScreenPlayUtil/ListPropertyHelper.h
|
||||
inc/public/ScreenPlayUtil/logginghandler.h
|
||||
inc/public/ScreenPlayUtil/projectfile.h
|
||||
inc/public/ScreenPlayUtil/PropertyHelpers.h
|
||||
inc/public/ScreenPlayUtil/PtrPropertyHelpers.h
|
||||
inc/public/ScreenPlayUtil/SingletonHelper.h
|
||||
inc/public/ScreenPlayUtil/logginghandler.h
|
||||
inc/public/ScreenPlayUtil/util.h)
|
||||
|
||||
if(APPLE)
|
||||
@ -98,7 +98,10 @@ target_include_directories(
|
||||
${PROJECT_NAME}
|
||||
PUBLIC inc/public/
|
||||
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)
|
||||
# Used for query windows monitor data
|
||||
|
@ -3,13 +3,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "ScreenPlayUtil/contenttypes.h"
|
||||
#include <QtGlobal>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QMetaEnum>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
#include <QVersionNumber>
|
||||
#include <QtGlobal>
|
||||
#include <optional>
|
||||
|
||||
namespace ScreenPlayUtil {
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "ScreenPlayUtil/logginghandler.h"
|
||||
#include "sysinfo.h"
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
@ -9,10 +8,15 @@
|
||||
#include <QUrl>
|
||||
#include <fmt/color.h>
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\class ScreenPlayUtil::LoggingHandler
|
||||
\inmodule core
|
||||
\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());
|
||||
|
||||
// Use hardcoded path for now because QStandardpaths gives us: 'C:/ProgramData/K3000'
|
||||
QDir directory;
|
||||
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
|
||||
directory = QDir(cacheDir + "/ScreenPlay/Logs");
|
||||
@ -78,29 +81,6 @@ void LoggingHandler::start()
|
||||
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 message = QString { "[%1] Start logging\n" }.arg(now);
|
||||
logFile().write(message.toStdString().c_str());
|
||||
|
@ -7,8 +7,7 @@ set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS
|
||||
Core
|
||||
COMPONENTS Core
|
||||
Quick
|
||||
Gui
|
||||
Widgets
|
||||
@ -55,25 +54,18 @@ set(LIB_HEADER)
|
||||
if(WIN32)
|
||||
set(LIB_SOURCES src/windowsintegration.cpp)
|
||||
set(LIB_HEADER src/windowsintegration.h)
|
||||
elseif(APPLE)
|
||||
set(LIB_SOURCES src/macintegration.cpp)
|
||||
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
|
||||
target_link_libraries(ScreenPlayWallpaperLib PUBLIC shcore.lib)
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADER}
|
||||
src/windowsintegration.h src/windowsintegration.cpp)
|
||||
add_executable(
|
||||
${PROJECT_NAME}
|
||||
${SOURCES}
|
||||
${HEADER}
|
||||
src/windowsintegration.h
|
||||
src/windowsintegration.cpp)
|
||||
|
||||
qt_add_qml_module(
|
||||
${PROJECT_NAME}
|
||||
@ -92,9 +84,7 @@ qt_add_qml_module(
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE
|
||||
ScreenPlaySDK
|
||||
ScreenPlayWallpaperLib
|
||||
PRIVATE ScreenPlaySDK
|
||||
ScreenPlayUtil
|
||||
ScreenPlayWeatherplugin
|
||||
Qt6::Quick
|
||||
@ -108,18 +98,20 @@ target_link_libraries(
|
||||
Qt6::WebEngineQuick)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin ScreenPlayWallpaperLib)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE X11)
|
||||
endif()
|
||||
|
||||
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/")
|
||||
find_package(LayerShellQt REQUIRED)
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE LayerShellQtInterface)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE LayerShellQtInterface)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
@ -20,37 +20,31 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
||||
# Output compile commands to compile_commands.json (for debugging CMake issues)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Build universal lib on macOS
|
||||
# Note that CMAKE_OSX_ARCHITECTURES must be set before project().
|
||||
# Build universal lib on macOS Note that CMAKE_OSX_ARCHITECTURES must be set before project().
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
set(CMAKE_OSX_ARCHITECTURES
|
||||
"x86_64;arm64"
|
||||
CACHE STRING "")
|
||||
endif()
|
||||
|
||||
# Main project information
|
||||
project(ScreenPlayGodotWallpaper
|
||||
LANGUAGES
|
||||
CXX
|
||||
)
|
||||
project(ScreenPlayGodotWallpaper LANGUAGES CXX)
|
||||
|
||||
# Create our library
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
cxx_std_17
|
||||
)
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
||||
|
||||
# LIB_ARCH is the architecture being built. It is set to the build system's architecture.
|
||||
# For macOS, we build a universal library (both arm64 and x86_64).
|
||||
# LIB_ARCH is the architecture being built. It is set to the build system's architecture. For macOS, we build a universal library (both
|
||||
# arm64 and x86_64).
|
||||
set(LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||
|
||||
if(APPLE)
|
||||
set(LIB_ARCH "universal")
|
||||
endif()
|
||||
|
||||
# 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 with the paths in the gdextension file.
|
||||
# e.g. linux.release.x86_64 = "lib/Linux-x86_64/libGDExtensionTemplate.so"
|
||||
# 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
|
||||
# with the paths in the gdextension file. e.g. linux.release.x86_64 = "lib/Linux-x86_64/libGDExtensionTemplate.so"
|
||||
set(LIB_DIR "lib/${CMAKE_SYSTEM_NAME}-${LIB_ARCH}")
|
||||
|
||||
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}/)
|
||||
|
||||
# Compile directly into our Godot project
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
set_target_properties(
|
||||
${PROJECT_NAME}
|
||||
PROPERTIES CXX_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN true
|
||||
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)
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
DEBUG_POSTFIX "-d"
|
||||
)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX "-d")
|
||||
endif()
|
||||
|
||||
# Warnings
|
||||
@ -88,16 +78,13 @@ set(INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/")
|
||||
|
||||
add_subdirectory(templates)
|
||||
|
||||
# ccache
|
||||
# Turns on ccache if found
|
||||
# ccache Turns on ccache if found
|
||||
include(ccache)
|
||||
|
||||
# Formatting
|
||||
# Adds a custom target to format all the code at once
|
||||
# Formatting Adds a custom target to format all the code at once
|
||||
include(ClangFormat)
|
||||
|
||||
# godot-cpp
|
||||
# From here: https://github.com/godotengine/godot-cpp
|
||||
# godot-cpp From here: https://github.com/godotengine/godot-cpp
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/extern/godot-cpp/Makefile")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
@ -105,17 +92,13 @@ if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/extern/godot-cpp/Makefile")
|
||||
)
|
||||
endif()
|
||||
|
||||
set(GODOT_CPP_SYSTEM_HEADERS ON CACHE BOOL "" FORCE)
|
||||
set(GODOT_CPP_SYSTEM_HEADERS
|
||||
ON
|
||||
CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory(extern/godot-cpp)
|
||||
|
||||
set_target_properties(godot-cpp
|
||||
PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden # visibility needs to be the same as the main library
|
||||
set_target_properties(godot-cpp PROPERTIES CXX_VISIBILITY_PRESET hidden # visibility needs to be the same as the main library
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
godot-cpp
|
||||
ScreenPlayWallpaperLib
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE godot-cpp ScreenPlayWallpaperLib)
|
||||
|
@ -1,20 +1,16 @@
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
ScreenPlayGodotWallpaper.h
|
||||
target_sources(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE ScreenPlayGodotWallpaper.h
|
||||
ScreenPlayGodotWallpaper.cpp
|
||||
WindowsPipe.h
|
||||
WindowsPipe.cpp
|
||||
RegisterExtension.cpp
|
||||
)
|
||||
RegisterExtension.cpp)
|
||||
find_package(Catch2 CONFIG REQUIRED)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
"src"
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "src")
|
||||
|
||||
# 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_include_directories(WindowsPipeTest PRIVATE "src")
|
@ -2,6 +2,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "godot_cpp/classes/control.hpp"
|
||||
#include "godot_cpp/classes/global_constants.hpp"
|
||||
#include "godot_cpp/classes/timer.hpp"
|
||||
@ -14,8 +18,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "ScreenPlayGodotWallpaper.h"
|
||||
#include "windowsintegration.h"
|
||||
#include "WindowsPipe.h"
|
||||
#include "windowsintegration.h"
|
||||
|
||||
class ScreenPlayGodotWallpaper : public godot::Node {
|
||||
GDCLASS(ScreenPlayGodotWallpaper, Node)
|
||||
@ -54,7 +58,6 @@ private:
|
||||
void hideFromTaskbar(HWND hwnd);
|
||||
|
||||
private:
|
||||
|
||||
OVERLAPPED overlappedRead = {};
|
||||
OVERLAPPED overlappedWrite = {};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "WindowsPipe.h"
|
||||
|
||||
bool WindowsPipe::connectToPipe() {
|
||||
bool WindowsPipe::connectToPipe()
|
||||
{
|
||||
if (m_pipeName.empty()) {
|
||||
std::cerr << "Pipe name not set." << std::endl;
|
||||
return false;
|
||||
@ -25,7 +26,8 @@ bool WindowsPipe::connectToPipe() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowsPipe::readFromPipe(std::string& outMessage) {
|
||||
bool WindowsPipe::readFromPipe(std::string& outMessage)
|
||||
{
|
||||
char buffer[128];
|
||||
DWORD bytesRead;
|
||||
|
||||
@ -52,8 +54,8 @@ bool WindowsPipe::readFromPipe(std::string& outMessage) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WindowsPipe::writeToPipe(const std::string& message) {
|
||||
bool WindowsPipe::writeToPipe(const std::string& message)
|
||||
{
|
||||
DWORD bytesWritten;
|
||||
|
||||
if (!WriteFile(m_hPipe, message.c_str(), static_cast<DWORD>(message.size()), &bytesWritten, &m_overlapped)) {
|
||||
|
@ -1,18 +1,17 @@
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
add_custom_target(templates
|
||||
SOURCES
|
||||
template.debug.gdextension.in
|
||||
template.release.gdextension.in
|
||||
)
|
||||
add_custom_target(templates SOURCES template.debug.gdextension.in template.release.gdextension.in)
|
||||
|
||||
add_dependencies(${PROJECT_NAME} templates)
|
||||
|
||||
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25)
|
||||
# But until we fix it here and in godot-cpp, ensure it's one we expect.
|
||||
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25) But until we fix it here and
|
||||
# in godot-cpp, ensure it's one we expect.
|
||||
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")
|
||||
endif()
|
||||
|
||||
|
@ -9,15 +9,15 @@
|
||||
#include "ScreenPlayWallpaper/CMakeVariables.h"
|
||||
|
||||
#include "ScreenPlayUtil/exitcodes.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
#include "ScreenPlayUtil/logginghandler.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "src/winwindow.h"
|
||||
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
||||
#elif defined(Q_OS_LINUX)
|
||||
#include "src/linuxx11window.h"
|
||||
#include "src/linuxwaylandwindow.h"
|
||||
#include "src/linuxx11window.h"
|
||||
#elif defined(Q_OS_OSX)
|
||||
#include "src/macwindow.h"
|
||||
#endif
|
||||
|
@ -35,7 +35,6 @@ BaseWindow::BaseWindow()
|
||||
"VideoCodec",
|
||||
"Error: only enums");
|
||||
|
||||
|
||||
setOSVersion(QSysInfo::productVersion());
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
#include "linuxwaylandwindow.h"
|
||||
#include <QScreen>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
#include <LayerShellQt/Window>
|
||||
#include <LayerShellQt/Shell>
|
||||
#include <LayerShellQt/Window>
|
||||
|
||||
ScreenPlay::WallpaperExitCode LinuxWaylandWindow::start()
|
||||
{
|
||||
@ -24,18 +24,10 @@ ScreenPlay::WallpaperExitCode LinuxWaylandWindow::start()
|
||||
if (QGuiApplication::platformName() == "wayland") {
|
||||
QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
|
||||
|
||||
|
||||
auto* layerShell = LayerShellQt::Window::get(&m_window);
|
||||
layerShell->setLayer(LayerShellQt::Window::LayerBackground);
|
||||
layerShell->setAnchors(static_cast<QFlags<LayerShellQt::Window::Anchor>>(
|
||||
LayerShellQt::Window::Anchor::AnchorTop |
|
||||
LayerShellQt::Window::Anchor::AnchorBottom |
|
||||
LayerShellQt::Window::Anchor::AnchorLeft |
|
||||
LayerShellQt::Window::Anchor::AnchorRight
|
||||
));
|
||||
|
||||
|
||||
|
||||
LayerShellQt::Window::Anchor::AnchorTop | LayerShellQt::Window::Anchor::AnchorBottom | LayerShellQt::Window::Anchor::AnchorLeft | LayerShellQt::Window::Anchor::AnchorRight));
|
||||
}
|
||||
|
||||
m_window.show();
|
||||
|
@ -1,6 +1,4 @@
|
||||
#include "windowsintegration.h"
|
||||
|
||||
|
||||
bool WindowsIntegration::searchWorkerWindowToParentTo()
|
||||
{
|
||||
|
||||
@ -91,7 +89,8 @@ BOOL SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
std::vector<Monitor> WindowsIntegration::GetAllMonitors() {
|
||||
std::vector<Monitor> WindowsIntegration::GetAllMonitors()
|
||||
{
|
||||
std::vector<Monitor> monitors;
|
||||
|
||||
// Use the static MonitorEnumProc callback for EnumDisplayMonitors
|
||||
@ -100,6 +99,234 @@ std::vector<Monitor> WindowsIntegration::GetAllMonitors() {
|
||||
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)
|
||||
{
|
||||
|
||||
@ -120,7 +347,8 @@ BOOL FindTheDesiredWnd(HWND hWnd, LPARAM lParam)
|
||||
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);
|
||||
|
||||
MONITORINFOEX info;
|
||||
|
@ -22,7 +22,8 @@ struct Monitor {
|
||||
SIZE size; // Monitor's width and height
|
||||
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 ID: " << monitorID << std::endl;
|
||||
std::cout << "Index: " << index << std::endl;
|
||||
@ -41,13 +42,11 @@ BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam);
|
||||
|
||||
struct WinMonitorStats {
|
||||
|
||||
|
||||
WinMonitorStats()
|
||||
{
|
||||
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||
}
|
||||
|
||||
|
||||
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
|
||||
{
|
||||
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
|
||||
@ -66,7 +65,7 @@ struct WinMonitorStats {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
std::vector<int> iMonitors;
|
||||
std::vector<size_t> iMonitors;
|
||||
std::vector<HMONITOR> hMonitors;
|
||||
std::vector<HDC> hdcMonitors;
|
||||
std::vector<RECT> rcMonitors;
|
||||
@ -84,262 +83,24 @@ struct sEnumInfo {
|
||||
HMONITOR hMonitor;
|
||||
};
|
||||
|
||||
struct WindowsIntegration {
|
||||
|
||||
class WindowsIntegration {
|
||||
public:
|
||||
|
||||
bool searchWorkerWindowToParentTo();
|
||||
float getScaling(const int monitorIndex) const;
|
||||
bool hasWindowScaling() const;
|
||||
HWND windowHandle {};
|
||||
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 {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
bool success = 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> 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;
|
||||
}
|
||||
|
||||
|
||||
bool searchWorkerWindowToParentTo();
|
||||
float getScaling(const int monitorIndex) const;
|
||||
bool hasWindowScaling() const;
|
||||
std::vector<Monitor> GetAllMonitors();
|
||||
int GetMonitorIndex(HMONITOR hMonitor);
|
||||
bool checkForFullScreenWindow(HWND windowHandle);
|
||||
std::optional<Monitor> setupWallpaperForOneScreen(const int activeScreen, HWND windowHwnd, HWND parentWindowHwnd, std::function<void(int, int)> updateWindowSize);
|
||||
SpanResult setupWallpaperForMultipleScreens(const std::vector<int>& activeScreens, HWND windowHwnd, HWND parentWindowHwnd);
|
||||
SpanResult setupWallpaperForAllScreens(HWND windowHwnd, HWND parentWindowHwnd);
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
#include "winwindow.h"
|
||||
#include "windowsintegration.h"
|
||||
#include "ScreenPlayUtil/projectfile.h"
|
||||
#include "windowsintegration.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QtQml>
|
||||
#include <algorithm>
|
||||
@ -16,7 +16,6 @@
|
||||
\brief ScreenPlayWindow used for the Windows implementation.
|
||||
*/
|
||||
|
||||
|
||||
HHOOK g_mouseHook;
|
||||
QPoint g_LastMousePosition { 0, 0 };
|
||||
QPoint g_globalOffset { 0, 0 };
|
||||
@ -182,7 +181,6 @@ void WinWindow::destroyThis()
|
||||
emit qmlExit();
|
||||
}
|
||||
|
||||
|
||||
void WinWindow::setupWallpaperForOneScreen(int activeScreen)
|
||||
{
|
||||
WindowsIntegration windowsIntegration;
|
||||
@ -193,7 +191,6 @@ void WinWindow::setupWallpaperForOneScreen(int activeScreen)
|
||||
m_window.setHeight(height);
|
||||
};
|
||||
std::optional<Monitor> monitor = windowsIntegration.setupWallpaperForOneScreen(activeScreen, m_windowHandle, m_windowHandleWorker, updateWindowSize);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -290,7 +287,8 @@ void WinWindow::clearComponentCache()
|
||||
m_window.engine()->clearComponentCache();
|
||||
}
|
||||
|
||||
void WinWindow::checkForFullScreenWindow(){
|
||||
void WinWindow::checkForFullScreenWindow()
|
||||
{
|
||||
bool hasFullscreenWindow = WindowsIntegration().checkForFullScreenWindow(m_windowHandle);
|
||||
|
||||
setVisualsPaused(hasFullscreenWindow);
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <QStringList>
|
||||
#include <QtWebEngineQuick>
|
||||
|
||||
#include "src/widgetwindow.h"
|
||||
#include "ScreenPlayUtil/logginghandler.h"
|
||||
#include "src/widgetwindow.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
Q_IMPORT_QML_PLUGIN(ScreenPlaySysInfoPlugin)
|
||||
|
2
ThirdParty/CMakeLists.txt
vendored
2
ThirdParty/CMakeLists.txt
vendored
@ -16,8 +16,6 @@ FetchContent_Populate(
|
||||
# https://bugreports.qt.io/browse/QTCREATORBUG-27083
|
||||
SOURCE_DIR ${THIRD_PARTY_PATH}/qml-plausible)
|
||||
|
||||
|
||||
|
||||
add_subdirectory(qml-plausible)
|
||||
add_subdirectory(QArchive)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user