mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-21 14:40:49 +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_renderer.h',
|
||||||
'tests/cefclient/client_switches.cc',
|
'tests/cefclient/client_switches.cc',
|
||||||
'tests/cefclient/client_switches.h',
|
'tests/cefclient/client_switches.h',
|
||||||
|
'tests/cefclient/client_types.h',
|
||||||
'tests/cefclient/dialog_test.cc',
|
'tests/cefclient/dialog_test.cc',
|
||||||
'tests/cefclient/dialog_test.h',
|
'tests/cefclient/dialog_test.h',
|
||||||
'tests/cefclient/main_context.cc',
|
'tests/cefclient/main_context.cc',
|
||||||
@ -187,12 +188,12 @@
|
|||||||
'<@(cefclient_bundle_resources_common)',
|
'<@(cefclient_bundle_resources_common)',
|
||||||
],
|
],
|
||||||
'cefclient_sources_win': [
|
'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.cc',
|
||||||
'tests/cefclient/browser_window_osr_win.h',
|
'tests/cefclient/browser_window_osr_win.h',
|
||||||
'tests/cefclient/browser_window_std_win.cc',
|
'tests/cefclient/browser_window_std_win.cc',
|
||||||
'tests/cefclient/browser_window_std_win.h',
|
'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.exe.manifest',
|
||||||
'tests/cefclient/cefclient.rc',
|
'tests/cefclient/cefclient.rc',
|
||||||
'tests/cefclient/cefclient_win.cc',
|
'tests/cefclient/cefclient_win.cc',
|
||||||
@ -279,18 +280,32 @@
|
|||||||
],
|
],
|
||||||
'cefclient_sources_linux': [
|
'cefclient_sources_linux': [
|
||||||
'tests/cefclient/cefclient_gtk.cc',
|
'tests/cefclient/cefclient_gtk.cc',
|
||||||
'tests/cefclient/client_handler_shared.cc',
|
'tests/cefclient/browser_window.cc',
|
||||||
'tests/cefclient/client_handler_shared.h',
|
'tests/cefclient/browser_window.h',
|
||||||
'tests/cefclient/client_handler_shared_gtk.cc',
|
'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.cc',
|
||||||
'tests/cefclient/dialog_handler_gtk.h',
|
'tests/cefclient/dialog_handler_gtk.h',
|
||||||
'tests/cefclient/main_context_impl_posix.cc',
|
'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.cc',
|
||||||
'tests/cefclient/print_handler_gtk.h',
|
'tests/cefclient/print_handler_gtk.h',
|
||||||
'tests/cefclient/resource_util_linux.cc',
|
'tests/cefclient/resource_util_linux.cc',
|
||||||
'tests/cefclient/resource_util_posix.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',
|
'tests/cefclient/window_test_gtk.cc',
|
||||||
],
|
],
|
||||||
'cefclient_bundle_resources_linux': [
|
'cefclient_bundle_resources_linux': [
|
||||||
|
@ -2,30 +2,30 @@
|
|||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// 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 "include/base/cef_bind.h"
|
||||||
#include "cefclient/main_message_loop.h"
|
#include "cefclient/main_message_loop.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
BrowserWindowWin::BrowserWindowWin(Delegate* delegate)
|
BrowserWindow::BrowserWindow(Delegate* delegate)
|
||||||
: delegate_(delegate),
|
: delegate_(delegate),
|
||||||
is_closing_(false) {
|
is_closing_(false) {
|
||||||
DCHECK(delegate_);
|
DCHECK(delegate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowser> BrowserWindowWin::GetBrowser() const {
|
CefRefPtr<CefBrowser> BrowserWindow::GetBrowser() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
return browser_;
|
return browser_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowserWindowWin::IsClosing() const {
|
bool BrowserWindow::IsClosing() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
return is_closing_;
|
return is_closing_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
void BrowserWindow::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
DCHECK(!browser_);
|
DCHECK(!browser_);
|
||||||
browser_ = browser;
|
browser_ = browser;
|
||||||
@ -33,13 +33,13 @@ void BrowserWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
|||||||
delegate_->OnBrowserCreated(browser);
|
delegate_->OnBrowserCreated(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
void BrowserWindow::OnBrowserClosing(CefRefPtr<CefBrowser> browser) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||||
is_closing_ = true;
|
is_closing_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
void BrowserWindow::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
DCHECK_EQ(browser->GetIdentifier(), browser_->GetIdentifier());
|
||||||
browser_ = NULL;
|
browser_ = NULL;
|
||||||
@ -51,19 +51,19 @@ void BrowserWindowWin::OnBrowserClosed(CefRefPtr<CefBrowser> browser) {
|
|||||||
delegate_->OnBrowserWindowDestroyed();
|
delegate_->OnBrowserWindowDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnSetAddress(const std::string& url) {
|
void BrowserWindow::OnSetAddress(const std::string& url) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
delegate_->OnSetAddress(url);
|
delegate_->OnSetAddress(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnSetTitle(const std::string& title) {
|
void BrowserWindow::OnSetTitle(const std::string& title) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
delegate_->OnSetTitle(title);
|
delegate_->OnSetTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowWin::OnSetLoadingState(bool isLoading,
|
void BrowserWindow::OnSetLoadingState(bool isLoading,
|
||||||
bool canGoBack,
|
bool canGoBack,
|
||||||
bool canGoForward) {
|
bool canGoForward) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||||
}
|
}
|
@ -2,21 +2,20 @@
|
|||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_H_
|
||||||
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_WIN_H_
|
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_H_
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "include/base/cef_scoped_ptr.h"
|
#include "include/base/cef_scoped_ptr.h"
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "cefclient/client_handler_single.h"
|
#include "cefclient/client_handler_single.h"
|
||||||
|
#include "cefclient/client_types.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
// Represents a native child window hosting a single browser instance. The
|
// Represents a native child window hosting a single browser instance. The
|
||||||
// methods of this class must be called on the main thread unless otherwise
|
// methods of this class must be called on the main thread unless otherwise
|
||||||
// indicated.
|
// indicated.
|
||||||
class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
class BrowserWindow : public ClientHandlerSingle::Delegate {
|
||||||
public:
|
public:
|
||||||
// This interface is implemented by the owner of the BrowserWindowWin. The
|
// This interface is implemented by the owner of the BrowserWindowWin. The
|
||||||
// methods of this class will be called on the main thread.
|
// 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.
|
// Create a new browser and native window.
|
||||||
virtual void CreateBrowser(HWND parent_hwnd,
|
virtual void CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
const RECT& rect,
|
const CefRect& rect,
|
||||||
const CefBrowserSettings& settings) = 0;
|
const CefBrowserSettings& settings) = 0;
|
||||||
|
|
||||||
// Retrieve the configuration that will be used when creating a popup window.
|
// 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.
|
// The popup browser will initially be parented to |temp_handle| which should
|
||||||
// This method may be called on any thread.
|
// be a pre-existing hidden window. The native window will be created later
|
||||||
virtual void GetPopupConfig(HWND temp_hwnd,
|
// after the browser has been created. This method may be called on any
|
||||||
|
// thread.
|
||||||
|
virtual void GetPopupConfig(CefWindowHandle temp_handle,
|
||||||
CefWindowInfo& windowInfo,
|
CefWindowInfo& windowInfo,
|
||||||
CefRefPtr<CefClient>& client,
|
CefRefPtr<CefClient>& client,
|
||||||
CefBrowserSettings& settings) = 0;
|
CefBrowserSettings& settings) = 0;
|
||||||
|
|
||||||
// Show the popup window with correct parent and bounds in parent coordinates.
|
// 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;
|
int x, int y, size_t width, size_t height) = 0;
|
||||||
|
|
||||||
// Show the window.
|
// Show the window.
|
||||||
@ -73,7 +74,7 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
|||||||
virtual void SetFocus() = 0;
|
virtual void SetFocus() = 0;
|
||||||
|
|
||||||
// Returns the window handle.
|
// Returns the window handle.
|
||||||
virtual HWND GetHWND() const = 0;
|
virtual ClientWindowHandle GetWindowHandle() const = 0;
|
||||||
|
|
||||||
// Returns the browser owned by the window.
|
// Returns the browser owned by the window.
|
||||||
CefRefPtr<CefBrowser> GetBrowser() const;
|
CefRefPtr<CefBrowser> GetBrowser() const;
|
||||||
@ -83,11 +84,11 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Allow deletion via scoped_ptr only.
|
// Allow deletion via scoped_ptr only.
|
||||||
friend struct base::DefaultDeleter<BrowserWindowWin>;
|
friend struct base::DefaultDeleter<BrowserWindow>;
|
||||||
|
|
||||||
// Constructor may be called on any thread.
|
// Constructor may be called on any thread.
|
||||||
// |root_window| and |delegate| must outlive this object.
|
// |root_window| and |delegate| must outlive this object.
|
||||||
explicit BrowserWindowWin(Delegate* delegate);
|
explicit BrowserWindow(Delegate* delegate);
|
||||||
|
|
||||||
// ClientHandlerSingle::Delegate methods.
|
// ClientHandlerSingle::Delegate methods.
|
||||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
@ -104,9 +105,9 @@ class BrowserWindowWin : public ClientHandlerSingle::Delegate {
|
|||||||
CefRefPtr<ClientHandlerSingle> client_handler_;
|
CefRefPtr<ClientHandlerSingle> client_handler_;
|
||||||
bool is_closing_;
|
bool is_closing_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowWin);
|
DISALLOW_COPY_AND_ASSIGN(BrowserWindow);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // 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
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// 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/gdk.h>
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
@ -17,23 +17,15 @@
|
|||||||
#include <X11/XF86keysym.h>
|
#include <X11/XF86keysym.h>
|
||||||
#include <X11/Xcursor/Xcursor.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 "include/wrapper/cef_closure_task.h"
|
||||||
|
#include "cefclient/main_message_loop.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
gint glarea_size_allocation(GtkWidget* widget,
|
int GetCefStateModifiers(guint state) {
|
||||||
GtkAllocation* allocation,
|
|
||||||
OSRWindow* window) {
|
|
||||||
CefRefPtr<CefBrowserHost> host = window->GetBrowserHost();
|
|
||||||
if (host)
|
|
||||||
host->WasResized();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_cef_state_modifiers(guint state) {
|
|
||||||
int modifiers = 0;
|
int modifiers = 0;
|
||||||
if (state & GDK_SHIFT_MASK)
|
if (state & GDK_SHIFT_MASK)
|
||||||
modifiers |= EVENTFLAG_SHIFT_DOWN;
|
modifiers |= EVENTFLAG_SHIFT_DOWN;
|
||||||
@ -865,183 +857,7 @@ int GetControlCharacter(KeyboardCode windows_key_code, bool shift) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gint glarea_click_event(GtkWidget* widget,
|
void GetWidgetRectInScreen(GtkWidget* widget, GdkRectangle* r) {
|
||||||
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) {
|
|
||||||
gint x, y, w, h;
|
gint x, y, w, h;
|
||||||
GdkRectangle extents;
|
GdkRectangle extents;
|
||||||
|
|
||||||
@ -1095,26 +911,128 @@ class ScopedGLContext {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate,
|
||||||
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
const std::string& startup_url,
|
||||||
bool transparent,
|
bool transparent,
|
||||||
bool show_update_rect,
|
bool show_update_rect)
|
||||||
ClientWindowHandle parentView) {
|
: BrowserWindow(delegate),
|
||||||
DCHECK(browser_provider);
|
renderer_(transparent, show_update_rect),
|
||||||
if (!browser_provider)
|
glarea_(NULL),
|
||||||
return NULL;
|
hidden_(false),
|
||||||
|
gl_enabled_(false),
|
||||||
return new OSRWindow(browser_provider, transparent, show_update_rect,
|
painting_popup_(false) {
|
||||||
parentView);
|
client_handler_ = new ClientHandlerOsr(this, this, startup_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
void BrowserWindowOsrGtk::CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
CefRefPtr<OSRWindow> OSRWindow::From(
|
const CefRect& rect,
|
||||||
CefRefPtr<ClientHandlerShared::RenderHandler> renderHandler) {
|
const CefBrowserSettings& settings) {
|
||||||
return static_cast<OSRWindow*>(renderHandler.get());
|
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|.
|
// Disconnect all signal handlers that reference |this|.
|
||||||
g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0,
|
g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0,
|
||||||
NULL, NULL, this);
|
NULL, NULL, this);
|
||||||
@ -1122,8 +1040,17 @@ void OSRWindow::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|||||||
DisableGL();
|
DisableGL();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
|
bool BrowserWindowOsrGtk::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||||
CefRect& rect) {
|
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_)
|
if (!glarea_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1135,20 +1062,32 @@ bool OSRWindow::GetViewRect(CefRefPtr<CefBrowser> browser,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSRWindow::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
bool BrowserWindowOsrGtk::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||||
int viewX,
|
int viewX,
|
||||||
int viewY,
|
int viewY,
|
||||||
int& screenX,
|
int& screenX,
|
||||||
int& screenY) {
|
int& screenY) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
GdkRectangle screen_rect;
|
GdkRectangle screen_rect;
|
||||||
widget_get_rect_in_screen(glarea_, &screen_rect);
|
GetWidgetRectInScreen(glarea_, &screen_rect);
|
||||||
screenX = screen_rect.x + viewX;
|
screenX = screen_rect.x + viewX;
|
||||||
screenY = screen_rect.y + viewY;
|
screenY = screen_rect.y + viewY;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
bool BrowserWindowOsrGtk::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||||
bool show) {
|
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) {
|
if (!show) {
|
||||||
renderer_.ClearPopupRects();
|
renderer_.ClearPopupRects();
|
||||||
browser->GetHost()->Invalidate(PET_VIEW);
|
browser->GetHost()->Invalidate(PET_VIEW);
|
||||||
@ -1156,16 +1095,29 @@ void OSRWindow::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
|||||||
renderer_.OnPopupShow(browser, show);
|
renderer_.OnPopupShow(browser, show);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
void BrowserWindowOsrGtk::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||||
const CefRect& rect) {
|
const CefRect& rect) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
renderer_.OnPopupSize(browser, rect);
|
renderer_.OnPopupSize(browser, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
void BrowserWindowOsrGtk::OnPaint(
|
||||||
PaintElementType type,
|
CefRefPtr<CefBrowser> browser,
|
||||||
const RectList& dirtyRects,
|
CefRenderHandler::PaintElementType type,
|
||||||
const void* buffer,
|
const CefRenderHandler::RectList& dirtyRects,
|
||||||
int width, int height) {
|
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_) {
|
if (painting_popup_) {
|
||||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||||
return;
|
return;
|
||||||
@ -1187,71 +1139,45 @@ void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||||||
renderer_.Render();
|
renderer_.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
void BrowserWindowOsrGtk::OnCursorChange(
|
||||||
CefCursorHandle cursor,
|
CefRefPtr<CefBrowser> browser,
|
||||||
CursorType type,
|
CefCursorHandle cursor,
|
||||||
const CefCursorInfo& custom_cursor_info) {
|
CefRenderHandler::CursorType type,
|
||||||
|
const CefCursorInfo& custom_cursor_info) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
// Retrieve the X11 display shared with Chromium.
|
// Retrieve the X11 display shared with Chromium.
|
||||||
::Display* xdisplay = cef_get_xdisplay();
|
::Display* xdisplay = cef_get_xdisplay();
|
||||||
DCHECK(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_));
|
::Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(glarea_));
|
||||||
|
|
||||||
// Set the cursor.
|
// Set the cursor.
|
||||||
XDefineCursor(xdisplay, xwindow, cursor);
|
XDefineCursor(xdisplay, xwindow, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::Invalidate() {
|
bool BrowserWindowOsrGtk::StartDragging(
|
||||||
if (!CefCurrentlyOn(TID_UI)) {
|
CefRefPtr<CefBrowser> browser,
|
||||||
CefPostTask(TID_UI, base::Bind(&OSRWindow::Invalidate, this));
|
CefRefPtr<CefDragData> drag_data,
|
||||||
return;
|
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||||
}
|
int x, int y) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
// Don't post another task if the previous task is still pending.
|
// TODO(port): Implement drag&drop support.
|
||||||
if (render_task_pending_)
|
return false;
|
||||||
return;
|
|
||||||
|
|
||||||
render_task_pending_ = true;
|
|
||||||
|
|
||||||
// Render at 30fps.
|
|
||||||
static const int kRenderDelay = 1000 / 30;
|
|
||||||
CefPostDelayedTask(TID_UI, base::Bind(&OSRWindow::Render, this),
|
|
||||||
kRenderDelay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OSRWindow::IsOverPopupWidget(int x, int y) const {
|
void BrowserWindowOsrGtk::UpdateDragCursor(
|
||||||
const CefRect& rc = renderer_.popup_rect();
|
CefRefPtr<CefBrowser> browser,
|
||||||
int popup_right = rc.x + rc.width;
|
CefRenderHandler::DragOperation operation) {
|
||||||
int popup_bottom = rc.y + rc.height;
|
CEF_REQUIRE_UI_THREAD();
|
||||||
return (x >= rc.x) && (x < popup_right) &&
|
|
||||||
(y >= rc.y) && (y < popup_bottom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int OSRWindow::GetPopupXOffset() const {
|
void BrowserWindowOsrGtk::Create(ClientWindowHandle parent_handle) {
|
||||||
return renderer_.original_popup_rect().x - renderer_.popup_rect().x;
|
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();
|
glarea_ = gtk_drawing_area_new();
|
||||||
DCHECK(glarea_);
|
DCHECK(glarea_);
|
||||||
|
|
||||||
@ -1261,13 +1187,12 @@ OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
|||||||
GDK_GL_MODE_DOUBLE));
|
GDK_GL_MODE_DOUBLE));
|
||||||
DCHECK(glconfig);
|
DCHECK(glconfig);
|
||||||
|
|
||||||
gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE,
|
gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
|
||||||
GDK_GL_RGBA_TYPE);
|
|
||||||
|
|
||||||
gtk_widget_set_can_focus(glarea_, TRUE);
|
gtk_widget_set_can_focus(glarea_, TRUE);
|
||||||
|
|
||||||
g_signal_connect(G_OBJECT(glarea_), "size_allocate",
|
g_signal_connect(G_OBJECT(glarea_), "size_allocate",
|
||||||
G_CALLBACK(glarea_size_allocation), this);
|
G_CALLBACK(&BrowserWindowOsrGtk::SizeAllocation), this);
|
||||||
|
|
||||||
gtk_widget_set_events(glarea_,
|
gtk_widget_set_events(glarea_,
|
||||||
GDK_BUTTON_PRESS_MASK |
|
GDK_BUTTON_PRESS_MASK |
|
||||||
@ -1281,49 +1206,265 @@ OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
|||||||
GDK_SCROLL_MASK |
|
GDK_SCROLL_MASK |
|
||||||
GDK_FOCUS_CHANGE_MASK);
|
GDK_FOCUS_CHANGE_MASK);
|
||||||
g_signal_connect(G_OBJECT(glarea_), "button_press_event",
|
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_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_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_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_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_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_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_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_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_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() {
|
// static
|
||||||
CEF_REQUIRE_UI_THREAD();
|
gint BrowserWindowOsrGtk::ClickEvent(GtkWidget* widget,
|
||||||
if (render_task_pending_)
|
GdkEventButton* event,
|
||||||
render_task_pending_ = false;
|
BrowserWindowOsrGtk* self) {
|
||||||
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
if (!gl_enabled_)
|
if (!self->browser_.get())
|
||||||
EnableGL();
|
return TRUE;
|
||||||
|
|
||||||
ScopedGLContext scoped_gl_context(glarea_, true);
|
CefRefPtr<CefBrowserHost> host = self->browser_->GetHost();
|
||||||
if (!scoped_gl_context.IsValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
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() {
|
// static
|
||||||
CEF_REQUIRE_UI_THREAD();
|
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_)
|
if (gl_enabled_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1336,8 +1477,8 @@ void OSRWindow::EnableGL() {
|
|||||||
gl_enabled_ = true;
|
gl_enabled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSRWindow::DisableGL() {
|
void BrowserWindowOsrGtk::DisableGL() {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
if (!gl_enabled_)
|
if (!gl_enabled_)
|
||||||
return;
|
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 {
|
namespace client {
|
||||||
|
|
||||||
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
||||||
const std::string& startup_url,
|
const std::string& startup_url,
|
||||||
bool transparent,
|
bool transparent,
|
||||||
bool show_update_rect)
|
bool show_update_rect)
|
||||||
: BrowserWindowWin(delegate),
|
: BrowserWindow(delegate),
|
||||||
transparent_(transparent),
|
transparent_(transparent),
|
||||||
osr_hwnd_(NULL) {
|
osr_hwnd_(NULL) {
|
||||||
osr_window_ = new OsrWindowWin(this, transparent, show_update_rect);
|
osr_window_ = new OsrWindowWin(this, transparent, show_update_rect);
|
||||||
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowOsrWin::CreateBrowser(HWND parent_hwnd,
|
void BrowserWindowOsrWin::CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
const RECT& rect,
|
const CefRect& rect,
|
||||||
const CefBrowserSettings& settings) {
|
const CefBrowserSettings& settings) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
// Create the new browser and native window on the UI 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());
|
client_handler_->startup_url());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowOsrWin::GetPopupConfig(HWND temp_hwnd,
|
void BrowserWindowOsrWin::GetPopupConfig(CefWindowHandle temp_handle,
|
||||||
CefWindowInfo& windowInfo,
|
CefWindowInfo& windowInfo,
|
||||||
CefRefPtr<CefClient>& client,
|
CefRefPtr<CefClient>& client,
|
||||||
CefBrowserSettings& settings) {
|
CefBrowserSettings& settings) {
|
||||||
// Note: This method may be called on any thread.
|
// Note: This method may be called on any thread.
|
||||||
windowInfo.SetAsWindowless(temp_hwnd, transparent_);
|
windowInfo.SetAsWindowless(temp_handle, transparent_);
|
||||||
client = client_handler_;
|
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) {
|
int x, int y, size_t width, size_t height) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
if (osr_window_)
|
if (osr_window_)
|
||||||
osr_window_->ShowPopup(parent_hwnd, x, y, width, height);
|
osr_window_->ShowPopup(parent_handle, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowOsrWin::Show() {
|
void BrowserWindowOsrWin::Show() {
|
||||||
@ -69,7 +70,7 @@ void BrowserWindowOsrWin::SetFocus() {
|
|||||||
osr_window_->SetFocus();
|
osr_window_->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND BrowserWindowOsrWin::GetHWND() const {
|
ClientWindowHandle BrowserWindowOsrWin::GetWindowHandle() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
return osr_hwnd_;
|
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.
|
// Release the OSR window reference. It will be deleted on the UI thread.
|
||||||
osr_window_ = NULL;
|
osr_window_ = NULL;
|
||||||
|
|
||||||
BrowserWindowWin::OnBrowserClosed(browser);
|
BrowserWindow::OnBrowserClosed(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowOsrWin::OnOsrNativeWindowCreated(HWND hwnd) {
|
void BrowserWindowOsrWin::OnOsrNativeWindowCreated(HWND hwnd) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_WIN_H_
|
||||||
#define 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"
|
#include "cefclient/osr_window_win.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -13,34 +13,34 @@ namespace client {
|
|||||||
// Represents a native child window hosting a single off-screen browser
|
// 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
|
// instance. The methods of this class must be called on the main thread unless
|
||||||
// otherwise indicated.
|
// otherwise indicated.
|
||||||
class BrowserWindowOsrWin : public BrowserWindowWin,
|
class BrowserWindowOsrWin : public BrowserWindow,
|
||||||
OsrWindowWin::Delegate {
|
public OsrWindowWin::Delegate {
|
||||||
public:
|
public:
|
||||||
// Constructor may be called on any thread.
|
// Constructor may be called on any thread.
|
||||||
// |delegate| must outlive this object.
|
// |delegate| must outlive this object.
|
||||||
BrowserWindowOsrWin(BrowserWindowWin::Delegate* delegate,
|
BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
||||||
const std::string& startup_url,
|
const std::string& startup_url,
|
||||||
bool transparent,
|
bool transparent,
|
||||||
bool show_update_rect);
|
bool show_update_rect);
|
||||||
|
|
||||||
// BrowserWindowWin methods.
|
// BrowserWindow methods.
|
||||||
void CreateBrowser(HWND parent_hwnd,
|
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
const RECT& rect,
|
const CefRect& rect,
|
||||||
const CefBrowserSettings& settings) OVERRIDE;
|
const CefBrowserSettings& settings) OVERRIDE;
|
||||||
void GetPopupConfig(HWND temp_hwnd,
|
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||||
CefWindowInfo& windowInfo,
|
CefWindowInfo& windowInfo,
|
||||||
CefRefPtr<CefClient>& client,
|
CefRefPtr<CefClient>& client,
|
||||||
CefBrowserSettings& settings) OVERRIDE;
|
CefBrowserSettings& settings) OVERRIDE;
|
||||||
void ShowPopup(HWND parent_hwnd,
|
void ShowPopup(ClientWindowHandle parent_handle,
|
||||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||||
void Show() OVERRIDE;
|
void Show() OVERRIDE;
|
||||||
void Hide() OVERRIDE;
|
void Hide() OVERRIDE;
|
||||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||||
void SetFocus() OVERRIDE;
|
void SetFocus() OVERRIDE;
|
||||||
HWND GetHWND() const OVERRIDE;
|
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ClientHandler::Delegate methods.
|
// ClienHandler::Delegate methods.
|
||||||
void OnBrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
void OnBrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
|
|
||||||
// OsrWindowWin::Delegate methods.
|
// 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,
|
BrowserWindowStdWin::BrowserWindowStdWin(Delegate* delegate,
|
||||||
const std::string& startup_url)
|
const std::string& startup_url)
|
||||||
: BrowserWindowWin(delegate) {
|
: BrowserWindow(delegate) {
|
||||||
client_handler_ = new ClientHandlerStd(this, startup_url);
|
client_handler_ = new ClientHandlerStd(this, startup_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowStdWin::CreateBrowser(HWND parent_hwnd,
|
void BrowserWindowStdWin::CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
const RECT& rect,
|
const CefRect& rect,
|
||||||
const CefBrowserSettings& settings) {
|
const CefBrowserSettings& settings) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
CefWindowInfo window_info;
|
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_,
|
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||||
client_handler_->startup_url(),
|
client_handler_->startup_url(),
|
||||||
settings, NULL);
|
settings, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserWindowStdWin::GetPopupConfig(HWND temp_hwnd,
|
void BrowserWindowStdWin::GetPopupConfig(CefWindowHandle temp_handle,
|
||||||
CefWindowInfo& windowInfo,
|
CefWindowInfo& windowInfo,
|
||||||
CefRefPtr<CefClient>& client,
|
CefRefPtr<CefClient>& client,
|
||||||
CefBrowserSettings& settings) {
|
CefBrowserSettings& settings) {
|
||||||
// Note: This method may be called on any thread.
|
// Note: This method may be called on any thread.
|
||||||
// The window will be properly sized after the browser is created.
|
// The window will be properly sized after the browser is created.
|
||||||
windowInfo.SetAsChild(temp_hwnd, RECT());
|
windowInfo.SetAsChild(temp_handle, RECT());
|
||||||
client = client_handler_;
|
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) {
|
int x, int y, size_t width, size_t height) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
HWND hwnd = GetHWND();
|
HWND hwnd = GetWindowHandle();
|
||||||
if (hwnd) {
|
if (hwnd) {
|
||||||
SetParent(hwnd, parent_hwnd);
|
SetParent(hwnd, parent_handle);
|
||||||
SetWindowPos(hwnd, NULL, x, y,
|
SetWindowPos(hwnd, NULL, x, y,
|
||||||
static_cast<int>(width), static_cast<int>(height),
|
static_cast<int>(width), static_cast<int>(height),
|
||||||
SWP_NOZORDER);
|
SWP_NOZORDER);
|
||||||
@ -55,7 +56,7 @@ void BrowserWindowStdWin::ShowPopup(HWND parent_hwnd,
|
|||||||
void BrowserWindowStdWin::Show() {
|
void BrowserWindowStdWin::Show() {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
HWND hwnd = GetHWND();
|
HWND hwnd = GetWindowHandle();
|
||||||
if (hwnd && !::IsWindowVisible(hwnd))
|
if (hwnd && !::IsWindowVisible(hwnd))
|
||||||
ShowWindow(hwnd, SW_SHOW);
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ void BrowserWindowStdWin::Show() {
|
|||||||
void BrowserWindowStdWin::Hide() {
|
void BrowserWindowStdWin::Hide() {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
HWND hwnd = GetHWND();
|
HWND hwnd = GetWindowHandle();
|
||||||
if (hwnd) {
|
if (hwnd) {
|
||||||
// When the frame window is minimized set the browser window size to 0x0 to
|
// When the frame window is minimized set the browser window size to 0x0 to
|
||||||
// reduce resource usage.
|
// reduce resource usage.
|
||||||
@ -75,7 +76,7 @@ void BrowserWindowStdWin::Hide() {
|
|||||||
void BrowserWindowStdWin::SetBounds(int x, int y, size_t width, size_t height) {
|
void BrowserWindowStdWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
HWND hwnd = GetHWND();
|
HWND hwnd = GetWindowHandle();
|
||||||
if (hwnd) {
|
if (hwnd) {
|
||||||
// Set the browser window bounds.
|
// Set the browser window bounds.
|
||||||
SetWindowPos(hwnd, NULL, x, y,
|
SetWindowPos(hwnd, NULL, x, y,
|
||||||
@ -93,7 +94,7 @@ void BrowserWindowStdWin::SetFocus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND BrowserWindowStdWin::GetHWND() const {
|
ClientWindowHandle BrowserWindowStdWin::GetWindowHandle() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
if (browser_)
|
if (browser_)
|
||||||
|
@ -5,35 +5,35 @@
|
|||||||
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_WIN_H_
|
||||||
#define 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 {
|
namespace client {
|
||||||
|
|
||||||
// Represents a native child window hosting a single windowed browser instance.
|
// 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
|
// The methods of this class must be called on the main thread unless otherwise
|
||||||
// indicated.
|
// indicated.
|
||||||
class BrowserWindowStdWin : public BrowserWindowWin {
|
class BrowserWindowStdWin : public BrowserWindow {
|
||||||
public:
|
public:
|
||||||
// Constructor may be called on any thread.
|
// Constructor may be called on any thread.
|
||||||
// |delegate| must outlive this object.
|
// |delegate| must outlive this object.
|
||||||
BrowserWindowStdWin(Delegate* delegate,
|
BrowserWindowStdWin(Delegate* delegate,
|
||||||
const std::string& startup_url);
|
const std::string& startup_url);
|
||||||
|
|
||||||
// BrowserWindowWin methods.
|
// BrowserWindow methods.
|
||||||
void CreateBrowser(HWND parent_hwnd,
|
void CreateBrowser(ClientWindowHandle parent_handle,
|
||||||
const RECT& rect,
|
const CefRect& rect,
|
||||||
const CefBrowserSettings& settings) OVERRIDE;
|
const CefBrowserSettings& settings) OVERRIDE;
|
||||||
void GetPopupConfig(HWND temp_hwnd,
|
void GetPopupConfig(CefWindowHandle temp_handle,
|
||||||
CefWindowInfo& windowInfo,
|
CefWindowInfo& windowInfo,
|
||||||
CefRefPtr<CefClient>& client,
|
CefRefPtr<CefClient>& client,
|
||||||
CefBrowserSettings& settings) OVERRIDE;
|
CefBrowserSettings& settings) OVERRIDE;
|
||||||
void ShowPopup(HWND parent_hwnd,
|
void ShowPopup(ClientWindowHandle parent_handle,
|
||||||
int x, int y, size_t width, size_t height) OVERRIDE;
|
int x, int y, size_t width, size_t height) OVERRIDE;
|
||||||
void Show() OVERRIDE;
|
void Show() OVERRIDE;
|
||||||
void Hide() OVERRIDE;
|
void Hide() OVERRIDE;
|
||||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||||
void SetFocus() OVERRIDE;
|
void SetFocus() OVERRIDE;
|
||||||
HWND GetHWND() const OVERRIDE;
|
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdWin);
|
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdWin);
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include <gdk/gdk.h>
|
|
||||||
#include <gdk/gdkx.h>
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gtk/gtkgl.h>
|
#include <gtk/gtkgl.h>
|
||||||
|
|
||||||
#include <X11/Xlib.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 <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -18,42 +16,15 @@
|
|||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
#include "include/base/cef_scoped_ptr.h"
|
#include "include/base/cef_scoped_ptr.h"
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_browser.h"
|
|
||||||
#include "include/cef_frame.h"
|
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
#include "cefclient/client_app.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_context_impl.h"
|
||||||
#include "cefclient/main_message_loop_std.h"
|
#include "cefclient/main_message_loop_std.h"
|
||||||
#include "cefclient/osr_widget_gtk.h"
|
|
||||||
#include "cefclient/resource.h"
|
|
||||||
#include "cefclient/test_runner.h"
|
#include "cefclient/test_runner.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
namespace {
|
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) {
|
int XErrorHandlerImpl(Display *display, XErrorEvent *event) {
|
||||||
LOG(WARNING)
|
LOG(WARNING)
|
||||||
<< "X error received: "
|
<< "X error received: "
|
||||||
@ -69,254 +40,9 @@ int XIOErrorHandlerImpl(Display *display) {
|
|||||||
return 0;
|
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) {
|
void TerminationSignalHandler(int signatl) {
|
||||||
MainMessageLoop::Get()->Quit();
|
LOG(ERROR) << "Received termination signal: " << signatl;
|
||||||
}
|
MainContext::Get()->GetRootWindowManager()->CloseAllWindows(true);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int RunMain(int argc, char* argv[]) {
|
int RunMain(int argc, char* argv[]) {
|
||||||
@ -334,7 +60,7 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
return exit_code;
|
return exit_code;
|
||||||
|
|
||||||
// Create the main context object.
|
// Create the main context object.
|
||||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv));
|
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv, true));
|
||||||
|
|
||||||
CefSettings settings;
|
CefSettings settings;
|
||||||
|
|
||||||
@ -350,7 +76,7 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
||||||
|
|
||||||
// Initialize CEF.
|
// 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
|
// The Chromium sandbox requires that there only be a single thread during
|
||||||
// initialization. Therefore initialize GTK after CEF.
|
// initialization. Therefore initialize GTK after CEF.
|
||||||
@ -359,130 +85,25 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
// Perform gtkglext initialization required by the OSR example.
|
// Perform gtkglext initialization required by the OSR example.
|
||||||
gtk_gl_init(&argc, &argv_copy);
|
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.
|
// Install a signal handler so we clean up after ourselves.
|
||||||
signal(SIGINT, TerminationSignalHandler);
|
signal(SIGINT, TerminationSignalHandler);
|
||||||
signal(SIGTERM, 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.
|
// Run the message loop. This will block until Quit() is called.
|
||||||
int result = message_loop->Run();
|
int result = message_loop->Run();
|
||||||
|
|
||||||
// Shut down CEF.
|
// Shut down CEF.
|
||||||
CefShutdown();
|
context->Shutdown();
|
||||||
|
|
||||||
// Release objects in reverse order of creation.
|
// Release objects in reverse order of creation.
|
||||||
message_loop.reset();
|
message_loop.reset();
|
||||||
|
@ -511,7 +511,7 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
[ClientApplication sharedApplication];
|
[ClientApplication sharedApplication];
|
||||||
|
|
||||||
// Create the main context object.
|
// Create the main context object.
|
||||||
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv));
|
scoped_ptr<MainContextImpl> context(new MainContextImpl(argc, argv, true));
|
||||||
|
|
||||||
CefSettings settings;
|
CefSettings settings;
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
scoped_ptr<MainMessageLoop> message_loop(new MainMessageLoopStd);
|
||||||
|
|
||||||
// Initialize CEF.
|
// Initialize CEF.
|
||||||
CefInitialize(main_args, settings, app.get(), NULL);
|
context->Initialize(main_args, settings, app.get(), NULL);
|
||||||
|
|
||||||
// Register scheme handlers.
|
// Register scheme handlers.
|
||||||
test_runner::RegisterSchemeHandlers();
|
test_runner::RegisterSchemeHandlers();
|
||||||
@ -537,7 +537,7 @@ int RunMain(int argc, char* argv[]) {
|
|||||||
int result = message_loop->Run();
|
int result = message_loop->Run();
|
||||||
|
|
||||||
// Shut down CEF.
|
// Shut down CEF.
|
||||||
CefShutdown();
|
context->Shutdown();
|
||||||
|
|
||||||
// Release objects in reverse order of creation.
|
// Release objects in reverse order of creation.
|
||||||
g_handler = NULL;
|
g_handler = NULL;
|
||||||
|
@ -66,7 +66,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
|||||||
message_loop.reset(new MainMessageLoopStd);
|
message_loop.reset(new MainMessageLoopStd);
|
||||||
|
|
||||||
// Initialize CEF.
|
// Initialize CEF.
|
||||||
CefInitialize(main_args, settings, app.get(), sandbox_info);
|
context->Initialize(main_args, settings, app.get(), sandbox_info);
|
||||||
|
|
||||||
// Register scheme handlers.
|
// Register scheme handlers.
|
||||||
test_runner::RegisterSchemeHandlers();
|
test_runner::RegisterSchemeHandlers();
|
||||||
@ -83,7 +83,7 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
|||||||
int result = message_loop->Run();
|
int result = message_loop->Run();
|
||||||
|
|
||||||
// Shut down CEF.
|
// Shut down CEF.
|
||||||
CefShutdown();
|
context->Shutdown();
|
||||||
|
|
||||||
// Release objects in reverse order of creation.
|
// Release objects in reverse order of creation.
|
||||||
message_loop.reset();
|
message_loop.reset();
|
||||||
|
@ -12,15 +12,10 @@
|
|||||||
#include "include/cef_client.h"
|
#include "include/cef_client.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
#include "include/wrapper/cef_message_router.h"
|
#include "include/wrapper/cef_message_router.h"
|
||||||
|
#include "cefclient/client_types.h"
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include "cefclient/dialog_handler_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
|
#endif
|
||||||
|
|
||||||
namespace client {
|
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 {
|
namespace client {
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||||
class RootWindowManager;
|
class RootWindowManager;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ class MainContext {
|
|||||||
virtual void PopulateSettings(CefSettings* settings) = 0;
|
virtual void PopulateSettings(CefSettings* settings) = 0;
|
||||||
virtual void PopulateBrowserSettings(CefBrowserSettings* 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.
|
// Returns the object used to create/manage RootWindow instances.
|
||||||
virtual RootWindowManager* GetRootWindowManager() = 0;
|
virtual RootWindowManager* GetRootWindowManager() = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
#include "cefclient/client_switches.h"
|
#include "cefclient/client_switches.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include "cefclient/root_window_manager.h"
|
|
||||||
#endif
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -19,11 +16,11 @@ const char kDefaultUrl[] = "http://www.google.com";
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MainContextImpl::MainContextImpl(int argc,
|
MainContextImpl::MainContextImpl(int argc,
|
||||||
const char* const* argv
|
const char* const* argv,
|
||||||
#if defined(OS_WIN)
|
bool terminate_when_all_windows_closed)
|
||||||
, bool terminate_when_all_windows_closed
|
: terminate_when_all_windows_closed_(terminate_when_all_windows_closed),
|
||||||
#endif
|
initialized_(false),
|
||||||
) {
|
shutdown_(false) {
|
||||||
// Parse the command line.
|
// Parse the command line.
|
||||||
command_line_ = CefCommandLine::CreateCommandLine();
|
command_line_ = CefCommandLine::CreateCommandLine();
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
@ -37,11 +34,12 @@ MainContextImpl::MainContextImpl(int argc,
|
|||||||
main_url_ = command_line_->GetSwitchValue(switches::kUrl);
|
main_url_ = command_line_->GetSwitchValue(switches::kUrl);
|
||||||
if (main_url_.empty())
|
if (main_url_.empty())
|
||||||
main_url_ = kDefaultUrl;
|
main_url_ = kDefaultUrl;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
MainContextImpl::~MainContextImpl() {
|
||||||
root_window_manager_.reset(
|
// The context must either not have been initialized, or it must have also
|
||||||
new RootWindowManager(terminate_when_all_windows_closed));
|
// been shut down.
|
||||||
#endif
|
DCHECK(!initialized_ || shutdown_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MainContextImpl::GetConsoleLogPath() {
|
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() {
|
RootWindowManager* MainContextImpl::GetRootWindowManager() {
|
||||||
|
DCHECK(InValidState());
|
||||||
return root_window_manager_.get();
|
return root_window_manager_.get();
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
} // namespace client
|
||||||
|
@ -6,20 +6,22 @@
|
|||||||
#define CEF_TESTS_CEFCLIENT_MAIN_CONTEXT_IMPL_H_
|
#define CEF_TESTS_CEFCLIENT_MAIN_CONTEXT_IMPL_H_
|
||||||
|
|
||||||
#include "include/base/cef_scoped_ptr.h"
|
#include "include/base/cef_scoped_ptr.h"
|
||||||
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_command_line.h"
|
#include "include/cef_command_line.h"
|
||||||
#include "cefclient/main_context.h"
|
#include "cefclient/main_context.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||||
|
#include "cefclient/root_window_manager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
// Used to store global context in the browser process.
|
// Used to store global context in the browser process.
|
||||||
class MainContextImpl : public MainContext {
|
class MainContextImpl : public MainContext {
|
||||||
public:
|
public:
|
||||||
MainContextImpl(int argc,
|
MainContextImpl(int argc,
|
||||||
const char* const* argv
|
const char* const* argv,
|
||||||
#if defined(OS_WIN)
|
bool terminate_when_all_windows_closed);
|
||||||
, bool terminate_when_all_windows_closed
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
// MainContext members.
|
// MainContext members.
|
||||||
std::string GetConsoleLogPath() OVERRIDE;
|
std::string GetConsoleLogPath() OVERRIDE;
|
||||||
@ -28,23 +30,51 @@ class MainContextImpl : public MainContext {
|
|||||||
std::string GetMainURL() OVERRIDE;
|
std::string GetMainURL() OVERRIDE;
|
||||||
void PopulateSettings(CefSettings* settings) OVERRIDE;
|
void PopulateSettings(CefSettings* settings) OVERRIDE;
|
||||||
void PopulateBrowserSettings(CefBrowserSettings* settings) OVERRIDE;
|
void PopulateBrowserSettings(CefBrowserSettings* settings) OVERRIDE;
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||||
RootWindowManager* GetRootWindowManager() OVERRIDE;
|
RootWindowManager* GetRootWindowManager() OVERRIDE;
|
||||||
#endif
|
#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:
|
private:
|
||||||
// Allow deletion via scoped_ptr only.
|
// Allow deletion via scoped_ptr only.
|
||||||
friend struct base::DefaultDeleter<MainContextImpl>;
|
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_;
|
CefRefPtr<CefCommandLine> command_line_;
|
||||||
std::string main_url_;
|
std::string main_url_;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||||
scoped_ptr<RootWindowManager> root_window_manager_;
|
scoped_ptr<RootWindowManager> root_window_manager_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Used to verify that methods are called on the correct thread.
|
||||||
|
base::ThreadChecker thread_checker_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MainContextImpl);
|
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) {
|
void OsrWindowWin::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
// Detach |this| from the ClientHandler.
|
// Detach |this| from the ClientHandlerOsr.
|
||||||
static_cast<ClientHandlerOsr*>(browser_->GetHost()->GetClient().get())->
|
static_cast<ClientHandlerOsr*>(browser_->GetHost()->GetClient().get())->
|
||||||
DetachOsrDelegate();
|
DetachOsrDelegate();
|
||||||
browser_ = NULL;
|
browser_ = NULL;
|
||||||
|
@ -96,7 +96,7 @@ class OsrWindowWin :
|
|||||||
int GetPopupYOffset() const;
|
int GetPopupYOffset() const;
|
||||||
void ApplyPopupOffset(int& x, int& y) const;
|
void ApplyPopupOffset(int& x, int& y) const;
|
||||||
|
|
||||||
// ClientHandlerOsr::Delegate methods.
|
// ClientHandlerOsr::OsrDelegate methods.
|
||||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "include/base/cef_ref_counted.h"
|
#include "include/base/cef_ref_counted.h"
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
|
#include "cefclient/client_types.h"
|
||||||
#include "cefclient/main_message_loop.h"
|
#include "cefclient/main_message_loop.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -90,7 +91,7 @@ class RootWindow :
|
|||||||
virtual CefRefPtr<CefBrowser> GetBrowser() const = 0;
|
virtual CefRefPtr<CefBrowser> GetBrowser() const = 0;
|
||||||
|
|
||||||
// Returns the handle for this window, if any.
|
// Returns the handle for this window, if any.
|
||||||
virtual CefWindowHandle GetWindowHandle() const = 0;
|
virtual ClientWindowHandle GetWindowHandle() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Allow deletion via scoped_refptr only.
|
// 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)
|
#if defined(OS_WIN)
|
||||||
#include "cefclient/temp_window_win.h"
|
#include "cefclient/temp_window_win.h"
|
||||||
|
#elif defined(OS_LINUX)
|
||||||
|
#include "cefclient/temp_window_x11.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -76,9 +78,11 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||||||
typedef std::set<scoped_refptr<RootWindow> > RootWindowSet;
|
typedef std::set<scoped_refptr<RootWindow> > RootWindowSet;
|
||||||
RootWindowSet root_windows_;
|
RootWindowSet root_windows_;
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
// Singleton window used as the temporary parent for popup browsers.
|
// Singleton window used as the temporary parent for popup browsers.
|
||||||
|
#if defined(OS_WIN)
|
||||||
TempWindowWin temp_window_win_;
|
TempWindowWin temp_window_win_;
|
||||||
|
#elif defined(OS_LINUX)
|
||||||
|
TempWindowX11 temp_window_x11_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RootWindowManager);
|
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
|
// 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
|
// window will be created after the browser is created and the popup window
|
||||||
// will be re-parented to it at that time.
|
// will be re-parented to it at that time.
|
||||||
browser_window_->GetPopupConfig(TempWindowWin::GetHWND(),
|
browser_window_->GetPopupConfig(TempWindowWin::GetWindowHandle(),
|
||||||
windowInfo, client, settings);
|
windowInfo, client, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +147,10 @@ void RootWindowWin::Show(ShowMode mode) {
|
|||||||
int nCmdShow = SW_SHOWNORMAL;
|
int nCmdShow = SW_SHOWNORMAL;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case ShowMinimized:
|
case ShowMinimized:
|
||||||
nCmdShow = SW_SHOWNORMAL;
|
nCmdShow = SW_SHOWMINIMIZED;
|
||||||
break;
|
break;
|
||||||
case ShowMaximized:
|
case ShowMaximized:
|
||||||
nCmdShow = SW_SHOWNORMAL;
|
nCmdShow = SW_SHOWMAXIMIZED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -193,7 +193,7 @@ CefRefPtr<CefBrowser> RootWindowWin::GetBrowser() const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CefWindowHandle RootWindowWin::GetWindowHandle() const {
|
ClientWindowHandle RootWindowWin::GetWindowHandle() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
return hwnd_;
|
return hwnd_;
|
||||||
}
|
}
|
||||||
@ -322,7 +322,10 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
|||||||
|
|
||||||
if (!is_popup_) {
|
if (!is_popup_) {
|
||||||
// Create the browser window.
|
// 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 {
|
} else {
|
||||||
// With popups we already have a browser window. Parent the browser window
|
// With popups we already have a browser window. Parent the browser window
|
||||||
// to the root window and show it in the correct location.
|
// 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;
|
int urloffset = rect.left + BUTTON_WIDTH * 4;
|
||||||
|
|
||||||
if (browser_window_) {
|
if (browser_window_) {
|
||||||
HWND browser_hwnd = browser_window_->GetHWND();
|
HWND browser_hwnd = browser_window_->GetWindowHandle();
|
||||||
HDWP hdwp = BeginDeferWindowPos(1);
|
HDWP hdwp = BeginDeferWindowPos(1);
|
||||||
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset,
|
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset,
|
||||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||||
@ -696,7 +699,6 @@ void RootWindowWin::OnBrowserWindowDestroyed() {
|
|||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
browser_window_.reset();
|
browser_window_.reset();
|
||||||
browser_destroyed_ = true;
|
|
||||||
|
|
||||||
if (!window_destroyed_) {
|
if (!window_destroyed_) {
|
||||||
// The browser was destroyed first. This could be due to the use of
|
// The browser was destroyed first. This could be due to the use of
|
||||||
@ -705,6 +707,7 @@ void RootWindowWin::OnBrowserWindowDestroyed() {
|
|||||||
Close(false);
|
Close(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
browser_destroyed_ = true;
|
||||||
NotifyDestroyedIfDone();
|
NotifyDestroyedIfDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "include/base/cef_scoped_ptr.h"
|
#include "include/base/cef_scoped_ptr.h"
|
||||||
#include "cefclient/browser_window_win.h"
|
#include "cefclient/browser_window.h"
|
||||||
#include "cefclient/root_window.h"
|
#include "cefclient/root_window.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -20,7 +20,7 @@ namespace client {
|
|||||||
// The methods of this class must be called on the main thread unless otherwise
|
// The methods of this class must be called on the main thread unless otherwise
|
||||||
// indicated.
|
// indicated.
|
||||||
class RootWindowWin : public RootWindow,
|
class RootWindowWin : public RootWindow,
|
||||||
public BrowserWindowWin::Delegate {
|
public BrowserWindow::Delegate {
|
||||||
public:
|
public:
|
||||||
// Constructor may be called on any thread.
|
// Constructor may be called on any thread.
|
||||||
RootWindowWin();
|
RootWindowWin();
|
||||||
@ -45,7 +45,7 @@ class RootWindowWin : public RootWindow,
|
|||||||
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
|
||||||
void Close(bool force) OVERRIDE;
|
void Close(bool force) OVERRIDE;
|
||||||
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
|
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
|
||||||
CefWindowHandle GetWindowHandle() const OVERRIDE;
|
ClientWindowHandle GetWindowHandle() const OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateBrowserWindow(bool with_osr, const std::string& startup_url);
|
void CreateBrowserWindow(bool with_osr, const std::string& startup_url);
|
||||||
@ -79,7 +79,7 @@ class RootWindowWin : public RootWindow,
|
|||||||
bool OnClose();
|
bool OnClose();
|
||||||
void OnDestroyed();
|
void OnDestroyed();
|
||||||
|
|
||||||
// BrowserWindowWin::Delegate methods.
|
// BrowserWindow::Delegate methods.
|
||||||
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
void OnBrowserWindowDestroyed() OVERRIDE;
|
void OnBrowserWindowDestroyed() OVERRIDE;
|
||||||
void OnSetAddress(const std::string& url) OVERRIDE;
|
void OnSetAddress(const std::string& url) OVERRIDE;
|
||||||
@ -96,7 +96,7 @@ class RootWindowWin : public RootWindow,
|
|||||||
bool with_controls_;
|
bool with_controls_;
|
||||||
bool is_popup_;
|
bool is_popup_;
|
||||||
RECT start_rect_;
|
RECT start_rect_;
|
||||||
scoped_ptr<BrowserWindowWin> browser_window_;
|
scoped_ptr<BrowserWindow> browser_window_;
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
|
||||||
// Main window.
|
// Main window.
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "cefclient/temp_window_win.h"
|
#include "cefclient/temp_window_win.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -50,7 +52,7 @@ TempWindowWin::~TempWindowWin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
HWND TempWindowWin::GetHWND() {
|
CefWindowHandle TempWindowWin::GetWindowHandle() {
|
||||||
DCHECK(g_temp_window);
|
DCHECK(g_temp_window);
|
||||||
return g_temp_window->hwnd_;
|
return g_temp_window->hwnd_;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||||
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "cefclient/main_message_loop.h"
|
#include "cefclient/main_message_loop.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -15,8 +13,8 @@ namespace client {
|
|||||||
// popup browsers.
|
// popup browsers.
|
||||||
class TempWindowWin {
|
class TempWindowWin {
|
||||||
public:
|
public:
|
||||||
// Returns the singleton window HWND.
|
// Returns the singleton window handle.
|
||||||
static HWND GetHWND();
|
static CefWindowHandle GetWindowHandle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// A single instance will be created/owned by RootWindowManager.
|
// A single instance will be created/owned by RootWindowManager.
|
||||||
@ -25,7 +23,7 @@ class TempWindowWin {
|
|||||||
TempWindowWin();
|
TempWindowWin();
|
||||||
~TempWindowWin();
|
~TempWindowWin();
|
||||||
|
|
||||||
HWND hwnd_;
|
CefWindowHandle hwnd_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TempWindowWin);
|
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