diff options
Diffstat (limited to 'chromium/ui/views/widget')
29 files changed, 807 insertions, 145 deletions
diff --git a/chromium/ui/views/widget/desktop_aura/OWNERS b/chromium/ui/views/widget/desktop_aura/OWNERS index deec8966b35..9069e120fb6 100644 --- a/chromium/ui/views/widget/desktop_aura/OWNERS +++ b/chromium/ui/views/widget/desktop_aura/OWNERS @@ -1,3 +1,2 @@ -# Elliot is the owner of all the X11 stuff. -per-file *x11*=erg@chromium.org -per-file window_event_filter*=erg@chromium.org +per-file *x11*=thomasanderson@chromium.org +per-file window_event_filter*=thomasanderson@chromium.org diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc index 55dcdf780eb..ad0123acabc 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc @@ -7,7 +7,6 @@ #include <stddef.h> #include <stdint.h> -#include "base/event_types.h" #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -30,6 +29,7 @@ #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/events/platform/platform_event_source.h" +#include "ui/events/platform_event.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_atom_cache.h" diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc index 5158b0d4e37..3a7edcd000f 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc @@ -4,7 +4,6 @@ #include "ui/views/widget/desktop_aura/desktop_drop_target_win.h" -#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/win/win_util.h" #include "ui/aura/client/drag_drop_client.h" diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index cde45a41be5..bb391ec3b33 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h" @@ -348,7 +347,8 @@ void DesktopNativeWidgetAura::OnDesktopWindowTreeHostDestroyed( } void DesktopNativeWidgetAura::HandleActivationChanged(bool active) { - native_widget_delegate_->OnNativeWidgetActivationChanged(active); + if (!native_widget_delegate_->OnNativeWidgetActivationChanged(active)) + return; wm::ActivationClient* activation_client = wm::GetActivationClient(host_->window()); if (!activation_client) @@ -432,7 +432,7 @@ void DesktopNativeWidgetAura::InitNativeWidget( } host_.reset(desktop_window_tree_host_->AsWindowTreeHost()); } - desktop_window_tree_host_->Init(content_window_, params); + desktop_window_tree_host_->Init(params); host_->window()->AddChild(content_window_); host_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this); @@ -473,6 +473,8 @@ void DesktopNativeWidgetAura::InitNativeWidget( aura::client::SetCursorClient(host_->window(), cursor_manager_); } + host_->window()->SetName(params.name); + content_window_->SetName("DesktopNativeWidgetAura - content window"); desktop_window_tree_host_->OnNativeWidgetCreated(params); UpdateWindowTransparency(); diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 812a37dac77..fc4d17f3285 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h @@ -51,6 +51,8 @@ class FocusManagerEventHandler; class TooltipManagerAura; class WindowReorderer; +// DesktopNativeWidgetAura handles top-level widgets on Windows, Linux, and +// Chrome OS with mash. class VIEWS_EXPORT DesktopNativeWidgetAura : public internal::NativeWidgetPrivate, public aura::WindowDelegate, diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc index 0e8bd99e750..e9ddabeeda6 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc @@ -134,6 +134,31 @@ TEST_F(DesktopNativeWidgetAuraTest, WidgetNotVisibleOnlyWindowTreeHostShown) { EXPECT_FALSE(widget.IsVisible()); } +TEST_F(DesktopNativeWidgetAuraTest, DesktopAuraWindowShowFrameless) { + Widget widget; + Widget::InitParams init_params = + CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS); + init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + init_params.native_widget = new DesktopNativeWidgetAura(&widget); + widget.Init(init_params); + + // Make sure that changing frame type doesn't crash when there's no non-client + // view. + ASSERT_EQ(nullptr, widget.non_client_view()); + widget.DebugToggleFrameType(); + widget.Show(); + +#if defined(OS_WIN) + // On Windows also make sure that handling WM_SYSCOMMAND doesn't crash with + // custom frame. Frame type needs to be toggled again if Aero Glass is + // disabled. + if (widget.ShouldUseNativeFrame()) + widget.DebugToggleFrameType(); + SendMessage(widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(), + WM_SYSCOMMAND, SC_RESTORE, 0); +#endif // OS_WIN +} + // Verify that the cursor state is shared between two native widgets. TEST_F(DesktopNativeWidgetAuraTest, GlobalCursorState) { // Create two native widgets, each owning different root windows. @@ -276,8 +301,8 @@ TEST_F(DesktopNativeWidgetAuraTest, WidgetCanBeDestroyedFromNestedLoop) { base::Closure quit_runloop = run_loop.QuitClosure(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, - base::Bind(&QuitNestedLoopAndCloseWidget, base::Passed(&widget), - base::Unretained(&quit_runloop))); + base::BindOnce(&QuitNestedLoopAndCloseWidget, std::move(widget), + base::Unretained(&quit_runloop))); run_loop.Run(); } diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc index 17464aafc78..2822c8e41ef 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc @@ -6,6 +6,8 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/memory/protected_memory_cfi.h" +#include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "ui/aura/window.h" @@ -33,14 +35,22 @@ #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h" +#include <dlfcn.h> + namespace { // static -gfx::ICCProfile GetICCProfileFromBestMonitor() { +gfx::ICCProfile GetICCProfileForMonitor(int monitor) { gfx::ICCProfile icc_profile; if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless)) return icc_profile; - Atom property = gfx::GetAtom("_ICC_PROFILE"); + std::string atom_name; + if (monitor == 0) { + atom_name = "_ICC_PROFILE"; + } else { + atom_name = base::StringPrintf("_ICC_PROFILE_%d", monitor); + } + Atom property = gfx::GetAtom(atom_name.c_str()); if (property != x11::None) { Atom prop_type = x11::None; int prop_format = 0; @@ -108,7 +118,7 @@ namespace views { DesktopScreenX11::DesktopScreenX11() : xdisplay_(gfx::GetXDisplay()), x_root_window_(DefaultRootWindow(xdisplay_)), - has_xrandr_(false), + xrandr_version_(0), xrandr_event_base_(0), primary_display_index_(0), weak_factory_(this) { @@ -118,12 +128,11 @@ DesktopScreenX11::DesktopScreenX11() // use the new interface instead of the 1.2 one. int randr_version_major = 0; int randr_version_minor = 0; - has_xrandr_ = XRRQueryVersion( - xdisplay_, &randr_version_major, &randr_version_minor) && - randr_version_major == 1 && - randr_version_minor >= 3; - - if (has_xrandr_) { + if (XRRQueryVersion(xdisplay_, &randr_version_major, &randr_version_minor)) { + xrandr_version_ = randr_version_major * 100 + randr_version_minor; + } + // Need at least xrandr version 1.3. + if (xrandr_version_ >= 103) { int error_base_ignored = 0; XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored); @@ -144,7 +153,7 @@ DesktopScreenX11::DesktopScreenX11() DesktopScreenX11::~DesktopScreenX11() { if (views::LinuxUI::instance()) views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this); - if (has_xrandr_ && ui::PlatformEventSource::GetInstance()) + if (xrandr_version_ >= 103 && ui::PlatformEventSource::GetInstance()) ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); } @@ -297,7 +306,7 @@ DesktopScreenX11::DesktopScreenX11( const std::vector<display::Display>& test_displays) : xdisplay_(gfx::GetXDisplay()), x_root_window_(DefaultRootWindow(xdisplay_)), - has_xrandr_(false), + xrandr_version_(0), xrandr_event_base_(0), displays_(test_displays), primary_display_index_(0), @@ -306,8 +315,16 @@ DesktopScreenX11::DesktopScreenX11( views::LinuxUI::instance()->AddDeviceScaleFactorObserver(this); } +typedef XRRMonitorInfo* (*XRRGetMonitors)(::Display*, Window, bool, int*); +typedef void (*XRRFreeMonitors)(XRRMonitorInfo*); + +PROTECTED_MEMORY_SECTION base::ProtectedMemory<XRRGetMonitors> + g_XRRGetMonitors_ptr; +PROTECTED_MEMORY_SECTION base::ProtectedMemory<XRRFreeMonitors> + g_XRRFreeMonitors_ptr; + std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { - DCHECK(has_xrandr_); + DCHECK(xrandr_version_ >= 103); std::vector<display::Display> displays; gfx::XScopedPtr< XRRScreenResources, @@ -318,6 +335,30 @@ std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { return GetFallbackDisplayList(); } + std::map<RROutput, int> output_to_monitor; + if (xrandr_version_ >= 105) { + void* xrandr_lib = dlopen(NULL, RTLD_NOW); + if (xrandr_lib) { + static base::ProtectedMemory<XRRGetMonitors>::Initializer get_init( + &g_XRRGetMonitors_ptr, reinterpret_cast<XRRGetMonitors>( + dlsym(xrandr_lib, "XRRGetMonitors"))); + static base::ProtectedMemory<XRRFreeMonitors>::Initializer free_init( + &g_XRRFreeMonitors_ptr, reinterpret_cast<XRRFreeMonitors>( + dlsym(xrandr_lib, "XRRFreeMonitors"))); + if (*g_XRRGetMonitors_ptr && *g_XRRFreeMonitors_ptr) { + int nmonitors = 0; + XRRMonitorInfo* monitors = base::UnsanitizedCfiCall( + g_XRRGetMonitors_ptr)(xdisplay_, x_root_window_, false, &nmonitors); + for (int monitor = 0; monitor < nmonitors; monitor++) { + for (int j = 0; j < monitors[monitor].noutput; j++) { + output_to_monitor[monitors[monitor].outputs[j]] = monitor; + } + } + base::UnsanitizedCfiCall(g_XRRFreeMonitors_ptr)(monitors); + } + } + } + primary_display_index_ = 0; RROutput primary_display_id = XRRGetOutputPrimary(xdisplay_, x_root_window_); @@ -397,10 +438,10 @@ std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() { if (is_primary_display) primary_display_index_ = displays.size(); - // TODO(ccameron): Populate this based on this specific display. - // http://crbug.com/735613 if (!display::Display::HasForceColorProfile()) { - gfx::ICCProfile icc_profile = GetICCProfileFromBestMonitor(); + auto monitor_iter = output_to_monitor.find(output_id); + gfx::ICCProfile icc_profile = GetICCProfileForMonitor( + monitor_iter == output_to_monitor.end() ? 0 : monitor_iter->second); icc_profile.HistogramDisplay(display.id()); display.set_color_space(icc_profile.GetColorSpace()); } @@ -424,7 +465,7 @@ void DesktopScreenX11::RestartDelayedConfigurationTask() { void DesktopScreenX11::UpdateDisplays() { std::vector<display::Display> old_displays = displays_; - if (has_xrandr_) + if (xrandr_version_ > 103) SetDisplaysInternal(BuildDisplaysFromXRandRInfo()); else SetDisplaysInternal(GetFallbackDisplayList()); diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h index 842eb013535..6b7cb73d7f6 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h +++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h @@ -87,8 +87,8 @@ class VIEWS_EXPORT DesktopScreenX11 : public display::Screen, ::Display* xdisplay_; ::Window x_root_window_; - // Whether the x server supports the XRandR extension. - bool has_xrandr_; + // XRandR version. MAJOR * 100 + MINOR. Zero if no xrandr is present. + int xrandr_version_; // The base of the event numbers used to represent XRandr events used in // decoding events regarding output add/remove. diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h index 834ab5d2379..437a0294a4d 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h @@ -48,8 +48,7 @@ class VIEWS_EXPORT DesktopWindowTreeHost { // Sets up resources needed before the WindowEventDispatcher has been created. // It is expected this calls InitHost() on the WindowTreeHost. - virtual void Init(aura::Window* content_window, - const Widget::InitParams& params) = 0; + virtual void Init(const Widget::InitParams& params) = 0; // Invoked once the DesktopNativeWidgetAura has been created. virtual void OnNativeWidgetCreated(const Widget::InitParams& params) = 0; diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc new file mode 100644 index 00000000000..97b54ace8b5 --- /dev/null +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc @@ -0,0 +1,426 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h" + +#include "ui/aura/client/drag_drop_client.h" +#include "ui/aura/client/transient_window_client.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/gfx/geometry/dip_util.h" +#include "ui/platform_window/platform_window.h" +#include "ui/views/corewm/tooltip_aura.h" +#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" +#include "ui/views/window/native_frame_view.h" +#include "ui/wm/core/window_util.h" + +namespace views { + +DesktopWindowTreeHostPlatform::DesktopWindowTreeHostPlatform( + internal::NativeWidgetDelegate* native_widget_delegate, + DesktopNativeWidgetAura* desktop_native_widget_aura) + : native_widget_delegate_(native_widget_delegate), + desktop_native_widget_aura_(desktop_native_widget_aura) {} + +DesktopWindowTreeHostPlatform::~DesktopWindowTreeHostPlatform() { + DCHECK(got_on_closed_); + desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); + DestroyDispatcher(); +} + +void DesktopWindowTreeHostPlatform::SetBoundsInDIP( + const gfx::Rect& bounds_in_dip) { + DCHECK_NE(0, device_scale_factor()); + SetBoundsInPixels( + gfx::ConvertRectToPixel(device_scale_factor(), bounds_in_dip)); +} + +void DesktopWindowTreeHostPlatform::Init(const Widget::InitParams& params) { + CreateAndSetDefaultPlatformWindow(); + // TODO(sky): this should be |params.force_software_compositing|, figure out + // why it has to be true now. + const bool use_software_compositing = true; + CreateCompositor(viz::FrameSinkId(), use_software_compositing); + aura::WindowTreeHost::OnAcceleratedWidgetAvailable(); + InitHost(); + if (!params.bounds.IsEmpty()) + SetBoundsInDIP(params.bounds); + window()->Show(); +} + +void DesktopWindowTreeHostPlatform::OnNativeWidgetCreated( + const Widget::InitParams& params) { + native_widget_delegate_->OnNativeWidgetCreated(true); +} + +void DesktopWindowTreeHostPlatform::OnWidgetInitDone() {} + +void DesktopWindowTreeHostPlatform::OnActiveWindowChanged(bool active) {} + +std::unique_ptr<corewm::Tooltip> +DesktopWindowTreeHostPlatform::CreateTooltip() { + return std::make_unique<corewm::TooltipAura>(); +} + +std::unique_ptr<aura::client::DragDropClient> +DesktopWindowTreeHostPlatform::CreateDragDropClient( + DesktopNativeCursorManager* cursor_manager) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return nullptr; +} + +void DesktopWindowTreeHostPlatform::Close() { + if (waiting_for_close_now_) + return; + + // Hide while waiting for the close. + platform_window()->Hide(); + + waiting_for_close_now_ = true; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&DesktopWindowTreeHostPlatform::CloseNow, + weak_factory_.GetWeakPtr())); +} + +void DesktopWindowTreeHostPlatform::CloseNow() { + auto weak_ref = weak_factory_.GetWeakPtr(); + // Deleting the PlatformWindow may not result in OnClosed() being called, if + // not behave as though it was. + SetPlatformWindow(nullptr); + if (!weak_ref || got_on_closed_) + return; + + got_on_closed_ = true; + desktop_native_widget_aura_->OnHostClosed(); +} + +aura::WindowTreeHost* DesktopWindowTreeHostPlatform::AsWindowTreeHost() { + return this; +} + +void DesktopWindowTreeHostPlatform::ShowWindowWithState( + ui::WindowShowState show_state) { + if (compositor()) { + platform_window()->Show(); + compositor()->SetVisible(true); + } + + switch (show_state) { + case ui::SHOW_STATE_MAXIMIZED: + platform_window()->Maximize(); + break; + case ui::SHOW_STATE_MINIMIZED: + platform_window()->Minimize(); + break; + case ui::SHOW_STATE_FULLSCREEN: + // TODO(sky): this isn't necessarily the same as explicitly setting + // fullscreen. + platform_window()->ToggleFullscreen(); + break; + default: + break; + } + + if (native_widget_delegate_->CanActivate()) { + if (show_state != ui::SHOW_STATE_INACTIVE) + Activate(); + + // SetInitialFocus() should be always be called, even for + // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will + // do the right thing. + // Activate() might fail if the window is non-activatable. In this case, we + // should pass SHOW_STATE_INACTIVE to SetInitialFocus() to stop the initial + // focused view from getting focused. See https://crbug.com/515594 for + // example. + native_widget_delegate_->SetInitialFocus( + IsActive() ? show_state : ui::SHOW_STATE_INACTIVE); + } +} + +void DesktopWindowTreeHostPlatform::ShowMaximizedWithBounds( + const gfx::Rect& restored_bounds) { + // TODO: support |restored_bounds|. + ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); +} + +bool DesktopWindowTreeHostPlatform::IsVisible() const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return true; +} + +void DesktopWindowTreeHostPlatform::SetSize(const gfx::Size& size) { + gfx::Rect screen_bounds = + gfx::ConvertRectToDIP(device_scale_factor(), GetBoundsInPixels()); + screen_bounds.set_size(size); + SetBoundsInDIP(screen_bounds); +} + +void DesktopWindowTreeHostPlatform::StackAbove(aura::Window* window) { + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::StackAtTop() { + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::CenterWindow(const gfx::Size& size) { + gfx::Rect bounds_to_center_in = GetWorkAreaBoundsInScreen(); + + // If there is a transient parent and it fits |size|, then center over it. + aura::Window* content_window = desktop_native_widget_aura_->content_window(); + if (wm::GetTransientParent(content_window)) { + gfx::Rect transient_parent_bounds = + wm::GetTransientParent(content_window)->GetBoundsInScreen(); + if (transient_parent_bounds.height() >= size.height() && + transient_parent_bounds.width() >= size.width()) { + bounds_to_center_in = transient_parent_bounds; + } + } + + gfx::Rect resulting_bounds(bounds_to_center_in); + resulting_bounds.ClampToCenteredSize(size); + SetBoundsInDIP(resulting_bounds); +} + +void DesktopWindowTreeHostPlatform::GetWindowPlacement( + gfx::Rect* bounds, + ui::WindowShowState* show_state) const { + NOTIMPLEMENTED_LOG_ONCE(); + *bounds = gfx::Rect(0, 0, 640, 840); + *show_state = ui::SHOW_STATE_NORMAL; +} + +gfx::Rect DesktopWindowTreeHostPlatform::GetWindowBoundsInScreen() const { + gfx::Rect bounds = + gfx::ConvertRectToDIP(device_scale_factor(), GetBoundsInPixels()); + bounds += display::Screen::GetScreen() + ->GetDisplayNearestWindow(const_cast<aura::Window*>(window())) + .bounds() + .OffsetFromOrigin(); + return bounds; +} + +gfx::Rect DesktopWindowTreeHostPlatform::GetClientAreaBoundsInScreen() const { + // View-to-screen coordinate system transformations depend on this returning + // the full window bounds, for example View::ConvertPointToScreen(). + return GetWindowBoundsInScreen(); +} + +gfx::Rect DesktopWindowTreeHostPlatform::GetRestoredBounds() const { + NOTIMPLEMENTED_LOG_ONCE(); + return gfx::Rect(0, 0, 640, 840); +} + +std::string DesktopWindowTreeHostPlatform::GetWorkspace() const { + return std::string(); +} + +gfx::Rect DesktopWindowTreeHostPlatform::GetWorkAreaBoundsInScreen() const { + // TODO(sky): GetDisplayNearestWindow() should take a const aura::Window*. + return display::Screen::GetScreen() + ->GetDisplayNearestWindow(const_cast<aura::Window*>(window())) + .work_area(); +} + +void DesktopWindowTreeHostPlatform::SetShape( + std::unique_ptr<Widget::ShapeRects> native_shape) { + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::Activate() { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::Deactivate() { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::IsActive() const { + return is_active_; +} + +void DesktopWindowTreeHostPlatform::Maximize() { + platform_window()->Maximize(); +} + +void DesktopWindowTreeHostPlatform::Minimize() { + platform_window()->Minimize(); +} + +void DesktopWindowTreeHostPlatform::Restore() { + platform_window()->Restore(); +} + +bool DesktopWindowTreeHostPlatform::IsMaximized() const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +bool DesktopWindowTreeHostPlatform::IsMinimized() const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +bool DesktopWindowTreeHostPlatform::HasCapture() const { + return platform_window()->HasCapture(); +} + +void DesktopWindowTreeHostPlatform::SetAlwaysOnTop(bool always_on_top) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::IsAlwaysOnTop() const { + // TODO: needs PlatformWindow support. + return false; +} + +void DesktopWindowTreeHostPlatform::SetVisibleOnAllWorkspaces( + bool always_visible) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::IsVisibleOnAllWorkspaces() const { + // TODO: needs PlatformWindow support. + return false; +} + +bool DesktopWindowTreeHostPlatform::SetWindowTitle( + const base::string16& title) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +void DesktopWindowTreeHostPlatform::ClearNativeFocus() { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +Widget::MoveLoopResult DesktopWindowTreeHostPlatform::RunMoveLoop( + const gfx::Vector2d& drag_offset, + Widget::MoveLoopSource source, + Widget::MoveLoopEscapeBehavior escape_behavior) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return Widget::MOVE_LOOP_CANCELED; +} + +void DesktopWindowTreeHostPlatform::EndMoveLoop() { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::SetVisibilityChangedAnimationsEnabled( + bool value) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +NonClientFrameView* DesktopWindowTreeHostPlatform::CreateNonClientFrameView() { + return ShouldUseNativeFrame() ? new NativeFrameView(GetWidget()) : nullptr; +} + +bool DesktopWindowTreeHostPlatform::ShouldUseNativeFrame() const { + return false; +} + +bool DesktopWindowTreeHostPlatform::ShouldWindowContentsBeTransparent() const { + return false; +} + +void DesktopWindowTreeHostPlatform::FrameTypeChanged() {} + +void DesktopWindowTreeHostPlatform::SetFullscreen(bool fullscreen) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::IsFullscreen() const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +void DesktopWindowTreeHostPlatform::SetOpacity(float opacity) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::SetWindowIcons( + const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::InitModalType(ui::ModalType modal_type) { + // TODO: needs PlatformWindow support (alternatively, remove as + // DesktopWindowTreeHostX11 doesn't support at all). + NOTIMPLEMENTED_LOG_ONCE(); +} + +void DesktopWindowTreeHostPlatform::FlashFrame(bool flash_frame) { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::IsAnimatingClosed() const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +bool DesktopWindowTreeHostPlatform::IsTranslucentWindowOpacitySupported() + const { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + +void DesktopWindowTreeHostPlatform::SizeConstraintsChanged() { + // TODO: needs PlatformWindow support. + NOTIMPLEMENTED_LOG_ONCE(); +} + +bool DesktopWindowTreeHostPlatform::ShouldUpdateWindowTransparency() const { + return false; +} + +bool DesktopWindowTreeHostPlatform::ShouldUseDesktopNativeCursorManager() + const { + return true; +} + +bool DesktopWindowTreeHostPlatform::ShouldCreateVisibilityController() const { + return true; +} + +void DesktopWindowTreeHostPlatform::OnClosed() { + got_on_closed_ = true; + desktop_native_widget_aura_->OnHostClosed(); +} + +void DesktopWindowTreeHostPlatform::OnCloseRequest() { + GetWidget()->Close(); +} + +void DesktopWindowTreeHostPlatform::OnActivationChanged(bool active) { + is_active_ = active; + aura::WindowTreeHostPlatform::OnActivationChanged(active); + desktop_native_widget_aura_->HandleActivationChanged(active); +} + +Widget* DesktopWindowTreeHostPlatform::GetWidget() { + return native_widget_delegate_->AsWidget(); +} + +} // namespace views diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h new file mode 100644 index 00000000000..e9bc864128e --- /dev/null +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h @@ -0,0 +1,116 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_PLATFORM_H_ +#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_PLATFORM_H_ + +#include "base/memory/weak_ptr.h" +#include "ui/aura/window_tree_host_platform.h" +#include "ui/views/views_export.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h" + +namespace views { + +class VIEWS_EXPORT DesktopWindowTreeHostPlatform + : public aura::WindowTreeHostPlatform, + public DesktopWindowTreeHost { + public: + DesktopWindowTreeHostPlatform( + internal::NativeWidgetDelegate* native_widget_delegate, + DesktopNativeWidgetAura* desktop_native_widget_aura); + ~DesktopWindowTreeHostPlatform() override; + + void SetBoundsInDIP(const gfx::Rect& bounds_in_dip); + + // DesktopWindowTreeHost: + void Init(const Widget::InitParams& params) override; + void OnNativeWidgetCreated(const Widget::InitParams& params) override; + void OnWidgetInitDone() override; + void OnActiveWindowChanged(bool active) override; + std::unique_ptr<corewm::Tooltip> CreateTooltip() override; + std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient( + DesktopNativeCursorManager* cursor_manager) override; + void Close() override; + void CloseNow() override; + aura::WindowTreeHost* AsWindowTreeHost() override; + void ShowWindowWithState(ui::WindowShowState show_state) override; + void ShowMaximizedWithBounds(const gfx::Rect& restored_bounds) override; + bool IsVisible() const override; + void SetSize(const gfx::Size& size) override; + void StackAbove(aura::Window* window) override; + void StackAtTop() override; + void CenterWindow(const gfx::Size& size) override; + void GetWindowPlacement(gfx::Rect* bounds, + ui::WindowShowState* show_state) const override; + gfx::Rect GetWindowBoundsInScreen() const override; + gfx::Rect GetClientAreaBoundsInScreen() const override; + gfx::Rect GetRestoredBounds() const override; + std::string GetWorkspace() const override; + gfx::Rect GetWorkAreaBoundsInScreen() const override; + void SetShape(std::unique_ptr<Widget::ShapeRects> native_shape) override; + void Activate() override; + void Deactivate() override; + bool IsActive() const override; + void Maximize() override; + void Minimize() override; + void Restore() override; + bool IsMaximized() const override; + bool IsMinimized() const override; + bool HasCapture() const override; + void SetAlwaysOnTop(bool always_on_top) override; + bool IsAlwaysOnTop() const override; + void SetVisibleOnAllWorkspaces(bool always_visible) override; + bool IsVisibleOnAllWorkspaces() const override; + bool SetWindowTitle(const base::string16& title) override; + void ClearNativeFocus() override; + Widget::MoveLoopResult RunMoveLoop( + const gfx::Vector2d& drag_offset, + Widget::MoveLoopSource source, + Widget::MoveLoopEscapeBehavior escape_behavior) override; + void EndMoveLoop() override; + void SetVisibilityChangedAnimationsEnabled(bool value) override; + NonClientFrameView* CreateNonClientFrameView() override; + bool ShouldUseNativeFrame() const override; + bool ShouldWindowContentsBeTransparent() const override; + void FrameTypeChanged() override; + void SetFullscreen(bool fullscreen) override; + bool IsFullscreen() const override; + void SetOpacity(float opacity) override; + void SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) override; + void InitModalType(ui::ModalType modal_type) override; + void FlashFrame(bool flash_frame) override; + bool IsAnimatingClosed() const override; + bool IsTranslucentWindowOpacitySupported() const override; + void SizeConstraintsChanged() override; + bool ShouldUpdateWindowTransparency() const override; + bool ShouldUseDesktopNativeCursorManager() const override; + bool ShouldCreateVisibilityController() const override; + + // WindowTreeHostPlatform: + void OnClosed() override; + void OnCloseRequest() override; + void OnActivationChanged(bool active) override; + + private: + Widget* GetWidget(); + + internal::NativeWidgetDelegate* const native_widget_delegate_; + DesktopNativeWidgetAura* const desktop_native_widget_aura_; + + // Set to true when Close() is called. + bool waiting_for_close_now_ = false; + + bool got_on_closed_ = false; + + bool is_active_ = false; + + base::WeakPtrFactory<DesktopWindowTreeHostPlatform> weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostPlatform); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_PLATFORM_H_ diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 19f103c0385..c8f868bf416 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc @@ -81,7 +81,6 @@ DesktopWindowTreeHostWin::DesktopWindowTreeHostWin( : message_handler_(new HWNDMessageHandler(this)), native_widget_delegate_(native_widget_delegate), desktop_native_widget_aura_(desktop_native_widget_aura), - content_window_(NULL), drag_drop_client_(NULL), should_animate_window_close_(false), pending_close_(false), @@ -90,7 +89,6 @@ DesktopWindowTreeHostWin::DesktopWindowTreeHostWin( } DesktopWindowTreeHostWin::~DesktopWindowTreeHostWin() { - // WARNING: |content_window_| has been destroyed by the time we get here. desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); DestroyDispatcher(); } @@ -108,16 +106,13 @@ aura::Window* DesktopWindowTreeHostWin::GetContentWindowForHWND(HWND hwnd) { //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHostWin, DesktopWindowTreeHost implementation: -void DesktopWindowTreeHostWin::Init(aura::Window* content_window, - const Widget::InitParams& params) { - // TODO(beng): SetInitParams(). - content_window_ = content_window; +void DesktopWindowTreeHostWin::Init(const Widget::InitParams& params) { wants_mouse_events_when_inactive_ = params.wants_mouse_events_when_inactive; - wm::SetAnimationHost(content_window_, this); + wm::SetAnimationHost(content_window(), this); if (params.type == Widget::InitParams::TYPE_WINDOW && !params.remove_standard_frame) - content_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); + content_window()->SetProperty(aura::client::kAnimationsDisabledKey, true); ConfigureWindowStyles(message_handler_.get(), params, GetWidget()->widget_delegate(), @@ -148,12 +143,12 @@ void DesktopWindowTreeHostWin::OnNativeWidgetCreated( if (cursor_client) is_cursor_visible_ = cursor_client->IsCursorVisible(); - window()->SetProperty(kContentWindowForRootWindow, content_window_); + window()->SetProperty(kContentWindowForRootWindow, content_window()); window()->SetProperty(kDesktopWindowTreeHostKey, this); should_animate_window_close_ = - content_window_->type() != aura::client::WINDOW_TYPE_NORMAL && - !wm::WindowAnimationsDisabled(content_window_); + content_window()->type() != aura::client::WINDOW_TYPE_NORMAL && + !wm::WindowAnimationsDisabled(content_window()); // TODO this is not invoked *after* Init(), but should be ok. SetWindowTransparency(); @@ -181,7 +176,7 @@ void DesktopWindowTreeHostWin::Close() { if (should_animate_window_close_) { pending_close_ = true; const bool is_animating = - content_window_->layer()->GetAnimator()->IsAnimatingProperty( + content_window()->layer()->GetAnimator()->IsAnimatingProperty( ui::LayerAnimationElement::VISIBILITY); // Animation may not start for a number of reasons. if (!is_animating) @@ -401,7 +396,7 @@ void DesktopWindowTreeHostWin::EndMoveLoop() { void DesktopWindowTreeHostWin::SetVisibilityChangedAnimationsEnabled( bool value) { message_handler_->SetVisibilityChangedAnimationsEnabled(value); - content_window_->SetProperty(aura::client::kAnimationsDisabledKey, !value); + content_window()->SetProperty(aura::client::kAnimationsDisabledKey, !value); } NonClientFrameView* DesktopWindowTreeHostWin::CreateNonClientFrameView() { @@ -434,10 +429,10 @@ void DesktopWindowTreeHostWin::SetFullscreen(bool fullscreen) { // TODO(sky): workaround for ScopedFullscreenVisibility showing window // directly. Instead of this should listen for visibility changes and then // update window. - if (message_handler_->IsVisible() && !content_window_->TargetVisibility()) { + if (message_handler_->IsVisible() && !content_window()->TargetVisibility()) { if (compositor()) compositor()->SetVisible(true); - content_window_->Show(); + content_window()->Show(); } SetWindowTransparency(); } @@ -447,7 +442,7 @@ bool DesktopWindowTreeHostWin::IsFullscreen() const { } void DesktopWindowTreeHostWin::SetOpacity(float opacity) { - content_window_->layer()->SetOpacity(opacity); + content_window()->layer()->SetOpacity(opacity); } void DesktopWindowTreeHostWin::SetWindowIcons( @@ -577,6 +572,10 @@ void DesktopWindowTreeHostWin::ReleaseSystemKeyEventCapture() { keyboard_hook_.reset(); } +bool DesktopWindowTreeHostWin::IsKeyLocked(int native_key_code) { + return keyboard_hook_ && keyboard_hook_->IsKeyLocked(native_key_code); +} + void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) { ui::CursorLoaderWin cursor_loader; cursor_loader.SetPlatformCursor(&cursor); @@ -727,7 +726,8 @@ gfx::Size DesktopWindowTreeHostWin::DIPToScreenSize( } void DesktopWindowTreeHostWin::ResetWindowControls() { - GetWidget()->non_client_view()->ResetWindowControls(); + if (GetWidget()->non_client_view()) + GetWidget()->non_client_view()->ResetWindowControls(); } gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() { @@ -845,7 +845,8 @@ void DesktopWindowTreeHostWin::HandleFrameChanged() { CheckForMonitorChange(); SetWindowTransparency(); // Replace the frame and layout the contents. - GetWidget()->non_client_view()->UpdateFrame(); + if (GetWidget()->non_client_view()) + GetWidget()->non_client_view()->UpdateFrame(); } void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) { @@ -856,9 +857,9 @@ void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) { // TODO(beng): inform the native_widget_delegate_. } -bool DesktopWindowTreeHostWin::HandleMouseEvent(const ui::MouseEvent& event) { - SendEventToSink(const_cast<ui::MouseEvent*>(&event)); - return event.handled(); +bool DesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { + SendEventToSink(event); + return event->handled(); } bool DesktopWindowTreeHostWin::HandlePointerEvent(ui::PointerEvent* event) { @@ -870,8 +871,7 @@ void DesktopWindowTreeHostWin::HandleKeyEvent(ui::KeyEvent* event) { SendEventToSink(event); } -void DesktopWindowTreeHostWin::HandleTouchEvent( - const ui::TouchEvent& event) { +void DesktopWindowTreeHostWin::HandleTouchEvent(ui::TouchEvent* event) { // HWNDMessageHandler asynchronously processes touch events. Because of this // it's possible for the aura::WindowEventDispatcher to have been destroyed // by the time we attempt to process them. @@ -885,10 +885,10 @@ void DesktopWindowTreeHostWin::HandleTouchEvent( DesktopWindowTreeHostWin* target = host->window()->GetProperty(kDesktopWindowTreeHostKey); if (target && target->HasCapture() && target != this) { - POINT target_location(event.location().ToPOINT()); + POINT target_location(event->location().ToPOINT()); ClientToScreen(GetHWND(), &target_location); ScreenToClient(target->GetHWND(), &target_location); - ui::TouchEvent target_event(event, static_cast<View*>(NULL), + ui::TouchEvent target_event(*event, static_cast<View*>(NULL), static_cast<View*>(NULL)); target_event.set_location(gfx::Point(target_location)); target_event.set_root_location(target_event.location()); @@ -896,7 +896,7 @@ void DesktopWindowTreeHostWin::HandleTouchEvent( return; } } - SendEventToSink(const_cast<ui::TouchEvent*>(&event)); + SendEventToSink(event); } bool DesktopWindowTreeHostWin::HandleIMEMessage(UINT message, @@ -949,10 +949,14 @@ void DesktopWindowTreeHostWin::PostHandleMSG(UINT message, LPARAM l_param) { } -bool DesktopWindowTreeHostWin::HandleScrollEvent( - const ui::ScrollEvent& event) { - SendEventToSink(const_cast<ui::ScrollEvent*>(&event)); - return event.handled(); +bool DesktopWindowTreeHostWin::HandleScrollEvent(ui::ScrollEvent* event) { + SendEventToSink(event); + return event->handled(); +} + +bool DesktopWindowTreeHostWin::HandleGestureEvent(ui::GestureEvent* event) { + SendEventToSink(event); + return event->handled(); } void DesktopWindowTreeHostWin::HandleWindowSizeChanging() { @@ -965,16 +969,18 @@ void DesktopWindowTreeHostWin::HandleWindowSizeUnchanged() { // changed (can occur on Windows 10 when snapping a window to the side of // the screen). In that case do a resize to the current size to reenable // swaps. - if (compositor()) { - compositor()->SetScaleAndSize( - compositor()->device_scale_factor(), - message_handler_->GetClientAreaBounds().size(), - window()->GetLocalSurfaceId()); - } + if (compositor()) + compositor()->ReenableSwap(); } void DesktopWindowTreeHostWin::HandleWindowScaleFactorChanged( float window_scale_factor) { + // TODO(ccameron): This will violate surface invariants, and is insane. + // Shouldn't the scale factor and window pixel size changes be sent + // atomically? And how does this interact with updates to display::Display? + // Should we expect the display::Display to be updated before this? If so, + // why can't we use the DisplayObserver that the base WindowTreeHost is + // using? if (compositor()) { compositor()->SetScaleAndSize( window_scale_factor, message_handler_->GetClientAreaBounds().size(), @@ -1002,7 +1008,7 @@ void DesktopWindowTreeHostWin::SetWindowTransparency() { compositor()->SetBackgroundColor(transparent ? SK_ColorTRANSPARENT : SK_ColorWHITE); window()->SetTransparent(transparent); - content_window_->SetTransparent(transparent); + content_window()->SetTransparent(transparent); } bool DesktopWindowTreeHostWin::IsModalWindowActive() const { @@ -1031,6 +1037,10 @@ void DesktopWindowTreeHostWin::CheckForMonitorChange() { OnHostDisplayChanged(); } +aura::Window* DesktopWindowTreeHostWin::content_window() { + return desktop_native_widget_aura_->content_window(); +} + //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHost, public: diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index 732f492c102..4120d3ae63f 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h @@ -56,8 +56,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin protected: // Overridden from DesktopWindowTreeHost: - void Init(aura::Window* content_window, - const Widget::InitParams& params) override; + void Init(const Widget::InitParams& params) override; void OnNativeWidgetCreated(const Widget::InitParams& params) override; void OnActiveWindowChanged(bool active) override; void OnWidgetInitDone() override; @@ -134,6 +133,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin bool CaptureSystemKeyEventsImpl( base::Optional<base::flat_set<int>> keys_codes) override; void ReleaseSystemKeyEventCapture() override; + bool IsKeyLocked(int native_key_code) override; void SetCursorNative(gfx::NativeCursor cursor) override; void OnCursorVisibilityChangedNative(bool show) override; void MoveCursorToScreenLocationInPixels( @@ -193,10 +193,10 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin void HandleFrameChanged() override; void HandleNativeFocus(HWND last_focused_window) override; void HandleNativeBlur(HWND focused_window) override; - bool HandleMouseEvent(const ui::MouseEvent& event) override; + bool HandleMouseEvent(ui::MouseEvent* event) override; bool HandlePointerEvent(ui::PointerEvent* event) override; void HandleKeyEvent(ui::KeyEvent* event) override; - void HandleTouchEvent(const ui::TouchEvent& event) override; + void HandleTouchEvent(ui::TouchEvent* event) override; bool HandleIMEMessage(UINT message, WPARAM w_param, LPARAM l_param, @@ -213,7 +213,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin LPARAM l_param, LRESULT* result) override; void PostHandleMSG(UINT message, WPARAM w_param, LPARAM l_param) override; - bool HandleScrollEvent(const ui::ScrollEvent& event) override; + bool HandleScrollEvent(ui::ScrollEvent* event) override; + bool HandleGestureEvent(ui::GestureEvent* event) override; void HandleWindowSizeChanging() override; void HandleWindowSizeUnchanged() override; void HandleWindowScaleFactorChanged(float window_scale_factor) override; @@ -232,6 +233,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin // has changed, and, if so, inform the aura::WindowTreeHost. void CheckForMonitorChange(); + // Accessor for DesktopNativeWidgetAura::content_window(). + aura::Window* content_window(); + HMONITOR last_monitor_from_window_ = nullptr; std::unique_ptr<HWNDMessageHandler> message_handler_; @@ -243,8 +247,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin DesktopNativeWidgetAura* desktop_native_widget_aura_; - aura::Window* content_window_; - // Owned by DesktopNativeWidgetAura. DesktopDragDropClientWin* drag_drop_client_; diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index f8550833ee6..806360dbc69 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc @@ -148,7 +148,6 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( drag_drop_client_(NULL), native_widget_delegate_(native_widget_delegate), desktop_native_widget_aura_(desktop_native_widget_aura), - content_window_(NULL), window_parent_(NULL), custom_window_shape_(false), urgency_hint_set_(false), @@ -388,13 +387,11 @@ void DesktopWindowTreeHostX11::CleanUpWindowList( //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHostX11, DesktopWindowTreeHost implementation: -void DesktopWindowTreeHostX11::Init(aura::Window* content_window, - const Widget::InitParams& params) { - content_window_ = content_window; +void DesktopWindowTreeHostX11::Init(const Widget::InitParams& params) { activatable_ = (params.activatable == Widget::InitParams::ACTIVATABLE_YES); if (params.type == Widget::InitParams::TYPE_WINDOW) - content_window_->SetProperty(aura::client::kAnimationsDisabledKey, true); + content_window()->SetProperty(aura::client::kAnimationsDisabledKey, true); // TODO(erg): Check whether we *should* be building a WindowTreeHost here, or // whether we should be proxying requests to another DRWHL. @@ -414,7 +411,7 @@ void DesktopWindowTreeHostX11::Init(aura::Window* content_window, void DesktopWindowTreeHostX11::OnNativeWidgetCreated( const Widget::InitParams& params) { - window()->SetProperty(kViewsWindowForRootWindow, content_window_); + window()->SetProperty(kViewsWindowForRootWindow, content_window()); window()->SetProperty(kHostForRootWindow, this); // Ensure that the X11DesktopHandler exists so that it tracks create/destroy @@ -518,7 +515,7 @@ aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { void DesktopWindowTreeHostX11::ShowWindowWithState( ui::WindowShowState show_state) { if (compositor()) - compositor()->SetVisible(true); + SetVisible(true); if (!IsVisible() || !window_mapped_in_server_) MapWindow(show_state); @@ -605,9 +602,9 @@ void DesktopWindowTreeHostX11::CenterWindow(const gfx::Size& size) { // If |window_|'s transient parent bounds are big enough to contain |size|, // use them instead. - if (wm::GetTransientParent(content_window_)) { + if (wm::GetTransientParent(content_window())) { gfx::Rect transient_parent_rect = - wm::GetTransientParent(content_window_)->GetBoundsInScreen(); + wm::GetTransientParent(content_window())->GetBoundsInScreen(); if (transient_parent_rect.height() >= size.height() && transient_parent_rect.width() >= size.width()) { parent_bounds_in_pixels = ToPixelRect(transient_parent_rect); @@ -875,6 +872,13 @@ bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const { return is_always_on_top_; } +void DesktopWindowTreeHostX11::SetVisible(bool visible) { + if (compositor()) + compositor()->SetVisible(visible); + if (IsVisible() != visible) + native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible); +} + void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) { ui::SetWMSpecState(xwindow_, always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), x11::None); @@ -932,12 +936,13 @@ bool DesktopWindowTreeHostX11::SetWindowTitle(const base::string16& title) { void DesktopWindowTreeHostX11::ClearNativeFocus() { // This method is weird and misnamed. Instead of clearing the native focus, - // it sets the focus to our |content_window_|, which will trigger a cascade + // it sets the focus to our content_window(), which will trigger a cascade // of focus changes into views. - if (content_window_ && aura::client::GetFocusClient(content_window_) && - content_window_->Contains( - aura::client::GetFocusClient(content_window_)->GetFocusedWindow())) { - aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_); + if (content_window() && aura::client::GetFocusClient(content_window()) && + content_window()->Contains( + aura::client::GetFocusClient(content_window())->GetFocusedWindow())) { + aura::client::GetFocusClient(content_window()) + ->FocusWindow(content_window()); } } @@ -948,7 +953,7 @@ Widget::MoveLoopResult DesktopWindowTreeHostX11::RunMoveLoop( wm::WindowMoveSource window_move_source = source == Widget::MOVE_LOOP_SOURCE_MOUSE ? wm::WINDOW_MOVE_SOURCE_MOUSE : wm::WINDOW_MOVE_SOURCE_TOUCH; - if (x11_window_move_client_->RunMoveLoop(content_window_, drag_offset, + if (x11_window_move_client_->RunMoveLoop(content_window(), drag_offset, window_move_source) == wm::MOVE_SUCCESSFUL) return Widget::MOVE_LOOP_SUCCESSFUL; @@ -1179,15 +1184,14 @@ gfx::AcceleratedWidget DesktopWindowTreeHostX11::GetAcceleratedWidget() { void DesktopWindowTreeHostX11::ShowImpl() { ShowWindowWithState(ui::SHOW_STATE_NORMAL); - native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); } void DesktopWindowTreeHostX11::HideImpl() { if (IsVisible()) { XWithdrawWindow(xdisplay_, xwindow_, 0); window_mapped_in_client_ = false; + native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); } - native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); } gfx::Rect DesktopWindowTreeHostX11::GetBoundsInPixels() const { @@ -1310,6 +1314,10 @@ void DesktopWindowTreeHostX11::ReleaseSystemKeyEventCapture() { keyboard_hook_.reset(); } +bool DesktopWindowTreeHostX11::IsKeyLocked(int native_key_code) { + return keyboard_hook_ && keyboard_hook_->IsKeyLocked(native_key_code); +} + void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { XDefineCursor(xdisplay_, xwindow_, cursor.platform()); } @@ -1628,11 +1636,11 @@ void DesktopWindowTreeHostX11::OnWMStateUpdated() { // minimized. if (is_minimized != was_minimized) { if (is_minimized) { - compositor()->SetVisible(false); - content_window_->Hide(); + SetVisible(false); + content_window()->Hide(); } else { - content_window_->Show(); - compositor()->SetVisible(true); + content_window()->Show(); + SetVisible(true); } } @@ -1759,10 +1767,10 @@ void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) { // events on the ash desktop are clicking in what Windows considers to be a // non client area.) Likewise, we won't want to do the following in any // WindowTreeHost that hosts ash. - if (content_window_ && content_window_->delegate()) { + if (content_window() && content_window()->delegate()) { int flags = event->flags(); int hit_test_code = - content_window_->delegate()->GetNonClientComponent(event->location()); + content_window()->delegate()->GetNonClientComponent(event->location()); if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE) flags |= ui::EF_IS_NON_CLIENT; event->set_flags(flags); @@ -1927,7 +1935,7 @@ void DesktopWindowTreeHostX11::SetWindowTransparency() { compositor()->SetBackgroundColor(use_argb_visual_ ? SK_ColorTRANSPARENT : SK_ColorWHITE); window()->SetTransparent(use_argb_visual_); - content_window_->SetTransparent(use_argb_visual_); + content_window()->SetTransparent(use_argb_visual_); } void DesktopWindowTreeHostX11::Relayout() { @@ -2338,6 +2346,10 @@ void DesktopWindowTreeHostX11::RestartDelayedResizeTask() { FROM_HERE, delayed_resize_task_.callback()); } +aura::Window* DesktopWindowTreeHostX11::content_window() { + return desktop_native_widget_aura_->content_window(); +} + //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHost, public: diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h index 021a1d9ad2b..79d677baa9f 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h @@ -51,7 +51,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 DesktopNativeWidgetAura* desktop_native_widget_aura); ~DesktopWindowTreeHostX11() override; - // A way of converting an X11 |xid| host window into a |content_window_|. + // A way of converting an X11 |xid| host window into the content_window() + // of the associated DesktopNativeWidgetAura. static aura::Window* GetContentWindowForXID(XID xid); // A way of converting an X11 |xid| host window into this object. @@ -88,8 +89,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 protected: // Overridden from DesktopWindowTreeHost: - void Init(aura::Window* content_window, - const Widget::InitParams& params) override; + void Init(const Widget::InitParams& params) override; void OnNativeWidgetCreated(const Widget::InitParams& params) override; void OnWidgetInitDone() override; void OnActiveWindowChanged(bool active) override; @@ -167,6 +167,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 bool CaptureSystemKeyEventsImpl( base::Optional<base::flat_set<int>> keys_codes) override; void ReleaseSystemKeyEventCapture() override; + bool IsKeyLocked(int native_key_code) override; void SetCursorNative(gfx::NativeCursor cursor) override; void MoveCursorToScreenLocationInPixels( const gfx::Point& location_in_pixels) override; @@ -188,7 +189,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 // initialization related to talking to the X11 server. void InitX11Window(const Widget::InitParams& params); - // Creates an aura::WindowEventDispatcher to contain the |content_window|, + // Creates an aura::WindowEventDispatcher to contain the content_window() // along with all aura client objects that direct behavior. aura::WindowEventDispatcher* InitDispatcher(const Widget::InitParams& params); @@ -282,6 +283,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 // the queue) and adds it back at the end of the queue. void RestartDelayedResizeTask(); + // Set visibility and fire OnNativeWidgetVisibilityChanged() if it changed. + void SetVisible(bool visible); + + // Accessor for DesktopNativeWidgetAura::content_window(). + aura::Window* content_window(); + // X11 things // The display and the native X window hosting the root window. XDisplay* xdisplay_; @@ -352,8 +359,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 DesktopNativeWidgetAura* desktop_native_widget_aura_; - aura::Window* content_window_; - // We can optionally have a parent which can order us to close, or own // children who we're responsible for closing when we CloseNow(). DesktopWindowTreeHostX11* window_parent_; diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc index 94d8a5768b1..73507805813 100644 --- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc +++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc @@ -8,7 +8,6 @@ #include "base/command_line.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc index 1e17f0f4cf4..e0a11a00d46 100644 --- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc +++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc @@ -11,7 +11,6 @@ #include <vector> #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "third_party/skia/include/core/SkRect.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" diff --git a/chromium/ui/views/widget/native_widget_aura.cc b/chromium/ui/views/widget/native_widget_aura.cc index a9be3abbd01..76f19a26a0b 100644 --- a/chromium/ui/views/widget/native_widget_aura.cc +++ b/chromium/ui/views/widget/native_widget_aura.cc @@ -6,7 +6,6 @@ #include "base/bind.h" #include "base/location.h" -#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -147,7 +146,6 @@ void NativeWidgetAura::SetShadowElevationFromInitParams( // NativeWidgetAura, internal::NativeWidgetPrivate implementation: void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { - // Aura needs to know which desktop (Ash or regular) will manage this widget. // See Widget::InitParams::context for details. DCHECK(params.parent || params.context); @@ -520,8 +518,8 @@ void NativeWidgetAura::Close() { if (!close_widget_factory_.HasWeakPtrs()) { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&NativeWidgetAura::CloseNow, - close_widget_factory_.GetWeakPtr())); + FROM_HERE, base::BindOnce(&NativeWidgetAura::CloseNow, + close_widget_factory_.GetWeakPtr())); } } diff --git a/chromium/ui/views/widget/native_widget_aura_interactive_uitest.cc b/chromium/ui/views/widget/native_widget_aura_interactive_uitest.cc index 28bfeac0fef..b4de50c7e2b 100644 --- a/chromium/ui/views/widget/native_widget_aura_interactive_uitest.cc +++ b/chromium/ui/views/widget/native_widget_aura_interactive_uitest.cc @@ -4,7 +4,6 @@ #include "ui/views/widget/native_widget_aura.h" -#include "base/memory/ptr_util.h" #include "ui/aura/window.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/test/native_widget_factory.h" diff --git a/chromium/ui/views/widget/native_widget_delegate.h b/chromium/ui/views/widget/native_widget_delegate.h index 8f2e56a4a4d..018bc2ce9d3 100644 --- a/chromium/ui/views/widget/native_widget_delegate.h +++ b/chromium/ui/views/widget/native_widget_delegate.h @@ -56,7 +56,8 @@ class VIEWS_EXPORT NativeWidgetDelegate { virtual bool IsAlwaysRenderAsActive() const = 0; // Called when the activation state of a window has changed. - virtual void OnNativeWidgetActivationChanged(bool active) = 0; + // Returns true if this event should be handled. + virtual bool OnNativeWidgetActivationChanged(bool active) = 0; // Called when native focus moves from one native view to another. virtual void OnNativeFocus() = 0; diff --git a/chromium/ui/views/widget/native_widget_mac.mm b/chromium/ui/views/widget/native_widget_mac.mm index f5db821551e..223eb1191d1 100644 --- a/chromium/ui/views/widget/native_widget_mac.mm +++ b/chromium/ui/views/widget/native_widget_mac.mm @@ -8,6 +8,7 @@ #include <utility> +#include "base/command_line.h" #import "base/mac/bind_objc_block.h" #include "base/mac/foundation_util.h" #include "base/mac/scoped_nsobject.h" @@ -16,6 +17,7 @@ #include "components/crash/core/common/crash_key.h" #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" #import "ui/base/cocoa/window_size_constants.h" +#include "ui/base/ui_base_switches.h" #include "ui/gfx/font_list.h" #import "ui/gfx/mac/coordinate_conversion.h" #import "ui/gfx/mac/nswindow_frame_controls.h" @@ -46,6 +48,11 @@ namespace views { namespace { +bool AreModalAnimationsEnabled() { + return !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableModalAnimations); +} + NSInteger StyleMaskForParams(const Widget::InitParams& params) { // If the Widget is modal, it will be displayed as a sheet. This works best if // it has NSTitledWindowMask. For example, with NSBorderlessWindowMask, the @@ -332,11 +339,8 @@ void NativeWidgetMac::SetSize(const gfx::Size& size) { } void NativeWidgetMac::StackAbove(gfx::NativeView native_view) { - // NativeWidgetMac currently only has machinery for stacking windows, and only - // stacks child windows above parents. That's currently all this is used for. - // DCHECK if a new use case comes along. - DCHECK(bridge_ && bridge_->parent()); - DCHECK_EQ([native_view window], bridge_->parent()->GetNSWindow()); + NSInteger view_parent = native_view.window.windowNumber; + [GetNativeWindow() orderWindow:NSWindowAbove relativeTo:view_parent]; } void NativeWidgetMac::StackAtTop() { @@ -365,7 +369,8 @@ void NativeWidgetMac::Close() { } // For other modal types, animate the close. - if (bridge_->animate() && delegate_->IsModal()) { + if (bridge_->animate() && AreModalAnimationsEnabled() && + delegate_->IsModal()) { [ViewsNSWindowCloseAnimator closeWindowWithAnimation:window]; return; } diff --git a/chromium/ui/views/widget/root_view.cc b/chromium/ui/views/widget/root_view.cc index 5d0dddf78c7..d07c9ba57f4 100644 --- a/chromium/ui/views/widget/root_view.cc +++ b/chromium/ui/views/widget/root_view.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "build/build_config.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/cursor/cursor.h" #include "ui/base/dragdrop/drag_drop_types.h" @@ -73,7 +74,8 @@ class PreEventDispatchHandler : public ui::EventHandler { View* v = NULL; if (owner_->GetFocusManager()) // Can be NULL in unittests. v = owner_->GetFocusManager()->GetFocusedView(); - +// macOS doesn't have keyboard-triggered context menus. +#if !defined(OS_MACOSX) // Special case to handle keyboard-triggered context menus. if (v && v->enabled() && ((event->key_code() == ui::VKEY_APPS) || (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) { @@ -88,6 +90,7 @@ class PreEventDispatchHandler : public ui::EventHandler { v->ShowContextMenu(location, ui::MENU_SOURCE_KEYBOARD); event->StopPropagation(); } +#endif } View* owner_; diff --git a/chromium/ui/views/widget/root_view_unittest.cc b/chromium/ui/views/widget/root_view_unittest.cc index 9f0cd55a02f..82959179009 100644 --- a/chromium/ui/views/widget/root_view_unittest.cc +++ b/chromium/ui/views/widget/root_view_unittest.cc @@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "build/build_config.h" #include "ui/events/event_utils.h" #include "ui/views/context_menu_controller.h" #include "ui/views/test/views_test_base.h" @@ -111,6 +112,10 @@ class TestContextMenuController : public ContextMenuController { // Tests that context menus are shown for certain key events (Shift+F10 // and VKEY_APPS) by the pre-target handler installed on RootView. TEST_F(RootViewTest, ContextMenuFromKeyEvent) { +#if defined(OS_MACOSX) + // This behavior is intentionally unsupported on macOS. + return; +#endif Widget widget; Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP); diff --git a/chromium/ui/views/widget/widget.cc b/chromium/ui/views/widget/widget.cc index 926519dfa33..7bc25d68ab4 100644 --- a/chromium/ui/views/widget/widget.cc +++ b/chromium/ui/views/widget/widget.cc @@ -84,6 +84,9 @@ void NotifyCaretBoundsChanged(ui::InputMethod* input_method) { } // namespace +// static +bool Widget::g_disable_activation_change_handling_ = false; + // A default implementation of WidgetDelegate, used by Widget when no // WidgetDelegate is supplied. class DefaultWidgetDelegate : public WidgetDelegate { @@ -325,6 +328,9 @@ void Widget::Init(const InitParams& in_params) { params.delegate : new DefaultWidgetDelegate(this); widget_delegate_->set_can_activate(can_activate); + // Henceforth, ensure the delegate outlives the Widget. + widget_delegate_->can_delete_this_ = false; + ownership_ = params.ownership; native_widget_ = CreateNativeWidget(params, this)->AsNativeWidgetPrivate(); root_view_.reset(CreateRootView()); @@ -1030,7 +1036,10 @@ bool Widget::IsAlwaysRenderAsActive() const { return always_render_as_active_; } -void Widget::OnNativeWidgetActivationChanged(bool active) { +bool Widget::OnNativeWidgetActivationChanged(bool active) { + if (g_disable_activation_change_handling_) + return false; + // On windows we may end up here before we've completed initialization (from // an WM_NCACTIVATE). If that happens the WidgetDelegate likely doesn't know // the Widget and will crash attempting to access it. @@ -1042,6 +1051,8 @@ void Widget::OnNativeWidgetActivationChanged(bool active) { if (non_client_view()) non_client_view()->frame_view()->ActivationChanged(active); + + return true; } void Widget::OnNativeFocus() { @@ -1092,6 +1103,7 @@ void Widget::OnNativeWidgetDestroying() { void Widget::OnNativeWidgetDestroyed() { for (WidgetObserver& observer : observers_) observer.OnWidgetDestroyed(this); + widget_delegate_->can_delete_this_ = true; widget_delegate_->DeleteDelegate(); widget_delegate_ = NULL; native_widget_destroyed_ = true; diff --git a/chromium/ui/views/widget/widget.h b/chromium/ui/views/widget/widget.h index 6c0c60807a2..e2df1f67a8b 100644 --- a/chromium/ui/views/widget/widget.h +++ b/chromium/ui/views/widget/widget.h @@ -276,8 +276,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // hierarchy this widget should be placed. (This is separate from |parent|; // if you pass a RootWindow to |parent|, your window will be parented to // |parent|. If you pass a RootWindow to |context|, we ask that RootWindow - // where it wants your window placed.) NULL is not allowed if you are using - // aura. + // where it wants your window placed.) Nullptr is not allowed on Windows and + // Linux. Nullptr is allowed on Chrome OS, which will place the window on + // the default desktop for new windows. gfx::NativeWindow context; // If true, forces the window to be shown in the taskbar, even for window // types that do not appear in the taskbar by default (popup and bubble). @@ -789,7 +790,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, bool CanActivate() const override; bool IsAlwaysRenderAsActive() const override; void SetAlwaysRenderAsActive(bool always_render_as_active) override; - void OnNativeWidgetActivationChanged(bool active) override; + bool OnNativeWidgetActivationChanged(bool active) override; void OnNativeFocus() override; void OnNativeBlur() override; void OnNativeWidgetVisibilityChanging(bool visible) override; @@ -858,6 +859,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, friend class ButtonTest; friend class TextfieldTest; friend class ViewAuraTest; + friend void DisableActivationChangeHandlingForTests(); // Persists the window's restored position and "show" state using the // window delegate. @@ -883,6 +885,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // layer. const View::Views& GetViewsWithLayers(); + static bool g_disable_activation_change_handling_; + internal::NativeWidgetPrivate* native_widget_; base::ObserverList<WidgetObserver> observers_; diff --git a/chromium/ui/views/widget/widget_delegate.cc b/chromium/ui/views/widget/widget_delegate.cc index 294113b8996..ea1c78ff1d6 100644 --- a/chromium/ui/views/widget/widget_delegate.cc +++ b/chromium/ui/views/widget/widget_delegate.cc @@ -4,6 +4,7 @@ #include "ui/views/widget/widget_delegate.h" +#include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "ui/gfx/image/image_skia.h" @@ -17,9 +18,9 @@ namespace views { //////////////////////////////////////////////////////////////////////////////// // WidgetDelegate: -WidgetDelegate::WidgetDelegate() - : default_contents_view_(NULL), - can_activate_(true) { +WidgetDelegate::WidgetDelegate() = default; +WidgetDelegate::~WidgetDelegate() { + CHECK(can_delete_this_) << "A WidgetDelegate must outlive its Widget"; } void WidgetDelegate::OnWidgetMove() { diff --git a/chromium/ui/views/widget/widget_delegate.h b/chromium/ui/views/widget/widget_delegate.h index 8ae82197483..c1cfaebc417 100644 --- a/chromium/ui/views/widget/widget_delegate.h +++ b/chromium/ui/views/widget/widget_delegate.h @@ -184,12 +184,16 @@ class VIEWS_EXPORT WidgetDelegate { virtual void GetAccessiblePanes(std::vector<View*>* panes) {} protected: - virtual ~WidgetDelegate() {} + virtual ~WidgetDelegate(); private: - View* default_contents_view_; + friend class Widget; - bool can_activate_; + View* default_contents_view_ = nullptr; + bool can_activate_ = true; + + // Managed by Widget. Ensures |this| outlives its Widget. + bool can_delete_this_ = true; DISALLOW_COPY_AND_ASSIGN(WidgetDelegate); }; diff --git a/chromium/ui/views/widget/widget_interactive_uitest.cc b/chromium/ui/views/widget/widget_interactive_uitest.cc index 1cad461f7dd..db44bd41b88 100644 --- a/chromium/ui/views/widget/widget_interactive_uitest.cc +++ b/chromium/ui/views/widget/widget_interactive_uitest.cc @@ -377,9 +377,7 @@ class TouchEventHandler : public ui::EventHandler { } void WaitForEvents() { - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); - base::RunLoop run_loop; + base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); quit_closure_ = run_loop.QuitClosure(); run_loop.Run(); } @@ -543,11 +541,12 @@ TEST_F(WidgetTestInteractive, DisableCaptureWidgetFromMousePress) { gfx::Point location(20, 20); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&Widget::OnMouseEvent, base::Unretained(second), - base::Owned(new ui::MouseEvent( - ui::ET_MOUSE_RELEASED, location, location, - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_LEFT_MOUSE_BUTTON)))); + FROM_HERE, + base::BindOnce( + &Widget::OnMouseEvent, base::Unretained(second), + base::Owned(new ui::MouseEvent( + ui::ET_MOUSE_RELEASED, location, location, ui::EventTimeForNow(), + ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)))); ui::MouseEvent press(ui::ET_MOUSE_PRESSED, location, location, ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); @@ -845,8 +844,9 @@ class WidgetActivationTest : public Widget { ~WidgetActivationTest() override {} - void OnNativeWidgetActivationChanged(bool active) override { + bool OnNativeWidgetActivationChanged(bool active) override { active_ = active; + return true; } bool active() const { return active_; } diff --git a/chromium/ui/views/widget/widget_unittest.cc b/chromium/ui/views/widget/widget_unittest.cc index 76a9b283676..b978aabb83c 100644 --- a/chromium/ui/views/widget/widget_unittest.cc +++ b/chromium/ui/views/widget/widget_unittest.cc @@ -3226,13 +3226,7 @@ class FullscreenAwareFrame : public views::NonClientFrameView { // Tests that frame Layout is called when a widget goes fullscreen without // changing its size or title. -// Fails on Mac, but only on bots. http://crbug.com/607403. -#if defined(OS_MACOSX) -#define MAYBE_FullscreenFrameLayout DISABLED_FullscreenFrameLayout -#else -#define MAYBE_FullscreenFrameLayout FullscreenFrameLayout -#endif -TEST_F(WidgetTest, MAYBE_FullscreenFrameLayout) { +TEST_F(WidgetTest, FullscreenFrameLayout) { WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget()); FullscreenAwareFrame* frame = new FullscreenAwareFrame(widget.get()); widget->non_client_view()->SetFrameView(frame); // Owns |frame|. |