Răsfoiți Sursa

Basic support for web wallpapers (#196)

* Updated gitignore

* Basic Web support

* Basic Cmake(not working)

* Working CEF

* Clean up Render/CWeb

* Download CEF in CMAKE

* Fixed compile error(excesive comma)

* Fixed CWeb compile error(scaling mode)

* Commented flag in CEF flag(-fno-rtti) which disabled dynamic cast

* Commented CEF compiler flags for MacOS

* Added third_party to gitignore

* Fixed libvulkan.so.1 error (deleted file entirely)

* Removed cefsimple, CefShutdown in signal, cleaned up cmake a bit

* Updated .gitignore

* Get render function to previous version

* Fixed typo in coment

* Fixed tab

* Removed shaders too

* Fix codefactor issues
Pasalc 2 ani în urmă
părinte
comite
ca3c73740c

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@ cmake-build-debug*
 .idea
 build/
 .vscode/
+third_party/
 
 *-protocol.o
 *-protocol.c

+ 86 - 3
CMakeLists.txt

@@ -1,6 +1,7 @@
 cmake_minimum_required(VERSION 3.12)
 project(linux-wallpaperengine)
 
+set_property(GLOBAL PROPERTY OS_FOLDERS ON)
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
 set(OpenGL_GL_PREFERENCE "LEGACY")
@@ -30,6 +31,63 @@ find_package(FFMPEG REQUIRED)
 find_package(FreeImage REQUIRED)
 find_package(PulseAudio REQUIRED)
 
+# Download CEF of specified version for current platform
+# Specify the CEF distribution version.
+set(CEF_VERSION "120.1.10+g3ce3184+chromium-120.0.6099.129")
+# Determine the platform.
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+  if("${PROJECT_ARCH}" STREQUAL "arm64")
+    set(CEF_PLATFORM "macosarm64")
+  elseif("${PROJECT_ARCH}" STREQUAL "x86_64")
+    set(CEF_PLATFORM "macosx64")
+  elseif("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64")
+    set(PROJECT_ARCH "arm64")
+    set(CEF_PLATFORM "macosarm64")
+  else()
+    set(PROJECT_ARCH "x86_64")
+    set(CEF_PLATFORM "macosx64")
+  endif()
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+  if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm")
+    set(CEF_PLATFORM "linuxarm")
+  elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm64")
+    set(CEF_PLATFORM "linuxarm64")
+  elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
+    set(CEF_PLATFORM "linux64")
+  else()
+    message(FATAL_ERROR "Linux x86 32-bit builds are discontinued.")
+  endif()
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  if("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM64")
+    set(CEF_PLATFORM "windowsarm64")
+  elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
+    set(CEF_PLATFORM "windows64")
+  else()
+    set(CEF_PLATFORM "windows32")
+  endif()
+endif()
+include(DownloadCEF)
+DownloadCEF("${CEF_PLATFORM}" "${CEF_VERSION}" "${CMAKE_SOURCE_DIR}/third_party/cef")
+
+find_package(CEF REQUIRED)
+
+set(
+    CMAKE_RUNTIME_OUTPUT_DIRECTORY
+    ${CMAKE_HOME_DIRECTORY}/build
+    )
+	
+set(
+    CMAKE_LIBRARY_OUTPUT_DIRECTORY
+    ${CMAKE_HOME_DIRECTORY}/lib
+    )
+	
+set(
+    TARGET_OUTPUT_DIRECTORY
+    ${CMAKE_HOME_DIRECTORY}/build
+    )
+
+add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
+
 include_directories(
     ${MPV_INCLUDE_DIR}
     ${X11_INCLUDE_DIR}
@@ -41,9 +99,19 @@ include_directories(
     ${FREEIMAGE_INCLUDE_DIR}
     ${PULSEAUDIO_INCLUDE_DIR}
     src
+    ${CEF_INCLUDE_PATH}
     ${CMAKE_SOURCE_DIR}
     include)
 
+
+add_library(ceflib SHARED IMPORTED)
+set_target_properties(ceflib 
+    PROPERTIES IMPORTED_LOCATION ${TARGET_OUTPUT_DIRECTORY}/libcef.so)
+
+ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
+# SET_CEF_TARGET_OUT_DIR()
+include_directories(${_CEF_ROOT})
+
 # try to enable wayland builds when possible
 pkg_check_modules(WAYLAND_SUPPORT wayland-cursor wayland-protocols egl wayland-egl)
 
@@ -206,6 +274,8 @@ add_executable(
     src/WallpaperEngine/Render/CScene.cpp
     src/WallpaperEngine/Render/CVideo.h
     src/WallpaperEngine/Render/CVideo.cpp
+    src/WallpaperEngine/Render/CWeb.h
+    src/WallpaperEngine/Render/CWeb.cpp
     src/WallpaperEngine/Render/CCamera.h
     src/WallpaperEngine/Render/CCamera.cpp
     src/WallpaperEngine/Render/CObject.h
@@ -245,6 +315,8 @@ add_executable(
     src/WallpaperEngine/Core/CScene.h
     src/WallpaperEngine/Core/CVideo.cpp
     src/WallpaperEngine/Core/CVideo.h
+    src/WallpaperEngine/Core/CWeb.cpp
+    src/WallpaperEngine/Core/CWeb.h
     src/WallpaperEngine/Core/CObject.cpp
     src/WallpaperEngine/Core/CObject.h
 
@@ -324,7 +396,16 @@ add_executable(
     ${WAYLAND_SOURCES}
 )
 
-target_link_libraries(linux-wallpaperengine
+COPY_FILES(linux-wallpaperengine "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
+COPY_FILES(linux-wallpaperengine "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
+
+SET_EXECUTABLE_TARGET_PROPERTIES(linux-wallpaperengine)
+add_dependencies(linux-wallpaperengine libcef_dll_wrapper)
+
+# Need to remove libvulkan, otherwise will get error on  linking:
+# /usr/bin/ld: /usr/lib/libmpv.so: undefined reference to `vkCreateXlibSurfaceKHR'
+file(REMOVE "${CEF_BINARY_DIR_DEBUG}/libvulkan.so.1" "${CEF_BINARY_DIR_RELEASE}/libvulkan.so.1") 
+target_link_libraries (linux-wallpaperengine PUBLIC 
     ${X11_LIBRARIES}
     ${Xrandr_LIBRARIES}
     ${X11_Xxf86vm_LIB}
@@ -338,10 +419,12 @@ target_link_libraries(linux-wallpaperengine
     ${FREEIMAGE_LIBRARIES}
     ${MPV_LIBRARY}
     ${PULSEAUDIO_LIBRARY}
-    glfw)
+    glfw
+    libcef_lib libcef_dll_wrapper)
+
 
 if (WAYLAND_SUPPORT_FOUND)
-    target_link_libraries(linux-wallpaperengine
+    target_link_libraries(linux-wallpaperengine PUBLIC
         pthread
         wayland-cursor
         wayland-client

+ 48 - 0
CMakeModules/DownloadCEF.cmake

@@ -0,0 +1,48 @@
+# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
+# reserved. Use of this source code is governed by a BSD-style license that
+# can be found in the LICENSE file.
+
+# Download the CEF binary distribution for |platform| and |version| to
+# |download_dir|. The |CEF_ROOT| variable will be set in global scope pointing
+# to the extracted location.
+# Visit https://cef-builds.spotifycdn.com/index.html for the list of
+# supported platforms and versions.
+
+function(DownloadCEF platform version download_dir)
+  # Specify the binary distribution type and download directory.
+  set(CEF_DISTRIBUTION "cef_binary_${version}_${platform}")
+  set(CEF_DOWNLOAD_DIR "${download_dir}")
+
+  # The location where we expect the extracted binary distribution.
+  set(CEF_ROOT "${CEF_DOWNLOAD_DIR}/${CEF_DISTRIBUTION}" CACHE INTERNAL "CEF_ROOT")
+
+  # Download and/or extract the binary distribution if necessary.
+  if(NOT IS_DIRECTORY "${CEF_ROOT}")
+    set(CEF_DOWNLOAD_FILENAME "${CEF_DISTRIBUTION}.tar.bz2")
+    set(CEF_DOWNLOAD_PATH "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}")
+    if(NOT EXISTS "${CEF_DOWNLOAD_PATH}")
+      set(CEF_DOWNLOAD_URL "https://cef-builds.spotifycdn.com/${CEF_DOWNLOAD_FILENAME}")
+      string(REPLACE "+" "%2B" CEF_DOWNLOAD_URL_ESCAPED ${CEF_DOWNLOAD_URL})
+
+      # Download the SHA1 hash for the binary distribution.
+      message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}.sha1 from ${CEF_DOWNLOAD_URL_ESCAPED}...")
+      file(DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}.sha1" "${CEF_DOWNLOAD_PATH}.sha1")
+      file(READ "${CEF_DOWNLOAD_PATH}.sha1" CEF_SHA1)
+
+      # Download the binary distribution and verify the hash.
+      message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}...")
+      file(
+        DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}" "${CEF_DOWNLOAD_PATH}"
+        EXPECTED_HASH SHA1=${CEF_SHA1}
+        SHOW_PROGRESS
+        )
+    endif()
+
+    # Extract the binary distribution.
+    message(STATUS "Extracting ${CEF_DOWNLOAD_PATH}...")
+    execute_process(
+      COMMAND ${CMAKE_COMMAND} -E tar xzf "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}"
+      WORKING_DIRECTORY ${CEF_DOWNLOAD_DIR}
+      )
+  endif()
+endfunction()

+ 39 - 0
CMakeModules/FindCEF.cmake

@@ -0,0 +1,39 @@
+# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
+# reserved. Use of this source code is governed by a BSD-style license that
+# can be found in the LICENSE file.
+
+#
+# This file is the CEF CMake configuration entry point and should be loaded
+# using `find_package(CEF REQUIRED)`. See the top-level CMakeLists.txt file
+# included with the CEF binary distribution for usage information.
+#
+
+# Find the CEF binary distribution root directory.
+set(_CEF_ROOT "")
+if(CEF_ROOT AND IS_DIRECTORY "${CEF_ROOT}")
+  set(_CEF_ROOT "${CEF_ROOT}")
+  set(_CEF_ROOT_EXPLICIT 1)
+else()
+  set(_ENV_CEF_ROOT "")
+  if(DEFINED ENV{CEF_ROOT})
+    file(TO_CMAKE_PATH "$ENV{CEF_ROOT}" _ENV_CEF_ROOT)
+  endif()
+  if(_ENV_CEF_ROOT AND IS_DIRECTORY "${_ENV_CEF_ROOT}")
+    set(_CEF_ROOT "${_ENV_CEF_ROOT}")
+    set(_CEF_ROOT_EXPLICIT 1)
+  endif()
+  unset(_ENV_CEF_ROOT)
+endif()
+
+if(NOT DEFINED _CEF_ROOT_EXPLICIT)
+  message(FATAL_ERROR "Must specify a CEF_ROOT value via CMake or environment variable.")
+endif()
+
+if(NOT IS_DIRECTORY "${_CEF_ROOT}/cmake")
+  message(FATAL_ERROR "No CMake bootstrap found for CEF binary distribution at: ${CEF_ROOT}.")
+endif()
+
+# Execute additional cmake files from the CEF binary distribution.
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${_CEF_ROOT}/cmake")
+include("cef_variables")
+include("cef_macros")

+ 387 - 0
CMakeModules/cef_macros.cmake

@@ -0,0 +1,387 @@
+# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
+# reserved. Use of this source code is governed by a BSD-style license that
+# can be found in the LICENSE file.
+
+# Must be loaded via FindCEF.cmake.
+if(NOT DEFINED _CEF_ROOT_EXPLICIT)
+  message(FATAL_ERROR "Use find_package(CEF) to load this file.")
+endif()
+
+
+#
+# Shared macros.
+#
+
+# Print the current CEF configuration.
+macro(PRINT_CEF_CONFIG)
+  message(STATUS "*** CEF CONFIGURATION SETTINGS ***")
+  message(STATUS "Generator:                    ${CMAKE_GENERATOR}")
+  message(STATUS "Platform:                     ${CMAKE_SYSTEM_NAME}")
+  message(STATUS "Project architecture:         ${PROJECT_ARCH}")
+
+  if(GEN_NINJA OR GEN_MAKEFILES)
+    message(STATUS "Build type:                   ${CMAKE_BUILD_TYPE}")
+  endif()
+
+  message(STATUS "Binary distribution root:     ${_CEF_ROOT}")
+
+  if(OS_MAC)
+    message(STATUS "Base SDK:                     ${CMAKE_OSX_SYSROOT}")
+    message(STATUS "Target SDK:                   ${CEF_TARGET_SDK}")
+  endif()
+
+  if(OS_WINDOWS)
+    message(STATUS "Visual Studio ATL support:    ${USE_ATL}")
+  endif()
+
+  message(STATUS "CEF sandbox:                  ${USE_SANDBOX}")
+
+  set(_libraries ${CEF_STANDARD_LIBS})
+  if(OS_WINDOWS AND USE_SANDBOX)
+    list(APPEND _libraries ${CEF_SANDBOX_STANDARD_LIBS})
+  endif()
+  message(STATUS "Standard libraries:           ${_libraries}")
+
+  message(STATUS "Compile defines:              ${CEF_COMPILER_DEFINES}")
+  message(STATUS "Compile defines (Debug):      ${CEF_COMPILER_DEFINES_DEBUG}")
+  message(STATUS "Compile defines (Release):    ${CEF_COMPILER_DEFINES_RELEASE}")
+  message(STATUS "C compile flags:              ${CEF_COMPILER_FLAGS} ${CEF_C_COMPILER_FLAGS}")
+  message(STATUS "C compile flags (Debug):      ${CEF_COMPILER_FLAGS_DEBUG} ${CEF_C_COMPILER_FLAGS_DEBUG}")
+  message(STATUS "C compile flags (Release):    ${CEF_COMPILER_FLAGS_RELEASE} ${CEF_C_COMPILER_FLAGS_RELEASE}")
+  message(STATUS "C++ compile flags:            ${CEF_COMPILER_FLAGS} ${CEF_CXX_COMPILER_FLAGS}")
+  message(STATUS "C++ compile flags (Debug):    ${CEF_COMPILER_FLAGS_DEBUG} ${CEF_CXX_COMPILER_FLAGS_DEBUG}")
+  message(STATUS "C++ compile flags (Release):  ${CEF_COMPILER_FLAGS_RELEASE} ${CEF_CXX_COMPILER_FLAGS_RELEASE}")
+  message(STATUS "Exe link flags:               ${CEF_LINKER_FLAGS} ${CEF_EXE_LINKER_FLAGS}")
+  message(STATUS "Exe link flags (Debug):       ${CEF_LINKER_FLAGS_DEBUG} ${CEF_EXE_LINKER_FLAGS_DEBUG}")
+  message(STATUS "Exe link flags (Release):     ${CEF_LINKER_FLAGS_RELEASE} ${CEF_EXE_LINKER_FLAGS_RELEASE}")
+  message(STATUS "Shared link flags:            ${CEF_LINKER_FLAGS} ${CEF_SHARED_LINKER_FLAGS}")
+  message(STATUS "Shared link flags (Debug):    ${CEF_LINKER_FLAGS_DEBUG} ${CEF_SHARED_LINKER_FLAGS_DEBUG}")
+  message(STATUS "Shared link flags (Release):  ${CEF_LINKER_FLAGS_RELEASE} ${CEF_SHARED_LINKER_FLAGS_RELEASE}")
+
+  if(OS_LINUX OR OS_WINDOWS)
+    message(STATUS "CEF Binary files:             ${CEF_BINARY_FILES}")
+    message(STATUS "CEF Resource files:           ${CEF_RESOURCE_FILES}")
+  endif()
+endmacro()
+
+# Append platform specific sources to a list of sources.
+macro(APPEND_PLATFORM_SOURCES name_of_list)
+  if(OS_LINUX AND ${name_of_list}_LINUX)
+    list(APPEND ${name_of_list} ${${name_of_list}_LINUX})
+  endif()
+  if(OS_POSIX AND ${name_of_list}_POSIX)
+    list(APPEND ${name_of_list} ${${name_of_list}_POSIX})
+  endif()
+  if(OS_WINDOWS AND ${name_of_list}_WINDOWS)
+    list(APPEND ${name_of_list} ${${name_of_list}_WINDOWS})
+  endif()
+  if(OS_MAC AND ${name_of_list}_MAC)
+    list(APPEND ${name_of_list} ${${name_of_list}_MAC})
+  endif()
+endmacro()
+
+# Determine the target output directory based on platform and generator.
+macro(SET_CEF_TARGET_OUT_DIR)
+  if(GEN_NINJA OR GEN_MAKEFILES)
+    # By default Ninja and Make builds don't create a subdirectory named after
+    # the configuration.
+    set(CEF_TARGET_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}")
+
+    # Output binaries (executables, libraries) to the correct directory.
+    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
+    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
+  else()
+    set(CEF_TARGET_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
+  endif()
+endmacro()
+
+# Copy a list of files from one directory to another. Relative file paths are maintained.
+macro(COPY_FILES target file_list source_dir target_dir)
+  foreach(FILENAME ${file_list})
+    set(source_file ${source_dir}/${FILENAME})
+
+    # Remove the target file path component.
+    get_filename_component(target_name ${FILENAME} NAME)
+    set(target_file ${target_dir}/${target_name})
+
+    COPY_SINGLE_FILE(${target} ${source_file} ${target_file})
+  endforeach()
+endmacro()
+
+# Copy a list of files from one directory to another. Relative file paths are maintained.
+macro(COPY_RESOURCES target file_list prefix_list source_dir target_dir)
+  foreach(FILENAME ${file_list})
+    set(source_file ${source_dir}/${FILENAME})
+
+    # Remove one or more prefixes from the source paths.
+    set(TARGET_FILENAME "${FILENAME}")
+    foreach(PREFIX ${prefix_list})
+      string(REGEX REPLACE "^.*${PREFIX}" "" TARGET_FILENAME ${TARGET_FILENAME})
+    endforeach()
+    set(target_file ${target_dir}/${TARGET_FILENAME})
+
+    COPY_SINGLE_FILE(${target} ${source_file} ${target_file})
+  endforeach()
+endmacro()
+
+macro(COPY_SINGLE_FILE target source_file target_file)
+  string(FIND ${source_file} "$<CONFIGURATION>" _pos)
+  if(NOT ${_pos} EQUAL -1)
+    # Must test with an actual configuration directory.
+    string(REPLACE "$<CONFIGURATION>" "Release" existing_source_file ${source_file})
+    if(NOT EXISTS ${existing_source_file})
+      string(REPLACE "$<CONFIGURATION>" "Debug" existing_source_file ${source_file})
+    endif()
+  else()
+    set(existing_source_file ${source_file})
+  endif()
+
+  if(IS_DIRECTORY ${existing_source_file})
+    add_custom_command(
+      TARGET ${target}
+      POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy_directory "${source_file}" "${target_file}"
+      VERBATIM
+      )
+  else()
+    add_custom_command(
+      TARGET ${target}
+      POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source_file}" "${target_file}"
+      VERBATIM
+      )
+  endif()
+endmacro()
+
+
+#
+# Linux macros.
+#
+
+if(OS_LINUX)
+
+# Use pkg-config to find Linux libraries and update compiler/linker variables.
+macro(FIND_LINUX_LIBRARIES libraries)
+  # Read pkg-config info into variables.
+  execute_process(COMMAND pkg-config --cflags ${libraries} OUTPUT_VARIABLE FLL_CFLAGS)
+  execute_process(COMMAND pkg-config --libs-only-L --libs-only-other ${libraries} OUTPUT_VARIABLE FLL_LDFLAGS)
+  execute_process(COMMAND pkg-config --libs-only-l ${libraries} OUTPUT_VARIABLE FLL_LIBS)
+
+  # Strip leading and trailing whitepspace.
+  STRING(STRIP "${FLL_CFLAGS}"  FLL_CFLAGS)
+  STRING(STRIP "${FLL_LDFLAGS}" FLL_LDFLAGS)
+  STRING(STRIP "${FLL_LIBS}"    FLL_LIBS)
+
+  # Convert to a list.
+  separate_arguments(FLL_CFLAGS)
+  separate_arguments(FLL_LDFLAGS)
+  separate_arguments(FLL_LIBS)
+
+  # Update build variables.
+  list(APPEND CEF_C_COMPILER_FLAGS    ${FLL_CFLAGS})
+  list(APPEND CEF_CXX_COMPILER_FLAGS  ${FLL_CFLAGS})
+  list(APPEND CEF_EXE_LINKER_FLAGS    ${FLL_LDFLAGS})
+  list(APPEND CEF_SHARED_LINKER_FLAGS ${FLL_LDFLAGS})
+  list(APPEND CEF_STANDARD_LIBS       ${FLL_LIBS})
+endmacro()
+
+# Set SUID permissions on the specified executable.
+macro(SET_LINUX_SUID_PERMISSIONS target executable)
+  add_custom_command(
+    TARGET ${target}
+    POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E echo ""
+    COMMAND ${CMAKE_COMMAND} -E echo "*** Run the following command manually to set SUID permissions ***"
+    COMMAND ${CMAKE_COMMAND} -E echo "EXE=\"${executable}\" && sudo -- chown root:root $EXE && sudo -- chmod 4755 $EXE"
+    COMMAND ${CMAKE_COMMAND} -E echo ""
+    VERBATIM
+    )
+endmacro()
+
+endif(OS_LINUX)
+
+
+#
+# Mac OS X macros.
+#
+
+if(OS_MAC)
+
+# Manually process and copy over resource files.
+macro(COPY_MAC_RESOURCES resource_list prefix_list target source_dir app_path)
+  foreach(FILENAME ${resource_list})
+    # Remove one or more prefixes from the source paths.
+    set(TARGET_FILENAME "${FILENAME}")
+    foreach(PREFIX ${prefix_list})
+      string(REGEX REPLACE "^.*${PREFIX}" "" TARGET_FILENAME ${TARGET_FILENAME})
+    endforeach()
+
+    # Determine the absolute source and target paths.
+    set(TARGET_PATH "${app_path}/Contents/Resources/${TARGET_FILENAME}")
+    if(IS_ABSOLUTE ${FILENAME})
+      set(SOURCE_PATH ${FILENAME})
+    else()
+      set(SOURCE_PATH "${source_dir}/${FILENAME}")
+    endif()
+
+    if(${FILENAME} MATCHES ".xib$")
+      # Change the target file extension.
+      string(REGEX REPLACE ".xib$" ".nib" TARGET_PATH ${TARGET_PATH})
+
+      get_filename_component(TARGET_DIRECTORY ${TARGET_PATH} PATH)
+      add_custom_command(
+        TARGET ${target}
+        POST_BUILD
+        # Create the target directory.
+        COMMAND ${CMAKE_COMMAND} -E make_directory "${TARGET_DIRECTORY}"
+        # Compile the XIB file to a NIB.
+        COMMAND /usr/bin/ibtool --output-format binary1 --compile "${TARGET_PATH}" "${SOURCE_PATH}"
+        VERBATIM
+        )
+    elseif(NOT ${TARGET_FILENAME} STREQUAL "Info.plist")
+      # Copy the file as-is.
+      add_custom_command(
+        TARGET ${target}
+        POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${TARGET_PATH}"
+        VERBATIM
+        )
+    endif()
+  endforeach()
+endmacro()
+
+endif(OS_MAC)
+
+
+#
+# Windows macros.
+#
+
+if(OS_WINDOWS)
+
+# Add custom manifest files to an executable target.
+macro(ADD_WINDOWS_MANIFEST manifest_path target extension)
+  add_custom_command(
+    TARGET ${target}
+    POST_BUILD
+    COMMAND "mt.exe" -nologo
+            -manifest \"${manifest_path}/${target}.${extension}.manifest\" \"${manifest_path}/compatibility.manifest\"
+            -outputresource:"${CEF_TARGET_OUT_DIR}/${target}.${extension}"\;\#1
+    COMMENT "Adding manifest..."
+    )
+endmacro()
+
+endif(OS_WINDOWS)
+
+
+#
+# Target configuration macros.
+#
+
+# Add a logical target that can be used to link the specified libraries into an
+# executable target.
+macro(ADD_LOGICAL_TARGET target debug_lib release_lib)
+  add_library(${target} ${CEF_LIBTYPE} IMPORTED)
+  set_target_properties(${target} PROPERTIES
+    IMPORTED_LOCATION "${release_lib}"
+    IMPORTED_LOCATION_DEBUG "${debug_lib}"
+    IMPORTED_LOCATION_RELEASE "${release_lib}"
+    )
+endmacro()
+
+# Set common target properties. Use SET_LIBRARY_TARGET_PROPERTIES() or
+# SET_EXECUTABLE_TARGET_PROPERTIES() instead of calling this macro directly.
+macro(SET_COMMON_TARGET_PROPERTIES target)
+  # Compile flags.
+  target_compile_options(${target} PRIVATE ${CEF_COMPILER_FLAGS} ${CEF_CXX_COMPILER_FLAGS})
+  target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:${CEF_COMPILER_FLAGS_DEBUG} ${CEF_CXX_COMPILER_FLAGS_DEBUG}>)
+  target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:${CEF_COMPILER_FLAGS_RELEASE} ${CEF_CXX_COMPILER_FLAGS_RELEASE}>)
+
+  # Compile definitions.
+  target_compile_definitions(${target} PRIVATE ${CEF_COMPILER_DEFINES})
+  target_compile_definitions(${target} PRIVATE $<$<CONFIG:Debug>:${CEF_COMPILER_DEFINES_DEBUG}>)
+  target_compile_definitions(${target} PRIVATE $<$<CONFIG:Release>:${CEF_COMPILER_DEFINES_RELEASE}>)
+
+  # Include directories.
+  target_include_directories(${target} PRIVATE ${CEF_INCLUDE_PATH})
+
+  # Linker flags.
+  if(CEF_LINKER_FLAGS)
+    string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
+  endif()
+  if(CEF_LINKER_FLAGS_DEBUG)
+    string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS_DEBUG}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
+  endif()
+  if(CEF_LINKER_FLAGS_RELEASE)
+    string(REPLACE ";" " " _flags_str "${CEF_LINKER_FLAGS_RELEASE}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
+  endif()
+
+  if(OS_MAC)
+    # Set Xcode target properties.
+    set_target_properties(${target} PROPERTIES
+      XCODE_ATTRIBUTE_ALWAYS_SEARCH_USER_PATHS                    NO
+      XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD                 "gnu++11"   # -std=gnu++11
+      XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME                     NO          # -fno-objc-link-runtime
+      XCODE_ATTRIBUTE_CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS  YES         # -Wobjc-missing-property-synthesis
+      XCODE_ATTRIBUTE_COPY_PHASE_STRIP                            NO
+      XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release]        YES         # -Wl,-dead_strip
+      XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD                     "c99"       # -std=c99
+      XCODE_ATTRIBUTE_GCC_CW_ASM_SYNTAX                           NO          # No -fasm-blocks
+      XCODE_ATTRIBUTE_GCC_DYNAMIC_NO_PIC                          NO
+      XCODE_ATTRIBUTE_GCC_ENABLE_CPP_EXCEPTIONS                   NO          # -fno-exceptions
+      XCODE_ATTRIBUTE_GCC_ENABLE_CPP_RTTI                         NO          # -fno-rtti
+      XCODE_ATTRIBUTE_GCC_ENABLE_PASCAL_STRINGS                   NO          # No -mpascal-strings
+      XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN              YES         # -fvisibility-inlines-hidden
+      XCODE_ATTRIBUTE_GCC_OBJC_CALL_CXX_CDTORS                    YES         # -fobjc-call-cxx-cdtors
+      XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN                  YES         # -fvisibility=hidden
+      XCODE_ATTRIBUTE_GCC_THREADSAFE_STATICS                      NO          # -fno-threadsafe-statics
+      XCODE_ATTRIBUTE_GCC_TREAT_WARNINGS_AS_ERRORS                YES         # -Werror
+      XCODE_ATTRIBUTE_GCC_VERSION                                 "com.apple.compilers.llvm.clang.1_0"
+      XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE              YES         # -Wnewline-eof
+      XCODE_ATTRIBUTE_USE_HEADERMAP                               NO
+      OSX_ARCHITECTURES_DEBUG                                     "${CMAKE_OSX_ARCHITECTURES}"
+      OSX_ARCHITECTURES_RELEASE                                   "${CMAKE_OSX_ARCHITECTURES}"
+      )
+  endif()
+endmacro()
+
+# Set library-specific properties.
+macro(SET_LIBRARY_TARGET_PROPERTIES target)
+  SET_COMMON_TARGET_PROPERTIES(${target})
+
+  # Shared library linker flags.
+  if(CEF_SHARED_LINKER_FLAGS)
+    string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
+  endif()
+  if(CEF_SHARED_LINKER_FLAGS_DEBUG)
+    string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS_DEBUG}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
+  endif()
+  if(CEF_SHARED_LINKER_FLAGS_RELEASE)
+    string(REPLACE ";" " " _flags_str "${CEF_SHARED_LINKER_FLAGS_RELEASE}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
+  endif()
+endmacro()
+
+# Set executable-specific properties.
+macro(SET_EXECUTABLE_TARGET_PROPERTIES target)
+  SET_COMMON_TARGET_PROPERTIES(${target})
+
+  # Executable linker flags.
+  if(CEF_EXE_LINKER_FLAGS)
+    string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS ${_flags_str})
+  endif()
+  if(CEF_EXE_LINKER_FLAGS_DEBUG)
+    string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS_DEBUG}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_DEBUG ${_flags_str})
+  endif()
+  if(CEF_EXE_LINKER_FLAGS_RELEASE)
+    string(REPLACE ";" " " _flags_str "${CEF_EXE_LINKER_FLAGS_RELEASE}")
+    set_property(TARGET ${target} PROPERTY LINK_FLAGS_RELEASE ${_flags_str})
+  endif()
+endmacro()

+ 582 - 0
CMakeModules/cef_variables.cmake

@@ -0,0 +1,582 @@
+# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
+# reserved. Use of this source code is governed by a BSD-style license that
+# can be found in the LICENSE file.
+
+# Must be loaded via FindCEF.cmake.
+if(NOT DEFINED _CEF_ROOT_EXPLICIT)
+  message(FATAL_ERROR "Use find_package(CEF) to load this file.")
+endif()
+
+
+#
+# Shared configuration.
+#
+
+# Determine the platform.
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+  set(OS_MAC 1)
+  set(OS_MACOSX 1)  # For backwards compatibility.
+  set(OS_POSIX 1)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+  set(OS_LINUX 1)
+  set(OS_POSIX 1)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+  set(OS_WINDOWS 1)
+endif()
+
+# Determine the project architecture.
+if(NOT DEFINED PROJECT_ARCH)
+  if(("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64") OR
+     ("${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "ARM64"))
+    set(PROJECT_ARCH "arm64")
+  elseif(CMAKE_SIZEOF_VOID_P MATCHES 8)
+    set(PROJECT_ARCH "x86_64")
+  else()
+    set(PROJECT_ARCH "x86")
+  endif()
+endif()
+
+if(${CMAKE_GENERATOR} STREQUAL "Ninja")
+  set(GEN_NINJA 1)
+elseif(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
+  set(GEN_MAKEFILES 1)
+endif()
+
+# Determine the build type.
+if(NOT CMAKE_BUILD_TYPE AND (GEN_NINJA OR GEN_MAKEFILES))
+  # CMAKE_BUILD_TYPE should be specified when using Ninja or Unix Makefiles.
+  set(CMAKE_BUILD_TYPE Release)
+  message(WARNING "No CMAKE_BUILD_TYPE value selected, using ${CMAKE_BUILD_TYPE}")
+endif()
+
+
+# Path to the include directory.
+set(CEF_INCLUDE_PATH "${_CEF_ROOT}")
+
+# Path to the libcef_dll_wrapper target.
+set(CEF_LIBCEF_DLL_WRAPPER_PATH "${_CEF_ROOT}/libcef_dll")
+
+
+# Shared compiler/linker flags.
+list(APPEND CEF_COMPILER_DEFINES
+  # Allow C++ programs to use stdint.h macros specified in the C99 standard that aren't 
+  # in the C++ standard (e.g. UINT8_MAX, INT64_MIN, etc)
+  __STDC_CONSTANT_MACROS __STDC_FORMAT_MACROS
+  )
+
+
+# Configure use of the sandbox.
+option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
+
+
+#
+# Linux configuration.
+#
+
+if(OS_LINUX)
+  # Platform-specific compiler/linker flags.
+  set(CEF_LIBTYPE SHARED)
+  list(APPEND CEF_COMPILER_FLAGS
+    -fno-strict-aliasing            # Avoid assumptions regarding non-aliasing of objects of different types
+    -fPIC                           # Generate position-independent code for shared libraries
+    -fstack-protector               # Protect some vulnerable functions from stack-smashing (security feature)
+    -funwind-tables                 # Support stack unwinding for backtrace()
+    -fvisibility=hidden             # Give hidden visibility to declarations that are not explicitly marked as visible
+    --param=ssp-buffer-size=4       # Set the minimum buffer size protected by SSP (security feature, related to stack-protector)
+    -pipe                           # Use pipes rather than temporary files for communication between build stages
+    -pthread                        # Use the pthread library
+    # -Wall                           # Enable all warnings
+    # -Werror                         # Treat warnings as errors
+    # -Wno-missing-field-initializers # Don't warn about missing field initializers
+    # -Wno-unused-parameter           # Don't warn about unused parameters
+    # -Wno-error=comment              # Don't warn about code in comments
+    # -Wno-comment                    # Don't warn about code in comments
+    # -Wno-deprecated-declarations    # Don't warn about using deprecated methods
+    )
+  list(APPEND CEF_C_COMPILER_FLAGS
+    -std=c99                        # Use the C99 language standard
+    )
+  list(APPEND CEF_CXX_COMPILER_FLAGS
+    # -fno-exceptions                 # Disable exceptions
+    # -fno-rtti                       # Disable real-time type information
+    -fno-threadsafe-statics         # Don't generate thread-safe statics
+    -fvisibility-inlines-hidden     # Give hidden visibility to inlined class member functions
+    -std=c++17                      # Use the C++17 language standard
+    -Wsign-compare                  # Warn about mixed signed/unsigned type comparisons
+    )
+  list(APPEND CEF_COMPILER_FLAGS_DEBUG
+    -O0                             # Disable optimizations
+    -g                              # Generate debug information
+    )
+  list(APPEND CEF_COMPILER_FLAGS_RELEASE
+    -O2                             # Optimize for maximum speed
+    -fdata-sections                 # Enable linker optimizations to improve locality of reference for data sections
+    -ffunction-sections             # Enable linker optimizations to improve locality of reference for function sections
+    -fno-ident                      # Ignore the #ident directive
+    -U_FORTIFY_SOURCE               # Undefine _FORTIFY_SOURCE in case it was previously defined
+    -D_FORTIFY_SOURCE=2             # Add memory and string function protection (security feature, related to stack-protector)
+    )
+  list(APPEND CEF_LINKER_FLAGS
+    -fPIC                           # Generate position-independent code for shared libraries
+    -pthread                        # Use the pthread library
+    -Wl,--disable-new-dtags         # Don't generate new-style dynamic tags in ELF
+    -Wl,--fatal-warnings            # Treat warnings as errors
+    -Wl,-rpath,.                    # Set rpath so that libraries can be placed next to the executable
+    -Wl,-z,noexecstack              # Mark the stack as non-executable (security feature)
+    -Wl,-z,now                      # Resolve symbols on program start instead of on first use (security feature)
+    -Wl,-z,relro                    # Mark relocation sections as read-only (security feature)
+    )
+  list(APPEND CEF_LINKER_FLAGS_RELEASE
+    -Wl,-O1                         # Enable linker optimizations
+    -Wl,--as-needed                 # Only link libraries that export symbols used by the binary
+    -Wl,--gc-sections               # Remove unused code resulting from -fdata-sections and -function-sections
+    )
+  list(APPEND CEF_COMPILER_DEFINES
+    _FILE_OFFSET_BITS=64            # Allow the Large File Support (LFS) interface to replace the old interface
+    )
+  list(APPEND CEF_COMPILER_DEFINES_RELEASE
+    NDEBUG                          # Not a debug build
+    )
+
+  include(CheckCCompilerFlag)
+  include(CheckCXXCompilerFlag)
+
+  CHECK_CXX_COMPILER_FLAG(-Wno-undefined-var-template COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
+  if(COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
+    list(APPEND CEF_CXX_COMPILER_FLAGS
+      -Wno-undefined-var-template   # Don't warn about potentially uninstantiated static members
+      )
+  endif()
+
+  CHECK_C_COMPILER_FLAG(-Wno-unused-local-typedefs COMPILER_SUPPORTS_NO_UNUSED_LOCAL_TYPEDEFS)
+  if(COMPILER_SUPPORTS_NO_UNUSED_LOCAL_TYPEDEFS)
+    list(APPEND CEF_C_COMPILER_FLAGS
+      -Wno-unused-local-typedefs  # Don't warn about unused local typedefs
+      )
+  endif()
+
+  CHECK_CXX_COMPILER_FLAG(-Wno-literal-suffix COMPILER_SUPPORTS_NO_LITERAL_SUFFIX)
+  if(COMPILER_SUPPORTS_NO_LITERAL_SUFFIX)
+    list(APPEND CEF_CXX_COMPILER_FLAGS
+      -Wno-literal-suffix         # Don't warn about invalid suffixes on literals
+      )
+  endif()
+
+  CHECK_CXX_COMPILER_FLAG(-Wno-narrowing COMPILER_SUPPORTS_NO_NARROWING)
+  if(COMPILER_SUPPORTS_NO_NARROWING)
+    list(APPEND CEF_CXX_COMPILER_FLAGS
+      -Wno-narrowing              # Don't warn about type narrowing
+      )
+  endif()
+
+  if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    list(APPEND CEF_CXX_COMPILER_FLAGS
+      -Wno-attributes             # The cfi-icall attribute is not supported by the GNU C++ compiler
+      )
+  endif()
+
+  if(PROJECT_ARCH STREQUAL "x86_64")
+    # 64-bit architecture.
+    list(APPEND CEF_COMPILER_FLAGS
+      -m64
+      -march=x86-64
+      )
+    list(APPEND CEF_LINKER_FLAGS
+      -m64
+      )
+  elseif(PROJECT_ARCH STREQUAL "x86")
+    # 32-bit architecture.
+    list(APPEND CEF_COMPILER_FLAGS
+      -msse2
+      -mfpmath=sse
+      -mmmx
+      -m32
+      )
+    list(APPEND CEF_LINKER_FLAGS
+      -m32
+      )
+  endif()
+
+  # Standard libraries.
+  set(CEF_STANDARD_LIBS
+    X11
+    )
+
+  # CEF directory paths.
+  set(CEF_RESOURCE_DIR        "${_CEF_ROOT}/Resources")
+  set(CEF_BINARY_DIR          "${_CEF_ROOT}/${CMAKE_BUILD_TYPE}")
+  set(CEF_BINARY_DIR_DEBUG    "${_CEF_ROOT}/Debug")
+  set(CEF_BINARY_DIR_RELEASE  "${_CEF_ROOT}/Release")
+
+  # CEF library paths.
+  set(CEF_LIB_DEBUG   "${CEF_BINARY_DIR_DEBUG}/libcef.so")
+  set(CEF_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/libcef.so")
+
+  # List of CEF binary files.
+  set(CEF_BINARY_FILES
+    chrome-sandbox
+    libcef.so
+    libEGL.so
+    libGLESv2.so
+    libvk_swiftshader.so
+    # libvulkan.so.1
+    snapshot_blob.bin
+    v8_context_snapshot.bin
+    vk_swiftshader_icd.json
+    )
+
+  # List of CEF resource files.
+  set(CEF_RESOURCE_FILES
+    chrome_100_percent.pak
+    chrome_200_percent.pak
+    resources.pak
+    icudtl.dat
+    locales
+    )
+
+  if(USE_SANDBOX)
+    list(APPEND CEF_COMPILER_DEFINES
+      CEF_USE_SANDBOX   # Used by apps to test if the sandbox is enabled
+      )
+  endif()
+endif()
+
+
+#
+# Mac OS X configuration.
+#
+
+if(OS_MAC)
+  # Platform-specific compiler/linker flags.
+  # See also Xcode target properties in cef_macros.cmake.
+  set(CEF_LIBTYPE SHARED)
+  list(APPEND CEF_COMPILER_FLAGS
+    -fno-strict-aliasing            # Avoid assumptions regarding non-aliasing of objects of different types
+    -fstack-protector               # Protect some vulnerable functions from stack-smashing (security feature)
+    -funwind-tables                 # Support stack unwinding for backtrace()
+    -fvisibility=hidden             # Give hidden visibility to declarations that are not explicitly marked as visible
+    -Wall                           # Enable all warnings
+    -Werror                         # Treat warnings as errors
+    -Wextra                         # Enable additional warnings
+    -Wendif-labels                  # Warn whenever an #else or an #endif is followed by text
+    -Wnewline-eof                   # Warn about no newline at end of file
+    -Wno-missing-field-initializers # Don't warn about missing field initializers
+    -Wno-unused-parameter           # Don't warn about unused parameters
+    )
+  list(APPEND CEF_C_COMPILER_FLAGS
+    -std=c99                        # Use the C99 language standard
+    )
+  list(APPEND CEF_CXX_COMPILER_FLAGS
+    # -fno-exceptions                 # Disable exceptions
+    # -fno-rtti                       # Disable real-time type information
+    -fno-threadsafe-statics         # Don't generate thread-safe statics
+    -fobjc-call-cxx-cdtors          # Call the constructor/destructor of C++ instance variables in ObjC objects
+    -fvisibility-inlines-hidden     # Give hidden visibility to inlined class member functions
+    -std=c++17                      # Use the C++17 language standard
+    -Wno-narrowing                  # Don't warn about type narrowing
+    -Wsign-compare                  # Warn about mixed signed/unsigned type comparisons
+    )
+  list(APPEND CEF_COMPILER_FLAGS_DEBUG
+    -O0                             # Disable optimizations
+    -g                              # Generate debug information
+    )
+  list(APPEND CEF_COMPILER_FLAGS_RELEASE
+    -O3                             # Optimize for maximum speed plus a few extras
+    )
+  list(APPEND CEF_LINKER_FLAGS
+    -Wl,-search_paths_first         # Search for static or shared library versions in the same pass
+    -Wl,-ObjC                       # Support creation of ObjC static libraries
+    -Wl,-pie                        # Generate position-independent code suitable for executables only
+    )
+  list(APPEND CEF_LINKER_FLAGS_RELEASE
+    -Wl,-dead_strip                 # Strip dead code
+    )
+
+  include(CheckCXXCompilerFlag)
+
+  CHECK_CXX_COMPILER_FLAG(-Wno-undefined-var-template COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
+  if(COMPILER_SUPPORTS_NO_UNDEFINED_VAR_TEMPLATE)
+    list(APPEND CEF_CXX_COMPILER_FLAGS
+      -Wno-undefined-var-template   # Don't warn about potentially uninstantiated static members
+      )
+  endif()
+
+  # Standard libraries.
+  set(CEF_STANDARD_LIBS
+    -lpthread
+    "-framework Cocoa"
+    "-framework AppKit"
+    )
+
+  # Find the newest available base SDK.
+  execute_process(COMMAND xcode-select --print-path OUTPUT_VARIABLE XCODE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
+  foreach(OS_VERSION 10.15 10.14 10.13)
+    set(SDK "${XCODE_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OS_VERSION}.sdk")
+    if(NOT "${CMAKE_OSX_SYSROOT}" AND EXISTS "${SDK}" AND IS_DIRECTORY "${SDK}")
+      set(CMAKE_OSX_SYSROOT ${SDK})
+    endif()
+  endforeach()
+
+  # Target SDK.
+  set(CEF_TARGET_SDK               "10.13")
+  list(APPEND CEF_COMPILER_FLAGS
+    -mmacosx-version-min=${CEF_TARGET_SDK}
+  )
+  set(CMAKE_OSX_DEPLOYMENT_TARGET  ${CEF_TARGET_SDK})
+
+  # Target architecture.
+  if(PROJECT_ARCH STREQUAL "x86_64")
+    set(CMAKE_OSX_ARCHITECTURES "x86_64")
+  elseif(PROJECT_ARCH STREQUAL "arm64")
+    set(CMAKE_OSX_ARCHITECTURES "arm64")
+  else()
+    set(CMAKE_OSX_ARCHITECTURES "i386")
+  endif()
+
+  # Prevent Xcode 11 from doing automatic codesigning.
+  set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "")
+
+  # CEF directory paths.
+  set(CEF_BINARY_DIR          "${_CEF_ROOT}/$<CONFIGURATION>")
+  set(CEF_BINARY_DIR_DEBUG    "${_CEF_ROOT}/Debug")
+  set(CEF_BINARY_DIR_RELEASE  "${_CEF_ROOT}/Release")
+
+  if(USE_SANDBOX)
+    list(APPEND CEF_COMPILER_DEFINES
+      CEF_USE_SANDBOX   # Used by apps to test if the sandbox is enabled
+      )
+
+    list(APPEND CEF_STANDARD_LIBS
+      -lsandbox
+      )
+
+    # CEF sandbox library paths.
+    set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.a")
+    set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.a")
+  endif()
+
+  # CEF Helper app suffixes.
+  # Format is "<name suffix>:<target suffix>:<plist suffix>".
+  set(CEF_HELPER_APP_SUFFIXES
+    "::"
+    " (Alerts):_alerts:.alerts"
+    " (GPU):_gpu:.gpu"
+    " (Plugin):_plugin:.plugin"
+    " (Renderer):_renderer:.renderer"
+    )
+endif()
+
+
+#
+# Windows configuration.
+#
+
+if(OS_WINDOWS)
+  if (GEN_NINJA)
+    # When using the Ninja generator clear the CMake defaults to avoid excessive
+    # console warnings (see issue #2120).
+    set(CMAKE_CXX_FLAGS "")
+    set(CMAKE_CXX_FLAGS_DEBUG "")
+    set(CMAKE_CXX_FLAGS_RELEASE "")
+  endif()
+
+  if(USE_SANDBOX)
+    # Check if the current MSVC version is compatible with the cef_sandbox.lib
+    # static library. We require VS2015 or newer.
+    if(MSVC_VERSION LESS 1900)
+      message(WARNING "CEF sandbox is not compatible with the current MSVC version (${MSVC_VERSION})")
+      set(USE_SANDBOX OFF)
+    endif()
+  endif()
+
+  # Consumers who run into LNK4099 warnings can pass /Z7 instead (see issue #385).
+  set(CEF_DEBUG_INFO_FLAG "/Zi" CACHE STRING "Optional flag specifying specific /Z flag to use")
+
+  # Consumers using different runtime types may want to pass different flags
+  set(CEF_RUNTIME_LIBRARY_FLAG "/MT" CACHE STRING "Optional flag specifying which runtime to use")
+  if (CEF_RUNTIME_LIBRARY_FLAG)
+    list(APPEND CEF_COMPILER_FLAGS_DEBUG ${CEF_RUNTIME_LIBRARY_FLAG}d)
+    list(APPEND CEF_COMPILER_FLAGS_RELEASE ${CEF_RUNTIME_LIBRARY_FLAG})
+  endif()
+
+  # Platform-specific compiler/linker flags.
+  set(CEF_LIBTYPE STATIC)
+  list(APPEND CEF_COMPILER_FLAGS
+    /MP           # Multiprocess compilation
+    /Gy           # Enable function-level linking
+    /GR-          # Disable run-time type information
+    /W4           # Warning level 4
+    /WX           # Treat warnings as errors
+    /wd4100       # Ignore "unreferenced formal parameter" warning
+    /wd4127       # Ignore "conditional expression is constant" warning
+    /wd4244       # Ignore "conversion possible loss of data" warning
+    /wd4324       # Ignore "structure was padded due to alignment specifier" warning
+    /wd4481       # Ignore "nonstandard extension used: override" warning
+    /wd4512       # Ignore "assignment operator could not be generated" warning
+    /wd4701       # Ignore "potentially uninitialized local variable" warning
+    /wd4702       # Ignore "unreachable code" warning
+    /wd4996       # Ignore "function or variable may be unsafe" warning
+    ${CEF_DEBUG_INFO_FLAG}
+    )
+  list(APPEND CEF_COMPILER_FLAGS_DEBUG
+    /RTC1         # Disable optimizations
+    /Od           # Enable basic run-time checks
+    )
+  list(APPEND CEF_COMPILER_FLAGS_RELEASE
+    /O2           # Optimize for maximum speed
+    /Ob2          # Inline any suitable function
+    /GF           # Enable string pooling
+    )
+  list(APPEND CEF_CXX_COMPILER_FLAGS
+    /std:c++17    # Use the C++17 language standard
+    )
+  list(APPEND CEF_LINKER_FLAGS_DEBUG
+    /DEBUG        # Generate debug information
+    )
+  list(APPEND CEF_EXE_LINKER_FLAGS
+    /MANIFEST:NO        # No default manifest (see ADD_WINDOWS_MANIFEST macro usage)
+    /LARGEADDRESSAWARE  # Allow 32-bit processes to access 3GB of RAM
+    )
+  list(APPEND CEF_COMPILER_DEFINES
+    WIN32 _WIN32 _WINDOWS             # Windows platform
+    UNICODE _UNICODE                  # Unicode build
+    # Targeting Windows 10. We can't say `=_WIN32_WINNT_WIN10` here because
+    # some files do `#if WINVER < 0x0600` without including windows.h before,
+    # and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00.
+    WINVER=0x0A00
+    _WIN32_WINNT=0x0A00
+    NTDDI_VERSION=NTDDI_WIN10_FE
+    NOMINMAX                          # Use the standard's templated min/max
+    WIN32_LEAN_AND_MEAN               # Exclude less common API declarations
+    _HAS_EXCEPTIONS=0                 # Disable exceptions
+    )
+  list(APPEND CEF_COMPILER_DEFINES_RELEASE
+    NDEBUG _NDEBUG                    # Not a debug build
+    )
+
+  if(PROJECT_ARCH STREQUAL "x86")
+    # Set the initial stack size to 0.5MiB, instead of the 1.5MiB minimum
+    # needed by CEF's main thread. This saves significant memory on threads
+    # (like those in the Windows thread pool, and others) whose stack size we
+    # can only control through this setting. The main thread (in 32-bit builds
+    # only) uses fibers to switch to a 4MiB stack at runtime via
+    # CefRunWinMainWithPreferredStackSize().
+    list(APPEND CEF_EXE_LINKER_FLAGS
+      /STACK:0x80000
+      )
+  else()
+    # Increase the initial stack size to 8MiB from the default 1MiB.
+    list(APPEND CEF_EXE_LINKER_FLAGS
+      /STACK:0x800000
+      )
+  endif()
+
+  # Standard libraries.
+  set(CEF_STANDARD_LIBS
+    comctl32.lib
+    gdi32.lib
+    rpcrt4.lib
+    shlwapi.lib
+    ws2_32.lib
+    )
+
+  # CEF directory paths.
+  set(CEF_RESOURCE_DIR        "${_CEF_ROOT}/Resources")
+  set(CEF_BINARY_DIR          "${_CEF_ROOT}/$<CONFIGURATION>")
+  set(CEF_BINARY_DIR_DEBUG    "${_CEF_ROOT}/Debug")
+  set(CEF_BINARY_DIR_RELEASE  "${_CEF_ROOT}/Release")
+
+  # CEF library paths.
+  set(CEF_LIB_DEBUG   "${CEF_BINARY_DIR_DEBUG}/libcef.lib")
+  set(CEF_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/libcef.lib")
+
+  # List of CEF binary files.
+  set(CEF_BINARY_FILES
+    chrome_elf.dll
+    d3dcompiler_47.dll
+    libcef.dll
+    libEGL.dll
+    libGLESv2.dll
+    snapshot_blob.bin
+    v8_context_snapshot.bin
+    vk_swiftshader.dll
+    vk_swiftshader_icd.json
+    vulkan-1.dll
+    )
+
+  # List of CEF resource files.
+  set(CEF_RESOURCE_FILES
+    chrome_100_percent.pak
+    chrome_200_percent.pak
+    resources.pak
+    icudtl.dat
+    locales
+    )
+
+  if(USE_SANDBOX)
+    list(APPEND CEF_COMPILER_DEFINES
+      PSAPI_VERSION=1   # Required by cef_sandbox.lib
+      CEF_USE_SANDBOX   # Used by apps to test if the sandbox is enabled
+      )
+    list(APPEND CEF_COMPILER_DEFINES_DEBUG
+      _HAS_ITERATOR_DEBUGGING=0   # Disable iterator debugging
+      )
+
+    # Libraries required by cef_sandbox.lib.
+    set(CEF_SANDBOX_STANDARD_LIBS
+      Advapi32.lib
+      dbghelp.lib
+      Delayimp.lib
+      ntdll.lib
+      OleAut32.lib
+      PowrProf.lib
+      Propsys.lib
+      psapi.lib
+      SetupAPI.lib
+      Shell32.lib
+      Shcore.lib
+      Userenv.lib
+      version.lib
+      wbemuuid.lib
+      WindowsApp.lib
+      winmm.lib
+      )
+
+    # CEF sandbox library paths.
+    set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.lib")
+    set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.lib")
+  endif()
+
+  # Configure use of ATL.
+  option(USE_ATL "Enable or disable use of ATL." ON)
+  if(USE_ATL)
+    # Locate the atlmfc directory if it exists. It may be at any depth inside
+    # the VC directory. The cl.exe path returned by CMAKE_CXX_COMPILER may also
+    # be at different depths depending on the toolchain version
+    # (e.g. "VC/bin/cl.exe", "VC/bin/amd64_x86/cl.exe",
+    # "VC/Tools/MSVC/14.10.25017/bin/HostX86/x86/cl.exe", etc).
+    set(HAS_ATLMFC 0)
+    get_filename_component(VC_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
+    get_filename_component(VC_DIR_NAME ${VC_DIR} NAME)
+    while(NOT ${VC_DIR_NAME} STREQUAL "VC")
+      get_filename_component(VC_DIR ${VC_DIR} DIRECTORY)
+      if(IS_DIRECTORY "${VC_DIR}/atlmfc")
+        set(HAS_ATLMFC 1)
+        break()
+      endif()
+      get_filename_component(VC_DIR_NAME ${VC_DIR} NAME)
+    endwhile()
+
+    # Determine if the Visual Studio install supports ATL.
+    if(NOT HAS_ATLMFC)
+      message(WARNING "ATL is not supported by your VC installation.")
+      set(USE_ATL OFF)
+    endif()
+  endif()
+
+  if(USE_ATL)
+    list(APPEND CEF_COMPILER_DEFINES
+      CEF_USE_ATL   # Used by apps to test if ATL support is enabled
+      )
+  endif()
+endif()

+ 69 - 4
main.cpp

@@ -3,6 +3,7 @@
 
 #include "WallpaperEngine/Application/CApplicationContext.h"
 #include "WallpaperEngine/Application/CWallpaperApplication.h"
+#include "WallpaperEngine/Core/CWeb.h"
 #include "common.h"
 
 WallpaperEngine::Application::CWallpaperApplication* appPointer;
@@ -21,11 +22,67 @@ void initLogging ()
     sLog.addError (new std::ostream (std::cerr.rdbuf ()));
 }
 
-int main (int argc, char* argv[])
+static void CEFsetUp(int argc, char** argv)
 {
-    initLogging ();
+    // This function should be called from the application entry point function to
+    // execute a secondary process. It can be used to run secondary processes from
+    // the browser client executable (default behavior) or from a separate
+    // executable specified by the CefSettings.browser_subprocess_path value. If
+    // called for the browser process (identified by no "type" command-line value)
+    // it will return immediately with a value of -1. If called for a recognized
+    // secondary process it will block until the process should exit and then return
+    // the process exit code. The |application| parameter may be empty. The
+    // |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
+    // cef_sandbox_win.h for details).
+    
+    CefMainArgs args(argc, argv);
+    
+    int exit_code = CefExecuteProcess(args, nullptr, nullptr);//Spawned processes will terminate here(see CefIninitilize below). Maybe implementing settings.browser_subprocess_path will allow it to work not in main function.
+    if (exit_code >= 0)
+    {
+        // Sub proccess has endend, so exit
+        exit(exit_code);
+    }
+    else if (exit_code == -1)
+    {
+        // If called for the browser process (identified by no "type" command-line value)
+        // it will return immediately with a value of -1
+    }
+
+    // Configurate Chromium
+    CefSettings settings;
+    //CefString(&settings.locales_dir_path) = "OffScreenCEF/godot/locales";
+    //CefString(&settings.resources_dir_path) = "OffScreenCEF/godot/";
+    //CefString(&settings.framework_dir_path) = "OffScreenCEF/godot/";
+    //CefString(&settings.cache_path) = "OffScreenCEF/godot/";
+    // CefString(&settings.browser_subprocess_path) = "path/to/client"
+    settings.windowless_rendering_enabled = true;
+#if defined(CEF_NO_SANDBOX)
+    settings.no_sandbox = true;
+#endif
+
+    bool result = CefInitialize(args, settings, nullptr, nullptr); //Spawn 2 new processes; Can be moved to Core::CWeb
+    if (!result)
+    {
+        std::cerr << "CefInitialize: failed" << std::endl;
+        exit(-2);
+    }
+}
 
-    WallpaperEngine::Application::CApplicationContext appContext (argc, argv);
+bool g_CEFused=false;//Will be set to true if wallpaper has "web" type 
+int main (int argc, char* argv[]) {
+    //START of CEF init block(it will run 3 times)
+    char** argv2 = new char*[argc]; //Cef modify argv on CefInit, copy it before that
+
+    for(int i=0; i<argc; ++i)
+    {
+        argv2[i] = new char[strlen(argv[i])+1];
+        strcpy(argv2[i],argv[i]);
+    }
+    CEFsetUp(argc,argv);//Cef will launch new process with main(argc,argv) twice. If we won't pass argc and argv from main, we will create fork bomb and system will freeze until reboot. 
+    //END of CEF init block 
+    initLogging ();
+    WallpaperEngine::Application::CApplicationContext appContext (argc, argv2);
     WallpaperEngine::Application::CWallpaperApplication app (appContext);
 
     // halt if the list-properties option was specified
@@ -38,10 +95,18 @@ int main (int argc, char* argv[])
     std::signal (SIGINT, signalhandler);
     std::signal (SIGTERM, signalhandler);
 
+    if(!g_CEFused){
+        sLog.debug("No web wallpapers, shutting down CEF");
+        CefShutdown();
+    }
     // show the wallpaper application
     app.show ();
 
-    appPointer = nullptr;
+    if(g_CEFused){
+        sLog.debug("Shutting down CEF");
+        CefShutdown();
+    }
 
+    appPointer = nullptr;
     return 0;
 }

+ 37 - 32
src/WallpaperEngine/Core/CProject.cpp

@@ -5,6 +5,7 @@
 #include "CProject.h"
 #include "CScene.h"
 #include "CVideo.h"
+#include "CWeb.h"
 
 using namespace WallpaperEngine::Core;
 using namespace WallpaperEngine::Assets;
@@ -18,41 +19,45 @@ CProject::CProject (std::string title, std::string type, CContainer* container)
 CProject* CProject::fromFile (const std::string& filename, CContainer* container) {
     json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
 
-    const std::string title = *jsonFindRequired (content, "title", "Project title missing");
-    std::string type = *jsonFindRequired (content, "type", "Project type missing");
-    const std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
-    const auto general = content.find ("general");
-    CWallpaper* wallpaper;
-
-    std::transform (type.begin (), type.end (), type.begin (), tolower);
-
-    CProject* project = new CProject (title, type, container);
-
-    if (type == "scene")
-        wallpaper = CScene::fromFile (file, *project, container);
-    else if (type == "video")
-        wallpaper = new CVideo (file, *project);
-    else if (type == "web")
-        sLog.exception ("Web wallpapers are not supported yet");
-    else
-        sLog.exception ("Unsupported wallpaper type: ", type);
-
-    project->setWallpaper (wallpaper);
-
-    if (general != content.end ()) {
-        const auto properties = general->find ("properties");
-
-        if (properties != general->end ()) {
-            for (const auto& cur : properties->items ()) {
-                Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
-
-                if (property != nullptr)
-                    project->insertProperty (property);
+    std::string dependency = jsonFindDefault<std::string> (content, "dependency", "No dependency");
+    if(dependency=="No dependency"){
+        std::string title = *jsonFindRequired (content, "title", "Project title missing");
+        std::string type = *jsonFindRequired (content, "type", "Project type missing");
+        std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
+        auto general = content.find ("general");
+        CWallpaper* wallpaper;
+
+        std::transform (type.begin (), type.end (), type.begin (), tolower);
+
+        CProject* project = new CProject (title, type, container);
+
+        if (type == "scene")
+            wallpaper = CScene::fromFile (file, *project, container);
+        else if (type == "video")
+            wallpaper = new CVideo (file.c_str (), *project);
+        else if (type == "web")
+            wallpaper = new CWeb (file.c_str (), *project);
+        else
+            sLog.exception ("Unsupported wallpaper type: ", type);
+
+        project->setWallpaper (wallpaper);
+
+        if (general != content.end ()) {
+            const auto properties = general->find ("properties");
+
+            if (properties != general-> end ()) {
+                for (const auto& cur : properties->items ()) {
+                    Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
+                    if (property != nullptr)
+                        project->insertProperty (property);
+                }
             }
         }
+        return project;
+    }
+    else{
+        sLog.exception("Project have dependency. They are not supported, quiting");
     }
-
-    return project;
 }
 
 void CProject::setWallpaper (CWallpaper* wallpaper) {

+ 71 - 0
src/WallpaperEngine/Core/CWeb.cpp

@@ -0,0 +1,71 @@
+#include "CWeb.h"
+
+#include <utility>
+#include "common.h"
+
+static void CEFsetUp(int argc, char** argv)
+{
+    // This function should be called from the application entry point function to
+    // execute a secondary process. It can be used to run secondary processes from
+    // the browser client executable (default behavior) or from a separate
+    // executable specified by the CefSettings.browser_subprocess_path value. If
+    // called for the browser process (identified by no "type" command-line value)
+    // it will return immediately with a value of -1. If called for a recognized
+    // secondary process it will block until the process should exit and then return
+    // the process exit code. The |application| parameter may be empty. The
+    // |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
+    // cef_sandbox_win.h for details).
+    CefMainArgs args(argc,argv);
+    int exit_code = CefExecuteProcess(args, nullptr, nullptr);
+    if (exit_code >= 0)
+    {
+        sLog.debug("CEF sub proccess has endend");
+        // Sub proccess has endend, so exit
+        exit(exit_code);
+    }
+    else if (exit_code == -1)
+    {
+        // If called for the browser process (identified by no "type" command-line value)
+        // it will return immediately with a value of -1
+    }
+
+    // Configurate Chromium
+    CefSettings settings;
+    //CefString(&settings.locales_dir_path) = "OffScreenCEF/godot/locales";
+    //CefString(&settings.resources_dir_path) = "OffScreenCEF/godot/";
+    //CefString(&settings.framework_dir_path) = "OffScreenCEF/godot/";
+    //CefString(&settings.cache_path) = "OffScreenCEF/godot/";
+    settings.windowless_rendering_enabled = true;
+#if defined(CEF_NO_SANDBOX)
+    settings.no_sandbox = true;
+#endif
+
+    bool result = CefInitialize(args, settings, nullptr, nullptr);
+    if (!result)
+    {
+        sLog.error("CefInitialize: failed");
+        exit(-2);
+    }
+}
+
+using namespace WallpaperEngine::Core;
+
+const std::string& CWeb::getFilename ()
+{
+    return this->m_filename;
+}
+
+CWeb::CWeb (std::string filename, CProject& project) :
+    CWallpaper (Type, project),
+    m_filename (std::move(filename))
+{   
+    if(!g_CEFused) {
+        sLog.debug("Setting up CEF");
+        // char** argv = new char*("linux-wallpaper\n");
+        // CEFsetUp(1, argv);
+        // delete argv;
+        g_CEFused=true;
+    }
+}
+
+const std::string CWeb::Type = "web";

+ 37 - 0
src/WallpaperEngine/Core/CWeb.h

@@ -0,0 +1,37 @@
+#pragma once
+
+#include "Core.h"
+#include "CWallpaper.h"
+
+// Chromium Embedded Framework
+#include "include/cef_render_handler.h"
+#include "include/cef_client.h"
+#include "include/cef_app.h"
+
+extern "C"
+{
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavutil/imgutils.h>
+#include <libswscale/swscale.h>
+}
+
+namespace WallpaperEngine::Core
+{
+    class CWeb : public CWallpaper
+    {
+    public:
+        explicit CWeb (std::string filename, CProject& project);
+
+        const std::string& getFilename ();
+        
+    protected:
+        friend class CWallpaper;
+
+        const std::string m_filename;
+
+        static const std::string Type;
+
+    private:
+    };
+}

+ 7 - 3
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -2,6 +2,7 @@
 #include "CScene.h"
 #include "CVideo.h"
 #include "common.h"
+#include "CWeb.h"
 
 #include <glm/glm.hpp>
 #include <glm/gtc/type_ptr.hpp>
@@ -24,7 +25,8 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend
     a_TexCoord (GL_NONE),
     m_vaoBuffer (GL_NONE),
     m_audioContext (audioContext),
-    m_state (scalingMode) {
+    m_state (scalingMode)
+{
     // generate the VAO to stop opengl from complaining
     glGenVertexArrays (1, &this->m_vaoBuffer);
     glBindVertexArray (this->m_vaoBuffer);
@@ -285,6 +287,8 @@ CWallpaper* CWallpaper::fromWallpaper (Core::CWallpaper* wallpaper, CRenderConte
         return new WallpaperEngine::Render::CScene (wallpaper->as<Core::CScene> (), context, audioContext, scalingMode);
     if (wallpaper->is<Core::CVideo> ())
         return new WallpaperEngine::Render::CVideo (wallpaper->as<Core::CVideo> (), context, audioContext, scalingMode);
-
-    sLog.exception ("Unsupported wallpaper type");
+    else if (wallpaper->is <Core::CWeb> ())
+        return new WallpaperEngine::Render::CWeb (wallpaper->as <Core::CWeb> (), context, audioContext, scalingMode);
+    else
+        sLog.exception ("Unsupported wallpaper type");
 }

+ 115 - 0
src/WallpaperEngine/Render/CWeb.cpp

@@ -0,0 +1,115 @@
+// This code is a modification of the original projects that can be found at
+// https://github.com/if1live/cef-gl-example
+// https://github.com/andmcgregor/cefgui
+#include "CWeb.h"
+
+using namespace WallpaperEngine::Render;
+
+CWeb::CWeb (Core::CWeb* web, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode) :
+    CWallpaper (web, Type, context, audioContext, scalingMode),
+    m_width (context.getOutput ().getFullWidth ()),
+    m_height (context.getOutput ().getFullHeight ()),
+    m_browser(),
+    m_client()
+{
+    // setup framebuffers
+    this->setupFramebuffers();
+
+    CefWindowInfo window_info;
+    window_info.SetAsWindowless(0);
+
+    this->m_render_handler = new RenderHandler(this);
+
+    CefBrowserSettings browserSettings;
+    //Documentaion says that 60 fps is maximum value
+    browserSettings.windowless_frame_rate = std::max(60,context.getApp().getContext().settings.render.maximumFPS);
+
+    m_client = new BrowserClient(m_render_handler);
+    std::filesystem::path htmlpath = this->getWeb ()->getProject ().getContainer ()->resolveRealFile (this->getWeb ()->getFilename ());
+    //To open local file in browser URL must be "file:///path/to/file.html"
+    const std::string htmlURL = std::string("file:///") + htmlpath.c_str();
+    m_browser = CefBrowserHost::CreateBrowserSync(window_info, m_client.get(),
+                                                  htmlURL, browserSettings,
+                                                  nullptr, nullptr);
+}
+
+void CWeb::setSize (int64_t width, int64_t height)
+{
+    this->m_width = width > 0 ? width : this->m_width;
+    this->m_height = height > 0 ? height : this->m_height;
+
+    // do not refresh the texture if any of the sizes are invalid
+    if (this->m_width <= 0 || this->m_height <= 0)
+        return;
+
+    // reconfigure the texture
+    glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture());
+    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, this->getWidth(), this->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+
+    // Notify cef that it was resized(maybe it's not even needed)
+    m_browser->GetHost()->WasResized();
+}
+
+void CWeb::renderFrame (glm::ivec4 viewport)
+{
+    // ensure the virtual mouse position is up to date
+    this->updateMouse (viewport);
+    // use the scene's framebuffer by default
+    glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
+    // ensure we render over the whole framebuffer
+    glViewport (0, 0, this->getWidth (), this->getHeight ());
+
+    //Cef processes all messages, including OnPaint, which renders frame
+    //If there is no OnPaint in message loop, we will not update(render) frame
+    // This means some frames will not have OnPaint call in cef messageLoop
+    // Because of that glClear will result in flickering on higher fps
+    // Do not use glClear until some method to control rendering with cef is supported
+    //We might actually try to use cef to execute javascript, and not using off-screen rendering at all
+    //But for now let it be like this
+    // glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    CefDoMessageLoopWork();
+}
+void CWeb::updateMouse (glm::ivec4 viewport)
+{
+    // update virtual mouse position first
+    glm::dvec2 position = this->getContext ().getInputContext ().getMouseInput ().position();
+
+    CefMouseEvent evt;
+    // Set mouse current position. Maybe clamps are not needed
+    evt.x = std::clamp(int(position.x - viewport.x),0,viewport.z);
+    evt.y = std::clamp(int(position.y - viewport.y),0,viewport.w);
+    // Send mouse position to cef
+    m_browser->GetHost()->SendMouseMoveEvent(evt, false);
+}
+
+CWeb::~CWeb(){
+    CefDoMessageLoopWork();
+    m_browser->GetHost()->CloseBrowser(true);
+}
+
+
+CWeb::RenderHandler::RenderHandler(CWeb* webdata):
+    m_webdata(webdata)
+{
+}
+CWeb::RenderHandler::~RenderHandler(){
+}
+//Required by CEF
+void CWeb::RenderHandler::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
+{
+    rect = CefRect(0, 0, this->m_webdata->getWidth(), this->m_webdata->getHeight());
+}
+//Will be executed in CEF message loop
+void CWeb::RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
+                                         const RectList &dirtyRects, const void *buffer,
+                                         int width, int height)
+{
+    //sLog.debug("BrowserView::RenderHandler::OnPaint");
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, this->texture());
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT,
+                         GL_UNSIGNED_BYTE, (unsigned char*)buffer);
+    glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+const std::string CWeb::Type = "web";

+ 117 - 0
src/WallpaperEngine/Render/CWeb.h

@@ -0,0 +1,117 @@
+#pragma once
+
+// Matrices manipulation for OpenGL
+#include <glm/glm.hpp>
+#include <glm/ext.hpp>
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <algorithm>
+
+#include "common.h"
+#include "WallpaperEngine/Core/CWeb.h"
+#include "WallpaperEngine/Render/CWallpaper.h"
+#include "WallpaperEngine/Audio/CAudioStream.h"
+
+namespace WallpaperEngine::Render
+{
+    class CWeb : public CWallpaper
+    {
+        public:
+            CWeb (Core::CWeb* scene, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode);
+            ~CWeb();
+            uint32_t getWidth  () const override { return this->m_width; }
+
+            uint32_t getHeight () const override { return this->m_height; }
+
+            void setSize (int64_t width, int64_t height);
+
+        protected:
+            void renderFrame (glm::ivec4 viewport) override;
+            void updateMouse (glm::ivec4 viewport);
+            Core::CWeb* getWeb ()
+            {
+                return this->getWallpaperData ()->as<Core::CWeb> ();
+            }
+
+            friend class CWallpaper;
+
+            static const std::string Type;
+
+        private:
+            // *************************************************************************
+            //! \brief Private implementation to handle CEF events to draw the web page.
+            // *************************************************************************
+            class RenderHandler: public CefRenderHandler
+            {
+                public:
+                    RenderHandler(CWeb* webdata);
+
+                    //! \brief
+                    ~RenderHandler();
+
+                    //! \brief Compile OpenGL shaders and create OpenGL objects (VAO,
+                    //! VBO, texture, locations ...)
+                    bool init();
+
+                    //! \brief CefRenderHandler interface
+                    void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect) override;
+
+                    //! \brief CefRenderHandler interface
+                    //! Update the OpenGL texture.
+                    void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
+                                        const RectList &dirtyRects, const void *buffer,
+                                        int width, int height) override;
+
+                    //! \brief CefBase interface
+                    IMPLEMENT_REFCOUNTING(RenderHandler);
+
+                private:
+                    CWeb* m_webdata;
+
+                    uint32_t getWidth () const {
+                        return this->m_webdata->getWidth();
+                    };
+                    uint32_t getHeight () const {
+                        return this->m_webdata->getHeight();
+                    };
+                    //! \brief Return the OpenGL texture handle
+                    GLuint texture() const
+                    {
+                        return this->m_webdata->getWallpaperFramebuffer();
+                    }
+            };
+
+            // *************************************************************************
+            //! \brief Provide access to browser-instance-specific callbacks. A single
+            //! CefClient instance can be shared among any number of browsers.
+            // *************************************************************************
+            class BrowserClient: public CefClient
+            {
+                public:
+                    BrowserClient(CefRefPtr<CefRenderHandler> ptr)
+                        : m_renderHandler(ptr)
+                    {}
+
+                    CefRefPtr<CefRenderHandler> GetRenderHandler() override
+                    {
+                        return m_renderHandler;
+                    }
+
+                    CefRefPtr<CefRenderHandler> m_renderHandler;
+
+                    IMPLEMENT_REFCOUNTING(BrowserClient);
+            };
+            
+            CefRefPtr<CefBrowser> m_browser;
+            CefRefPtr<BrowserClient> m_client;
+            RenderHandler* m_render_handler = nullptr;
+
+            int64_t m_width;
+            int64_t m_height;
+
+            glm::vec2 m_mousePosition;
+            glm::vec2 m_mousePositionLast;
+    };
+}

+ 5 - 0
src/common.h

@@ -1,3 +1,8 @@
 #pragma once
 
 #include "WallpaperEngine/Logging/CLog.h"
+#include "WallpaperEngine/Core/CWeb.h"
+
+//global variables are bad
+extern bool g_CEFused;
+extern CefMainArgs g_args;