From 561bb6956b2bfd2b1fe8e73b5802d4850c68cd4c Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 21 Oct 2011 19:35:19 +0000 Subject: [PATCH] Add support for transparency on Windows (issue #99). - Enable the use of Skia instead of GDI for text rendering. - Add a new CefWindowInfo::m_bTransparentPainting member. - Add transparent popup window and off-screen rendering examples to cefclient. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@334 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- cef.gypi | 2 + cef_paths.gypi | 1 + include/internal/cef_types_win.h | 3 + include/internal/cef_win.h | 6 + libcef/browser_impl_win.cc | 40 ++++++ libcef/webwidget_host_win.cc | 12 ++ tests/cefclient/cefclient.h | 4 + tests/cefclient/cefclient.rc | 3 + tests/cefclient/cefclient_win.cpp | 29 +++- tests/cefclient/client_handler.cpp | 8 +- tests/cefclient/client_handler.h | 10 +- tests/cefclient/client_handler_win.cpp | 8 +- tests/cefclient/osrplugin.cpp | 176 +++++++++++++++++++++---- tests/cefclient/osrplugin.h | 2 + tests/cefclient/osrplugin_test.cpp | 12 +- tests/cefclient/osrplugin_test.h | 2 +- tests/cefclient/res/osrplugin.html | 4 +- tests/cefclient/res/transparency.html | 36 +++++ tests/cefclient/resource.h | 3 + 19 files changed, 316 insertions(+), 45 deletions(-) create mode 100644 tests/cefclient/res/transparency.html diff --git a/cef.gypi b/cef.gypi index 886a67536..04ecebd5e 100644 --- a/cef.gypi +++ b/cef.gypi @@ -10,6 +10,8 @@ 'cef_directory' : 'm_hWndParent = src->m_hWndParent; target->m_hMenu = src->m_hMenu; target->m_bWindowRenderingDisabled = src->m_bWindowRenderingDisabled; + target->m_bTransparentPainting = src->m_bTransparentPainting; target->m_hWnd = src->m_hWnd; } }; @@ -144,6 +145,11 @@ public: m_bWindowRenderingDisabled = TRUE; m_hWndParent = hWndParent; } + + void SetTransparentPainting(BOOL transparentPainting) + { + m_bTransparentPainting = transparentPainting; + } }; diff --git a/libcef/browser_impl_win.cc b/libcef/browser_impl_win.cc index 658f9bc02..853e998a6 100644 --- a/libcef/browser_impl_win.cc +++ b/libcef/browser_impl_win.cc @@ -8,6 +8,7 @@ #include "browser_settings.h" #include "printing/units.h" +#include "base/win/windows_version.h" #include "skia/ext/vector_canvas.h" #include "skia/ext/vector_platform_device_emf_win.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" @@ -18,14 +19,37 @@ #include "ui/base/win/hwnd_util.h" #include "webkit/glue/webpreferences.h" +#include #include #include #include #include +#pragma comment(lib, "dwmapi.lib") + using WebKit::WebRect; using WebKit::WebSize; +namespace { + +bool IsAeroGlassEnabled() { + if (base::win::GetVersion() < base::win::VERSION_VISTA) + return false; + + BOOL enabled = FALSE; + return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled; +} + +void SetAeroGlass(HWND hWnd) { + if (!IsAeroGlassEnabled()) + return; + + // Make the whole window transparent. + MARGINS mgMarInset = { -1, -1, -1, -1 }; + DwmExtendFrameIntoClientArea(hWnd, &mgMarInset); +} + +} // namespace LPCTSTR CefBrowserImpl::GetWndClass() { @@ -100,6 +124,13 @@ LRESULT CALLBACK CefBrowserImpl::WndProc(HWND hwnd, UINT message, case WM_ERASEBKGND: return 0; + + case WM_DWMCOMPOSITIONCHANGED: + // Message sent to top-level windows when composition has been enabled or + // disabled. + if (browser->window_info_.m_bTransparentPainting) + SetAeroGlass(hwnd); + break; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -148,6 +179,12 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url) ::GetModuleHandle(NULL), NULL); DCHECK(window_info_.m_hWnd != NULL); + if (window_info_.m_bTransparentPainting && + !(window_info_.m_dwStyle & WS_CHILD)) { + // Transparent top-level windows will be given "sheet of glass" effect. + SetAeroGlass(window_info_.m_hWnd); + } + // Set window user data to this object for future reference from the window // procedure ui::SetWindowUserData(window_info_.m_hWnd, this); @@ -174,6 +211,9 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url) paint_delegate_.get(), dev_tools_agent_.get(), prefs)); + if (window_info_.m_bTransparentPainting) + webviewhost_->webview()->setIsTransparent(true); + if (!settings_.developer_tools_disabled) dev_tools_agent_->SetWebView(webviewhost_->webview()); diff --git a/libcef/webwidget_host_win.cc b/libcef/webwidget_host_win.cc index 2b63741ba..5fd84736f 100644 --- a/libcef/webwidget_host_win.cc +++ b/libcef/webwidget_host_win.cc @@ -16,6 +16,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebInputEventFactory.h" #include "third_party/WebKit/Source/WebKit/chromium/public/win/WebScreenInfoFactory.h" #include "ui/base/ime/composition_text.h" @@ -709,6 +710,17 @@ void WebWidgetHost::PaintRect(const gfx::Rect& rect) { #endif DCHECK(canvas_.get()); + if (!popup() && ((WebKit::WebView*)webwidget_)->isTransparent()) { + // When using transparency mode clear the rectangle before painting. + SkPaint clearpaint; + clearpaint.setARGB(0,0,0,0); + clearpaint.setXfermodeMode(SkXfermode::kClear_Mode); + + SkRect skrc; + skrc.set(rect.x(), rect.y(), rect.right(), rect.bottom()); + canvas_->drawRect(skrc, clearpaint); + } + set_painting(true); webwidget_->paint(canvas_.get(), rect); set_painting(false); diff --git a/tests/cefclient/cefclient.h b/tests/cefclient/cefclient.h index ceb76cf12..1fcfccbd8 100644 --- a/tests/cefclient/cefclient.h +++ b/tests/cefclient/cefclient.h @@ -33,4 +33,8 @@ void RunDOMAccessTest(CefRefPtr browser); void RunDragDropTest(CefRefPtr browser); void RunModalDialogTest(CefRefPtr browser); +#if defined(OS_WIN) +void RunTransparentPopupTest(CefRefPtr browser); +#endif + #endif // _CEFCLIENT_H diff --git a/tests/cefclient/cefclient.rc b/tests/cefclient/cefclient.rc index d69de0f30..95b852d6e 100644 --- a/tests/cefclient/cefclient.rc +++ b/tests/cefclient/cefclient.rc @@ -38,6 +38,7 @@ IDS_DOMACCESS BINARY "res\\domaccess.html" IDS_MODALMAIN BINARY "res\\modalmain.html" IDS_MODALDIALOG BINARY "res\\modaldialog.html" IDS_EXTENSIONPERF BINARY "res\\extensionperf.html" +IDS_TRANSPARENCY BINARY "res\\transparency.html" ///////////////////////////////////////////////////////////////////////////// // @@ -78,10 +79,12 @@ BEGIN MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE MENUITEM "Plugin", ID_TESTS_PLUGIN MENUITEM "Popup Window", ID_TESTS_POPUP + MENUITEM "Transparent Popup Window", ID_TESTS_TRANSPARENT_POPUP MENUITEM "Request", ID_TESTS_REQUEST MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER MENUITEM "UI App Example", ID_TESTS_UIAPP MENUITEM "Off-Screen Rendering Example",ID_TESTS_OSRAPP + MENUITEM "Transparent Off-Screen Rendering Example",ID_TESTS_TRANSPARENT_OSRAPP MENUITEM "Local Storage", ID_TESTS_LOCALSTORAGE MENUITEM "XMLHttpRequest", ID_TESTS_XMLHTTPREQUEST MENUITEM "WebURLRequest", ID_TESTS_WEBURLREQUEST diff --git a/tests/cefclient/cefclient_win.cpp b/tests/cefclient/cefclient_win.cpp index c8ceff8be..7172fa1cb 100644 --- a/tests/cefclient/cefclient_win.cpp +++ b/tests/cefclient/cefclient_win.cpp @@ -374,7 +374,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Initialize window info to the defaults for a child window info.SetAsChild(hWnd, rect); - // Creat the new child child browser window + // Creat the new child browser window CefBrowser::CreateBrowser(info, static_cast >(g_handler), "http://www.google.com", settings); @@ -495,6 +495,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if(browser.get()) RunPopupTest(browser); return 0; + case ID_TESTS_TRANSPARENT_POPUP: // Test a transparent popup window + if(browser.get()) + RunTransparentPopupTest(browser); + return 0; case ID_TESTS_REQUEST: // Test a request if(browser.get()) RunRequestTest(browser); @@ -509,7 +513,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case ID_TESTS_OSRAPP: // Test the OSR app if(browser.get()) - RunOSRPluginTest(browser); + RunOSRPluginTest(browser, false); + return 0; + case ID_TESTS_TRANSPARENT_OSRAPP: // Test the OSR app with transparency + if(browser.get()) + RunOSRPluginTest(browser, true); return 0; case ID_TESTS_DOMACCESS: // Test DOM access if(browser.get()) @@ -665,3 +673,20 @@ std::string AppGetWorkingDirectory() { return szWorkingDir; } + +void RunTransparentPopupTest(CefRefPtr browser) +{ + CefWindowInfo info; + CefBrowserSettings settings; + + // Initialize window info to the defaults for a popup window + info.SetAsPopup(NULL, "TransparentPopup"); + info.SetTransparentPainting(TRUE); + info.m_nWidth = 500; + info.m_nHeight = 500; + + // Creat the popup browser window + CefBrowser::CreateBrowser(info, + static_cast >(g_handler), + "http://tests/transparency", settings); +} diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index 29edffa3e..30c3b1d88 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -35,7 +35,7 @@ void ClientHandler::OnAfterCreated(CefRefPtr browser) REQUIRE_UI_THREAD(); AutoLock lock_scope(this); - if(!browser->IsPopup()) + if(!m_Browser.get()) { // We need to keep the main child window, but not popup windows m_Browser = browser; @@ -47,7 +47,7 @@ bool ClientHandler::DoClose(CefRefPtr browser) { REQUIRE_UI_THREAD(); - if (!browser->IsPopup()) { + if (m_BrowserHwnd == browser->GetWindowHandle()) { // Since the main window contains the browser window, we need to close // the parent window instead of the browser window. CloseMainWindow(); @@ -78,7 +78,7 @@ void ClientHandler::OnLoadStart(CefRefPtr browser, { REQUIRE_UI_THREAD(); - if(!browser->IsPopup() && frame->IsMain()) { + if(m_BrowserHwnd == browser->GetWindowHandle() && frame->IsMain()) { // We've just started loading a page SetLoading(true); } @@ -90,7 +90,7 @@ void ClientHandler::OnLoadEnd(CefRefPtr browser, { REQUIRE_UI_THREAD(); - if(!browser->IsPopup() && frame->IsMain()) { + if(m_BrowserHwnd == browser->GetWindowHandle() && frame->IsMain()) { // We've just finished loading a page SetLoading(false); diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index 5834b8850..edf434e79 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -54,11 +54,11 @@ public: // CefLifeSpanHandler methods virtual bool OnBeforePopup(CefRefPtr parentBrowser, - const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, - const CefString& url, - CefRefPtr& client, - CefBrowserSettings& settings) OVERRIDE; + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + const CefString& url, + CefRefPtr& client, + CefBrowserSettings& settings) OVERRIDE; virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; virtual bool DoClose(CefRefPtr browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; diff --git a/tests/cefclient/client_handler_win.cpp b/tests/cefclient/client_handler_win.cpp index 3db7149a6..eed894484 100644 --- a/tests/cefclient/client_handler_win.cpp +++ b/tests/cefclient/client_handler_win.cpp @@ -24,7 +24,7 @@ bool ClientHandler::OnBeforePopup(CefRefPtr parentBrowser, #ifdef TEST_REDIRECT_POPUP_URLS std::string urlStr = url; - if(urlStr.find("resources/inspector/devtools.html") == std::string::npos) { + if(urlStr.find("chrome-devtools:") == std::string::npos) { // Show all popup windows excluding DevTools in the current window. windowInfo.m_dwStyle &= ~WS_VISIBLE; client = new ClientPopupHandler(m_Browser); @@ -95,6 +95,10 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr browser, resourceStream = GetBinaryResourceReader(IDS_MODALDIALOG); response->SetMimeType("text/html"); response->SetStatus(200); + } else if(url == "http://tests/transparency") { + resourceStream = GetBinaryResourceReader(IDS_TRANSPARENCY); + response->SetMimeType("text/html"); + response->SetStatus(200); } return false; @@ -120,7 +124,7 @@ void ClientHandler::OnTitleChange(CefRefPtr browser, // Set the frame window title bar CefWindowHandle hwnd = browser->GetWindowHandle(); - if(!browser->IsPopup()) + if(m_BrowserHwnd == hwnd) { // The frame window will be the parent of the browser window hwnd = GetParent(hwnd); diff --git a/tests/cefclient/osrplugin.cpp b/tests/cefclient/osrplugin.cpp index 8dc0a15cb..c16e48ed4 100644 --- a/tests/cefclient/osrplugin.cpp +++ b/tests/cefclient/osrplugin.cpp @@ -4,9 +4,11 @@ // found in the LICENSE file. #include "include/cef.h" -#include "osrplugin.h" #include "cefclient.h" #include "client_popup_handler.h" +#include "osrplugin.h" +#include "resource.h" +#include "resource_util.h" #include "string_util.h" #include "util.h" #include @@ -28,6 +30,12 @@ float g_spinY = 0.0f; int g_width = -1, g_height = -1; CefRefPtr g_offscreenBrowser; +// If set to true alpha transparency will be used. +bool g_offscreenTransparent = false; + +#define GL_IMAGE_FORMAT (g_offscreenTransparent?GL_RGBA:GL_RGB) +#define GL_BYTE_COUNT (g_offscreenTransparent?4:3) + // Class holding pointers for the client plugin window. class ClientPlugin { @@ -48,6 +56,7 @@ public: class ClientOSRHandler : public CefClient, public CefLifeSpanHandler, public CefLoadHandler, + public CefRequestHandler, public CefDisplayHandler, public CefRenderHandler { @@ -73,6 +82,8 @@ public: { return this; } virtual CefRefPtr GetLoadHandler() OVERRIDE { return this; } + virtual CefRefPtr GetRequestHandler() OVERRIDE + { return this; } virtual CefRefPtr GetDisplayHandler() OVERRIDE { return this; } virtual CefRefPtr GetRenderHandler() OVERRIDE @@ -134,6 +145,27 @@ public: } } + // CefRequestHandler methods + + virtual bool OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr request, + CefString& redirectUrl, + CefRefPtr& resourceStream, + CefRefPtr response, + int loadFlags) OVERRIDE + { + REQUIRE_IO_THREAD(); + + std::string url = request->GetURL(); + if(url == "http://tests/transparency") { + resourceStream = GetBinaryResourceReader(IDS_TRANSPARENCY); + response->SetMimeType("text/html"); + response->SetStatus(200); + } + + return false; + } + // CefDisplayHandler methods virtual void OnNavStateChange(CefRefPtr browser, @@ -254,32 +286,55 @@ public: REQUIRE_UI_THREAD(); wglMakeCurrent(plugin_->hDC, plugin_->hRC); - + + if (g_offscreenTransparent) { + // Enable alpha blending. + glEnable(GL_BLEND); + } + + // Enable 2D textures. + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, g_textureID); if (type == PET_VIEW) { // Paint the view. - SetRGB(buffer, g_width, g_height, true); + if (g_offscreenTransparent) + SetRGBA(buffer, g_width, g_height, true); + else + SetRGB(buffer, g_width, g_height, true); // Update the whole texture. This is done for simplicity instead of // updating just the dirty region. - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_width, g_height, GL_RGB, - GL_UNSIGNED_BYTE, view_buffer_); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_width, g_height, + GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, view_buffer_); } if(popup_rect_.width > 0) { if (type == PET_POPUP) { // Paint the popup. - SetRGB(buffer, popup_rect_.width, popup_rect_.height, false); + if (g_offscreenTransparent) + SetRGBA(buffer, popup_rect_.width, popup_rect_.height, false); + else + SetRGB(buffer, popup_rect_.width, popup_rect_.height, false); } if (popup_buffer_) { // Update the popup region. glTexSubImage2D(GL_TEXTURE_2D, 0, popup_rect_.x, g_height-popup_rect_.y-popup_rect_.height, popup_rect_.width, - popup_rect_.height, GL_RGB, GL_UNSIGNED_BYTE, popup_buffer_); + popup_rect_.height, GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, + popup_buffer_); } } + + // Disable 2D textures. + glDisable(GL_TEXTURE_2D); + + if (g_offscreenTransparent) { + // Disable alpha blending. + glDisable(GL_BLEND); + } } virtual void OnCursorChange(CefRefPtr browser, @@ -305,18 +360,10 @@ private: AppGetBrowser()->GetMainFrame()->ExecuteJavaScript(ss.str(), "", 0); } - // Set the contents of the RGB buffer. - void SetRGB(const void* src, int width, int height, bool view) - { - SetBufferSize(width, height, view); - ConvertToRGB((unsigned char*)src, view?view_buffer_:popup_buffer_, width, - height); - } - // Size the RGB buffer. void SetBufferSize(int width, int height, bool view) { - int dst_size = width * height * 3; + int dst_size = width * height * GL_BYTE_COUNT; // Allocate a new buffer if necesary. if (view) { @@ -336,6 +383,38 @@ private: } } + // Set the contents of the RGBA buffer. + void SetRGBA(const void* src, int width, int height, bool view) + { + SetBufferSize(width, height, view); + ConvertToRGBA((unsigned char*)src, view?view_buffer_:popup_buffer_, width, + height); + } + + // Convert from BGRA to RGBA format and from upper-left to lower-left origin. + static void ConvertToRGBA(const unsigned char* src, unsigned char* dst, + int width, int height) + { + int sp = 0, dp = (height-1) * width * 4; + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++, dp += 4, sp += 4) { + dst[dp] = src[sp+2]; // R + dst[dp+1] = src[sp+1]; // G + dst[dp+2] = src[sp]; // B + dst[dp+3] = src[sp+3]; // A + } + dp -= width * 8; + } + } + + // Set the contents of the RGB buffer. + void SetRGB(const void* src, int width, int height, bool view) + { + SetBufferSize(width, height, view); + ConvertToRGB((unsigned char*)src, view?view_buffer_:popup_buffer_, width, + height); + } + // Convert from BGRA to RGB format and from upper-left to lower-left origin. static void ConvertToRGB(const unsigned char* src, unsigned char* dst, int width, int height) @@ -392,10 +471,14 @@ void EnableGL(HWND hWnd, HDC * hDC, HGLRC * hRC) wglMakeCurrent(*hDC, *hRC); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_TEXTURE_2D); // Necessary for non-power-of-2 textures to render correctly. glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if (g_offscreenTransparent) { + // Alpha blending style. + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } } // Disable GL. @@ -424,6 +507,14 @@ void SizeGL(ClientPlugin* plugin, int width, int height) glLoadIdentity(); glOrtho(0, 0, width, height, 0.1, 100.0); + if (g_offscreenTransparent) { + // Enable alpha blending. + glEnable(GL_BLEND); + } + + // Enable 2D textures. + glEnable(GL_TEXTURE_2D); + // Delete the existing exture. if(g_textureID != -1) glDeleteTextures(1, &g_textureID); @@ -435,12 +526,20 @@ void SizeGL(ClientPlugin* plugin, int width, int height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Start with all white contents. - int size = width * height * 3; + int size = width * height * GL_BYTE_COUNT; unsigned char* buffer = new unsigned char[size]; memset(buffer, 255, size); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, - GL_RGB, GL_UNSIGNED_BYTE, buffer); + GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, buffer); + + // Disable 2D textures. + glDisable(GL_TEXTURE_2D); + + if (g_offscreenTransparent) { + // Disable alpha blending. + glDisable(GL_BLEND); + } delete [] buffer; @@ -468,21 +567,43 @@ void RenderGL(ClientPlugin* plugin) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //glTranslatef(0.0f, 0.0f, -3.0f); + + // Draw the background gradient. + glPushAttrib(GL_ALL_ATTRIB_BITS); + glBegin(GL_QUADS); + glColor4f(1.0,0.0,0.0,1.0); // red + glVertex2f(-1.0,-1.0); + glVertex2f(1.0,-1.0); + glColor4f(0.0,0.0,1.0,1.0); // blue + glVertex2f(1.0, 1.0); + glVertex2f(-1.0, 1.0); + glEnd(); + glPopAttrib(); // Rotate the view based on the mouse spin. glRotatef(-g_spinX, 1.0f, 0.0f, 0.0f); glRotatef(-g_spinY, 0.0f, 1.0f, 0.0f); - // Enable alpha blending. - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (g_offscreenTransparent) { + // Enable alpha blending. + glEnable(GL_BLEND); + } + + // Enable 2D textures. + glEnable(GL_TEXTURE_2D); // Draw the facets with the texture. glBindTexture(GL_TEXTURE_2D, g_textureID); glInterleavedArrays(GL_T2F_V3F, 0, vertices); glDrawArrays(GL_QUADS, 0, 4); - //glDisable(GL_BLEND); + // Disable 2D textures. + glDisable(GL_TEXTURE_2D); + + if (g_offscreenTransparent) { + // Disable alpha blending. + glDisable(GL_BLEND); + } SwapBuffers(plugin->hDC); } @@ -556,6 +677,8 @@ NPError NPP_SetWindowImpl(NPP instance, NPWindow* window_info) { CefWindowInfo windowInfo; CefBrowserSettings settings; windowInfo.SetAsOffScreen(plugin->hWnd); + if (g_offscreenTransparent) + windowInfo.SetTransparentPainting(TRUE); CefBrowser::CreateBrowser(windowInfo, new ClientOSRHandler(plugin), "http://www.google.com", settings); } @@ -774,4 +897,9 @@ CefRefPtr GetOffScreenBrowser() return g_offscreenBrowser; } +void SetOffScreenTransparent(bool transparent) +{ + g_offscreenTransparent = transparent; +} + #endif // OS_WIN diff --git a/tests/cefclient/osrplugin.h b/tests/cefclient/osrplugin.h index d6a31e397..0ea76ca1e 100644 --- a/tests/cefclient/osrplugin.h +++ b/tests/cefclient/osrplugin.h @@ -22,6 +22,8 @@ NPError API_CALL NP_OSRShutdown(void); CefRefPtr GetOffScreenBrowser(); +void SetOffScreenTransparent(bool transparent); + #endif // OS_WIN #endif // _CEFCLIENT_OSRPLUGIN_H diff --git a/tests/cefclient/osrplugin_test.cpp b/tests/cefclient/osrplugin_test.cpp index e81fb48df..451dc8fb2 100644 --- a/tests/cefclient/osrplugin_test.cpp +++ b/tests/cefclient/osrplugin_test.cpp @@ -26,7 +26,7 @@ void InitOSRPluginTest() CefRegisterPlugin(plugin_info); } -void RunOSRPluginTest(CefRefPtr browser) +void RunOSRPluginTest(CefRefPtr browser, bool transparent) { class Listener : public CefDOMEventListener { @@ -58,9 +58,10 @@ void RunOSRPluginTest(CefRefPtr browser) CefString value = url->GetValue(); if (!value.empty()) browser->GetMainFrame()->LoadURL(value); - } else if(elementId == "testWindowedPlugin") { - // Run the windowed plugin test. - RunPluginTest(browser); + } else if(elementId == "testTransparency") { + // Transparency test. + browser->GetMainFrame()->LoadURL( + "http://tests/transparency"); } else if(elementId == "testWindowlessPlugin") { // Load flash, which is a windowless plugin. browser->GetMainFrame()->LoadURL( @@ -101,7 +102,7 @@ void RunOSRPluginTest(CefRefPtr browser) RegisterClickListener(document, listener, "stop"); RegisterClickListener(document, listener, "reload"); RegisterClickListener(document, listener, "go"); - RegisterClickListener(document, listener, "testWindowedPlugin"); + RegisterClickListener(document, listener, "testTransparency"); RegisterClickListener(document, listener, "testWindowlessPlugin"); RegisterClickListener(document, listener, "viewSource"); } @@ -124,5 +125,6 @@ void RunOSRPluginTest(CefRefPtr browser) static_cast(client.get())->AddDOMVisitor( "http://tests/osrapp", new Visitor()); + SetOffScreenTransparent(transparent); browser->GetMainFrame()->LoadURL("http://tests/osrapp"); } diff --git a/tests/cefclient/osrplugin_test.h b/tests/cefclient/osrplugin_test.h index 25d289aca..25a7b0d07 100644 --- a/tests/cefclient/osrplugin_test.h +++ b/tests/cefclient/osrplugin_test.h @@ -11,6 +11,6 @@ void InitOSRPluginTest(); // Run the test. -void RunOSRPluginTest(CefRefPtr browser); +void RunOSRPluginTest(CefRefPtr browser, bool transparent); #endif // _CEFCLIENT_OSRPLUGIN_TEST_H diff --git a/tests/cefclient/res/osrplugin.html b/tests/cefclient/res/osrplugin.html index ed8f019ef..ddf8b0d02 100644 --- a/tests/cefclient/res/osrplugin.html +++ b/tests/cefclient/res/osrplugin.html @@ -24,8 +24,8 @@
  • Click and drag the view with the left mouse button while holding the shift key.
  • Enter a URL and click the "Go!" button to browse to a new Website.
  • -
  • Click here to test a windowed plugin. Windowed plugins must handle the WM_PRINTCLIENT message.
  • -
  • Click here to test a windowless plugin. Windowless plugins can be used without modification.
  • +
  • Click here to test transparency.
  • +
  • Click here to test a windowless plugin.
diff --git a/tests/cefclient/res/transparency.html b/tests/cefclient/res/transparency.html new file mode 100644 index 000000000..3b8cf7fbb --- /dev/null +++ b/tests/cefclient/res/transparency.html @@ -0,0 +1,36 @@ + + + +Transparency Examples + + + + +

Image Transparency

+Hover over an image to make it fully opaque.
+klematis +klematis + +

Div Transparency

+
This is some text in a transparent box.
+ + diff --git a/tests/cefclient/resource.h b/tests/cefclient/resource.h index 9b2ed6b4d..402b1f10b 100644 --- a/tests/cefclient/resource.h +++ b/tests/cefclient/resource.h @@ -53,6 +53,8 @@ #define ID_TESTS_OSRAPP 32793 #define ID_TESTS_MODALDIALOG 32794 #define ID_TESTS_JAVASCRIPT_PERFORMANCE 32795 +#define ID_TESTS_TRANSPARENT_POPUP 32796 +#define ID_TESTS_TRANSPARENT_OSRAPP 32797 #define IDC_STATIC -1 #define IDS_LOGO 1000 #define IDS_UIPLUGIN 1001 @@ -64,6 +66,7 @@ #define IDS_MODALMAIN 1007 #define IDS_MODALDIALOG 1008 #define IDS_EXTENSIONPERF 1009 +#define IDS_TRANSPARENCY 1010 // Avoid files associated with MacOS #define _X86_