├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── build-linux-x86_64.yml │ ├── build-macos-x86_64.yml │ └── build-windows-x86_64.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── LICENSE ├── cmake └── SetupCef.cmake ├── dep └── readme.md ├── docs └── images │ └── cefview-stack.jpg ├── gen-linux-arm.sh ├── gen-linux-arm64.sh ├── gen-linux-x64.sh ├── gen-linux-x86.sh ├── gen-mac-arm64.sh ├── gen-mac-x64.sh ├── gen-win-arm64.bat ├── gen-win-x64.bat ├── gen-win-x86.bat ├── include ├── CefVersion.h ├── CefViewBrowserApp.h ├── CefViewBrowserAppDelegate.h ├── CefViewBrowserClient.h ├── CefViewBrowserClientDelegate.h └── CefViewCoreGlobal.h ├── readme.md └── src ├── CMakeLists.txt ├── CefVersion.h.in ├── CefView └── CefBrowserApp │ ├── CefViewBrowserApp.cpp │ ├── CefViewBrowserClient.cpp │ ├── CefViewBrowserClient_ContextMenuHandler.cpp │ ├── CefViewBrowserClient_DialogHandler.cpp │ ├── CefViewBrowserClient_DisplayHandler.cpp │ ├── CefViewBrowserClient_DownloadHandler.cpp │ ├── CefViewBrowserClient_DragHandler.cpp │ ├── CefViewBrowserClient_FindHandler.cpp │ ├── CefViewBrowserClient_FocusHandler.cpp │ ├── CefViewBrowserClient_JSDialogHandler.cpp │ ├── CefViewBrowserClient_KeyboardHandler.cpp │ ├── CefViewBrowserClient_LifeSpanHandler.cpp │ ├── CefViewBrowserClient_LoadHandler.cpp │ ├── CefViewBrowserClient_RenderHandler.cpp │ ├── CefViewBrowserClient_RequestHandler.cpp │ ├── CefViewBrowserClient_ResourceRequestHandler.cpp │ ├── CefViewQueryHandler │ ├── CefViewQueryHandler.cpp │ └── CefViewQueryHandler.h │ └── CefViewSchemeHandler │ ├── CefViewSchemeHandler.cpp │ ├── CefViewSchemeHandler.h │ ├── CefViewSchemeHandlerFactory.cpp │ └── CefViewSchemeHandlerFactory.h ├── CefViewCoreProtocol.h.in ├── CefWing ├── App │ ├── CefViewAppBase.cpp │ ├── CefViewAppBase.h │ ├── CefViewOtherApp.cpp │ ├── CefViewOtherApp.h │ ├── CefViewRenderApp.cpp │ └── CefViewRenderApp.h ├── Bridge │ ├── CefViewBridgeObject.cpp │ └── CefViewBridgeObject.h ├── linux │ └── main.cpp ├── mac │ ├── CefViewWing.entitlements │ ├── Info.plist │ └── main.mm └── win │ ├── CefViewWing.manifest │ ├── main.cpp │ └── resource.rc.in └── Shared └── Common ├── CefViewCoreLog.cpp ├── CefViewCoreLog.h ├── CefViewDebug.cpp └── CefViewDebug.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Mozilla 3 | ColumnLimit: 120 4 | AlignAfterOpenBracket: Align 5 | BinPackArguments: false 6 | SortIncludes: false 7 | FixNamespaceComments: true # add commend at end: 8 | NamespaceIndentation: None #intend content of namespace 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # To learn more about .editorconfig see https://aka.ms/editorconfigdocs 2 | 3 | # All files 4 | [*.{c,cpp,cxx,h,hpp,hxx}] 5 | indent_style = space 6 | charset = utf-8-bom 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.{cmd,[cC][mM][dD]} text eol=crlf 3 | *.{bat,[bB][aA][tT]} text eol=crlf -------------------------------------------------------------------------------- /.github/workflows/build-linux-x86_64.yml: -------------------------------------------------------------------------------- 1 | name: Build on Linux 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - ".github/workflows/build-linux-x86_64.yml" 8 | - "CMakeLists.txt" 9 | - "CefConfig.cmake" 10 | - "include/**" 11 | - "src/**" 12 | 13 | pull_request: 14 | branches: [main] 15 | paths: 16 | - "CMakeLists.txt" 17 | - "CefConfig.cmake" 18 | - "include/**" 19 | - "src/**" 20 | 21 | env: 22 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 23 | BUILD_TYPE: Release 24 | 25 | jobs: 26 | build: 27 | # The CMake configure and build commands are platform agnostic and should work equally 28 | # well on Windows or Mac. You can convert this to a matrix build if you need 29 | # cross-platform coverage. 30 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 31 | runs-on: ubuntu-latest 32 | 33 | steps: 34 | - name: Checkout Source 35 | uses: actions/checkout@v2 36 | with: 37 | submodules: "true" 38 | 39 | - name: Cache CEF folders 40 | uses: actions/cache@v3 41 | with: 42 | path: ${{github.workspace}}/dep 43 | key: ${{ runner.os }}-dep-cef 44 | 45 | - name: Install x11 46 | run: sudo apt-get install -y libx11-dev 47 | 48 | - name: Configure CMake 49 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 50 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 51 | run: cmake -B ${{github.workspace}}/build -DPROJECT_ARCH=x86_64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_SANDBOX=ON 52 | 53 | - name: Build 54 | # Build your program with the given configuration 55 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 56 | -------------------------------------------------------------------------------- /.github/workflows/build-macos-x86_64.yml: -------------------------------------------------------------------------------- 1 | name: Build on macOS 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - ".github/workflows/build-macos-x86_64.yml" 8 | - "CMakeLists.txt" 9 | - "CefConfig.cmake" 10 | - "include/**" 11 | - "src/**" 12 | 13 | pull_request: 14 | branches: [main] 15 | paths: 16 | - "CMakeLists.txt" 17 | - "CefConfig.cmake" 18 | - "include/**" 19 | - "src/**" 20 | 21 | env: 22 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 23 | BUILD_TYPE: Release 24 | 25 | jobs: 26 | build: 27 | # The CMake configure and build commands are platform agnostic and should work equally 28 | # well on Windows or Mac. You can convert this to a matrix build if you need 29 | # cross-platform coverage. 30 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 31 | runs-on: macos-latest 32 | 33 | steps: 34 | - name: Checkout Source 35 | uses: actions/checkout@v2 36 | with: 37 | submodules: "true" 38 | 39 | - name: Cache CEF folders 40 | uses: actions/cache@v3 41 | with: 42 | path: ${{github.workspace}}/dep 43 | key: ${{ runner.os }}-dep-cef 44 | 45 | - name: Setup Xcode version 46 | uses: maxim-lobanov/setup-xcode@v1 47 | with: 48 | xcode-version: "15" 49 | 50 | - name: Configure CMake 51 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 52 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 53 | run: cmake -G "Xcode" -B ${{github.workspace}}/build -DPROJECT_ARCH=x86_64 -DTARGET_ARCH=x86_64 -DUSE_SANDBOX=ON 54 | 55 | - name: Build 56 | # Build your program with the given configuration 57 | run: xcodebuild -project ${{github.workspace}}/build/CefViewCore.xcodeproj -configuration ${{env.BUILD_TYPE}} 58 | -------------------------------------------------------------------------------- /.github/workflows/build-windows-x86_64.yml: -------------------------------------------------------------------------------- 1 | name: Build on Windows 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - ".github/workflows/build-windows-x86_64.yml" 8 | - "CMakeLists.txt" 9 | - "CefConfig.cmake" 10 | - "include/**" 11 | - "src/**" 12 | 13 | pull_request: 14 | branches: [main] 15 | paths: 16 | - "CMakeLists.txt" 17 | - "CefConfig.cmake" 18 | - "include/**" 19 | - "src/**" 20 | 21 | env: 22 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 23 | BUILD_TYPE: Release 24 | 25 | jobs: 26 | build: 27 | # The CMake configure and build commands are platform agnostic and should work equally 28 | # well on Windows or Mac. You can convert this to a matrix build if you need 29 | # cross-platform coverage. 30 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 31 | runs-on: windows-latest 32 | 33 | steps: 34 | - name: Checkout Source 35 | uses: actions/checkout@v2 36 | with: 37 | submodules: "true" 38 | 39 | - name: Cache CEF folders 40 | uses: actions/cache@v3 41 | with: 42 | path: ${{github.workspace}}/dep 43 | key: ${{ runner.os }}-dep-cef 44 | 45 | - name: Configure CMake 46 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 47 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 48 | run: cmake -B ${{github.workspace}}/build -A x64 -DPROJECT_ARCH=x86_64 -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 49 | 50 | - name: Build 51 | # Build your program with the given configuration 52 | run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .build.* 2 | dep/cef 3 | output 4 | dep/*.bz2 5 | .DS_Store 6 | dep/cef_binary_* 7 | .build 8 | include/CefViewWingProcessName.h 9 | include/CefViewCoreProtocol.h 10 | include/CefViewCoreProtocol.h 11 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # The main config file for CefViewCore 3 | # 4 | cmake_minimum_required(VERSION 3.19.1) 5 | project(CefViewCore) 6 | 7 | option(USE_SANDBOX "Enable CEF Sandbox" OFF) 8 | 9 | option(STATIC_CRT "Use MultiThreaded linkage for MSVC" OFF) 10 | 11 | option(USE_GPU_OPTIMUS "Enable GPU Optimus (Only for Windows and usually not needed)" OFF) 12 | 13 | # add camke modules 14 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 15 | 16 | # Determine the project architecture. 17 | if(NOT DEFINED PROJECT_ARCH) 18 | if(OS_WINDOWS AND "${CMAKE_GENERATOR_PLATFORM}" STREQUAL "arm64") 19 | set(PROJECT_ARCH "arm64") 20 | elseif(CMAKE_SIZEOF_VOID_P MATCHES 8) 21 | set(PROJECT_ARCH "x86_64") 22 | else() 23 | set(PROJECT_ARCH "x86") 24 | endif() 25 | endif() 26 | 27 | if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 28 | set(OS_MACOS 1) 29 | set(OS_POSIX 1) 30 | add_definitions(-DOS_MACOS=1 -DOS_POSIX=1) 31 | 32 | # Target architecture. 33 | if(PROJECT_ARCH STREQUAL "x86_64") 34 | set(CMAKE_OSX_ARCHITECTURES "x86_64") 35 | elseif(PROJECT_ARCH STREQUAL "arm64") 36 | set(CMAKE_OSX_ARCHITECTURES "arm64") 37 | else() 38 | set(CMAKE_OSX_ARCHITECTURES "i386") 39 | endif() 40 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") 41 | set(OS_LINUX 1) 42 | set(OS_POSIX 1) 43 | add_definitions(-DOS_LINUX=1 -DOS_POSIX=1) 44 | add_compile_options(-Wno-unknown-pragmas) 45 | 46 | # Target architecture. 47 | if(PROJECT_ARCH STREQUAL "x86_64") 48 | # x86 64-bit architecture. 49 | add_compile_options(-m64 -march=x86-64) 50 | add_link_options(-m64) 51 | elseif(PROJECT_ARCH STREQUAL "x86") 52 | # x86 32-bit architecture. 53 | add_compile_options(-m32) 54 | add_link_options(-m32) 55 | endif() 56 | elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") 57 | set(OS_WINDOWS 1) 58 | add_definitions(-DOS_WINDOWS=1) 59 | 60 | if(USE_GPU_OPTIMUS) 61 | add_definitions(-DENABLE_GPU_OPTIMUS=1) 62 | endif() 63 | endif() 64 | 65 | # Only generate Debug and Release configuration types. 66 | set(CMAKE_CONFIGURATION_TYPES Debug Release) 67 | 68 | if(NOT CMAKE_BUILD_TYPE) 69 | set(CMAKE_BUILD_TYPE "Debug") 70 | endif() 71 | 72 | # Use folders in the resulting project files. 73 | set_property(GLOBAL PROPERTY OS_FOLDERS ON) 74 | 75 | # C standard 76 | set(CMAKE_C_STANDARD_REQUIRED ON) 77 | set(CMAKE_C_STANDARD 11) 78 | 79 | # C++ standard 80 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 81 | set(CMAKE_CXX_STANDARD 17) 82 | 83 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/output/$/bin) 84 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/output/$/lib) 85 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/output/$/lib) 86 | 87 | # set CefView Helper Process Name 88 | if(NOT CEFVIEW_WING_NAME) 89 | set(DEFAULT_CEFVIEW_WING_NAME "CefViewWing") 90 | message(STATUS 91 | "CEFVIEW_WING_NAME is empty, use default version ${DEFAULT_CEFVIEW_WING_NAME}\n" 92 | "You can change the name by adding -DCEFVIEW_WING_NAME=xxx to commandline for generation") 93 | set(CEFVIEW_WING_NAME ${DEFAULT_CEFVIEW_WING_NAME} CACHE STRING "CefViewWing Helper Process Name" FORCE) 94 | endif() 95 | 96 | configure_file( 97 | "${CMAKE_CURRENT_SOURCE_DIR}/src/CefViewCoreProtocol.h.in" 98 | "${CMAKE_CURRENT_SOURCE_DIR}/include/CefViewCoreProtocol.h" 99 | @ONLY 100 | ) 101 | 102 | # Config the CEF 103 | # ############################################################## 104 | message(STATUS "Detecting CEF_SDK_VERSION: ${CEF_SDK_VERSION}") 105 | 106 | if(NOT CEF_SDK_VERSION) 107 | # set CEF version to be used 108 | # https://cef-builds.spotifycdn.com/index.html 109 | # https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding.md 110 | # set(DEFAULT_CEF_SDK_VERSION "89.0.18+gb36241d+chromium-89.0.4389.114") # GOOD 111 | # set(DEFAULT_CEF_SDK_VERSION "91.1.23+g04c8d56+chromium-91.0.4472.164") # GOOD 112 | # set(DEFAULT_CEF_SDK_VERSION "92.0.27+g274abcf+chromium-92.0.4515.159") # GOOD 113 | # set(DEFAULT_CEF_SDK_VERSION "93.1.14+gf38ce34+chromium-93.0.4577.82") # GOOD 114 | # set(DEFAULT_CEF_SDK_VERSION "94.4.11+gc4d96f0+chromium-94.0.4606.81") # GOOD 115 | # set(DEFAULT_CEF_SDK_VERSION "95.7.18+g0d6005e+chromium-95.0.4638.69") # GOOD 116 | # set(DEFAULT_CEF_SDK_VERSION "96.0.18+gfe551e4+chromium-96.0.4664.110") # GOOD 117 | # set(DEFAULT_CEF_SDK_VERSION "97.1.9+ga00bca5+chromium-97.0.4692.99") # GOOD 118 | # set(DEFAULT_CEF_SDK_VERSION "98.2.1+g29d6e22+chromium-98.0.4758.109") # GOOD 119 | # set(DEFAULT_CEF_SDK_VERSION "99.2.15+g71e9523+chromium-99.0.4844.84") # IME poisition incorrect 120 | # set(DEFAULT_CEF_SDK_VERSION "100.0.24+g0783cf8+chromium-100.0.4896.127") # IME poisition incorrect 121 | # set(DEFAULT_CEF_SDK_VERSION "101.0.18+g367b4a0+chromium-101.0.4951.67") # IME poisition incorrect 122 | # set(DEFAULT_CEF_SDK_VERSION "102.0.10+gf249b2e+chromium-102.0.5005.115") # IME poisition incorrect 123 | # set(DEFAULT_CEF_SDK_VERSION "103.0.12+g8eb56c7+chromium-103.0.5060.134") # IME poisition incorrect 124 | # set(DEFAULT_CEF_SDK_VERSION "104.4.26+g4180781+chromium-104.0.5112.102") # GOOD 125 | # set(DEFAULT_CEF_SDK_VERSION "105.3.39+g2ec21f9+chromium-105.0.5195.127") # GOOD 126 | # set(DEFAULT_CEF_SDK_VERSION "106.1.1+g5891c70+chromium-106.0.5249.119") # GOOD 127 | # set(DEFAULT_CEF_SDK_VERSION "107.1.12+g65b79a6+chromium-107.0.5304.122") # GOOD 128 | # set(DEFAULT_CEF_SDK_VERSION "108.4.13+ga98cd4c+chromium-108.0.5359.125") # GOOD 129 | # set(DEFAULT_CEF_SDK_VERSION "109.1.18+gf1c41e4+chromium-109.0.5414.120") # GOOD 130 | # set(DEFAULT_CEF_SDK_VERSION "110.0.32+g291f1df+chromium-110.0.5481.180") # GOOD 131 | # set(DEFAULT_CEF_SDK_VERSION "111.2.7+gebf5d6a+chromium-111.0.5563.148") # GOOD 132 | # set(DEFAULT_CEF_SDK_VERSION "112.3.0+gb09c4ca+chromium-112.0.5615.165") # GOOD 133 | # set(DEFAULT_CEF_SDK_VERSION "113.3.1+g525fa10+chromium-113.0.5672.128") # GOOD 134 | # set(DEFAULT_CEF_SDK_VERSION "114.2.13+g6792e13+chromium-114.0.5735.200") 135 | # set(DEFAULT_CEF_SDK_VERSION "115.3.15+g21130e0+chromium-115.0.5790.173") 136 | # set(DEFAULT_CEF_SDK_VERSION "116.0.27+gd8c85ac+chromium-116.0.5845.190") 137 | # set(DEFAULT_CEF_SDK_VERSION "117.2.5+gda4c36a+chromium-117.0.5938.152") 138 | # set(DEFAULT_CEF_SDK_VERSION "118.7.1+g99817d2+chromium-118.0.5993.119") 139 | # set(DEFAULT_CEF_SDK_VERSION "119.4.7+g55e15c8+chromium-119.0.6045.199") # GOOD 140 | # set(DEFAULT_CEF_SDK_VERSION "120.1.6+gf08b1fd+chromium-120.0.6099.71") # GOOD 141 | # set(DEFAULT_CEF_SDK_VERSION "121.3.15+g4d3b0b4+chromium-121.0.6167.184") # GOOD 142 | # set(DEFAULT_CEF_SDK_VERSION "122.1.13+gde5b724+chromium-122.0.6261.130") # GOOD 143 | # set(DEFAULT_CEF_SDK_VERSION "123.0.13+gfc703fb+chromium-123.0.6312.124") # NOT TEST 144 | # set(DEFAULT_CEF_SDK_VERSION "124.3.9+g9bd638f+chromium-124.0.6367.207") # NOT TEST 145 | # set(DEFAULT_CEF_SDK_VERSION "125.0.22+gc410c95+chromium-125.0.6422.142") # NOT TEST 146 | # set(DEFAULT_CEF_SDK_VERSION "126.2.18+g3647d39+chromium-126.0.6478.183") # NOT TEST 147 | set(DEFAULT_CEF_SDK_VERSION "127.3.5+g114ea2a+chromium-127.0.6533.120") # GOOD 148 | 149 | # set(DEFAULT_CEF_SDK_VERSION "128.4.9+g9840ad9+chromium-128.0.6613.120") # BAD # debugbreak - debug mode 150 | message(STATUS 151 | "CEF_SDK_VERSION is empty, use default version ${DEFAULT_CEF_SDK_VERSION}\n" 152 | "You can change the version by adding -DCEF_SDK_VERSION=xxx to commandline for generation") 153 | set(CEF_SDK_VERSION ${DEFAULT_CEF_SDK_VERSION} CACHE STRING "Cef binary SDK version" FORCE) 154 | endif() 155 | 156 | # setup CEF 157 | include(SetupCef) 158 | 159 | # ############################################################## 160 | set(CMAKE_SUPPRESS_REGENERATION TRUE) 161 | 162 | # ############################################################## 163 | set(CefViewCore_INCLUDE_PATH 164 | "${CEF_INCLUDE_PATH}" 165 | "${CMAKE_CURRENT_SOURCE_DIR}/include" 166 | ) 167 | 168 | add_subdirectory(src) 169 | 170 | if(OS_MACOS) 171 | set(CefViewCore_HELPER_TARGETS "${CEFVIEW_WING_NAME};${CEFVIEW_WING_NAME}_gpu;${CEFVIEW_WING_NAME}_plugin;${CEFVIEW_WING_NAME}_renderer") 172 | else() 173 | set(CefViewCore_HELPER_TARGETS "${CEFVIEW_WING_NAME}") 174 | endif() 175 | 176 | get_directory_property(IS_CURRENT_IN_SUBDIRECTORY PARENT_DIRECTORY) 177 | 178 | if(IS_CURRENT_IN_SUBDIRECTORY) 179 | set(CEFVIEW_WING_NAME ${CEFVIEW_WING_NAME} PARENT_SCOPE) 180 | set(CefViewCore_EXPORT_INCLUDE_PATH ${CefViewCore_INCLUDE_PATH} PARENT_SCOPE) 181 | set(CefViewCore_HELPER_APP_TARGETS ${CefViewCore_HELPER_TARGETS} PARENT_SCOPE) 182 | set(CefViewCore_CEF_BINARY_DIR ${CEF_BINARY_DIR} PARENT_SCOPE) 183 | set(CefViewCore_CEF_RESOURCE_DIR ${CEF_RESOURCE_DIR} PARENT_SCOPE) 184 | set(CefViewCore_CEF_INCLUDE_DIR ${CEF_ROOT}/include PARENT_SCOPE) 185 | endif() 186 | 187 | install( 188 | DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/output/$/lib" 189 | DESTINATION "$" 190 | ) 191 | install( 192 | DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/output/$/bin" 193 | DESTINATION "$" 194 | USE_SOURCE_PERMISSIONS 195 | ) 196 | install( 197 | DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" 198 | DESTINATION "include/CefViewCore" 199 | ) 200 | install( 201 | DIRECTORY "${CEF_SDK_DIR}/include" 202 | DESTINATION "include/cef" 203 | ) 204 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 6, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 20, 6 | "patch": 0 7 | }, 8 | "include": [], 9 | "configurePresets": [ 10 | { 11 | "name": "default", 12 | "hidden": true 13 | }, 14 | { 15 | "name": "win", 16 | "hidden": true, 17 | "inherits": "default" 18 | }, 19 | { 20 | "name": "win-x86", 21 | "inherits": "win", 22 | "displayName": "Windows x86 (Debug & Release)", 23 | "binaryDir": "${sourceDir}/.build/win.x86", 24 | "architecture": "Win32", 25 | "cacheVariables": { 26 | "PROJECT_ARCH": "x86", 27 | "USE_SANDBOX": "ON" 28 | } 29 | }, 30 | { 31 | "name": "win-x64", 32 | "inherits": "win", 33 | "displayName": "Windows x64 (Debug & Release)", 34 | "binaryDir": "${sourceDir}/.build/win.x64", 35 | "architecture": "x64", 36 | "cacheVariables": { 37 | "PROJECT_ARCH": "x86_64", 38 | "USE_SANDBOX": "ON" 39 | } 40 | }, 41 | { 42 | "name": "win-arm64", 43 | "inherits": "win", 44 | "displayName": "Windows arm64 (Debug & Release)", 45 | "binaryDir": "${sourceDir}/.build/win.arm64", 46 | "architecture": "ARM64", 47 | "cacheVariables": { 48 | "PROJECT_ARCH": "arm64", 49 | "USE_SANDBOX": "ON" 50 | } 51 | }, 52 | { 53 | "name": "osx", 54 | "hidden": true, 55 | "generator": "Xcode", 56 | "inherits": "default" 57 | }, 58 | { 59 | "name": "osx-x64", 60 | "inherits": "osx", 61 | "displayName": "macOS x64 (Debug & Release)", 62 | "binaryDir": "${sourceDir}/.build/osx.x64", 63 | "architecture": "x64", 64 | "cacheVariables": { 65 | "PROJECT_ARCH": "x86_64", 66 | "USE_SANDBOX": "ON" 67 | } 68 | }, 69 | { 70 | "name": "osx-arm64", 71 | "inherits": "osx", 72 | "displayName": "macOS arm64 (Debug & Release)", 73 | "binaryDir": "${sourceDir}/.build/osx.arm64", 74 | "architecture": "arm64", 75 | "cacheVariables": { 76 | "PROJECT_ARCH": "arm64", 77 | "USE_SANDBOX": "ON" 78 | } 79 | }, 80 | { 81 | "name": "linux", 82 | "hidden": true, 83 | "inherits": "default" 84 | }, 85 | { 86 | "name": "linux-x64", 87 | "inherits": "linux", 88 | "displayName": "Linux x64", 89 | "binaryDir": "${sourceDir}/.build/linux.x64", 90 | "architecture": "x64", 91 | "cacheVariables": { 92 | "PROJECT_ARCH": "x86_64", 93 | "USE_SANDBOX": "ON" 94 | } 95 | }, 96 | { 97 | "name": "linux-arm64", 98 | "inherits": "linux", 99 | "displayName": "Linux arm64", 100 | "binaryDir": "${sourceDir}/.build/linux.arm64", 101 | "architecture": "arm64", 102 | "cacheVariables": { 103 | "PROJECT_ARCH": "arm64", 104 | "USE_SANDBOX": "ON" 105 | } 106 | }, 107 | { 108 | "name": "linux-x86", 109 | "inherits": "linux", 110 | "displayName": "Linux x86", 111 | "binaryDir": "${sourceDir}/.build/linux.x86", 112 | "architecture": "x86", 113 | "cacheVariables": { 114 | "PROJECT_ARCH": "x86", 115 | "USE_SANDBOX": "ON" 116 | } 117 | }, 118 | { 119 | "name": "linux-arm", 120 | "inherits": "linux", 121 | "displayName": "Linux arm", 122 | "binaryDir": "${sourceDir}/.build/linux.arm", 123 | "architecture": "arm", 124 | "cacheVariables": { 125 | "PROJECT_ARCH": "arm", 126 | "USE_SANDBOX": "ON" 127 | } 128 | } 129 | ] 130 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 CefView 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmake/SetupCef.cmake: -------------------------------------------------------------------------------- 1 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2 | # Generally, there is NO NEED to modify the following config 3 | # 4 | # Download CEF binary package 5 | # https://cef-builds.spotifycdn.com/index.html 6 | # 7 | 8 | # ################################################################################# 9 | # Stage 1. Download CEF binary package 10 | if(NOT CEF_SDK_VERSION) 11 | message(FATAL_ERROR "CEF_SDK_VERSION is missing!") 12 | endif() 13 | 14 | if(OS_WINDOWS) 15 | set(CEF_SDK_PLATFORM "windows") 16 | elseif(OS_LINUX) 17 | set(CEF_SDK_PLATFORM "linux") 18 | elseif(OS_MACOS) 19 | set(CEF_SDK_PLATFORM "macos") 20 | else() 21 | message(FATAL_ERROR "Unsupported Operating System") 22 | endif() 23 | 24 | if(PROJECT_ARCH STREQUAL "x86_64") 25 | set(CEF_SDK_ARCH "64") 26 | elseif(PROJECT_ARCH STREQUAL "x86") 27 | set(CEF_SDK_ARCH "32") 28 | elseif(PROJECT_ARCH STREQUAL "arm64") 29 | set(CEF_SDK_ARCH "arm64") 30 | elseif(PROJECT_ARCH STREQUAL "arm") 31 | set(CEF_SDK_ARCH "arm") 32 | else() 33 | message(FATAL_ERROR "Unsupported Processor Architecture") 34 | endif() 35 | 36 | # set cef sdk package name 37 | set(CEF_SDK_WORKSPACE "${CMAKE_CURRENT_SOURCE_DIR}/dep") 38 | 39 | if(OS_MACOS AND PROJECT_ARCH STREQUAL "x86_64") 40 | # macosx64 41 | set(CEF_SDK_PACKAGE_NAME "cef_binary_${CEF_SDK_VERSION}_${CEF_SDK_PLATFORM}x${CEF_SDK_ARCH}") 42 | else() 43 | set(CEF_SDK_PACKAGE_NAME "cef_binary_${CEF_SDK_VERSION}_${CEF_SDK_PLATFORM}${CEF_SDK_ARCH}") 44 | endif() 45 | 46 | if(NOT CUSTOM_CEF_SDK_DIR) 47 | # Scan extracted sdk dir 48 | set(CEF_SDK_EXTRACTED_DIR "${CEF_SDK_WORKSPACE}/${CEF_SDK_PACKAGE_NAME}") 49 | file(GLOB CEF_SDK_DIR "${CEF_SDK_EXTRACTED_DIR}") 50 | else() 51 | message(STATUS "CUSTOM_CEF_SDK_DIR set: ${CUSTOM_CEF_SDK_DIR}") 52 | set(CEF_SDK_DIR "${CUSTOM_CEF_SDK_DIR}") 53 | endif() 54 | 55 | # output 56 | message(STATUS "CEF SDK dir: ${CEF_SDK_DIR}") 57 | 58 | # ################################################################################# 59 | # Stage 2. Extract CEF binary package 60 | if(NOT EXISTS ${CEF_SDK_DIR}) 61 | set(CEF_LOCAL_PACKAGE_PATH "${CEF_SDK_WORKSPACE}/${CEF_SDK_PACKAGE_NAME}.tar.bz2") 62 | 63 | # if no local cef sdk package file then download it 64 | if(NOT EXISTS "${CEF_LOCAL_PACKAGE_PATH}") 65 | set(CEF_SDK_DOWNLOAD_URL "https://cef-builds.spotifycdn.com/${CEF_SDK_PACKAGE_NAME}.tar.bz2") 66 | message(STATUS "Downloading CEF binary SDK from ${CEF_SDK_DOWNLOAD_URL}") 67 | file(DOWNLOAD 68 | "${CEF_SDK_DOWNLOAD_URL}" # URL 69 | "${CEF_LOCAL_PACKAGE_PATH}" # Local Path 70 | SHOW_PROGRESS 71 | TLS_VERIFY ON 72 | STATUS DOWNLOAD_RESULT 73 | ) 74 | list(GET DOWNLOAD_RESULT 0 DOWNLOAD_RESULT_CODE) 75 | list(GET DOWNLOAD_RESULT 1 DOWNLOAD_RESULT_MESSAGE) 76 | 77 | if(NOT DOWNLOAD_RESULT_CODE EQUAL 0) 78 | file(REMOVE "${CEF_LOCAL_PACKAGE_PATH}") 79 | message(FATAL_ERROR "Failed to download CEF binary SDK, ERROR:[${DOWNLOAD_RESULT_CODE}]${DOWNLOAD_RESULT_MESSAGE}") 80 | endif() 81 | endif() 82 | 83 | message(STATUS "Extracting CEF binary SDK from ${CEF_LOCAL_PACKAGE_PATH}") 84 | 85 | # Extract 86 | file(ARCHIVE_EXTRACT 87 | INPUT "${CEF_LOCAL_PACKAGE_PATH}" 88 | DESTINATION "${CEF_SDK_WORKSPACE}" 89 | VERBOSE 90 | ) 91 | 92 | # Capture the dir name 93 | file(GLOB CEF_SDK_DIR "${CEF_SDK_EXTRACTED_DIR}") 94 | endif() 95 | 96 | # ################################################################################# 97 | # Stage 3. Config CEF 98 | if(${CMAKE_VERSION} GREATER "3.11") 99 | cmake_policy(SET CMP0074 NEW) 100 | endif() 101 | 102 | if(${CMAKE_VERSION} GREATER "3.12") 103 | cmake_policy(SET CMP0077 NEW) 104 | endif() 105 | 106 | if(OS_WINDOWS) 107 | add_link_options(/DEBUG) 108 | 109 | if(USE_SANDBOX) 110 | # cef_sandbox.lib is MT already, must keep the same with it 111 | set(CEF_RUNTIME_LIBRARY_FLAG "/MT" CACHE STRING "Use static runtime") 112 | add_compile_options("/MT$<$:d>") 113 | else() 114 | # either MT or MD is supported 115 | set(CEF_RUNTIME_LIBRARY_FLAG "/M$,T,D>" CACHE STRING "Use static runtime" FORCE) 116 | add_compile_options("/M$,T,D>$<$:d>") 117 | endif() 118 | else() 119 | add_compile_options( 120 | "-g" 121 | "$<$:-O0>" 122 | "$<$:-O3>" 123 | ) 124 | endif() 125 | 126 | # Append CEF root dir to CMAKE_MODULE_PATH 127 | set(CEF_ROOT "${CEF_SDK_DIR}") 128 | list(APPEND CMAKE_MODULE_PATH "${CEF_ROOT}/cmake") 129 | find_package(CEF REQUIRED) 130 | 131 | # Add libcef dll wrapper 132 | add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper) 133 | 134 | if(USE_SANDBOX AND(OS_WINDOWS OR OS_MACOS)) 135 | add_definitions(-DCEF_USE_SANDBOX) 136 | 137 | # message(STATUS "cef_sandbox_lib path:" "${CEF_SANDBOX_LIB_DEBUG}," "${CEF_SANDBOX_LIB_RELEASE}" ) 138 | # Logical target used to link the cef_sandbox library. 139 | ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}") 140 | endif() 141 | 142 | PRINT_CEF_CONFIG() 143 | 144 | # ################################################################################# 145 | # Stage 4. Read CEF version and generated CefVersion.h 146 | # set need configure QCefView_global to false 147 | set(Need_Config_CefVersion_File FALSE) 148 | 149 | message(STATUS "${CEF_ROOT}/include/cef_version.h") 150 | file(READ "${CEF_ROOT}/include/cef_version.h" cef_version_content) 151 | 152 | # ------------ check CEF_VERSION 153 | string(REGEX MATCH "#define CEF_VERSION \"([a-z0-9\.\+\-]+)\"" _ ${cef_version_content}) 154 | 155 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_VERSION}") 156 | set(CEF_VERSION ${CMAKE_MATCH_1} CACHE STRING "CEF Version" FORCE) 157 | set(Need_Config_CefVersion_File TRUE) 158 | message(STATUS "CEF_VERSION: ${CEF_VERSION} - Updated!") 159 | else() 160 | message(STATUS "CEF_VERSION: ${CEF_VERSION} - No Change!") 161 | endif() 162 | 163 | # ------------ check CEF_VERSION_MAJOR 164 | string(REGEX MATCH "#define CEF_VERSION_MAJOR ([0-9]+)" _ ${cef_version_content}) 165 | 166 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_VERSION_MAJOR}") 167 | set(CEF_VERSION_MAJOR ${CMAKE_MATCH_1} CACHE STRING "CEF Major Version" FORCE) 168 | set(Need_Config_CefVersion_File TRUE) 169 | message(STATUS "CEF_VERSION_MAJOR: ${CEF_VERSION_MAJOR} - Updated!") 170 | else() 171 | message(STATUS "CEF_VERSION_MAJOR: ${CEF_VERSION_MAJOR} - No Change!") 172 | endif() 173 | 174 | # ------------ check CEF_VERSION_MINOR 175 | string(REGEX MATCH "#define CEF_VERSION_MINOR ([0-9]+)" _ ${cef_version_content}) 176 | 177 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_VERSION_MINOR}") 178 | set(CEF_VERSION_MINOR ${CMAKE_MATCH_1} CACHE STRING "CEF Minor Version" FORCE) 179 | set(Need_Config_CefVersion_File TRUE) 180 | message(STATUS "CEF_VERSION_MINOR: ${CEF_VERSION_MINOR} - Updated!") 181 | else() 182 | message(STATUS "CEF_VERSION_MINOR: ${CEF_VERSION_MINOR} - No Change!") 183 | endif() 184 | 185 | # ------------ check CEF_VERSION_PATCH 186 | string(REGEX MATCH "#define CEF_VERSION_PATCH ([0-9]+)" _ ${cef_version_content}) 187 | 188 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_VERSION_PATCH}") 189 | set(CEF_VERSION_PATCH ${CMAKE_MATCH_1} CACHE STRING "CEF Patch Version" FORCE) 190 | set(Need_Config_CefVersion_File TRUE) 191 | message(STATUS "CEF_VERSION_PATCH: ${CEF_VERSION_PATCH} - Updated!") 192 | else() 193 | message(STATUS "CEF_VERSION_PATCH: ${CEF_VERSION_PATCH} - No Change!") 194 | endif() 195 | 196 | # ------------ check CEF_COMMIT_NUMBER 197 | string(REGEX MATCH "#define CEF_COMMIT_NUMBER ([0-9]+)" _ ${cef_version_content}) 198 | 199 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_COMMIT_NUMBER}") 200 | set(CEF_COMMIT_NUMBER ${CMAKE_MATCH_1} CACHE STRING "CEF Commit Number" FORCE) 201 | set(Need_Config_CefVersion_File TRUE) 202 | message(STATUS "CEF_COMMIT_NUMBER: ${CEF_COMMIT_NUMBER} - Updated!") 203 | else() 204 | message(STATUS "CEF_COMMIT_NUMBER: ${CEF_COMMIT_NUMBER} - No Change!") 205 | endif() 206 | 207 | # ------------ check CEF_COMMIT_HASH 208 | string(REGEX MATCH "#define CEF_COMMIT_HASH \"([a-z0-9]+)\"" _ ${cef_version_content}) 209 | 210 | if(NOT "${CMAKE_MATCH_1}" STREQUAL "${CEF_COMMIT_HASH}") 211 | set(CEF_COMMIT_HASH ${CMAKE_MATCH_1} CACHE STRING "CEF Commit Hash" FORCE) 212 | set(Need_Config_CefVersion_File TRUE) 213 | message(STATUS "CEF_COMMIT_HASH: ${CEF_COMMIT_HASH} - Updated!") 214 | else() 215 | message(STATUS "CEF_COMMIT_HASH: ${CEF_COMMIT_HASH} - No Change!") 216 | endif() 217 | 218 | if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include/CefVersion.h") 219 | set(Need_Config_CefVersion_File TRUE) 220 | endif() 221 | 222 | if(${Need_Config_CefVersion_File}) 223 | message(STATUS "Need to configure CefVersion.h file") 224 | configure_file( 225 | "${CMAKE_CURRENT_SOURCE_DIR}/src/CefVersion.h.in" 226 | "${CMAKE_CURRENT_SOURCE_DIR}/include/CefVersion.h" 227 | @ONLY 228 | NEWLINE_STYLE UNIX 229 | ) 230 | else() 231 | message(STATUS "No need to configure CefVersion.h file") 232 | endif() 233 | -------------------------------------------------------------------------------- /dep/readme.md: -------------------------------------------------------------------------------- 1 | Download cef binary release from https://cef-builds.spotifycdn.com/index.html 2 | Then extract the content to this folder and rename the folder to 'cef'. The folder layout shoudl be: 3 | ``` 4 | dep 5 | |--cef 6 | | |--cmake 7 | | |--Debug 8 | | |-include 9 | ... 10 | ``` 11 | -------------------------------------------------------------------------------- /docs/images/cefview-stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CefView/CefViewCore/8b618d4290c9187eedfb8b176aae8a7dfcaa51ab/docs/images/cefview-stack.jpg -------------------------------------------------------------------------------- /gen-linux-arm.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=linux-arm %* -------------------------------------------------------------------------------- /gen-linux-arm64.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=linux-arm64 %* -------------------------------------------------------------------------------- /gen-linux-x64.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=linux-x64 %* -------------------------------------------------------------------------------- /gen-linux-x86.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=linux-x86 %* -------------------------------------------------------------------------------- /gen-mac-arm64.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=osx-arm64 %* -------------------------------------------------------------------------------- /gen-mac-x64.sh: -------------------------------------------------------------------------------- 1 | cmake --preset=osx-x64 %* -------------------------------------------------------------------------------- /gen-win-arm64.bat: -------------------------------------------------------------------------------- 1 | cmake --preset=win-arm64 %* -------------------------------------------------------------------------------- /gen-win-x64.bat: -------------------------------------------------------------------------------- 1 | cmake --preset=win-x64 %* -------------------------------------------------------------------------------- /gen-win-x86.bat: -------------------------------------------------------------------------------- 1 | cmake --preset=win-x86 %* -------------------------------------------------------------------------------- /include/CefVersion.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefVersion.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2025/1/19. 6 | // This file was generated during CMake configuring. 7 | // Do not edit this file directly by manual. 8 | // Edit the CefVersion.h.in and then re-config project with CMake. 9 | // 10 | 11 | #ifndef CefVersion_h 12 | #define CefVersion_h 13 | #pragma once 14 | 15 | // clang-format off 16 | #define CEF_VERSION "127.3.5+g114ea2a+chromium-127.0.6533.120" 17 | #define CEF_VERSION_MAJOR 127 18 | #define CEF_VERSION_MINOR 3 19 | #define CEF_VERSION_PATCH 5 20 | #define CEF_COMMIT_NUMBER 3037 21 | #define CEF_COMMIT_HASH "114ea2af1ba9da18c4ac5e599ccdbb17d01ba75a" 22 | // clang-format on 23 | 24 | #endif // CefVersion 25 | -------------------------------------------------------------------------------- /include/CefViewBrowserApp.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewBrowserApp.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/11. 6 | // 7 | 8 | #ifndef CefViewBrowserApp_h 9 | #define CefViewBrowserApp_h 10 | #pragma once 11 | 12 | #pragma region stl_headers 13 | #include 14 | #include 15 | #pragma endregion 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct FolderResourceMapping 22 | { 23 | CefString path; 24 | CefString url; 25 | int priority; 26 | }; 27 | 28 | struct ArchiveResourceMapping 29 | { 30 | CefString path; 31 | CefString url; 32 | CefString password; 33 | int priority; 34 | }; 35 | 36 | class CefViewBrowserApp 37 | : public CefApp 38 | , public CefBrowserProcessHandler 39 | { 40 | IMPLEMENT_REFCOUNTING(CefViewBrowserApp); 41 | 42 | private: 43 | // The name of the bridge object 44 | CefString builtin_scheme_name_; 45 | CefString bridge_object_name_; 46 | std::unordered_map client_handler_map_; 47 | 48 | // The app delegate 49 | CefViewBrowserAppDelegateInterface::WeakPtr app_delegate_; 50 | 51 | std::list folderResourceMappingList_; 52 | 53 | std::list archiveResourceMappingList_; 54 | 55 | public: 56 | CefViewBrowserApp(const CefString& scheme_name, 57 | const CefString& bridge_name, 58 | CefViewBrowserAppDelegateInterface::RefPtr delegate); 59 | 60 | ~CefViewBrowserApp(); 61 | 62 | void CheckInClient(void* ctx, const CefViewBrowserClientDelegateInterface::RefPtr& handler); 63 | 64 | void CheckOutClient(void* ctx); 65 | 66 | CefViewBrowserClientDelegateInterface::RefPtr GetClientHandler(void* ctx); 67 | 68 | void AddLocalFolderResource(const CefString& path, const CefString& url, int priority = 0); 69 | const std::list& FolderResourceMappingList(); 70 | 71 | void AddArchiveResource(const CefString& path, 72 | const CefString& url, 73 | const CefString& password = "", 74 | int priority = 0); 75 | const std::list& ArchiveResourceMappingList(); 76 | 77 | bool AddGlobalCookie(const CefString& name, 78 | const CefString& value, 79 | const CefString& domain, 80 | const CefString& url); 81 | 82 | bool DeleteAllCookies(); 83 | 84 | bool AddCrossOriginWhitelistEntry(const CefString& sourceOrigin, 85 | const CefString& targetSchema, 86 | const CefString& targetDomain, 87 | bool allowTargetSubdomains); 88 | 89 | bool RemoveCrossOriginWhitelistEntry(const CefString& sourceOrigin, 90 | const CefString& targetSchema, 91 | const CefString& targetDomain, 92 | bool allowTargetSubdomains); 93 | 94 | bool ClearCrossOriginWhitelistEntry(); 95 | 96 | bool IsSafeToExit(); 97 | 98 | private: 99 | #pragma region CefApp 100 | ////////////////////////////////////////////////////////////////////////// 101 | // CefApp methods: 102 | virtual void OnBeforeCommandLineProcessing(const CefString& process_type, 103 | CefRefPtr command_line) override; 104 | 105 | virtual void OnRegisterCustomSchemes(CefRawPtr registrar) override; 106 | 107 | virtual CefRefPtr GetResourceBundleHandler() override; 108 | 109 | virtual CefRefPtr GetBrowserProcessHandler() override; 110 | 111 | virtual CefRefPtr GetRenderProcessHandler() override; 112 | 113 | #pragma endregion 114 | 115 | #pragma region CefBrowserProcessHandler 116 | ////////////////////////////////////////////////////////////////////////// 117 | // CefBrowserProcessHandler methods: 118 | virtual void OnContextInitialized() override; 119 | 120 | virtual void OnBeforeChildProcessLaunch(CefRefPtr command_line) override; 121 | 122 | virtual void OnScheduleMessagePumpWork(int64_t delay_ms) override; 123 | 124 | CefRefPtr GetDefaultClient() override; 125 | 126 | #pragma endregion 127 | }; 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /include/CefViewBrowserAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewBrowserAppDelegate.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/11. 6 | // 7 | 8 | #ifndef CefViewBrowserAppDelegate_h 9 | #define CefViewBrowserAppDelegate_h 10 | #pragma once 11 | 12 | #pragma region stl_headers 13 | #include 14 | #pragma endregion 15 | 16 | #include 17 | 18 | /// 19 | /// 20 | /// 21 | class CefViewBrowserAppDelegateInterface 22 | { 23 | public: 24 | /// 25 | /// 26 | /// 27 | typedef std::shared_ptr RefPtr; 28 | 29 | /// 30 | /// 31 | /// 32 | typedef std::weak_ptr WeakPtr; 33 | 34 | /// 35 | /// 36 | /// 37 | virtual ~CefViewBrowserAppDelegateInterface(){}; 38 | 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | virtual void onBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) = 0; 45 | 46 | /// 47 | /// 48 | /// 49 | /// 50 | virtual void onBeforeChildProcessLaunch(CefRefPtr command_line) = 0; 51 | 52 | /// 53 | /// 54 | /// 55 | /// 56 | virtual void onScheduleMessageLoopWork(int64_t delay_ms) = 0; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/CefViewBrowserClientDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewBrowserHandlerDelegate.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/11. 6 | // 7 | 8 | #ifndef CefViewBrowserHandlerDelegate_h 9 | #define CefViewBrowserHandlerDelegate_h 10 | #pragma once 11 | 12 | #pragma region stl_headers 13 | #include 14 | #pragma endregion 15 | 16 | #include 17 | 18 | /// 19 | /// 20 | /// 21 | class CefViewBrowserClientDelegateInterface 22 | { 23 | public: 24 | /// 25 | /// 26 | /// 27 | typedef std::shared_ptr RefPtr; 28 | 29 | /// 30 | /// 31 | /// 32 | typedef std::weak_ptr WeakPtr; 33 | 34 | /// 35 | /// 36 | /// 37 | virtual ~CefViewBrowserClientDelegateInterface() {} 38 | 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | virtual void processUrlRequest(CefRefPtr& browser, CefRefPtr& frame, const CefString& url) = 0; 46 | 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | virtual void processQueryRequest(CefRefPtr& browser, 55 | CefRefPtr& frame, 56 | const CefString& query, 57 | const int64_t query_id) = 0; 58 | 59 | /// 60 | /// 61 | /// 62 | /// 63 | /// 64 | /// 65 | virtual void focusedEditableNodeChanged(CefRefPtr& browser, 66 | CefRefPtr& frame, 67 | bool focusOnEditableNode) = 0; 68 | 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | virtual void invokeMethodNotify(CefRefPtr& browser, 77 | CefRefPtr& frame, 78 | const CefString& method, 79 | const CefRefPtr& arguments) = 0; 80 | 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | /// 88 | virtual void reportJSResult(CefRefPtr& browser, 89 | CefRefPtr& frame, 90 | const CefString& context, 91 | const CefRefPtr& result) = 0; 92 | 93 | // context menu handler 94 | #pragma region ContextMenuHandler 95 | virtual void onBeforeContextMenu(CefRefPtr& browser, 96 | CefRefPtr& frame, 97 | CefRefPtr& params, 98 | CefRefPtr& model) = 0; 99 | virtual bool onRunContextMenu(CefRefPtr& browser, 100 | CefRefPtr& frame, 101 | CefRefPtr& params, 102 | CefRefPtr& model, 103 | CefRefPtr& callback) = 0; 104 | virtual bool onContextMenuCommand(CefRefPtr& browser, 105 | CefRefPtr& frame, 106 | CefRefPtr& params, 107 | int command_id, 108 | CefContextMenuHandler::EventFlags event_flags) = 0; 109 | virtual void onContextMenuDismissed(CefRefPtr& browser, CefRefPtr& frame) = 0; 110 | #pragma endregion 111 | 112 | // dialog handler 113 | #pragma region DialogHandler 114 | virtual bool onFileDialog(CefRefPtr& browser, 115 | CefBrowserHost::FileDialogMode mode, 116 | const CefString& title, 117 | const CefString& default_file_path, 118 | const std::vector& accept_filters, 119 | #if CEF_VERSION_MAJOR < 102 120 | int selected_accept_filter, 121 | #endif 122 | CefRefPtr& callback) 123 | { 124 | return false; 125 | }; 126 | #pragma endregion 127 | 128 | // display handler 129 | #pragma region DisplayHandler 130 | virtual void addressChanged(CefRefPtr& browser, CefRefPtr& frame, const CefString& url) = 0; 131 | 132 | virtual void titleChanged(CefRefPtr& browser, const CefString& title) = 0; 133 | 134 | virtual void faviconURLChanged(CefRefPtr& browser, const std::vector& icon_urls) = 0; 135 | 136 | virtual bool tooltipMessage(CefRefPtr& browser, const CefString& text) = 0; 137 | 138 | virtual void fullscreenModeChanged(CefRefPtr& browser, bool fullscreen) = 0; 139 | 140 | virtual void statusMessage(CefRefPtr& browser, const CefString& value) = 0; 141 | 142 | virtual void loadingProgressChanged(CefRefPtr& browser, double progress) = 0; 143 | 144 | virtual void consoleMessage(CefRefPtr& browser, const CefString& message, int level) = 0; 145 | 146 | virtual bool cursorChanged(CefRefPtr& browser, 147 | CefCursorHandle cursor, 148 | cef_cursor_type_t type, 149 | const CefCursorInfo& custom_cursor_info) = 0; 150 | #pragma endregion 151 | 152 | // download hander 153 | #pragma region DownloadHandler 154 | virtual void onBeforeDownload(CefRefPtr& browser, 155 | CefRefPtr& download_item, 156 | const CefString& suggested_name, 157 | CefRefPtr& callback) = 0; 158 | 159 | virtual void onDownloadUpdated(CefRefPtr& browser, 160 | CefRefPtr& download_item, 161 | CefRefPtr& callback) = 0; 162 | #pragma endregion 163 | 164 | // drag hander 165 | #pragma region DragHandler 166 | virtual bool onDragEnter(CefRefPtr& browser, 167 | CefRefPtr& dragData, 168 | CefDragHandler::DragOperationsMask mask) 169 | { 170 | return true; 171 | } 172 | 173 | virtual void draggableRegionChanged(CefRefPtr& browser, 174 | CefRefPtr& frame, 175 | const std::vector& regions) = 0; 176 | #pragma endregion 177 | 178 | // focus handler 179 | #pragma region FocusHandler 180 | virtual void takeFocus(CefRefPtr& browser, bool next) = 0; 181 | 182 | virtual bool setFocus(CefRefPtr& browser) = 0; 183 | 184 | virtual void gotFocus(CefRefPtr& browser) = 0; 185 | #pragma endregion 186 | 187 | // JS dialog handler 188 | #pragma region JSDialogHandler 189 | virtual bool onJSDialog(CefRefPtr& browser, 190 | const CefString& origin_url, 191 | CefJSDialogHandler::JSDialogType dialog_type, 192 | const CefString& message_text, 193 | const CefString& default_prompt_text, 194 | CefRefPtr& callback, 195 | bool& suppress_message) = 0; 196 | 197 | virtual bool onBeforeUnloadDialog(CefRefPtr& browser, 198 | const CefString& message_text, 199 | bool is_reload, 200 | CefRefPtr& callback) = 0; 201 | virtual void onResetDialogState(CefRefPtr& browser) = 0; 202 | virtual void onDialogClosed(CefRefPtr& browser) = 0; 203 | #pragma endregion 204 | 205 | // keyboard handler 206 | #pragma region KeyboardHandler 207 | virtual bool onPreKeyEvent(CefRefPtr& browser, 208 | const CefKeyEvent& event, 209 | CefEventHandle os_event, 210 | bool* is_keyboard_shortcut) = 0; 211 | 212 | virtual bool onKeyEvent(CefRefPtr& browser, const CefKeyEvent& event, CefEventHandle os_event) = 0; 213 | #pragma endregion 214 | 215 | // life span handler 216 | #pragma region LifeSpanHandler 217 | virtual bool onBeforePopup(CefRefPtr& browser, 218 | CefRefPtr& frame, 219 | const CefString& targetUrl, 220 | const CefString& targetFrameName, 221 | CefLifeSpanHandler::WindowOpenDisposition targetDisposition, 222 | CefWindowInfo& windowInfo, 223 | CefBrowserSettings& settings, 224 | bool& DisableJavascriptAccess) = 0; 225 | virtual void onAfterCreate(CefRefPtr& browser) = 0; 226 | 227 | virtual bool doClose(CefRefPtr& browser) = 0; 228 | 229 | virtual bool requestClose(CefRefPtr& browser) = 0; 230 | 231 | virtual void onBeforeClose(CefRefPtr& browser) = 0; 232 | #pragma endregion 233 | 234 | // load handler 235 | #pragma region LoadHandler 236 | virtual void loadingStateChanged(CefRefPtr& browser, 237 | bool isLoading, 238 | bool canGoBack, 239 | bool canGoForward) = 0; 240 | 241 | virtual void loadStart(CefRefPtr& browser, CefRefPtr& frame, int transition_type) = 0; 242 | 243 | virtual void loadEnd(CefRefPtr& browser, CefRefPtr& frame, int httpStatusCode) = 0; 244 | 245 | virtual void loadError(CefRefPtr& browser, 246 | CefRefPtr& frame, 247 | int errorCode, 248 | const CefString& errorMsg, 249 | const CefString& failedUrl, 250 | bool& handled) = 0; 251 | #pragma endregion 252 | 253 | // Off screen rendering 254 | #pragma region RenderHandler 255 | virtual bool getRootScreenRect(CefRefPtr& browser, CefRect& rect) { return false; } 256 | virtual void getViewRect(CefRefPtr& browser, CefRect& rect) {} 257 | virtual bool getScreenPoint(CefRefPtr& browser, int viewX, int viewY, int& screenX, int& screenY) 258 | { 259 | return false; 260 | } 261 | virtual bool getScreenInfo(CefRefPtr& browser, CefScreenInfo& screen_info) { return false; } 262 | virtual void onPopupShow(CefRefPtr& browser, bool show) {} 263 | virtual void onPopupSize(CefRefPtr& browser, const CefRect& rect) {} 264 | virtual void onPaint(CefRefPtr& browser, 265 | CefRenderHandler::PaintElementType type, 266 | const CefRenderHandler::RectList& dirtyRects, 267 | const void* buffer, 268 | int width, 269 | int height) 270 | { 271 | } 272 | #if CEF_VERSION_MAJOR < 124 273 | virtual void onAcceleratedPaint(CefRefPtr& browser, 274 | CefRenderHandler::PaintElementType type, 275 | const CefRenderHandler::RectList& dirtyRects, 276 | void* shared_handle) 277 | { 278 | } 279 | #else 280 | virtual void onAcceleratedPaint(CefRefPtr& browser, 281 | CefRenderHandler::PaintElementType type, 282 | const CefRenderHandler::RectList& dirtyRects, 283 | const CefAcceleratedPaintInfo& info) 284 | { 285 | } 286 | #endif 287 | virtual bool startDragging(CefRefPtr& browser, 288 | CefRefPtr& drag_data, 289 | CefRenderHandler::DragOperationsMask allowed_ops, 290 | int x, 291 | int y) 292 | { 293 | return false; 294 | } 295 | virtual void updateDragCursor(CefRefPtr& browser, CefRenderHandler::DragOperation operation) {} 296 | virtual void onScrollOffsetChanged(CefRefPtr& browser, double x, double y) {} 297 | virtual void onImeCompositionRangeChanged(CefRefPtr& browser, 298 | const CefRange& selected_range, 299 | const CefRenderHandler::RectList& character_bounds) 300 | { 301 | } 302 | virtual void onTextSelectionChanged(CefRefPtr& browser, 303 | const CefString& selected_text, 304 | const CefRange& selected_range) 305 | { 306 | } 307 | virtual void onVirtualKeyboardRequested(CefRefPtr& browser, CefRenderHandler::TextInputMode input_mode) {} 308 | #pragma endregion 309 | }; 310 | 311 | #endif 312 | -------------------------------------------------------------------------------- /include/CefViewCoreGlobal.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewCoreGlobal.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2023/5/30. 6 | // 7 | 8 | #ifndef CefViewCoreGlobal_h 9 | #define CefViewCoreGlobal_h 10 | #pragma once 11 | 12 | #pragma region stl_headers 13 | #include 14 | #include 15 | #pragma endregion 16 | 17 | #pragma region cef_headers 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #pragma endregion 26 | 27 | #if CEF_VERSION_MAJOR < 122 28 | using CefFrameId = int64_t; 29 | #else 30 | using CefFrameId = CefString; 31 | 32 | template<> 33 | struct std::hash 34 | { 35 | std::size_t operator()(const CefFrameId& k) const 36 | { 37 | using std::hash; 38 | using std::string; 39 | return std::hash()(k.ToString()); 40 | } 41 | }; 42 | #endif // CEF_VERSION_MAJOR < 122 43 | 44 | #endif // CefViewCoreGlobal_h 45 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # CefViewCore 2 | 3 | CefViewCore is the core abstraction layer of CefView projects. The QCefView and CocoaCefView are both based on the CefViewCore. In ther future there would be more CefView projects with different languange bindings or platform supports. 4 | 5 | CefViewCore was written in only C++ (minor Objective-C code is used in CefViewWing application for macOS) so that it could be a common base layer for the other high level projects. 6 | 7 |
8 | 9 |
10 | CefView Stack 11 |
12 | 13 | ## Build status 14 | | triplets | status | 15 | |---|---| 16 | | Windows-x64 | [![Build on Windows](https://github.com/CefView/CefViewCore/actions/workflows/build-windows-x86_64.yml/badge.svg)](https://github.com/CefView/CefViewCore/actions/workflows/build-windows-x86_64.yml) | 17 | | macOS-x64 | [![Build on macOS](https://github.com/CefView/CefViewCore/actions/workflows/build-macos-x86_64.yml/badge.svg)](https://github.com/CefView/CefViewCore/actions/workflows/build-macos-x86_64.yml) | 18 | | Linux-x64 | [![Build on Linux](https://github.com/CefView/CefViewCore/actions/workflows/build-linux-x86_64.yml/badge.svg)](https://github.com/CefView/CefViewCore/actions/workflows/build-linux-x86_64.yml) | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE CefViewCore_SHARED_SRC_FILES 2 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared/*.cpp" 3 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared/*.h" 4 | ) 5 | source_group( 6 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/Shared" 7 | PREFIX Shared 8 | FILES ${CefViewCore_SHARED_SRC_FILES} 9 | ) 10 | 11 | # ## CefViewCore 12 | # ############################################################################################### 13 | # header files 14 | file(GLOB_RECURSE CefViewCore_INCLUDE_FILES 15 | "${CMAKE_CURRENT_SOURCE_DIR}/../include/*.h" 16 | ) 17 | source_group( 18 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/../include" 19 | PREFIX Include 20 | FILES ${CefViewCore_INCLUDE_FILES} 21 | ) 22 | 23 | # soruce code for all platforms 24 | file(GLOB_RECURSE CefViewCore_SRC_FILES 25 | "${CMAKE_CURRENT_SOURCE_DIR}/CefView/CefBrowserApp/*.h" 26 | "${CMAKE_CURRENT_SOURCE_DIR}/CefView/CefBrowserApp/*.cpp" 27 | ) 28 | source_group( 29 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/CefView/CefBrowserApp" 30 | PREFIX Source 31 | FILES ${CefViewCore_SRC_FILES} 32 | ) 33 | 34 | add_library(CefViewCore STATIC 35 | ${CefViewCore_SHARED_SRC_FILES} 36 | ${CefViewCore_INCLUDE_FILES} 37 | ${CefViewCore_SRC_FILES} 38 | ) 39 | 40 | target_include_directories(CefViewCore 41 | PUBLIC 42 | ${CefViewCore_INCLUDE_PATH} 43 | PRIVATE 44 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared" 45 | ) 46 | 47 | # ADD_LOGICAL_TARGET(libcef_lib 48 | # "${CEF_LIB_DEBUG}" 49 | # "${CEF_LIB_RELEASE}" 50 | # ) 51 | add_library(libcef_lib ${CEF_LIBTYPE} IMPORTED GLOBAL) 52 | set_target_properties(libcef_lib 53 | PROPERTIES 54 | IMPORTED_LOCATION "${CEF_LIB_RELEASE}" 55 | IMPORTED_LOCATION_DEBUG "${CEF_LIB_DEBUG}" 56 | IMPORTED_LOCATION_RELEASE "${CEF_LIB_RELEASE}" 57 | ) 58 | 59 | if(OS_WINDOWS) 60 | SET_LIBRARY_TARGET_PROPERTIES(CefViewCore) 61 | 62 | add_dependencies(CefViewCore 63 | libcef_lib 64 | libcef_dll_wrapper 65 | ) 66 | 67 | set(CefViewCore_LIBS 68 | libcef_lib 69 | libcef_dll_wrapper 70 | ${CEF_STANDARD_LIBS} 71 | ) 72 | 73 | if(USE_SANDBOX) 74 | list(APPEND CefViewCore_LIBS cef_sandbox_lib) 75 | endif() 76 | 77 | target_link_libraries(CefViewCore 78 | PUBLIC 79 | ${CefViewCore_LIBS} 80 | ) 81 | endif() # OS_WINDOWS 82 | 83 | if(OS_LINUX) 84 | SET_LIBRARY_TARGET_PROPERTIES(CefViewCore) 85 | 86 | add_dependencies(CefViewCore 87 | libcef_lib 88 | libcef_dll_wrapper 89 | ) 90 | 91 | set(CefViewCore_LIBS 92 | libcef_lib 93 | libcef_dll_wrapper 94 | ${CEF_STANDARD_LIBS} 95 | ) 96 | 97 | target_link_libraries(CefViewCore 98 | PUBLIC 99 | ${CefViewCore_LIBS} 100 | ) 101 | endif() # OS_LINUX 102 | 103 | if(OS_MACOS) 104 | file(GLOB_RECURSE CefViewCore_PUBLIC_HEADERS 105 | "${CMAKE_CURRENT_SOURCE_DIR}/../include/*.h" 106 | ) 107 | 108 | target_compile_options(CefViewCore 109 | PRIVATE 110 | "-fobjc-arc" 111 | ) 112 | 113 | SET_LIBRARY_TARGET_PROPERTIES(CefViewCore) 114 | 115 | set_target_properties(CefViewCore 116 | PROPERTIES 117 | FRAMEWORK TRUE 118 | PUBLIC_HEADER "${CefViewCore_PUBLIC_HEADERS}" 119 | CLANG_ENABLE_OBJC_ARC "YES" 120 | APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc" 121 | XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "gnu++11" # -std=gnu++11 122 | XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME "NO" # -fno-objc-link-runtime 123 | XCODE_ATTRIBUTE_COPY_PHASE_STRIP "NO" 124 | XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release] "YES" # -Wl,-dead_strip 125 | XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD "c99" # -std=c99 126 | XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.cefview.cefview" 127 | ) 128 | 129 | add_dependencies(CefViewCore 130 | libcef_dll_wrapper 131 | ) 132 | 133 | set(CefViewCore_LIBS 134 | libcef_dll_wrapper 135 | ${CEF_STANDARD_LIBS} 136 | ) 137 | 138 | if(USE_SANDBOX) 139 | list(APPEND CefViewCore_LIBS cef_sandbox_lib) 140 | endif() 141 | 142 | target_link_libraries(CefViewCore 143 | PUBLIC 144 | ${CefViewCore_LIBS} 145 | ) 146 | endif() # OS_MACOS 147 | 148 | add_library(CefViewCore::CefViewCore ALIAS CefViewCore) 149 | 150 | # ## CefViewWing 151 | # ############################################################################################### 152 | # soruce code for all platforms 153 | file(GLOB_RECURSE CefViewWing_SRC_FILES 154 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/App/*.h" 155 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/App/*.cpp" 156 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/Bridge/*.h" 157 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/Bridge/*.cpp" 158 | ) 159 | source_group( 160 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/CefWing" 161 | PREFIX Source 162 | FILES ${CefViewWing_SRC_FILES} 163 | ) 164 | 165 | if(OS_WINDOWS) 166 | file(GLOB_RECURSE CefViewWing_PLATFORM_SRC_FILES 167 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/win/*.h" 168 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/win/*.cpp" 169 | ) 170 | source_group( 171 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/win" 172 | PREFIX Source 173 | FILES ${CefViewWing_PLATFORM_SRC_FILES} 174 | ) 175 | 176 | if(EXISTS ${CEFVIEW_WING_ICON}) 177 | # Copy icon file to binary dir 178 | configure_file( 179 | "${CEFVIEW_WING_ICON}" 180 | "${CMAKE_CURRENT_BINARY_DIR}/app.ico" 181 | COPYONLY 182 | ) 183 | 184 | # Config resource file 185 | configure_file( 186 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/win/resource.rc.in" 187 | "${CMAKE_CURRENT_BINARY_DIR}/resource.rc" 188 | COPYONLY 189 | ) 190 | set(CefViewWing_WIN_RESOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/resource.rc") 191 | else() 192 | set(CefViewWing_WIN_RESOURCE_FILE "") 193 | endif() 194 | 195 | # Create Helper executable target. 196 | add_executable(${CEFVIEW_WING_NAME} WIN32 197 | ${CefViewCore_SHARED_SRC_FILES} 198 | ${CefViewWing_SRC_FILES} 199 | ${CefViewWing_PLATFORM_SRC_FILES} 200 | ${CefViewWing_WIN_RESOURCE_FILE} 201 | ) 202 | 203 | SET_EXECUTABLE_TARGET_PROPERTIES(${CEFVIEW_WING_NAME}) 204 | target_link_options(${CEFVIEW_WING_NAME} 205 | PRIVATE 206 | "/MANIFEST" 207 | ) 208 | 209 | target_include_directories(${CEFVIEW_WING_NAME} 210 | PUBLIC 211 | ${CefViewCore_INCLUDE_PATH} 212 | PRIVATE 213 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared" 214 | ) 215 | 216 | add_dependencies(${CEFVIEW_WING_NAME} 217 | libcef_lib 218 | libcef_dll_wrapper 219 | ) 220 | 221 | set(_helper_libs 222 | d3d11.lib 223 | glu32.lib 224 | imm32.lib 225 | opengl32.lib 226 | 227 | libcef_lib 228 | libcef_dll_wrapper 229 | ${CEF_STANDARD_LIBS} 230 | ${CEF_SANDBOX_STANDARD_LIBS} 231 | ) 232 | 233 | if(USE_SANDBOX) 234 | list(APPEND _helper_libs cef_sandbox_lib) 235 | endif() 236 | 237 | target_link_libraries(${CEFVIEW_WING_NAME} 238 | ${_helper_libs} 239 | ) 240 | 241 | # Add the Helper as a dependency of the main executable target. 242 | add_dependencies(CefViewCore ${CEFVIEW_WING_NAME}) 243 | 244 | add_custom_command(TARGET ${CEFVIEW_WING_NAME} 245 | POST_BUILD 246 | 247 | # embed the manifest file 248 | COMMAND mt.exe 249 | -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\CefWing\\win\\CefViewWing.manifest\" 250 | -outputresource:\"$\" 251 | 252 | # copy cef binary files 253 | # .1 copy the cef resources to output dir 254 | COMMAND ${CMAKE_COMMAND} -E copy_directory 255 | "${CEF_RESOURCE_DIR}" 256 | "$" 257 | 258 | # copy all cef binary files to output dir 259 | COMMAND ${CMAKE_COMMAND} -E copy_directory 260 | "${CEF_BINARY_DIR}" 261 | "$" 262 | 263 | # move libcef.lib to lib output 264 | COMMAND ${CMAKE_COMMAND} -E rename 265 | "$/libcef.lib" 266 | "$/libcef.lib" 267 | 268 | # move cef_sandbox.lib to lib output 269 | COMMAND ${CMAKE_COMMAND} -E rename 270 | "$/cef_sandbox.lib" 271 | "$/cef_sandbox.lib" 272 | ) 273 | endif() # OS_WINDOWS 274 | 275 | if(OS_LINUX) 276 | file(GLOB_RECURSE CefViewWing_PLATFORM_SRC_FILES 277 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/linux/*.h" 278 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/linux/*.cpp" 279 | ) 280 | source_group( 281 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/linux" 282 | PREFIX Source 283 | FILES ${CefViewWing_PLATFORM_SRC_FILES} 284 | ) 285 | 286 | # Create Helper executable target. 287 | add_executable(${CEFVIEW_WING_NAME} 288 | ${CefViewCore_SHARED_SRC_FILES} 289 | ${CefViewWing_SRC_FILES} 290 | ${CefViewWing_PLATFORM_SRC_FILES} 291 | ) 292 | 293 | SET_EXECUTABLE_TARGET_PROPERTIES(${CEFVIEW_WING_NAME}) 294 | 295 | set_target_properties(${CEFVIEW_WING_NAME} 296 | PROPERTIES 297 | INSTALL_RPATH "$ORIGIN" 298 | BUILD_WITH_INSTALL_RPATH TRUE 299 | ) 300 | 301 | target_include_directories(${CEFVIEW_WING_NAME} 302 | PUBLIC 303 | ${CefViewCore_INCLUDE_PATH} 304 | PRIVATE 305 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared" 306 | ) 307 | 308 | add_dependencies(${CEFVIEW_WING_NAME} 309 | libcef_lib 310 | libcef_dll_wrapper 311 | ) 312 | 313 | set(_helper_libs 314 | libcef_lib 315 | libcef_dll_wrapper 316 | ${CEF_STANDARD_LIBS} 317 | ) 318 | 319 | target_link_libraries(${CEFVIEW_WING_NAME} 320 | ${_helper_libs} 321 | ) 322 | 323 | # Add the Helper as a dependency of the main executable target. 324 | add_dependencies(CefViewCore ${CEFVIEW_WING_NAME}) 325 | 326 | # copy cef binary files 327 | add_custom_command(TARGET ${CEFVIEW_WING_NAME} 328 | POST_BUILD 329 | 330 | # copy cef binary files 331 | # .1 copy the cef resources to output dir 332 | COMMAND ${CMAKE_COMMAND} -E copy_directory 333 | "${CEF_RESOURCE_DIR}" 334 | "$" 335 | 336 | # copy all cef binary files to output dir 337 | COMMAND ${CMAKE_COMMAND} -E copy_directory 338 | "${CEF_BINARY_DIR}" 339 | "$" 340 | ) 341 | 342 | SET_LINUX_SUID_PERMISSIONS(${CEFVIEW_WING_NAME} "$/chrome-sandbox") 343 | endif() # OS_LINUX 344 | 345 | if(OS_MACOS) 346 | file(GLOB_RECURSE CefViewWing_PLATFORM_SRC_FILES 347 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/*.h" 348 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/*.m" 349 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/*.mm" 350 | "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/*.cpp" 351 | ) 352 | source_group( 353 | TREE "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac" 354 | PREFIX Source 355 | FILES ${CefViewWing_PLATFORM_SRC_FILES} 356 | ) 357 | 358 | set(CefViewWing_LIBS 359 | libcef_dll_wrapper 360 | ${CEF_STANDARD_LIBS} 361 | ) 362 | 363 | if(USE_SANDBOX) 364 | list(APPEND CefViewWing_LIBS cef_sandbox_lib) 365 | endif() 366 | 367 | # Create the multiple Helper app bundle targets. 368 | foreach(_suffix_list ${CEF_HELPER_APP_SUFFIXES}) 369 | # Convert to a list and extract the suffix values. 370 | string(REPLACE ":" ";" _suffix_list ${_suffix_list}) 371 | list(GET _suffix_list 0 _name_suffix) 372 | list(GET _suffix_list 1 _target_suffix) 373 | list(GET _suffix_list 2 _plist_suffix) 374 | 375 | # Define Helper target and output names. 376 | set(_helper_target "${CEFVIEW_WING_NAME}${_target_suffix}") 377 | set(_helper_output_name "${CEFVIEW_WING_NAME}${_name_suffix}") 378 | 379 | # Create Helper executable target. 380 | add_executable(${_helper_target} MACOSX_BUNDLE 381 | ${CefViewCore_SHARED_SRC_FILES} 382 | ${CefViewWing_SRC_FILES} 383 | ${CefViewWing_PLATFORM_SRC_FILES} 384 | ) 385 | SET_EXECUTABLE_TARGET_PROPERTIES(${_helper_target}) 386 | 387 | set(_helper_info_plist "${CMAKE_CURRENT_BINARY_DIR}/helper-Info${_target_suffix}.plist") 388 | file(READ "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/info.plist" _plist_contents) 389 | file(WRITE ${_helper_info_plist} ${_plist_contents}) 390 | 391 | set_target_properties(${_helper_target} 392 | PROPERTIES 393 | CLANG_ENABLE_OBJC_ARC "YES" 394 | OUTPUT_NAME "${_helper_output_name}" 395 | MACOSX_BUNDLE_INFO_PLIST "${_helper_info_plist}" 396 | XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.cefview.${CEFVIEW_WING_NAME}${_plist_suffix}" 397 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES" 398 | XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/CefWing/mac/CefViewWing.entitlements" 399 | ) 400 | 401 | target_include_directories(${_helper_target} 402 | PUBLIC 403 | ${CefViewCore_INCLUDE_PATH} 404 | PRIVATE 405 | "${CMAKE_CURRENT_SOURCE_DIR}/Shared" 406 | ) 407 | 408 | add_dependencies(${_helper_target} 409 | libcef_dll_wrapper 410 | ) 411 | 412 | target_link_libraries(${_helper_target} 413 | ${CefViewWing_LIBS} 414 | ) 415 | 416 | # Add the Helper as a dependency of the main executable target. 417 | add_dependencies(CefViewCore ${_helper_target}) 418 | endforeach() 419 | 420 | # copy cef binary files to the output folder 421 | add_custom_command(TARGET ${CEFVIEW_WING_NAME} 422 | POST_BUILD 423 | 424 | # copy the cef framework to output directory 425 | COMMAND ${CMAKE_COMMAND} -E copy_directory 426 | "${CEF_BINARY_DIR}/Chromium Embedded Framework.framework" 427 | "$/../Chromium Embedded Framework.framework" 428 | VERBATIM 429 | ) 430 | endif() # OS_MACOS 431 | 432 | # add alias for heper process target 433 | add_executable(CefViewCore::CefViewWing ALIAS ${CEFVIEW_WING_NAME}) 434 | -------------------------------------------------------------------------------- /src/CefVersion.h.in: -------------------------------------------------------------------------------- 1 | // 2 | // CefVersion.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2025/1/19. 6 | // This file was generated during CMake configuring. 7 | // Do not edit this file directly by manual. 8 | // Edit the CefVersion.h.in and then re-config project with CMake. 9 | // 10 | 11 | #ifndef CefVersion_h 12 | #define CefVersion_h 13 | #pragma once 14 | 15 | // clang-format off 16 | #define CEF_VERSION "@CEF_VERSION@" 17 | #define CEF_VERSION_MAJOR @CEF_VERSION_MAJOR@ 18 | #define CEF_VERSION_MINOR @CEF_VERSION_MINOR@ 19 | #define CEF_VERSION_PATCH @CEF_VERSION_PATCH@ 20 | #define CEF_COMMIT_NUMBER @CEF_COMMIT_NUMBER@ 21 | #define CEF_COMMIT_HASH "@CEF_COMMIT_HASH@" 22 | // clang-format on 23 | 24 | #endif // CefVersion -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserApp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region cef_headers 4 | #include 5 | #pragma endregion 6 | 7 | #pragma region stl_headers 8 | #include 9 | #include 10 | #pragma endregion 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include "CefViewSchemeHandler/CefViewSchemeHandlerFactory.h" 17 | 18 | CefViewBrowserApp::CefViewBrowserApp(const CefString& scheme_name, 19 | const CefString& bridge_name, 20 | CefViewBrowserAppDelegateInterface::RefPtr delegate) 21 | : builtin_scheme_name_(scheme_name.empty() ? kCefViewDefaultBuiltinSchemaName : scheme_name) 22 | , bridge_object_name_(bridge_name.empty() ? kCefViewDefaultBridgeObjectName : bridge_name) 23 | , app_delegate_(delegate) 24 | { 25 | } 26 | 27 | CefViewBrowserApp::~CefViewBrowserApp() 28 | { 29 | logD("CefViewBrowserApp::~CefViewBrowserApp"); 30 | } 31 | 32 | void 33 | CefViewBrowserApp::CheckInClient(void* ctx, const CefViewBrowserClientDelegateInterface::RefPtr& handler) 34 | { 35 | client_handler_map_[ctx] = handler; 36 | } 37 | 38 | void 39 | CefViewBrowserApp::CheckOutClient(void* ctx) 40 | { 41 | client_handler_map_.erase(ctx); 42 | } 43 | 44 | CefViewBrowserClientDelegateInterface::RefPtr 45 | CefViewBrowserApp::GetClientHandler(void* ctx) 46 | { 47 | if (client_handler_map_.count(ctx)) { 48 | return client_handler_map_[ctx].lock(); 49 | } 50 | return nullptr; 51 | } 52 | 53 | void 54 | CefViewBrowserApp::AddLocalFolderResource(const CefString& path, const CefString& url, int priority /*= 0*/) 55 | { 56 | folderResourceMappingList_.emplace_back(FolderResourceMapping{ path, url, priority }); 57 | } 58 | 59 | const std::list& 60 | CefViewBrowserApp::FolderResourceMappingList() 61 | { 62 | return folderResourceMappingList_; 63 | } 64 | 65 | void 66 | CefViewBrowserApp::AddArchiveResource(const CefString& path, 67 | const CefString& url, 68 | const CefString& password /*= ""*/, 69 | int priority /*= 0*/) 70 | { 71 | archiveResourceMappingList_.emplace_back(ArchiveResourceMapping{ path, url, password, priority }); 72 | } 73 | 74 | const std::list& 75 | CefViewBrowserApp::ArchiveResourceMappingList() 76 | { 77 | return archiveResourceMappingList_; 78 | } 79 | 80 | bool 81 | CefViewBrowserApp::AddGlobalCookie(const CefString& name, 82 | const CefString& value, 83 | const CefString& domain, 84 | const CefString& url) 85 | { 86 | CefCookie cookie; 87 | CefString(&cookie.name) = name; 88 | CefString(&cookie.value) = value; 89 | CefString(&cookie.domain) = domain; 90 | return CefCookieManager::GetGlobalManager(nullptr)->SetCookie(CefString(url), cookie, nullptr); 91 | } 92 | 93 | bool 94 | CefViewBrowserApp::DeleteAllCookies() 95 | { 96 | return CefCookieManager::GetGlobalManager(nullptr)->DeleteCookies(CefString(), CefString(), nullptr); 97 | } 98 | 99 | bool 100 | CefViewBrowserApp::AddCrossOriginWhitelistEntry(const CefString& sourceOrigin, 101 | const CefString& targetSchema, 102 | const CefString& targetDomain, 103 | bool allowTargetSubdomains) 104 | { 105 | return CefAddCrossOriginWhitelistEntry(sourceOrigin, targetSchema, targetDomain, allowTargetSubdomains); 106 | } 107 | 108 | bool 109 | CefViewBrowserApp::RemoveCrossOriginWhitelistEntry(const CefString& sourceOrigin, 110 | const CefString& targetSchema, 111 | const CefString& targetDomain, 112 | bool allowTargetSubdomains) 113 | { 114 | return CefRemoveCrossOriginWhitelistEntry(sourceOrigin, targetSchema, targetDomain, allowTargetSubdomains); 115 | } 116 | 117 | bool 118 | CefViewBrowserApp::ClearCrossOriginWhitelistEntry() 119 | { 120 | return CefClearCrossOriginWhitelist(); 121 | } 122 | 123 | bool 124 | CefViewBrowserApp::IsSafeToExit() 125 | { 126 | return client_handler_map_.empty(); 127 | } 128 | 129 | ////////////////////////////////////////////////////////////////////////// 130 | void 131 | CefViewBrowserApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr command_line) 132 | { 133 | auto delegate = app_delegate_.lock(); 134 | if (delegate) 135 | delegate->onBeforeCommandLineProcessing(process_type, command_line); 136 | } 137 | 138 | void 139 | CefViewBrowserApp::OnRegisterCustomSchemes(CefRawPtr registrar) 140 | { 141 | if (registrar) { 142 | // register custom scheme 143 | int options = 0 // 144 | | CEF_SCHEME_OPTION_STANDARD // 145 | | CEF_SCHEME_OPTION_SECURE // 146 | | CEF_SCHEME_OPTION_CORS_ENABLED // 147 | | CEF_SCHEME_OPTION_FETCH_ENABLED // 148 | | 0; 149 | if (!registrar->AddCustomScheme(builtin_scheme_name_, options)) { 150 | logE("faield to add built-in scheme: %s", builtin_scheme_name_.c_str()); 151 | } 152 | } 153 | } 154 | 155 | CefRefPtr 156 | CefViewBrowserApp::GetResourceBundleHandler() 157 | { 158 | return nullptr; 159 | } 160 | 161 | CefRefPtr 162 | CefViewBrowserApp::GetBrowserProcessHandler() 163 | { 164 | return this; 165 | } 166 | 167 | CefRefPtr 168 | CefViewBrowserApp::GetRenderProcessHandler() 169 | { 170 | return nullptr; 171 | } 172 | 173 | ////////////////////////////////////////////////////////////////////////// 174 | void 175 | CefViewBrowserApp::OnContextInitialized() 176 | { 177 | CEF_REQUIRE_UI_THREAD(); 178 | 179 | // register custom scheme and handler 180 | CefRegisterSchemeHandlerFactory(builtin_scheme_name_, "", new CefViewSchemeHandlerFactory(this)); 181 | } 182 | 183 | void 184 | CefViewBrowserApp::OnBeforeChildProcessLaunch(CefRefPtr command_line) 185 | { 186 | auto delegate = app_delegate_.lock(); 187 | if (delegate) 188 | delegate->onBeforeChildProcessLaunch(command_line); 189 | 190 | if (bridge_object_name_.empty()) 191 | bridge_object_name_ = kCefViewDefaultBridgeObjectName; 192 | command_line->AppendSwitchWithValue(kCefViewBridgeObjectNameKey, bridge_object_name_); 193 | 194 | if (builtin_scheme_name_.empty()) 195 | builtin_scheme_name_ = kCefViewBuiltinSchemeNameKey; 196 | command_line->AppendSwitchWithValue(kCefViewBuiltinSchemeNameKey, bridge_object_name_); 197 | } 198 | 199 | void 200 | CefViewBrowserApp::OnScheduleMessagePumpWork(int64_t delay_ms) 201 | { 202 | auto delegate = app_delegate_.lock(); 203 | 204 | if (delegate) 205 | delegate->onScheduleMessageLoopWork(delay_ms); 206 | } 207 | 208 | CefRefPtr 209 | CefViewBrowserApp::GetDefaultClient() 210 | { 211 | return nullptr; 212 | } 213 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | #include 12 | 13 | #include "CefViewQueryHandler/CefViewQueryHandler.h" 14 | 15 | CefViewBrowserClient::CefViewBrowserClient(CefRefPtr app, 16 | CefViewBrowserClientDelegateInterface::RefPtr delegate) 17 | : app_(app) 18 | , client_delegate_(delegate) 19 | , is_closing_(false) 20 | , close_by_native_(false) 21 | , initial_navigation_(true) 22 | , message_router_(nullptr) 23 | , message_router_handler_(nullptr) 24 | , resource_manager_(new CefResourceManager()) 25 | { 26 | app_->CheckInClient(this, delegate); 27 | 28 | for (auto& folderMapping : app_->FolderResourceMappingList()) { 29 | AddLocalDirectoryResourceProvider(folderMapping.path, folderMapping.url, folderMapping.priority); 30 | } 31 | 32 | for (auto& archiveMapping : app_->ArchiveResourceMappingList()) { 33 | AddArchiveResourceProvider( 34 | archiveMapping.path, archiveMapping.url, archiveMapping.password, archiveMapping.priority); 35 | } 36 | 37 | // Create the browser-side router for query handling. 38 | message_router_config_.js_query_function = kCefViewQueryFuntionName; 39 | message_router_config_.js_cancel_function = kCefViewQueryCancelFunctionName; 40 | } 41 | 42 | CefViewBrowserClient::~CefViewBrowserClient() 43 | { 44 | log_debug("CefViewBrowserClient::~CefViewBrowserClient()"); 45 | 46 | app_->CheckOutClient(this); 47 | } 48 | 49 | void 50 | CefViewBrowserClient::CloseAllBrowsers() 51 | { 52 | close_by_native_ = true; 53 | auto browsers = browser_map_; 54 | for (auto& kv : browsers) { 55 | kv.second->StopLoad(); 56 | kv.second->GetHost()->CloseBrowser(true); 57 | } 58 | } 59 | 60 | void 61 | CefViewBrowserClient::AddLocalDirectoryResourceProvider(const CefString& dir_path, 62 | const CefString& url, 63 | int priority /* = 0*/) 64 | { 65 | if (dir_path.empty() || url.empty()) 66 | return; 67 | 68 | // convert to lower case 69 | auto lower_url = url.ToString(); 70 | std::transform( 71 | lower_url.begin(), lower_url.end(), lower_url.begin(), [](unsigned char c) { return std::tolower(c); }); 72 | 73 | std::string identifier; 74 | resource_manager_->AddDirectoryProvider(lower_url, dir_path, priority, identifier); 75 | } 76 | 77 | void 78 | CefViewBrowserClient::AddArchiveResourceProvider(const CefString& archive_path, 79 | const CefString& url, 80 | const CefString& password, 81 | int priority /*= 0*/) 82 | { 83 | if (archive_path.empty() || url.empty()) 84 | return; 85 | 86 | std::string identifier; 87 | resource_manager_->AddArchiveProvider(url, archive_path, password, 0, identifier); 88 | } 89 | 90 | bool 91 | CefViewBrowserClient::TriggerEvent(CefRefPtr browser, 92 | const CefFrameId& frame_id, 93 | const CefRefPtr msg) 94 | { 95 | if (msg->GetName().empty()) 96 | return false; 97 | 98 | if (browser) { 99 | std::vector frameIds; 100 | if (frame_id == CEFVIEW_MAIN_FRAME) { 101 | frameIds.push_back(browser->GetMainFrame()->GetIdentifier()); 102 | } else if (frame_id == CEFVIEW_ALL_FRAMES) { 103 | browser->GetFrameIdentifiers(frameIds); 104 | } else { 105 | frameIds.push_back(frame_id); 106 | } 107 | 108 | for (auto id : frameIds) { 109 | auto m = msg->Copy(); 110 | #if CEF_VERSION_MAJOR > 121 111 | auto frame = browser->GetFrameByIdentifier(id); 112 | #else 113 | auto frame = browser->GetFrame(id); 114 | #endif 115 | 116 | frame->SendProcessMessage(PID_RENDERER, m); 117 | } 118 | 119 | return true; 120 | } 121 | 122 | return false; 123 | } 124 | 125 | bool 126 | CefViewBrowserClient::ResponseQuery(const int64_t query, bool success, const CefString& response, int error) 127 | { 128 | if (message_router_handler_) 129 | return message_router_handler_->Response(query, success, response, error); 130 | 131 | return false; 132 | } 133 | 134 | bool 135 | CefViewBrowserClient::AsyncExecuteJSCode(CefRefPtr browser, 136 | CefRefPtr frame, 137 | const CefString& code, 138 | const CefString& url, 139 | const CefString& context) 140 | { 141 | /* 142 | * Javascript code: 143 | * 144 | * window.__cefview_report_js_result__(context, function() { ... })()); 145 | */ 146 | std::ostringstream codeWrapper; 147 | codeWrapper << "window." << kCefViewReportJSResultFunctionName // 148 | << "(" // 149 | << "\"" << context << "\", " // 150 | << "function(){" << code << " }()" // 151 | << ");"; 152 | 153 | frame->ExecuteJavaScript(codeWrapper.str().c_str(), url, 0); 154 | 155 | return true; 156 | } 157 | 158 | bool 159 | CefViewBrowserClient::DispatchRenderMessage(CefRefPtr browser, 160 | CefRefPtr frame, 161 | CefRefPtr message) 162 | { 163 | auto msgName = message->GetName(); 164 | if (msgName == kCefViewClientRenderFocusedNodeChangedMessage) { 165 | return OnRenderFocusedNodeChangedMessage(browser, frame, message); 166 | } else if (msgName == kCefViewClientRenderInvokeMethodMessage) { 167 | return OnRenderInvokeMethodMessage(browser, frame, message); 168 | } else if (msgName == kCefViewClientRenderReportJSResultMessage) { 169 | return OnRenderReportJSResultMessage(browser, frame, message); 170 | } else { 171 | } 172 | 173 | return false; 174 | } 175 | 176 | bool 177 | CefViewBrowserClient::OnRenderFocusedNodeChangedMessage(CefRefPtr browser, 178 | CefRefPtr frame, 179 | CefRefPtr message) 180 | { 181 | auto delegate = client_delegate_.lock(); 182 | if (!delegate) 183 | return false; 184 | 185 | // validate the argument list 186 | CefRefPtr arguments = message->GetArgumentList(); 187 | if (!arguments || (arguments->GetSize() < 1)) 188 | return false; 189 | 190 | if (CefValueType::VTYPE_BOOL != arguments->GetType(0)) 191 | return false; 192 | 193 | bool focusOnEditableField = message->GetArgumentList()->GetBool(0); 194 | delegate->focusedEditableNodeChanged(browser, frame, focusOnEditableField); 195 | 196 | return true; 197 | } 198 | 199 | bool 200 | CefViewBrowserClient::OnRenderInvokeMethodMessage(CefRefPtr browser, 201 | CefRefPtr frame, 202 | CefRefPtr message) 203 | { 204 | // validate the argument list 205 | CefRefPtr arguments = message->GetArgumentList(); 206 | if (!arguments || (arguments->GetSize() < 1)) 207 | return false; 208 | 209 | // validate the delegate 210 | auto delegate = client_delegate_.lock(); 211 | if (!delegate) 212 | return false; 213 | 214 | // copy the arguments 215 | arguments = arguments->Copy(); 216 | 217 | // validate the method name 218 | std::string method; 219 | if (CefValueType::VTYPE_STRING != arguments->GetType(0)) 220 | return false; 221 | method = arguments->GetString(0).ToString(); 222 | if (method.empty()) 223 | return false; 224 | arguments->Remove(0); 225 | 226 | delegate->invokeMethodNotify(browser, frame, method, arguments); 227 | 228 | return true; 229 | } 230 | 231 | bool 232 | CefViewBrowserClient::OnRenderReportJSResultMessage(CefRefPtr browser, 233 | CefRefPtr frame, 234 | CefRefPtr message) 235 | { 236 | // validate the argument list 237 | CefRefPtr arguments = message->GetArgumentList(); 238 | if (!arguments || (arguments->GetSize() != 2)) 239 | return false; 240 | 241 | // validate the delegate 242 | auto delegate = client_delegate_.lock(); 243 | if (!delegate) 244 | return false; 245 | 246 | // get context 247 | std::string context; 248 | if (CefValueType::VTYPE_STRING != arguments->GetType(0)) 249 | return false; 250 | context = arguments->GetString(0).ToString(); 251 | if (context.empty()) 252 | return false; 253 | 254 | // get script result 255 | auto result = arguments->GetValue(1); 256 | 257 | delegate->reportJSResult(browser, frame, context, result); 258 | 259 | return true; 260 | } 261 | 262 | bool 263 | CefViewBrowserClient::OnProcessMessageReceived(CefRefPtr browser, 264 | CefRefPtr frame, 265 | CefProcessId source_process, 266 | CefRefPtr message) 267 | { 268 | CEF_REQUIRE_UI_THREAD(); 269 | if (message_router_->OnProcessMessageReceived(browser, frame, source_process, message)) 270 | return true; 271 | 272 | if (DispatchRenderMessage(browser, frame, message)) 273 | return true; 274 | 275 | return false; 276 | } 277 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_ContextMenuHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetContextMenuHandler() 13 | { 14 | return this; 15 | } 16 | 17 | void 18 | CefViewBrowserClient::OnBeforeContextMenu(CefRefPtr browser, 19 | CefRefPtr frame, 20 | CefRefPtr params, 21 | CefRefPtr model) 22 | { 23 | CEF_REQUIRE_UI_THREAD(); 24 | 25 | auto delegate = client_delegate_.lock(); 26 | if (delegate) 27 | delegate->onBeforeContextMenu(browser, frame, params, model); 28 | } 29 | 30 | bool 31 | CefViewBrowserClient::RunContextMenu(CefRefPtr browser, 32 | CefRefPtr frame, 33 | CefRefPtr params, 34 | CefRefPtr model, 35 | CefRefPtr callback) 36 | { 37 | CEF_REQUIRE_UI_THREAD(); 38 | 39 | auto delegate = client_delegate_.lock(); 40 | if (delegate) 41 | return delegate->onRunContextMenu(browser, frame, params, model, callback); 42 | 43 | return false; 44 | } 45 | 46 | bool 47 | CefViewBrowserClient::OnContextMenuCommand(CefRefPtr browser, 48 | CefRefPtr frame, 49 | CefRefPtr params, 50 | int command_id, 51 | EventFlags event_flags) 52 | { 53 | CEF_REQUIRE_UI_THREAD(); 54 | 55 | auto delegate = client_delegate_.lock(); 56 | if (delegate) 57 | return delegate->onContextMenuCommand(browser, frame, params, command_id, event_flags); 58 | 59 | return false; 60 | } 61 | 62 | void 63 | CefViewBrowserClient::OnContextMenuDismissed(CefRefPtr browser, CefRefPtr frame) 64 | { 65 | CEF_REQUIRE_UI_THREAD(); 66 | 67 | auto delegate = client_delegate_.lock(); 68 | if (delegate) 69 | delegate->onContextMenuDismissed(browser, frame); 70 | } 71 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_DialogHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetDialogHandler() 13 | { 14 | return this; 15 | } 16 | 17 | #if CEF_VERSION_MAJOR < 102 18 | bool 19 | CefViewBrowserClient::OnFileDialog(CefRefPtr browser, 20 | FileDialogMode mode, 21 | const CefString& title, 22 | const CefString& default_file_path, 23 | const std::vector& accept_filters, 24 | int selected_accept_filter, 25 | CefRefPtr callback) 26 | #elif CEF_VERSION_MAJOR < 126 27 | bool 28 | CefViewBrowserClient::OnFileDialog(CefRefPtr browser, 29 | FileDialogMode mode, 30 | const CefString& title, 31 | const CefString& default_file_path, 32 | const std::vector& accept_filters, 33 | CefRefPtr callback) 34 | #else 35 | bool 36 | CefViewBrowserClient::OnFileDialog(CefRefPtr browser, 37 | FileDialogMode mode, 38 | const CefString& title, 39 | const CefString& default_file_path, 40 | const std::vector& accept_filters, 41 | const std::vector& accept_extensions, 42 | const std::vector& accept_descriptions, 43 | CefRefPtr callback) 44 | #endif 45 | { 46 | auto delegate = client_delegate_.lock(); 47 | if (delegate) 48 | return delegate->onFileDialog(browser, 49 | mode, 50 | title, 51 | default_file_path, 52 | accept_filters, 53 | #if CEF_VERSION_MAJOR < 102 54 | selected_accept_filter, 55 | #endif 56 | callback); 57 | 58 | return false; 59 | } 60 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_DisplayHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetDisplayHandler() 13 | { 14 | return this; 15 | } 16 | 17 | void 18 | CefViewBrowserClient::OnAddressChange(CefRefPtr browser, CefRefPtr frame, const CefString& url) 19 | { 20 | CEF_REQUIRE_UI_THREAD(); 21 | 22 | auto delegate = client_delegate_.lock(); 23 | if (delegate) 24 | delegate->addressChanged(browser, frame, url); 25 | } 26 | 27 | void 28 | CefViewBrowserClient::OnTitleChange(CefRefPtr browser, const CefString& title) 29 | { 30 | CEF_REQUIRE_UI_THREAD(); 31 | 32 | auto delegate = client_delegate_.lock(); 33 | if (delegate) 34 | delegate->titleChanged(browser, title); 35 | } 36 | 37 | void 38 | CefViewBrowserClient::OnFaviconURLChange(CefRefPtr browser, const std::vector& icon_urls) 39 | { 40 | CEF_REQUIRE_UI_THREAD(); 41 | 42 | auto delegate = client_delegate_.lock(); 43 | if (delegate) { 44 | delegate->faviconURLChanged(browser, icon_urls); 45 | } 46 | } 47 | 48 | void 49 | CefViewBrowserClient::OnFullscreenModeChange(CefRefPtr browser, bool fullscreen) 50 | { 51 | CEF_REQUIRE_UI_THREAD(); 52 | 53 | auto delegate = client_delegate_.lock(); 54 | if (delegate) 55 | delegate->fullscreenModeChanged(browser, fullscreen); 56 | } 57 | 58 | bool 59 | CefViewBrowserClient::OnTooltip(CefRefPtr browser, CefString& text) 60 | { 61 | CEF_REQUIRE_UI_THREAD(); 62 | 63 | auto delegate = client_delegate_.lock(); 64 | if (delegate) 65 | return delegate->tooltipMessage(browser, text); 66 | 67 | return false; 68 | } 69 | 70 | void 71 | CefViewBrowserClient::OnStatusMessage(CefRefPtr browser, const CefString& value) 72 | { 73 | CEF_REQUIRE_UI_THREAD(); 74 | 75 | auto delegate = client_delegate_.lock(); 76 | if (delegate) 77 | delegate->statusMessage(browser, value); 78 | } 79 | 80 | bool 81 | CefViewBrowserClient::OnConsoleMessage(CefRefPtr browser, 82 | cef_log_severity_t level, 83 | const CefString& message, 84 | const CefString& source, 85 | int line) 86 | { 87 | CEF_REQUIRE_UI_THREAD(); 88 | 89 | auto delegate = client_delegate_.lock(); 90 | if (delegate) 91 | delegate->consoleMessage(browser, message.ToString(), level); 92 | 93 | #if (defined(DEBUG) || defined(_DEBUG) || !defined(NDEBUG)) 94 | return false; 95 | #else 96 | return true; 97 | #endif 98 | } 99 | 100 | bool 101 | CefViewBrowserClient::OnAutoResize(CefRefPtr browser, const CefSize& new_size) 102 | { 103 | CEF_REQUIRE_UI_THREAD(); 104 | return false; 105 | } 106 | 107 | void 108 | CefViewBrowserClient::OnLoadingProgressChange(CefRefPtr browser, double progress) 109 | { 110 | CEF_REQUIRE_UI_THREAD(); 111 | 112 | auto delegate = client_delegate_.lock(); 113 | if (delegate) 114 | delegate->loadingProgressChanged(browser, progress); 115 | } 116 | 117 | bool 118 | CefViewBrowserClient::OnCursorChange(CefRefPtr browser, 119 | CefCursorHandle cursor, 120 | cef_cursor_type_t type, 121 | const CefCursorInfo& custom_cursor_info) 122 | { 123 | CEF_REQUIRE_UI_THREAD(); 124 | 125 | auto delegate = client_delegate_.lock(); 126 | if (delegate) 127 | return delegate->cursorChanged(browser, cursor, type, custom_cursor_info); 128 | 129 | return false; 130 | } 131 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_DownloadHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetDownloadHandler() 13 | { 14 | return this; 15 | } 16 | 17 | #if CEF_VERSION_MAJOR < 125 18 | void 19 | CefViewBrowserClient::OnBeforeDownload(CefRefPtr browser, 20 | CefRefPtr download_item, 21 | const CefString& suggested_name, 22 | CefRefPtr callback) 23 | { 24 | CEF_REQUIRE_UI_THREAD(); 25 | 26 | auto delegate = client_delegate_.lock(); 27 | if (delegate) 28 | delegate->onBeforeDownload(browser, download_item, suggested_name, callback); 29 | } 30 | #else 31 | bool 32 | CefViewBrowserClient::OnBeforeDownload(CefRefPtr browser, 33 | CefRefPtr download_item, 34 | const CefString& suggested_name, 35 | CefRefPtr callback) 36 | { 37 | CEF_REQUIRE_UI_THREAD(); 38 | 39 | auto delegate = client_delegate_.lock(); 40 | if (delegate) { 41 | delegate->onBeforeDownload(browser, download_item, suggested_name, callback); 42 | } else { 43 | // no delegate, just allow this download and then cancel it in OnDownloadUpdated 44 | if (callback) { 45 | callback->Continue("", false); 46 | } 47 | } 48 | 49 | /// Return true and execute |callback| either asynchronously or in this method to continue or cancel the download. 50 | /// Return false to proceed with default handling (cancel with Alloy style, download shelf with Chrome style) 51 | return true; 52 | } 53 | #endif 54 | 55 | void 56 | CefViewBrowserClient::OnDownloadUpdated(CefRefPtr browser, 57 | CefRefPtr download_item, 58 | CefRefPtr callback) 59 | { 60 | CEF_REQUIRE_UI_THREAD(); 61 | 62 | auto delegate = client_delegate_.lock(); 63 | if (delegate) { 64 | delegate->onDownloadUpdated(browser, download_item, callback); 65 | } else { 66 | // no delegate, just cancel this downloading 67 | if (callback) { 68 | callback->Cancel(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_DragHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetDragHandler() 13 | { 14 | return this; 15 | } 16 | 17 | bool 18 | CefViewBrowserClient::OnDragEnter(CefRefPtr browser, 19 | CefRefPtr dragData, 20 | CefDragHandler::DragOperationsMask mask) 21 | { 22 | CEF_REQUIRE_UI_THREAD(); 23 | 24 | auto delegate = client_delegate_.lock(); 25 | if (delegate) 26 | return delegate->onDragEnter(browser, dragData, mask); 27 | 28 | return true; 29 | } 30 | 31 | void 32 | CefViewBrowserClient::OnDraggableRegionsChanged(CefRefPtr browser, 33 | CefRefPtr frame, 34 | const std::vector& regions) 35 | { 36 | CEF_REQUIRE_UI_THREAD(); 37 | 38 | auto delegate = client_delegate_.lock(); 39 | if (delegate) 40 | delegate->draggableRegionChanged(browser, frame, regions); 41 | } 42 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_FindHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | CefRefPtr 6 | CefViewBrowserClient::GetFindHandler() 7 | { 8 | return this; 9 | } 10 | 11 | void 12 | CefViewBrowserClient::OnFindResult(CefRefPtr browser, 13 | int identifier, 14 | int count, 15 | const CefRect& selectionRect, 16 | int activeMatchOrdinal, 17 | bool finalUpdate) 18 | { 19 | CEF_REQUIRE_UI_THREAD(); 20 | } 21 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_FocusHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetFocusHandler() 13 | { 14 | return this; 15 | } 16 | 17 | void 18 | CefViewBrowserClient::OnTakeFocus(CefRefPtr browser, bool next) 19 | { 20 | CEF_REQUIRE_UI_THREAD(); 21 | 22 | auto delegate = client_delegate_.lock(); 23 | if (delegate) 24 | delegate->takeFocus(browser, next); 25 | } 26 | 27 | bool 28 | CefViewBrowserClient::OnSetFocus(CefRefPtr browser, FocusSource source) 29 | { 30 | CEF_REQUIRE_UI_THREAD(); 31 | 32 | auto delegate = client_delegate_.lock(); 33 | if (delegate) 34 | return delegate->setFocus(browser); 35 | 36 | return true; 37 | } 38 | 39 | void 40 | CefViewBrowserClient::OnGotFocus(CefRefPtr browser) 41 | { 42 | auto delegate = client_delegate_.lock(); 43 | if (delegate) 44 | delegate->gotFocus(browser); 45 | } 46 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_JSDialogHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetJSDialogHandler() 13 | { 14 | return this; 15 | } 16 | 17 | bool 18 | CefViewBrowserClient::OnJSDialog(CefRefPtr browser, 19 | const CefString& origin_url, 20 | JSDialogType dialog_type, 21 | const CefString& message_text, 22 | const CefString& default_prompt_text, 23 | CefRefPtr callback, 24 | bool& suppress_message) 25 | { 26 | CEF_REQUIRE_UI_THREAD(); 27 | 28 | /// Called to run a JavaScript dialog. 29 | /// 30 | /// If |origin_url| is non-empty it can be passed to the CefFormatUrlForSecurityDisplay 31 | /// function to retrieve a secureand user-friendly display string. 32 | /// 33 | /// The |default_prompt_text| value will be specified for prompt dialogs only. 34 | /// 35 | /// Set |suppress_message| to true and return false to suppress the message 36 | /// (suppressing messages is preferable to immediately executing the callback 37 | /// as this is used to detect presumably malicious behavior like spamming alert 38 | /// messages in onbeforeunload). 39 | /// 40 | /// Set |suppress_message| to false and return false to use the default 41 | /// implementation (the default implementation will show one modal dialog at a 42 | /// time and suppress any additional dialog requests until the displayed 43 | /// dialog is dismissed). 44 | /// 45 | /// Return true if the application will use a custom dialog or if the callback has 46 | /// been executed immediately. Custom dialogs may be either modal or modeless. If a 47 | /// custom dialog is used the application must execute |callback| once the custom 48 | /// dialog is dismissed. 49 | 50 | auto delegate = client_delegate_.lock(); 51 | if (delegate) { 52 | return delegate->onJSDialog( 53 | browser, origin_url, dialog_type, message_text, default_prompt_text, callback, suppress_message); 54 | } 55 | 56 | return false; 57 | } 58 | 59 | bool 60 | CefViewBrowserClient::OnBeforeUnloadDialog(CefRefPtr browser, 61 | const CefString& message_text, 62 | bool is_reload, 63 | CefRefPtr callback) 64 | { 65 | CEF_REQUIRE_UI_THREAD(); 66 | 67 | /// Called to run a dialog asking the user if they want to leave a page. 68 | /// Return false to use the default dialog implementation. Return true if the 69 | /// application will use a custom dialog or if the callback has been executed 70 | /// immediately. Custom dialogs may be either modal or modeless. If a custom 71 | /// dialog is used the application must execute |callback| once the custom 72 | /// dialog is dismissed. 73 | 74 | auto delegate = client_delegate_.lock(); 75 | if (delegate) { 76 | return delegate->onBeforeUnloadDialog(browser, message_text, is_reload, callback); 77 | } 78 | 79 | return false; 80 | } 81 | 82 | void 83 | CefViewBrowserClient::OnResetDialogState(CefRefPtr browser) 84 | { 85 | CEF_REQUIRE_UI_THREAD(); 86 | 87 | /// Called to cancel any pending dialogs and reset any saved dialog state. 88 | /// Will be called due to events like page navigation irregardless of whether 89 | /// any dialogs are currently pending. 90 | 91 | auto delegate = client_delegate_.lock(); 92 | if (delegate) 93 | delegate->onResetDialogState(browser); 94 | } 95 | 96 | void 97 | CefViewBrowserClient::OnDialogClosed(CefRefPtr browser) 98 | { 99 | CEF_REQUIRE_UI_THREAD(); 100 | 101 | /// Called when the dialog is closed. 102 | 103 | auto delegate = client_delegate_.lock(); 104 | if (delegate) 105 | delegate->onDialogClosed(browser); 106 | } 107 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_KeyboardHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetKeyboardHandler() 13 | { 14 | return this; 15 | } 16 | 17 | bool 18 | CefViewBrowserClient::OnPreKeyEvent(CefRefPtr browser, 19 | const CefKeyEvent& event, 20 | CefEventHandle os_event, 21 | bool* is_keyboard_shortcut) 22 | { 23 | CEF_REQUIRE_UI_THREAD(); 24 | 25 | auto delegate = client_delegate_.lock(); 26 | if (delegate) 27 | return delegate->onPreKeyEvent(browser, event, os_event, is_keyboard_shortcut); 28 | 29 | return false; 30 | } 31 | 32 | bool 33 | CefViewBrowserClient::OnKeyEvent(CefRefPtr browser, const CefKeyEvent& event, CefEventHandle os_event) 34 | { 35 | CEF_REQUIRE_UI_THREAD(); 36 | 37 | auto delegate = client_delegate_.lock(); 38 | if (delegate) 39 | return delegate->onKeyEvent(browser, event, os_event); 40 | 41 | return false; 42 | } 43 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_LifeSpanHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | #include "CefViewQueryHandler/CefViewQueryHandler.h" 12 | 13 | CefRefPtr 14 | CefViewBrowserClient::GetLifeSpanHandler() 15 | { 16 | return this; 17 | } 18 | 19 | bool 20 | CefViewBrowserClient::OnBeforePopup(CefRefPtr browser, 21 | CefRefPtr frame, 22 | #if CEF_VERSION_MAJOR > 131 23 | int popup_id, 24 | #endif 25 | const CefString& target_url, 26 | const CefString& target_frame_name, 27 | CefLifeSpanHandler::WindowOpenDisposition target_disposition, 28 | bool user_gesture, 29 | const CefPopupFeatures& popupFeatures, 30 | CefWindowInfo& windowInfo, 31 | CefRefPtr& client, 32 | CefBrowserSettings& settings, 33 | CefRefPtr& extra_info, 34 | bool* no_javascript_access) 35 | { 36 | CEF_REQUIRE_UI_THREAD(); 37 | 38 | // If the browser is closing, block the popup 39 | if (is_closing_) 40 | return true; 41 | 42 | bool result = false; 43 | 44 | auto delegate = client_delegate_.lock(); 45 | if (delegate) { 46 | bool disableJSAccess = no_javascript_access ? *no_javascript_access : false; 47 | result = delegate->onBeforePopup(browser, 48 | frame, 49 | target_url.ToString(), 50 | target_frame_name.ToString(), 51 | target_disposition, 52 | windowInfo, 53 | settings, 54 | disableJSAccess); 55 | if (no_javascript_access) 56 | *no_javascript_access = disableJSAccess; 57 | } 58 | 59 | return result; 60 | } 61 | 62 | void 63 | CefViewBrowserClient::OnAfterCreated(CefRefPtr browser) 64 | { 65 | CEF_REQUIRE_UI_THREAD(); 66 | 67 | // If the browser is closing, return immediately to release the new created browser 68 | if (is_closing_) { 69 | browser->GetHost()->CloseBrowser(true); 70 | return; 71 | } 72 | 73 | // Register handlers with the router. 74 | if (browser_map_.empty()) { 75 | message_router_ = CefMessageRouterBrowserSide::Create(message_router_config_); 76 | 77 | message_router_handler_ = new CefViewQueryHandler(client_delegate_); 78 | message_router_->AddHandler(message_router_handler_.get(), false); 79 | } 80 | 81 | auto delegate = client_delegate_.lock(); 82 | if (delegate) 83 | delegate->onAfterCreate(browser); 84 | 85 | browser_map_[browser->GetIdentifier()] = browser; 86 | } 87 | 88 | bool 89 | CefViewBrowserClient::DoClose(CefRefPtr browser) 90 | { 91 | CEF_REQUIRE_UI_THREAD(); 92 | 93 | bool ignoreClose = false; 94 | 95 | if (browser->IsPopup()) { 96 | return ignoreClose; 97 | } 98 | 99 | auto delegate = client_delegate_.lock(); 100 | if (delegate) { 101 | if (close_by_native_) { 102 | // close by native 103 | ignoreClose = delegate->doClose(browser); 104 | } else { 105 | // close request from web 106 | ignoreClose = delegate->requestClose(browser); 107 | } 108 | } 109 | 110 | if (!ignoreClose) { 111 | is_closing_ = true; 112 | } 113 | 114 | return ignoreClose; 115 | } 116 | 117 | void 118 | CefViewBrowserClient::OnBeforeClose(CefRefPtr browser) 119 | { 120 | CEF_REQUIRE_UI_THREAD(); 121 | 122 | auto delegate = client_delegate_.lock(); 123 | if (delegate) 124 | delegate->onBeforeClose(browser); 125 | 126 | message_router_->OnBeforeClose(browser); 127 | 128 | browser_map_.erase(browser->GetIdentifier()); 129 | 130 | if (browser_map_.empty()) { 131 | message_router_->RemoveHandler(message_router_handler_.get()); 132 | message_router_ = nullptr; 133 | message_router_handler_ = nullptr; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_LoadHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetLoadHandler() 13 | { 14 | return this; 15 | } 16 | 17 | void 18 | CefViewBrowserClient::OnLoadingStateChange(CefRefPtr browser, 19 | bool isLoading, 20 | bool canGoBack, 21 | bool canGoForward) 22 | { 23 | CEF_REQUIRE_UI_THREAD(); 24 | 25 | if (!isLoading && initial_navigation_) { 26 | initial_navigation_ = false; 27 | } 28 | 29 | auto delegate = client_delegate_.lock(); 30 | if (delegate) 31 | delegate->loadingStateChanged(browser, isLoading, canGoBack, canGoForward); 32 | } 33 | 34 | void 35 | CefViewBrowserClient::OnLoadStart(CefRefPtr browser, 36 | CefRefPtr frame, 37 | TransitionType transition_type) 38 | { 39 | logScope(); 40 | 41 | CEF_REQUIRE_UI_THREAD(); 42 | 43 | // [Javascript Context] 44 | // from now on, you can send Javascript to the frame, but they will not be executed immediately, 45 | // the script will be executed right after the initialization of V8 context for this frame, 46 | // that means the scripts you write here will be scheduled. 47 | frame->ExecuteJavaScript("console.info('[JSRuntime]:frame context is ready')", frame->GetURL(), 0); 48 | 49 | auto delegate = client_delegate_.lock(); 50 | if (delegate) 51 | delegate->loadStart(browser, frame, transition_type); 52 | } 53 | 54 | void 55 | CefViewBrowserClient::OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) 56 | { 57 | logScope(); 58 | 59 | CEF_REQUIRE_UI_THREAD(); 60 | auto delegate = client_delegate_.lock(); 61 | if (delegate) 62 | delegate->loadEnd(browser, frame, httpStatusCode); 63 | } 64 | 65 | void 66 | CefViewBrowserClient::OnLoadError(CefRefPtr browser, 67 | CefRefPtr frame, 68 | ErrorCode errorCode, 69 | const CefString& errorText, 70 | const CefString& failedUrl) 71 | { 72 | CEF_REQUIRE_UI_THREAD(); 73 | if (errorCode == ERR_ABORTED) 74 | return; 75 | 76 | // If the browser is closing, block the popup 77 | if (is_closing_) 78 | return; 79 | 80 | auto msg = errorText.ToString(); 81 | auto url = failedUrl.ToString(); 82 | 83 | bool handled = false; 84 | auto delegate = client_delegate_.lock(); 85 | if (delegate) 86 | delegate->loadError(browser, frame, errorCode, msg, url, handled); 87 | 88 | if (handled) 89 | return; 90 | 91 | std::ostringstream oss; 92 | oss << "" 93 | << "

Failed to load URL: " << url << "

" 94 | << "

Error: " << msg << "(" << errorCode << ")

" 95 | << ""; 96 | 97 | std::string data = oss.str(); 98 | data = CefURIEncode(CefBase64Encode(data.c_str(), data.size()), false).ToString(); 99 | data = "data:text/html;base64," + data; 100 | frame->LoadURL(data); 101 | } 102 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_RenderHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetRenderHandler() 13 | { 14 | return this; 15 | } 16 | 17 | CefRefPtr 18 | CefViewBrowserClient::GetAccessibilityHandler() 19 | { 20 | return nullptr; 21 | } 22 | bool 23 | CefViewBrowserClient::GetRootScreenRect(CefRefPtr browser, CefRect& rect) 24 | { 25 | auto delegate = client_delegate_.lock(); 26 | if (delegate) 27 | return delegate->getRootScreenRect(browser, rect); 28 | 29 | return false; 30 | } 31 | 32 | void 33 | CefViewBrowserClient::GetViewRect(CefRefPtr browser, CefRect& rect) 34 | { 35 | auto delegate = client_delegate_.lock(); 36 | if (delegate) 37 | return delegate->getViewRect(browser, rect); 38 | } 39 | 40 | bool 41 | CefViewBrowserClient::GetScreenPoint(CefRefPtr browser, int viewX, int viewY, int& screenX, int& screenY) 42 | { 43 | auto delegate = client_delegate_.lock(); 44 | if (delegate) 45 | return delegate->getScreenPoint(browser, viewX, viewY, screenX, screenY); 46 | 47 | return false; 48 | } 49 | 50 | bool 51 | CefViewBrowserClient::GetScreenInfo(CefRefPtr browser, CefScreenInfo& screen_info) 52 | { 53 | auto delegate = client_delegate_.lock(); 54 | if (delegate) 55 | return delegate->getScreenInfo(browser, screen_info); 56 | 57 | return false; 58 | } 59 | 60 | void 61 | CefViewBrowserClient::OnPopupShow(CefRefPtr browser, bool show) 62 | { 63 | auto delegate = client_delegate_.lock(); 64 | if (delegate) 65 | return delegate->onPopupShow(browser, show); 66 | } 67 | 68 | void 69 | CefViewBrowserClient::OnPopupSize(CefRefPtr browser, const CefRect& rect) 70 | { 71 | auto delegate = client_delegate_.lock(); 72 | if (delegate) 73 | return delegate->onPopupSize(browser, rect); 74 | } 75 | 76 | void 77 | CefViewBrowserClient::OnPaint(CefRefPtr browser, 78 | PaintElementType type, 79 | const RectList& dirtyRects, 80 | const void* buffer, 81 | int width, 82 | int height) 83 | { 84 | auto delegate = client_delegate_.lock(); 85 | if (delegate) 86 | return delegate->onPaint(browser, type, dirtyRects, buffer, width, height); 87 | } 88 | 89 | #if CEF_VERSION_MAJOR < 124 90 | void 91 | CefViewBrowserClient::OnAcceleratedPaint(CefRefPtr browser, 92 | PaintElementType type, 93 | const RectList& dirtyRects, 94 | void* shared_handle) 95 | { 96 | auto delegate = client_delegate_.lock(); 97 | if (delegate) 98 | delegate->onAcceleratedPaint(browser, type, dirtyRects, shared_handle); 99 | } 100 | #else 101 | 102 | void 103 | CefViewBrowserClient::OnAcceleratedPaint(CefRefPtr browser, 104 | PaintElementType type, 105 | const RectList& dirtyRects, 106 | const CefAcceleratedPaintInfo& info) 107 | { 108 | auto delegate = client_delegate_.lock(); 109 | if (delegate) 110 | delegate->onAcceleratedPaint(browser, type, dirtyRects, info); 111 | } 112 | #endif 113 | 114 | bool 115 | CefViewBrowserClient::StartDragging(CefRefPtr browser, 116 | CefRefPtr drag_data, 117 | CefRenderHandler::DragOperationsMask allowed_ops, 118 | int x, 119 | int y) 120 | { 121 | auto delegate = client_delegate_.lock(); 122 | if (delegate) 123 | return delegate->startDragging(browser, drag_data, allowed_ops, x, y); 124 | 125 | return false; 126 | } 127 | 128 | void 129 | CefViewBrowserClient::UpdateDragCursor(CefRefPtr browser, DragOperation operation) 130 | { 131 | auto delegate = client_delegate_.lock(); 132 | if (delegate) 133 | delegate->updateDragCursor(browser, operation); 134 | } 135 | 136 | void 137 | CefViewBrowserClient::OnScrollOffsetChanged(CefRefPtr browser, double x, double y) 138 | { 139 | auto delegate = client_delegate_.lock(); 140 | if (delegate) 141 | return delegate->onScrollOffsetChanged(browser, x, y); 142 | } 143 | 144 | void 145 | CefViewBrowserClient::OnImeCompositionRangeChanged(CefRefPtr browser, 146 | const CefRange& selected_range, 147 | const RectList& character_bounds) 148 | { 149 | auto delegate = client_delegate_.lock(); 150 | if (delegate) 151 | return delegate->onImeCompositionRangeChanged(browser, selected_range, character_bounds); 152 | } 153 | 154 | void 155 | CefViewBrowserClient::OnTextSelectionChanged(CefRefPtr browser, 156 | const CefString& selected_text, 157 | const CefRange& selected_range) 158 | { 159 | auto delegate = client_delegate_.lock(); 160 | if (delegate) 161 | return delegate->onTextSelectionChanged(browser, selected_text, selected_range); 162 | } 163 | 164 | void 165 | CefViewBrowserClient::OnVirtualKeyboardRequested(CefRefPtr browser, TextInputMode input_mode) 166 | { 167 | auto delegate = client_delegate_.lock(); 168 | if (delegate) 169 | return delegate->onVirtualKeyboardRequested(browser, input_mode); 170 | } 171 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_RequestHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetRequestHandler() 13 | { 14 | return this; 15 | } 16 | 17 | bool 18 | CefViewBrowserClient::OnBeforeBrowse(CefRefPtr browser, 19 | CefRefPtr frame, 20 | CefRefPtr request, 21 | bool user_gesture, 22 | bool is_redirect) 23 | { 24 | CEF_REQUIRE_UI_THREAD(); 25 | 26 | message_router_->OnBeforeBrowse(browser, frame); 27 | return false; 28 | } 29 | 30 | bool 31 | CefViewBrowserClient::OnOpenURLFromTab(CefRefPtr browser, 32 | CefRefPtr frame, 33 | const CefString& target_url, 34 | CefRequestHandler::WindowOpenDisposition target_disposition, 35 | bool user_gesture) 36 | { 37 | CEF_REQUIRE_UI_THREAD(); 38 | 39 | return false; // return true to cancel this navigation. 40 | } 41 | 42 | #if CEF_VERSION_MAJOR > 91 && CEF_VERSION_MAJOR < 109 43 | bool 44 | CefViewBrowserClient::OnQuotaRequest(CefRefPtr browser, 45 | const CefString& origin_url, 46 | int64 new_size, 47 | CefRefPtr callback) 48 | { 49 | CEF_REQUIRE_IO_THREAD(); 50 | static const int maxSize = 10 * 1024 * 1024; 51 | if (new_size <= maxSize) 52 | callback->Continue(); 53 | else 54 | callback->Cancel(); 55 | 56 | return true; 57 | } 58 | #endif 59 | 60 | #if CEF_VERSION_MAJOR < 124 61 | void 62 | CefViewBrowserClient::OnRenderProcessTerminated(CefRefPtr browser, TerminationStatus status) 63 | #else 64 | void 65 | CefViewBrowserClient::OnRenderProcessTerminated(CefRefPtr browser, 66 | TerminationStatus status, 67 | int error_code, 68 | const CefString& error_string) 69 | #endif 70 | { 71 | CEF_REQUIRE_UI_THREAD(); 72 | 73 | message_router_->OnRenderProcessTerminated(browser); 74 | 75 | if (browser) { 76 | CefString url = browser->GetMainFrame()->GetURL(); 77 | if (!url.empty()) { 78 | browser->GetMainFrame()->LoadURL(url); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewBrowserClient_ResourceRequestHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma region stl_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | CefRefPtr 12 | CefViewBrowserClient::GetResourceRequestHandler(CefRefPtr browser, 13 | CefRefPtr frame, 14 | CefRefPtr request, 15 | bool is_navigation, 16 | bool is_download, 17 | const CefString& request_initiator, 18 | bool& disable_default_handling) 19 | { 20 | return this; 21 | } 22 | 23 | CefResourceRequestHandler::ReturnValue 24 | CefViewBrowserClient::OnBeforeResourceLoad(CefRefPtr browser, 25 | CefRefPtr frame, 26 | CefRefPtr request, 27 | #if CEF_VERSION_MAJOR > 91 28 | CefRefPtr callback 29 | #else 30 | CefRefPtr callback 31 | #endif 32 | ) 33 | { 34 | auto url = request->GetURL().ToString(); 35 | // logD("require resource: %s", url.c_str()); 36 | return resource_manager_->OnBeforeResourceLoad(browser, frame, request, callback); 37 | } 38 | 39 | CefRefPtr 40 | CefViewBrowserClient::GetResourceHandler(CefRefPtr browser, 41 | CefRefPtr frame, 42 | CefRefPtr request) 43 | { 44 | return resource_manager_->GetResourceHandler(browser, frame, request); 45 | } 46 | 47 | void 48 | CefViewBrowserClient::OnProtocolExecution(CefRefPtr browser, 49 | CefRefPtr frame, 50 | CefRefPtr request, 51 | bool& allow_os_execution) 52 | { 53 | } 54 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewQueryHandler/CefViewQueryHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewQueryHandler.h" 2 | 3 | CefViewQueryHandler::CefViewQueryHandler(CefViewBrowserClientDelegateInterface::WeakPtr delegate) 4 | : handler_delegate_(delegate) 5 | { 6 | } 7 | 8 | CefViewQueryHandler::~CefViewQueryHandler() {} 9 | 10 | bool 11 | CefViewQueryHandler::Response(int64_t query, bool success, const CefString& response, int error) 12 | { 13 | CefRefPtr cb; 14 | mtxCallbackMap_.lock(); 15 | auto it = mapCallback_.find(query); 16 | if (it != mapCallback_.end()) { 17 | cb = it->second; 18 | mapCallback_.erase(it); 19 | } 20 | mtxCallbackMap_.unlock(); 21 | 22 | if (!cb) 23 | return false; 24 | 25 | if (success) 26 | cb->Success(response); 27 | else 28 | cb->Failure(error, response); 29 | 30 | return true; 31 | } 32 | 33 | bool 34 | CefViewQueryHandler::OnQuery(CefRefPtr browser, 35 | CefRefPtr frame, 36 | int64_t query_id, 37 | const CefString& request, 38 | bool persistent, 39 | CefRefPtr callback) 40 | { 41 | auto browserDelegate = handler_delegate_.lock(); 42 | if (browserDelegate) { 43 | mtxCallbackMap_.lock(); 44 | mapCallback_[query_id] = callback; 45 | mtxCallbackMap_.unlock(); 46 | 47 | browserDelegate->processQueryRequest(browser, frame, request.ToString(), query_id); 48 | 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | void 56 | CefViewQueryHandler::OnQueryCanceled(CefRefPtr browser, CefRefPtr frame, int64_t query_id) 57 | { 58 | mtxCallbackMap_.lock(); 59 | auto it = mapCallback_.find(query_id); 60 | if (it != mapCallback_.end()) 61 | mapCallback_.erase(it); 62 | 63 | mtxCallbackMap_.unlock(); 64 | } 65 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewQueryHandler/CefViewQueryHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewQueryHandler.h 3 | // CefView 4 | // 5 | // Created by Sheen Tian on 2020/6/11. 6 | // 7 | 8 | #ifndef CefViewQueryHandler_h 9 | #define CefViewQueryHandler_h 10 | #pragma once 11 | 12 | #pragma region stl_headers 13 | #include 14 | #include 15 | #pragma endregion 16 | 17 | #include 18 | #include 19 | 20 | /// 21 | /// 22 | /// 23 | class CefViewQueryHandler 24 | : public CefBaseRefCounted 25 | , public CefMessageRouterBrowserSide::Handler 26 | { 27 | IMPLEMENT_REFCOUNTING(CefViewQueryHandler); 28 | 29 | private: 30 | /// 31 | /// 32 | /// 33 | CefViewBrowserClientDelegateInterface::WeakPtr handler_delegate_; 34 | 35 | /// 36 | /// 37 | /// 38 | std::map> mapCallback_; 39 | 40 | /// 41 | /// 42 | /// 43 | std::mutex mtxCallbackMap_; 44 | 45 | public: 46 | /// 47 | /// 48 | /// 49 | /// 50 | CefViewQueryHandler(CefViewBrowserClientDelegateInterface::WeakPtr delegate); 51 | 52 | /// 53 | /// 54 | /// 55 | ~CefViewQueryHandler(); 56 | 57 | /// 58 | /// 59 | /// 60 | /// 61 | /// 62 | /// 63 | /// 64 | /// 65 | bool Response(int64_t query, bool success, const CefString& response, int error); 66 | 67 | protected: 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | /// 77 | /// 78 | virtual bool OnQuery(CefRefPtr browser, 79 | CefRefPtr frame, 80 | int64_t query_id, 81 | const CefString& request, 82 | bool persistent, 83 | CefRefPtr callback) override; 84 | 85 | /// 86 | /// 87 | /// 88 | /// 89 | /// 90 | /// 91 | virtual void OnQueryCanceled(CefRefPtr browser, CefRefPtr frame, int64_t query_id) override; 92 | }; 93 | #endif 94 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewSchemeHandler/CefViewSchemeHandler.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewSchemeHandler.h" 2 | 3 | CefViewSchemeHandler::CefViewSchemeHandler(CefRefPtr browser, 4 | CefRefPtr frame, 5 | CefViewBrowserClientDelegateInterface::RefPtr delegate) 6 | : browser_(browser) 7 | , frame_(frame) 8 | , handler_delegate_(delegate) 9 | , offset_(0) 10 | { 11 | } 12 | 13 | CefViewSchemeHandler::~CefViewSchemeHandler() {} 14 | 15 | bool 16 | CefViewSchemeHandler::Open(CefRefPtr request, bool& handle_request, CefRefPtr callback) 17 | { 18 | // DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO)); 19 | 20 | handle_request = true; 21 | 22 | auto browserDelegate = handler_delegate_.lock(); 23 | if (browserDelegate) { 24 | CefString cefStrUrl = request->GetURL(); 25 | browserDelegate->processUrlRequest(browser_, frame_, cefStrUrl.ToString()); 26 | } 27 | 28 | data_ = "ok"; 29 | mime_type_ = "text/html"; 30 | 31 | return true; 32 | } 33 | 34 | void 35 | CefViewSchemeHandler::GetResponseHeaders(CefRefPtr response, 36 | int64_t& response_length, 37 | CefString& redirectUrl) 38 | { 39 | CEF_REQUIRE_IO_THREAD(); 40 | 41 | DCHECK(!data_.empty()); 42 | response->SetMimeType(mime_type_); 43 | response->SetStatus(200); 44 | // Set the resulting response length 45 | response_length = data_.length(); 46 | } 47 | 48 | bool 49 | CefViewSchemeHandler::Skip(int64_t bytes_to_skip, int64_t& bytes_skipped, CefRefPtr callback) 50 | { 51 | // CEF_REQUIRE_IO_THREAD(); 52 | 53 | bytes_skipped = 0; 54 | 55 | offset_ += bytes_to_skip; 56 | if (offset_ <= (int)data_.length()) { 57 | bytes_skipped = bytes_to_skip; 58 | } else { 59 | offset_ = (int)data_.length(); 60 | bytes_skipped = data_.length() - offset_; 61 | } 62 | 63 | return true; 64 | } 65 | 66 | bool 67 | CefViewSchemeHandler::Read(void* data_out, 68 | int bytes_to_read, 69 | int& bytes_read, 70 | CefRefPtr callback) 71 | { 72 | // DCHECK(!CefCurrentlyOn(TID_UI) && !CefCurrentlyOn(TID_IO)); 73 | 74 | bytes_read = 0; 75 | if (offset_ < (int)data_.length()) { 76 | // Copy the next block of data into the buffer. 77 | int transfer_size = std::min(bytes_to_read, static_cast(data_.length() - offset_)); 78 | memcpy(data_out, data_.c_str() + offset_, transfer_size); 79 | offset_ += transfer_size; 80 | bytes_read = transfer_size; 81 | } 82 | 83 | return bytes_read > 0; 84 | } 85 | 86 | void 87 | CefViewSchemeHandler::Cancel() 88 | { 89 | // CEF_REQUIRE_IO_THREAD(); 90 | } 91 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewSchemeHandler/CefViewSchemeHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewSchemeHandler.h 3 | // CefView 4 | // 5 | // Created by Sheen Tian on 2024/10/9. 6 | // 7 | 8 | #ifndef CefViewSchemeHandler_h 9 | #define CefViewSchemeHandler_h 10 | 11 | #pragma once 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | class CefViewSchemeHandler : public CefResourceHandler 19 | { 20 | IMPLEMENT_REFCOUNTING(CefViewSchemeHandler); 21 | 22 | private: 23 | /// 24 | /// 25 | /// 26 | CefRefPtr browser_; 27 | 28 | /// 29 | /// 30 | /// 31 | CefRefPtr frame_; 32 | 33 | /// 34 | /// 35 | /// 36 | CefViewBrowserClientDelegateInterface::WeakPtr handler_delegate_; 37 | 38 | int offset_; 39 | std::string data_; 40 | std::string mime_type_; 41 | 42 | public: 43 | CefViewSchemeHandler(CefRefPtr browser, 44 | CefRefPtr frame, 45 | CefViewBrowserClientDelegateInterface::RefPtr delegate); 46 | 47 | ~CefViewSchemeHandler(); 48 | 49 | virtual bool Open(CefRefPtr request, bool& handle_request, CefRefPtr callback) override; 50 | 51 | virtual void GetResponseHeaders(CefRefPtr response, 52 | int64_t& response_length, 53 | CefString& redirectUrl) override; 54 | 55 | virtual bool Skip(int64_t bytes_to_skip, 56 | int64_t& bytes_skipped, 57 | CefRefPtr callback) override; 58 | 59 | virtual bool Read(void* data_out, 60 | int bytes_to_read, 61 | int& bytes_read, 62 | CefRefPtr callback) override; 63 | 64 | virtual void Cancel() override; 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewSchemeHandler/CefViewSchemeHandlerFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewSchemeHandlerFactory.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "CefViewSchemeHandler.h" 7 | 8 | CefViewSchemeHandlerFactory::CefViewSchemeHandlerFactory(CefRefPtr app) 9 | : app_(app) 10 | { 11 | } 12 | 13 | CefViewSchemeHandlerFactory::~CefViewSchemeHandlerFactory() {} 14 | 15 | CefRefPtr 16 | CefViewSchemeHandlerFactory::Create(CefRefPtr browser, 17 | CefRefPtr frame, 18 | const CefString& scheme_name, 19 | CefRefPtr request) 20 | { 21 | if (!app_) { 22 | return nullptr; 23 | } 24 | 25 | auto client = browser->GetHost()->GetClient(); 26 | if (!client) { 27 | return nullptr; 28 | } 29 | 30 | auto handler = app_->GetClientHandler(client.get()); 31 | if (!handler) { 32 | return nullptr; 33 | } 34 | return new CefViewSchemeHandler(browser, frame, handler); 35 | } 36 | -------------------------------------------------------------------------------- /src/CefView/CefBrowserApp/CefViewSchemeHandler/CefViewSchemeHandlerFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewSchemeHandlerFactory.h 3 | // CefView 4 | // 5 | // Created by Sheen Tian on 2024/10/9. 6 | // 7 | 8 | #ifndef CefViewSchemeHandlerFactory_h 9 | #define CefViewSchemeHandlerFactory_h 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | class CefViewSchemeHandlerFactory : public CefSchemeHandlerFactory 17 | { 18 | IMPLEMENT_REFCOUNTING(CefViewSchemeHandlerFactory); 19 | 20 | private: 21 | /// 22 | /// 23 | /// 24 | CefRefPtr app_; 25 | 26 | public: 27 | /// 28 | /// 29 | /// 30 | /// 31 | CefViewSchemeHandlerFactory(CefRefPtr app); 32 | 33 | /// 34 | /// 35 | /// 36 | ~CefViewSchemeHandlerFactory(); 37 | 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | /// 46 | virtual CefRefPtr Create(CefRefPtr browser, 47 | CefRefPtr frame, 48 | const CefString& scheme_name, 49 | CefRefPtr request) override; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/CefViewCoreProtocol.h.in: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewCoreProtocol.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/11. 6 | // This file was generated during CMake configuring. 7 | // Do not edit this file directly by manual. 8 | // Edit the CefViewCoreProtocol.h.in and then re-config project with CMake. 9 | // 10 | 11 | #ifndef CefViewCoreProtocol_h 12 | #define CefViewCoreProtocol_h 13 | #pragma once 14 | 15 | /// 16 | /// CefView Helper Process Name 17 | /// 18 | #define kCefViewRenderProcessName "@CEFVIEW_WING_NAME@" 19 | 20 | /// 21 | /// 22 | /// 23 | #define kCefViewQueryFuntionName "cefViewQuery" 24 | 25 | /// 26 | /// 27 | /// 28 | #define kCefViewQueryCancelFunctionName "cefViewQueryCancel" 29 | 30 | /// 31 | /// 32 | /// 33 | #define kCefViewBridgeObjectNameKey "bridge-obj-name" 34 | 35 | /// 36 | /// 37 | /// 38 | #define kCefViewBuiltinSchemeNameKey "builtin-scheme-name" 39 | 40 | /// 41 | /// 42 | /// 43 | #define kCefViewWindowsJobNameKey "windows-job-name" 44 | 45 | /// 46 | /// 47 | /// 48 | #define kCefViewDefaultBridgeObjectName "CefViewClient" 49 | 50 | /// 51 | /// 52 | /// 53 | #define kCefViewDefaultBuiltinSchemaName "CefView" 54 | 55 | /// 56 | /// CEFVIEWClient.invokeMethod("method_name", ...) 57 | /// 58 | #define kCefViewInvokeMethodFunctionName "invoke" 59 | 60 | /// 61 | /// CEFVIEWClient.addEventListener(type, listener) 62 | /// 63 | #define kCefViewAddEventListenerFunctionName "addEventListener" 64 | 65 | /// 66 | /// CEFVIEWClient.removeEventListener(type, listener) 67 | /// 68 | #define kCefViewRemoveEventListenerFunctionName "removeEventListener" 69 | 70 | /// 71 | /// this message is sent from render process to browser process 72 | /// and is processed in the Qt UI thread 73 | /// 74 | /// 75 | #define kCefViewClientRenderFocusedNodeChangedMessage "CefViewClientRender.FocusedNodeChanged" 76 | 77 | /// 78 | /// this message is sent from render process to browser process 79 | /// and is processed in the Qt UI thread 80 | /// 81 | /// 82 | #define kCefViewClientRenderReportJSResultMessage "CefViewClientRender.ReportJSResult" 83 | 84 | /// 85 | /// this message is sent from render process to browser process 86 | /// and is processed in the Qt UI thread 87 | /// 88 | /// format 89 | /// msg.name 90 | /// msg.arg[0]: function name 91 | /// msg.arg[1~...]: function parameters 92 | /// 93 | #define kCefViewClientRenderInvokeMethodMessage "CefViewClientRender.InvokeMethod" 94 | 95 | /// 96 | /// this message is sent from browser process to render process 97 | /// and is processed in the CefRenderer_Main thread 98 | /// 99 | /// format: 100 | /// msg.name: 101 | /// msg.arg[0]: function name 102 | /// msg.arg[1~...]: function parameters 103 | /// 104 | #define kCefViewClientBrowserTriggerEventMessage "CefViewClientBrowser.TriggerEvent" 105 | 106 | /// 107 | /// window.__cefview_report_js_result__(context, result) 108 | /// context must be double 109 | /// 110 | #define kCefViewReportJSResultFunctionName "__cefview_report_js_result__" 111 | 112 | /// 113 | /// 114 | /// 115 | #define kCefViewResourceDirectoryName "resources" 116 | 117 | /// 118 | /// 119 | /// 120 | #define kCefViewLocalesDirectoryName "locales" 121 | 122 | /// 123 | /// 124 | /// 125 | #if defined(OS_WINDOWS) 126 | #define kCefViewDefaultUserAgent "CefView/1.0 (Windows; en-us)" 127 | #elif defined(OS_MACOS) 128 | #define kCefViewDefaultUserAgent "CefView/1.0 (macOS; en-us)" 129 | #elif defined(OS_LINUX) 130 | #define kCefViewDefaultUserAgent "CefView/1.0 (Linux; en-us)" 131 | #else 132 | #define kCefViewDefaultUserAgent "CefView/1.0 (Unknown; en-us)" 133 | #endif 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewAppBase.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewAppBase.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | // These flags must match the Chromium values. 8 | const char kProcessType[] = "type"; 9 | const char kZygoteProcess[] = "zygote"; 10 | const char kRendererProcess[] = "renderer"; 11 | 12 | CefViewAppBase::CefViewAppBase(const CefString& scheme_name) 13 | : builtin_scheme_name_(scheme_name) 14 | { 15 | } 16 | 17 | // static 18 | CefViewAppBase::ProcessType 19 | CefViewAppBase::GetProcessType(CefRefPtr command_line) 20 | { 21 | // The command-line flag won't be specified for the browser process. 22 | if (!command_line->HasSwitch(kProcessType)) 23 | return UnkownProcess; 24 | 25 | auto process_type = command_line->GetSwitchValue(kProcessType); 26 | logI("process type parameter is: %s", process_type.c_str()); 27 | if (process_type == kZygoteProcess) { 28 | // for linux only 29 | return ZygoteProcess; 30 | } else if (process_type == kRendererProcess) { 31 | return RendererProcess; 32 | } 33 | 34 | return OtherProcess; 35 | } 36 | 37 | CefString 38 | CefViewAppBase::GetBridgeObjectName(CefRefPtr command_line) 39 | { 40 | if (!command_line->HasSwitch(kCefViewBridgeObjectNameKey)) 41 | return ""; 42 | 43 | auto name = command_line->GetSwitchValue(kCefViewBridgeObjectNameKey); 44 | logI("bridge object name: %s", name.c_str()); 45 | return name; 46 | } 47 | 48 | CefString 49 | CefViewAppBase::GetBuiltinSchemeName(CefRefPtr command_line) 50 | { 51 | if (!command_line->HasSwitch(kCefViewBuiltinSchemeNameKey)) 52 | return ""; 53 | 54 | auto name = command_line->GetSwitchValue(kCefViewBuiltinSchemeNameKey); 55 | logI("built-in scheme name: %s", name.c_str()); 56 | return name; 57 | } 58 | 59 | void 60 | CefViewAppBase::OnRegisterCustomSchemes(CefRawPtr registrar) 61 | { 62 | if (registrar) { 63 | int options = 0 // 64 | | CEF_SCHEME_OPTION_STANDARD // 65 | | CEF_SCHEME_OPTION_SECURE // 66 | | CEF_SCHEME_OPTION_CORS_ENABLED // 67 | | CEF_SCHEME_OPTION_FETCH_ENABLED // 68 | | 0; 69 | auto scheme = builtin_scheme_name_.empty() ? kCefViewDefaultBuiltinSchemaName : builtin_scheme_name_; 70 | if (!registrar->AddCustomScheme(scheme, options)) { 71 | logE("faield to add built-in scheme: %s", scheme.c_str()); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewAppBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefWingAppBase.hpp 3 | // CefViewWing 4 | // 5 | // Created by Sheen Tian on 2020/6/17. 6 | // 7 | 8 | #ifndef CefAppBase_h 9 | #define CefAppBase_h 10 | 11 | #pragma region stl_headers 12 | #include 13 | #include 14 | #pragma endregion 15 | 16 | #pragma region cef_headers 17 | #include 18 | #pragma endregion 19 | 20 | class CefViewAppBase : public CefApp 21 | { 22 | /// 23 | /// 24 | /// 25 | CefString builtin_scheme_name_; 26 | 27 | public: 28 | CefViewAppBase(const CefString& scheme_name); 29 | 30 | enum ProcessType 31 | { 32 | UnkownProcess, 33 | ZygoteProcess, 34 | RendererProcess, 35 | OtherProcess, 36 | }; 37 | 38 | /// 39 | /// Gets the current process type 40 | /// 41 | /// The command line 42 | /// The process type 43 | static ProcessType GetProcessType(CefRefPtr command_line); 44 | 45 | /// 46 | /// Gets the bridge object name from command line 47 | /// 48 | /// The command line 49 | /// The bridge object name 50 | static CefString GetBridgeObjectName(CefRefPtr command_line); 51 | 52 | /// 53 | /// Gets the built-in scheme name 54 | /// 55 | /// The command line 56 | /// The built-in scheme name 57 | static CefString GetBuiltinSchemeName(CefRefPtr command_line); 58 | 59 | private: 60 | /// 61 | /// 62 | /// 63 | /// 64 | virtual void OnRegisterCustomSchemes(CefRawPtr registrar) override; 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewOtherApp.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewOtherApp.h" 2 | 3 | CefViewOtherApp::CefViewOtherApp(const CefString& scheme_name) 4 | : CefViewAppBase(scheme_name) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewOtherApp.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefOtherApp.hpp 3 | // CefViewWing 4 | // 5 | // Created by Sheen Tian on 2020/6/17. 6 | // 7 | 8 | #ifndef CefOtherApp_h 9 | #define CefOtherApp_h 10 | #pragma once 11 | 12 | #include "CefViewAppBase.h" 13 | 14 | class CefViewOtherApp : public CefViewAppBase 15 | { 16 | IMPLEMENT_REFCOUNTING(CefViewOtherApp); 17 | 18 | public: 19 | CefViewOtherApp(const CefString& scheme_name); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewRenderApp.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewRenderApp.h" 2 | 3 | #pragma region cef_headers 4 | #include 5 | #include 6 | #include 7 | #pragma endregion 8 | 9 | #include 10 | 11 | #include 12 | 13 | CefViewRenderApp::CefViewRenderApp(const CefString& scheme_name, const CefString& bridge_name) 14 | : CefViewAppBase(scheme_name) 15 | , bridge_object_name_(bridge_name) 16 | , last_node_is_editable_(false) 17 | { 18 | } 19 | 20 | CefViewRenderApp::~CefViewRenderApp() {} 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | CefRefPtr 24 | CefViewRenderApp::GetRenderProcessHandler() 25 | { 26 | return this; 27 | } 28 | 29 | void 30 | CefViewRenderApp::OnWebKitInitialized() 31 | { 32 | CEF_REQUIRE_RENDERER_THREAD(); 33 | 34 | CefMessageRouterConfig config; 35 | config.js_query_function = kCefViewQueryFuntionName; 36 | config.js_cancel_function = kCefViewQueryCancelFunctionName; 37 | message_router_ = CefMessageRouterRendererSide::Create(config); 38 | } 39 | 40 | void 41 | CefViewRenderApp::OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info) 42 | { 43 | CEF_REQUIRE_RENDERER_THREAD(); 44 | } 45 | 46 | void 47 | CefViewRenderApp::OnBrowserDestroyed(CefRefPtr browser) 48 | { 49 | CEF_REQUIRE_RENDERER_THREAD(); 50 | } 51 | 52 | CefRefPtr 53 | CefViewRenderApp::GetLoadHandler() 54 | { 55 | CEF_REQUIRE_RENDERER_THREAD(); 56 | 57 | return nullptr; 58 | } 59 | 60 | void 61 | CefViewRenderApp::OnContextCreated(CefRefPtr browser, 62 | CefRefPtr frame, 63 | CefRefPtr context) 64 | { 65 | CEF_REQUIRE_RENDERER_THREAD(); 66 | 67 | // [Javascript Context] 68 | // V8 context for this frame has been initialized already, 69 | // but the script of the page hasn't been executed now 70 | message_router_->OnContextCreated(browser, frame, context); 71 | 72 | // log this event 73 | frame->ExecuteJavaScript("console.info('[JSRuntime]:frame context created')", frame->GetURL(), 0); 74 | 75 | // binding bridge object and functions 76 | auto frameId = frame->GetIdentifier(); 77 | auto it = frame_id_to_bridge_obj_map_.find(frameId); 78 | if (it == frame_id_to_bridge_obj_map_.end()) { 79 | // create and insert the bridge Object into this frame.window object 80 | CefRefPtr objWindow = context->GetGlobal(); 81 | CefRefPtr objClient = new CefViewBridgeObject(browser, frame, objWindow, bridge_object_name_); 82 | if (!objClient) { 83 | log_error("Failed to create the client object"); 84 | return; 85 | } 86 | frame_id_to_bridge_obj_map_[frameId] = objClient; 87 | } 88 | } 89 | 90 | void 91 | CefViewRenderApp::OnContextReleased(CefRefPtr browser, 92 | CefRefPtr frame, 93 | CefRefPtr context) 94 | { 95 | CEF_REQUIRE_RENDERER_THREAD(); 96 | 97 | message_router_->OnContextReleased(browser, frame, context); 98 | 99 | auto frameId = frame->GetIdentifier(); 100 | auto it = frame_id_to_bridge_obj_map_.find(frameId); 101 | if (it != frame_id_to_bridge_obj_map_.end()) { 102 | frame_id_to_bridge_obj_map_.erase(it); 103 | } 104 | } 105 | 106 | void 107 | CefViewRenderApp::OnUncaughtException(CefRefPtr browser, 108 | CefRefPtr frame, 109 | CefRefPtr context, 110 | CefRefPtr exception, 111 | CefRefPtr stackTrace) 112 | { 113 | CEF_REQUIRE_RENDERER_THREAD(); 114 | } 115 | 116 | void 117 | CefViewRenderApp::OnFocusedNodeChanged(CefRefPtr browser, 118 | CefRefPtr frame, 119 | CefRefPtr node) 120 | { 121 | CEF_REQUIRE_RENDERER_THREAD(); 122 | 123 | bool is_editable = (node.get() && node->IsEditable()); 124 | if (is_editable != last_node_is_editable_) { 125 | // Notify the browser of the change in focused element type. 126 | last_node_is_editable_ = is_editable; 127 | CefRefPtr message = CefProcessMessage::Create(kCefViewClientRenderFocusedNodeChangedMessage); 128 | message->GetArgumentList()->SetBool(0, is_editable); 129 | frame->SendProcessMessage(PID_BROWSER, message); 130 | } 131 | } 132 | 133 | bool 134 | CefViewRenderApp::OnProcessMessageReceived(CefRefPtr browser, 135 | CefRefPtr frame, 136 | CefProcessId source_process, 137 | CefRefPtr message) 138 | { 139 | CEF_REQUIRE_RENDERER_THREAD(); 140 | 141 | bool handled = false; 142 | 143 | if (message_router_->OnProcessMessageReceived(browser, frame, source_process, message)) { 144 | handled = true; 145 | } 146 | 147 | if (OnTriggerEventNotifyMessage(browser, frame, source_process, message)) { 148 | handled = true; 149 | } 150 | 151 | return handled; 152 | } 153 | 154 | bool 155 | CefViewRenderApp::OnTriggerEventNotifyMessage(CefRefPtr browser, 156 | CefRefPtr frame, 157 | CefProcessId source_process, 158 | CefRefPtr message) 159 | { 160 | if (message->GetName() == kCefViewClientBrowserTriggerEventMessage) { 161 | CefRefPtr args = message->GetArgumentList()->Copy(); 162 | //** arguments(CefValueList) 163 | //** +------------+ 164 | //** | event name | 165 | //** | event arg1 | 166 | //** | event arg2 | 167 | //** | event arg3 | 168 | //** | event arg4 | 169 | //** | ... | 170 | //** | ... | 171 | //** | ... | 172 | //** | ... | 173 | //** +------------+ 174 | if (!args || args->GetSize() <= 0) { 175 | log_error("Invalid message arguments, event name is required"); 176 | return true; 177 | } 178 | 179 | if (CefValueType::VTYPE_STRING != args->GetType(0)) { 180 | log_error("Invalid message arguments, invalid type for event name"); 181 | return true; 182 | } 183 | 184 | auto name = args->GetString(0); 185 | args->Remove(0); 186 | ExecuteEventListener(browser, frame, name, args); 187 | 188 | return true; 189 | } 190 | 191 | return false; 192 | } 193 | 194 | void 195 | CefViewRenderApp::ExecuteEventListener(CefRefPtr browser, 196 | CefRefPtr frame, 197 | const CefString& name, 198 | CefRefPtr args) 199 | { 200 | if (browser && frame) { 201 | auto frameId = frame->GetIdentifier(); 202 | auto it = frame_id_to_bridge_obj_map_.find(frameId); 203 | if (it != frame_id_to_bridge_obj_map_.end()) { 204 | const CefRefPtr& objClient = it->second; 205 | objClient->ExecuteEventListener(name, args); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/CefWing/App/CefViewRenderApp.h: -------------------------------------------------------------------------------- 1 | #ifndef CefRenderApp_h 2 | #define CefRenderApp_h 3 | #pragma once 4 | 5 | #pragma region stl_headers 6 | #include 7 | #pragma endregion 8 | 9 | #pragma region cef_headers 10 | #include 11 | #pragma endregion 12 | 13 | #include 14 | 15 | #include "CefViewAppBase.h" 16 | #include "../Bridge/CefViewBridgeObject.h" 17 | 18 | /// 19 | /// 20 | /// 21 | class CefViewRenderApp 22 | : public CefViewAppBase 23 | , public CefRenderProcessHandler 24 | { 25 | // Include the default reference counting implementation. 26 | IMPLEMENT_REFCOUNTING(CefViewRenderApp); 27 | 28 | private: 29 | CefString bridge_object_name_; 30 | 31 | /// 32 | /// 33 | /// 34 | CefRefPtr message_router_; 35 | 36 | /// 37 | /// 38 | /// 39 | typedef std::unordered_map> FrameID2BridgeObjMap; 40 | FrameID2BridgeObjMap frame_id_to_bridge_obj_map_; 41 | 42 | /// 43 | /// 44 | /// 45 | bool last_node_is_editable_; 46 | 47 | public: 48 | /// 49 | /// 50 | /// 51 | CefViewRenderApp(const CefString& scheme_name, const CefString& bridge_name); 52 | 53 | /// 54 | /// 55 | /// 56 | ~CefViewRenderApp(); 57 | 58 | private: 59 | #pragma region CefApp 60 | /// 61 | /// 62 | /// 63 | /// 64 | virtual CefRefPtr GetRenderProcessHandler() override; 65 | 66 | #pragma endregion 67 | 68 | #pragma region CefRenderProcessHandler 69 | 70 | /// 71 | /// 72 | /// 73 | virtual void OnWebKitInitialized() override; 74 | 75 | /// 76 | /// 77 | /// 78 | /// 79 | /// 80 | virtual void OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info) override; 81 | 82 | /// 83 | /// 84 | /// 85 | /// 86 | virtual void OnBrowserDestroyed(CefRefPtr browser) override; 87 | 88 | /// 89 | /// 90 | /// 91 | /// 92 | virtual CefRefPtr GetLoadHandler() override; 93 | 94 | /// 95 | /// 96 | /// 97 | /// 98 | /// 99 | /// 100 | virtual void OnContextCreated(CefRefPtr browser, 101 | CefRefPtr frame, 102 | CefRefPtr context) override; 103 | 104 | /// 105 | /// 106 | /// 107 | /// 108 | /// 109 | /// 110 | virtual void OnContextReleased(CefRefPtr browser, 111 | CefRefPtr frame, 112 | CefRefPtr context) override; 113 | 114 | /// 115 | /// 116 | /// 117 | /// 118 | /// 119 | /// 120 | /// 121 | /// 122 | virtual void OnUncaughtException(CefRefPtr browser, 123 | CefRefPtr frame, 124 | CefRefPtr context, 125 | CefRefPtr exception, 126 | CefRefPtr stackTrace) override; 127 | 128 | /// 129 | /// 130 | /// 131 | /// 132 | /// 133 | /// 134 | virtual void OnFocusedNodeChanged(CefRefPtr browser, 135 | CefRefPtr frame, 136 | CefRefPtr node) override; 137 | 138 | /// 139 | /// 140 | /// 141 | /// 142 | /// 143 | /// 144 | /// 145 | /// 146 | virtual bool OnProcessMessageReceived(CefRefPtr browser, 147 | CefRefPtr frame, 148 | CefProcessId source_process, 149 | CefRefPtr message) override; 150 | 151 | #pragma endregion 152 | 153 | private: 154 | /// 155 | /// 156 | /// 157 | /// 158 | /// 159 | /// 160 | /// 161 | /// 162 | bool OnTriggerEventNotifyMessage(CefRefPtr browser, 163 | CefRefPtr frame, 164 | CefProcessId source_process, 165 | CefRefPtr message); 166 | 167 | /// 168 | /// 169 | /// 170 | /// 171 | /// 172 | /// 173 | /// 174 | void ExecuteEventListener(CefRefPtr browser, 175 | CefRefPtr frame, 176 | const CefString& name, 177 | CefRefPtr args); 178 | }; 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /src/CefWing/Bridge/CefViewBridgeObject.cpp: -------------------------------------------------------------------------------- 1 | #include "CefViewBridgeObject.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | #if CEF_VERSION_MAJOR >= 119 11 | class CefViewArrayBuffer : public CefV8ArrayBufferReleaseCallback 12 | { 13 | IMPLEMENT_REFCOUNTING(CefViewArrayBuffer); 14 | DISALLOW_COPY_AND_ASSIGN(CefViewArrayBuffer); 15 | 16 | public: 17 | /// 18 | /// 19 | /// 20 | /// 21 | CefViewArrayBuffer(CefBinaryValue* v) 22 | : m_size(0) 23 | , m_buffer(nullptr) 24 | { 25 | if (v) { 26 | auto l = v->GetSize(); 27 | if (l) { 28 | m_buffer = std::make_unique(l); 29 | v->GetData(m_buffer.get(), l, 0); 30 | m_size = l; 31 | } 32 | } 33 | } 34 | 35 | /// 36 | /// 37 | /// 38 | ~CefViewArrayBuffer() 39 | { 40 | m_buffer.reset(); 41 | m_size = 0; 42 | } 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | void* GetBuffer() 49 | { 50 | // get under layer buffer address 51 | return m_buffer.get(); 52 | } 53 | 54 | /// 55 | /// 56 | /// 57 | /// 58 | size_t GetSize() 59 | { 60 | // return size 61 | return m_size; 62 | } 63 | 64 | /// 65 | /// 66 | /// 67 | /// 68 | void ReleaseBuffer(void* buffer) override 69 | { 70 | // release under layer buffer 71 | m_buffer.reset(); 72 | m_size = 0; 73 | } 74 | 75 | private: 76 | size_t m_size; 77 | std::unique_ptr m_buffer; 78 | }; 79 | #endif 80 | 81 | CefViewBridgeObject::V8Handler::V8Handler(CefViewBridgeObject* object) 82 | : object_(object) 83 | { 84 | } 85 | 86 | bool 87 | CefViewBridgeObject::V8Handler::Execute(const CefString& function, 88 | CefRefPtr object, 89 | const CefV8ValueList& arguments, 90 | CefRefPtr& retval, 91 | CefString& exception) 92 | { 93 | if (function == kCefViewInvokeMethodFunctionName) 94 | ExecuteNativeMethod(object, arguments, retval, exception); 95 | else if (function == kCefViewAddEventListenerFunctionName) 96 | ExecuteAddEventListener(object, arguments, retval, exception); 97 | else if (function == kCefViewRemoveEventListenerFunctionName) 98 | ExecuteRemoveEventListener(object, arguments, retval, exception); 99 | else if (function == kCefViewReportJSResultFunctionName) 100 | ExecuteReportJSResult(object, arguments, retval, exception); 101 | else 102 | return false; 103 | 104 | return true; 105 | } 106 | 107 | void 108 | CefViewBridgeObject::V8Handler::ExecuteNativeMethod(CefRefPtr object, 109 | const CefV8ValueList& arguments, 110 | CefRefPtr& retval, 111 | CefString& exception) 112 | { 113 | object_->AsyncExecuteNativeMethod(arguments); 114 | retval = CefV8Value::CreateUndefined(); 115 | } 116 | 117 | void 118 | CefViewBridgeObject::V8Handler::ExecuteAddEventListener(CefRefPtr object, 119 | const CefV8ValueList& arguments, 120 | CefRefPtr& retval, 121 | CefString& exception) 122 | { 123 | bool bRet = false; 124 | 125 | if (arguments.size() == 2) { 126 | if (arguments[0]->IsString()) { 127 | if (arguments[1]->IsFunction()) { 128 | CefString eventName = arguments[0]->GetStringValue(); 129 | EventListener listener; 130 | listener.callback_ = arguments[1]; 131 | listener.context_ = CefV8Context::GetCurrentContext(); 132 | object_->AddEventListener(eventName, listener); 133 | bRet = true; 134 | } else 135 | exception = "Invalid arguments; argument 2 must be a function"; 136 | } else 137 | exception = "Invalid arguments; argument 1 must be a string"; 138 | } else 139 | exception = "Invalid arguments; expecting 2 arguments"; 140 | 141 | retval = CefV8Value::CreateBool(bRet); 142 | } 143 | 144 | void 145 | CefViewBridgeObject::V8Handler::ExecuteRemoveEventListener(CefRefPtr object, 146 | const CefV8ValueList& arguments, 147 | CefRefPtr& retval, 148 | CefString& exception) 149 | { 150 | bool bRet = false; 151 | 152 | if (arguments.size() == 2) { 153 | if (arguments[0]->IsString()) { 154 | if (arguments[1]->IsFunction()) { 155 | CefString eventName = arguments[0]->GetStringValue(); 156 | EventListener listener; 157 | listener.callback_ = arguments[1]; 158 | listener.context_ = CefV8Context::GetCurrentContext(); 159 | object_->RemoveEventListener(eventName, listener); 160 | bRet = true; 161 | } else 162 | exception = "Invalid arguments; argument 2 must be a function"; 163 | } else 164 | exception = "Invalid arguments; argument 1 must be a string"; 165 | } else 166 | exception = "Invalid arguments; expecting 2 arguments"; 167 | 168 | retval = CefV8Value::CreateBool(bRet); 169 | } 170 | 171 | void 172 | CefViewBridgeObject::V8Handler::ExecuteReportJSResult(CefRefPtr object, 173 | const CefV8ValueList& arguments, 174 | CefRefPtr& retval, 175 | CefString& exception) 176 | { 177 | if (arguments.size() == 2) { 178 | if (arguments[0]->IsString()) { 179 | object_->AsyncExecuteReportJSResult(arguments); 180 | } else 181 | exception = "Invalid argument; argument 1 must be a double"; 182 | } else 183 | exception = "Invalid argument; expecting 2 argument"; 184 | 185 | retval = CefV8Value::CreateUndefined(); 186 | } 187 | 188 | ////////////////////////////////////////////////////////////////////////// 189 | 190 | CefViewBridgeObject::CefViewBridgeObject(CefRefPtr browser, 191 | CefRefPtr frame, 192 | CefRefPtr global, 193 | const CefString& name) 194 | : name_(name.empty() ? kCefViewDefaultBridgeObjectName : name) 195 | , bridgeObject_(nullptr) 196 | , reportJSResultFunction_(nullptr) 197 | , browser_(browser) 198 | , frame_(frame) 199 | , v8Handler_(new V8Handler(this)) 200 | { 201 | // create bridge object and mount it on the global context(window) 202 | bridgeObject_ = CefV8Value::CreateObject(nullptr, nullptr); 203 | 204 | // create function "invokeMethod" 205 | CefRefPtr funcInvokeMethod = CefV8Value::CreateFunction(kCefViewInvokeMethodFunctionName, v8Handler_); 206 | // add this function to window object 207 | bridgeObject_->SetValue(kCefViewInvokeMethodFunctionName, 208 | funcInvokeMethod, 209 | static_cast(V8_PROPERTY_ATTRIBUTE_READONLY | 210 | V8_PROPERTY_ATTRIBUTE_DONTENUM | 211 | V8_PROPERTY_ATTRIBUTE_DONTDELETE)); 212 | 213 | // create function addEventListener 214 | CefRefPtr funcAddEventListener = 215 | CefV8Value::CreateFunction(kCefViewAddEventListenerFunctionName, v8Handler_); 216 | // add this function to window object 217 | bridgeObject_->SetValue(kCefViewAddEventListenerFunctionName, 218 | funcAddEventListener, 219 | static_cast(V8_PROPERTY_ATTRIBUTE_READONLY | 220 | V8_PROPERTY_ATTRIBUTE_DONTENUM | 221 | V8_PROPERTY_ATTRIBUTE_DONTDELETE)); 222 | 223 | // create function removeListener 224 | CefRefPtr funcRemoveEventListener = 225 | CefV8Value::CreateFunction(kCefViewRemoveEventListenerFunctionName, v8Handler_); 226 | // add this function to window object 227 | bridgeObject_->SetValue(kCefViewRemoveEventListenerFunctionName, 228 | funcRemoveEventListener, 229 | static_cast(V8_PROPERTY_ATTRIBUTE_READONLY | 230 | V8_PROPERTY_ATTRIBUTE_DONTENUM | 231 | V8_PROPERTY_ATTRIBUTE_DONTDELETE)); 232 | 233 | // mount the client object to the global context(usually the window object) 234 | global->SetValue(name_, 235 | bridgeObject_, 236 | static_cast(V8_PROPERTY_ATTRIBUTE_READONLY | 237 | V8_PROPERTY_ATTRIBUTE_DONTENUM | 238 | V8_PROPERTY_ATTRIBUTE_DONTDELETE)); 239 | frame_->ExecuteJavaScript("console.info('[JSRuntime]:window." + name_.ToString() + " [object] created');", frame_->GetURL(), 0); 240 | 241 | // create "__cefview_report_js_result__" function and mount it on the global context(window) 242 | reportJSResultFunction_ = CefV8Value::CreateFunction(kCefViewReportJSResultFunctionName, v8Handler_); 243 | global->SetValue(kCefViewReportJSResultFunctionName, 244 | reportJSResultFunction_, 245 | static_cast(V8_PROPERTY_ATTRIBUTE_READONLY | 246 | V8_PROPERTY_ATTRIBUTE_DONTENUM | 247 | V8_PROPERTY_ATTRIBUTE_DONTDELETE)); 248 | frame_->ExecuteJavaScript("console.info('[JSRuntime]:window." kCefViewReportJSResultFunctionName 249 | " [function] created');", 250 | frame_->GetURL(), 251 | 0); 252 | } 253 | 254 | CefRefPtr 255 | CefViewBridgeObject::CefValueToV8Value(CefValue* cefValue) 256 | { 257 | CefRefPtr v8Value = CefV8Value::CreateNull(); 258 | if (!cefValue) { 259 | return v8Value; 260 | } 261 | 262 | auto type = cefValue->GetType(); 263 | switch (type) { 264 | case CefValueType::VTYPE_INVALID: { 265 | v8Value = CefV8Value::CreateUndefined(); 266 | } break; 267 | case CefValueType::VTYPE_NULL: { 268 | v8Value = CefV8Value::CreateNull(); 269 | } break; 270 | case CefValueType::VTYPE_BOOL: { 271 | auto v = cefValue->GetBool(); 272 | v8Value = CefV8Value::CreateBool(v); 273 | } break; 274 | case CefValueType::VTYPE_INT: { 275 | auto v = cefValue->GetInt(); 276 | v8Value = CefV8Value::CreateInt(v); 277 | } break; 278 | case CefValueType::VTYPE_DOUBLE: { 279 | auto v = cefValue->GetDouble(); 280 | v8Value = CefV8Value::CreateDouble(v); 281 | } break; 282 | case CefValueType::VTYPE_STRING: { 283 | auto v = cefValue->GetString(); 284 | v8Value = CefV8Value::CreateString(v); 285 | } break; 286 | case CefValueType::VTYPE_BINARY: { 287 | #if CEF_VERSION_MAJOR >= 119 288 | auto v = cefValue->GetBinary(); 289 | auto arryBuffer = new CefViewArrayBuffer(v.get()); 290 | v8Value = CefV8Value::CreateArrayBuffer(arryBuffer->GetBuffer(), arryBuffer->GetSize(), arryBuffer); 291 | #else 292 | // currently not supported 293 | #endif 294 | } break; 295 | case CefValueType::VTYPE_DICTIONARY: { 296 | auto cDict = cefValue->GetDictionary(); 297 | CefDictionaryValue::KeyList cKeys; 298 | cDict->GetKeys(cKeys); 299 | v8Value = CefV8Value::CreateObject(nullptr, nullptr); 300 | for (auto& key : cKeys) { 301 | auto cVal = cDict->GetValue(key); 302 | auto v8Val = CefValueToV8Value(cVal.get()); 303 | v8Value->SetValue(key, v8Val.get(), V8_PROPERTY_ATTRIBUTE_NONE); 304 | } 305 | } break; 306 | case CefValueType::VTYPE_LIST: { 307 | auto cList = cefValue->GetList(); 308 | int cCount = static_cast(cList->GetSize()); 309 | v8Value = CefV8Value::CreateArray(static_cast(cCount)); 310 | for (int i = 0; i < cCount; i++) { 311 | auto cVal = cList->GetValue(i); 312 | auto v8Val = CefValueToV8Value(cVal.get()); 313 | v8Value->SetValue(i, v8Val.get()); 314 | } 315 | } break; 316 | default: 317 | break; 318 | } 319 | 320 | return v8Value; 321 | } 322 | 323 | CefRefPtr 324 | CefViewBridgeObject::V8ValueToCefValue(CefV8Value* v8Value) 325 | { 326 | CefRefPtr cefValue = CefValue::Create(); 327 | if (!v8Value) { 328 | return cefValue; 329 | } 330 | 331 | /** 332 | * The IsDouble, IsInt and IsUint methods return a boolean value indicating whether the CefV8Value instance is an 333 | * target type or can be converted to the target type.If the value can be converted to the target type, the methods 334 | * will attempt to do so and return true. If the value is not the target type or cannot be converted to the target 335 | * type, the method will return false. 336 | * 337 | * For example the code below: 338 | * auto v = CefV8Value::CreateInt(1000); 339 | * auto isDouble = v->IsDouble(); 340 | * logD("isDouble: %d", isDouble); // true 341 | * auto isUnint = v->IsUInt(); 342 | * logD("isUnint: %d", isUnint); // true 343 | * auto isInt = v->IsInt(); 344 | * logD("isInt: %d", isInt); // true 345 | * 346 | * auto v = CefV8Value::CreateDouble(0.1); 347 | * auto isDouble = v->IsDouble(); 348 | * logD("isDouble: %d", isDouble); // true 349 | * auto isUnint = v->IsUInt(); 350 | * logD("isUnint: %d", isUnint); // false 351 | * auto isInt = v->IsInt(); 352 | * logD("isInt: %d", isInt); // false 353 | * 354 | * so we need to keep the testing order, IsInt/IsUint - IsDouble 355 | * since there is no Uint type in JavaScript, we just ignore it. 356 | * Please refer to this test souce: 357 | * https://github.com/svn2github/cef/blob/master/tests/cefclient/binding_test.cpp 358 | */ 359 | if (v8Value->IsNull() || v8Value->IsUndefined()) 360 | cefValue->SetNull(); 361 | else if (v8Value->IsBool()) 362 | cefValue->SetBool(v8Value->GetBoolValue()); 363 | else if (v8Value->IsInt()) 364 | cefValue->SetInt(v8Value->GetIntValue()); 365 | else if (v8Value->IsDouble()) 366 | cefValue->SetDouble(v8Value->GetDoubleValue()); 367 | else if (v8Value->IsString()) 368 | cefValue->SetString(v8Value->GetStringValue()); 369 | else if (v8Value->IsArrayBuffer()) { 370 | #if CEF_VERSION_MAJOR >= 119 371 | auto size = v8Value->GetArrayBufferByteLength(); 372 | auto data = v8Value->GetArrayBufferData(); 373 | cefValue->SetBinary(CefBinaryValue::Create(data, size)); 374 | #else 375 | // currently not supported 376 | #endif 377 | } else if (v8Value->IsArray()) { 378 | auto s = v8Value->GetArrayLength(); 379 | auto cefList = CefListValue::Create(); 380 | for (int i = 0; i < s; i++) { 381 | auto v8Val = v8Value->GetValue(i); 382 | auto cefVal = V8ValueToCefValue(v8Val.get()); 383 | cefList->SetValue(i, cefVal); 384 | } 385 | cefValue->SetList(cefList); 386 | } else if (v8Value->IsObject()) { 387 | CefDictionaryValue::KeyList keys; 388 | v8Value->GetKeys(keys); 389 | auto cefDict = CefDictionaryValue::Create(); 390 | for (auto& key : keys) { 391 | auto v8Val = v8Value->GetValue(key); 392 | auto cefVal = V8ValueToCefValue(v8Val.get()); 393 | cefDict->SetValue(key, cefVal.get()); 394 | } 395 | cefValue->SetDictionary(cefDict); 396 | } else 397 | cefValue->SetNull(); 398 | 399 | return cefValue; 400 | } 401 | 402 | void 403 | CefViewBridgeObject::AsyncExecuteNativeMethod(const CefV8ValueList& arguments) 404 | { 405 | CefRefPtr msg = CefProcessMessage::Create(kCefViewClientRenderInvokeMethodMessage); 406 | 407 | //** arguments(CefValueList) 408 | //** +-------+ 409 | //** |0 name | <- the method name 410 | //** |1 arg1 | 411 | //** |2 arg2 | 412 | //** |3 arg3 | 413 | //** |4 arg4 | 414 | //** | ... | 415 | //** | ... | 416 | //** | ... | 417 | //** | ... | 418 | //** +-------+ 419 | CefRefPtr args = msg->GetArgumentList(); 420 | 421 | // push back all the arguments 422 | for (std::size_t i = 0; i < arguments.size(); i++) { 423 | auto cefValue = V8ValueToCefValue(arguments[i].get()); 424 | args->SetValue(i, cefValue); 425 | } 426 | 427 | // send the message 428 | if (browser_) 429 | frame_->SendProcessMessage(PID_BROWSER, msg); 430 | } 431 | 432 | void 433 | CefViewBridgeObject::AsyncExecuteReportJSResult(const CefV8ValueList& arguments) 434 | { 435 | CefRefPtr msg = CefProcessMessage::Create(kCefViewClientRenderReportJSResultMessage); 436 | 437 | //** arguments(CefValueList) 438 | //** +_------+ 439 | //** |0 arg | <- the context (string) 440 | //** |1 arg | <- the result value 441 | //** +-------+ 442 | CefRefPtr args = msg->GetArgumentList(); 443 | 444 | // push back the result value 445 | for (std::size_t i = 0; i < arguments.size(); i++) { 446 | auto cefValue = V8ValueToCefValue(arguments[i].get()); 447 | args->SetValue(i, cefValue.get()); 448 | } 449 | 450 | // send the message 451 | if (browser_) 452 | frame_->SendProcessMessage(PID_BROWSER, msg); 453 | } 454 | 455 | void 456 | CefViewBridgeObject::AddEventListener(const CefString& name, const EventListener& listener) 457 | { 458 | auto itListenerList = eventListenerListMap_.find(name); 459 | if (itListenerList == eventListenerListMap_.end()) { 460 | EventListenerList eventListenerList; 461 | eventListenerList.push_back(listener); 462 | eventListenerListMap_[name] = eventListenerList; 463 | } else { 464 | EventListenerList& eventListenerList = itListenerList->second; 465 | // does this listener exist? 466 | bool found = false; 467 | for (auto item : eventListenerList) { 468 | if (item.callback_->IsSame(listener.callback_)) { 469 | found = true; 470 | break; 471 | } 472 | } 473 | 474 | if (!found) 475 | eventListenerList.push_back(listener); 476 | } 477 | } 478 | 479 | void 480 | CefViewBridgeObject::RemoveEventListener(const CefString& name, const EventListener& listener) 481 | { 482 | auto itListenerList = eventListenerListMap_.find(name); 483 | if (itListenerList != eventListenerListMap_.end()) { 484 | EventListenerList& eventListenerList = itListenerList->second; 485 | for (auto itListener = eventListenerList.begin(); itListener != eventListenerList.end(); itListener++) { 486 | if (itListener->callback_->IsSame(listener.callback_)) { 487 | eventListenerList.erase(itListener); 488 | break; 489 | } 490 | } 491 | } 492 | } 493 | 494 | void 495 | CefViewBridgeObject::ExecuteEventListener(const CefString eventName, CefRefPtr args) 496 | { 497 | // find the listeners 498 | auto itListenerList = eventListenerListMap_.find(eventName); 499 | if (itListenerList == eventListenerListMap_.end()) { 500 | return; 501 | } 502 | 503 | EventListenerList& eventListenerList = itListenerList->second; 504 | for (auto listener : eventListenerList) { 505 | listener.context_->Enter(); 506 | 507 | // convert argument list from CefValue to CefV8Value 508 | CefV8ValueList v8ArgList; 509 | for (size_t i = 0; i < args->GetSize(); i++) { 510 | auto cefValue = args->GetValue(i); 511 | auto v8Value = CefValueToV8Value(cefValue.get()); 512 | v8ArgList.push_back(v8Value.get()); 513 | } 514 | 515 | listener.callback_->ExecuteFunction(bridgeObject_, v8ArgList); 516 | listener.context_->Exit(); 517 | } 518 | } 519 | -------------------------------------------------------------------------------- /src/CefWing/Bridge/CefViewBridgeObject.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma region stl_headers 3 | #include 4 | #include 5 | #pragma endregion 6 | 7 | #pragma region cef_headers 8 | #include 9 | #pragma endregion 10 | 11 | /// 12 | /// 13 | /// 14 | class CefViewBridgeObject : public CefBaseRefCounted 15 | { 16 | IMPLEMENT_REFCOUNTING(CefViewBridgeObject); 17 | DISALLOW_COPY_AND_ASSIGN(CefViewBridgeObject); 18 | 19 | /// 20 | /// 21 | /// 22 | typedef struct _EventListener 23 | { 24 | CefRefPtr callback_; 25 | CefRefPtr context_; 26 | } EventListener; 27 | 28 | /// 29 | /// 30 | /// 31 | typedef std::list EventListenerList; 32 | 33 | /// 34 | /// 35 | /// 36 | typedef std::map> EventListenerListMap; 37 | 38 | /// 39 | /// 40 | /// 41 | class V8Handler : public CefV8Handler 42 | { 43 | public: 44 | /// 45 | /// 46 | /// 47 | /// 48 | V8Handler(CefViewBridgeObject* object); 49 | 50 | /// 51 | /// 52 | /// 53 | /// 54 | /// 55 | /// 56 | /// 57 | /// 58 | /// 59 | virtual bool Execute(const CefString& function, 60 | CefRefPtr object, 61 | const CefV8ValueList& arguments, 62 | CefRefPtr& retval, 63 | CefString& exception) override; 64 | 65 | protected: 66 | /// 67 | /// 68 | /// 69 | /// 70 | /// 71 | /// 72 | /// 73 | void ExecuteNativeMethod(CefRefPtr object, 74 | const CefV8ValueList& arguments, 75 | CefRefPtr& retval, 76 | CefString& exception); 77 | 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | /// 84 | /// 85 | void ExecuteAddEventListener(CefRefPtr object, 86 | const CefV8ValueList& arguments, 87 | CefRefPtr& retval, 88 | CefString& exception); 89 | 90 | /// 91 | /// 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | void ExecuteRemoveEventListener(CefRefPtr object, 98 | const CefV8ValueList& arguments, 99 | CefRefPtr& retval, 100 | CefString& exception); 101 | 102 | /// 103 | /// 104 | /// 105 | /// 106 | /// 107 | /// 108 | /// 109 | void ExecuteReportJSResult(CefRefPtr object, 110 | const CefV8ValueList& arguments, 111 | CefRefPtr& retval, 112 | CefString& exception); 113 | 114 | private: 115 | /// 116 | /// 117 | /// 118 | CefViewBridgeObject* object_; 119 | 120 | private: 121 | IMPLEMENT_REFCOUNTING(V8Handler); 122 | }; 123 | 124 | public: 125 | /// 126 | /// 127 | /// 128 | /// 129 | /// 130 | /// 131 | /// 132 | CefViewBridgeObject(CefRefPtr browser, 133 | CefRefPtr frame, 134 | CefRefPtr global, 135 | const CefString& name); 136 | 137 | /// 138 | /// 139 | /// 140 | /// 141 | /// 142 | /// 143 | CefRefPtr CefValueToV8Value(CefValue* cefValue); 144 | 145 | /// 146 | /// 147 | /// 148 | /// 149 | /// 150 | CefRefPtr V8ValueToCefValue(CefV8Value* v8Value); 151 | 152 | /// 153 | /// 154 | /// 155 | /// 156 | void AsyncExecuteNativeMethod(const CefV8ValueList& arguments); 157 | 158 | /// 159 | /// 160 | /// 161 | /// 162 | void AsyncExecuteReportJSResult(const CefV8ValueList& arguments); 163 | 164 | /// 165 | /// 166 | /// 167 | /// 168 | /// 169 | /// 170 | void AddEventListener(const CefString& name, const EventListener& listener); 171 | 172 | /// 173 | /// 174 | /// 175 | /// 176 | /// 177 | void RemoveEventListener(const CefString& name, const EventListener& listener); 178 | 179 | /// 180 | /// 181 | /// 182 | /// 183 | /// 184 | void ExecuteEventListener(const CefString eventName, CefRefPtr args); 185 | 186 | private: 187 | /// 188 | /// 189 | /// 190 | CefString name_; 191 | 192 | /// 193 | /// 194 | /// 195 | CefRefPtr bridgeObject_; 196 | 197 | /// 198 | /// 199 | /// 200 | CefRefPtr reportJSResultFunction_; 201 | 202 | /// 203 | /// 204 | /// 205 | CefRefPtr browser_; 206 | 207 | /// 208 | /// 209 | /// 210 | CefRefPtr frame_; 211 | 212 | /// 213 | /// 214 | /// 215 | CefRefPtr v8Handler_; 216 | 217 | /// 218 | /// 219 | /// 220 | CefViewBridgeObject::EventListenerListMap eventListenerListMap_; 221 | }; 222 | -------------------------------------------------------------------------------- /src/CefWing/linux/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // CeViewfWing 4 | // 5 | // Created by Sheen Tian on 2020/6/10. 6 | // 7 | 8 | #pragma region cef_headers 9 | #include 10 | #pragma endregion 11 | 12 | #include 13 | 14 | #include "../App/CefViewAppBase.h" 15 | #include "../App/CefViewOtherApp.h" 16 | #include "../App/CefViewRenderApp.h" 17 | 18 | int 19 | CefViewWingMain(int argc, char* argv[]) 20 | { 21 | logI("CefViewWing is launching...."); 22 | CefMainArgs main_args(argc, argv); 23 | 24 | CefRefPtr app; 25 | CefRefPtr command_line = CefCommandLine::CreateCommandLine(); 26 | command_line->InitFromArgv(argc, argv); 27 | 28 | // get parameter from command line 29 | auto process_type = CefViewAppBase::GetProcessType(command_line); 30 | auto builtin_scheme_name = CefViewAppBase::GetBuiltinSchemeName(command_line); 31 | auto bridge_object_name = CefViewAppBase::GetBridgeObjectName(command_line); 32 | 33 | if (process_type == CefViewAppBase::RendererProcess || process_type == CefViewAppBase::ZygoteProcess) { 34 | app = new CefViewRenderApp(builtin_scheme_name, bridge_object_name); 35 | } else if (process_type == CefViewAppBase::OtherProcess) { 36 | app = new CefViewOtherApp(builtin_scheme_name); 37 | } else { 38 | logI("Parse process unknown, exit"); 39 | return 1; 40 | } 41 | 42 | // Execute the secondary process. 43 | int rt = CefExecuteProcess(main_args, app, nullptr); 44 | logI("process returned with code: %d", rt); 45 | 46 | return rt; 47 | } 48 | 49 | // Program entry point function. 50 | int 51 | main(int argc, const char* argv[]) 52 | { 53 | return CefViewWingMain(argc, const_cast(argv)); 54 | } 55 | -------------------------------------------------------------------------------- /src/CefWing/mac/CefViewWing.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.disable-library-validation 8 | 9 | com.apple.security.cs.allow-jit 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/CefWing/mac/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 CefView. All rights reserved. 27 | LSUIElement 28 | 1 29 | LSFileQuarantineEnabled 30 | 31 | NSSupportsAutomaticGraphicsSwitching 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/CefWing/mac/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CefViewWing 4 | // 5 | // Created by Sheen Tian on 2020/6/10. 6 | // 7 | 8 | #pragma region cef_headers 9 | #include 10 | #include 11 | #if defined(CEF_USE_SANDBOX) 12 | #include 13 | #endif 14 | #pragma endregion 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "../App/CefViewAppBase.h" 23 | #include "../App/CefViewOtherApp.h" 24 | #include "../App/CefViewRenderApp.h" 25 | 26 | const char kFrameworkPath[] = "Chromium Embedded Framework.framework/Chromium Embedded Framework"; 27 | const char kPathFromHelperExe[] = "../../.."; 28 | 29 | std::string GetFrameworkPath() { 30 | uint32_t exec_path_size = 0; 31 | int rv = _NSGetExecutablePath(NULL, &exec_path_size); 32 | if (rv != -1) { 33 | return std::string(); 34 | } 35 | 36 | std::unique_ptr exec_path(new char[exec_path_size]); 37 | rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size); 38 | if (rv != 0) { 39 | return std::string(); 40 | } 41 | 42 | // Get the directory path of the executable. 43 | const char *parent_dir = dirname(exec_path.get()); 44 | if (!parent_dir) { 45 | return std::string(); 46 | } 47 | 48 | // Append the relative path to the framework. 49 | std::stringstream ss; 50 | ss << parent_dir << "/" << kPathFromHelperExe << "/" << kFrameworkPath; 51 | return ss.str(); 52 | } 53 | 54 | bool LoadCefLibrary() { 55 | std::string cef_lib_path = GetFrameworkPath(); 56 | return (1 == cef_load_library(cef_lib_path.c_str())); 57 | } 58 | 59 | int CefViewWingMain(int argc, char *argv[]) { 60 | logI("CefViewWing is launching...."); 61 | 62 | #if defined(CEF_USE_SANDBOX) 63 | // Initialize the macOS sandbox for this helper process. 64 | CefScopedSandboxContext sandbox_context; 65 | logI("Initializing the sandbox context"); 66 | if (!sandbox_context.Initialize(argc, argv)) { 67 | logE("Failed to initialize the cef sandbox context"); 68 | return 1; 69 | } 70 | #endif 71 | 72 | logI("Loading the cef library"); 73 | if (!LoadCefLibrary()) { 74 | logI("Failed to load cef library"); 75 | return 1; 76 | } 77 | 78 | CefMainArgs main_args(argc, argv); 79 | 80 | CefRefPtr app; 81 | CefRefPtr command_line = CefCommandLine::CreateCommandLine(); 82 | command_line->InitFromArgv(argc, argv); 83 | 84 | // get parameter from command line 85 | auto process_type = CefViewAppBase::GetProcessType(command_line); 86 | auto builtin_scheme_name = CefViewAppBase::GetBuiltinSchemeName(command_line); 87 | auto bridge_object_name = CefViewAppBase::GetBridgeObjectName(command_line); 88 | 89 | if (process_type == CefViewAppBase::RendererProcess) { 90 | app = new CefViewRenderApp(builtin_scheme_name, bridge_object_name); 91 | } else if (process_type == CefViewAppBase::OtherProcess) { 92 | app = new CefViewOtherApp(builtin_scheme_name); 93 | } else { 94 | logI("Parse process unknown, exit"); 95 | return 1; 96 | } 97 | 98 | // Execute the secondary process. 99 | int rt = CefExecuteProcess(main_args, app, nullptr); 100 | logI("process returned with code: %d", rt); 101 | 102 | return rt; 103 | } 104 | 105 | int main(int argc, const char *argv[]) { 106 | // main 107 | return CefViewWingMain(argc, const_cast(argv)); 108 | } 109 | -------------------------------------------------------------------------------- /src/CefWing/win/CefViewWing.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | QCefView Auxiliary Process 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/CefWing/win/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // CeViewfWing 4 | // 5 | // Created by Sheen Tian on 2020/6/10. 6 | // 7 | 8 | #pragma region cef_headers 9 | #include 10 | #include 11 | #if defined(CEF_USE_SANDBOX) 12 | #include 13 | #endif 14 | #pragma endregion 15 | 16 | #include 17 | 18 | #include 19 | 20 | #include "../App/CefViewAppBase.h" 21 | #include "../App/CefViewOtherApp.h" 22 | #include "../App/CefViewRenderApp.h" 23 | 24 | #if defined(ENABLE_GPU_OPTIMUS) && ENABLE_GPU_OPTIMUS 25 | extern "C" 26 | { 27 | // http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf 28 | __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; 29 | 30 | // https://gpuopen.com/learn/amdpowerxpressrequesthighperformance 31 | _declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001; 32 | } 33 | #endif 34 | 35 | int 36 | CefViewWingMain(HINSTANCE hInstance) 37 | { 38 | logI("CefViewWing is launching...."); 39 | #if CEF_VERSION_MAJOR < 112 40 | CefEnableHighDPISupport(); 41 | #endif 42 | 43 | void* sandbox_info = NULL; 44 | #if defined(CEF_USE_SANDBOX) 45 | // Manage the life span of the sandbox information object. This is necessary 46 | // for sandbox support on Windows. See cef_sandbox_win.h for complete details. 47 | CefScopedSandboxInfo scoped_sandbox; 48 | sandbox_info = scoped_sandbox.sandbox_info(); 49 | #endif 50 | 51 | CefMainArgs main_args(hInstance); 52 | 53 | CefRefPtr app; 54 | CefRefPtr command_line = CefCommandLine::CreateCommandLine(); 55 | command_line->InitFromString(::GetCommandLineW()); 56 | 57 | // get parameter from command line 58 | auto process_type = CefViewAppBase::GetProcessType(command_line); 59 | auto builtin_scheme_name = CefViewAppBase::GetBuiltinSchemeName(command_line); 60 | auto bridge_object_name = CefViewAppBase::GetBridgeObjectName(command_line); 61 | 62 | // create application 63 | if (process_type == CefViewAppBase::RendererProcess) { 64 | app = new CefViewRenderApp(builtin_scheme_name, bridge_object_name); 65 | } else if (process_type == CefViewAppBase::OtherProcess) { 66 | app = new CefViewOtherApp(builtin_scheme_name); 67 | } else { 68 | logI("Parse process unknown, exit"); 69 | return 1; 70 | } 71 | 72 | // assign current process to window job 73 | if (command_line->HasSwitch(kCefViewWindowsJobNameKey)) { 74 | auto job_name = command_line->GetSwitchValue(kCefViewWindowsJobNameKey); 75 | HANDLE job_handle = ::OpenJobObjectA(JOB_OBJECT_ASSIGN_PROCESS, FALSE, job_name.ToString().c_str()); 76 | if (job_handle) { 77 | if (!::AssignProcessToJobObject(job_handle, ::GetCurrentProcess())) { 78 | logE("Failed to assign current process to windows job object: %d", ::GetLastError()); 79 | } 80 | ::CloseHandle(job_handle); 81 | } else { 82 | logE("Failed to open windows job object: %d", ::GetLastError()); 83 | } 84 | } 85 | 86 | // Execute the secondary process. 87 | int rt = CefExecuteProcess(main_args, app, sandbox_info); 88 | logI("process returned with code: %d", rt); 89 | 90 | return rt; 91 | } 92 | 93 | // Program entry point function. 94 | int APIENTRY 95 | wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 96 | { 97 | UNREFERENCED_PARAMETER(hPrevInstance); 98 | UNREFERENCED_PARAMETER(lpCmdLine); 99 | return CefViewWingMain(hInstance); 100 | } 101 | -------------------------------------------------------------------------------- /src/CefWing/win/resource.rc.in: -------------------------------------------------------------------------------- 1 | #include "winres.h" 2 | 3 | IDI_ICON ICON app.ico 4 | -------------------------------------------------------------------------------- /src/Shared/Common/CefViewCoreLog.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewCoreLog.cpp 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/19. 6 | // 7 | 8 | #include "CefViewCoreLog.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | typedef enum log_level 15 | { 16 | ll_debug = 1, 17 | ll_info, 18 | ll_error, 19 | ll_fatal, 20 | } log_level; 21 | 22 | #if defined(__APPLE__) 23 | #include 24 | void 25 | cefView_log(log_level level, const char* message) 26 | { 27 | switch (level) { 28 | case ll_debug: 29 | os_log_debug(OS_LOG_DEFAULT, "[DEBUG]%s", message); 30 | break; 31 | case ll_info: 32 | os_log_info(OS_LOG_DEFAULT, "[INFO]%s", message); 33 | break; 34 | case ll_error: 35 | os_log_error(OS_LOG_DEFAULT, "[ERROR]%s", message); 36 | break; 37 | case ll_fatal: 38 | os_log_fault(OS_LOG_DEFAULT, "[FATAL]%s", message); 39 | break; 40 | default: 41 | break; 42 | } 43 | } 44 | #elif defined(_WIN32) 45 | #include 46 | void 47 | cefView_log(log_level level, const char* message) 48 | { 49 | std::string msg; 50 | switch (level) { 51 | case ll_debug: 52 | msg = "[DEBUG]"; 53 | break; 54 | case ll_info: 55 | msg = "[INFO]"; 56 | break; 57 | case ll_error: 58 | msg = "[ERROR]"; 59 | break; 60 | case ll_fatal: 61 | msg = "[FATAL]"; 62 | break; 63 | default: 64 | msg = "[]"; 65 | break; 66 | } 67 | msg += message; 68 | msg += "\r\n"; 69 | OutputDebugStringA(msg.c_str()); 70 | } 71 | #elif defined(__linux__) 72 | #include 73 | void 74 | cefView_log(log_level level, const char* message) 75 | { 76 | switch (level) { 77 | case ll_debug: 78 | syslog(LOG_USER | LOG_DEBUG, "[DEBUG]%s", message); 79 | break; 80 | case ll_info: 81 | syslog(LOG_USER | LOG_INFO, "[INFO]%s", message); 82 | break; 83 | case ll_error: 84 | syslog(LOG_USER | LOG_ERR, "[ERROR]%s", message); 85 | break; 86 | case ll_fatal: 87 | syslog(LOG_USER | LOG_CRIT, "[FATAL]%s", message); 88 | break; 89 | default: 90 | break; 91 | } 92 | } 93 | #else 94 | #error "unsupported platform" 95 | #endif 96 | 97 | #define LOG_MSG_BUFFER_LIMIT 4096 98 | 99 | void 100 | log_debug(const char* fmt, ...) 101 | { 102 | std::vector msg(LOG_MSG_BUFFER_LIMIT, 0); 103 | va_list args; 104 | va_start(args, fmt); 105 | vsnprintf(msg.data(), LOG_MSG_BUFFER_LIMIT, fmt, args); 106 | va_end(args); 107 | cefView_log(ll_debug, msg.data()); 108 | } 109 | 110 | void 111 | log_info(const char* fmt, ...) 112 | { 113 | std::vector msg(LOG_MSG_BUFFER_LIMIT, 0); 114 | va_list args; 115 | va_start(args, fmt); 116 | vsnprintf(msg.data(), LOG_MSG_BUFFER_LIMIT, fmt, args); 117 | va_end(args); 118 | cefView_log(ll_info, msg.data()); 119 | } 120 | 121 | void 122 | log_error(const char* fmt, ...) 123 | { 124 | std::vector msg(LOG_MSG_BUFFER_LIMIT, 0); 125 | va_list args; 126 | va_start(args, fmt); 127 | vsnprintf(msg.data(), LOG_MSG_BUFFER_LIMIT, fmt, args); 128 | va_end(args); 129 | cefView_log(ll_error, msg.data()); 130 | } 131 | 132 | void 133 | log_fatal(const char* fmt, ...) 134 | { 135 | std::vector msg(LOG_MSG_BUFFER_LIMIT, 0); 136 | va_list args; 137 | va_start(args, fmt); 138 | vsnprintf(msg.data(), LOG_MSG_BUFFER_LIMIT, fmt, args); 139 | va_end(args); 140 | cefView_log(ll_fatal, msg.data()); 141 | } 142 | -------------------------------------------------------------------------------- /src/Shared/Common/CefViewCoreLog.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewCoreLog.h 3 | // CefViewCore 4 | // 5 | // Created by Sheen Tian on 2020/6/19. 6 | // 7 | 8 | #ifndef CefViewCoreLog_h 9 | #define CefViewCoreLog_h 10 | #pragma once 11 | #include 12 | 13 | void 14 | log_debug(const char* fmt, ...); 15 | void 16 | log_info(const char* fmt, ...); 17 | void 18 | log_error(const char* fmt, ...); 19 | void 20 | log_fatal(const char* fmt, ...); 21 | 22 | class ScopeLogger 23 | { 24 | public: 25 | ScopeLogger(const std::string& fn) 26 | : functionName_(fn) 27 | { 28 | // enter scope 29 | log_debug("+++ %s", functionName_.c_str()); 30 | } 31 | 32 | ~ScopeLogger() 33 | { 34 | // leave scope 35 | log_debug("--- %s", functionName_.c_str()); 36 | } 37 | 38 | std::string functionName_; 39 | }; 40 | 41 | #if (defined(DEBUG) || defined(_DEBUG) || !defined(NDEBUG)) 42 | // DEBUG BUILD 43 | #define logD(format, ...) log_debug(format, ##__VA_ARGS__) 44 | #define logI(format, ...) log_info(format, ##__VA_ARGS__) 45 | #define logE(format, ...) log_error(format, ##__VA_ARGS__) 46 | #define logF(format, ...) log_fatal(format, ##__VA_ARGS__) 47 | #define logScope() ScopeLogger __scope_logger__(__FUNCTION__); 48 | #else 49 | // RELEASE BUILD 50 | #define logD(format, ...) 51 | #define logI(format, ...) log_info(format, ##__VA_ARGS__) 52 | #define logE(format, ...) log_error(format, ##__VA_ARGS__) 53 | #define logF(format, ...) log_fatal(format, ##__VA_ARGS__) 54 | #define logScope() 55 | #endif 56 | 57 | #endif /* CefViewCoreLog_hpp */ 58 | -------------------------------------------------------------------------------- /src/Shared/Common/CefViewDebug.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewCoreLog.cpp 3 | // CefViewCore 4 | // 5 | // Created by leashi on 2022/5/10. 6 | // 7 | 8 | #include 9 | 10 | #include "CefViewDebug.h" 11 | 12 | #include 13 | 14 | std::string 15 | toString(CefRefPtr browser) 16 | { 17 | std::string msg; 18 | 19 | msg += "( "; 20 | msg += "CefBrowser:"; 21 | msg += ", ptr=" + std::to_string((int64_t)browser.get()); 22 | #if CEF_VERSION_MAJOR > 91 23 | msg += ", IsValid=" + std::to_string(browser->IsValid()); 24 | #endif 25 | msg += ", GetHost=" + std::to_string((int64_t)browser->GetHost().get()); 26 | msg += ", CanGoBack=" + std::to_string(browser->CanGoBack()); 27 | msg += ", CanGoForward=" + std::to_string(browser->CanGoForward()); 28 | msg += ", IsLoading=" + std::to_string(browser->IsLoading()); 29 | msg += ", GetIdentifier=" + std::to_string(browser->GetIdentifier()); 30 | msg += ", IsPopup=" + std::to_string(browser->IsPopup()); 31 | msg += ", HasDocument=" + std::to_string(browser->HasDocument()); 32 | msg += ", GetMainFrame=" + std::to_string((int64_t)browser->GetMainFrame().get()); 33 | msg += ", GetFocusedFrame=" + std::to_string((int64_t)browser->GetFocusedFrame().get()); 34 | msg += ", GetFrameCount=" + std::to_string(browser->GetFrameCount()); 35 | msg += " )"; 36 | 37 | return msg; 38 | } 39 | 40 | std::string 41 | toString(CefRefPtr frame) 42 | { 43 | std::string msg; 44 | 45 | msg += "( "; 46 | msg += "CefFrame:"; 47 | msg += ", ptr=" + std::to_string((int64_t)frame.get()); 48 | msg += ", IsValid=" + std::to_string(frame->IsValid()); 49 | msg += ", IsMain=" + std::to_string(frame->IsMain()); 50 | msg += ", IsFocused=" + std::to_string(frame->IsFocused()); 51 | msg += ", GetName=" + frame->GetName().ToString(); 52 | #if CEF_VERSION_MAJOR < 122 53 | msg += ", GetIdentifier=" + std::to_string(frame->GetIdentifier()); 54 | #else 55 | msg += ", GetIdentifier=" + frame->GetIdentifier().ToString(); 56 | #endif 57 | msg += ", GetParent=" + std::to_string((int64_t)frame->GetParent().get()); 58 | msg += ", GetURL=" + frame->GetURL().ToString(); 59 | msg += ", GetBrowser=" + std::to_string((int64_t)frame->GetBrowser().get()); 60 | // msg += ", GetV8Context=" + std::to_string((int64_t)frame->GetV8Context().get()); 61 | msg += " )"; 62 | 63 | return msg; 64 | } 65 | -------------------------------------------------------------------------------- /src/Shared/Common/CefViewDebug.h: -------------------------------------------------------------------------------- 1 | // 2 | // CefViewDebug.h 3 | // CefViewCore 4 | // 5 | // Created by leashi on 2022/5/10. 6 | // 7 | 8 | #ifndef CefViewDebug_h 9 | #define CefViewDebug_h 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | 17 | std::string toString(CefRefPtr browser); 18 | std::string toString(CefRefPtr frame); 19 | 20 | 21 | #endif /* CefViewDebug_h */ 22 | --------------------------------------------------------------------------------