mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-16 20:20:51 +01:00
- cefclient: Linux: Introduce RootWindow concept and associated window/client object hierarchy (issue #1500).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2004 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
37464c2a4c
commit
89de4a5bb6
@ -160,6 +160,7 @@
|
||||
'tests/cefclient/client_renderer.h',
|
||||
'tests/cefclient/client_switches.cc',
|
||||
'tests/cefclient/client_switches.h',
|
||||
'tests/cefclient/client_types.h',
|
||||
'tests/cefclient/dialog_test.cc',
|
||||
'tests/cefclient/dialog_test.h',
|
||||
'tests/cefclient/main_context.cc',
|
||||
@ -187,12 +188,12 @@
|
||||
'<@(cefclient_bundle_resources_common)',
|
||||
],
|
||||
'cefclient_sources_win': [
|
||||
'tests/cefclient/browser_window.cc',
|
||||
'tests/cefclient/browser_window.h',
|
||||
'tests/cefclient/browser_window_osr_win.cc',
|
||||
'tests/cefclient/browser_window_osr_win.h',
|
||||
'tests/cefclient/browser_window_std_win.cc',
|
||||
'tests/cefclient/browser_window_std_win.h',
|
||||
'tests/cefclient/browser_window_win.cc',
|
||||
'tests/cefclient/browser_window_win.h',
|
||||
'tests/cefclient/cefclient.exe.manifest',
|
||||
'tests/cefclient/cefclient.rc',
|
||||
'tests/cefclient/cefclient_win.cc',
|
||||
@ -279,18 +280,32 @@
|
||||
],
|
||||
'cefclient_sources_linux': [
|
||||
'tests/cefclient/cefclient_gtk.cc',
|
||||
'tests/cefclient/client_handler_shared.cc',
|
||||
'tests/cefclient/client_handler_shared.h',
|
||||
'tests/cefclient/client_handler_shared_gtk.cc',
|
||||
'tests/cefclient/browser_window.cc',
|
||||
'tests/cefclient/browser_window.h',
|
||||
'tests/cefclient/browser_window_osr_gtk.cc',
|
||||
'tests/cefclient/browser_window_osr_gtk.h',
|
||||
'tests/cefclient/browser_window_std_gtk.cc',
|
||||
'tests/cefclient/browser_window_std_gtk.h',
|
||||
'tests/cefclient/client_handler_osr.cc',
|
||||
'tests/cefclient/client_handler_osr.h',
|
||||
'tests/cefclient/client_handler_single.cc',
|
||||
'tests/cefclient/client_handler_single.h',
|
||||
'tests/cefclient/client_handler_std.cc',
|
||||
'tests/cefclient/client_handler_std.h',
|
||||
'tests/cefclient/dialog_handler_gtk.cc',
|
||||
'tests/cefclient/dialog_handler_gtk.h',
|
||||
'tests/cefclient/main_context_impl_posix.cc',
|
||||
'tests/cefclient/osr_widget_gtk.h',
|
||||
'tests/cefclient/osr_widget_gtk.cc',
|
||||
'tests/cefclient/print_handler_gtk.cc',
|
||||
'tests/cefclient/print_handler_gtk.h',
|
||||
'tests/cefclient/resource_util_linux.cc',
|
||||
'tests/cefclient/resource_util_posix.cc',
|
||||
'tests/cefclient/root_window.h',
|
||||
'tests/cefclient/root_window_manager.cc',
|
||||
'tests/cefclient/root_window_manager.h',
|
||||
'tests/cefclient/root_window_gtk.cc',
|
||||
'tests/cefclient/root_window_gtk.h',
|
||||
'tests/cefclient/temp_window_x11.cc',
|
||||
'tests/cefclient/temp_window_x11.h',
|
||||
'tests/cefclient/window_test_gtk.cc',
|
||||
],
|
||||
'cefclient_bundle_resources_linux': [
|
||||
|
@ -2,30 +2,30 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/browser_window.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
BrowserWindowWin::BrowserWindowWin(Delegate* delegate)
|
||||
BrowserWindow::BrowserWindow(Delegate* delegate)
|
||||
: delegate_(delegate),
|
||||
is_closing_(false) {
|
||||
DCHECK(delegate_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> BrowserWindowWin::GetBrowser() const {
|
||||
CefRefPtr<CefBrowser> BrowserWindow::GetBrowser() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return browser_;
|
||||
}
|
||||
|
||||
bool BrowserWindowWin::IsClosing() const {
|
||||
bool BrowserWindow::IsClosing() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return is_closing_;
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
void BrowserWindow::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!browser_);
|
||||
browser_ = browser;
|
||||
@ -33,13 +33,13 @@ void BrowserWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
delegate_->OnBrowserCreated(browser);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
void BrowserWindow::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||
is_closing_ = true;
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
void BrowserWindow::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||
browser_ = NULL;
|
||||
@ -51,19 +51,19 @@ void BrowserWindowWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
delegate_->OnBrowserWindowDestroyed();
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetAddress(const std::string& url) {
|
||||
void BrowserWindow::OnSetAddress(const std::string& url) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetAddress(url);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetTitle(const std::string& title) {
|
||||
void BrowserWindow::OnSetTitle(const std::string& title) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetTitle(title);
|
||||
}
|
||||
|
||||
void BrowserWindowWin::OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
void BrowserWindow::OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
@ -2,21 +2,20 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_H_
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "cefclient/client_handler_single.h"
|
||||
#include "cefclient/client_types.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single browser instance. The
|
||||
// methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
class BrowserWindow : public ClientHandlerSingle::Delegate {
|
||||
public:
|
||||
// This interface is implemented by the owner of the BrowserWindowWin. The
|
||||
// methods of this class will be called on the main thread.
|
||||
@ -44,20 +43,22 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
};
|
||||
|
||||
// Create a new browser and native window.
|
||||
virtual void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
virtual void CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) = 0;
|
||||
|
||||
// Retrieve the configuration that will be used when creating a popup window.
|
||||
// The native window will be created later after the browser has been created.
|
||||
// This method may be called on any thread.
|
||||
virtual void GetPopupConfig(HWND temp_hwnd,
|
||||
// The popup browser will initially be parented to |temp_handle| which should
|
||||
// be a pre-existing hidden window. The native window will be created later
|
||||
// after the browser has been created. This method may be called on any
|
||||
// thread.
|
||||
virtual void GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) = 0;
|
||||
|
||||
// Show the popup window with correct parent and bounds in parent coordinates.
|
||||
virtual void ShowPopup(HWND parent_hwnd,
|
||||
virtual void ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) = 0;
|
||||
|
||||
// Show the window.
|
||||
@ -73,7 +74,7 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
virtual void SetFocus() = 0;
|
||||
|
||||
// Returns the window handle.
|
||||
virtual HWND GetHWND() const = 0;
|
||||
virtual ClientWindowHandle GetWindowHandle() const = 0;
|
||||
|
||||
// Returns the browser owned by the window.
|
||||
CefRefPtr<CefBrowser> GetBrowser() const;
|
||||
@ -83,11 +84,11 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
|
||||
protected:
|
||||
// Allow deletion via scoped_ptr only.
|
||||
friend struct base::DefaultDeleter<BrowserWindowWin>;
|
||||
friend struct base::DefaultDeleter<BrowserWindow>;
|
||||
|
||||
// Constructor may be called on any thread.
|
||||
// |root_window| and |delegate| must outlive this object.
|
||||
explicit BrowserWindowWin(Delegate* delegate);
|
||||
explicit BrowserWindow(Delegate* delegate);
|
||||
|
||||
// ClientHandlerSingle::Delegate methods.
|
||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
@ -104,9 +105,9 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
||||
CefRefPtr<ClientHandlerSingle> client_handler_;
|
||||
bool is_closing_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowWin);
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindow);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_H_
|
@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
|
||||
// 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 "cefclient/osr_widget_gtk.h"
|
||||
#include "cefclient/browser_window_osr_gtk.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
@ -17,23 +17,15 @@
|
||||
#include <X11/XF86keysym.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
gint glarea_size_allocation(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (host)
|
||||
host->WasResized();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int get_cef_state_modifiers(guint state) {
|
||||
int GetCefStateModifiers(guint state) {
|
||||
int modifiers = 0;
|
||||
if (state & GDK_SHIFT_MASK)
|
||||
modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||
@ -865,183 +857,7 @@ int GetControlCharacter(KeyboardCode windows_key_code, bool shift) {
|
||||
}
|
||||
}
|
||||
|
||||
gint glarea_click_event(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (!host)
|
||||
return TRUE;
|
||||
|
||||
CefBrowserHost::MouseButtonType button_type = MBT_LEFT;
|
||||
switch (event->button) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
button_type = MBT_MIDDLE;
|
||||
break;
|
||||
case 3:
|
||||
button_type = MBT_RIGHT;
|
||||
break;
|
||||
default:
|
||||
// Other mouse buttons are not handled here.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = event->x;
|
||||
mouse_event.y = event->y;
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = get_cef_state_modifiers(event->state);
|
||||
|
||||
bool mouse_up = (event->type == GDK_BUTTON_RELEASE);
|
||||
if (!mouse_up)
|
||||
gtk_widget_grab_focus(widget);
|
||||
|
||||
int click_count = 1;
|
||||
switch (event->type) {
|
||||
case GDK_2BUTTON_PRESS:
|
||||
click_count = 2;
|
||||
break;
|
||||
case GDK_3BUTTON_PRESS:
|
||||
click_count = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint glarea_move_event(GtkWidget* widget,
|
||||
GdkEventMotion* event,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (!host)
|
||||
return TRUE;
|
||||
|
||||
gint x, y;
|
||||
GdkModifierType state;
|
||||
|
||||
if (event->is_hint) {
|
||||
gdk_window_get_pointer(event->window, &x, &y, &state);
|
||||
} else {
|
||||
x = (gint)event->x;
|
||||
y = (gint)event->y;
|
||||
state = (GdkModifierType)event->state;
|
||||
}
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = get_cef_state_modifiers(state);
|
||||
|
||||
bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
|
||||
|
||||
host->SendMouseMoveEvent(mouse_event, mouse_leave);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint glarea_scroll_event(GtkWidget* widget,
|
||||
GdkEventScroll* event,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (!host)
|
||||
return TRUE;
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = event->x;
|
||||
mouse_event.y = event->y;
|
||||
window->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = get_cef_state_modifiers(event->state);
|
||||
|
||||
static const int scrollbarPixelsPerGtkTick = 40;
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
switch (event->direction) {
|
||||
case GDK_SCROLL_UP:
|
||||
deltaY = scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_DOWN:
|
||||
deltaY = -scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_LEFT:
|
||||
deltaX = scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_RIGHT:
|
||||
deltaX = -scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
}
|
||||
|
||||
host->SendMouseWheelEvent(mouse_event, deltaX, deltaY);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint glarea_key_event(GtkWidget* widget,
|
||||
GdkEventKey* event,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (!host)
|
||||
return TRUE;
|
||||
|
||||
// Based on WebKeyboardEventBuilder::Build from
|
||||
// content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
|
||||
CefKeyEvent key_event;
|
||||
KeyboardCode windows_key_code = GdkEventToWindowsKeyCode(event);
|
||||
key_event.windows_key_code =
|
||||
GetWindowsKeyCodeWithoutLocation(windows_key_code);
|
||||
key_event.native_key_code = event->hardware_keycode;
|
||||
|
||||
key_event.modifiers = get_cef_state_modifiers(event->state);
|
||||
if (event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9)
|
||||
key_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||
if (key_event.modifiers & EVENTFLAG_ALT_DOWN)
|
||||
key_event.is_system_key = true;
|
||||
|
||||
if (windows_key_code == VKEY_RETURN) {
|
||||
// We need to treat the enter key as a key press of character \r. This
|
||||
// is apparently just how webkit handles it and what it expects.
|
||||
key_event.unmodified_character = '\r';
|
||||
} else {
|
||||
// FIXME: fix for non BMP chars
|
||||
key_event.unmodified_character =
|
||||
static_cast<int>(gdk_keyval_to_unicode(event->keyval));
|
||||
}
|
||||
|
||||
// If ctrl key is pressed down, then control character shall be input.
|
||||
if (key_event.modifiers & EVENTFLAG_CONTROL_DOWN) {
|
||||
key_event.character =
|
||||
GetControlCharacter(windows_key_code,
|
||||
key_event.modifiers & EVENTFLAG_SHIFT_DOWN);
|
||||
} else {
|
||||
key_event.character = key_event.unmodified_character;
|
||||
}
|
||||
|
||||
if (event->type == GDK_KEY_PRESS) {
|
||||
key_event.type = KEYEVENT_RAWKEYDOWN;
|
||||
host->SendKeyEvent(key_event);
|
||||
} else {
|
||||
// Need to send both KEYUP and CHAR events.
|
||||
key_event.type = KEYEVENT_KEYUP;
|
||||
host->SendKeyEvent(key_event);
|
||||
key_event.type = KEYEVENT_CHAR;
|
||||
host->SendKeyEvent(key_event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint glarea_focus_event(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
OSRWindow* window) {
|
||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
||||
if (host)
|
||||
host->SendFocusEvent(event->in == TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void widget_get_rect_in_screen(GtkWidget* widget, GdkRectangle* r) {
|
||||
void GetWidgetRectInScreen(GtkWidget* widget, GdkRectangle* r) {
|
||||
gint x, y, w, h;
|
||||
GdkRectangle extents;
|
||||
|
||||
@ -1095,26 +911,128 @@ class ScopedGLContext {
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView) {
|
||||
DCHECK(browser_provider);
|
||||
if (!browser_provider)
|
||||
return NULL;
|
||||
|
||||
return new OSRWindow(browser_provider, transparent, show_update_rect,
|
||||
parentView);
|
||||
BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: BrowserWindow(delegate),
|
||||
renderer_(transparent, show_update_rect),
|
||||
glarea_(NULL),
|
||||
hidden_(false),
|
||||
gl_enabled_(false),
|
||||
painting_popup_(false) {
|
||||
client_handler_ = new ClientHandlerOsr(this, this, startup_url);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::From(
|
||||
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler) {
|
||||
return static_cast<OSRWindow*>(renderHandler.get());
|
||||
void BrowserWindowOsrGtk::CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Set the window handle for GTK dialogs.
|
||||
client_handler_->SetMainWindowHandle(parent_handle);
|
||||
|
||||
// Create the native window.
|
||||
Create(parent_handle);
|
||||
|
||||
// Retrieve the X11 Window ID for the GTK parent window.
|
||||
GtkWidget* window = gtk_widget_get_ancestor(
|
||||
GTK_WIDGET(parent_handle), GTK_TYPE_WINDOW);
|
||||
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
|
||||
DCHECK(xwindow);
|
||||
|
||||
CefWindowInfo window_info;
|
||||
window_info.SetAsWindowless(xwindow, renderer_.IsTransparent());
|
||||
|
||||
// Create the browser asynchronously.
|
||||
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||
client_handler_->startup_url(),
|
||||
settings, NULL);
|
||||
}
|
||||
|
||||
void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
void BrowserWindowOsrGtk::GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any thread.
|
||||
windowInfo.SetAsWindowless(temp_handle, renderer_.IsTransparent());
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(browser_.get());
|
||||
|
||||
// Set the window handle for GTK dialogs.
|
||||
client_handler_->SetMainWindowHandle(parent_handle);
|
||||
|
||||
// Create the native window.
|
||||
Create(parent_handle);
|
||||
|
||||
// Send resize notification so the compositor is assigned the correct
|
||||
// viewport size and begins rendering.
|
||||
browser_->GetHost()->WasResized();
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::Show() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hidden_) {
|
||||
// Set the browser as visible.
|
||||
browser_->GetHost()->WasHidden(false);
|
||||
hidden_ = false;
|
||||
}
|
||||
|
||||
// Give focus to the browser.
|
||||
browser_->GetHost()->SendFocusEvent(true);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!browser_)
|
||||
return;
|
||||
|
||||
// Remove focus from the browser.
|
||||
browser_->GetHost()->SendFocusEvent(false);
|
||||
|
||||
if (!hidden_) {
|
||||
// Set the browser as hidden.
|
||||
browser_->GetHost()->WasHidden(true);
|
||||
hidden_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
// Nothing to do here. GTK will take care of positioning in the container.
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::SetFocus() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (glarea_)
|
||||
gtk_widget_grab_focus(glarea_);
|
||||
}
|
||||
|
||||
ClientWindowHandle BrowserWindowOsrGtk::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return glarea_;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Detach |this| from the ClientHandlerOsr.
|
||||
static_cast<ClientHandlerOsr*>(client_handler_.get())->DetachOsrDelegate();
|
||||
|
||||
// Disconnect all signal handlers that reference |this|.
|
||||
g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0,
|
||||
NULL, NULL, this);
|
||||
@ -1122,8 +1040,17 @@ void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
DisableGL();
|
||||
}
|
||||
|
||||
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
bool BrowserWindowOsrGtk::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BrowserWindowOsrGtk::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!glarea_)
|
||||
return false;
|
||||
|
||||
@ -1135,20 +1062,32 @@ bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) {
|
||||
bool BrowserWindowOsrGtk::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
GdkRectangle screen_rect;
|
||||
widget_get_rect_in_screen(glarea_, &screen_rect);
|
||||
GetWidgetRectInScreen(glarea_, &screen_rect);
|
||||
screenX = screen_rect.x + viewX;
|
||||
screenY = screen_rect.y + viewY;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) {
|
||||
bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return false;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!show) {
|
||||
renderer_.ClearPopupRects();
|
||||
browser->GetHost()->Invalidate(PET_VIEW);
|
||||
@ -1156,16 +1095,29 @@ void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
renderer_.OnPopupShow(browser, show);
|
||||
}
|
||||
|
||||
void OSRWindow::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
renderer_.OnPopupSize(browser, rect);
|
||||
}
|
||||
|
||||
void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width, int height) {
|
||||
void BrowserWindowOsrGtk::OnPaint(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (width <= 2 && height <= 2) {
|
||||
// Ignore really small buffer sizes while the widget is starting up.
|
||||
return;
|
||||
}
|
||||
|
||||
if (painting_popup_) {
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
return;
|
||||
@ -1187,71 +1139,45 @@ void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
renderer_.Render();
|
||||
}
|
||||
|
||||
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) {
|
||||
void BrowserWindowOsrGtk::OnCursorChange(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CefRenderHandler::CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Retrieve the X11 display shared with Chromium.
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
DCHECK(xdisplay);
|
||||
|
||||
// Retrieve the X11 window handle for OSR widget.
|
||||
// Retrieve the X11 window handle for the GTK widget.
|
||||
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(glarea_));
|
||||
|
||||
// Set the cursor.
|
||||
XDefineCursor(xdisplay, xwindow, cursor);
|
||||
}
|
||||
|
||||
void OSRWindow::Invalidate() {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(&OSRWindow::Invalidate, this));
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't post another task if the previous task is still pending.
|
||||
if (render_task_pending_)
|
||||
return;
|
||||
|
||||
render_task_pending_ = true;
|
||||
|
||||
// Render at 30fps.
|
||||
static const int kRenderDelay = 1000 / 30;
|
||||
CefPostDelayedTask(TID_UI, base::Bind(&OSRWindow::Render, this),
|
||||
kRenderDelay);
|
||||
bool BrowserWindowOsrGtk::StartDragging(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// TODO(port): Implement drag&drop support.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSRWindow::IsOverPopupWidget(int x, int y) const {
|
||||
const CefRect& rc = renderer_.popup_rect();
|
||||
int popup_right = rc.x + rc.width;
|
||||
int popup_bottom = rc.y + rc.height;
|
||||
return (x >= rc.x) && (x < popup_right) &&
|
||||
(y >= rc.y) && (y < popup_bottom);
|
||||
void BrowserWindowOsrGtk::UpdateDragCursor(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
}
|
||||
|
||||
int OSRWindow::GetPopupXOffset() const {
|
||||
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
||||
}
|
||||
void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!glarea_);
|
||||
|
||||
int OSRWindow::GetPopupYOffset() const {
|
||||
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
|
||||
}
|
||||
|
||||
void OSRWindow::ApplyPopupOffset(int& x, int& y) const {
|
||||
if (IsOverPopupWidget(x, y)) {
|
||||
x += GetPopupXOffset();
|
||||
y += GetPopupYOffset();
|
||||
}
|
||||
}
|
||||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView)
|
||||
: renderer_(transparent, show_update_rect),
|
||||
browser_provider_(browser_provider),
|
||||
gl_enabled_(false),
|
||||
painting_popup_(false),
|
||||
render_task_pending_(false) {
|
||||
glarea_ = gtk_drawing_area_new();
|
||||
DCHECK(glarea_);
|
||||
|
||||
@ -1261,13 +1187,12 @@ OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
GDK_GL_MODE_DOUBLE));
|
||||
DCHECK(glconfig);
|
||||
|
||||
gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE,
|
||||
GDK_GL_RGBA_TYPE);
|
||||
gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
|
||||
|
||||
gtk_widget_set_can_focus(glarea_, TRUE);
|
||||
|
||||
g_signal_connect(G_OBJECT(glarea_), "size_allocate",
|
||||
G_CALLBACK(glarea_size_allocation), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::SizeAllocation), this);
|
||||
|
||||
gtk_widget_set_events(glarea_,
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
@ -1281,49 +1206,265 @@ OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
GDK_SCROLL_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK);
|
||||
g_signal_connect(G_OBJECT(glarea_), "button_press_event",
|
||||
G_CALLBACK(glarea_click_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::ClickEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "button_release_event",
|
||||
G_CALLBACK(glarea_click_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::ClickEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "key_press_event",
|
||||
G_CALLBACK(glarea_key_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::KeyEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "key_release_event",
|
||||
G_CALLBACK(glarea_key_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::KeyEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "enter_notify_event",
|
||||
G_CALLBACK(glarea_move_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "leave_notify_event",
|
||||
G_CALLBACK(glarea_move_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "motion_notify_event",
|
||||
G_CALLBACK(glarea_move_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::MoveEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "scroll_event",
|
||||
G_CALLBACK(glarea_scroll_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::ScrollEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "focus_in_event",
|
||||
G_CALLBACK(glarea_focus_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::FocusEvent), this);
|
||||
g_signal_connect(G_OBJECT(glarea_), "focus_out_event",
|
||||
G_CALLBACK(glarea_focus_event), this);
|
||||
G_CALLBACK(&BrowserWindowOsrGtk::FocusEvent), this);
|
||||
|
||||
gtk_container_add(GTK_CONTAINER(parentView), glarea_);
|
||||
gtk_container_add(GTK_CONTAINER(parent_handle), glarea_);
|
||||
|
||||
// Make the GlArea visible in the parent container.
|
||||
gtk_widget_show_all(parent_handle);
|
||||
}
|
||||
|
||||
OSRWindow::~OSRWindow() {
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::SizeAllocation(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (self->browser_.get()) {
|
||||
// Results in a call to GetViewRect().
|
||||
self->browser_->GetHost()->WasResized();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void OSRWindow::Render() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (render_task_pending_)
|
||||
render_task_pending_ = false;
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!gl_enabled_)
|
||||
EnableGL();
|
||||
if (!self->browser_.get())
|
||||
return TRUE;
|
||||
|
||||
ScopedGLContext scoped_gl_context(glarea_, true);
|
||||
if (!scoped_gl_context.IsValid())
|
||||
return;
|
||||
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
|
||||
|
||||
renderer_.Render();
|
||||
CefBrowserHost::MouseButtonType button_type = MBT_LEFT;
|
||||
switch (event->button) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
button_type = MBT_MIDDLE;
|
||||
break;
|
||||
case 3:
|
||||
button_type = MBT_RIGHT;
|
||||
break;
|
||||
default:
|
||||
// Other mouse buttons are not handled here.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = event->x;
|
||||
mouse_event.y = event->y;
|
||||
self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefStateModifiers(event->state);
|
||||
|
||||
bool mouse_up = (event->type == GDK_BUTTON_RELEASE);
|
||||
if (!mouse_up)
|
||||
gtk_widget_grab_focus(widget);
|
||||
|
||||
int click_count = 1;
|
||||
switch (event->type) {
|
||||
case GDK_2BUTTON_PRESS:
|
||||
click_count = 2;
|
||||
break;
|
||||
case GDK_3BUTTON_PRESS:
|
||||
click_count = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void OSRWindow::EnableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::KeyEvent(GtkWidget* widget,
|
||||
GdkEventKey* event,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!self->browser_.get())
|
||||
return TRUE;
|
||||
|
||||
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
|
||||
|
||||
// Based on WebKeyboardEventBuilder::Build from
|
||||
// content/browser/renderer_host/input/web_input_event_builders_gtk.cc.
|
||||
CefKeyEvent key_event;
|
||||
KeyboardCode windows_key_code = GdkEventToWindowsKeyCode(event);
|
||||
key_event.windows_key_code =
|
||||
GetWindowsKeyCodeWithoutLocation(windows_key_code);
|
||||
key_event.native_key_code = event->hardware_keycode;
|
||||
|
||||
key_event.modifiers = GetCefStateModifiers(event->state);
|
||||
if (event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9)
|
||||
key_event.modifiers |= EVENTFLAG_IS_KEY_PAD;
|
||||
if (key_event.modifiers & EVENTFLAG_ALT_DOWN)
|
||||
key_event.is_system_key = true;
|
||||
|
||||
if (windows_key_code == VKEY_RETURN) {
|
||||
// We need to treat the enter key as a key press of character \r. This
|
||||
// is apparently just how webkit handles it and what it expects.
|
||||
key_event.unmodified_character = '\r';
|
||||
} else {
|
||||
// FIXME: fix for non BMP chars
|
||||
key_event.unmodified_character =
|
||||
static_cast<int>(gdk_keyval_to_unicode(event->keyval));
|
||||
}
|
||||
|
||||
// If ctrl key is pressed down, then control character shall be input.
|
||||
if (key_event.modifiers & EVENTFLAG_CONTROL_DOWN) {
|
||||
key_event.character =
|
||||
GetControlCharacter(windows_key_code,
|
||||
key_event.modifiers & EVENTFLAG_SHIFT_DOWN);
|
||||
} else {
|
||||
key_event.character = key_event.unmodified_character;
|
||||
}
|
||||
|
||||
if (event->type == GDK_KEY_PRESS) {
|
||||
key_event.type = KEYEVENT_RAWKEYDOWN;
|
||||
host->SendKeyEvent(key_event);
|
||||
} else {
|
||||
// Need to send both KEYUP and CHAR events.
|
||||
key_event.type = KEYEVENT_KEYUP;
|
||||
host->SendKeyEvent(key_event);
|
||||
key_event.type = KEYEVENT_CHAR;
|
||||
host->SendKeyEvent(key_event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::MoveEvent(GtkWidget* widget,
|
||||
GdkEventMotion* event,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!self->browser_.get())
|
||||
return TRUE;
|
||||
|
||||
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
|
||||
|
||||
gint x, y;
|
||||
GdkModifierType state;
|
||||
|
||||
if (event->is_hint) {
|
||||
gdk_window_get_pointer(event->window, &x, &y, &state);
|
||||
} else {
|
||||
x = (gint)event->x;
|
||||
y = (gint)event->y;
|
||||
state = (GdkModifierType)event->state;
|
||||
}
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefStateModifiers(state);
|
||||
|
||||
bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY);
|
||||
|
||||
host->SendMouseMoveEvent(mouse_event, mouse_leave);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::ScrollEvent(GtkWidget* widget,
|
||||
GdkEventScroll* event,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!self->browser_.get())
|
||||
return TRUE;
|
||||
|
||||
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
|
||||
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = event->x;
|
||||
mouse_event.y = event->y;
|
||||
self->ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
mouse_event.modifiers = GetCefStateModifiers(event->state);
|
||||
|
||||
static const int scrollbarPixelsPerGtkTick = 40;
|
||||
int deltaX = 0;
|
||||
int deltaY = 0;
|
||||
switch (event->direction) {
|
||||
case GDK_SCROLL_UP:
|
||||
deltaY = scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_DOWN:
|
||||
deltaY = -scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_LEFT:
|
||||
deltaX = scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
case GDK_SCROLL_RIGHT:
|
||||
deltaX = -scrollbarPixelsPerGtkTick;
|
||||
break;
|
||||
}
|
||||
|
||||
host->SendMouseWheelEvent(mouse_event, deltaX, deltaY);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
gint BrowserWindowOsrGtk::FocusEvent(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
BrowserWindowOsrGtk* self) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (self->browser_.get())
|
||||
self->browser_->GetHost()->SendFocusEvent(event->in == TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool BrowserWindowOsrGtk::IsOverPopupWidget(int x, int y) const {
|
||||
const CefRect& rc = renderer_.popup_rect();
|
||||
int popup_right = rc.x + rc.width;
|
||||
int popup_bottom = rc.y + rc.height;
|
||||
return (x >= rc.x) && (x < popup_right) &&
|
||||
(y >= rc.y) && (y < popup_bottom);
|
||||
}
|
||||
|
||||
int BrowserWindowOsrGtk::GetPopupXOffset() const {
|
||||
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
||||
}
|
||||
|
||||
int BrowserWindowOsrGtk::GetPopupYOffset() const {
|
||||
return renderer_.original_popup_rect().y - renderer_.popup_rect().y;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::ApplyPopupOffset(int& x, int& y) const {
|
||||
if (IsOverPopupWidget(x, y)) {
|
||||
x += GetPopupXOffset();
|
||||
y += GetPopupYOffset();
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowOsrGtk::EnableGL() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (gl_enabled_)
|
||||
return;
|
||||
|
||||
@ -1336,8 +1477,8 @@ void OSRWindow::EnableGL() {
|
||||
gl_enabled_ = true;
|
||||
}
|
||||
|
||||
void OSRWindow::DisableGL() {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
void BrowserWindowOsrGtk::DisableGL() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!gl_enabled_)
|
||||
return;
|
122
tests/cefclient/browser_window_osr_gtk.h
Normal file
122
tests/cefclient/browser_window_osr_gtk.h
Normal file
@ -0,0 +1,122 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_GTK_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_GTK_H_
|
||||
|
||||
#include "cefclient/browser_window.h"
|
||||
#include "cefclient/client_handler_osr.h"
|
||||
#include "cefclient/osr_renderer.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single off-screen browser
|
||||
// instance. The methods of this class must be called on the main thread unless
|
||||
// otherwise indicated.
|
||||
class BrowserWindowOsrGtk : public BrowserWindow,
|
||||
public ClientHandlerOsr::OsrDelegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
// BrowserWindow methods.
|
||||
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
// ClientHandlerOsr::OsrDelegate methods.
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) OVERRIDE;
|
||||
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) OVERRIDE;
|
||||
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
|
||||
void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE;
|
||||
void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::PaintElementType type,
|
||||
const CefRenderHandler::RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) OVERRIDE;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CefRenderHandler::CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) OVERRIDE;
|
||||
bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) OVERRIDE;
|
||||
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
|
||||
CefRenderHandler::DragOperation operation) OVERRIDE;
|
||||
|
||||
private:
|
||||
// Create the GTK GlArea.
|
||||
void Create(ClientWindowHandle parent_handle);
|
||||
|
||||
// Signal handlers for the GTK GlArea.
|
||||
static gint SizeAllocation(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gint ClickEvent(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gint KeyEvent(GtkWidget* widget,
|
||||
GdkEventKey* event,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gint MoveEvent(GtkWidget* widget,
|
||||
GdkEventMotion* event,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gint ScrollEvent(GtkWidget* widget,
|
||||
GdkEventScroll* event,
|
||||
BrowserWindowOsrGtk* self);
|
||||
static gint FocusEvent(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
BrowserWindowOsrGtk* self);
|
||||
|
||||
bool IsOverPopupWidget(int x, int y) const;
|
||||
int GetPopupXOffset() const;
|
||||
int GetPopupYOffset() const;
|
||||
void ApplyPopupOffset(int& x, int& y) const;
|
||||
|
||||
void EnableGL();
|
||||
void DisableGL();
|
||||
|
||||
// The below members will only be accessed on the main thread which should be
|
||||
// the same as the CEF UI thread.
|
||||
OsrRenderer renderer_;
|
||||
ClientWindowHandle glarea_;
|
||||
bool hidden_;
|
||||
bool gl_enabled_;
|
||||
bool painting_popup_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrGtk);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_GTK_H_
|
@ -8,41 +8,42 @@
|
||||
|
||||
namespace client {
|
||||
|
||||
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
||||
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: BrowserWindowWin(delegate),
|
||||
: BrowserWindow(delegate),
|
||||
transparent_(transparent),
|
||||
osr_hwnd_(NULL) {
|
||||
osr_window_ = new OsrWindowWin(this, transparent, show_update_rect);
|
||||
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
void BrowserWindowOsrWin::CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Create the new browser and native window on the UI thread.
|
||||
osr_window_->CreateBrowser(parent_hwnd, rect, client_handler_, settings,
|
||||
RECT wnd_rect = {rect.x, rect.y, rect.x + rect.width, rect.y + rect.height};
|
||||
osr_window_->CreateBrowser(parent_handle, wnd_rect, client_handler_, settings,
|
||||
client_handler_->startup_url());
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::GetPopupConfig(HWND temp_hwnd,
|
||||
void BrowserWindowOsrWin::GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any thread.
|
||||
windowInfo.SetAsWindowless(temp_hwnd, transparent_);
|
||||
windowInfo.SetAsWindowless(temp_handle, transparent_);
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::ShowPopup(HWND parent_hwnd,
|
||||
void BrowserWindowOsrWin::ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
if (osr_window_)
|
||||
osr_window_->ShowPopup(parent_hwnd, x, y, width, height);
|
||||
osr_window_->ShowPopup(parent_handle, x, y, width, height);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::Show() {
|
||||
@ -69,7 +70,7 @@ void BrowserWindowOsrWin::SetFocus() {
|
||||
osr_window_->SetFocus();
|
||||
}
|
||||
|
||||
HWND BrowserWindowOsrWin::GetHWND() const {
|
||||
ClientWindowHandle BrowserWindowOsrWin::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return osr_hwnd_;
|
||||
}
|
||||
@ -80,7 +81,7 @@ void BrowserWindowOsrWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||
// Release the OSR window reference. It will be deleted on the UI thread.
|
||||
osr_window_ = NULL;
|
||||
|
||||
BrowserWindowWin::OnBrowserClosed(browser);
|
||||
BrowserWindow::OnBrowserClosed(browser);
|
||||
}
|
||||
|
||||
void BrowserWindowOsrWin::OnOsrNativeWindowCreated(HWND hwnd) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/browser_window.h"
|
||||
#include "cefclient/osr_window_win.h"
|
||||
|
||||
namespace client {
|
||||
@ -13,34 +13,34 @@ namespace client {
|
||||
// Represents a native child window hosting a single off-screen browser
|
||||
// instance. The methods of this class must be called on the main thread unless
|
||||
// otherwise indicated.
|
||||
class BrowserWindowOsrWin : public BrowserWindowWin,
|
||||
OsrWindowWin::Delegate {
|
||||
class BrowserWindowOsrWin : public BrowserWindow,
|
||||
public OsrWindowWin::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
||||
BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
||||
const std::string& startup_url,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
// BrowserWindowWin methods.
|
||||
void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
// BrowserWindow methods.
|
||||
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(HWND temp_hwnd,
|
||||
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(HWND parent_hwnd,
|
||||
void ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
HWND GetHWND() const OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
// ClientHandler::Delegate methods.
|
||||
// ClienHandler::Delegate methods.
|
||||
void OnBrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
// OsrWindowWin::Delegate methods.
|
||||
|
186
tests/cefclient/browser_window_std_gtk.cc
Normal file
186
tests/cefclient/browser_window_std_gtk.cc
Normal file
@ -0,0 +1,186 @@
|
||||
// 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 "cefclient/browser_window_std_gtk.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.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 "include/cef_app.h"
|
||||
#include "cefclient/client_handler_std.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
::Window GetXWindowForWidget(GtkWidget* widget) {
|
||||
// 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(::Window xwindow, bool visible) {
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
|
||||
// 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.
|
||||
scoped_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,
|
||||
NULL,
|
||||
0); // num items
|
||||
}
|
||||
}
|
||||
|
||||
void SetXWindowBounds(::Window xwindow,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
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,
|
||||
const std::string& startup_url)
|
||||
: BrowserWindow(delegate) {
|
||||
client_handler_ = new ClientHandlerStd(this, startup_url);
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Set the window handle for GTK dialogs.
|
||||
client_handler_->SetMainWindowHandle(parent_handle);
|
||||
|
||||
CefWindowInfo window_info;
|
||||
window_info.SetAsChild(GetXWindowForWidget(parent_handle), rect);
|
||||
|
||||
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||
client_handler_->startup_url(),
|
||||
settings, NULL);
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any 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();
|
||||
|
||||
// Set the window handle for GTK dialogs.
|
||||
client_handler_->SetMainWindowHandle(parent_handle);
|
||||
|
||||
if (browser_) {
|
||||
::Window parent_xwindow = GetXWindowForWidget(parent_handle);
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
::Window xwindow = browser_->GetHost()->GetWindowHandle();
|
||||
DCHECK(xwindow);
|
||||
|
||||
XReparentWindow(xdisplay, xwindow, parent_xwindow, x, y);
|
||||
|
||||
SetXWindowBounds(xwindow, x, y, width, height);
|
||||
SetXWindowVisible(xwindow, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::Show() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_) {
|
||||
::Window xwindow = browser_->GetHost()->GetWindowHandle();
|
||||
DCHECK(xwindow);
|
||||
SetXWindowVisible(xwindow, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_) {
|
||||
::Window xwindow = browser_->GetHost()->GetWindowHandle();
|
||||
DCHECK(xwindow);
|
||||
SetXWindowVisible(xwindow, false);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_) {
|
||||
::Window xwindow = browser_->GetHost()->GetWindowHandle();
|
||||
DCHECK(xwindow);
|
||||
SetXWindowBounds(xwindow, x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindowStdGtk::SetFocus() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_) {
|
||||
// Give focus to the browser window.
|
||||
browser_->GetHost()->SetFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
ClientWindowHandle BrowserWindowStdGtk::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// There is no GtkWidget* representation of this object.
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // namespace client
|
44
tests/cefclient/browser_window_std_gtk.h
Normal file
44
tests/cefclient/browser_window_std_gtk.h
Normal file
@ -0,0 +1,44 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_GTK_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_GTK_H_
|
||||
|
||||
#include "cefclient/browser_window.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single windowed browser instance.
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class BrowserWindowStdGtk : public BrowserWindow {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowStdGtk(Delegate* delegate,
|
||||
const std::string& startup_url);
|
||||
|
||||
// BrowserWindow methods.
|
||||
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdGtk);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_GTK_H_
|
@ -11,40 +11,41 @@ namespace client {
|
||||
|
||||
BrowserWindowStdWin::BrowserWindowStdWin(Delegate* delegate,
|
||||
const std::string& startup_url)
|
||||
: BrowserWindowWin(delegate) {
|
||||
: BrowserWindow(delegate) {
|
||||
client_handler_ = new ClientHandlerStd(this, startup_url);
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
void BrowserWindowStdWin::CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
CefWindowInfo window_info;
|
||||
window_info.SetAsChild(parent_hwnd, rect);
|
||||
RECT wnd_rect = {rect.x, rect.y, rect.x + rect.width, rect.y + rect.height};
|
||||
window_info.SetAsChild(parent_handle, wnd_rect);
|
||||
|
||||
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||
client_handler_->startup_url(),
|
||||
settings, NULL);
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::GetPopupConfig(HWND temp_hwnd,
|
||||
void BrowserWindowStdWin::GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
// Note: This method may be called on any thread.
|
||||
// The window will be properly sized after the browser is created.
|
||||
windowInfo.SetAsChild(temp_hwnd, RECT());
|
||||
windowInfo.SetAsChild(temp_handle, RECT());
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
void BrowserWindowStdWin::ShowPopup(HWND parent_hwnd,
|
||||
void BrowserWindowStdWin::ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
HWND hwnd = GetWindowHandle();
|
||||
if (hwnd) {
|
||||
SetParent(hwnd, parent_hwnd);
|
||||
SetParent(hwnd, parent_handle);
|
||||
SetWindowPos(hwnd, NULL, x, y,
|
||||
static_cast<int>(width), static_cast<int>(height),
|
||||
SWP_NOZORDER);
|
||||
@ -55,7 +56,7 @@ void BrowserWindowStdWin::ShowPopup(HWND parent_hwnd,
|
||||
void BrowserWindowStdWin::Show() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
HWND hwnd = GetWindowHandle();
|
||||
if (hwnd && !::IsWindowVisible(hwnd))
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
}
|
||||
@ -63,7 +64,7 @@ void BrowserWindowStdWin::Show() {
|
||||
void BrowserWindowStdWin::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
HWND hwnd = GetWindowHandle();
|
||||
if (hwnd) {
|
||||
// When the frame window is minimized set the browser window size to 0x0 to
|
||||
// reduce resource usage.
|
||||
@ -75,7 +76,7 @@ void BrowserWindowStdWin::Hide() {
|
||||
void BrowserWindowStdWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
HWND hwnd = GetHWND();
|
||||
HWND hwnd = GetWindowHandle();
|
||||
if (hwnd) {
|
||||
// Set the browser window bounds.
|
||||
SetWindowPos(hwnd, NULL, x, y,
|
||||
@ -93,7 +94,7 @@ void BrowserWindowStdWin::SetFocus() {
|
||||
}
|
||||
}
|
||||
|
||||
HWND BrowserWindowStdWin::GetHWND() const {
|
||||
ClientWindowHandle BrowserWindowStdWin::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_)
|
||||
|
@ -5,35 +5,35 @@
|
||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
||||
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/browser_window.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a native child window hosting a single windowed browser instance.
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class BrowserWindowStdWin : public BrowserWindowWin {
|
||||
class BrowserWindowStdWin : public BrowserWindow {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
// |delegate| must outlive this object.
|
||||
BrowserWindowStdWin(Delegate* delegate,
|
||||
const std::string& startup_url);
|
||||
|
||||
// BrowserWindowWin methods.
|
||||
void CreateBrowser(HWND parent_hwnd,
|
||||
const RECT& rect,
|
||||
// BrowserWindow methods.
|
||||
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings) OVERRIDE;
|
||||
void GetPopupConfig(HWND temp_hwnd,
|
||||
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void ShowPopup(HWND parent_hwnd,
|
||||
void ShowPopup(ClientWindowHandle parent_handle,
|
||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Show() OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void SetFocus() OVERRIDE;
|
||||
HWND GetHWND() const OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdWin);
|
||||
|
@ -2,14 +2,12 @@
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkgl.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#undef Status // Definition conflicts with cef_urlrequest.h
|
||||
#undef Success // Definition conflicts with cef_message_router.h
|
||||
#undef Success // Definition conflicts with cef_message_router.h
|
||||
#undef RootWindow // Definition conflicts with root_window.h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -18,42 +16,15 @@
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_frame.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "cefclient/client_app.h"
|
||||
#include "cefclient/client_handler_shared.h"
|
||||
#include "cefclient/client_switches.h"
|
||||
#include "cefclient/main_context_impl.h"
|
||||
#include "cefclient/main_message_loop_std.h"
|
||||
#include "cefclient/osr_widget_gtk.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/test_runner.h"
|
||||
|
||||
namespace client {
|
||||
namespace {
|
||||
|
||||
// The global ClientHandlerShared reference.
|
||||
CefRefPtr<ClientHandlerShared> g_handler;
|
||||
|
||||
// Height of the buttons at the top of the GTK window.
|
||||
int g_toolbar_height = 0;
|
||||
|
||||
// Height of the integrated menu bar (if any) at the top of the GTK window.
|
||||
int g_menubar_height = 0;
|
||||
|
||||
|
||||
// Used by off-screen rendering to find the associated CefBrowser.
|
||||
class MainBrowserProvider : public OSRBrowserProvider {
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() {
|
||||
if (g_handler.get())
|
||||
return g_handler->GetBrowser();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} g_main_browser_provider;
|
||||
|
||||
|
||||
int XErrorHandlerImpl(Display *display, XErrorEvent *event) {
|
||||
LOG(WARNING)
|
||||
<< "X error received: "
|
||||
@ -69,254 +40,9 @@ int XIOErrorHandlerImpl(Display *display) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void destroy(GtkWidget* widget, gpointer data) {
|
||||
// Quitting CEF is handled in ClientHandler::OnBeforeClose().
|
||||
}
|
||||
|
||||
gboolean delete_event(GtkWidget* widget, GdkEvent* event,
|
||||
GtkWindow* window) {
|
||||
if (g_handler.get() && !g_handler->IsClosing()) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser.get()) {
|
||||
// Notify the browser window that we would like to close it. This
|
||||
// will result in a call to ClientHandler::DoClose() if the
|
||||
// JavaScript 'onbeforeunload' event handler allows it.
|
||||
browser->GetHost()->CloseBrowser(false);
|
||||
|
||||
// Cancel the close.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the close.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TerminationSignalHandler(int signatl) {
|
||||
MainMessageLoop::Get()->Quit();
|
||||
}
|
||||
|
||||
void VboxSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
void* data) {
|
||||
if (g_handler) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser && !browser->GetHost()->IsWindowRenderingDisabled()) {
|
||||
// Size the browser window to match the GTK widget.
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
::Window xwindow = browser->GetHost()->GetWindowHandle();
|
||||
XWindowChanges changes = {0};
|
||||
changes.width = allocation->width;
|
||||
changes.height = allocation->height -
|
||||
(g_toolbar_height + g_menubar_height);
|
||||
changes.y = g_toolbar_height + g_menubar_height;
|
||||
XConfigureWindow(xdisplay, xwindow, CWHeight | CWWidth | CWY, &changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
void* data) {
|
||||
g_toolbar_height = allocation->height;
|
||||
}
|
||||
|
||||
void MenubarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
void* data) {
|
||||
g_menubar_height = allocation->height;
|
||||
}
|
||||
|
||||
gboolean WindowFocusIn(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
gpointer user_data) {
|
||||
if (g_handler && event->in) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser) {
|
||||
if (browser->GetHost()->IsWindowRenderingDisabled()) {
|
||||
// Give focus to the off-screen browser.
|
||||
browser->GetHost()->SendFocusEvent(true);
|
||||
} else {
|
||||
// Give focus to the browser window.
|
||||
browser->GetHost()->SetFocus(true);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean WindowState(GtkWidget* widget,
|
||||
GdkEventWindowState* event,
|
||||
gpointer user_data) {
|
||||
if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED))
|
||||
return TRUE;
|
||||
|
||||
if (!g_handler)
|
||||
return TRUE;
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (!browser)
|
||||
return TRUE;
|
||||
|
||||
const bool iconified = (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED);
|
||||
if (browser->GetHost()->IsWindowRenderingDisabled()) {
|
||||
// Notify the off-screen browser that it was shown or hidden.
|
||||
browser->GetHost()->WasHidden(iconified);
|
||||
} else {
|
||||
// Forward the state change event to the browser window.
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
::Window xwindow = browser->GetHost()->GetWindowHandle();
|
||||
|
||||
// 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 (iconified) {
|
||||
// Set the hidden property state value.
|
||||
scoped_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,
|
||||
NULL,
|
||||
0); // num items
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean WindowConfigure(GtkWindow* window,
|
||||
GdkEvent* event,
|
||||
gpointer data) {
|
||||
// Called when size, position or stack order changes.
|
||||
if (g_handler) {
|
||||
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
|
||||
if (browser) {
|
||||
// Notify the browser of move/resize events so that:
|
||||
// - Popup windows are displayed in the correct location and dismissed
|
||||
// when the window moves.
|
||||
// - Drag&drop areas are updated accordingly.
|
||||
browser->GetHost()->NotifyMoveOrResizeStarted();
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // Don't stop this message.
|
||||
}
|
||||
|
||||
// Callback for Tests menu items.
|
||||
gboolean MenuItemActivated(GtkWidget* widget, gpointer data) {
|
||||
if (g_handler.get() && g_handler->GetBrowserId())
|
||||
test_runner::RunTest(g_handler->GetBrowser(), GPOINTER_TO_INT(data));
|
||||
|
||||
return FALSE; // Don't stop this message.
|
||||
}
|
||||
|
||||
// Callback for when you click the back button.
|
||||
void BackButtonClicked(GtkButton* button) {
|
||||
if (g_handler.get() && g_handler->GetBrowserId())
|
||||
g_handler->GetBrowser()->GoBack();
|
||||
}
|
||||
|
||||
// Callback for when you click the forward button.
|
||||
void ForwardButtonClicked(GtkButton* button) {
|
||||
if (g_handler.get() && g_handler->GetBrowserId())
|
||||
g_handler->GetBrowser()->GoForward();
|
||||
}
|
||||
|
||||
// Callback for when you click the stop button.
|
||||
void StopButtonClicked(GtkButton* button) {
|
||||
if (g_handler.get() && g_handler->GetBrowserId())
|
||||
g_handler->GetBrowser()->StopLoad();
|
||||
}
|
||||
|
||||
// Callback for when you click the reload button.
|
||||
void ReloadButtonClicked(GtkButton* button) {
|
||||
if (g_handler.get() && g_handler->GetBrowserId())
|
||||
g_handler->GetBrowser()->Reload();
|
||||
}
|
||||
|
||||
// Callback for when you press enter in the URL box.
|
||||
void URLEntryActivate(GtkEntry* entry) {
|
||||
if (!g_handler.get() || !g_handler->GetBrowserId())
|
||||
return;
|
||||
|
||||
const gchar* url = gtk_entry_get_text(entry);
|
||||
g_handler->GetBrowser()->GetMainFrame()->LoadURL(std::string(url).c_str());
|
||||
}
|
||||
|
||||
gboolean URLEntryButtonPress(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
gpointer user_data) {
|
||||
// Give focus to the GTK window.
|
||||
GtkWidget* window = gtk_widget_get_ancestor(widget,
|
||||
GTK_TYPE_WINDOW);
|
||||
GdkWindow* gdk_window = gtk_widget_get_window(window);
|
||||
::Display* xdisplay = GDK_WINDOW_XDISPLAY(gdk_window);
|
||||
::Window xwindow = GDK_WINDOW_XID(gdk_window);
|
||||
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// GTK utility functions ----------------------------------------------
|
||||
|
||||
GtkWidget* AddMenuEntry(GtkWidget* menu_widget, const char* text, int id) {
|
||||
GtkWidget* entry = gtk_menu_item_new_with_label(text);
|
||||
g_signal_connect(entry, "activate", G_CALLBACK(MenuItemActivated),
|
||||
GINT_TO_POINTER(id));
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu_widget), entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text) {
|
||||
GtkWidget* menu_widget = gtk_menu_new();
|
||||
GtkWidget* menu_header = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_header), menu_widget);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_header);
|
||||
return menu_widget;
|
||||
}
|
||||
|
||||
GtkWidget* CreateMenuBar() {
|
||||
GtkWidget* menu_bar = gtk_menu_bar_new();
|
||||
GtkWidget* debug_menu = CreateMenu(menu_bar, "Tests");
|
||||
|
||||
AddMenuEntry(debug_menu, "Get Source", ID_TESTS_GETSOURCE);
|
||||
AddMenuEntry(debug_menu, "Get Text", ID_TESTS_GETTEXT);
|
||||
AddMenuEntry(debug_menu, "Popup Window", ID_TESTS_POPUP);
|
||||
AddMenuEntry(debug_menu, "Request", ID_TESTS_REQUEST);
|
||||
AddMenuEntry(debug_menu, "Plugin Info", ID_TESTS_PLUGIN_INFO);
|
||||
AddMenuEntry(debug_menu, "Zoom In", ID_TESTS_ZOOM_IN);
|
||||
AddMenuEntry(debug_menu, "Zoom Out", ID_TESTS_ZOOM_OUT);
|
||||
AddMenuEntry(debug_menu, "Zoom Reset", ID_TESTS_ZOOM_RESET);
|
||||
AddMenuEntry(debug_menu, "Begin Tracing", ID_TESTS_TRACING_BEGIN);
|
||||
AddMenuEntry(debug_menu, "End Tracing", ID_TESTS_TRACING_END);
|
||||
AddMenuEntry(debug_menu, "Print", ID_TESTS_PRINT);
|
||||
AddMenuEntry(debug_menu, "Other Tests", ID_TESTS_OTHER_TESTS);
|
||||
return menu_bar;
|
||||
LOG(ERROR) << "Received termination signal: " << signatl;
|
||||
MainContext::Get()->GetRootWindowManager()->CloseAllWindows(true);
|
||||
}
|
||||
|
||||
int RunMain(int argc, char* argv[]) {
|
||||
@ -334,7 +60,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
return exit_code;
|
||||
|
||||
// Create the main context object.
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv));
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv, true));
|
||||
|
||||
CefSettings settings;
|
||||
|
||||
@ -350,7 +76,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
||||
|
||||
// Initialize CEF.
|
||||
CefInitialize(main_args, settings, app.get(), NULL);
|
||||
context->Initialize(main_args, settings, app.get(), NULL);
|
||||
|
||||
// The Chromium sandbox requires that there only be a single thread during
|
||||
// initialization. Therefore initialize GTK after CEF.
|
||||
@ -359,130 +85,25 @@ int RunMain(int argc, char* argv[]) {
|
||||
// Perform gtkglext initialization required by the OSR example.
|
||||
gtk_gl_init(&argc, &argv_copy);
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
|
||||
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
||||
g_signal_connect(window, "focus-in-event",
|
||||
G_CALLBACK(WindowFocusIn), NULL);
|
||||
g_signal_connect(window, "window-state-event",
|
||||
G_CALLBACK(WindowState), NULL);
|
||||
g_signal_connect(G_OBJECT(window), "configure-event",
|
||||
G_CALLBACK(WindowConfigure), NULL);
|
||||
|
||||
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
|
||||
g_signal_connect(vbox, "size-allocate",
|
||||
G_CALLBACK(VboxSizeAllocated), NULL);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
|
||||
GtkWidget* menu_bar = CreateMenuBar();
|
||||
g_signal_connect(menu_bar, "size-allocate",
|
||||
G_CALLBACK(MenubarSizeAllocated), NULL);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget* toolbar = gtk_toolbar_new();
|
||||
// Turn off the labels on the toolbar buttons.
|
||||
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
|
||||
g_signal_connect(toolbar, "size-allocate",
|
||||
G_CALLBACK(ToolbarSizeAllocated), NULL);
|
||||
|
||||
GtkToolItem* back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
|
||||
g_signal_connect(back, "clicked",
|
||||
G_CALLBACK(BackButtonClicked), NULL);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), back, -1 /* append */);
|
||||
|
||||
GtkToolItem* forward = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
|
||||
g_signal_connect(forward, "clicked",
|
||||
G_CALLBACK(ForwardButtonClicked), NULL);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), forward, -1 /* append */);
|
||||
|
||||
GtkToolItem* reload = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH);
|
||||
g_signal_connect(reload, "clicked",
|
||||
G_CALLBACK(ReloadButtonClicked), NULL);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), reload, -1 /* append */);
|
||||
|
||||
GtkToolItem* stop = gtk_tool_button_new_from_stock(GTK_STOCK_STOP);
|
||||
g_signal_connect(stop, "clicked",
|
||||
G_CALLBACK(StopButtonClicked), NULL);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), stop, -1 /* append */);
|
||||
|
||||
GtkWidget* entry = gtk_entry_new();
|
||||
g_signal_connect(entry, "activate",
|
||||
G_CALLBACK(URLEntryActivate), NULL);
|
||||
g_signal_connect(entry, "button-press-event",
|
||||
G_CALLBACK(URLEntryButtonPress), NULL);
|
||||
|
||||
GtkToolItem* tool_item = gtk_tool_item_new();
|
||||
gtk_container_add(GTK_CONTAINER(tool_item), entry);
|
||||
gtk_tool_item_set_expand(tool_item, TRUE);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_item, -1); // append
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect(G_OBJECT(window), "destroy",
|
||||
G_CALLBACK(destroy), NULL);
|
||||
g_signal_connect(G_OBJECT(window), "delete_event",
|
||||
G_CALLBACK(delete_event), window);
|
||||
|
||||
// Create the handler.
|
||||
g_handler = new ClientHandlerShared();
|
||||
g_handler->SetMainWindowHandle(vbox);
|
||||
g_handler->SetUXWindowHandles(entry, GTK_WIDGET(back), GTK_WIDGET(forward),
|
||||
GTK_WIDGET(reload), GTK_WIDGET(stop));
|
||||
|
||||
CefWindowInfo window_info;
|
||||
CefBrowserSettings browserSettings;
|
||||
|
||||
// Populate the browser settings based on command line arguments.
|
||||
context->PopulateBrowserSettings(&browserSettings);
|
||||
|
||||
if (g_handler->is_osr()) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
const bool transparent =
|
||||
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
command_line->HasSwitch(switches::kShowUpdateRect);
|
||||
|
||||
// Create the GTKGL surface.
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent,
|
||||
show_update_rect, vbox);
|
||||
|
||||
// Show the GTK window.
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
|
||||
// The GTK window must be visible before we can retrieve the XID.
|
||||
::Window xwindow =
|
||||
GDK_WINDOW_XID(gtk_widget_get_window(osr_window->GetWindowHandle()));
|
||||
window_info.SetAsWindowless(xwindow, transparent);
|
||||
g_handler->SetOSRHandler(osr_window.get());
|
||||
} else {
|
||||
// Show the GTK window.
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
|
||||
// The GTK window must be visible before we can retrieve the XID.
|
||||
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(window));
|
||||
window_info.SetAsChild(xwindow,
|
||||
CefRect(0, g_toolbar_height, 800, 600 - g_toolbar_height));
|
||||
}
|
||||
|
||||
// Create the browser window.
|
||||
CefBrowserHost::CreateBrowserSync(
|
||||
window_info, g_handler.get(),
|
||||
g_handler->startup_url(), browserSettings, NULL);
|
||||
|
||||
// Install a signal handler so we clean up after ourselves.
|
||||
signal(SIGINT, TerminationSignalHandler);
|
||||
signal(SIGTERM, TerminationSignalHandler);
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
|
||||
// Create the first window.
|
||||
context->GetRootWindowManager()->CreateRootWindow(
|
||||
true, // Show controls.
|
||||
settings.windowless_rendering_enabled ? true : false,
|
||||
CefRect(), // Use default system size.
|
||||
std::string()); // Use default URL.
|
||||
|
||||
// Run the message loop. This will block until Quit() is called.
|
||||
int result = message_loop->Run();
|
||||
|
||||
// Shut down CEF.
|
||||
CefShutdown();
|
||||
context->Shutdown();
|
||||
|
||||
// Release objects in reverse order of creation.
|
||||
message_loop.reset();
|
||||
|
@ -511,7 +511,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
[ClientApplication sharedApplication];
|
||||
|
||||
// Create the main context object.
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv));
|
||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv, true));
|
||||
|
||||
CefSettings settings;
|
||||
|
||||
@ -522,7 +522,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
||||
|
||||
// Initialize CEF.
|
||||
CefInitialize(main_args, settings, app.get(), NULL);
|
||||
context->Initialize(main_args, settings, app.get(), NULL);
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
@ -537,7 +537,7 @@ int RunMain(int argc, char* argv[]) {
|
||||
int result = message_loop->Run();
|
||||
|
||||
// Shut down CEF.
|
||||
CefShutdown();
|
||||
context->Shutdown();
|
||||
|
||||
// Release objects in reverse order of creation.
|
||||
g_handler = NULL;
|
||||
|
@ -66,7 +66,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
message_loop.reset(new MainMessageLoopStd);
|
||||
|
||||
// Initialize CEF.
|
||||
CefInitialize(main_args, settings, app.get(), sandbox_info);
|
||||
context->Initialize(main_args, settings, app.get(), sandbox_info);
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
@ -83,7 +83,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
int result = message_loop->Run();
|
||||
|
||||
// Shut down CEF.
|
||||
CefShutdown();
|
||||
context->Shutdown();
|
||||
|
||||
// Release objects in reverse order of creation.
|
||||
message_loop.reset();
|
||||
|
@ -12,15 +12,10 @@
|
||||
#include "include/cef_client.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
#include "cefclient/client_types.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <gtk/gtk.h>
|
||||
#include "cefclient/dialog_handler_gtk.h"
|
||||
|
||||
// The Linux client uses GTK instead of the underlying platform type (X11).
|
||||
#define ClientWindowHandle GtkWidget*
|
||||
#else
|
||||
#define ClientWindowHandle CefWindowHandle
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
|
20
tests/cefclient/client_types.h
Normal file
20
tests/cefclient/client_types.h
Normal file
@ -0,0 +1,20 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_TYPES_H_
|
||||
#define CEF_TESTS_CEFCLIENT_CLIENT_TYPES_H_
|
||||
|
||||
#include "include/cef_base.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
// The Linux client uses GTK instead of the underlying platform type (X11).
|
||||
#define ClientWindowHandle GtkWidget*
|
||||
#else
|
||||
#define ClientWindowHandle CefWindowHandle
|
||||
#endif
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_CLIENT_TYPES_H_
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace client {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
class RootWindowManager;
|
||||
#endif
|
||||
|
||||
@ -39,7 +39,7 @@ class MainContext {
|
||||
virtual void PopulateSettings(CefSettings* settings) = 0;
|
||||
virtual void PopulateBrowserSettings(CefBrowserSettings* settings) = 0;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
// Returns the object used to create/manage RootWindow instances.
|
||||
virtual RootWindowManager* GetRootWindowManager() = 0;
|
||||
#endif
|
||||
|
@ -6,9 +6,6 @@
|
||||
|
||||
#include "cefclient/client_switches.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "cefclient/root_window_manager.h"
|
||||
#endif
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
@ -19,11 +16,11 @@ const char kDefaultUrl[] = "http://www.google.com";
|
||||
} // namespace
|
||||
|
||||
MainContextImpl::MainContextImpl(int argc,
|
||||
const char* const* argv
|
||||
#if defined(OS_WIN)
|
||||
, bool terminate_when_all_windows_closed
|
||||
#endif
|
||||
) {
|
||||
const char* const* argv,
|
||||
bool terminate_when_all_windows_closed)
|
||||
: terminate_when_all_windows_closed_(terminate_when_all_windows_closed),
|
||||
initialized_(false),
|
||||
shutdown_(false) {
|
||||
// Parse the command line.
|
||||
command_line_ = CefCommandLine::CreateCommandLine();
|
||||
#if defined(OS_WIN)
|
||||
@ -37,11 +34,12 @@ MainContextImpl::MainContextImpl(int argc,
|
||||
main_url_ = command_line_->GetSwitchValue(switches::kUrl);
|
||||
if (main_url_.empty())
|
||||
main_url_ = kDefaultUrl;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
root_window_manager_.reset(
|
||||
new RootWindowManager(terminate_when_all_windows_closed));
|
||||
#endif
|
||||
MainContextImpl::~MainContextImpl() {
|
||||
// The context must either not have been initialized, or it must have also
|
||||
// been shut down.
|
||||
DCHECK(!initialized_ || shutdown_);
|
||||
}
|
||||
|
||||
std::string MainContextImpl::GetConsoleLogPath() {
|
||||
@ -72,10 +70,48 @@ void MainContextImpl::PopulateBrowserSettings(CefBrowserSettings* settings) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
RootWindowManager* MainContextImpl::GetRootWindowManager() {
|
||||
DCHECK(InValidState());
|
||||
return root_window_manager_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool MainContextImpl::Initialize(const CefMainArgs& args,
|
||||
const CefSettings& settings,
|
||||
CefRefPtr<CefApp> application,
|
||||
void* windows_sandbox_info) {
|
||||
DCHECK(thread_checker_.CalledOnValidThread());
|
||||
DCHECK(!initialized_);
|
||||
DCHECK(!shutdown_);
|
||||
|
||||
if (!CefInitialize(args, settings, application, windows_sandbox_info))
|
||||
return false;
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
// Need to create the RootWindowManager after calling CefInitialize because
|
||||
// TempWindowX11 uses cef_get_xdisplay().
|
||||
root_window_manager_.reset(
|
||||
new RootWindowManager(terminate_when_all_windows_closed_));
|
||||
#endif
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainContextImpl::Shutdown() {
|
||||
DCHECK(thread_checker_.CalledOnValidThread());
|
||||
DCHECK(initialized_);
|
||||
DCHECK(!shutdown_);
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
root_window_manager_.reset();
|
||||
#endif
|
||||
|
||||
CefShutdown();
|
||||
|
||||
shutdown_ = true;
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@ -6,20 +6,22 @@
|
||||
#define CEF_TESTS_CEFCLIENT_MAIN_CONTEXT_IMPL_H_
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "cefclient/main_context.h"
|
||||
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
#include "cefclient/root_window_manager.h"
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
|
||||
// Used to store global context in the browser process.
|
||||
class MainContextImpl : public MainContext {
|
||||
public:
|
||||
MainContextImpl(int argc,
|
||||
const char* const* argv
|
||||
#if defined(OS_WIN)
|
||||
, bool terminate_when_all_windows_closed
|
||||
#endif
|
||||
);
|
||||
const char* const* argv,
|
||||
bool terminate_when_all_windows_closed);
|
||||
|
||||
// MainContext members.
|
||||
std::string GetConsoleLogPath() OVERRIDE;
|
||||
@ -28,23 +30,51 @@ class MainContextImpl : public MainContext {
|
||||
std::string GetMainURL() OVERRIDE;
|
||||
void PopulateSettings(CefSettings* settings) OVERRIDE;
|
||||
void PopulateBrowserSettings(CefBrowserSettings* settings) OVERRIDE;
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
RootWindowManager* GetRootWindowManager() OVERRIDE;
|
||||
#endif
|
||||
|
||||
// Initialize CEF and associated main context state. This method must be
|
||||
// called on the same thread that created this object.
|
||||
bool Initialize(const CefMainArgs& args,
|
||||
const CefSettings& settings,
|
||||
CefRefPtr<CefApp> application,
|
||||
void* windows_sandbox_info);
|
||||
|
||||
// Shut down CEF and associated context state. This method must be called on
|
||||
// the same thread that created this object.
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
// Allow deletion via scoped_ptr only.
|
||||
friend struct base::DefaultDeleter<MainContextImpl>;
|
||||
|
||||
~MainContextImpl() {}
|
||||
~MainContextImpl();
|
||||
|
||||
// Returns true if the context is in a valid state (initialized and not yet
|
||||
// shut down).
|
||||
bool InValidState() const {
|
||||
return initialized_ && !shutdown_;
|
||||
}
|
||||
|
||||
const bool terminate_when_all_windows_closed_;
|
||||
|
||||
// Track context state. Accessing these variables from multiple threads is
|
||||
// safe because only a single thread will exist at the time that they're set
|
||||
// (during context initialization and shutdown).
|
||||
bool initialized_;
|
||||
bool shutdown_;
|
||||
|
||||
CefRefPtr<CefCommandLine> command_line_;
|
||||
std::string main_url_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
scoped_ptr<RootWindowManager> root_window_manager_;
|
||||
#endif
|
||||
|
||||
// Used to verify that methods are called on the correct thread.
|
||||
base::ThreadChecker thread_checker_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MainContextImpl);
|
||||
};
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
// 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_CEFCLIENT_OSR_WIDGET_GTK_H_
|
||||
#define CEF_TESTS_CEFCLIENT_OSR_WIDGET_GTK_H_
|
||||
#pragma once
|
||||
|
||||
#include "include/cef_render_handler.h"
|
||||
#include "cefclient/client_handler_shared.h"
|
||||
#include "cefclient/osr_renderer.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
class OSRBrowserProvider {
|
||||
public:
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
|
||||
|
||||
protected:
|
||||
virtual ~OSRBrowserProvider() {}
|
||||
};
|
||||
|
||||
class OSRWindow : public ClientHandlerShared::RenderHandler {
|
||||
public:
|
||||
// Create a new OSRWindow instance. |browser_provider| must outlive this
|
||||
// object.
|
||||
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView);
|
||||
|
||||
static CefRefPtr<OSRWindow> From(
|
||||
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler);
|
||||
|
||||
ClientWindowHandle GetWindowHandle() const {
|
||||
return glarea_;
|
||||
}
|
||||
CefRefPtr<CefBrowserHost> GetBrowserHost() const {
|
||||
if (browser_provider_->GetBrowser())
|
||||
return browser_provider_->GetBrowser()->GetHost();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ClientHandlerShared::RenderHandler methods
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
// CefRenderHandler methods
|
||||
bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) OVERRIDE;
|
||||
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
int viewX,
|
||||
int viewY,
|
||||
int& screenX,
|
||||
int& screenY) OVERRIDE;
|
||||
void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
bool show) OVERRIDE;
|
||||
void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) OVERRIDE;
|
||||
void OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
PaintElementType type,
|
||||
const RectList& dirtyRects,
|
||||
const void* buffer,
|
||||
int width,
|
||||
int height) OVERRIDE;
|
||||
void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
CefCursorHandle cursor,
|
||||
CursorType type,
|
||||
const CefCursorInfo& custom_cursor_info) OVERRIDE;
|
||||
|
||||
void Invalidate();
|
||||
bool IsOverPopupWidget(int x, int y) const;
|
||||
int GetPopupXOffset() const;
|
||||
int GetPopupYOffset() const;
|
||||
void ApplyPopupOffset(int& x, int& y) const;
|
||||
|
||||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView);
|
||||
~OSRWindow();
|
||||
|
||||
void Render();
|
||||
void EnableGL();
|
||||
void DisableGL();
|
||||
|
||||
OsrRenderer renderer_;
|
||||
OSRBrowserProvider* browser_provider_;
|
||||
ClientWindowHandle glarea_;
|
||||
bool gl_enabled_;
|
||||
|
||||
bool painting_popup_;
|
||||
bool render_task_pending_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(OSRWindow);
|
||||
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_OSR_WIDGET_GTK_H_
|
@ -713,7 +713,7 @@ void OsrWindowWin::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
||||
void OsrWindowWin::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Detach |this| from the ClientHandler.
|
||||
// Detach |this| from the ClientHandlerOsr.
|
||||
static_cast<ClientHandlerOsr*>(browser_->GetHost()->GetClient().get())->
|
||||
DetachOsrDelegate();
|
||||
browser_ = NULL;
|
||||
|
@ -96,7 +96,7 @@ class OsrWindowWin :
|
||||
int GetPopupYOffset() const;
|
||||
void ApplyPopupOffset(int& x, int& y) const;
|
||||
|
||||
// ClientHandlerOsr::Delegate methods.
|
||||
// ClientHandlerOsr::OsrDelegate methods.
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "cefclient/client_types.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
@ -90,7 +91,7 @@ class RootWindow :
|
||||
virtual CefRefPtr<CefBrowser> GetBrowser() const = 0;
|
||||
|
||||
// Returns the handle for this window, if any.
|
||||
virtual CefWindowHandle GetWindowHandle() const = 0;
|
||||
virtual ClientWindowHandle GetWindowHandle() const = 0;
|
||||
|
||||
protected:
|
||||
// Allow deletion via scoped_refptr only.
|
||||
|
622
tests/cefclient/root_window_gtk.cc
Normal file
622
tests/cefclient/root_window_gtk.cc
Normal file
@ -0,0 +1,622 @@
|
||||
// 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 "cefclient/root_window_gtk.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.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_bind.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "cefclient/browser_window_osr_gtk.h"
|
||||
#include "cefclient/browser_window_std_gtk.h"
|
||||
#include "cefclient/client_switches.h"
|
||||
#include "cefclient/main_message_loop.h"
|
||||
#include "cefclient/resource.h"
|
||||
#include "cefclient/temp_window_x11.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
const char kMenuIdKey[] = "menu_id";
|
||||
|
||||
bool IsWindowMaximized(GtkWindow* window) {
|
||||
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
|
||||
gint state = gdk_window_get_state(gdk_window);
|
||||
return (state & GDK_WINDOW_STATE_MAXIMIZED) ? true : false;
|
||||
}
|
||||
|
||||
void MinimizeWindow(GtkWindow* window) {
|
||||
// Unmaximize the window before minimizing so restore behaves correctly.
|
||||
if (IsWindowMaximized(window))
|
||||
gtk_window_unmaximize(window);
|
||||
|
||||
gtk_window_iconify(window);
|
||||
}
|
||||
|
||||
void MaximizeWindow(GtkWindow* window) {
|
||||
gtk_window_maximize(window);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RootWindowGtk::RootWindowGtk()
|
||||
: delegate_(NULL),
|
||||
with_controls_(false),
|
||||
with_osr_(false),
|
||||
is_popup_(false),
|
||||
initialized_(false),
|
||||
window_(NULL),
|
||||
back_button_(NULL),
|
||||
forward_button_(NULL),
|
||||
reload_button_(NULL),
|
||||
stop_button_(NULL),
|
||||
url_entry_(NULL),
|
||||
toolbar_height_(0),
|
||||
menubar_height_(0),
|
||||
force_close_(false),
|
||||
window_destroyed_(false),
|
||||
browser_destroyed_(false) {
|
||||
}
|
||||
|
||||
RootWindowGtk::~RootWindowGtk() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// The window and browser should already have been destroyed.
|
||||
DCHECK(window_destroyed_);
|
||||
DCHECK(browser_destroyed_);
|
||||
}
|
||||
|
||||
void RootWindowGtk::Init(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& bounds,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& url) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(!initialized_);
|
||||
|
||||
delegate_ = delegate;
|
||||
with_controls_ = with_controls;
|
||||
with_osr_ = with_osr;
|
||||
start_rect_ = bounds;
|
||||
|
||||
CreateBrowserWindow(url);
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
// Create the native root window on the main thread.
|
||||
if (CURRENTLY_ON_MAIN_THREAD()) {
|
||||
CreateRootWindow(settings);
|
||||
} else {
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&RootWindowGtk::CreateRootWindow, this, settings));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::InitAsPopup(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(!initialized_);
|
||||
|
||||
delegate_ = delegate;
|
||||
with_controls_ = with_controls;
|
||||
with_osr_ = with_osr;
|
||||
is_popup_ = true;
|
||||
|
||||
if (popupFeatures.xSet)
|
||||
start_rect_.x = popupFeatures.x;
|
||||
if (popupFeatures.ySet)
|
||||
start_rect_.y = popupFeatures.y;
|
||||
if (popupFeatures.widthSet)
|
||||
start_rect_.width = popupFeatures.width;
|
||||
if (popupFeatures.heightSet)
|
||||
start_rect_.height = popupFeatures.height;
|
||||
|
||||
CreateBrowserWindow(std::string());
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
// The new popup is initially parented to a temporary window. The native root
|
||||
// window will be created after the browser is created and the popup window
|
||||
// will be re-parented to it at that time.
|
||||
browser_window_->GetPopupConfig(TempWindowX11::GetWindowHandle(),
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
void RootWindowGtk::Show(ShowMode mode) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!window_)
|
||||
return;
|
||||
|
||||
// Show the GTK window.
|
||||
gtk_widget_show_all(window_);
|
||||
|
||||
if (mode == ShowMinimized)
|
||||
MinimizeWindow(GTK_WINDOW(window_));
|
||||
else if (mode == ShowMaximized)
|
||||
MaximizeWindow(GTK_WINDOW(window_));
|
||||
}
|
||||
|
||||
void RootWindowGtk::Hide() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (window_)
|
||||
gtk_widget_hide(window_);
|
||||
}
|
||||
|
||||
void RootWindowGtk::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (!window_)
|
||||
return;
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(window_);
|
||||
GdkWindow* gdk_window = gtk_widget_get_window(window_);
|
||||
|
||||
// Make sure the window isn't minimized or maximized.
|
||||
if (IsWindowMaximized(window))
|
||||
gtk_window_unmaximize(window);
|
||||
else
|
||||
gtk_window_present(window);
|
||||
|
||||
// Retrieve information about the display that contains the window.
|
||||
GdkScreen* screen = gdk_screen_get_default();
|
||||
const gint monitor = gdk_screen_get_monitor_at_window(screen, gdk_window);
|
||||
GdkRectangle rect;
|
||||
gdk_screen_get_monitor_geometry(screen, monitor, &rect);
|
||||
|
||||
gdk_window_move_resize(gdk_window, rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
void RootWindowGtk::Close(bool force) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (window_) {
|
||||
force_close_ = force;
|
||||
gtk_widget_destroy(window_);
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> RootWindowGtk::GetBrowser() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (browser_window_)
|
||||
return browser_window_->GetBrowser();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClientWindowHandle RootWindowGtk::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return window_;
|
||||
}
|
||||
|
||||
void RootWindowGtk::CreateBrowserWindow(const std::string& startup_url) {
|
||||
if (with_osr_) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
const bool transparent =
|
||||
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
command_line->HasSwitch(switches::kShowUpdateRect);
|
||||
browser_window_.reset(new BrowserWindowOsrGtk(this, startup_url,
|
||||
transparent,
|
||||
show_update_rect));
|
||||
} else {
|
||||
browser_window_.reset(new BrowserWindowStdGtk(this, startup_url));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
DCHECK(!window_);
|
||||
|
||||
// TODO(port): If no x,y position is specified the window will always appear
|
||||
// in the upper-left corner. Maybe there's a better default place to put it?
|
||||
int x = start_rect_.x;
|
||||
int y = start_rect_.y;
|
||||
int width, height;
|
||||
if (start_rect_.IsEmpty()) {
|
||||
// TODO(port): Also, maybe there's a better way to choose the default size.
|
||||
width = 800;
|
||||
height = 600;
|
||||
} else {
|
||||
width = start_rect_.width;
|
||||
height = start_rect_.height;
|
||||
}
|
||||
|
||||
window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window_), width, height);
|
||||
g_signal_connect(G_OBJECT(window_), "focus-in-event",
|
||||
G_CALLBACK(&RootWindowGtk::WindowFocusIn), this);
|
||||
g_signal_connect(G_OBJECT(window_), "window-state-event",
|
||||
G_CALLBACK(&RootWindowGtk::WindowState), this);
|
||||
g_signal_connect(G_OBJECT(window_), "configure-event",
|
||||
G_CALLBACK(&RootWindowGtk::WindowConfigure), this);
|
||||
g_signal_connect(G_OBJECT(window_), "destroy",
|
||||
G_CALLBACK(&RootWindowGtk::WindowDestroy), this);
|
||||
g_signal_connect(G_OBJECT(window_), "delete_event",
|
||||
G_CALLBACK(&RootWindowGtk::WindowDelete), this);
|
||||
|
||||
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
|
||||
g_signal_connect(vbox, "size-allocate",
|
||||
G_CALLBACK(&RootWindowGtk::VboxSizeAllocated), this);
|
||||
gtk_container_add(GTK_CONTAINER(window_), vbox);
|
||||
|
||||
if (with_controls_) {
|
||||
GtkWidget* menu_bar = CreateMenuBar();
|
||||
g_signal_connect(menu_bar, "size-allocate",
|
||||
G_CALLBACK(&RootWindowGtk::MenubarSizeAllocated), this);
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 0);
|
||||
|
||||
GtkWidget* toolbar = gtk_toolbar_new();
|
||||
// Turn off the labels on the toolbar buttons.
|
||||
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
|
||||
g_signal_connect(toolbar, "size-allocate",
|
||||
G_CALLBACK(&RootWindowGtk::ToolbarSizeAllocated), this);
|
||||
|
||||
back_button_ = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
|
||||
g_signal_connect(back_button_, "clicked",
|
||||
G_CALLBACK(&RootWindowGtk::BackButtonClicked), this);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), back_button_, -1 /* append */);
|
||||
|
||||
forward_button_ = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
|
||||
g_signal_connect(forward_button_, "clicked",
|
||||
G_CALLBACK(&RootWindowGtk::ForwardButtonClicked), this);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), forward_button_, -1 /* append */);
|
||||
|
||||
reload_button_ = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH);
|
||||
g_signal_connect(reload_button_, "clicked",
|
||||
G_CALLBACK(&RootWindowGtk::ReloadButtonClicked), this);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), reload_button_, -1 /* append */);
|
||||
|
||||
stop_button_ = gtk_tool_button_new_from_stock(GTK_STOCK_STOP);
|
||||
g_signal_connect(stop_button_, "clicked",
|
||||
G_CALLBACK(&RootWindowGtk::StopButtonClicked), this);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), stop_button_, -1 /* append */);
|
||||
|
||||
url_entry_ = gtk_entry_new();
|
||||
g_signal_connect(url_entry_, "activate",
|
||||
G_CALLBACK(&RootWindowGtk::URLEntryActivate), this);
|
||||
g_signal_connect(url_entry_, "button-press-event",
|
||||
G_CALLBACK(&RootWindowGtk::URLEntryButtonPress), this);
|
||||
|
||||
GtkToolItem* tool_item = gtk_tool_item_new();
|
||||
gtk_container_add(GTK_CONTAINER(tool_item), url_entry_);
|
||||
gtk_tool_item_set_expand(tool_item, TRUE);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_item, -1); // append
|
||||
|
||||
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
// Realize (show) the GTK widget. This must be done before the browser is
|
||||
// created because the underlying X11 Window is required. |browser_bounds_|
|
||||
// will be set at this point based on the GTK *SizeAllocated signal callbacks.
|
||||
Show(ShowNormal);
|
||||
|
||||
// Most window managers ignore requests for initial window positions (instead
|
||||
// using a user-defined placement algorithm) and honor requests after the
|
||||
// window has already been shown.
|
||||
gtk_window_move(GTK_WINDOW(window_), x, y);
|
||||
|
||||
// Windowed browsers are parented to the X11 Window underlying the GtkWindow*
|
||||
// and must be sized manually. The OSR GTK widget, on the other hand, can be
|
||||
// added to the Vbox container for automatic layout-based sizing.
|
||||
GtkWidget* parent = with_osr_ ? vbox : window_;
|
||||
|
||||
if (!is_popup_) {
|
||||
// Create the browser window.
|
||||
browser_window_->CreateBrowser(parent, browser_bounds_, settings);
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
browser_window_->ShowPopup(parent, browser_bounds_.x, browser_bounds_.y,
|
||||
browser_bounds_.width, browser_bounds_.height);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// For popup browsers create the root window once the browser has been
|
||||
// created.
|
||||
if (is_popup_)
|
||||
CreateRootWindow(CefBrowserSettings());
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnBrowserWindowDestroyed() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
browser_window_.reset();
|
||||
|
||||
if (!window_destroyed_) {
|
||||
// The browser was destroyed first. This could be due to the use of
|
||||
// off-screen rendering or execution of JavaScript window.close().
|
||||
// Close the RootWindow asynchronously.
|
||||
Close(false);
|
||||
}
|
||||
|
||||
browser_destroyed_ = true;
|
||||
NotifyDestroyedIfDone();
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnSetAddress(const std::string& url) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (url_entry_) {
|
||||
std::string urlStr(url);
|
||||
gtk_entry_set_text(GTK_ENTRY(url_entry_), urlStr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnSetTitle(const std::string& title) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (window_) {
|
||||
std::string titleStr(title);
|
||||
gtk_window_set_title(GTK_WINDOW(window_), titleStr.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (with_controls_) {
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), isLoading);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(reload_button_), !isLoading);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(back_button_), canGoBack);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(forward_button_), canGoForward);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::NotifyDestroyedIfDone() {
|
||||
// Notify once both the window and the browser have been destroyed.
|
||||
if (window_destroyed_ && browser_destroyed_)
|
||||
delegate_->OnRootWindowDestroyed(this);
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
RootWindowGtk* self) {
|
||||
if (event->in && self->browser_window_.get()) {
|
||||
self->browser_window_->SetFocus();
|
||||
// Return true for a windowed browser so that focus is not passed to GTK.
|
||||
return self->with_osr_ ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::WindowState(GtkWidget* widget,
|
||||
GdkEventWindowState* event,
|
||||
RootWindowGtk* self) {
|
||||
// Called when the root window is iconified or restored. Hide the browser
|
||||
// window when the root window is iconified to reduce resource usage.
|
||||
if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) &&
|
||||
self->browser_window_.get()) {
|
||||
if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)
|
||||
self->browser_window_->Hide();
|
||||
else
|
||||
self->browser_window_->Show();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::WindowConfigure(GtkWindow* window,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self) {
|
||||
// Called when size, position or stack order changes.
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get()) {
|
||||
// Notify the browser of move/resize events so that:
|
||||
// - Popup windows are displayed in the correct location and dismissed
|
||||
// when the window moves.
|
||||
// - Drag&drop areas are updated accordingly.
|
||||
browser->GetHost()->NotifyMoveOrResizeStarted();
|
||||
}
|
||||
|
||||
return FALSE; // Don't stop this message.
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::WindowDestroy(GtkWidget* widget, RootWindowGtk* self) {
|
||||
// Called when the root window is destroyed.
|
||||
self->window_destroyed_ = true;
|
||||
self->NotifyDestroyedIfDone();
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::WindowDelete(GtkWidget* widget,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self) {
|
||||
// Called to query whether the root window should be closed.
|
||||
if (self->force_close_)
|
||||
return FALSE; // Allow the close.
|
||||
|
||||
if (self->browser_window_.get() && !self->browser_window_->IsClosing()) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser) {
|
||||
// Notify the browser window that we would like to close it. This
|
||||
// will result in a call to ClientHandler::DoClose() if the
|
||||
// JavaScript 'onbeforeunload' event handler allows it.
|
||||
browser->GetHost()->CloseBrowser(false);
|
||||
|
||||
// Cancel the close.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the close.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::VboxSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self) {
|
||||
// Offset browser positioning by any controls that will appear in the client
|
||||
// area.
|
||||
const int ux_height = self->toolbar_height_ + self->menubar_height_;
|
||||
const int x = allocation->x;
|
||||
const int y = allocation->y + ux_height;
|
||||
const int width = allocation->width;
|
||||
const int height = allocation->height - ux_height;
|
||||
|
||||
// Size the browser window to match the GTK widget.
|
||||
self->browser_bounds_ = CefRect(x, y, width, height);
|
||||
if (self->browser_window_.get())
|
||||
self->browser_window_->SetBounds(x, y, width, height);
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::MenubarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self) {
|
||||
self->menubar_height_ = allocation->height;
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::MenuItemActivated(GtkWidget* widget,
|
||||
RootWindowGtk* self) {
|
||||
// Retrieve the menu ID set in AddMenuEntry.
|
||||
int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), kMenuIdKey));
|
||||
// Run the test.
|
||||
if (self->delegate_)
|
||||
self->delegate_->OnTest(self, id);
|
||||
|
||||
return FALSE; // Don't stop this message.
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::ToolbarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self) {
|
||||
self->toolbar_height_ = allocation->height;
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::BackButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get())
|
||||
browser->GoBack();
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::ForwardButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get())
|
||||
browser->GoForward();
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::StopButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get())
|
||||
browser->StopLoad();
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::ReloadButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get())
|
||||
browser->Reload();
|
||||
}
|
||||
|
||||
// static
|
||||
void RootWindowGtk::URLEntryActivate(GtkEntry* entry,
|
||||
RootWindowGtk* self) {
|
||||
CefRefPtr<CefBrowser> browser = self->GetBrowser();
|
||||
if (browser.get()) {
|
||||
const gchar* url = gtk_entry_get_text(entry);
|
||||
browser->GetMainFrame()->LoadURL(std::string(url).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
gboolean RootWindowGtk::URLEntryButtonPress(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
RootWindowGtk* self) {
|
||||
// Give focus to the GTK window. This is a work-around for bad focus-related
|
||||
// interaction between the root window managed by GTK and the browser managed
|
||||
// by X11.
|
||||
GtkWidget* window = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
|
||||
GdkWindow* gdk_window = gtk_widget_get_window(window);
|
||||
::Display* xdisplay = GDK_WINDOW_XDISPLAY(gdk_window);
|
||||
::Window xwindow = GDK_WINDOW_XID(gdk_window);
|
||||
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GtkWidget* RootWindowGtk::CreateMenuBar() {
|
||||
GtkWidget* menu_bar = gtk_menu_bar_new();
|
||||
|
||||
// Create the test menu.
|
||||
GtkWidget* test_menu = CreateMenu(menu_bar, "Tests");
|
||||
AddMenuEntry(test_menu, "Get Source", ID_TESTS_GETSOURCE);
|
||||
AddMenuEntry(test_menu, "Get Text", ID_TESTS_GETTEXT);
|
||||
AddMenuEntry(test_menu, "Popup Window", ID_TESTS_POPUP);
|
||||
AddMenuEntry(test_menu, "Request", ID_TESTS_REQUEST);
|
||||
AddMenuEntry(test_menu, "Plugin Info", ID_TESTS_PLUGIN_INFO);
|
||||
AddMenuEntry(test_menu, "Zoom In", ID_TESTS_ZOOM_IN);
|
||||
AddMenuEntry(test_menu, "Zoom Out", ID_TESTS_ZOOM_OUT);
|
||||
AddMenuEntry(test_menu, "Zoom Reset", ID_TESTS_ZOOM_RESET);
|
||||
AddMenuEntry(test_menu, "Begin Tracing", ID_TESTS_TRACING_BEGIN);
|
||||
AddMenuEntry(test_menu, "End Tracing", ID_TESTS_TRACING_END);
|
||||
AddMenuEntry(test_menu, "Print", ID_TESTS_PRINT);
|
||||
AddMenuEntry(test_menu, "Other Tests", ID_TESTS_OTHER_TESTS);
|
||||
|
||||
return menu_bar;
|
||||
}
|
||||
|
||||
GtkWidget* RootWindowGtk::CreateMenu(GtkWidget* menu_bar, const char* text) {
|
||||
GtkWidget* menu_widget = gtk_menu_new();
|
||||
GtkWidget* menu_header = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_header), menu_widget);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_header);
|
||||
return menu_widget;
|
||||
}
|
||||
|
||||
GtkWidget* RootWindowGtk::AddMenuEntry(GtkWidget* menu_widget,
|
||||
const char* text,
|
||||
int id) {
|
||||
GtkWidget* entry = gtk_menu_item_new_with_label(text);
|
||||
g_signal_connect(entry, "activate",
|
||||
G_CALLBACK(&RootWindowGtk::MenuItemActivated), this);
|
||||
|
||||
// Set the menu ID that will be retrieved in MenuItemActivated.
|
||||
g_object_set_data(G_OBJECT(entry), kMenuIdKey, GINT_TO_POINTER(id));
|
||||
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu_widget), entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_refptr<RootWindow> RootWindow::Create() {
|
||||
return new RootWindowGtk();
|
||||
}
|
||||
|
||||
} // namespace client
|
151
tests/cefclient/root_window_gtk.h
Normal file
151
tests/cefclient/root_window_gtk.h
Normal file
@ -0,0 +1,151 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_ROOT_WINDOW_GTK_H_
|
||||
#define CEF_TESTS_CEFCLIENT_ROOT_WINDOW_GTK_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "cefclient/browser_window.h"
|
||||
#include "cefclient/root_window.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// GTK implementation of a top-level native window in the browser process.
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class RootWindowGtk : public RootWindow,
|
||||
public BrowserWindow::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
RootWindowGtk();
|
||||
~RootWindowGtk();
|
||||
|
||||
// RootWindow methods.
|
||||
void Init(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefRect& rect,
|
||||
const CefBrowserSettings& settings,
|
||||
const std::string& url) OVERRIDE;
|
||||
void InitAsPopup(RootWindow::Delegate* delegate,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) OVERRIDE;
|
||||
void Show(ShowMode mode) OVERRIDE;
|
||||
void Hide() OVERRIDE;
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Close(bool force) OVERRIDE;
|
||||
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
void CreateBrowserWindow(const std::string& startup_url);
|
||||
void CreateRootWindow(const CefBrowserSettings& settings);
|
||||
|
||||
// BrowserWindow::Delegate methods.
|
||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBrowserWindowDestroyed() OVERRIDE;
|
||||
void OnSetAddress(const std::string& url) OVERRIDE;
|
||||
void OnSetTitle(const std::string& title) OVERRIDE;
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
|
||||
void NotifyDestroyedIfDone();
|
||||
|
||||
GtkWidget* CreateMenuBar();
|
||||
GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text);
|
||||
GtkWidget* AddMenuEntry(GtkWidget* menu_widget, const char* text, int id);
|
||||
|
||||
// Signal handlers for the top-level GTK window.
|
||||
static gboolean WindowFocusIn(GtkWidget* widget,
|
||||
GdkEventFocus* event,
|
||||
RootWindowGtk* self);
|
||||
static gboolean WindowState(GtkWidget* widget,
|
||||
GdkEventWindowState* event,
|
||||
RootWindowGtk* self);
|
||||
static gboolean WindowConfigure(GtkWindow* window,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self);
|
||||
static void WindowDestroy(GtkWidget* widget, RootWindowGtk* self);
|
||||
static gboolean WindowDelete(GtkWidget* widget,
|
||||
GdkEvent* event,
|
||||
RootWindowGtk* self);
|
||||
|
||||
// Signal handlers for the GTK Vbox containing all UX elements.
|
||||
static void VboxSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self);
|
||||
|
||||
// Signal handlers for the GTK menu bar.
|
||||
static void MenubarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self);
|
||||
static gboolean MenuItemActivated(GtkWidget* widget,
|
||||
RootWindowGtk* self);
|
||||
|
||||
// Signal handlers for the GTK toolbar.
|
||||
static void ToolbarSizeAllocated(GtkWidget* widget,
|
||||
GtkAllocation* allocation,
|
||||
RootWindowGtk* self);
|
||||
static void BackButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self);
|
||||
static void ForwardButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self);
|
||||
static void StopButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self);
|
||||
static void ReloadButtonClicked(GtkButton* button,
|
||||
RootWindowGtk* self);
|
||||
|
||||
// Signal handlers for the GTK URL entry field.
|
||||
static void URLEntryActivate(GtkEntry* entry,
|
||||
RootWindowGtk* self);
|
||||
static gboolean URLEntryButtonPress(GtkWidget* widget,
|
||||
GdkEventButton* event,
|
||||
RootWindowGtk* self);
|
||||
|
||||
// After initialization all members are only accessed on the main thread.
|
||||
// Members set during initialization.
|
||||
RootWindow::Delegate* delegate_;
|
||||
bool with_controls_;
|
||||
bool with_osr_;
|
||||
bool is_popup_;
|
||||
CefRect start_rect_;
|
||||
scoped_ptr<BrowserWindow> browser_window_;
|
||||
bool initialized_;
|
||||
|
||||
// Main window.
|
||||
GtkWidget* window_;
|
||||
|
||||
// Buttons.
|
||||
GtkToolItem* back_button_;
|
||||
GtkToolItem* forward_button_;
|
||||
GtkToolItem* reload_button_;
|
||||
GtkToolItem* stop_button_;
|
||||
|
||||
// URL text field.
|
||||
GtkWidget* url_entry_;
|
||||
|
||||
// Height of UX controls that affect browser window placement.
|
||||
int toolbar_height_;
|
||||
int menubar_height_;
|
||||
|
||||
CefRect browser_bounds_;
|
||||
|
||||
bool force_close_;
|
||||
bool window_destroyed_;
|
||||
bool browser_destroyed_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RootWindowGtk);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_ROOT_WINDOW_GTK_H_
|
@ -13,6 +13,8 @@
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "cefclient/temp_window_win.h"
|
||||
#elif defined(OS_LINUX)
|
||||
#include "cefclient/temp_window_x11.h"
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
@ -76,9 +78,11 @@ class RootWindowManager : public RootWindow::Delegate {
|
||||
typedef std::set<scoped_refptr<RootWindow> > RootWindowSet;
|
||||
RootWindowSet root_windows_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Singleton window used as the temporary parent for popup browsers.
|
||||
#if defined(OS_WIN)
|
||||
TempWindowWin temp_window_win_;
|
||||
#elif defined(OS_LINUX)
|
||||
TempWindowX11 temp_window_x11_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RootWindowManager);
|
||||
|
@ -134,7 +134,7 @@ void RootWindowWin::InitAsPopup(RootWindow::Delegate* delegate,
|
||||
// The new popup is initially parented to a temporary window. The native root
|
||||
// window will be created after the browser is created and the popup window
|
||||
// will be re-parented to it at that time.
|
||||
browser_window_->GetPopupConfig(TempWindowWin::GetHWND(),
|
||||
browser_window_->GetPopupConfig(TempWindowWin::GetWindowHandle(),
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
@ -147,10 +147,10 @@ void RootWindowWin::Show(ShowMode mode) {
|
||||
int nCmdShow = SW_SHOWNORMAL;
|
||||
switch (mode) {
|
||||
case ShowMinimized:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
nCmdShow = SW_SHOWMINIMIZED;
|
||||
break;
|
||||
case ShowMaximized:
|
||||
nCmdShow = SW_SHOWNORMAL;
|
||||
nCmdShow = SW_SHOWMAXIMIZED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -193,7 +193,7 @@ CefRefPtr<CefBrowser> RootWindowWin::GetBrowser() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefWindowHandle RootWindowWin::GetWindowHandle() const {
|
||||
ClientWindowHandle RootWindowWin::GetWindowHandle() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return hwnd_;
|
||||
}
|
||||
@ -322,7 +322,10 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
|
||||
if (!is_popup_) {
|
||||
// Create the browser window.
|
||||
browser_window_->CreateBrowser(hwnd_, rect, settings);
|
||||
CefRect cef_rect(rect.left, rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top);
|
||||
browser_window_->CreateBrowser(hwnd_, cef_rect, settings);
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
@ -533,7 +536,7 @@ void RootWindowWin::OnSize(bool minimized) {
|
||||
int urloffset = rect.left + BUTTON_WIDTH * 4;
|
||||
|
||||
if (browser_window_) {
|
||||
HWND browser_hwnd = browser_window_->GetHWND();
|
||||
HWND browser_hwnd = browser_window_->GetWindowHandle();
|
||||
HDWP hdwp = BeginDeferWindowPos(1);
|
||||
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
@ -696,7 +699,6 @@ void RootWindowWin::OnBrowserWindowDestroyed() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
browser_window_.reset();
|
||||
browser_destroyed_ = true;
|
||||
|
||||
if (!window_destroyed_) {
|
||||
// The browser was destroyed first. This could be due to the use of
|
||||
@ -705,6 +707,7 @@ void RootWindowWin::OnBrowserWindowDestroyed() {
|
||||
Close(false);
|
||||
}
|
||||
|
||||
browser_destroyed_ = true;
|
||||
NotifyDestroyedIfDone();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "include/base/cef_scoped_ptr.h"
|
||||
#include "cefclient/browser_window_win.h"
|
||||
#include "cefclient/browser_window.h"
|
||||
#include "cefclient/root_window.h"
|
||||
|
||||
namespace client {
|
||||
@ -20,7 +20,7 @@ namespace client {
|
||||
// The methods of this class must be called on the main thread unless otherwise
|
||||
// indicated.
|
||||
class RootWindowWin : public RootWindow,
|
||||
public BrowserWindowWin::Delegate {
|
||||
public BrowserWindow::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
RootWindowWin();
|
||||
@ -45,7 +45,7 @@ class RootWindowWin : public RootWindow,
|
||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||
void Close(bool force) OVERRIDE;
|
||||
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
|
||||
CefWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||
|
||||
private:
|
||||
void CreateBrowserWindow(bool with_osr, const std::string& startup_url);
|
||||
@ -79,7 +79,7 @@ class RootWindowWin : public RootWindow,
|
||||
bool OnClose();
|
||||
void OnDestroyed();
|
||||
|
||||
// BrowserWindowWin::Delegate methods.
|
||||
// BrowserWindow::Delegate methods.
|
||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
void OnBrowserWindowDestroyed() OVERRIDE;
|
||||
void OnSetAddress(const std::string& url) OVERRIDE;
|
||||
@ -96,7 +96,7 @@ class RootWindowWin : public RootWindow,
|
||||
bool with_controls_;
|
||||
bool is_popup_;
|
||||
RECT start_rect_;
|
||||
scoped_ptr<BrowserWindowWin> browser_window_;
|
||||
scoped_ptr<BrowserWindow> browser_window_;
|
||||
bool initialized_;
|
||||
|
||||
// Main window.
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "cefclient/temp_window_win.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
|
||||
namespace client {
|
||||
@ -50,7 +52,7 @@ TempWindowWin::~TempWindowWin() {
|
||||
}
|
||||
|
||||
// static
|
||||
HWND TempWindowWin::GetHWND() {
|
||||
CefWindowHandle TempWindowWin::GetWindowHandle() {
|
||||
DCHECK(g_temp_window);
|
||||
return g_temp_window->hwnd_;
|
||||
}
|
||||
|
@ -5,8 +5,6 @@
|
||||
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
@ -15,8 +13,8 @@ namespace client {
|
||||
// popup browsers.
|
||||
class TempWindowWin {
|
||||
public:
|
||||
// Returns the singleton window HWND.
|
||||
static HWND GetHWND();
|
||||
// Returns the singleton window handle.
|
||||
static CefWindowHandle GetWindowHandle();
|
||||
|
||||
private:
|
||||
// A single instance will be created/owned by RootWindowManager.
|
||||
@ -25,7 +23,7 @@ class TempWindowWin {
|
||||
TempWindowWin();
|
||||
~TempWindowWin();
|
||||
|
||||
HWND hwnd_;
|
||||
CefWindowHandle hwnd_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TempWindowWin);
|
||||
};
|
||||
|
69
tests/cefclient/temp_window_x11.cc
Normal file
69
tests/cefclient/temp_window_x11.cc
Normal file
@ -0,0 +1,69 @@
|
||||
// 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 "cefclient/temp_window_x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_app.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// Create the temp window.
|
||||
::Window CreateTempWindow() {
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
::Window parent_xwindow = DefaultRootWindow(xdisplay);
|
||||
|
||||
XSetWindowAttributes swa;
|
||||
memset(&swa, 0, sizeof(swa));
|
||||
swa.background_pixmap = None;
|
||||
swa.override_redirect = false;
|
||||
return XCreateWindow(
|
||||
xdisplay, parent_xwindow,
|
||||
0, 0, 1, 1, // size (1x1px)
|
||||
0, // border width
|
||||
CopyFromParent, // depth
|
||||
InputOutput,
|
||||
CopyFromParent, // visual
|
||||
CWBackPixmap | CWOverrideRedirect,
|
||||
&swa);
|
||||
}
|
||||
|
||||
// Close the temp window.
|
||||
void CloseTempWindow(::Window xwindow) {
|
||||
::Display* xdisplay = cef_get_xdisplay();
|
||||
XDestroyWindow(xdisplay, xwindow);
|
||||
}
|
||||
|
||||
TempWindowX11* g_temp_window = NULL;
|
||||
|
||||
} // namespace
|
||||
|
||||
TempWindowX11::TempWindowX11()
|
||||
: xwindow_(kNullWindowHandle) {
|
||||
DCHECK(!g_temp_window);
|
||||
g_temp_window = this;
|
||||
|
||||
xwindow_ = CreateTempWindow();
|
||||
CHECK(xwindow_);
|
||||
}
|
||||
|
||||
TempWindowX11::~TempWindowX11() {
|
||||
g_temp_window = NULL;
|
||||
DCHECK(xwindow_);
|
||||
|
||||
CloseTempWindow(xwindow_);
|
||||
}
|
||||
|
||||
// static
|
||||
CefWindowHandle TempWindowX11::GetWindowHandle() {
|
||||
DCHECK(g_temp_window);
|
||||
return g_temp_window->xwindow_;
|
||||
}
|
||||
|
||||
} // namespace client
|
33
tests/cefclient/temp_window_x11.h
Normal file
33
tests/cefclient/temp_window_x11.h
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_X11_H_
|
||||
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_X11_H_
|
||||
|
||||
#include "cefclient/main_message_loop.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Represents a singleton hidden window that acts at temporary parent for
|
||||
// popup browsers.
|
||||
class TempWindowX11 {
|
||||
public:
|
||||
// Returns the singleton window handle.
|
||||
static CefWindowHandle GetWindowHandle();
|
||||
|
||||
private:
|
||||
// A single instance will be created/owned by RootWindowManager.
|
||||
friend class RootWindowManager;
|
||||
|
||||
TempWindowX11();
|
||||
~TempWindowX11();
|
||||
|
||||
CefWindowHandle xwindow_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TempWindowX11);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_TEMP_WINDOW_X11_H_
|
Loading…
x
Reference in New Issue
Block a user