diff options
Diffstat (limited to 'chromium/ui/aura')
18 files changed, 360 insertions, 89 deletions
diff --git a/chromium/ui/aura/client/aura_constants.cc b/chromium/ui/aura/client/aura_constants.cc index bea5795840b..409191bb33f 100644 --- a/chromium/ui/aura/client/aura_constants.cc +++ b/chromium/ui/aura/client/aura_constants.cc @@ -68,18 +68,14 @@ DEFINE_UI_CLASS_PROPERTY_KEY(gfx::NativeViewAccessible, kParentNativeViewAccessibleKey, nullptr) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Size, kPreferredSize, nullptr) -DEFINE_UI_CLASS_PROPERTY_KEY(ui::WindowShowState, - kPreMinimizedShowStateKey, - ui::SHOW_STATE_DEFAULT) -DEFINE_UI_CLASS_PROPERTY_KEY(ui::WindowShowState, - kPreFullscreenShowStateKey, - ui::SHOW_STATE_DEFAULT) DEFINE_UI_CLASS_PROPERTY_KEY(int, kResizeBehaviorKey, kResizeBehaviorCanResize) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr) DEFINE_UI_CLASS_PROPERTY_KEY(ui::WindowShowState, kShowStateKey, ui::SHOW_STATE_DEFAULT) -DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIsRestoringKey, false) +DEFINE_UI_CLASS_PROPERTY_KEY(ui::WindowShowState, + kRestoreShowStateKey, + ui::SHOW_STATE_NORMAL) DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSkipImeProcessing, false) DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(std::u16string, kTitleKey, nullptr) DEFINE_UI_CLASS_PROPERTY_KEY(int, kTopViewInset, 0) diff --git a/chromium/ui/aura/client/aura_constants.h b/chromium/ui/aura/client/aura_constants.h index 932f1685620..abf3c63e895 100644 --- a/chromium/ui/aura/client/aura_constants.h +++ b/chromium/ui/aura/client/aura_constants.h @@ -135,18 +135,6 @@ AURA_EXPORT extern const aura::WindowProperty<gfx::NativeViewAccessible>* const // A property key to store the preferred size of the window. AURA_EXPORT extern const WindowProperty<gfx::Size*>* const kPreferredSize; -// A property key to store ui::WindowShowState for restoring a window from -// minimized show state. -// Used in Ash to remember the show state before the window was minimized. -AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const - kPreMinimizedShowStateKey; - -// A property key to store ui::WindowShowState for restoring a window from -// fullscreen show state. -// Used in Ash to remember the show state before the window was fullscreen. -AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const - kPreFullscreenShowStateKey; - // A property key to store the resize behavior, which is a bitmask of the // ResizeBehavior values. AURA_EXPORT extern const WindowProperty<int>* const kResizeBehaviorKey; @@ -160,14 +148,10 @@ AURA_EXPORT extern const WindowProperty<gfx::Rect*>* const kRestoreBoundsKey; AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const kShowStateKey; -// A property key to indicate if a window is currently being restored. Normally -// restoring a window equals to changing window's state to normal window state. -// This property will be used in ash to decide if we should use window state -// restore stack to decide which window state the window should restore back to, -// and it's not unnecessarily always the normal window state. As an example, -// unminimizing a window will restore the window back to its pre-minimized -// window state. -AURA_EXPORT extern const WindowProperty<bool>* const kIsRestoringKey; +// A property key to store ui::WindowShowState for a window to restore back to +// from the current window show state. +AURA_EXPORT extern const WindowProperty<ui::WindowShowState>* const + kRestoreShowStateKey; // A property key to store key event dispatch policy. The default value is // false, which means IME receives a key event in PREDISPATCH phace before a diff --git a/chromium/ui/aura/client/drag_drop_delegate.h b/chromium/ui/aura/client/drag_drop_delegate.h index fca177a2e60..d35f58e0463 100644 --- a/chromium/ui/aura/client/drag_drop_delegate.h +++ b/chromium/ui/aura/client/drag_drop_delegate.h @@ -48,8 +48,7 @@ class AURA_EXPORT DragDropDelegate { // OnDragEntered is invoked when the mouse enters this window during a drag & // drop session. This is immediately followed by an invocation of - // OnDragUpdated, and eventually one of OnDragExited, OnPerformDrop, or - // GetDropCallback. + // OnDragUpdated, and eventually one of OnDragExited, or GetDropCallback. virtual void OnDragEntered(const ui::DropTargetEvent& event) = 0; // Invoked during a drag and drop session while the mouse is over the window. diff --git a/chromium/ui/aura/cursor/BUILD.gn b/chromium/ui/aura/cursor/BUILD.gn index 57683e9616c..41b7004c087 100644 --- a/chromium/ui/aura/cursor/BUILD.gn +++ b/chromium/ui/aura/cursor/BUILD.gn @@ -42,8 +42,11 @@ source_set("unittests") { "//skia", "//testing/gtest", "//ui/aura:test_support", + "//ui/base", "//ui/base/cursor", "//ui/base/cursor/mojom:cursor_type", + "//ui/gfx:gfx_skia", "//ui/gfx/geometry", ] + data_deps = [ "//ui/resources:ui_test_pak_data" ] } diff --git a/chromium/ui/aura/cursor/cursor_loader_unittest.cc b/chromium/ui/aura/cursor/cursor_loader_unittest.cc index d939ac5cb83..64529c0033d 100644 --- a/chromium/ui/aura/cursor/cursor_loader_unittest.cc +++ b/chromium/ui/aura/cursor/cursor_loader_unittest.cc @@ -4,21 +4,36 @@ #include "ui/aura/cursor/cursor_loader.h" +#include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" +#include "base/path_service.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/aura/cursor/cursor_lookup.h" +#include "ui/aura/cursor/cursors_aura.h" #include "ui/aura/test/aura_test_base.h" #include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor_factory.h" #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" #include "ui/base/cursor/platform_cursor.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_paths.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/skia_util.h" namespace aura { namespace { -using CursorLoaderTest = ::aura::test::AuraTestBase; +using CursorLoaderTest = test::AuraTestBase; using ::ui::mojom::CursorType; +SkBitmap GetTestBitmap() { + SkBitmap bitmap; + bitmap.allocN32Pixels(10, 10); + return bitmap; +} + } // namespace TEST_F(CursorLoaderTest, InvisibleCursor) { @@ -26,9 +41,39 @@ TEST_F(CursorLoaderTest, InvisibleCursor) { ui::Cursor invisible_cursor(CursorType::kNone); cursor_loader.SetPlatformCursor(&invisible_cursor); - ASSERT_EQ( + EXPECT_EQ( invisible_cursor.platform(), ui::CursorFactory::GetInstance()->GetDefaultCursor(CursorType::kNone)); } +// TODO(https://crbug.com/1270302): although this is testing `GetCursorBitmap` +// from cursor_lookup.h, that will be replaced by a method of the same name in +// CursorLoader. +TEST_F(CursorLoaderTest, GetCursorData) { + ui::RegisterPathProvider(); + base::FilePath ui_test_pak_path = + base::PathService::CheckedGet(ui::UI_TEST_PAK); + ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path); + + const ui::Cursor invisible_cursor = CursorType::kNone; + EXPECT_TRUE(GetCursorBitmap(invisible_cursor).isNull()); + EXPECT_TRUE(GetCursorHotspot(invisible_cursor).IsOrigin()); + + const ui::Cursor pointer_cursor = CursorType::kPointer; + EXPECT_FALSE(GetCursorBitmap(pointer_cursor).isNull()); + EXPECT_TRUE(gfx::BitmapsAreEqual(GetCursorBitmap(pointer_cursor), + GetDefaultBitmap(pointer_cursor))); + EXPECT_EQ(GetCursorHotspot(pointer_cursor), + GetDefaultHotspot(pointer_cursor)); + + ui::Cursor custom_cursor(CursorType::kCustom); + const SkBitmap kBitmap = GetTestBitmap(); + constexpr gfx::Point kHotspot = gfx::Point(10, 10); + custom_cursor.set_custom_bitmap(kBitmap); + custom_cursor.set_custom_hotspot(kHotspot); + EXPECT_EQ(GetCursorBitmap(custom_cursor).getGenerationID(), + kBitmap.getGenerationID()); + EXPECT_EQ(GetCursorHotspot(custom_cursor), kHotspot); +} + } // namespace aura diff --git a/chromium/ui/aura/cursor/cursors_aura.h b/chromium/ui/aura/cursor/cursors_aura.h index 020a43ae09a..3a13dcdc887 100644 --- a/chromium/ui/aura/cursor/cursors_aura.h +++ b/chromium/ui/aura/cursor/cursors_aura.h @@ -32,8 +32,10 @@ bool GetCursorDataFor(ui::CursorSize cursor_size, int* resource_id, gfx::Point* point); +COMPONENT_EXPORT(UI_AURA_CURSOR) SkBitmap GetDefaultBitmap(const ui::Cursor& cursor); +COMPONENT_EXPORT(UI_AURA_CURSOR) gfx::Point GetDefaultHotspot(const ui::Cursor& cursor); } // namespace aura diff --git a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc index 8f728b81c73..17600f796b0 100644 --- a/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc +++ b/chromium/ui/aura/gestures/gesture_recognizer_unittest.cc @@ -4806,5 +4806,42 @@ TEST_F(GestureRecognizerTest, GestureConsumerCleanupBeforeTouchAck) { EXPECT_0_EVENTS(delegate->events()); } +// Verifies that destructing a `GestureRecognizerImpl` instance with gesture +// providers works as expected (https://crbug.com/1325256). +TEST_F(GestureRecognizerTest, ResetGestureRecognizerWithGestureProvider) { + TimedEvents tes; + const int kTouchId = 4; + std::unique_ptr<GestureEventConsumeDelegate> delegate( + new GestureEventConsumeDelegate()); + std::unique_ptr<aura::Window> window(CreateTestWindowWithDelegate( + delegate.get(), /*id=*/-2345, /*bounds=*/gfx::Rect(0, 0, 50, 50), + /*parent=*/root_window())); + + // Touch press then release on `window`. + constexpr gfx::Point touch_location(/*x=*/10, /*y=*/20); + ui::TouchEvent press( + ui::ET_TOUCH_PRESSED, touch_location, /*time_stamp=*/tes.Now(), + ui::PointerDetails(ui::EventPointerType::kTouch, kTouchId)); + delegate->Reset(); + DispatchEventUsingWindowDispatcher(&press); + EXPECT_TRUE(delegate->tap_down()); + delegate->Reset(); + ui::TouchEvent release( + ui::ET_TOUCH_RELEASED, touch_location, + /*time_stamp=*/press.time_stamp() + base::Milliseconds(50), + ui::PointerDetails(ui::EventPointerType::kTouch, kTouchId)); + DispatchEventUsingWindowDispatcher(&release); + EXPECT_FALSE(delegate->tap_down()); + + // Check that the gesture recognizer owns one gesture provider. + EXPECT_EQ(1u, static_cast<ui::GestureRecognizerImpl*>( + aura::Env::GetInstance()->gesture_recognizer()) + ->consumer_gesture_provider_.size()); + + // Destroy the current gesture recognizer. + aura::Env::GetInstance()->SetGestureRecognizer( + std::make_unique<ui::GestureRecognizerImpl>()); +} + } // namespace test } // namespace aura diff --git a/chromium/ui/aura/native_window_occlusion_tracker.cc b/chromium/ui/aura/native_window_occlusion_tracker.cc index 4d7091142a5..74ad6b56d0c 100644 --- a/chromium/ui/aura/native_window_occlusion_tracker.cc +++ b/chromium/ui/aura/native_window_occlusion_tracker.cc @@ -39,6 +39,7 @@ void NativeWindowOcclusionTracker::DisableNativeWindowOcclusionTracking( #if BUILDFLAG(IS_WIN) if (host->IsNativeWindowOcclusionEnabled()) { host->SetNativeWindowOcclusionState(Window::OcclusionState::UNKNOWN, {}); + host->set_on_current_workspace(absl::nullopt); NativeWindowOcclusionTrackerWin::GetOrCreateInstance()->Disable( host->window()); } diff --git a/chromium/ui/aura/native_window_occlusion_tracker_win.cc b/chromium/ui/aura/native_window_occlusion_tracker_win.cc index f0d96bbbcd6..01d9ccbca25 100644 --- a/chromium/ui/aura/native_window_occlusion_tracker_win.cc +++ b/chromium/ui/aura/native_window_occlusion_tracker_win.cc @@ -315,6 +315,8 @@ void NativeWindowOcclusionTrackerWin::UpdateOcclusionState( // The window was destroyed while processing occlusion. if (it == hwnd_root_window_map_.end()) continue; + it->second->GetHost()->set_on_current_workspace( + root_window_pair.second.on_current_workspace); // Check Window::IsVisible here, on the UI thread, because it can't be // checked on the occlusion calculation thread. Do this first before // checking screen_locked_ or display_on_ so that hidden windows remain @@ -584,11 +586,13 @@ void NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator:: // Reset RootOcclusionState to a clean state. root_window_pair.second = {}; + root_window_pair.second.on_current_workspace = + IsWindowOnCurrentVirtualDesktop(hwnd); // IsIconic() checks for a minimized window. Immediately set the state of // minimized windows to HIDDEN. if (IsIconic(hwnd)) { root_window_pair.second.occlusion_state = Window::OcclusionState::HIDDEN; - } else if (IsWindowOnCurrentVirtualDesktop(hwnd) == false) { + } else if (root_window_pair.second.on_current_workspace == false) { // If window is not on the current virtual desktop, immediately // set the state of the window to OCCLUDED. root_window_pair.second.occlusion_state = diff --git a/chromium/ui/aura/native_window_occlusion_tracker_win.h b/chromium/ui/aura/native_window_occlusion_tracker_win.h index 7e47a6630d8..d6a1789d7b0 100644 --- a/chromium/ui/aura/native_window_occlusion_tracker_win.h +++ b/chromium/ui/aura/native_window_occlusion_tracker_win.h @@ -20,6 +20,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" #include "base/timer/timer.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/aura/aura_export.h" #include "ui/aura/window.h" @@ -75,7 +76,7 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin // Tracks the occlusion state of HWNDs registered via Enable(). struct RootOcclusionState { Window::OcclusionState occlusion_state = Window::OcclusionState::UNKNOWN; - + absl::optional<bool> on_current_workspace; // If `occlusion_state` is VISIBLE, this gives the occluded region. It may // be empty (which indicates the the window is entirely visible). This is // relative to the origin of the HWND. In other words, it's in window diff --git a/chromium/ui/aura/screen_ozone.cc b/chromium/ui/aura/screen_ozone.cc index d133110c30a..a78a6a48f1d 100644 --- a/chromium/ui/aura/screen_ozone.cc +++ b/chromium/ui/aura/screen_ozone.cc @@ -13,10 +13,13 @@ namespace aura { -ScreenOzone::ScreenOzone() = default; +ScreenOzone::ScreenOzone() { + DCHECK(!display::Screen::HasScreen()); + display::Screen::SetScreenInstance(this); +} ScreenOzone::~ScreenOzone() { - display::Screen::SetScreenInstance(old_screen_); + display::Screen::SetScreenInstance(nullptr); } void ScreenOzone::Initialize() { @@ -34,6 +37,11 @@ void ScreenOzone::Initialize() { } } +// static +bool ScreenOzone::IsOzoneInitialized() { + return ui::OzonePlatform::IsInitialized(); +} + gfx::Point ScreenOzone::GetCursorScreenPoint() { return platform_screen_->GetCursorScreenPoint(); } @@ -149,4 +157,17 @@ gfx::AcceleratedWidget ScreenOzone::GetAcceleratedWidgetForWindow( void ScreenOzone::OnBeforePlatformScreenInit() {} +ScopedScreenOzone::ScopedScreenOzone(const base::Location& location) + : ScopedNativeScreen(/*call_maybe_init=*/false, location) { + MaybeInit(); +} + +ScopedScreenOzone::~ScopedScreenOzone() = default; + +display::Screen* ScopedScreenOzone::CreateScreen() { + auto* screen = new ScreenOzone(); + screen->Initialize(); + return screen; +} + } // namespace aura diff --git a/chromium/ui/aura/screen_ozone.h b/chromium/ui/aura/screen_ozone.h index 7a55866c762..2970a0e0e7d 100644 --- a/chromium/ui/aura/screen_ozone.h +++ b/chromium/ui/aura/screen_ozone.h @@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "build/chromeos_buildflags.h" #include "ui/aura/aura_export.h" #include "ui/display/screen.h" @@ -59,6 +60,8 @@ class AURA_EXPORT ScreenOzone : public display::Screen { virtual gfx::NativeWindow GetNativeWindowFromAcceleratedWidget( gfx::AcceleratedWidget widget) const; + static bool IsOzoneInitialized(); + protected: ui::PlatformScreen* platform_screen() { return platform_screen_.get(); } @@ -72,10 +75,22 @@ class AURA_EXPORT ScreenOzone : public display::Screen { virtual void OnBeforePlatformScreenInit(); - display::Screen* const old_screen_ = display::Screen::SetScreenInstance(this); std::unique_ptr<ui::PlatformScreen> platform_screen_; }; +// ScopedScreenOzone creates a ScreenOzone instead of NativeScreen +// (created by `CreateNativeScreen()`) if the screen hasn't been set. +class AURA_EXPORT ScopedScreenOzone : public display::ScopedNativeScreen { + public: + explicit ScopedScreenOzone(const base::Location& location = FROM_HERE); + ScopedScreenOzone(const ScopedScreenOzone&) = delete; + ScopedScreenOzone operator=(const ScopedScreenOzone&) = delete; + ~ScopedScreenOzone() override; + + private: + display::Screen* CreateScreen() override; +}; + } // namespace aura #endif // UI_AURA_SCREEN_OZONE_H_ diff --git a/chromium/ui/aura/window_tree_host.cc b/chromium/ui/aura/window_tree_host.cc index dac4faec0c1..618560b574a 100644 --- a/chromium/ui/aura/window_tree_host.cc +++ b/chromium/ui/aura/window_tree_host.cc @@ -193,7 +193,7 @@ void WindowTreeHost::InitHost() { display::Screen::GetScreen()->GetDisplayNearestWindow(window()); device_scale_factor_ = display.device_scale_factor(); - UpdateRootWindowSizeInPixels(); + UpdateRootWindowSize(); InitCompositor(); Env::GetInstance()->NotifyHostInitialized(this); } @@ -223,7 +223,7 @@ gfx::Transform WindowTreeHost::GetRootTransform() const { void WindowTreeHost::SetRootTransform(const gfx::Transform& transform) { window()->SetTransform(transform); - UpdateRootWindowSizeInPixels(); + UpdateRootWindowSize(); } gfx::Transform WindowTreeHost::GetInverseRootTransform() const { @@ -256,16 +256,6 @@ gfx::Transform WindowTreeHost::GetInverseRootTransformForLocalEventCoordinates() return invert; } -void WindowTreeHost::UpdateRootWindowSizeInPixels() { - // Validate that the LocalSurfaceId does not change. - bool compositor_inited = !!compositor()->root_layer(); - ScopedLocalSurfaceIdValidator lsi_validator(compositor_inited ? window() - : nullptr); - gfx::Rect transformed_bounds_in_pixels = - GetTransformedRootWindowBoundsInPixels(GetBoundsInPixels().size()); - window()->SetBounds(transformed_bounds_in_pixels); -} - void WindowTreeHost::UpdateCompositorScaleAndSize( const gfx::Size& new_size_in_pixels) { gfx::Rect new_bounds(new_size_in_pixels); @@ -296,15 +286,23 @@ void WindowTreeHost::ConvertScreenInPixelsToDIP(gfx::Point* point) const { } void WindowTreeHost::ConvertDIPToPixels(gfx::Point* point) const { - auto point_3f = gfx::Point3F(gfx::PointF(*point)); - GetRootTransform().TransformPoint(&point_3f); - *point = gfx::ToFlooredPoint(point_3f.AsPointF()); + gfx::PointF point_f{*point}; + ConvertDIPToPixels(&point_f); + *point = gfx::ToFlooredPoint(point_f); +} + +void WindowTreeHost::ConvertDIPToPixels(gfx::PointF* point) const { + GetRootTransform().TransformPoint(point); } void WindowTreeHost::ConvertPixelsToDIP(gfx::Point* point) const { - auto point_3f = gfx::Point3F(gfx::PointF(*point)); - GetInverseRootTransform().TransformPoint(&point_3f); - *point = gfx::ToFlooredPoint(point_3f.AsPointF()); + gfx::PointF point_f{*point}; + ConvertPixelsToDIP(&point_f); + *point = gfx::ToFlooredPoint(point_f); +} + +void WindowTreeHost::ConvertPixelsToDIP(gfx::PointF* point) const { + GetInverseRootTransform().TransformPoint(point); } void WindowTreeHost::SetCursor(gfx::NativeCursor cursor) { @@ -401,6 +399,13 @@ void WindowTreeHost::Hide() { OnAcceleratedWidgetMadeVisible(false); } +gfx::Rect WindowTreeHost::GetBoundsInDIP() const { + aura::Window* root_window = const_cast<aura::Window*>(window()); + display::Screen* screen = display::Screen::GetScreen(); + gfx::Rect screen_bounds = GetBoundsInPixels(); + return screen->ScreenToDIPRectInWindow(root_window, screen_bounds); +} + gfx::Rect WindowTreeHost::GetBoundsInAcceleratedWidgetPixelCoordinates() { return gfx::Rect(GetBoundsInPixels().size()); } @@ -455,6 +460,19 @@ void WindowTreeHost::SetNativeWindowOcclusionState( observer.OnOcclusionStateChanged(this, state, occluded_region); } +void WindowTreeHost::UpdateRootWindowSize() { + // Validate that the LocalSurfaceId does not change. + bool compositor_inited = !!compositor()->root_layer(); + ScopedLocalSurfaceIdValidator lsi_validator(compositor_inited ? window() + : nullptr); + window()->SetBounds(CalculateRootWindowBounds()); +} + +gfx::Rect WindowTreeHost::CalculateRootWindowBounds() const { + return GetTransformedRootWindowBoundsFromPixelSize( + GetBoundsInPixels().size()); +} + std::unique_ptr<ScopedEnableUnadjustedMouseEvents> WindowTreeHost::RequestUnadjustedMovement() { NOTIMPLEMENTED(); @@ -524,11 +542,6 @@ WindowTreeHost::WindowTreeHost(std::unique_ptr<Window> window) #endif } -void WindowTreeHost::IntializeDeviceScaleFactor(float device_scale_factor) { - DCHECK(!compositor_->root_layer()) << "Only call this before InitHost()"; - device_scale_factor_ = device_scale_factor; -} - void WindowTreeHost::UpdateCompositorVisibility(bool visible) { if (!compositor()) return; @@ -589,7 +602,7 @@ void WindowTreeHost::DestroyDispatcher() { // ~Window, but by that time any calls to virtual methods overriden here (such // as GetRootWindow()) result in Window's implementation. By destroying here // we ensure GetRootWindow() still returns this. - //window()->RemoveOrDestroyChildren(); + // window()->RemoveOrDestroyChildren(); } void WindowTreeHost::OnAcceleratedWidgetMadeVisible(bool value) { @@ -671,7 +684,7 @@ void WindowTreeHost::OnHostResizedInPixels( if (display.is_valid()) device_scale_factor_ = display.device_scale_factor(); - UpdateRootWindowSizeInPixels(); + UpdateRootWindowSize(); // Passing |new_size_in_pixels| to set compositor size. It could be different // from GetBoundsInPixels() on Windows to contain extra space for window @@ -729,7 +742,7 @@ void WindowTreeHost::OnDisplayMetricsChanged(const display::Display& display, #endif } -gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsInPixels( +gfx::Rect WindowTreeHost::GetTransformedRootWindowBoundsFromPixelSize( const gfx::Size& size_in_pixels) const { gfx::RectF new_bounds = gfx::RectF(gfx::Rect(size_in_pixels)); GetInverseRootTransform().TransformRect(&new_bounds); diff --git a/chromium/ui/aura/window_tree_host.h b/chromium/ui/aura/window_tree_host.h index c2303641dc6..2e1ffa04104 100644 --- a/chromium/ui/aura/window_tree_host.h +++ b/chromium/ui/aura/window_tree_host.h @@ -35,7 +35,7 @@ class Point; class Rect; class Size; class Transform; -} +} // namespace gfx namespace ui { class Compositor; @@ -44,7 +44,7 @@ class EventSink; class InputMethod; class ViewProp; struct PlatformWindowInitProperties; -} +} // namespace ui namespace viz { class FrameSinkId; @@ -131,13 +131,6 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, virtual gfx::Transform GetInverseRootTransformForLocalEventCoordinates() const; - // Updates the root window's size using |host_size_in_pixels|, current - // transform and outsets. - // TODO(ccameron): Make this function no longer public. The interaction - // between this call, GetBounds, and OnHostResizedInPixels is ambiguous and - // allows for inconsistencies. - void UpdateRootWindowSizeInPixels(); - // Updates the compositor's size and scale from |new_size_in_pixels|, // |device_scale_factor_| and the compositor's transform hint. void UpdateCompositorScaleAndSize(const gfx::Size& new_size_in_pixels); @@ -151,11 +144,13 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, // Converts |point| from the root window's coordinate system to the // host window's. - virtual void ConvertDIPToPixels(gfx::Point* point) const; + void ConvertDIPToPixels(gfx::Point* point) const; + virtual void ConvertDIPToPixels(gfx::PointF* point) const; // Converts |point| from the host window's coordinate system to the // root window's. - virtual void ConvertPixelsToDIP(gfx::Point* point) const; + void ConvertPixelsToDIP(gfx::Point* point) const; + virtual void ConvertPixelsToDIP(gfx::PointF* point) const; // Sets the currently-displayed cursor. If the cursor was previously hidden // via ShowCursor(false), it will remain hidden until ShowCursor(true) is @@ -230,6 +225,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, virtual void SetBoundsInPixels(const gfx::Rect& bounds_in_pixels) = 0; virtual gfx::Rect GetBoundsInPixels() const = 0; + // Gets the bounds in DIP. + virtual gfx::Rect GetBoundsInDIP() const; + // Returns the bounds relative to the accelerated widget. In the typical case, // the origin is 0,0 and the size is the same as the pixel-bounds. On some // OSs the bounds may be inset (on Windows, this is referred to as the client @@ -297,16 +295,26 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, bool holding_pointer_moves() const { return holding_pointer_moves_; } +#if BUILDFLAG(IS_WIN) + // Returns whether a host's window is on the current workspace or not, + // absl::nullopt if the state is not known. + absl::optional<bool> on_current_workspace() const { + return on_current_workspace_; + }; + + // Determining if a host's window is on the current workspace can be very + // expensive COM call on Windows, so this caches that information. + void set_on_current_workspace(absl::optional<bool> on_current_workspace) { + on_current_workspace_ = on_current_workspace; + } +#endif // BUILDFLAG_(IS_WIN) + protected: friend class ScopedKeyboardHook; friend class TestScreen; // TODO(beng): see if we can remove/consolidate. explicit WindowTreeHost(std::unique_ptr<Window> window = nullptr); - // Set the cached display device scale factor. This should only be called - // during subclass initialization, when the value is needed before InitHost(). - void IntializeDeviceScaleFactor(float device_scale_factor); - // All calls to changing the visibility of the Compositor funnel into this. // In addition to changing the visibility this may also evict the root frame. void UpdateCompositorVisibility(bool visible); @@ -371,7 +379,8 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, // True if |dom_code| is reserved for an active KeyboardLock request. virtual bool IsKeyLocked(ui::DomCode dom_code) = 0; - virtual gfx::Rect GetTransformedRootWindowBoundsInPixels( + // Return root window size computed from given pixel size. + virtual gfx::Rect GetTransformedRootWindowBoundsFromPixelSize( const gfx::Size& size_in_pixels) const; const base::ObserverList<WindowTreeHostObserver>::Unchecked& observers() @@ -382,6 +391,12 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, // Called to enabled/disable native window occlusion calculation. void SetNativeWindowOcclusionEnabled(bool enable); + // Updates the root window's size after WindowTreeHost's property changed. + void UpdateRootWindowSize(); + + // Calculates the root window bounds to be used by UpdateRootwindowSize(). + virtual gfx::Rect CalculateRootWindowBounds() const; + private: class HideHelper; @@ -434,6 +449,12 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, // Keeps track of the occlusion state of the host, and used to send // notifications to observers when it changes. Window::OcclusionState occlusion_state_ = Window::OcclusionState::UNKNOWN; + + // This is set if we know whether the window is on the current workspace. + // This is useful on Windows, where a COM call is required to determine this, + // which can block the UI. The native window occlusion tracking code already + // figures this out, so it's cheaper to store the fact here. + absl::optional<bool> on_current_workspace_; SkRegion occluded_region_; base::ObserverList<WindowTreeHostObserver>::Unchecked observers_; diff --git a/chromium/ui/aura/window_tree_host_platform.cc b/chromium/ui/aura/window_tree_host_platform.cc index 03a1e689388..e25a3357dae 100644 --- a/chromium/ui/aura/window_tree_host_platform.cc +++ b/chromium/ui/aura/window_tree_host_platform.cc @@ -110,15 +110,11 @@ void WindowTreeHostPlatform::HideImpl() { } gfx::Rect WindowTreeHostPlatform::GetBoundsInPixels() const { - return platform_window_->GetBounds(); + return platform_window_->GetBoundsInPixels(); } void WindowTreeHostPlatform::SetBoundsInPixels(const gfx::Rect& bounds) { - platform_window_->SetBounds(bounds); -} - -gfx::Point WindowTreeHostPlatform::GetLocationOnScreenInPixels() const { - return platform_window_->GetBounds().origin(); + platform_window_->SetBoundsInPixels(bounds); } void WindowTreeHostPlatform::SetCapture() { @@ -129,6 +125,10 @@ void WindowTreeHostPlatform::ReleaseCapture() { platform_window_->ReleaseCapture(); } +gfx::Point WindowTreeHostPlatform::GetLocationOnScreenInPixels() const { + return platform_window_->GetBoundsInPixels().origin(); +} + bool WindowTreeHostPlatform::CaptureSystemKeyEventsImpl( absl::optional<base::flat_set<ui::DomCode>> dom_codes) { // Only one KeyboardHook should be active at a time, otherwise there will be diff --git a/chromium/ui/aura/window_tree_host_platform.h b/chromium/ui/aura/window_tree_host_platform.h index 1148496713b..db462e1209a 100644 --- a/chromium/ui/aura/window_tree_host_platform.h +++ b/chromium/ui/aura/window_tree_host_platform.h @@ -43,7 +43,6 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, void HideImpl() override; gfx::Rect GetBoundsInPixels() const override; void SetBoundsInPixels(const gfx::Rect& bounds) override; - gfx::Point GetLocationOnScreenInPixels() const override; void SetCapture() override; void ReleaseCapture() override; void SetCursorNative(gfx::NativeCursor cursor) override; @@ -87,6 +86,7 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, void SetFrameRateThrottleEnabled(bool enabled) override; // Overridden from aura::WindowTreeHost: + gfx::Point GetLocationOnScreenInPixels() const override; bool CaptureSystemKeyEventsImpl( absl::optional<base::flat_set<ui::DomCode>> dom_codes) override; void ReleaseSystemKeyEventCapture() override; diff --git a/chromium/ui/aura/window_tree_host_platform_unittest.cc b/chromium/ui/aura/window_tree_host_platform_unittest.cc index 5a6ed0885c7..603cd9cd36a 100644 --- a/chromium/ui/aura/window_tree_host_platform_unittest.cc +++ b/chromium/ui/aura/window_tree_host_platform_unittest.cc @@ -83,7 +83,7 @@ class TestWindowTreeHostObserver : public WindowTreeHostObserver { return; should_change_bounds_in_on_resized_ = false; - gfx::Rect bounds = platform_window_->GetBounds(); + gfx::Rect bounds = platform_window_->GetBoundsInPixels(); bounds.set_x(bounds.x() + 1); host_->SetBoundsInPixels(bounds); } diff --git a/chromium/ui/aura/window_tree_host_unittest.cc b/chromium/ui/aura/window_tree_host_unittest.cc index b24385c85d2..82fddad0d39 100644 --- a/chromium/ui/aura/window_tree_host_unittest.cc +++ b/chromium/ui/aura/window_tree_host_unittest.cc @@ -32,6 +32,38 @@ namespace aura { +namespace { + +// A convenient wrapper that makes it easy to invoke this method inside an +// EXPECT_EQ statement. +gfx::Point ConvertDIPToPixels(const WindowTreeHost* host, gfx::Point point) { + host->ConvertDIPToPixels(&point); + return point; +} + +// A convenient wrapper that makes it easy to invoke this method inside an +// EXPECT_EQ statement. +gfx::PointF ConvertDIPToPixels(const WindowTreeHost* host, gfx::PointF point) { + host->ConvertDIPToPixels(&point); + return point; +} + +// A convenient wrapper that makes it easy to invoke this method inside an +// EXPECT_EQ statement. +gfx::Point ConvertPixelsToDIP(const WindowTreeHost* host, gfx::Point point) { + host->ConvertPixelsToDIP(&point); + return point; +} + +// A convenient wrapper that makes it easy to invoke this method inside an +// EXPECT_EQ statement. +gfx::PointF ConvertPixelsToDIP(const WindowTreeHost* host, gfx::PointF point) { + host->ConvertPixelsToDIP(&point); + return point; +} + +} // namespace + using WindowTreeHostTest = test::AuraTestBase; TEST_F(WindowTreeHostTest, DPIWindowSize) { @@ -166,6 +198,103 @@ TEST_F(WindowTreeHostTest, NoRewritesPostIME) { host()->RemoveEventRewriter(&event_rewriter); } +TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldRespectScaleFactor) { + const int width_in_pixels = 400; + const int height_in_pixels = 300; + const int width_in_dip = 200; + const int height_in_dip = 150; + + host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels)); + test_screen()->SetDisplayRotation(display::Display::ROTATE_0); + + test_screen()->SetDeviceScaleFactor(2.f); + + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, 0)), gfx::Point(0, 0)); + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, 0)), + gfx::Point(width_in_pixels, 0)); + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, height_in_dip)), + gfx::Point(0, height_in_pixels)); +} + +TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldRespectRotation) { + const int width_in_pixels = 400; + const int height_in_pixels = 300; + const int width_in_dip = 300; + const int height_in_dip = 400; + + host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels)); + test_screen()->SetDeviceScaleFactor(1.f); + + test_screen()->SetDisplayRotation(display::Display::ROTATE_90); + + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, 0)), + gfx::Point(width_in_pixels, 0)); + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, 0)), + gfx::Point(width_in_pixels, height_in_pixels)); + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, height_in_dip)), + gfx::Point(0, height_in_pixels)); + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, height_in_dip)), + gfx::Point(0, 0)); +} + +TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldWorkWithPointF) { + host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 400)); + test_screen()->SetDisplayRotation(display::Display::ROTATE_0); + test_screen()->SetDeviceScaleFactor(2.f); + + EXPECT_EQ(ConvertDIPToPixels(host(), gfx::PointF(5.3f, 0)), + gfx::PointF(10.6f, 0)); +} + +TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldRespectScaleFactor) { + const int width_in_pixels = 400; + const int height_in_pixels = 300; + const int width_in_dip = 200; + const int height_in_dip = 150; + + host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels)); + test_screen()->SetDisplayRotation(display::Display::ROTATE_0); + + test_screen()->SetDeviceScaleFactor(2.f); + + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, 0)), gfx::Point(0, 0)); + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, 0)), + gfx::Point(width_in_dip, 0)); + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, height_in_pixels)), + gfx::Point(0, height_in_dip)); +} + +TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldRespectRotation) { + const int width_in_pixels = 400; + const int height_in_pixels = 300; + const int width_in_dip = 300; + const int height_in_dip = 400; + + host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels)); + test_screen()->SetDeviceScaleFactor(1.f); + + test_screen()->SetDisplayRotation(display::Display::ROTATE_90); + + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, 0)), + gfx::Point(0, height_in_dip)); + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, 0)), + gfx::Point(0, 0)); + EXPECT_EQ( + ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, height_in_pixels)), + gfx::Point(width_in_dip, 0)); + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, height_in_pixels)), + gfx::Point(width_in_dip, height_in_dip)); +} + +TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldWorkWithPointF) { + host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 400)); + test_screen()->SetDisplayRotation(display::Display::ROTATE_0); + test_screen()->SetDeviceScaleFactor(2.f); + + EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::PointF(10.6f, 0)), + gfx::PointF(5.3f, 0)); +} + class TestWindow : public ui::StubWindow { public: explicit TestWindow(ui::PlatformWindowDelegate* delegate) @@ -347,7 +476,7 @@ class WindowTreeHostWithThrottleTest : public test::AuraTestBase { base::test::ScopedFeatureList scoped_feature_list_; }; -TEST_F(WindowTreeHostWithThrottleTest, Basic) { +TEST_F(WindowTreeHostWithThrottleTest, DISABLED_Basic) { host()->Show(); EXPECT_TRUE(host()->compositor()->IsVisible()); EXPECT_TRUE(test::GetThrottledHosts().empty()); @@ -359,7 +488,7 @@ TEST_F(WindowTreeHostWithThrottleTest, Basic) { EXPECT_TRUE(host()->compositor()->IsVisible()); } -TEST_F(WindowTreeHostWithThrottleTest, CallHideDirectly) { +TEST_F(WindowTreeHostWithThrottleTest, DISABLED_CallHideDirectly) { host()->Show(); EXPECT_TRUE(host()->compositor()->IsVisible()); EXPECT_TRUE(test::GetThrottledHosts().empty()); @@ -371,6 +500,6 @@ TEST_F(WindowTreeHostWithThrottleTest, CallHideDirectly) { EXPECT_FALSE(host()->compositor()->IsVisible()); } -#endif +#endif // BUILDFLAG(IS_WIN) } // namespace aura |