Add CefRenderHandler::OnVirtualKeyboardRequested (issue #2607)

This commit is contained in:
Riku Palomäki 2019-02-26 16:49:41 +00:00 committed by Marshall Greenblatt
parent c72d57aa60
commit 379fb8d39e
10 changed files with 173 additions and 5 deletions

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=cf5dc6f6d2c64d5dc706edd5adc5cf6c7c752750$ // $hash=0640490eead86e5631e8db67f3a0de8b43c10640$
// //
#ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_ #ifndef CEF_INCLUDE_CAPI_CEF_RENDER_HANDLER_CAPI_H_
@ -231,6 +231,17 @@ typedef struct _cef_render_handler_t {
struct _cef_browser_t* browser, struct _cef_browser_t* browser,
const cef_string_t* selected_text, const cef_string_t* selected_text,
const cef_range_t* selected_range); const cef_range_t* selected_range);
///
// Called when an on-screen keyboard should be shown or hidden for the
// specified |browser|. |input_mode| specifies what kind of keyboard should be
// opened. If |input_mode| is CEF_TEXT_INPUT_MODE_NONE, any existing keyboard
// for this browser should be hidden.
///
void(CEF_CALLBACK* on_virtual_keyboard_requested)(
struct _cef_render_handler_t* self,
struct _cef_browser_t* browser,
cef_text_input_mode_t input_mode);
} cef_render_handler_t; } cef_render_handler_t;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -57,6 +57,7 @@ class CefRenderHandler : public virtual CefBaseRefCounted {
typedef cef_drag_operations_mask_t DragOperationsMask; typedef cef_drag_operations_mask_t DragOperationsMask;
typedef cef_paint_element_type_t PaintElementType; typedef cef_paint_element_type_t PaintElementType;
typedef std::vector<CefRect> RectList; typedef std::vector<CefRect> RectList;
typedef cef_text_input_mode_t TextInputMode;
/// ///
// Return the handler for accessibility notifications. If no handler is // Return the handler for accessibility notifications. If no handler is
@ -231,6 +232,16 @@ class CefRenderHandler : public virtual CefBaseRefCounted {
virtual void OnTextSelectionChanged(CefRefPtr<CefBrowser> browser, virtual void OnTextSelectionChanged(CefRefPtr<CefBrowser> browser,
const CefString& selected_text, const CefString& selected_text,
const CefRange& selected_range) {} const CefRange& selected_range) {}
///
// Called when an on-screen keyboard should be shown or hidden for the
// specified |browser|. |input_mode| specifies what kind of keyboard
// should be opened. If |input_mode| is CEF_TEXT_INPUT_MODE_NONE, any
// existing keyboard for this browser should be hidden.
///
/*--cef()--*/
virtual void OnVirtualKeyboardRequested(CefRefPtr<CefBrowser> browser,
TextInputMode input_mode) {}
}; };
#endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_ #endif // CEF_INCLUDE_CEF_RENDER_HANDLER_H_

View File

@ -994,6 +994,25 @@ typedef enum {
DRAG_OPERATION_EVERY = UINT_MAX DRAG_OPERATION_EVERY = UINT_MAX
} cef_drag_operations_mask_t; } cef_drag_operations_mask_t;
///
// Input mode of a virtual keyboard. These constants match their equivalents
// in Chromium's text_input_mode.h and should not be renumbered.
// See https://html.spec.whatwg.org/#input-modalities:-the-inputmode-attribute
///
typedef enum {
CEF_TEXT_INPUT_MODE_DEFAULT,
CEF_TEXT_INPUT_MODE_NONE,
CEF_TEXT_INPUT_MODE_TEXT,
CEF_TEXT_INPUT_MODE_TEL,
CEF_TEXT_INPUT_MODE_URL,
CEF_TEXT_INPUT_MODE_EMAIL,
CEF_TEXT_INPUT_MODE_NUMERIC,
CEF_TEXT_INPUT_MODE_DECIMAL,
CEF_TEXT_INPUT_MODE_SEARCH,
CEF_TEXT_INPUT_MODE_MAX = CEF_TEXT_INPUT_MODE_SEARCH,
} cef_text_input_mode_t;
/// ///
// V8 access control values. // V8 access control values.
/// ///

View File

@ -396,6 +396,9 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
// Do this last because it may result in a call to SetNeedsBeginFrames. // Do this last because it may result in a call to SetNeedsBeginFrames.
render_widget_host_->SetView(this); render_widget_host_->SetView(this);
if (GetTextInputManager())
GetTextInputManager()->AddObserver(this);
} }
CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() { CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
@ -425,6 +428,9 @@ CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
DCHECK(popup_host_view_ == NULL); DCHECK(popup_host_view_ == NULL);
DCHECK(child_host_view_ == NULL); DCHECK(child_host_view_ == NULL);
DCHECK(guest_host_views_.empty()); DCHECK(guest_host_views_.empty());
if (text_input_manager_)
text_input_manager_->RemoveObserver(this);
} }
// Called for full-screen widgets. // Called for full-screen widgets.
@ -1424,6 +1430,31 @@ void CefRenderWidgetHostViewOSR::SendFocusEvent(bool focus) {
} }
} }
void CefRenderWidgetHostViewOSR::OnUpdateTextInputStateCalled(
content::TextInputManager* text_input_manager,
content::RenderWidgetHostViewBase* updated_view,
bool did_update_state) {
const content::TextInputState* state =
text_input_manager->GetTextInputState();
if (state && !state->show_ime_if_needed)
return;
CefRenderHandler::TextInputMode mode = CEF_TEXT_INPUT_MODE_NONE;
if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
static_assert(
static_cast<int>(CEF_TEXT_INPUT_MODE_MAX) ==
static_cast<int>(ui::TEXT_INPUT_MODE_MAX),
"Enum values in cef_text_input_mode_t must match ui::TextInputMode");
mode = static_cast<CefRenderHandler::TextInputMode>(state->mode);
}
CefRefPtr<CefRenderHandler> handler =
browser_impl_->GetClient()->GetRenderHandler();
CHECK(handler);
handler->OnVirtualKeyboardRequested(browser_impl_->GetBrowser(), mode);
}
void CefRenderWidgetHostViewOSR::UpdateFrameRate() { void CefRenderWidgetHostViewOSR::UpdateFrameRate() {
frame_rate_threshold_us_ = 0; frame_rate_threshold_us_ = 0;
SetFrameRate(); SetFrameRate();

View File

@ -20,6 +20,7 @@
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/public/common/widget_type.h" #include "content/public/common/widget_type.h"
#include "ui/compositor/compositor.h" #include "ui/compositor/compositor.h"
#include "ui/compositor/external_begin_frame_client.h" #include "ui/compositor/external_begin_frame_client.h"
@ -96,7 +97,8 @@ class MacHelper;
class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase, class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
public ui::ExternalBeginFrameClient, public ui::ExternalBeginFrameClient,
public ui::CompositorDelegate { public ui::CompositorDelegate,
public content::TextInputManager::Observer {
public: public:
CefRenderWidgetHostViewOSR(SkColor background_color, CefRenderWidgetHostViewOSR(SkColor background_color,
bool use_shared_texture, bool use_shared_texture,
@ -205,6 +207,12 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase,
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice( std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
ui::Compositor* compositor) override; ui::Compositor* compositor) override;
// TextInputManager::Observer implementation.
void OnUpdateTextInputStateCalled(
content::TextInputManager* text_input_manager,
RenderWidgetHostViewBase* updated_view,
bool did_update_state) override;
bool InstallTransparency(); bool InstallTransparency();
void SynchronizeVisualProperties(); void SynchronizeVisualProperties();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=7af995d59f8f171a08ea92b3b0c3428fb26f93ad$ // $hash=94f5afecaaa5c9c534438a1c97a4af27a97d148c$
// //
#include "libcef_dll/cpptoc/render_handler_cpptoc.h" #include "libcef_dll/cpptoc/render_handler_cpptoc.h"
@ -500,6 +500,27 @@ render_handler_on_text_selection_changed(struct _cef_render_handler_t* self,
selected_rangeVal); selected_rangeVal);
} }
void CEF_CALLBACK
render_handler_on_virtual_keyboard_requested(struct _cef_render_handler_t* self,
cef_browser_t* browser,
cef_text_input_mode_t input_mode) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return;
// Execute
CefRenderHandlerCppToC::Get(self)->OnVirtualKeyboardRequested(
CefBrowserCToCpp::Wrap(browser), input_mode);
}
} // namespace } // namespace
// CONSTRUCTOR - Do not edit by hand. // CONSTRUCTOR - Do not edit by hand.
@ -524,6 +545,8 @@ CefRenderHandlerCppToC::CefRenderHandlerCppToC() {
render_handler_on_ime_composition_range_changed; render_handler_on_ime_composition_range_changed;
GetStruct()->on_text_selection_changed = GetStruct()->on_text_selection_changed =
render_handler_on_text_selection_changed; render_handler_on_text_selection_changed;
GetStruct()->on_virtual_keyboard_requested =
render_handler_on_virtual_keyboard_requested;
} }
// DESTRUCTOR - Do not edit by hand. // DESTRUCTOR - Do not edit by hand.

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=bb77b018f638f1bc43208d48a84b02696b9c055c$ // $hash=9a7d89bc978623c025c82f438eec0da543aaa7a6$
// //
#include "libcef_dll/ctocpp/render_handler_ctocpp.h" #include "libcef_dll/ctocpp/render_handler_ctocpp.h"
@ -431,6 +431,28 @@ void CefRenderHandlerCToCpp::OnTextSelectionChanged(
&selected_range); &selected_range);
} }
NO_SANITIZE("cfi-icall")
void CefRenderHandlerCToCpp::OnVirtualKeyboardRequested(
CefRefPtr<CefBrowser> browser,
TextInputMode input_mode) {
shutdown_checker::AssertNotShutdown();
cef_render_handler_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, on_virtual_keyboard_requested))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return;
// Execute
_struct->on_virtual_keyboard_requested(
_struct, CefBrowserCppToC::Wrap(browser), input_mode);
}
// CONSTRUCTOR - Do not edit by hand. // CONSTRUCTOR - Do not edit by hand.
CefRenderHandlerCToCpp::CefRenderHandlerCToCpp() {} CefRenderHandlerCToCpp::CefRenderHandlerCToCpp() {}

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=f76bdd2d055df74b08fe6c77b40b68d908f20dc9$ // $hash=b4922b3f59c932edf64692772b300f231e588388$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_
@ -77,6 +77,8 @@ class CefRenderHandlerCToCpp
void OnTextSelectionChanged(CefRefPtr<CefBrowser> browser, void OnTextSelectionChanged(CefRefPtr<CefBrowser> browser,
const CefString& selected_text, const CefString& selected_text,
const CefRange& selected_range) override; const CefRange& selected_range) override;
void OnVirtualKeyboardRequested(CefRefPtr<CefBrowser> browser,
TextInputMode input_mode) override;
}; };
#endif // CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_ #endif // CEF_LIBCEF_DLL_CTOCPP_RENDER_HANDLER_CTOCPP_H_

View File

@ -158,6 +158,8 @@ enum OSRTestType {
OSR_TEST_IME_CANCEL_COMPOSITION, OSR_TEST_IME_CANCEL_COMPOSITION,
// text selection range changed // text selection range changed
OSR_TEST_TEXT_SELECTION_CHANGE, OSR_TEST_TEXT_SELECTION_CHANGE,
// clicking on text input will call OnVirtualKeyboardRequested
OSR_TEST_VIRTUAL_KEYBOARD,
// Define the range for popup tests. // Define the range for popup tests.
OSR_TEST_POPUP_FIRST = OSR_TEST_POPUP_PAINT, OSR_TEST_POPUP_FIRST = OSR_TEST_POPUP_PAINT,
@ -948,6 +950,19 @@ class OSRTestHandler : public RoutingTestHandler,
1); 1);
} }
} break; } break;
case OSR_TEST_VIRTUAL_KEYBOARD: {
if (StartTest()) {
CefMouseEvent mouse_event;
const CefRect& input = GetElementBounds("email");
mouse_event.x = MiddleX(input);
mouse_event.y = MiddleY(input);
mouse_event.modifiers = 0;
browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, false,
1);
browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, true,
1);
}
} break;
default: default:
break; break;
} }
@ -1103,6 +1118,28 @@ class OSRTestHandler : public RoutingTestHandler,
} }
} }
void OnVirtualKeyboardRequested(CefRefPtr<CefBrowser> browser,
TextInputMode input_mode) override {
if (test_type_ == OSR_TEST_VIRTUAL_KEYBOARD && started()) {
if (!got_virtual_keyboard_event_.isSet()) {
got_virtual_keyboard_event_.yes();
EXPECT_EQ(CEF_TEXT_INPUT_MODE_EMAIL, input_mode);
CefMouseEvent mouse_event;
const CefRect& input = GetElementBounds("LI01");
mouse_event.x = MiddleX(input);
mouse_event.y = MiddleY(input);
mouse_event.modifiers = 0;
browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, false,
1);
browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_LEFT, true, 1);
} else {
EXPECT_EQ(CEF_TEXT_INPUT_MODE_NONE, input_mode);
DestroySucceededTestSoon();
}
}
}
bool OnTooltip(CefRefPtr<CefBrowser> browser, CefString& text) override { bool OnTooltip(CefRefPtr<CefBrowser> browser, CefString& text) override {
if (test_type_ == OSR_TEST_TOOLTIP && started()) { if (test_type_ == OSR_TEST_TOOLTIP && started()) {
EXPECT_STREQ("EXPECTED_TOOLTIP", text.ToString().c_str()); EXPECT_STREQ("EXPECTED_TOOLTIP", text.ToString().c_str());
@ -1319,6 +1356,7 @@ class OSRTestHandler : public RoutingTestHandler,
TrackCallback got_navigation_focus_event_; TrackCallback got_navigation_focus_event_;
TrackCallback got_system_focus_event_; TrackCallback got_system_focus_event_;
TrackCallback got_initial_text_selection_event_; TrackCallback got_initial_text_selection_event_;
TrackCallback got_virtual_keyboard_event_;
typedef std::map<std::string, CefRect> ElementBoundsMap; typedef std::map<std::string, CefRect> ElementBoundsMap;
ElementBoundsMap element_bounds_; ElementBoundsMap element_bounds_;
@ -1405,3 +1443,4 @@ OSR_TEST(IMECancelComposition, OSR_TEST_IME_CANCEL_COMPOSITION, 1.0f);
OSR_TEST(IMECancelComposition2x, OSR_TEST_IME_CANCEL_COMPOSITION, 2.0f); OSR_TEST(IMECancelComposition2x, OSR_TEST_IME_CANCEL_COMPOSITION, 2.0f);
OSR_TEST(TextSelectionChanged, OSR_TEST_TEXT_SELECTION_CHANGE, 1.0f); OSR_TEST(TextSelectionChanged, OSR_TEST_TEXT_SELECTION_CHANGE, 1.0f);
OSR_TEST(TextSelectionChanged2x, OSR_TEST_TEXT_SELECTION_CHANGE, 2.0f); OSR_TEST(TextSelectionChanged2x, OSR_TEST_TEXT_SELECTION_CHANGE, 2.0f);
OSR_TEST(VirtualKeyboard, OSR_TEST_VIRTUAL_KEYBOARD, 1.0f);

View File

@ -48,6 +48,7 @@
elems.push(getElementBounds('LI10')); elems.push(getElementBounds('LI10'));
elems.push(getElementBounds('LI11')); elems.push(getElementBounds('LI11'));
elems.push(getElementBounds('LI11select')); elems.push(getElementBounds('LI11select'));
elems.push(getElementBounds('email'));
elems.push(getElementBounds('editbox')); elems.push(getElementBounds('editbox'));
elems.push(getElementBounds('btnnavigate')); elems.push(getElementBounds('btnnavigate'));
elems.push(getElementBounds('dropdiv')); elems.push(getElementBounds('dropdiv'));
@ -143,6 +144,7 @@
<li id='LI10' title='EXPECTED_TOOLTIP'>Mouse over this element will <li id='LI10' title='EXPECTED_TOOLTIP'>Mouse over this element will
trigger show a tooltip</li> trigger show a tooltip</li>
<li id='LI11' onclick='selectText(event)'>SELECTED_TEXT_RANGE</li> <li id='LI11' onclick='selectText(event)'>SELECTED_TEXT_RANGE</li>
<li><input id='email' type='text' size=10 inputmode='email'></li>
</ol> </ol>
<div class="dropdiv" id="dropdiv" ondrop="drop(event)" ondragover="allowDrop(event)"> <div class="dropdiv" id="dropdiv" ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="draghere">Drag here</span> <span id="draghere">Drag here</span>