 Chromium Code Reviews
 Chromium Code Reviews Issue 1986153005:
  The on screen keyboard on Windows 8+ should not obscure the input field.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1986153005:
  The on screen keyboard on Windows 8+ should not obscure the input field.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: content/browser/renderer_host/render_widget_host_view_aura.cc | 
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc | 
| index c33e325cef30eaab1a331b7c0dcf7f6d7f8f6166..05eb3244ed7737e51f3855147fa8b6ae5261361a 100644 | 
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc | 
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc | 
| @@ -97,10 +97,13 @@ | 
| #include "ui/wm/public/window_types.h" | 
| #if defined(OS_WIN) | 
| +#include "base/time/time.h" | 
| #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 
| #include "content/browser/accessibility/browser_accessibility_win.h" | 
| #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | 
| #include "ui/base/win/hidden_window.h" | 
| +#include "ui/base/win/osk_display_manager.h" | 
| +#include "ui/base/win/osk_display_observer.h" | 
| #include "ui/display/win/screen_win.h" | 
| #include "ui/gfx/gdi_util.h" | 
| #endif | 
| @@ -212,6 +215,86 @@ void MarkUnchangedTouchPointsAsStationary( | 
| } | 
| } | 
| +#if defined(OS_WIN) | 
| +// This class implements the ui::OnScreenKeyboardObserver interface | 
| +// which provides notifications about the on screen keyboard on Windows getting | 
| +// displayed or hidden in response to taps on editable fields. | 
| +// It provides functionality to request blink to scroll the input field if it | 
| +// is obscured by the on screen keyboard. | 
| +class WinScreenKeyboardObserver : public ui::OnScreenKeyboardObserver { | 
| + public: | 
| + WinScreenKeyboardObserver(RenderWidgetHostImpl* host, | 
| + const gfx::Point& location_dips_screen, | 
| + float scale_factor, | 
| + aura::Window* window) | 
| + : host_(host), | 
| + location_dips_screen_(location_dips_screen), | 
| + device_scale_factor_(scale_factor), | 
| + window_(window) { | 
| + host_->GetView()->SetInsets(gfx::Insets()); | 
| + } | 
| + | 
| + // base::win::OnScreenKeyboardObserver overrides. | 
| + void OnKeyboardVisible(const gfx::Rect& keyboard_rect_pixels) override { | 
| + gfx::Point location_in_pixels = | 
| + gfx::ConvertPointToPixel(device_scale_factor_, location_dips_screen_); | 
| + | 
| + if (keyboard_rect_pixels.Contains(location_in_pixels)) { | 
| + aura::client::ScreenPositionClient* screen_position_client = | 
| + aura::client::GetScreenPositionClient(window_->GetRootWindow()); | 
| + if (!screen_position_client) | 
| + return; | 
| 
sky
2016/05/21 16:04:38
If you early return in this function do you need t
 
ananta
2016/05/23 19:32:07
Reset the view port at the top of this function.
 | 
| + | 
| + DVLOG(1) << "OSK covering focus point."; | 
| + gfx::Rect keyboard_rect_dips = | 
| + gfx::ConvertRectToDIP(device_scale_factor_, keyboard_rect_pixels); | 
| + gfx::Rect bounds_in_screen = window_->GetBoundsInScreen(); | 
| + | 
| + // Set the viewport of the window to be just above the on screen | 
| + // keyboard. | 
| + int viewport_bottom = | 
| + abs(keyboard_rect_dips.y() - bounds_in_screen.bottom()); | 
| 
sky
2016/05/21 16:04:38
Why do you do abs here? Shouldn't bounds_in_screen
 
ananta
2016/05/23 19:32:07
Done.
 
ananta
2016/05/23 19:32:07
Done.
 | 
| + | 
| + // If the viewport is bigger than the view, then we cannot handle it | 
| + // with the current approach. Moving the window above the OSK is one way. | 
| + // That for a later patchset. | 
| + if (viewport_bottom > bounds_in_screen.height()) | 
| + return; | 
| + | 
| + host_->GetView()->SetInsets(gfx::Insets(0, 0, viewport_bottom, 0)); | 
| + | 
| + gfx::Point origin(location_dips_screen_); | 
| + screen_position_client->ConvertPointFromScreen(window_, &origin); | 
| + | 
| + // We want to scroll the node into a rectangle which originates from | 
| + // the touch point and a small offset (10) in either direction. | 
| + gfx::Rect node_rect(origin.x(), origin.y(), 10, 10); | 
| + host_->ScrollFocusedEditableNodeIntoRect(node_rect); | 
| + } else { | 
| + // Restore the viewport. | 
| + host_->GetView()->SetInsets(gfx::Insets()); | 
| + } | 
| + } | 
| + | 
| + void OnKeyboardHidden(const gfx::Rect& keyboard_rect_pixels) override { | 
| + // Restore the viewport. | 
| + host_->GetView()->SetInsets(gfx::Insets()); | 
| + } | 
| + | 
| + private: | 
| + RenderWidgetHostImpl* host_; | 
| + // The location in DIPs where the touch occurred. | 
| + gfx::Point location_dips_screen_; | 
| + // The current device scale factor. | 
| + float device_scale_factor_; | 
| + | 
| + // The content Window. | 
| + aura::Window* window_; | 
| + | 
| + DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver); | 
| +}; | 
| +#endif | 
| + | 
| } // namespace | 
| // We need to watch for mouse events outside a Web Popup or its parent | 
| @@ -383,6 +466,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host, | 
| #if defined(OS_WIN) | 
| legacy_render_widget_host_HWND_(nullptr), | 
| legacy_window_destroyed_(false), | 
| + virtual_keyboard_requested_(false), | 
| #endif | 
| has_snapped_to_boundary_(false), | 
| is_guest_view_hack_(is_guest_view_hack), | 
| @@ -864,6 +948,30 @@ void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) { | 
| } | 
| } | 
| +void RenderWidgetHostViewAura::FocusedNodeTouched( | 
| + const gfx::Point& location_dips_screen, | 
| + bool editable) { | 
| +#if defined(OS_WIN) | 
| + RenderViewHost* rvh = RenderViewHost::From(host_); | 
| + if (rvh && rvh->GetDelegate()) | 
| + rvh->GetDelegate()->SetIsVirtualKeyboardRequested(editable); | 
| + | 
| + ui::OnScreenKeyboardDisplayManager* osk_display_manager = | 
| + ui::OnScreenKeyboardDisplayManager::GetInstance(); | 
| + DCHECK(osk_display_manager); | 
| + if (editable && host_ && host_->GetView()) { | 
| + keyboard_observer_.reset(new WinScreenKeyboardObserver( | 
| + host_, location_dips_screen, device_scale_factor_, | 
| + window_)); | 
| + virtual_keyboard_requested_ = | 
| + osk_display_manager->DisplayVirtualKeyboard(keyboard_observer_.get()); | 
| + } else { | 
| + virtual_keyboard_requested_ = false; | 
| + osk_display_manager->DismissVirtualKeyboard(); | 
| + } | 
| +#endif | 
| +} | 
| + | 
| void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) { | 
| current_cursor_ = cursor; | 
| const display::Display display = | 
| @@ -2003,6 +2111,21 @@ void RenderWidgetHostViewAura::TransformPointToLocalCoordSpace( | 
| gfx::ConvertPointToDIP(device_scale_factor_, *transformed_point); | 
| } | 
| +void RenderWidgetHostViewAura::FocusedNodeChanged(bool editable) { | 
| +#if defined(OS_WIN) | 
| + if (!editable && virtual_keyboard_requested_) { | 
| + virtual_keyboard_requested_ = false; | 
| + | 
| + RenderViewHost* rvh = RenderViewHost::From(host_); | 
| + if (rvh && rvh->GetDelegate()) | 
| + rvh->GetDelegate()->SetIsVirtualKeyboardRequested(false); | 
| + | 
| + DCHECK(ui::OnScreenKeyboardDisplayManager::GetInstance()); | 
| + ui::OnScreenKeyboardDisplayManager::GetInstance()->DismissVirtualKeyboard(); | 
| + } | 
| +#endif | 
| +} | 
| + | 
| void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { | 
| TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent"); | 
| @@ -2286,6 +2409,14 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() { | 
| // RenderWidgetHostViewAura::OnWindowDestroying and the pointer should | 
| // be set to NULL. | 
| DCHECK(!legacy_render_widget_host_HWND_); | 
| + if (virtual_keyboard_requested_) { | 
| + DCHECK(keyboard_observer_.get()); | 
| + ui::OnScreenKeyboardDisplayManager* osk_display_manager = | 
| + ui::OnScreenKeyboardDisplayManager::GetInstance(); | 
| + DCHECK(osk_display_manager); | 
| + osk_display_manager->RemoveObserver(keyboard_observer_.get()); | 
| + } | 
| + | 
| #endif | 
| } |