// Copyright (c) 2015 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/cefclient/browser/browser_window_std_gtk.h" #include #include #include #include #undef Success // Definition conflicts with cef_message_router.h #undef RootWindow // Definition conflicts with root_window.h #include "include/base/cef_logging.h" #include "tests/cefclient/browser/client_handler_std.h" #include "tests/cefclient/browser/util_gtk.h" #include "tests/shared/browser/main_message_loop.h" namespace client { namespace { ::Window GetXWindowForWidget(GtkWidget* widget) { ScopedGdkThreadsEnter scoped_gdk_threads; // The GTK window must be visible before we can retrieve the XID. ::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(widget)); DCHECK(xwindow); return xwindow; } void SetXWindowVisible(XDisplay* xdisplay, ::Window xwindow, bool visible) { CHECK(xdisplay != 0); // Retrieve the atoms required by the below XChangeProperty call. const char* kAtoms[] = {"_NET_WM_STATE", "ATOM", "_NET_WM_STATE_HIDDEN"}; Atom atoms[3]; int result = XInternAtoms(xdisplay, const_cast(kAtoms), 3, false, atoms); if (!result) NOTREACHED(); if (!visible) { // Set the hidden property state value. scoped_ptr data(new Atom[1]); data[0] = atoms[2]; XChangeProperty(xdisplay, xwindow, atoms[0], // name atoms[1], // type 32, // size in bits of items in 'value' PropModeReplace, reinterpret_cast(data.get()), 1); // num items } else { // Set an empty array of property state values. XChangeProperty(xdisplay, xwindow, atoms[0], // name atoms[1], // type 32, // size in bits of items in 'value' PropModeReplace, NULL, 0); // num items } } void SetXWindowBounds(XDisplay* xdisplay, ::Window xwindow, int x, int y, size_t width, size_t height) { CHECK(xdisplay != 0); XWindowChanges changes = {0}; changes.x = x; changes.y = y; changes.width = static_cast(width); changes.height = static_cast(height); XConfigureWindow(xdisplay, xwindow, CWX | CWY | CWHeight | CWWidth, &changes); } } // namespace BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate, const std::string& startup_url) : BrowserWindow(delegate), xdisplay_(nullptr) { client_handler_ = new ClientHandlerStd(this, startup_url); } void BrowserWindowStdGtk::set_xdisplay(XDisplay* xdisplay) { REQUIRE_MAIN_THREAD(); DCHECK(!xdisplay_); xdisplay_ = xdisplay; } void BrowserWindowStdGtk::CreateBrowser( ClientWindowHandle parent_handle, const CefRect& rect, const CefBrowserSettings& settings, CefRefPtr extra_info, CefRefPtr request_context) { REQUIRE_MAIN_THREAD(); CefWindowInfo window_info; window_info.SetAsChild(GetXWindowForWidget(parent_handle), rect); CefBrowserHost::CreateBrowser(window_info, client_handler_, client_handler_->startup_url(), settings, extra_info, request_context); } void BrowserWindowStdGtk::GetPopupConfig(CefWindowHandle temp_handle, CefWindowInfo& windowInfo, CefRefPtr& client, CefBrowserSettings& settings) { CEF_REQUIRE_UI_THREAD(); // The window will be properly sized after the browser is created. windowInfo.SetAsChild(temp_handle, CefRect()); client = client_handler_; } void BrowserWindowStdGtk::ShowPopup(ClientWindowHandle parent_handle, int x, int y, size_t width, size_t height) { REQUIRE_MAIN_THREAD(); if (browser_) { ::Window parent_xwindow = GetXWindowForWidget(parent_handle); CHECK(xdisplay_ != 0); ::Window xwindow = browser_->GetHost()->GetWindowHandle(); DCHECK(xwindow); XReparentWindow(xdisplay_, xwindow, parent_xwindow, x, y); SetXWindowBounds(xdisplay_, xwindow, x, y, width, height); SetXWindowVisible(xdisplay_, xwindow, true); } } void BrowserWindowStdGtk::Show() { REQUIRE_MAIN_THREAD(); if (browser_) { ::Window xwindow = browser_->GetHost()->GetWindowHandle(); DCHECK(xwindow); SetXWindowVisible(xdisplay_, xwindow, true); } } void BrowserWindowStdGtk::Hide() { REQUIRE_MAIN_THREAD(); if (browser_) { ::Window xwindow = browser_->GetHost()->GetWindowHandle(); DCHECK(xwindow); SetXWindowVisible(xdisplay_, xwindow, false); } } void BrowserWindowStdGtk::SetBounds(int x, int y, size_t width, size_t height) { REQUIRE_MAIN_THREAD(); if (xdisplay_ && browser_) { ::Window xwindow = browser_->GetHost()->GetWindowHandle(); DCHECK(xwindow); SetXWindowBounds(xdisplay_, xwindow, x, y, width, height); } } void BrowserWindowStdGtk::SetFocus(bool focus) { REQUIRE_MAIN_THREAD(); if (browser_) browser_->GetHost()->SetFocus(focus); } ClientWindowHandle BrowserWindowStdGtk::GetWindowHandle() const { REQUIRE_MAIN_THREAD(); // There is no GtkWidget* representation of this object. NOTREACHED(); return NULL; } } // namespace client