diff options
Diffstat (limited to 'tests/cefclient/browser/browser_window_std_gtk.cc')
-rw-r--r-- | tests/cefclient/browser/browser_window_std_gtk.cc | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tests/cefclient/browser/browser_window_std_gtk.cc b/tests/cefclient/browser/browser_window_std_gtk.cc new file mode 100644 index 00000000..8d4bd577 --- /dev/null +++ b/tests/cefclient/browser/browser_window_std_gtk.cc @@ -0,0 +1,191 @@ +// 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 <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include <X11/Xlib.h> +#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<char**>(kAtoms), 3, false, atoms); + if (!result) { + NOTREACHED(); + } + + if (!visible) { + // Set the hidden property state value. + std::unique_ptr<Atom[]> 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<const unsigned char*>(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, nullptr, + 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<int>(width); + changes.height = static_cast<int>(height); + XConfigureWindow(xdisplay, xwindow, CWX | CWY | CWHeight | CWWidth, &changes); +} + +} // namespace + +BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate, + bool with_controls, + const std::string& startup_url) + : BrowserWindow(delegate), xdisplay_(nullptr) { + client_handler_ = new ClientHandlerStd(this, with_controls, 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<CefDictionaryValue> extra_info, + CefRefPtr<CefRequestContext> 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<CefClient>& 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 nullptr; +} + +} // namespace client |