mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-08 08:08:45 +01:00
140 lines
4.4 KiB
C++
140 lines
4.4 KiB
C++
// Copyright 2020 The Chromium Embedded Framework Authors. Portions copyright
|
|
// 2012 The Chromium 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 "libcef/browser/native/cursor_util.h"
|
|
|
|
#include "libcef/browser/browser_host_base.h"
|
|
|
|
#include "content/common/cursors/webcursor.h"
|
|
#include "content/public/browser/render_widget_host_view.h"
|
|
#include "ui/base/cursor/cursor_factory.h"
|
|
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
|
|
|
#if defined(USE_AURA)
|
|
#include "ui/display/display_util.h"
|
|
#include "ui/wm/core/cursor_loader.h"
|
|
#endif
|
|
|
|
namespace cursor_util {
|
|
|
|
namespace {
|
|
|
|
#if defined(USE_AURA)
|
|
|
|
display::ScreenInfo GetScreenInfo(CefRefPtr<CefBrowser> browser) {
|
|
display::ScreenInfo screen_info;
|
|
|
|
bool screen_info_set = false;
|
|
if (auto web_contents =
|
|
static_cast<CefBrowserHostBase*>(browser.get())->GetWebContents()) {
|
|
if (auto view = web_contents->GetRenderWidgetHostView()) {
|
|
const auto screen_infos = view->GetScreenInfos();
|
|
if (!screen_infos.screen_infos.empty()) {
|
|
screen_info = screen_infos.current();
|
|
screen_info_set = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!screen_info_set) {
|
|
display::DisplayUtil::GetDefaultScreenInfo(&screen_info);
|
|
}
|
|
|
|
return screen_info;
|
|
}
|
|
|
|
display::Display::Rotation OrientationAngleToRotation(
|
|
uint16_t orientation_angle) {
|
|
// The Display rotation and the ScreenInfo orientation are not the same
|
|
// angle. The former is the physical display rotation while the later is the
|
|
// rotation required by the content to be shown properly on the screen, in
|
|
// other words, relative to the physical display.
|
|
if (orientation_angle == 0) {
|
|
return display::Display::ROTATE_0;
|
|
}
|
|
if (orientation_angle == 90) {
|
|
return display::Display::ROTATE_270;
|
|
}
|
|
if (orientation_angle == 180) {
|
|
return display::Display::ROTATE_180;
|
|
}
|
|
if (orientation_angle == 270) {
|
|
return display::Display::ROTATE_90;
|
|
}
|
|
NOTREACHED();
|
|
return display::Display::ROTATE_0;
|
|
}
|
|
|
|
#endif // defined(USE_AURA)
|
|
|
|
} // namespace
|
|
|
|
bool OnCursorChange(CefRefPtr<CefBrowser> browser,
|
|
const ui::Cursor& ui_cursor) {
|
|
auto client = browser->GetHost()->GetClient();
|
|
if (!client) {
|
|
return false;
|
|
}
|
|
auto handler = client->GetDisplayHandler();
|
|
if (!handler) {
|
|
return false;
|
|
}
|
|
|
|
const cef_cursor_type_t cursor_type =
|
|
static_cast<cef_cursor_type_t>(ui_cursor.type());
|
|
CefCursorInfo custom_cursor_info;
|
|
if (ui_cursor.type() == ui::mojom::CursorType::kCustom) {
|
|
custom_cursor_info.hotspot.x = ui_cursor.custom_hotspot().x();
|
|
custom_cursor_info.hotspot.y = ui_cursor.custom_hotspot().y();
|
|
custom_cursor_info.image_scale_factor = ui_cursor.image_scale_factor();
|
|
custom_cursor_info.buffer = ui_cursor.custom_bitmap().getPixels();
|
|
custom_cursor_info.size.width = ui_cursor.custom_bitmap().width();
|
|
custom_cursor_info.size.height = ui_cursor.custom_bitmap().height();
|
|
}
|
|
|
|
bool handled = false;
|
|
|
|
#if defined(USE_AURA)
|
|
wm::CursorLoader cursor_loader;
|
|
scoped_refptr<ui::PlatformCursor> platform_cursor;
|
|
CefCursorHandle native_cursor = kNullCursorHandle;
|
|
|
|
ui::Cursor loaded_cursor = ui_cursor;
|
|
|
|
if (ui_cursor.type() == ui::mojom::CursorType::kCustom) {
|
|
platform_cursor = ui::CursorFactory::GetInstance()->CreateImageCursor(
|
|
ui::mojom::CursorType::kCustom, ui_cursor.custom_bitmap(),
|
|
ui_cursor.custom_hotspot());
|
|
} else {
|
|
const auto& screen_info = GetScreenInfo(browser);
|
|
cursor_loader.SetDisplayData(
|
|
OrientationAngleToRotation(screen_info.orientation_angle),
|
|
screen_info.device_scale_factor);
|
|
|
|
// Attempts to load the cursor via the platform or from pak resources.
|
|
cursor_loader.SetPlatformCursor(&loaded_cursor);
|
|
platform_cursor = loaded_cursor.platform();
|
|
}
|
|
|
|
if (platform_cursor) {
|
|
native_cursor = cursor_util::ToCursorHandle(platform_cursor);
|
|
}
|
|
|
|
handled = handler->OnCursorChange(browser, native_cursor, cursor_type,
|
|
custom_cursor_info);
|
|
#elif BUILDFLAG(IS_MAC)
|
|
// |web_cursor| owns the resulting |native_cursor|.
|
|
content::WebCursor web_cursor(ui_cursor);
|
|
CefCursorHandle native_cursor = web_cursor.GetNativeCursor();
|
|
handled = handler->OnCursorChange(browser, native_cursor, cursor_type,
|
|
custom_cursor_info);
|
|
#else
|
|
NOTIMPLEMENTED();
|
|
#endif
|
|
|
|
return handled;
|
|
}
|
|
|
|
} // namespace cursor_util
|