mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-22 10:42:29 +01:00
Add working Godot Wallpaper
This commit is contained in:
parent
7ecbd2e8d1
commit
c70fa6224a
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -4,6 +4,7 @@
|
||||
"delgan.qml-format",
|
||||
"ms-vscode.cpptools-extension-pack",
|
||||
"ms-vscode.cmake-tools",
|
||||
"seanwu.vscode-qt-for-python"
|
||||
"seanwu.vscode-qt-for-python",
|
||||
"josetr.cmake-language-support-vscode"
|
||||
]
|
||||
}
|
2
Content/wallpaper_godot_fjord/.gitattributes
vendored
Normal file
2
Content/wallpaper_godot_fjord/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
2
Content/wallpaper_godot_fjord/.gitignore
vendored
Normal file
2
Content/wallpaper_godot_fjord/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
16
Content/wallpaper_godot_fjord/Path3D.gd
Normal file
16
Content/wallpaper_godot_fjord/Path3D.gd
Normal file
@ -0,0 +1,16 @@
|
||||
extends Path3D
|
||||
|
||||
# Reference to the PathFollow node
|
||||
@onready var path_follow = $PathFollow3D
|
||||
|
||||
# Speed of the movement along the path
|
||||
var speed = 0.4
|
||||
|
||||
func _process(delta):
|
||||
# Update the offset to move the object along the path
|
||||
path_follow.progress += speed * delta
|
||||
print(path_follow.progress)
|
||||
|
||||
# Loop back to the start if we've reached the end of the path
|
||||
if path_follow.progress > 10:
|
||||
path_follow.progress = 0.0
|
61
Content/wallpaper_godot_fjord/export_presets.cfg
Normal file
61
Content/wallpaper_godot_fjord/export_presets.cfg
Normal file
@ -0,0 +1,61 @@
|
||||
[preset.0]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
1
Content/wallpaper_godot_fjord/icon.svg
Normal file
1
Content/wallpaper_godot_fjord/icon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>
|
After Width: | Height: | Size: 950 B |
37
Content/wallpaper_godot_fjord/icon.svg.import
Normal file
37
Content/wallpaper_godot_fjord/icon.svg.import
Normal file
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://boex5vkldqpl5"
|
||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
20
Content/wallpaper_godot_fjord/project.godot
Normal file
20
Content/wallpaper_godot_fjord/project.godot
Normal file
@ -0,0 +1,20 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Fjord"
|
||||
run/main_scene="res://wallpaper.tscn"
|
||||
config/features=PackedStringArray("4.1", "Mobile")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="mobile"
|
36
Content/wallpaper_godot_fjord/wallpaper.tscn
Normal file
36
Content/wallpaper_godot_fjord/wallpaper.tscn
Normal file
@ -0,0 +1,36 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cxlfu6y6b3l5o"]
|
||||
|
||||
[ext_resource type="Script" path="res://Path3D.gd" id="1_76sq1"]
|
||||
|
||||
[sub_resource type="Curve3D" id="Curve3D_8adw4"]
|
||||
_data = {
|
||||
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -0.820513, 0.281883, 0.141011, 0, 0, 0, 0, 0, 0, -0.1735, 0.399895, -0.280881, 0, 0, 0, 0, 0, 0, 0.510953, 0.524736, -0.727188, 0, 0, 0, 0, 0, 0, 2.26923, 2.38419e-07, -1.10178, 0, 0, 0, 0, 0, 0, 2.53764, -0.832639, -0.471864, 0, 0, 0, 0, 0, 0, 0.836093, -1.07116, 0.572063, 0, 0, 0, 0, 0, 0, -0.416085, -0.732896, 0.871186, 0, 0, 0, 0, 0, 0, -0.809435, -0.0867326, 0.472196),
|
||||
"tilts": PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
point_count = 8
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.04825, 4.0185)
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.093655, 0)
|
||||
size = Vector3(5.24075, 0.0764128, 3.72353)
|
||||
|
||||
[node name="Path3D" type="Path3D" parent="."]
|
||||
curve = SubResource("Curve3D_8adw4")
|
||||
script = ExtResource("1_76sq1")
|
||||
|
||||
[node name="PathFollow3D" type="PathFollow3D" parent="Path3D"]
|
||||
transform = Transform3D(0.546201, -0.126512, -0.828045, 7.45058e-09, 0.988529, -0.151031, 0.837654, 0.0824935, 0.539936, -0.820513, 0.281883, 0.141011)
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="Path3D/PathFollow3D"]
|
||||
light_color = Color(0.921569, 0.52549, 0.32549, 1)
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.391226, -1.25994)
|
||||
shaded = true
|
||||
text = "GODO WALLPAPER"
|
||||
font_size = 126
|
||||
outline_size = 42
|
@ -8,16 +8,16 @@ set(CMAKE_AUTOMOC ON)
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS Core
|
||||
Quick
|
||||
Gui
|
||||
Widgets
|
||||
WebSockets
|
||||
Svg
|
||||
Multimedia
|
||||
WebEngineCore
|
||||
WebEngineQuick
|
||||
WebChannel
|
||||
Positioning)
|
||||
Quick
|
||||
Gui
|
||||
Widgets
|
||||
WebSockets
|
||||
Svg
|
||||
Multimedia
|
||||
WebEngineCore
|
||||
WebEngineQuick
|
||||
WebChannel
|
||||
Positioning)
|
||||
|
||||
if(WIN32)
|
||||
set(SOURCES src/windowsdesktopproperties.cpp src/winwindow.cpp)
|
||||
@ -38,6 +38,7 @@ set(SOURCES ${SOURCES} main.cpp src/basewindow.cpp)
|
||||
set(HEADER ${HEADER} src/basewindow.h)
|
||||
|
||||
set(QML
|
||||
|
||||
# cmake-format: sort
|
||||
qml/GifWallpaper.qml
|
||||
qml/MultimediaView.qml
|
||||
@ -48,6 +49,17 @@ set(QML
|
||||
|
||||
set(RESOURCES dot.png qtquickcontrols2.conf index.html)
|
||||
|
||||
set(LIB_SOURCES ${SOURCES} src/basewindow.cpp)
|
||||
set(LIB_HEADER ${HEADER} src/basewindow.h)
|
||||
|
||||
add_library(ScreenPlayWallpaperLib STATIC src/windowshook.cpp src/windowshook.h)
|
||||
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})
|
||||
|
||||
qt_add_qml_module(
|
||||
@ -68,17 +80,19 @@ qt_add_qml_module(
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE ScreenPlaySDK
|
||||
ScreenPlayUtil
|
||||
ScreenPlayWeatherplugin
|
||||
Qt6::Quick
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Core
|
||||
Qt6::WebSockets
|
||||
Qt6::Svg
|
||||
Qt6::Multimedia
|
||||
Qt6::WebEngineCore
|
||||
Qt6::WebEngineQuick)
|
||||
ScreenPlayWallpaperLib
|
||||
ScreenPlayUtil
|
||||
ScreenPlayWeatherplugin
|
||||
Qt6::Quick
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Core
|
||||
Qt6::WebSockets
|
||||
Qt6::Svg
|
||||
Qt6::Multimedia
|
||||
Qt6::WebEngineCore
|
||||
Qt6::WebEngineQuick)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
@ -92,12 +106,13 @@ endif()
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")
|
||||
|
||||
if(NOT OSX_BUNDLE)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/index.html
|
||||
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/)
|
||||
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1,128 +1,130 @@
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
cmake_minimum_required( VERSION 3.22 )
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
message( STATUS "Using CMake ${CMAKE_VERSION}" )
|
||||
message(STATUS "Using CMake ${CMAKE_VERSION}")
|
||||
|
||||
# Require out-of-source builds
|
||||
file( TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH )
|
||||
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
|
||||
|
||||
if ( EXISTS "${LOC_PATH}" )
|
||||
message( FATAL_ERROR "You cannot build in the source directory. Please use a build subdirectory." )
|
||||
if(EXISTS "${LOC_PATH}")
|
||||
message(FATAL_ERROR "You cannot build in the source directory. Please use a build subdirectory.")
|
||||
endif()
|
||||
|
||||
# Add paths to modules
|
||||
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
|
||||
# Turn on link time optimization for everything
|
||||
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON )
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
|
||||
|
||||
# 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
|
||||
# Note that CMAKE_OSX_ARCHITECTURES must be set before project().
|
||||
if ( APPLE )
|
||||
set( CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "" )
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
endif()
|
||||
|
||||
# Main project information
|
||||
project( GDExtensionTemplate
|
||||
project(ScreenPlayGodotWallpaper
|
||||
LANGUAGES
|
||||
CXX
|
||||
VERSION
|
||||
0.1.0
|
||||
CXX
|
||||
)
|
||||
|
||||
# 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
|
||||
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).
|
||||
set( LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR} )
|
||||
if ( APPLE )
|
||||
set( LIB_ARCH "universal" )
|
||||
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"
|
||||
set( LIB_DIR "lib/${CMAKE_SYSTEM_NAME}-${LIB_ARCH}" )
|
||||
# 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}")
|
||||
message(STATUS "Building ${PROJECT_NAME} for ${LIB_ARCH} on ${CMAKE_SYSTEM_NAME}")
|
||||
|
||||
# BUILD_OUTPUT_DIR is where we put the resulting library (in the build directory)
|
||||
set( BUILD_OUTPUT_DIR "${PROJECT_BINARY_DIR}/${PROJECT_NAME}/" )
|
||||
set(BUILD_OUTPUT_DIR "${PROJECT_BINARY_DIR}/${PROJECT_NAME}/")
|
||||
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||
|
||||
set_target_properties( ${PROJECT_NAME}
|
||||
# Compile directly into our Godot project
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN true
|
||||
RUNTIME_OUTPUT_DIRECTORY "${BUILD_OUTPUT_DIR}/${LIB_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_DIR}/${LIB_DIR}"
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN true
|
||||
RUNTIME_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
||||
)
|
||||
|
||||
if( NOT DEFINED CMAKE_DEBUG_POSTFIX )
|
||||
set_target_properties( ${PROJECT_NAME}
|
||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
DEBUG_POSTFIX "-d"
|
||||
DEBUG_POSTFIX "-d"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Warnings
|
||||
include( CompilerWarnings )
|
||||
include(CompilerWarnings)
|
||||
|
||||
# Create and include version info file from git
|
||||
include( GitVersionInfo )
|
||||
include(GitVersionInfo)
|
||||
|
||||
add_subdirectory( src )
|
||||
add_subdirectory(src)
|
||||
|
||||
# Install library and extension file in ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}
|
||||
set( INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/" )
|
||||
set(INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/")
|
||||
|
||||
message( STATUS "Install directory: ${INSTALL_DIR}")
|
||||
message(STATUS "Install directory: ${INSTALL_DIR}")
|
||||
|
||||
install( TARGETS ${PROJECT_NAME}
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
LIBRARY
|
||||
DESTINATION ${INSTALL_DIR}/${LIB_DIR}
|
||||
DESTINATION ${INSTALL_DIR}/${LIB_DIR}
|
||||
RUNTIME
|
||||
DESTINATION ${INSTALL_DIR}/${LIB_DIR}
|
||||
DESTINATION ${INSTALL_DIR}/${LIB_DIR}
|
||||
)
|
||||
|
||||
add_subdirectory( templates )
|
||||
add_subdirectory(templates)
|
||||
|
||||
# ccache
|
||||
# Turns on ccache if found
|
||||
include( ccache )
|
||||
include(ccache)
|
||||
|
||||
# Formatting
|
||||
# Adds a custom target to format all the code at once
|
||||
include( ClangFormat )
|
||||
include(ClangFormat)
|
||||
|
||||
# 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(
|
||||
FATAL_ERROR
|
||||
"[${PROJECT_NAME}] The godot-cpp submodule was not downloaded. Please update submodules: git submodule update --init --recursive."
|
||||
"[${PROJECT_NAME}] The godot-cpp submodule was not downloaded. Please update submodules: git submodule update --init --recursive."
|
||||
)
|
||||
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
|
||||
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
|
||||
godot-cpp
|
||||
ScreenPlayWallpaperLib
|
||||
)
|
||||
|
@ -1,15 +1,13 @@
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
target_sources( ${PROJECT_NAME}
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
ScreenPlayWallpaper.h
|
||||
ScreenPlayWallpaper.cpp
|
||||
GDExtensionTemplate.h
|
||||
GDExtensionTemplate.cpp
|
||||
RegisterExtension.cpp
|
||||
ScreenPlayGodotWallpaper.h
|
||||
ScreenPlayGodotWallpaper.cpp
|
||||
RegisterExtension.cpp
|
||||
)
|
||||
|
||||
target_include_directories( ${PROJECT_NAME}
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
"src"
|
||||
"src"
|
||||
)
|
||||
|
@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: Unlicense
|
||||
|
||||
#include "godot_cpp/core/class_db.hpp"
|
||||
|
||||
#include "GDExtensionTemplate.h"
|
||||
#include "Version.h"
|
||||
|
||||
/// @file
|
||||
/// GDExtensionTemplate example implementation.
|
||||
|
||||
/*!
|
||||
@brief Get the version string for this extension.
|
||||
|
||||
@details
|
||||
The version string is generated by cmake using src/Version.h.in.
|
||||
|
||||
It uses the form "<project name> <last tag>-<# commits since last tag>-<short commit hash>".
|
||||
If there are no commits since the last tag, only the tag is shown.
|
||||
|
||||
@return The version string (e.g. "Foo v1.2.3-gdedbd01").
|
||||
*/
|
||||
godot::String GDExtensionTemplate::version()
|
||||
{
|
||||
return VersionInfo::VERSION_STR.data();
|
||||
}
|
||||
|
||||
/// Bind our methods so GDScript can access them.
|
||||
void GDExtensionTemplate::_bind_methods()
|
||||
{
|
||||
godot::ClassDB::bind_static_method( "GDExtensionTemplate", godot::D_METHOD( "version" ),
|
||||
&GDExtensionTemplate::version );
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
// SPDX-License-Identifier: Unlicense
|
||||
|
||||
#include "godot_cpp/classes/object.hpp"
|
||||
|
||||
namespace godot
|
||||
{
|
||||
class ClassDB;
|
||||
};
|
||||
|
||||
class GDExtensionTemplate : public godot::Object
|
||||
{
|
||||
GDCLASS( GDExtensionTemplate, godot::Object )
|
||||
|
||||
public:
|
||||
static godot::String version();
|
||||
|
||||
private:
|
||||
static void _bind_methods();
|
||||
};
|
@ -6,8 +6,7 @@
|
||||
#include "godot_cpp/core/defs.hpp"
|
||||
#include "godot_cpp/godot.hpp"
|
||||
|
||||
#include "GDExtensionTemplate.h"
|
||||
#include "ScreenPlayWallpaper.h"
|
||||
#include "ScreenPlayGodotWallpaper.h"
|
||||
|
||||
/// @file
|
||||
/// Register our classes with Godot.
|
||||
@ -24,13 +23,7 @@ void initializeExtension(godot::ModuleInitializationLevel p_level)
|
||||
return;
|
||||
}
|
||||
|
||||
godot::ClassDB::register_class<ScreenPlayWallpaper>();
|
||||
godot::ClassDB::register_class<ExampleMin>();
|
||||
godot::ClassDB::register_class<Example>();
|
||||
godot::ClassDB::register_class<ExampleVirtual>(true);
|
||||
godot::ClassDB::register_abstract_class<ExampleAbstract>();
|
||||
|
||||
godot::ClassDB::register_class<GDExtensionTemplate>();
|
||||
godot::ClassDB::register_class<ScreenPlayGodotWallpaper>();
|
||||
}
|
||||
|
||||
/// @brief Called by Godot to let us do any cleanup.
|
||||
|
@ -0,0 +1,117 @@
|
||||
// Copied from godot-cpp/test/src and modified.
|
||||
|
||||
#include "ScreenPlayGodotWallpaper.h"
|
||||
#include "godot_cpp/classes/display_server.hpp"
|
||||
#include "godot_cpp/classes/global_constants.hpp"
|
||||
#include "godot_cpp/classes/label.hpp"
|
||||
#include "godot_cpp/classes/os.hpp"
|
||||
#include "godot_cpp/core/class_db.hpp"
|
||||
#include "godot_cpp/variant/utility_functions.hpp"
|
||||
|
||||
//// ScreenPlayWallpaper
|
||||
|
||||
int ScreenPlayGodotWallpaper::sInstanceCount = 0;
|
||||
int ScreenPlayGodotWallpaper::sLastID = 0;
|
||||
|
||||
ScreenPlayGodotWallpaper::ScreenPlayGodotWallpaper()
|
||||
{
|
||||
mID = ++sLastID;
|
||||
sInstanceCount++;
|
||||
|
||||
godot::UtilityFunctions::print(
|
||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||
" created, current instance count: ", godot::itos(sInstanceCount));
|
||||
}
|
||||
|
||||
ScreenPlayGodotWallpaper::~ScreenPlayGodotWallpaper()
|
||||
{
|
||||
sInstanceCount--;
|
||||
godot::UtilityFunctions::print(
|
||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||
" destroyed, current instance count: ", godot::itos(sInstanceCount));
|
||||
|
||||
// Somehow this gets called at editor startup
|
||||
// so just return if not initialized
|
||||
if (!m_hook)
|
||||
return;
|
||||
|
||||
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
||||
|
||||
// Force refresh so that we display the regular
|
||||
// desktop wallpaper again
|
||||
ShowWindow(m_hook->windowHandleWorker, SW_HIDE);
|
||||
ShowWindow(m_hook->windowHandleWorker, SW_SHOW);
|
||||
}
|
||||
|
||||
bool ScreenPlayGodotWallpaper::configureWindowGeometry()
|
||||
{
|
||||
if (!m_hook->searchWorkerWindowToParentTo()) {
|
||||
godot::UtilityFunctions::print("No worker window found");
|
||||
return false;
|
||||
}
|
||||
|
||||
RECT rect {};
|
||||
if (!GetWindowRect(m_hook->windowHandleWorker, &rect)) {
|
||||
godot::UtilityFunctions::print("Unable to get WindoeRect from worker");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Windows coordante system begins at 0x0 at the
|
||||
// main monitors upper left and not at the most left top monitor.
|
||||
// This can be easily read from the worker window.
|
||||
m_hook->zeroPoint = { std::abs(rect.left), std::abs(rect.top) };
|
||||
|
||||
// WARNING: Setting Window flags must be called *here*!
|
||||
SetWindowLongPtr(m_hook->windowHandle, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT);
|
||||
SetWindowLongPtr(m_hook->windowHandle, GWL_STYLE, WS_POPUPWINDOW);
|
||||
return true;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::init(int activeScreen)
|
||||
{
|
||||
auto* displayServer = godot::DisplayServer::get_singleton();
|
||||
int64_t handle_int = displayServer->window_get_native_handle(godot::DisplayServer::HandleType::WINDOW_HANDLE, activeScreen);
|
||||
HWND hwnd = reinterpret_cast<HWND>(static_cast<intptr_t>(handle_int));
|
||||
m_hook = std::make_unique<WindowsHook>();
|
||||
m_hook->windowHandle = hwnd;
|
||||
if (!configureWindowGeometry()) {
|
||||
return false;
|
||||
}
|
||||
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
||||
|
||||
const int borderWidth = 2;
|
||||
const float scaling = m_hook->getScaling(activeScreen); // Assuming getScaling is your own function
|
||||
const int borderOffset = -1;
|
||||
|
||||
WinMonitorStats monitors; // Assuming this is your own function
|
||||
const int width = static_cast<int>(std::abs(monitors.rcMonitors[activeScreen].right - monitors.rcMonitors[activeScreen].left) / scaling) + borderWidth;
|
||||
const int height = static_cast<int>(std::abs(monitors.rcMonitors[activeScreen].top - monitors.rcMonitors[activeScreen].bottom) / scaling) + borderWidth;
|
||||
|
||||
const int x = monitors.rcMonitors[activeScreen].left + m_hook->zeroPoint.x + borderOffset; // Assuming m_zeroPoint is a POINT struct
|
||||
const int y = monitors.rcMonitors[activeScreen].top + m_hook->zeroPoint.y + borderOffset;
|
||||
|
||||
godot::String output = "Setup window activeScreen: " + godot::itos(activeScreen) + " scaling: " + godot::rtos(scaling) + " x: " + godot::itos(x) + " y: " + godot::itos(y) + " width: " + godot::itos(width) + " height: " + godot::itos(height);
|
||||
godot::UtilityFunctions::print(output);
|
||||
|
||||
// Must be called twice for some reason when window has scaling...
|
||||
if (!SetWindowPos(m_hook->windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
|
||||
godot::UtilityFunctions::print("Could not set window pos");
|
||||
return false;
|
||||
}
|
||||
if (!SetWindowPos(m_hook->windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
|
||||
godot::UtilityFunctions::print("Could not set window pos 2");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SetParent(m_hook->windowHandle, m_hook->windowHandleWorker) == nullptr) {
|
||||
godot::UtilityFunctions::print("Could not attach to parent window");
|
||||
return false;
|
||||
}
|
||||
displayServer->window_set_size(godot::Vector2((real_t)width, (real_t)height));
|
||||
ShowWindow(m_hook->windowHandle, SW_SHOW);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScreenPlayGodotWallpaper::_bind_methods()
|
||||
{
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("init"), &ScreenPlayGodotWallpaper::init);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
// Copied from godot-cpp/test/src and modified.
|
||||
|
||||
#include "godot_cpp/classes/control.hpp"
|
||||
#include "godot_cpp/classes/global_constants.hpp"
|
||||
#include "godot_cpp/classes/viewport.hpp"
|
||||
#include "godot_cpp/core/binder_common.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ScreenPlayGodotWallpaper.h"
|
||||
#include "windowshook.h"
|
||||
|
||||
class ScreenPlayGodotWallpaper : public godot::Node {
|
||||
GDCLASS(ScreenPlayGodotWallpaper, Node)
|
||||
|
||||
public:
|
||||
ScreenPlayGodotWallpaper();
|
||||
~ScreenPlayGodotWallpaper() override;
|
||||
|
||||
bool init(int activeScreen);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
bool configureWindowGeometry();
|
||||
|
||||
private:
|
||||
static int sInstanceCount;
|
||||
static int sLastID;
|
||||
|
||||
int mID;
|
||||
std::unique_ptr<WindowsHook> m_hook;
|
||||
};
|
@ -1,475 +0,0 @@
|
||||
// Copied from godot-cpp/test/src and modified.
|
||||
|
||||
#include "godot_cpp/classes/global_constants.hpp"
|
||||
#include "godot_cpp/classes/label.hpp"
|
||||
#include "godot_cpp/core/class_db.hpp"
|
||||
#include "godot_cpp/variant/utility_functions.hpp"
|
||||
|
||||
#include "ScreenPlayWallpaper.h"
|
||||
|
||||
// Used to mark unused parameters to indicate intent and suppress warnings.
|
||||
#define UNUSED(expr) (void)(expr)
|
||||
|
||||
namespace {
|
||||
constexpr int MAGIC_NUMBER = 42;
|
||||
}
|
||||
|
||||
//// ScreenPlayWallpaper
|
||||
|
||||
int ScreenPlayWallpaper::sInstanceCount = 0;
|
||||
int ScreenPlayWallpaper::sLastID = 0;
|
||||
|
||||
ScreenPlayWallpaper::ScreenPlayWallpaper()
|
||||
{
|
||||
mID = ++sLastID;
|
||||
sInstanceCount++;
|
||||
|
||||
godot::UtilityFunctions::print(
|
||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||
" created, current instance count: ", godot::itos(sInstanceCount));
|
||||
}
|
||||
|
||||
ScreenPlayWallpaper::~ScreenPlayWallpaper()
|
||||
{
|
||||
sInstanceCount--;
|
||||
godot::UtilityFunctions::print(
|
||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||
" destroyed, current instance count: ", godot::itos(sInstanceCount));
|
||||
}
|
||||
|
||||
int ScreenPlayWallpaper::getID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
void ScreenPlayWallpaper::_bind_methods()
|
||||
{
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("get_id"), &ScreenPlayWallpaper::getID);
|
||||
}
|
||||
|
||||
//// ExampleMin
|
||||
|
||||
void ExampleMin::_bind_methods()
|
||||
{
|
||||
}
|
||||
|
||||
//// Example
|
||||
|
||||
Example::Example()
|
||||
{
|
||||
godot::UtilityFunctions::print("Constructor.");
|
||||
}
|
||||
|
||||
Example::~Example()
|
||||
{
|
||||
godot::UtilityFunctions::print("Destructor.");
|
||||
}
|
||||
|
||||
// Methods.
|
||||
void Example::simpleFunc()
|
||||
{
|
||||
godot::UtilityFunctions::print(" Simple func called.");
|
||||
}
|
||||
|
||||
void Example::simpleConstFunc() const
|
||||
{
|
||||
godot::UtilityFunctions::print(" Simple const func called.");
|
||||
}
|
||||
|
||||
godot::String Example::returnSomething(const godot::String& inBase)
|
||||
{
|
||||
godot::UtilityFunctions::print(" Return something called.");
|
||||
|
||||
return inBase;
|
||||
}
|
||||
|
||||
godot::Viewport* Example::returnSomethingConst() const
|
||||
{
|
||||
godot::UtilityFunctions::print(" Return something const called.");
|
||||
|
||||
if (is_inside_tree()) {
|
||||
godot::Viewport* result = get_viewport();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
godot::Ref<ScreenPlayWallpaper> Example::returnEmptyRef() const
|
||||
{
|
||||
godot::Ref<ScreenPlayWallpaper> ref;
|
||||
return ref;
|
||||
}
|
||||
|
||||
ScreenPlayWallpaper* Example::returnExtendedRef() const
|
||||
{
|
||||
// You can instance and return a refcounted object like this, but keep in mind that refcounting
|
||||
// starts with the returned object and it will be destroyed when all references are destroyed.
|
||||
// If you store this pointer you run the risk of having a pointer to a destroyed object.
|
||||
return memnew(ScreenPlayWallpaper());
|
||||
}
|
||||
|
||||
godot::Ref<ScreenPlayWallpaper> Example::extendedRefChecks(godot::Ref<ScreenPlayWallpaper> inRef) const
|
||||
{
|
||||
// This is the preferred way of instancing and returning a refcounted object:
|
||||
godot::Ref<ScreenPlayWallpaper> ref;
|
||||
ref.instantiate();
|
||||
|
||||
godot::UtilityFunctions::print(
|
||||
" Example ref checks called with value: ", inRef->get_instance_id(),
|
||||
", returning value: ", ref->get_instance_id());
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
godot::Variant Example::varargsFunc(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError)
|
||||
{
|
||||
UNUSED(inArgs);
|
||||
UNUSED(outError);
|
||||
|
||||
godot::UtilityFunctions::print(" Varargs (Variant return) called with ",
|
||||
godot::String::num_int64(inArgCount), " arguments");
|
||||
|
||||
return inArgCount;
|
||||
}
|
||||
|
||||
int Example::varargsFuncNonVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError)
|
||||
{
|
||||
UNUSED(inArgs);
|
||||
UNUSED(outError);
|
||||
|
||||
godot::UtilityFunctions::print(" Varargs (int return) called with ",
|
||||
godot::String::num_int64(inArgCount), " arguments");
|
||||
|
||||
return MAGIC_NUMBER;
|
||||
}
|
||||
|
||||
void Example::varargsFuncVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError)
|
||||
{
|
||||
UNUSED(inArgs);
|
||||
UNUSED(outError);
|
||||
|
||||
godot::UtilityFunctions::print(" Varargs (no return) called with ",
|
||||
godot::String::num_int64(inArgCount), " arguments");
|
||||
}
|
||||
|
||||
void Example::emitCustomSignal(const godot::String& inName, int inValue)
|
||||
{
|
||||
emit_signal("custom_signal", inName, inValue);
|
||||
}
|
||||
|
||||
int Example::defArgs(int inA, int inB) const
|
||||
{
|
||||
return inA + inB;
|
||||
}
|
||||
|
||||
godot::Array Example::testArray() const
|
||||
{
|
||||
godot::Array arr;
|
||||
|
||||
arr.resize(2);
|
||||
arr[0] = godot::Variant(1);
|
||||
arr[1] = godot::Variant(2);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
void Example::testTypedArrayArg(const godot::TypedArray<int64_t>& inArray)
|
||||
{
|
||||
for (int i = 0; i < inArray.size(); ++i) {
|
||||
godot::UtilityFunctions::print(inArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
godot::TypedArray<godot::Vector2> Example::testTypedArray() const
|
||||
{
|
||||
godot::TypedArray<godot::Vector2> arr;
|
||||
|
||||
arr.resize(2);
|
||||
arr[0] = godot::Vector2(1, 2);
|
||||
arr[1] = godot::Vector2(2, 3);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
godot::Dictionary Example::testDictionary() const
|
||||
{
|
||||
godot::Dictionary dict;
|
||||
|
||||
dict["hello"] = "world";
|
||||
dict["foo"] = "bar";
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
Example* Example::testNodeArgument(Example* inNode) const
|
||||
{
|
||||
// This should use godot::String::num_uint64(), but it is currently broken:
|
||||
// https://github.com/godotengine/godot-cpp/issues/1014
|
||||
godot::UtilityFunctions::print(
|
||||
" Test node argument called with ",
|
||||
(inNode != nullptr)
|
||||
? godot::String::num_int64(static_cast<int64_t>(inNode->get_instance_id()))
|
||||
: "null");
|
||||
return inNode;
|
||||
}
|
||||
|
||||
godot::String Example::testStringOps() const
|
||||
{
|
||||
godot::String s = godot::String("A");
|
||||
s += "B";
|
||||
s += "C";
|
||||
s += char32_t(0x010E);
|
||||
s = s + "E";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int Example::testVectorOps() const
|
||||
{
|
||||
godot::PackedInt32Array arr;
|
||||
arr.push_back(10);
|
||||
arr.push_back(20);
|
||||
arr.push_back(30);
|
||||
arr.push_back(45);
|
||||
|
||||
int ret = 0;
|
||||
for (const int32_t& E : arr) {
|
||||
ret += E;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
godot::BitField<Example::Flags> Example::testBitfield(godot::BitField<Flags> inFlags)
|
||||
{
|
||||
godot::UtilityFunctions::print(" Got BitField: ", godot::String::num_int64(inFlags));
|
||||
return inFlags;
|
||||
}
|
||||
|
||||
// Properties.
|
||||
void Example::setCustomPosition(const godot::Vector2& inPos)
|
||||
{
|
||||
mCustomPosition = inPos;
|
||||
}
|
||||
|
||||
godot::Vector2 Example::getCustomPosition() const
|
||||
{
|
||||
return mCustomPosition;
|
||||
}
|
||||
|
||||
godot::Vector4 Example::getV4() const
|
||||
{
|
||||
return { 1.2f, 3.4f, 5.6f, 7.8f };
|
||||
}
|
||||
|
||||
// Static methods
|
||||
int Example::testStatic(int inA, int inB)
|
||||
{
|
||||
return inA + inB;
|
||||
}
|
||||
|
||||
void Example::testStatic2()
|
||||
{
|
||||
godot::UtilityFunctions::print(" void static");
|
||||
}
|
||||
|
||||
// Virtual function override.
|
||||
bool Example::_has_point(const godot::Vector2& inPoint) const
|
||||
{
|
||||
auto* label = godot::Control::get_node<godot::Label>("Label");
|
||||
|
||||
label->set_text("Got point: " + godot::Variant(inPoint).stringify());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Example::_bind_methods()
|
||||
{
|
||||
// Methods.
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("simple_func"), &Example::simpleFunc);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("simple_const_func"),
|
||||
&Example::simpleConstFunc);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("return_something"), &Example::returnSomething);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("return_something_const"),
|
||||
&Example::returnSomethingConst);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("return_empty_ref"), &Example::returnEmptyRef);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("return_extended_ref"),
|
||||
&Example::returnExtendedRef);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("extended_ref_checks", "ref"),
|
||||
&Example::extendedRefChecks);
|
||||
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_array"), &Example::testArray);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_tarray_arg", "array"),
|
||||
&Example::testTypedArrayArg);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_tarray"), &Example::testTypedArray);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_dictionary"), &Example::testDictionary);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_node_argument"),
|
||||
&Example::testNodeArgument);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_string_ops"), &Example::testStringOps);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_vector_ops"), &Example::testVectorOps);
|
||||
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("test_bitfield", "flags"),
|
||||
&Example::testBitfield);
|
||||
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("def_args", "a", "b"), &Example::defArgs,
|
||||
DEFVAL(100), DEFVAL(200));
|
||||
|
||||
godot::ClassDB::bind_static_method("Example", godot::D_METHOD("test_static", "a", "b"),
|
||||
&Example::testStatic);
|
||||
godot::ClassDB::bind_static_method("Example", godot::D_METHOD("test_static2"),
|
||||
&Example::testStatic2);
|
||||
|
||||
{
|
||||
godot::MethodInfo mi;
|
||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
||||
mi.name = "varargs_func";
|
||||
|
||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func",
|
||||
&Example::varargsFunc, mi);
|
||||
}
|
||||
|
||||
{
|
||||
godot::MethodInfo mi;
|
||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
||||
mi.name = "varargs_func_nv";
|
||||
|
||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func_nv",
|
||||
&Example::varargsFuncNonVoidReturn, mi);
|
||||
}
|
||||
|
||||
{
|
||||
godot::MethodInfo mi;
|
||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
||||
mi.name = "varargs_func_void";
|
||||
|
||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func_void",
|
||||
&Example::varargsFuncVoidReturn, mi);
|
||||
}
|
||||
|
||||
// Properties.
|
||||
ADD_GROUP("Test group", "group_");
|
||||
ADD_SUBGROUP("Test subgroup", "group_subgroup_");
|
||||
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("get_custom_position"),
|
||||
&Example::getCustomPosition);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("get_v4"), &Example::getV4);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("set_custom_position", "position"),
|
||||
&Example::setCustomPosition);
|
||||
ADD_PROPERTY(godot::PropertyInfo(godot::Variant::VECTOR2, "group_subgroup_custom_position"),
|
||||
"set_custom_position", "get_custom_position");
|
||||
|
||||
// Signals.
|
||||
ADD_SIGNAL(godot::MethodInfo("custom_signal",
|
||||
godot::PropertyInfo(godot::Variant::STRING, "name"),
|
||||
godot::PropertyInfo(godot::Variant::INT, "value")));
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("emit_custom_signal", "name", "value"),
|
||||
&Example::emitCustomSignal);
|
||||
|
||||
// Constants.
|
||||
BIND_ENUM_CONSTANT(FIRST)
|
||||
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING)
|
||||
|
||||
BIND_BITFIELD_FLAG(FLAG_ONE);
|
||||
BIND_BITFIELD_FLAG(FLAG_TWO);
|
||||
|
||||
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
||||
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
||||
}
|
||||
|
||||
void Example::_notification(int inWhat)
|
||||
{
|
||||
godot::UtilityFunctions::print("Notification: ", godot::String::num(inWhat));
|
||||
}
|
||||
|
||||
bool Example::_set(const godot::StringName& inName, const godot::Variant& inValue)
|
||||
{
|
||||
godot::String name = inName;
|
||||
|
||||
if (name.begins_with("dproperty")) {
|
||||
int64_t index = name.get_slicec('_', 1).to_int();
|
||||
mDProp[index] = inValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "property_from_list") {
|
||||
mPropertyFromList = inValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Example::_get(const godot::StringName& inName, godot::Variant& outReturn) const
|
||||
{
|
||||
godot::String name = inName;
|
||||
|
||||
if (name.begins_with("dproperty")) {
|
||||
int64_t index = name.get_slicec('_', 1).to_int();
|
||||
outReturn = mDProp[index];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "property_from_list") {
|
||||
outReturn = mPropertyFromList;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Example::_get_property_list(godot::List<godot::PropertyInfo>* outList) const
|
||||
{
|
||||
outList->push_back(godot::PropertyInfo(godot::Variant::VECTOR3, "property_from_list"));
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
outList->push_back(
|
||||
godot::PropertyInfo(godot::Variant::VECTOR2, "dproperty_" + godot::itos(i)));
|
||||
}
|
||||
}
|
||||
|
||||
bool Example::_property_can_revert(const godot::StringName& inName) const
|
||||
{
|
||||
if (inName == godot::StringName("property_from_list") && mPropertyFromList != godot::Vector3(MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
bool Example::_property_get_revert(const godot::StringName& inName,
|
||||
godot::Variant& outProperty) const
|
||||
{
|
||||
if (inName == godot::StringName("property_from_list")) {
|
||||
outProperty = godot::Vector3(MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
godot::String Example::_to_string() const
|
||||
{
|
||||
return "[ GDExtension::Example <--> Instance ID:" + godot::uitos(get_instance_id()) + " ]";
|
||||
}
|
||||
|
||||
//// ExampleVirtual
|
||||
|
||||
void ExampleVirtual::_bind_methods()
|
||||
{
|
||||
}
|
||||
|
||||
//// ExampleAbstract
|
||||
|
||||
void ExampleAbstract::_bind_methods()
|
||||
{
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
#pragma once
|
||||
// Copied from godot-cpp/test/src and modified.
|
||||
|
||||
#include "godot_cpp/classes/control.hpp"
|
||||
#include "godot_cpp/classes/global_constants.hpp"
|
||||
#include "godot_cpp/classes/viewport.hpp"
|
||||
#include "godot_cpp/core/binder_common.hpp"
|
||||
|
||||
class ScreenPlayWallpaper : public godot::RefCounted {
|
||||
GDCLASS(ScreenPlayWallpaper, RefCounted)
|
||||
|
||||
public:
|
||||
ScreenPlayWallpaper();
|
||||
~ScreenPlayWallpaper() override;
|
||||
|
||||
int getID() const;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
static int sInstanceCount;
|
||||
static int sLastID;
|
||||
|
||||
int mID;
|
||||
};
|
||||
|
||||
class ExampleMin : public godot::Control {
|
||||
GDCLASS(ExampleMin, Control)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
class Example : public godot::Control {
|
||||
GDCLASS(Example, godot::Control)
|
||||
|
||||
public:
|
||||
// Constants.
|
||||
enum Constants {
|
||||
FIRST,
|
||||
ANSWER_TO_EVERYTHING = 42,
|
||||
};
|
||||
|
||||
enum {
|
||||
CONSTANT_WITHOUT_ENUM = 314,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
FLAG_ONE = 1,
|
||||
FLAG_TWO = 2,
|
||||
};
|
||||
|
||||
Example();
|
||||
~Example() override;
|
||||
|
||||
// Functions.
|
||||
void simpleFunc();
|
||||
void simpleConstFunc() const;
|
||||
godot::String returnSomething(const godot::String& inBase);
|
||||
godot::Viewport* returnSomethingConst() const;
|
||||
godot::Ref<ScreenPlayWallpaper> returnEmptyRef() const;
|
||||
ScreenPlayWallpaper* returnExtendedRef() const;
|
||||
godot::Ref<ScreenPlayWallpaper> extendedRefChecks(godot::Ref<ScreenPlayWallpaper> inRef) const;
|
||||
godot::Variant varargsFunc(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError);
|
||||
int varargsFuncNonVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError);
|
||||
void varargsFuncVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
||||
GDExtensionCallError& outError);
|
||||
|
||||
void emitCustomSignal(const godot::String& inName, int inValue);
|
||||
int defArgs(int inA = 100, int inB = 200) const;
|
||||
|
||||
godot::Array testArray() const;
|
||||
void testTypedArrayArg(const godot::TypedArray<int64_t>& inArray);
|
||||
godot::TypedArray<godot::Vector2> testTypedArray() const;
|
||||
godot::Dictionary testDictionary() const;
|
||||
Example* testNodeArgument(Example* inNode) const;
|
||||
godot::String testStringOps() const;
|
||||
int testVectorOps() const;
|
||||
|
||||
godot::BitField<Flags> testBitfield(godot::BitField<Flags> inFlags);
|
||||
|
||||
// Property.
|
||||
void setCustomPosition(const godot::Vector2& inPos);
|
||||
godot::Vector2 getCustomPosition() const;
|
||||
godot::Vector4 getV4() const;
|
||||
|
||||
// Static method.
|
||||
static int testStatic(int inA, int inB);
|
||||
static void testStatic2();
|
||||
|
||||
// Virtual function override (no need to bind manually).
|
||||
virtual bool _has_point(const godot::Vector2& inPoint) const override;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int inWhat);
|
||||
bool _set(const godot::StringName& inName, const godot::Variant& inValue);
|
||||
bool _get(const godot::StringName& inName, godot::Variant& outReturn) const;
|
||||
void _get_property_list(godot::List<godot::PropertyInfo>* outList) const;
|
||||
bool _property_can_revert(const godot::StringName& inName) const;
|
||||
bool _property_get_revert(const godot::StringName& inName, godot::Variant& outProperty) const;
|
||||
|
||||
godot::String _to_string() const;
|
||||
|
||||
private:
|
||||
godot::Vector2 mCustomPosition;
|
||||
godot::Vector3 mPropertyFromList;
|
||||
godot::Vector2 mDProp[3];
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Example::Constants);
|
||||
VARIANT_BITFIELD_CAST(Example::Flags);
|
||||
|
||||
enum EnumWithoutClass {
|
||||
OUTSIDE_OF_CLASS = 512
|
||||
};
|
||||
VARIANT_ENUM_CAST(EnumWithoutClass);
|
||||
|
||||
class ExampleVirtual : public godot::Object {
|
||||
GDCLASS(ExampleVirtual, godot::Object)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
class ExampleAbstract : public godot::Object {
|
||||
GDCLASS(ExampleAbstract, godot::Object)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
@ -1,32 +1,34 @@
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
add_custom_target( templates
|
||||
add_custom_target(templates
|
||||
SOURCES
|
||||
template.debug.gdextension.in
|
||||
template.release.gdextension.in
|
||||
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)
|
||||
# But until we fix it here and in godot-cpp, ensure it's one we expect.
|
||||
set ( ALLOWED_BUILDS "Debug;Release" )
|
||||
if ( NOT "${CMAKE_BUILD_TYPE}" IN_LIST ALLOWED_BUILDS )
|
||||
message( FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release" )
|
||||
set(ALLOWED_BUILDS "Debug;Release")
|
||||
|
||||
if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST ALLOWED_BUILDS)
|
||||
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release")
|
||||
endif()
|
||||
|
||||
# Get our gdextension input file name based on build type
|
||||
string( TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE )
|
||||
set( GD_EXTENSION_FILE_INPUT template.${BUILD_TYPE}.gdextension.in )
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
|
||||
set(GD_EXTENSION_FILE_INPUT template.${BUILD_TYPE}.gdextension.in)
|
||||
|
||||
# Workaround to add the "lib" prefix to the library in our template file if using MSYS2.
|
||||
if ( MINGW )
|
||||
set( LIB_PREFIX "lib")
|
||||
if(MINGW)
|
||||
set(LIB_PREFIX "lib")
|
||||
endif()
|
||||
|
||||
# Generate our project's .gdextension file from the template
|
||||
set( GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension )
|
||||
configure_file( ${GD_EXTENSION_FILE_INPUT} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}/${GD_EXTENSION_FILE} )
|
||||
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||
set(GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension)
|
||||
configure_file(${GD_EXTENSION_FILE_INPUT} ${OUT_PATH}/${GD_EXTENSION_FILE})
|
||||
|
||||
# Install the gdextension file from the build directory
|
||||
install(
|
||||
@ -34,8 +36,8 @@ install(
|
||||
DESTINATION ${INSTALL_DIR}
|
||||
)
|
||||
|
||||
unset( ALLOWED_BUILDS )
|
||||
unset( BUILD_TYPE )
|
||||
unset( GD_EXTENSION_FILE )
|
||||
unset( GD_EXTENSION_FILE_INPUT )
|
||||
unset( LIB_PREFIX )
|
||||
unset(ALLOWED_BUILDS)
|
||||
unset(BUILD_TYPE)
|
||||
unset(GD_EXTENSION_FILE)
|
||||
unset(GD_EXTENSION_FILE_INPUT)
|
||||
unset(LIB_PREFIX)
|
||||
|
@ -0,0 +1,10 @@
|
||||
[configuration]
|
||||
|
||||
entry_symbol = "GDExtensionInit"
|
||||
compatibility_minimum = 4.1
|
||||
|
||||
[libraries]
|
||||
|
||||
linux.debug.x86_64 = "res://ScreenPlayGodotWallpaper/lib/Linux-x86_64/libScreenPlayGodotWallpaper-d.so"
|
||||
macos.debug = "res://ScreenPlayGodotWallpaper/lib/Darwin-Universal/libScreenPlayGodotWallpaper-d.dylib"
|
||||
windows.debug.x86_64 = "res://ScreenPlayGodotWallpaper/lib/Windows-AMD64/ScreenPlayGodotWallpaper-d.dll"
|
@ -1,13 +1,18 @@
|
||||
extends Node3D
|
||||
|
||||
@onready var screen_play_wallpaper = $ScreenPlayGodotWallpaper
|
||||
|
||||
func _ready():
|
||||
var path = ""
|
||||
# "C:\\Code\\cpp\\ScreenPlay\\ScreenPlay\\Content\\wallpaper_godot_fjord\\fjord.zip"
|
||||
var path = "C:\\Code\\cpp\\ScreenPlay\\ScreenPlay\\Content\\wallpaper_godot_fjord\\fjord.zip"
|
||||
var success = ProjectSettings.load_resource_pack (path)
|
||||
if success:
|
||||
var scene_resource = load("res://wallpaper.tscn")
|
||||
if scene_resource:
|
||||
var scene_instance = scene_resource.instantiate()
|
||||
add_child(scene_instance)
|
||||
var ok = screen_play_wallpaper.init(0)
|
||||
print("init ", ok)
|
||||
else:
|
||||
print("Failed to load the wallpaper.tscn scene.")
|
||||
else:
|
||||
|
@ -4,3 +4,5 @@
|
||||
|
||||
[node name="Wallpaper" type="Node3D"]
|
||||
script = ExtResource("1_ceeuk")
|
||||
|
||||
[node name="ScreenPlayGodotWallpaper" type="ScreenPlayGodotWallpaper" parent="."]
|
||||
|
@ -14,8 +14,18 @@ config/name="ScreenPlay"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/features=PackedStringArray("4.1", "Mobile")
|
||||
boot_splash/show_image=false
|
||||
boot_splash/fullsize=false
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1
|
||||
window/size/viewport_height=1
|
||||
window/size/mode=1
|
||||
window/size/initial_position_type=0
|
||||
window/size/initial_position=Vector2i(9999999, 9999999)
|
||||
window/size/borderless=true
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="mobile"
|
||||
|
111
ScreenPlayWallpaper/src/windowshook.cpp
Normal file
111
ScreenPlayWallpaper/src/windowshook.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "windowshook.h"
|
||||
|
||||
BOOL CALLBACK WinMonitorStats::MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
|
||||
{
|
||||
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
|
||||
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
|
||||
GetScaleFactorForMonitor(hMon, &scaleFactor);
|
||||
|
||||
UINT x = 0;
|
||||
UINT y = 0;
|
||||
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
|
||||
pThis->sizes.push_back({ x, y });
|
||||
pThis->scaleFactor.push_back(scaleFactor);
|
||||
pThis->hMonitors.push_back(hMon);
|
||||
pThis->hdcMonitors.push_back(hdc);
|
||||
pThis->rcMonitors.push_back(*lprcMonitor);
|
||||
pThis->iMonitors.push_back(static_cast<int>(pThis->hdcMonitors.size()));
|
||||
|
||||
// qInfo() << std::abs(lprcMonitor->right - lprcMonitor->left) << std::abs(lprcMonitor->top - lprcMonitor->bottom);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*!
|
||||
\brief Searches for the worker window for our window to parent to.
|
||||
*/
|
||||
BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
||||
{
|
||||
// 0xXXXXXXX "" WorkerW
|
||||
// ...
|
||||
// 0xXXXXXXX "" SHELLDLL_DefView
|
||||
// 0xXXXXXXXX "FolderView" SysListView32
|
||||
// 0xXXXXXXXX "" WorkerW <---- We want this one
|
||||
// 0xXXXXXXXX "Program Manager" Progman
|
||||
if (FindWindowExW(hwnd, nullptr, L"SHELLDLL_DefView", nullptr))
|
||||
*reinterpret_cast<HWND*>(lparam) = FindWindowExW(nullptr, hwnd, L"WorkerW", nullptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool WindowsHook::searchWorkerWindowToParentTo()
|
||||
{
|
||||
|
||||
HWND progman_hwnd = FindWindowW(L"Progman", L"Program Manager");
|
||||
const DWORD WM_SPAWN_WORKER = 0x052C;
|
||||
SendMessageTimeoutW(progman_hwnd, WM_SPAWN_WORKER, 0xD, 0x1, SMTO_NORMAL,
|
||||
10000, nullptr);
|
||||
|
||||
return EnumWindows(SearchForWorkerWindow, reinterpret_cast<LPARAM>(&windowHandleWorker));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns scaling factor as reported by Windows.
|
||||
*/
|
||||
float WindowsHook::getScaling(const int monitorIndex) const
|
||||
{
|
||||
// Get all monitors
|
||||
int monitorCount = GetSystemMetrics(SM_CMONITORS);
|
||||
|
||||
if (monitorIndex < 0 || monitorIndex >= monitorCount) {
|
||||
// Invalid monitor index
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
DISPLAY_DEVICE displayDevice;
|
||||
ZeroMemory(&displayDevice, sizeof(displayDevice));
|
||||
displayDevice.cb = sizeof(displayDevice);
|
||||
|
||||
// Enumerate through monitors until we find the one we're looking for
|
||||
for (int i = 0; EnumDisplayDevices(NULL, i, &displayDevice, 0); i++) {
|
||||
if (i == monitorIndex) {
|
||||
DEVMODE devMode;
|
||||
ZeroMemory(&devMode, sizeof(devMode));
|
||||
devMode.dmSize = sizeof(devMode);
|
||||
|
||||
// Get settings for selected monitor
|
||||
if (!EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) {
|
||||
// Unable to get monitor settings
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// Get DPI for selected monitor
|
||||
HMONITOR hMonitor = MonitorFromPoint({ devMode.dmPosition.x, devMode.dmPosition.y }, MONITOR_DEFAULTTONEAREST);
|
||||
UINT dpiX = 0, dpiY = 0;
|
||||
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
|
||||
return (float)dpiX / 96.0f; // Standard DPI is 96
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here, it means we couldn't find the monitor with the given index or couldn't get the DPI.
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns true of at least one monitor has active scaling enabled.
|
||||
*/
|
||||
bool WindowsHook::hasWindowScaling() const
|
||||
{
|
||||
auto enumMonitorCallback = [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
|
||||
int scaling = GetDeviceCaps(hdcMonitor, LOGPIXELSX) / 96;
|
||||
if (scaling != 1) {
|
||||
*(bool*)dwData = true;
|
||||
return false; // Stop enumeration
|
||||
}
|
||||
return true; // Continue enumeration
|
||||
};
|
||||
|
||||
bool hasScaling = false;
|
||||
EnumDisplayMonitors(NULL, NULL, enumMonitorCallback, (LPARAM)&hasScaling);
|
||||
|
||||
return hasScaling;
|
||||
}
|
41
ScreenPlayWallpaper/src/windowshook.h
Normal file
41
ScreenPlayWallpaper/src/windowshook.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <shellscalingapi.h>
|
||||
#include <vector>
|
||||
|
||||
struct WinMonitorStats {
|
||||
|
||||
WinMonitorStats()
|
||||
{
|
||||
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData);
|
||||
std::vector<int> iMonitors;
|
||||
std::vector<HMONITOR> hMonitors;
|
||||
std::vector<HDC> hdcMonitors;
|
||||
std::vector<RECT> rcMonitors;
|
||||
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
|
||||
std::vector<std::pair<UINT, UINT>> sizes;
|
||||
int index = 0;
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
};
|
||||
|
||||
struct WindowsHook {
|
||||
bool searchWorkerWindowToParentTo();
|
||||
float getScaling(const int monitorIndex) const;
|
||||
bool hasWindowScaling() const;
|
||||
HWND windowHandle {};
|
||||
HWND windowHandleWorker {};
|
||||
Point zeroPoint;
|
||||
};
|
Loading…
Reference in New Issue
Block a user