Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1645)

Unified Diff: content/browser/renderer_host/render_widget_host_view_aura.cc

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
Patch Set: Update comment Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..cb1f6277cce16ffee5724a1869bfdba6c7625394 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,101 @@ void MarkUnchangedTouchPointsAsStationary(
}
}
+#if defined(OS_WIN)
+const int kVirtualKeyboardDisplayWaitTimeoutMs = 100;
+const int kMaxVirtualKeyboardDisplayRetries = 5;
+
+// Using a static variable here to detect retries could cause issues in cases
+// like the virtual keyboard getting displayed in multiple tabs/windows. The
+// attempts to dismiss the virtual keyboard in these tabs/windows would result
+// in the retry counter getting overwritten incorrectly thus leading to issues.
+// TODO(ananta)
+// Come up with a better approach to handle this.
+void DismissVirtualKeyboardTask() {
+ static int virtual_keyboard_display_retries = 0;
+ // If the virtual keyboard is not yet visible, then we execute the task again
+ // waiting for it to show up.
+ if (!ui::DismissVirtualKeyboard()) {
+ if (virtual_keyboard_display_retries < kMaxVirtualKeyboardDisplayRetries) {
+ BrowserThread::PostDelayedTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(base::IgnoreResult(&DismissVirtualKeyboardTask)),
ncarter (slow) 2016/05/19 21:46:16 nit: can drop the IgnoreResult here too.
ananta 2016/05/19 22:00:56 Done.
+ base::TimeDelta::FromMilliseconds(
+ kVirtualKeyboardDisplayWaitTimeoutMs));
+ ++virtual_keyboard_display_retries;
+ } else {
+ virtual_keyboard_display_retries = 0;
+ }
+ }
+}
+
+// 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:
+ explicit WinScreenKeyboardObserver(RenderWidgetHostImpl* host,
+ const gfx::Point& location_dips,
+ float scale_factor)
+ : host_(host),
+ location_in_dips_(location_dips),
+ device_scale_factor_(scale_factor) {
+ if (host_ && host_->GetView())
+ host_->GetView()->SetInsets(gfx::Insets());
+ }
+
+ // base::win::OnScreenKeyboardObserver overrides.
+ void OnKeyboardVisible(const gfx::Rect& keyboard_rect_dips) override {
+ DCHECK(host_);
+
+ if (host_ && host_->GetView()) {
+ // We use the PtInRect API to determine if the touch occurred in the
+ // bounds of the OSK.
+ // The API expects the point and the rectangle in pixels.
+ gfx::Rect keyboard_rect_pixels =
+ gfx::ConvertRectToPixel(device_scale_factor_, keyboard_rect_dips);
+ RECT keyboard_rect_windows = keyboard_rect_pixels.ToRECT();
+
+ gfx::Point location_in_pixels =
+ gfx::ConvertPointToPixel(device_scale_factor_, location_in_dips_);
+ POINT touch_location = location_in_pixels.ToPOINT();
+
+ if (::PtInRect(&keyboard_rect_windows, touch_location)) {
+ DVLOG(1) << "OSK covering focus point.";
+ // Get the intersection of the view rectangle and the OSK.
+ // The viewport needs to be moved up by the height of the intersection.
+ gfx::Rect screen_rect = host_->GetView()->GetBoundsInRootWindow();
+ gfx::Rect intersect =
+ gfx::IntersectRects(keyboard_rect_dips, screen_rect);
+ host_->GetView()->SetInsets(gfx::Insets(0, 0, intersect.height(), 0));
+ host_->ScrollFocusedEditableNodeIntoRect(intersect);
+ } else {
+ // Restore the viewport.
+ host_->GetView()->SetInsets(gfx::Insets());
+ }
+ }
+ }
+
+ void OnKeyboardHidden(const gfx::Rect& keyboard_rect_dips) override {
+ DCHECK(host_);
+ // Restore the viewport.
+ if (host_ && host_->GetView())
+ host_->GetView()->SetInsets(gfx::Insets());
+ }
+
+ private:
+ RenderWidgetHostImpl* host_;
+ // The location in DIPs where the touch occurred.
+ gfx::Point location_in_dips_;
+ // The current device scale factor.
+ float device_scale_factor_;
+
+ DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver);
+};
+#endif
+
} // namespace
// We need to watch for mouse events outside a Web Popup or its parent
@@ -383,6 +481,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 +963,29 @@ void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
}
}
+void RenderWidgetHostViewAura::FocusedNodeTouched(
+ const gfx::Point& location_dips,
+ 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) {
+ keyboard_observer_.reset(new WinScreenKeyboardObserver(
+ host_, location_dips, device_scale_factor_));
+ 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 +2125,23 @@ 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);
+
+ BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&DismissVirtualKeyboardTask),
+ base::TimeDelta::FromMilliseconds(
+ kVirtualKeyboardDisplayWaitTimeoutMs));
+ }
+#endif
+}
+
void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");

Powered by Google App Engine
This is Rietveld 408576698