chromium/ui/views/widget/widget_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>
#include <optional>
#include <set>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/hit_test.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/color/color_id.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_provider_manager.h"
#include "ui/color/color_recipe.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
#include "ui/events/event_observer.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/test_native_theme.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/buildflags.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/event_monitor.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/test/mock_drag_controller.h"
#include "ui/views/test/mock_native_widget.h"
#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/views_test_utils.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/view_test_api.h"
#include "ui/views/views_test_suite.h"
#include "ui/views/widget/native_widget_delegate.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/unique_widget_ptr.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_deletion_observer.h"
#include "ui/views/widget/widget_interactive_uitest_utils.h"
#include "ui/views/widget/widget_removals_observer.h"
#include "ui/views/widget/widget_utils.h"
#include "ui/views/window/dialog_delegate.h"
#include "ui/views/window/native_frame_view.h"

#if defined(USE_AURA)
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/view_prop.h"
#include "ui/views/test/test_platform_native_widget.h"
#include "ui/views/widget/native_widget_aura.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/focus_controller.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/shadow_controller_delegate.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "ui/base/win/window_event_target.h"
#include "ui/views/win/hwnd_util.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "base/mac/mac_util.h"
#endif

#if BUILDFLAG(ENABLE_DESKTOP_AURA)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif

namespace views::test {

namespace {

_;
IsEmpty;
Not;

// TODO(tdanderson): This utility function is used in different unittest
//                   files. Move to a common location to avoid
//                   repeated code.
gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {}

std::unique_ptr<ui::test::EventGenerator> CreateEventGenerator(
    gfx::NativeWindow root_window,
    gfx::NativeWindow target_window) {}

class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {};

BEGIN_METADATA()

// Convenience to make constructing a GestureEvent simpler.
ui::GestureEvent CreateTestGestureEvent(ui::EventType type, int x, int y) {}

ui::GestureEvent CreateTestGestureEvent(const ui::GestureEventDetails& details,
                                        int x,
                                        int y) {}

class TestWidgetRemovalsObserver : public WidgetRemovalsObserver {};

}  // namespace

// A view that keeps track of the events it receives, and consumes all scroll
// gesture events and ui::EventType::kScroll events.
class ScrollableEventCountView : public EventCountView {};

BEGIN_METADATA()

// A view that implements GetMinimumSize.
class MinimumSizeFrameView : public NativeFrameView {};

BEGIN_METADATA()

// An event handler that simply keeps a count of the different types of events
// it receives.
class EventCountHandler : public ui::EventHandler {};

TEST_F(WidgetTest, WidgetInitParams) {}

// Tests that the internal name is propagated through widget initialization to
// the native widget and back.
class WidgetWithCustomParamsTest : public WidgetTest {};

TEST_F(WidgetWithCustomParamsTest, NamePropagatedFromParams) {}

TEST_F(WidgetWithCustomParamsTest, NamePropagatedFromDelegate) {}

// Test that Widget::InitParams::autosize allows widget to
// automatically resize when content view size changes.
TEST_F(WidgetWithCustomParamsTest, Autosize) {}

namespace {

class ViewWithClassName : public View {};

BEGIN_METADATA()

}  // namespace

TEST_F(WidgetWithCustomParamsTest, NamePropagatedFromContentsViewClassName) {}

namespace {

class TestView : public View {};

BEGIN_METADATA()

}  // namespace

TEST_F(WidgetWithCustomParamsTest, InitWithNativeTheme) {}

class WidgetColorModeTest : public WidgetTest {};

TEST_F(WidgetColorModeTest, ColorModeOverride_NoOverride) {}

TEST_F(WidgetColorModeTest, ColorModeOverride_DarkOverride) {}

TEST_F(WidgetColorModeTest, ColorModeOverride_LightOverride) {}

TEST_F(WidgetColorModeTest, ChildInheritsColorMode_NoOverrides) {}

TEST_F(WidgetColorModeTest, ChildInheritsColorMode_Overrides) {}

TEST_F(WidgetTest, NativeWindowProperty) {}

TEST_F(WidgetTest, GetParent) {}

// Verify that there is no change in focus if |enable_arrow_key_traversal| is
// false (the default).
TEST_F(WidgetTest, ArrowKeyFocusTraversalOffByDefault) {}

// Verify that arrow keys can change focus if |enable_arrow_key_traversal| is
// set to true.
TEST_F(WidgetTest, ArrowKeyTraversalMovesFocusBetweenViews) {}

TEST_F(WidgetTest, ArrowKeyTraversalNotInheritedByChildWidgets) {}

TEST_F(WidgetTest, ArrowKeyTraversalMayBeExplicitlyEnabledByChildWidgets) {}

////////////////////////////////////////////////////////////////////////////////
// Widget::GetTopLevelWidget tests.

TEST_F(WidgetTest, GetTopLevelWidget_Native) {}

// Test if a focus manager and an inputmethod work without CHECK failure
// when window activation changes.
TEST_F(WidgetTest, ChangeActivation) {}

// Tests visibility of child widgets.
TEST_F(WidgetTest, Visibility) {}

// Test that child widgets are positioned relative to their parent.
TEST_F(WidgetTest, ChildBoundsRelativeToParent) {}

////////////////////////////////////////////////////////////////////////////////
// Widget ownership tests.
//
// Tests various permutations of Widget ownership specified in the
// InitParams::Ownership param. Make sure that they are properly destructed
// during shutdown.

// A bag of state to monitor destructions.
struct OwnershipTestState {};

class WidgetOwnershipTest : public WidgetTest {};

// A Widget subclass that updates a bag of state when it is destroyed.
class OwnershipTestWidget : public Widget {};

class NativeWidgetDestroyedWaiter {};

NativeWidgetOwnsWidgetTest;
// NativeWidget owns its Widget, part 1.1: NativeWidget is a non-desktop
// widget, CloseNow() destroys Widget and NativeWidget synchronously.
TEST_F(NativeWidgetOwnsWidgetTest, NonDesktopWidget_CloseNow) {}

// NativeWidget owns its Widget, part 1.2: NativeWidget is a non-desktop
// widget, Close() destroys Widget and NativeWidget asynchronously.
TEST_F(NativeWidgetOwnsWidgetTest, NonDesktopWidget_Close) {}

// NativeWidget owns its Widget, part 1.3: NativeWidget is a desktop
// widget, Close() destroys Widget and NativeWidget asynchronously.
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
TEST_F(NativeWidgetOwnsWidgetTest, DesktopWidget_Close) {}
#endif

// NativeWidget owns its Widget, part 1.4: NativeWidget is a desktop
// widget. Unlike desktop widget, CloseNow() might destroy Widget and
// NativeWidget asynchronously.
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
TEST_F(NativeWidgetOwnsWidgetTest, DesktopWidget_CloseNow) {}
#endif

// NativeWidget owns its Widget, part 2.1: NativeWidget is a non-desktop
// widget. CloseNow() the parent should destroy the child.
TEST_F(NativeWidgetOwnsWidgetTest, NonDestkopWidget_CloseNowParent) {}

// NativeWidget owns its Widget, part 2.2: NativeWidget is a desktop
// widget. CloseNow() the parent should destroy the child.
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
TEST_F(NativeWidgetOwnsWidgetTest, DestkopWidget_CloseNowParent) {}
#endif

// NativeWidget owns its Widget, part 3.1: NativeWidget is a non-desktop
// widget, destroyed out from under it by the OS.
TEST_F(NativeWidgetOwnsWidgetTest, NonDesktopWidget_NativeDestroy) {}

#if BUILDFLAG(ENABLE_DESKTOP_AURA)
// NativeWidget owns its Widget, part 3.2: NativeWidget is a desktop
// widget, destroyed out from under it by the OS.
TEST_F(NativeWidgetOwnsWidgetTest, DesktopWidget_NativeDestroy) {}
#endif

WidgetOwnsNativeWidgetTest;
// Widget owns its NativeWidget, part 1.
TEST_F(WidgetOwnsNativeWidgetTest, Ownership) {}

// Widget owns its NativeWidget, part 2: destroy the parent view.
TEST_F(WidgetOwnsNativeWidgetTest, DestroyParentView) {}

// Widget owns its NativeWidget, part 3: has a WidgetDelegateView as contents.
TEST_F(WidgetOwnsNativeWidgetTest, WidgetDelegateView) {}

// Widget owns its NativeWidget, part 4: Widget::CloseNow should be idempotent.
TEST_F(WidgetOwnsNativeWidgetTest, IdempotentCloseNow) {}

// Widget owns its NativeWidget, part 5: Widget::Close should be idempotent.
TEST_F(WidgetOwnsNativeWidgetTest, IdempotentClose) {}

// Tests for CLIENT_OWNS_WIDGET. The client holds a unique_ptr<Widget>.
// The NativeWidget will be destroyed when the platform window is closed.
ClientOwnsWidgetTest;

TEST_F(ClientOwnsWidgetTest, Ownership) {}

TEST_F(ClientOwnsWidgetTest, DestructWithAsyncCloseFirst) {}

TEST_F(ClientOwnsWidgetTest, DestructWithoutExplicitClose) {}

class WidgetDestroyCounter : public WidgetObserver {};

TEST_F(ClientOwnsWidgetTest, NotificationsTest) {}

////////////////////////////////////////////////////////////////////////////////
// Test to verify using various Widget methods doesn't crash when the underlying
// NativeView and NativeWidget is destroyed. Currently, for
// the WIDGET_OWNS_NATIVE_WIDGET ownership pattern, the NativeWidget will not be
// destroyed, but |native_widget_| will still be set to nullptr.

class WidgetWithDestroyedNativeViewOrNativeWidgetTest
    : public ViewsTestBase,
      public testing::WithParamInterface<
          std::tuple<ViewsTestBase::NativeWidgetType,
                     Widget::InitParams::Ownership>> {};

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Activate) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, AddAndRemoveObserver) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       AddAndRemoveRemovalsObserver) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, AsWidget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, CanActivate) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, CenterWindow) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ClearNativeFocus) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ClientView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Close) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       CloseAllSecondaryWidgets) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, CloseNow) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ClosedReason) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, CloseWithReason) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       CreateNonClientFrameView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Deactivate) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, DraggedView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, EndMoveLoop) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ExecuteCommand) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, FlashFrame) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, FrameType) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, FrameTypeChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetAccelerator) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetAllChildWidgets) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetAllOwnedWidgets) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetAndSetZOrderLevel) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetClientAreaBoundsInScreen) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetColorProvider) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetCompositor) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetContentsView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetCustomTheme) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetEventSink) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetFocusSearch) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetFocusManager) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetFocusTraversable) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetGestureConsumer) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetGestureRecognizer) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetHitTestMask) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetInputMethod) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetLayer) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetMinimumSize) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetMaximumSize) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetName) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetNativeTheme) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetNativeView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetNativeWindow) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetNativeWindowProperty) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetNonClientComponent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetPrimaryWindowWidget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetRestoredBounds) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetRootView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetSublevelManager) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetThemeProvider) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetTooltipManager) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetTopLevelWidget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetTopLevelWidgetForNativeView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetWeakPtr) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetWidgetForNativeView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetWidgetForNativeWindow) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetWindowBoundsInScreen) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       GetWorkAreaBoundsInScreen) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetWorkspace) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, GetZOrderSublevel) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, HasCapture) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, HasFocusManager) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, HasHitTestMask) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, HasObserver) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, HasRemovalsObserver) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Hide) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Init) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, is_secondary_widget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsActive) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsClosed) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsDialogBox) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsFullscreen) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsMaximized) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsMinimized) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsModal) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsMouseEventsEnabled) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsMoveLoopSupported) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       IsNativeWidgetInitialized) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsStackedAbove) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, IsVisible) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       IsVisibleOnAllWorkspaces) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnGestureEvent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnKeyEvent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnMouseCaptureLost) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnMouseEvent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeBlur) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeFocus) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeThemeUpdated) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetActivationChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetAddedToCompositor) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetBeginUserBoundsChange) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeWidgetCreated) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetDestroyed) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetDestroying) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetEndUserBoundsChange) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeWidgetMove) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnNativeWidgetPaint) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetParentChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetRemovingFromCompositor) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetSizeChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetVisibilityChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetWindowShowStateChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnNativeWidgetWorkspaceChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnOwnerClosing) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnParentShouldPaintAsActiveChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, OnScrollEvent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       OnSizeConstraintsChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, LayerTreeChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       LayoutRootViewIfNecessary) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, LockPaintAsActive) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Maximize) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Minimize) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, movement_disabled) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, native_widget_private) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, native_widget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, non_client_view) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       NotifyNativeViewHierarchyChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       NotifyNativeViewHierarchyWillChange) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, NotifyWillRemoveView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, parent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       RegisterPaintAsActiveChangedCallback) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ReleaseCapture) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ReorderNativeViews) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ReparentNativeView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Restore) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, RunMoveLoop) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, RunShellDrag) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ScheduleLayout) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SchedulePaintInRect) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetAspectRatio) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetBounds) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetBoundsConstrained) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetCanAppearInExistingFullscreenSpaces) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetCapture) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetContentsView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetCursor) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetFocusTraversableParent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetFocusTraversableParentView) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetFullscreen) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetInitialFocus) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetNativeWindowProperty) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetOpacity) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetShape) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetSize) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetVisibilityChangedAnimationsEnabled) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetVisibilityAnimationDuration) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetVisibilityAnimationTransition) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, SetVisible) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SetVisibleOnAllWorkspaces) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       ShouldDescendIntoChildForEventHandling) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       ShouldHandleNativeWidgetActivationChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ShouldPaintAsActive) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ShouldUseNativeFrame) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       ShouldWindowContentsBeTransparent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, Show) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ShowEmojiPanel) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ShowInactive) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, StackAbove) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, StackAboveWidget) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, StackAtTop) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest,
       SynthesizeMouseMoveEvent) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ThemeChanged) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, UnlockPaintAsActive) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, UpdateWindowIcon) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, UpdateWindowTitle) {}

TEST_P(WidgetWithDestroyedNativeViewOrNativeWidgetTest, ViewHierarchyChanged) {}

INSTANTIATE_TEST_SUITE_P();

////////////////////////////////////////////////////////////////////////////////
// Widget observer tests.
//

class WidgetObserverTest : public WidgetTest, public WidgetObserver {};

// This test appears to be flaky on Mac.
#if BUILDFLAG(IS_MAC)
#define MAYBE_ActivationChange
#else
#define MAYBE_ActivationChange
#endif

TEST_F(WidgetObserverTest, MAYBE_ActivationChange) {}

namespace {

// This class simulates a focus manager that moves focus to a second widget when
// the first one is closed. It simulates a situation where a sequence of widget
// observers might try to call Widget::Close in response to a OnWidgetClosing().
class WidgetActivationForwarder : public TestWidgetObserver {};

// This class observes a widget and counts the number of times OnWidgetClosing
// is called.
class WidgetCloseCounter : public TestWidgetObserver {};

}  // namespace

// Makes sure close notifications aren't sent more than once when a Widget is
// shutting down. Test for crbug.com/714334
TEST_F(WidgetObserverTest, CloseReentrancy) {}

TEST_F(WidgetObserverTest, VisibilityChange) {}

TEST_F(WidgetObserverTest, DestroyBubble) {}

TEST_F(WidgetObserverTest, WidgetBoundsChanged) {}

// An extension to WidgetBoundsChanged to ensure notifications are forwarded
// by the NativeWidget implementation.
TEST_F(WidgetObserverTest, WidgetBoundsChangedNative) {}

namespace {

class MoveTrackingTestDesktopWidgetDelegate : public TestDesktopWidgetDelegate {};

}  // namespace

class DesktopWidgetObserverTest : public WidgetObserverTest {};

// An extension to the WidgetBoundsChangedNative test above to ensure move
// notifications propagate to the WidgetDelegate.
TEST_F(DesktopWidgetObserverTest, OnWidgetMovedWhenOriginChangesNative) {}

// Test correct behavior when widgets close themselves in response to visibility
// changes.
TEST_F(WidgetObserverTest, ClosingOnHiddenParent) {}

// Test behavior of NativeWidget*::GetWindowPlacement on the native desktop.
#if BUILDFLAG(IS_LINUX)
// On desktop-Linux cheat and use non-desktop widgets. On X11, minimize is
// asynchronous. Also (harder) showing a window doesn't activate it without
// user interaction (or extra steps only done for interactive ui tests).
// Without that, show_state remains in ui::SHOW_STATE_INACTIVE throughout.
// TODO(tapted): Find a nice way to run this with desktop widgets on Linux.
TEST_F(WidgetTest, GetWindowPlacement) {}

// Test that widget size constraints are properly applied immediately after
// Init(), and that SetBounds() calls are appropriately clamped.
TEST_F(DesktopWidgetTest, MinimumSizeConstraints) {}

// When a non-desktop widget has a desktop child widget, due to the
// async nature of desktop widget shutdown, the parent can be destroyed before
// its child. Make sure that parent() returns nullptr at this time.
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
TEST_F(DesktopWidgetTest, GetPossiblyDestroyedParent) {}
#endif  // BUILDFLAG(ENABLE_DESKTOP_AURA)

// Tests that SetBounds() and GetWindowBoundsInScreen() is symmetric when the
// widget is visible and not maximized or fullscreen.
TEST_F(WidgetTest, GetWindowBoundsInScreen) {}

// Chrome OS widgets need the shell to maximize/fullscreen window.
// Disable on desktop Linux because windows restore to the wrong bounds.
// See http://crbug.com/515369.
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
#define MAYBE_GetRestoredBounds
#else
#define MAYBE_GetRestoredBounds
#endif

// Test that GetRestoredBounds() returns the original bounds of the window.
TEST_F(DesktopWidgetTest, MAYBE_GetRestoredBounds) {}

// The key-event propagation from Widget happens differently on aura and
// non-aura systems because of the difference in IME. So this test works only on
// aura.
TEST_F(WidgetTest, KeyboardInputEvent) {}

TEST_F(WidgetTest, BubbleControlsResetOnInit) {}

#if BUILDFLAG(IS_WIN)
// Test to ensure that after minimize, view width is set to zero. This is only
// the case for desktop widgets on Windows. Other platforms retain the window
// size while minimized.
TEST_F(DesktopWidgetTest, TestViewWidthAfterMinimizingWidget) {
  // Create a widget.
  std::unique_ptr<Widget> widget =
      CreateTestWidget(Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
                       Widget::InitParams::TYPE_WINDOW);
  NonClientView* non_client_view = widget->non_client_view();
  non_client_view->SetFrameView(
      std::make_unique<MinimumSizeFrameView>(widget.get()));
  // Setting the frame view doesn't do a layout, so force one.
  non_client_view->InvalidateLayout();
  views::test::RunScheduledLayout(non_client_view);
  widget->Show();
  EXPECT_NE(0, non_client_view->frame_view()->width());
  widget->Minimize();
  EXPECT_EQ(0, non_client_view->frame_view()->width());
}
#endif

// Desktop native widget Aura tests are for non Chrome OS platforms.
// This class validates whether paints are received for a visible Widget.
// It observes Widget visibility and Close() and tracks whether subsequent
// paints are expected.
class DesktopAuraTestValidPaintWidget : public Widget, public WidgetObserver {};

namespace {

class ContentsView : public View {};

BEGIN_METADATA()

}  // namespace

class DesktopAuraPaintWidgetTest : public DesktopWidgetTest {};

TEST_F(DesktopAuraPaintWidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {}

TEST_F(DesktopAuraPaintWidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) {}

// Test to ensure that the aura Window's visibility state is set to visible if
// the underlying widget is hidden and then shown.
TEST_F(DesktopWidgetTest, TestWindowVisibilityAfterHide) {}

// Tests that wheel events generated from scroll events are targeted to the
// views under the cursor when the focused view does not processed them.
TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) {}

// Tests that if a scroll-begin gesture is not handled, then subsequent scroll
// events are not dispatched to any view.
TEST_F(WidgetTest, GestureScrollEventDispatching) {}

// Tests that event-handlers installed on the RootView get triggered correctly.
// TODO(tdanderson): Clean up this test as part of crbug.com/355680.
TEST_F(WidgetTest, EventHandlersOnRootView) {}

TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {}

namespace {

// ui::EventHandler which handles all mouse press events.
class MousePressEventConsumer : public ui::EventHandler {};

}  // namespace

// No touch on desktop Mac. Tracked in http://crbug.com/445520.
#if !BUILDFLAG(IS_MAC) || defined(USE_AURA)

// Test that mouse presses and mouse releases are dispatched normally when a
// touch is down.
TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {}

#endif  // !BUILDFLAG(IS_MAC) || defined(USE_AURA)

// Tests that when there is no active capture, that a mouse press causes capture
// to be set.
TEST_F(WidgetTest, MousePressCausesCapture) {}

namespace {

// An EventHandler which shows a Widget upon receiving a mouse event. The Widget
// proceeds to take capture.
class CaptureEventConsumer : public ui::EventHandler {};

}  // namespace

// Tests that if explicit capture occurs during a mouse press, that implicit
// capture is not applied.
TEST_F(WidgetTest, CaptureDuringMousePressNotOverridden) {}

class ClosingEventObserver : public ui::EventObserver {};

class ClosingView : public View {};

BEGIN_METADATA()

// Ensures that when multiple objects are intercepting OS-level events, that one
// can safely close a Widget that has capture.
TEST_F(WidgetTest, DestroyedWithCaptureViaEventMonitor) {}

TEST_F(WidgetTest, LockPaintAsActive) {}

TEST_F(WidgetTest, LockPaintAsActive_AlreadyActive) {}

TEST_F(WidgetTest, LockPaintAsActive_BecomesActive) {}

class PaintAsActiveCallbackCounter {};

TEST_F(WidgetTest, LockParentPaintAsActive) {}

// Tests to make sure that child widgets do not cause their parent widget to
// paint inactive immediately when they are closed. This avoids having the
// parent paint as inactive in the time between when the bubble is closed and
// when it's eventually destroyed by its native widget (see crbug.com/1303549).
TEST_F(DesktopWidgetTest,
       ClosingActiveChildDoesNotPrematurelyPaintParentInactive) {}

// Tests that there is no crash when paint as active lock is removed for child
// widget while its parent widget is being closed.
TEST_F(DesktopWidgetTest, LockPaintAsActiveAndCloseParent) {}

// Widget used to destroy itself when OnNativeWidgetDestroyed is called.
class TestNativeWidgetDestroyedWidget : public Widget {};

void TestNativeWidgetDestroyedWidget::OnNativeWidgetDestroyed() {}

// Verifies that widget destroyed itself in OnNativeWidgetDestroyed does not
// crash in ASan.
TEST_F(DesktopWidgetTest, WidgetDestroyedItselfDoesNotCrash) {}

// Verifies WindowClosing() is invoked correctly on the delegate when a Widget
// is closed.
TEST_F(DesktopWidgetTest, SingleWindowClosing) {}

TEST_F(DesktopWidgetTest, CloseRequested_AllowsClose) {}

TEST_F(DesktopWidgetTest, CloseRequested_DisallowClose) {}

TEST_F(DesktopWidgetTest, CloseRequested_SecondCloseIgnored) {}

class WidgetWindowTitleTest : public DesktopWidgetTest {};

TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_NativeWidget) {}

TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {}

TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) {}

// No touch on desktop Mac. Tracked in http://crbug.com/445520.
#if !BUILDFLAG(IS_MAC) || defined(USE_AURA)

TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) {}

#endif  // !BUILDFLAG(IS_MAC) || defined(USE_AURA)

// See description of RunGetNativeThemeFromDestructor() for details.
class GetNativeThemeFromDestructorView : public WidgetDelegateView {};

// Verifies GetNativeTheme() from the destructor of a WidgetDelegateView doesn't
// crash. |is_first_run| is true if this is the first call. A return value of
// true indicates this should be run again with a value of false.
// First run uses DesktopNativeWidgetAura (if possible). Second run doesn't.
bool RunGetNativeThemeFromDestructor(Widget::InitParams params,
                                     bool is_first_run) {}

// See description of RunGetNativeThemeFromDestructor() for details.
TEST_F(DesktopWidgetTest, DISABLED_GetNativeThemeFromDestructor) {}

// Used by HideCloseDestroy. Allows setting a boolean when the widget is
// destroyed.
class CloseDestroysWidget : public Widget {};

// An observer that registers that an animation has ended.
class AnimationEndObserver : public ui::ImplicitAnimationObserver {};

// An observer that registers the bounds of a widget on destruction.
class WidgetBoundsObserver : public WidgetObserver {};

// Verifies Close() results in destroying.
TEST_F(DesktopWidgetTest, CloseDestroys) {}

// Tests that killing a widget while animating it does not crash.
TEST_F(WidgetTest, CloseWidgetWhileAnimating) {}

// Test Widget::CloseAllSecondaryWidgets works as expected across platforms.
// ChromeOS doesn't implement or need CloseAllSecondaryWidgets() since
// everything is under a single root window.
#if BUILDFLAG(ENABLE_DESKTOP_AURA) || BUILDFLAG(IS_MAC)
TEST_F(DesktopWidgetTest, CloseAllSecondaryWidgets) {}
#endif

// Test that the NativeWidget is still valid during OnNativeWidgetDestroying(),
// and properties that depend on it are valid, when closed via CloseNow().
TEST_F(DesktopWidgetTest, ValidDuringOnNativeWidgetDestroyingFromCloseNow) {}

// Test that the NativeWidget is still valid during OnNativeWidgetDestroying(),
// and properties that depend on it are valid, when closed via Close().
TEST_F(DesktopWidgetTest, ValidDuringOnNativeWidgetDestroyingFromClose) {}

// Tests that we do not crash when a Widget is destroyed by going out of
// scope (as opposed to being explicitly deleted by its NativeWidget).
TEST_F(WidgetTest, NoCrashOnWidgetDelete) {}

TEST_F(WidgetTest, NoCrashOnResizeConstraintsWindowTitleOnPopup) {}

// Tests that we do not crash when a Widget is destroyed before it finishes
// processing of pending input events in the message loop.
TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) {}

// A view that consumes mouse-pressed event and gesture-tap-down events.
class RootViewTestView : public View {};

BEGIN_METADATA()

// Checks if RootView::*_handler_ fields are unset when widget is hidden.
// Fails on chromium.webkit Windows bot, see crbug.com/264872.
#if BUILDFLAG(IS_WIN)
#define MAYBE_DisableTestRootViewHandlersWhenHidden
#else
#define MAYBE_DisableTestRootViewHandlersWhenHidden
#endif
TEST_F(WidgetTest, MAYBE_DisableTestRootViewHandlersWhenHidden) {}

// Tests that the |gesture_handler_| member in RootView is always NULL
// after the dispatch of a ui::EventType::kGestureEnd event corresponding to
// the release of the final touch point on the screen, but that
// ui::EventType::kGestureEnd events corresponding to the removal of any other
// touch point do not modify |gesture_handler_|.
TEST_F(WidgetTest, GestureEndEvents) {}

// Tests that gesture events which should not be processed (because
// RootView::OnEventProcessingStarted() has marked them as handled) are not
// dispatched to any views.
TEST_F(WidgetTest, GestureEventsNotProcessed) {}

// Tests that a (non-scroll) gesture event is dispatched to the correct views
// in a view hierarchy and that the default gesture handler in RootView is set
// correctly.
TEST_F(WidgetTest, GestureEventDispatch) {}

// Tests that gesture scroll events will change the default gesture handler in
// RootView if the current handler to which they are dispatched does not handle
// gesture scroll events.
TEST_F(WidgetTest, ScrollGestureEventDispatch) {}

// TODO(b/271490637): on Mac a drag controller should still be notified when
// drag will start. Figure out how to write a unit test for Mac. Then remove
// this build flag check.
#if !BUILDFLAG(IS_MAC)

// Verifies that the drag controller is notified when the view drag will start.
TEST_F(WidgetTest, NotifyDragControllerWhenDragWillStart) {}

#endif  // !BUILDFLAG(IS_MAC)

// A class used in WidgetTest.GestureEventLocationWhileBubbling to verify
// that when a gesture event bubbles up a View hierarchy, the location
// of a gesture event seen by each View is in the local coordinate space
// of that View.
class GestureLocationView : public EventCountView {};

BEGIN_METADATA()

// Verifies that the location of a gesture event is always in the local
// coordinate space of the View receiving the event while bubbling.
TEST_F(WidgetTest, GestureEventLocationWhileBubbling) {}

// Test the result of Widget::GetAllChildWidgets().
TEST_F(WidgetTest, GetAllChildWidgets) {}

// Used by DestroyChildWidgetsInOrder. On destruction adds the supplied name to
// a vector.
class DestroyedTrackingView : public View {};

BEGIN_METADATA()

class WidgetChildDestructionTest : public DesktopWidgetTest {};

// See description of RunDestroyChildWidgetsTest(). Parent uses
// DesktopNativeWidgetAura.
TEST_F(WidgetChildDestructionTest,
       DestroyChildWidgetsInOrderWithDesktopNativeWidget) {}

// See description of RunDestroyChildWidgetsTest(). Both parent and child use
// DesktopNativeWidgetAura.
TEST_F(WidgetChildDestructionTest,
       DestroyChildWidgetsInOrderWithDesktopNativeWidgetForBoth) {}

// See description of RunDestroyChildWidgetsTest().
TEST_F(WidgetChildDestructionTest, DestroyChildWidgetsInOrder) {}

// Verifies nativeview visbility matches that of Widget visibility when
// SetFullscreen is invoked.
TEST_F(WidgetTest, FullscreenStatePropagated) {}

// Verifies nativeview visbility matches that of Widget visibility when
// SetFullscreen is invoked, for a widget provided with a desktop widget.
TEST_F(DesktopWidgetTest, FullscreenStatePropagated_DesktopWidget) {}

// Used to delete the widget when the supplied bounds changes.
class DestroyingWidgetBoundsObserver : public WidgetObserver {};

// Deletes a Widget when the bounds change as part of toggling fullscreen.
// This is a regression test for https://crbug.com/1197436.
// Disabled on Mac: This test has historically deleted the Widget not during
// SetFullscreen, but at the end of the test. When the Widget is deleted inside
// SetFullscreen, the test crashes.
// https://crbug.com/1307486
#if BUILDFLAG(IS_MAC)
#define MAYBE_DeleteInSetFullscreen
#else
#define MAYBE_DeleteInSetFullscreen
#endif
TEST_F(DesktopWidgetTest, MAYBE_DeleteInSetFullscreen) {}

namespace {

class FullscreenAwareFrame : public views::NonClientFrameView {};

BEGIN_METADATA()

}  // namespace

// Tests that frame Layout is called when a widget goes fullscreen without
// changing its size or title.
TEST_F(WidgetTest, FullscreenFrameLayout) {}

namespace {

// Trivial WidgetObserverTest that invokes Widget::IsActive() from
// OnWindowDestroying.
class IsActiveFromDestroyObserver : public WidgetObserver {};

}  // namespace

class ChildDesktopWidgetTest : public DesktopWidgetTest {};

// Verifies Widget::IsActive() invoked from
// WidgetObserver::OnWidgetDestroying() in a child widget doesn't crash.
TEST_F(ChildDesktopWidgetTest, IsActiveFromDestroy) {}

// Tests that events propagate through from the dispatcher with the correct
// event type, and that the different platforms behave the same.
TEST_F(WidgetTest, MouseEventTypesViaGenerator) {}

// Tests that the root view is correctly set up for Widget types that do not
// require a non-client view, before any other views are added to the widget.
// That is, before Widget::ReorderNativeViews() is called which, if called with
// a root view not set, could cause the root view to get resized to the widget.
TEST_F(WidgetTest, NonClientWindowValidAfterInit) {}

#if BUILDFLAG(IS_WIN)
// Provides functionality to subclass a window and keep track of messages
// received.
class SubclassWindowHelper {
 public:
  explicit SubclassWindowHelper(HWND window)
      : window_(window), message_to_destroy_on_(0) {
    EXPECT_EQ(instance_, nullptr);
    instance_ = this;
    EXPECT_TRUE(Subclass());
  }

  SubclassWindowHelper(const SubclassWindowHelper&) = delete;
  SubclassWindowHelper& operator=(const SubclassWindowHelper&) = delete;

  ~SubclassWindowHelper() {
    Unsubclass();
    instance_ = nullptr;
  }

  // Returns true if the |message| passed in was received.
  bool received_message(unsigned int message) {
    return (messages_.find(message) != messages_.end());
  }

  void Clear() { messages_.clear(); }

  void set_message_to_destroy_on(unsigned int message) {
    message_to_destroy_on_ = message;
  }

 private:
  bool Subclass() {
    old_proc_ = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(
        window_, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc)));
    return old_proc_ != nullptr;
  }

  void Unsubclass() {
    ::SetWindowLongPtr(window_, GWLP_WNDPROC,
                       reinterpret_cast<LONG_PTR>(old_proc_));
  }

  static LRESULT CALLBACK WndProc(HWND window,
                                  unsigned int message,
                                  WPARAM w_param,
                                  LPARAM l_param) {
    EXPECT_NE(instance_, nullptr);
    EXPECT_EQ(window, instance_->window_);

    // Keep track of messags received for this window.
    instance_->messages_.insert(message);

    LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message,
                                   w_param, l_param);
    if (message == instance_->message_to_destroy_on_) {
      instance_->Unsubclass();
      ::DestroyWindow(window);
    }
    return ret;
  }

  WNDPROC old_proc_;
  HWND window_;
  static SubclassWindowHelper* instance_;
  std::set<unsigned int> messages_;
  unsigned int message_to_destroy_on_;
};

SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr;

// This test validates whether the WM_SYSCOMMAND message for SC_MOVE is
// received when we post a WM_NCLBUTTONDOWN message for the caption in the
// following scenarios:-
// 1. Posting a WM_NCMOUSEMOVE message for a different location.
// 2. Posting a WM_NCMOUSEMOVE message with a different hittest code.
// 3. Posting a WM_MOUSEMOVE message.
// Disabled because of flaky timeouts: http://crbug.com/592742
TEST_F(DesktopWidgetTest,
       DISABLED_SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
  std::unique_ptr<Widget> widget =
      CreateTestWidget(Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
                       Widget::InitParams::TYPE_WINDOW);
  widget->Show();
  ::SetCursorPos(500, 500);

  HWND window = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();

  SubclassWindowHelper subclass_helper(window);

  // Posting just a WM_NCLBUTTONDOWN message should not result in a
  // WM_SYSCOMMAND
  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  RunPendingMessages();
  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND));

  subclass_helper.Clear();
  // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at the
  // same location should not result in a WM_SYSCOMMAND message.
  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(100, 100));
  RunPendingMessages();

  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
  EXPECT_FALSE(subclass_helper.received_message(WM_SYSCOMMAND));

  subclass_helper.Clear();
  // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a
  // different location should result in a WM_SYSCOMMAND message.
  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
  RunPendingMessages();

  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
  EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));

  subclass_helper.Clear();
  // Posting a WM_NCLBUTTONDOWN message followed by a WM_NCMOUSEMOVE at a
  // different location with a different hittest code should result in a
  // WM_SYSCOMMAND message.
  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  ::PostMessage(window, WM_NCMOUSEMOVE, HTTOP, MAKELPARAM(110, 102));
  RunPendingMessages();

  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_TRUE(subclass_helper.received_message(WM_NCMOUSEMOVE));
  EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));

  subclass_helper.Clear();
  // Posting a WM_NCLBUTTONDOWN message followed by a WM_MOUSEMOVE should
  // result in a WM_SYSCOMMAND message.
  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  ::PostMessage(window, WM_MOUSEMOVE, HTCLIENT, MAKELPARAM(110, 110));
  RunPendingMessages();

  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_TRUE(subclass_helper.received_message(WM_MOUSEMOVE));
  EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
}

// This test validates that destroying the window in the context of the
// WM_SYSCOMMAND message with SC_MOVE does not crash.
// Disabled because of flaky timeouts: http://crbug.com/592742
TEST_F(DesktopWidgetTest, DISABLED_DestroyInSysCommandNCLButtonDownOnCaption) {
  std::unique_ptr<Widget> widget =
      CreateTestWidget(Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
                       Widget::InitParams::TYPE_WINDOW);
  widget->Show();
  ::SetCursorPos(500, 500);

  HWND window = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();

  SubclassWindowHelper subclass_helper(window);

  // Destroying the window in the context of the WM_SYSCOMMAND message
  // should not crash.
  subclass_helper.set_message_to_destroy_on(WM_SYSCOMMAND);

  ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
  ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
  RunPendingMessages();

  EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
  EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
}

#endif

// Test that the z-order levels round-trip.
TEST_F(WidgetTest, ZOrderLevel) {}

namespace {

class ScaleFactorView : public View {};

BEGIN_METADATA()

}  // namespace

// Ensure scale factor changes are propagated from the native Widget.
TEST_F(WidgetTest, OnDeviceScaleFactorChanged) {}

// Test that WidgetRemovalsObserver::OnWillRemoveView is called when deleting
// a view.
TEST_F(WidgetTest, WidgetRemovalsObserverCalled) {}

// Test that WidgetRemovalsObserver::OnWillRemoveView is called when deleting
// the root view.
TEST_F(WidgetTest, WidgetRemovalsObserverCalledWhenRemovingRootView) {}

// Test that WidgetRemovalsObserver::OnWillRemoveView is called when moving
// a view from one widget to another, but not when moving a view within
// the same widget.
TEST_F(WidgetTest, WidgetRemovalsObserverCalledWhenMovingBetweenWidgets) {}

// Test dispatch of ui::EventType::kMousewheel.
TEST_F(WidgetTest, MouseWheelEvent) {}

// Test that ui::EventType::kMouseEntered is dispatched even when not followed
// by ui::EventType::kMouseMoved.
TEST_F(WidgetTest, MouseEnteredWithoutMoved) {}

// Test that ui::EventType::kMouseMoved after ui::EventType::kMouseEntered
// doesn't cause an extra ui::EventType::kMouseEntered.
TEST_F(WidgetTest, MouseMovedAfterEnteredDoesntCauseEntered) {}

class CloseFromClosingObserver : public WidgetObserver {};

TEST_F(WidgetTest, CloseNowFollowedByCloseDoesntCallOnWidgetClosingTwice) {}

namespace {

class TestSaveWindowPlacementWidgetDelegate : public TestDesktopWidgetDelegate {};

}  // namespace

TEST_F(WidgetTest, ShouldSaveWindowPlacement) {}

TEST_F(WidgetTest, RootViewAccessibilityCacheInitialized) {}

TEST_F(WidgetTest, ClientViewAccessibilityProperties) {}

TEST_F(WidgetTest, NonClientViewAccessibilityProperties) {}

// Parameterized test that verifies the behavior of SetAspectRatio with respect
// to the excluded margin.
class WidgetSetAspectRatioTest
    : public ViewsTestBase,
      public testing::WithParamInterface<gfx::Size /* margin */> {};

TEST_P(WidgetSetAspectRatioTest, SetAspectRatioIncludesMargin) {}

INSTANTIATE_TEST_SUITE_P();

class WidgetShadowTest : public WidgetTest {};

// Disabled on Mac: All drop shadows are managed out of process for now.
#if BUILDFLAG(IS_MAC)
#define MAYBE_ShadowsInRootWindow
#else
#define MAYBE_ShadowsInRootWindow
#endif

// Test that shadows are not added to root windows when created or upon
// activation. Test that shadows are added to non-root windows even if not
// activated.
TEST_F(WidgetShadowTest, MAYBE_ShadowsInRootWindow) {}

#if BUILDFLAG(IS_WIN)

// Tests the case where an intervening owner popup window is destroyed out from
// under the currently active modal top-level window. In this instance, the
// remaining top-level windows should be re-enabled.
TEST_F(DesktopWidgetTest, WindowModalOwnerDestroyedEnabledTest) {
  // top_level_widget owns owner_dialog_widget which owns owned_dialog_widget.
  std::unique_ptr<Widget> top_level_widget =
      CreateTestWidget(Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
  top_level_widget->Show();

  // Create the owner modal dialog.
  const auto create_params = [this](Widget* widget, gfx::NativeView parent) {
    Widget::InitParams init_params =
        CreateParamsForTestWidget(Widget::InitParams::TYPE_WINDOW);
    init_params.delegate = new WidgetDelegate();
    init_params.delegate->SetModalType(ui::mojom::ModalType::kWindow);
    init_params.parent = parent;
    init_params.native_widget =
        new test::TestPlatformNativeWidget<DesktopNativeWidgetAura>(
            widget, false, nullptr);
    return init_params;
  };
  Widget owner_dialog_widget;
  owner_dialog_widget.Init(
      create_params(&owner_dialog_widget, top_level_widget->GetNativeView()));
  owner_dialog_widget.Show();
  HWND owner_hwnd = HWNDForWidget(&owner_dialog_widget);

  // Create the owned modal dialog.
  Widget owned_dialog_widget;
  owned_dialog_widget.Init(
      create_params(&owned_dialog_widget, owner_dialog_widget.GetNativeView()));
  owned_dialog_widget.Show();
  HWND owned_hwnd = HWNDForWidget(&owned_dialog_widget);

  RunPendingMessages();

  HWND top_hwnd = HWNDForWidget(top_level_widget.get());

  EXPECT_FALSE(!!IsWindowEnabled(owner_hwnd));
  EXPECT_FALSE(!!IsWindowEnabled(top_hwnd));
  EXPECT_TRUE(!!IsWindowEnabled(owned_hwnd));

  owner_dialog_widget.CloseNow();
  RunPendingMessages();

  EXPECT_FALSE(!!IsWindow(owner_hwnd));
  EXPECT_FALSE(!!IsWindow(owned_hwnd));
  EXPECT_TRUE(!!IsWindowEnabled(top_hwnd));

  top_level_widget->CloseNow();
}

TEST_F(DesktopWidgetTest, StackAboveTest) {
  WidgetAutoclosePtr root_one(CreateTopLevelNativeWidget());
  WidgetAutoclosePtr root_two(CreateTopLevelNativeWidget());
  Widget* child_one = CreateChildNativeWidgetWithParent(root_one->AsWidget());
  Widget* child_one_b = CreateChildNativeWidgetWithParent(root_one->AsWidget());
  Widget* child_two = CreateChildNativeWidgetWithParent(root_two->AsWidget());
  Widget* grandchild_one =
      CreateChildNativeWidgetWithParent(child_one->AsWidget());
  Widget* grandchild_two =
      CreateChildNativeWidgetWithParent(child_two->AsWidget());

  root_one->ShowInactive();
  child_one->ShowInactive();
  child_one_b->ShowInactive();
  grandchild_one->ShowInactive();
  root_two->ShowInactive();
  child_two->ShowInactive();
  grandchild_two->ShowInactive();

  // Creates the following where Z-Order is from Left to Right.
  //            root_one                    root_two
  //             /    \                         /
  //       child_one_b  child_one           child_two
  //                       /                  /
  //                 grandchild_one    grandchild_two
  //
  // Note: child_one and grandchild_one were brought to front
  //       when grandchild_one was shown.

  // Child elements are stacked above parent.
  EXPECT_TRUE(child_one->IsStackedAbove(root_one->GetNativeView()));
  EXPECT_TRUE(child_one_b->IsStackedAbove(root_one->GetNativeView()));
  EXPECT_TRUE(grandchild_one->IsStackedAbove(child_one->GetNativeView()));
  EXPECT_TRUE(grandchild_two->IsStackedAbove(root_two->GetNativeView()));

  // Siblings with higher z-order are stacked correctly.
  EXPECT_TRUE(child_one->IsStackedAbove(child_one_b->GetNativeView()));
  EXPECT_TRUE(grandchild_one->IsStackedAbove(child_one_b->GetNativeView()));

  // Root elements are stacked above child of a root with lower z-order.
  EXPECT_TRUE(root_two->IsStackedAbove(root_one->GetNativeView()));
  EXPECT_TRUE(root_two->IsStackedAbove(child_one_b->GetNativeView()));

  // Child elements are stacked above child of root with lower z-order.
  EXPECT_TRUE(child_two->IsStackedAbove(child_one_b->GetNativeView()));
  EXPECT_TRUE(child_two->IsStackedAbove(grandchild_one->GetNativeView()));
  EXPECT_TRUE(grandchild_two->IsStackedAbove(child_one->GetNativeView()));
  EXPECT_TRUE(grandchild_two->IsStackedAbove(root_one->GetNativeView()));

  // False cases to verify function is not just returning true for all cases.
  EXPECT_FALSE(root_one->IsStackedAbove(grandchild_two->GetNativeView()));
  EXPECT_FALSE(root_one->IsStackedAbove(grandchild_one->GetNativeView()));
  EXPECT_FALSE(child_two->IsStackedAbove(grandchild_two->GetNativeView()));
  EXPECT_FALSE(child_one->IsStackedAbove(grandchild_two->GetNativeView()));
  EXPECT_FALSE(child_one_b->IsStackedAbove(child_two->GetNativeView()));
  EXPECT_FALSE(grandchild_one->IsStackedAbove(grandchild_two->GetNativeView()));
  EXPECT_FALSE(grandchild_one->IsStackedAbove(root_two->GetNativeView()));
  EXPECT_FALSE(child_one_b->IsStackedAbove(grandchild_one->GetNativeView()));
}

#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(ENABLE_DESKTOP_AURA) || BUILDFLAG(IS_MAC)

namespace {

class CompositingWidgetTest : public DesktopWidgetTest {};

}  // namespace

// Only test manually set opacity via kOpaque or kTranslucent.  kInferred is
// unpredictable and depends on the platform and window type.
TEST_F(CompositingWidgetTest, Transparency_DesktopWidgetOpaque) {}

TEST_F(CompositingWidgetTest, Transparency_DesktopWidgetTranslucent) {}

namespace {

class ScreenshotWidgetTest : public ViewsTestBase {};

}  // namespace

TEST_F(ScreenshotWidgetTest, CallsNativeWidget) {}

#endif  // BUILDFLAG(ENABLE_DESKTOP_AURA) || BUILDFLAG(IS_MAC)

}  // namespace views::test