input_method_surface.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/exo/input_method_surface.h"
  5. #include "ash/public/cpp/shell_window_ids.h"
  6. #include "components/exo/input_method_surface_manager.h"
  7. #include "components/exo/wm_helper.h"
  8. #include "ui/base/class_property.h"
  9. #include "ui/gfx/geometry/dip_util.h"
  10. #include "ui/gfx/geometry/rect.h"
  11. #include "ui/gfx/geometry/rect_conversions.h"
  12. #include "ui/views/accessibility/view_accessibility.h"
  13. DEFINE_UI_CLASS_PROPERTY_KEY(exo::InputMethodSurface*,
  14. kInputMethodSurface,
  15. nullptr)
  16. DEFINE_UI_CLASS_PROPERTY_TYPE(exo::InputMethodSurface*)
  17. namespace exo {
  18. InputMethodSurface::InputMethodSurface(InputMethodSurfaceManager* manager,
  19. Surface* surface,
  20. bool default_scale_cancellation)
  21. : ClientControlledShellSurface(
  22. surface,
  23. true /* can_minimize */,
  24. ash::kShellWindowId_ArcVirtualKeyboardContainer,
  25. default_scale_cancellation),
  26. manager_(manager),
  27. input_method_bounds_() {
  28. host_window()->SetName("ExoInputMethodSurface");
  29. host_window()->SetProperty(kInputMethodSurface, this);
  30. }
  31. InputMethodSurface::~InputMethodSurface() {
  32. if (added_to_manager_)
  33. manager_->RemoveSurface(this);
  34. }
  35. exo::InputMethodSurface* InputMethodSurface::GetInputMethodSurface() {
  36. WMHelper* wm_helper = exo::WMHelper::GetInstance();
  37. if (!wm_helper)
  38. return nullptr;
  39. aura::Window* container = wm_helper->GetPrimaryDisplayContainer(
  40. ash::kShellWindowId_ArcVirtualKeyboardContainer);
  41. if (!container)
  42. return nullptr;
  43. // Host window of InputMethodSurface is grandchild of the container.
  44. if (container->children().empty())
  45. return nullptr;
  46. aura::Window* child = container->children().at(0);
  47. if (child->children().empty())
  48. return nullptr;
  49. aura::Window* host_window = child->children().at(0);
  50. return host_window->GetProperty(kInputMethodSurface);
  51. }
  52. void InputMethodSurface::OnSurfaceCommit() {
  53. ClientControlledShellSurface::OnSurfaceCommit();
  54. if (!added_to_manager_) {
  55. added_to_manager_ = true;
  56. manager_->AddSurface(this);
  57. }
  58. gfx::RectF new_bounds_in_dips = gfx::ConvertRectToDips(
  59. root_surface()->hit_test_region().bounds(), GetScale());
  60. // TODO(crbug.com/1131682): We should avoid dropping precision to integers
  61. // here if we want to know the true rectangle bounds in DIPs. If not, we
  62. // should use ToEnclosingRect() if we want to include DIPs that partly overlap
  63. // the physical pixel bounds, or ToEnclosedRect() if we do not.
  64. gfx::Rect int_bounds_in_dips =
  65. gfx::ToFlooredRectDeprecated(new_bounds_in_dips);
  66. if (input_method_bounds_ != int_bounds_in_dips) {
  67. input_method_bounds_ = int_bounds_in_dips;
  68. manager_->OnTouchableBoundsChanged(this);
  69. GetViewAccessibility().OverrideBounds(gfx::RectF(input_method_bounds_));
  70. }
  71. }
  72. void InputMethodSurface::SetWidgetBounds(const gfx::Rect& bounds,
  73. bool adjusted_by_server) {
  74. if (bounds == widget_->GetWindowBoundsInScreen())
  75. return;
  76. widget_->SetBounds(bounds);
  77. UpdateSurfaceBounds();
  78. // Bounds change requests will be ignored in client side.
  79. }
  80. gfx::Rect InputMethodSurface::GetBounds() const {
  81. return input_method_bounds_;
  82. }
  83. } // namespace exo