I have successfully implemented a window binding as described by herein: https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration.
All that remains, really, is to instruct cocoa to actually change the size of the window. It's here that I get what appears to be a very strange error. I say error because the window seems to be frozen at this point. What actually happens is that upon calling the function to change the window size, the window un-paints itself and turns grey.
I'm not seeing any similar errors upon a google search which leads me to think that I'm probably screwing up the syntax.
Two things occur to me.
Firstly, I wonder if I'm trying to call "[window setFrame: newRect display: YES]" in the wrong process. If that is the case, which process do I need to be calling it in, and which process am I currently calling from? Eventually learning IPC will have to happen but I'm still at the start of my cef journey.
Secondly- that the screen turns grey leads to think that maybe an un-paint function is being called prior to the browser then attempting to resize the window. A error might then be occurring which prevents the resize and as such, no re-paint function is being called, resulting in an unpainted, blank page.
Below is all of my code which is in any way different from what ships with the binary. The files window_controller.h, .cc, and .mm are all specific to my project.
CMakeLists.txt
- Code: Select all
# Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
# reserved. Use of this source code is governed by a BSD-style license that
# can be found in the LICENSE file.
#
# Source files.
#
# cefsimple sources.
set(CEFSIMPLE_SRCS
simple_app.cc
simple_app.h
simple_handler.cc
simple_handler.h
)
set(CEFSIMPLE_SRCS_LINUX
cefsimple_linux.cc
simple_handler_linux.cc
)
set(CEFSIMPLE_SRCS_MACOSX
cefsimple_mac.mm
simple_handler_mac.mm
)
set(CEFSIMPLE_SRCS_WINDOWS
cefsimple.rc
cefsimple_win.cc
resource.h
simple_handler_win.cc
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_SRCS)
source_group(cefsimple FILES ${CEFSIMPLE_SRCS})
set(CEFSIMPLE_SRCS
${CEFSIMPLE_SRCS}
)
# cefsimple helper sources.
set(CEFSIMPLE_HELPER_SRCS_MACOSX
process_helper_mac.cc
window_controller.cc
window_controller.h
window_controller.mm
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_HELPER_SRCS)
source_group(cefsimple FILES ${CEFSIMPLE_HELPER_SRCS})
# cefsimple resources.
set(CEFSIMPLE_RESOURCES_MAC_SRCS_MACOSX
mac/Info.plist
mac/cefsimple.icns
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_RESOURCES_MAC_SRCS)
source_group(cefsimple\\\\mac FILES ${CEFSIMPLE_RESOURCES_MAC_SRCS})
set(CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS_MACOSX
mac/English.lproj/InfoPlist.strings
mac/English.lproj/MainMenu.xib
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS)
source_group(cefsimple\\\\mac\\\\English.lproj FILES ${CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS})
set(CEFSIMPLE_RESOURCES_SRCS
${CEFSIMPLE_RESOURCES_MAC_SRCS}
${CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS}
)
#
# Shared configuration.
#
# Target executable names.
set(CEF_TARGET "cefsimple")
if(OS_MACOSX)
set(CEF_HELPER_TARGET "cefsimple_Helper")
set(CEF_HELPER_OUTPUT_NAME "cefsimple Helper")
else()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
endif()
# Determine the target output directory.
SET_CEF_TARGET_OUT_DIR()
#
# Linux configuration.
#
if(OS_LINUX)
# Executable target.
add_executable(${CEF_TARGET} ${CEFSIMPLE_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper)
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
# Set rpath so that libraries can be placed next to the executable.
set_target_properties(${CEF_TARGET} PROPERTIES INSTALL_RPATH "$ORIGIN")
set_target_properties(${CEF_TARGET} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
set_target_properties(${CEF_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
# Copy binary and resource files to the target output directory.
COPY_FILES("${CEF_TARGET}" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
COPY_FILES("${CEF_TARGET}" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CEF_TARGET_OUT_DIR}")
if (EXISTS "${CEF_BINARY_DIR}/libminigbm.so")
COPY_FILES("${CEF_TARGET}" "libminigbm.so" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
endif()
# Set SUID permissions on the chrome-sandbox target.
SET_LINUX_SUID_PERMISSIONS("${CEF_TARGET}" "${CEF_TARGET_OUT_DIR}/chrome-sandbox")
endif()
#
# Mac OS X configuration.
#
if(OS_MACOSX)
option(OPTION_USE_ARC "Build with ARC (automatic Reference Counting) on macOS." ON)
if(OPTION_USE_ARC)
list(APPEND CEF_COMPILER_FLAGS
-fobjc-arc
)
set_target_properties(${target} PROPERTIES
CLANG_ENABLE_OBJC_ARC "YES"
)
endif()
# Output path for the main app bundle.
set(CEF_APP "${CEF_TARGET_OUT_DIR}/${CEF_TARGET}.app")
# Variables referenced from the main Info.plist file.
set(EXECUTABLE_NAME "${CEF_TARGET}")
set(PRODUCT_NAME "${CEF_TARGET}")
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
endif()
# Main app bundle target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFSIMPLE_RESOURCES_SRCS} ${CEFSIMPLE_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper)
target_link_libraries(${CEF_TARGET} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/Info.plist
)
# Copy the CEF framework into the Frameworks directory.
add_custom_command(
TARGET ${CEF_TARGET}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CEF_BINARY_DIR}/Chromium Embedded Framework.framework"
"${CEF_APP}/Contents/Frameworks/Chromium Embedded Framework.framework"
VERBATIM
)
# Create the multiple Helper app bundle targets.
foreach(_suffix_list ${CEF_HELPER_APP_SUFFIXES})
# Convert to a list and extract the suffix values.
string(REPLACE ":" ";" _suffix_list ${_suffix_list})
list(GET _suffix_list 0 _name_suffix)
list(GET _suffix_list 1 _target_suffix)
list(GET _suffix_list 2 _plist_suffix)
# Define Helper target and output names.
set(_helper_target "${CEF_HELPER_TARGET}${_target_suffix}")
set(_helper_output_name "${CEF_HELPER_OUTPUT_NAME}${_name_suffix}")
# Create Helper-specific variants of the helper-Info.plist file. Do this
# manually because the configure_file command (which is executed as part of
# MACOSX_BUNDLE_INFO_PLIST) uses global env variables and would insert the
# wrong values with multiple targets.
set(_helper_info_plist "${CMAKE_CURRENT_BINARY_DIR}/helper-Info${_target_suffix}.plist")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/mac/helper-Info.plist" _plist_contents)
string(REPLACE "\${EXECUTABLE_NAME}" "${_helper_output_name}" _plist_contents ${_plist_contents})
string(REPLACE "\${PRODUCT_NAME}" "${_helper_output_name}" _plist_contents ${_plist_contents})
string(REPLACE "\${BUNDLE_ID_SUFFIX}" "${_plist_suffix}" _plist_contents ${_plist_contents})
file(WRITE ${_helper_info_plist} ${_plist_contents})
# Create Helper executable target.
add_executable(${_helper_target} MACOSX_BUNDLE ${CEFSIMPLE_HELPER_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${_helper_target})
add_dependencies(${_helper_target} libcef_dll_wrapper)
target_link_libraries(${_helper_target} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${_helper_target} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${_helper_info_plist}
OUTPUT_NAME ${_helper_output_name}
)
if(USE_SANDBOX)
target_link_libraries(${_helper_target} cef_sandbox_lib)
endif()
# Add the Helper as a dependency of the main executable target.
add_dependencies(${CEF_TARGET} "${_helper_target}")
# Copy the Helper app bundle into the Frameworks directory.
add_custom_command(
TARGET ${CEF_TARGET}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CEF_TARGET_OUT_DIR}/${_helper_output_name}.app"
"${CEF_APP}/Contents/Frameworks/${_helper_output_name}.app"
VERBATIM
)
endforeach()
# Manually process and copy over resource files.
# The Xcode generator can support this via the set_target_properties RESOURCE
# directive but that doesn't properly handle nested resource directories.
# Remove these prefixes from input file paths.
set(PREFIXES "mac/")
COPY_MACOSX_RESOURCES("${CEFSIMPLE_RESOURCES_SRCS}" "${PREFIXES}" "${CEF_TARGET}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_APP}")
endif()
#
# Windows configuration.
#
if(OS_WINDOWS)
# Executable target.
add_executable(${CEF_TARGET} WIN32 ${CEFSIMPLE_SRCS})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper)
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_TARGET} cef_sandbox_lib ${CEF_SANDBOX_STANDARD_LIBS})
endif()
# Add the custom manifest files to the executable.
ADD_WINDOWS_MANIFEST("${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_TARGET}" "exe")
# Copy binary and resource files to the target output directory.
COPY_FILES("${CEF_TARGET}" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
COPY_FILES("${CEF_TARGET}" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CEF_TARGET_OUT_DIR}")
endif()
process_helper_mac.mm
- Code: Select all
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
#include "include/cef_app.h"
#include "include/wrapper/cef_library_loader.h"
#include "tests/cefsimple/window_controller.h"
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_mac.h"
#endif
// Entry point function for sub-processes.
int main(int argc, char* argv[]) {
#if defined(CEF_USE_SANDBOX)
// Initialize the macOS sandbox for this helper process.
CefScopedSandboxContext sandbox_context;
if (!sandbox_context.Initialize(argc, argv))
return 1;
#endif
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInHelper())
return 1;
// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);
CefRefPtr<WindowController> app(new WindowController);
// Execute the sub-process.
return CefExecuteProcess(main_args, app, NULL);
}
window_controller.h
- Code: Select all
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFSIMPLE_WINDOW_CONTROLLER_H_
#define CEF_TESTS_CEFSIMPLE_WINDOW_CONTROLLER_H_
#include "include/cef_app.h"
#include "include/cef_browser.h"
// Implement application-level callbacks for the browser process.
class WindowController : public CefApp, public CefRenderProcessHandler {
public:
WindowController();
static void SetPos(CefRefPtr<CefBrowser> browser,
int x,
int y,
int width,
int height);
static void Minimize(CefRefPtr<CefBrowser> browser);
static void Maximize(CefRefPtr<CefBrowser> browser);
static void Restore(CefRefPtr<CefBrowser> browser);
static void ModifyBounds(const CefRect& display, CefRect& window);
// CefApp methods:
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()
OVERRIDE {
return this;
}
virtual void OnContextCreated( CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context ) OVERRIDE;
private:
IMPLEMENT_REFCOUNTING(WindowController);
};
#endif // CEF_TESTS_CEFSIMPLE_WINDOW_CONTROLLER_H_
window_controller.cc
- Code: Select all
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "tests/cefsimple/window_controller.h"
class resizeToHandler : public CefV8Handler {
public:
resizeToHandler() {}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
retval = NULL;
if (name == "_resizeTo") {
CefRefPtr<CefBrowser> browser = CefV8Context::GetCurrentContext()->GetBrowser();
int xPos = 100;
int yPos = 100;
int newWidth = arguments[0]->GetIntValue();
int newHeight = arguments[1]->GetIntValue();
WindowController::SetPos( browser,
xPos,
yPos,
newWidth,
newHeight );
return true;
}
return false;
}
// Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(resizeToHandler);
};
WindowController::WindowController() {}
void WindowController::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
CefRefPtr<CefV8Value> object = context->GetGlobal();
CefRefPtr<CefV8Handler> _resizeToHandler = new resizeToHandler();
CefRefPtr<CefV8Value> _resizeToFunction = CefV8Value::CreateFunction("_resizeTo", _resizeToHandler);
object->SetValue("_resizeTo", _resizeToFunction, V8_PROPERTY_ATTRIBUTE_NONE);
}
void WindowController::ModifyBounds(const CefRect& display, CefRect& window) {
window.x += display.x;
window.y += display.y;
if (window.x < display.x)
window.x = display.x;
if (window.y < display.y)
window.y = display.y;
if (window.width < 100)
window.width = 100;
else if (window.width >= display.width)
window.width = display.width;
if (window.height < 100)
window.height = 100;
else if (window.height >= display.height)
window.height = display.height;
if (window.x + window.width >= display.x + display.width)
window.x = display.x + display.width - window.width;
if (window.y + window.height >= display.y + display.height)
window.y = display.y + display.height - window.height;
}
window_controller.mm
- Code: Select all
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "tests/cefsimple/window_controller.h"
#import <Cocoa/Cocoa.h>
#include "include/cef_browser.h"
NSWindow* GetWindow(CefRefPtr<CefBrowser> browser) {
NSView* view =
CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(browser->GetHost()->GetWindowHandle());
return [view window];
}
void WindowController::SetPos(CefRefPtr<CefBrowser> browser,
int xPos,
int yPos,
int width,
int height ) {
NSWindow* window = GetWindow(browser);
NSRect newRect;
newRect.origin.x = xPos;
newRect.origin.y = yPos;
newRect.size.width = width;
newRect.size.height = height;
[window setFrame: newRect display: YES];
}
void WindowController::Minimize(CefRefPtr<CefBrowser> browser) {
}
void WindowController::Maximize(CefRefPtr<CefBrowser> browser) {
}
void WindowController::Restore(CefRefPtr<CefBrowser> browser) {
}
resize_test.html
- Code: Select all
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body style="background-color: black">
<script type="text/javascript">
window.resizeTo( 500, 250 );
</script>
</body>
</html>
Sorry I can't give a more detailed description of the problem. I'm a bit out of my depth. Hopefully my code will speak for themselves.