diff --git chrome/browser/extensions/api/sessions/sessions_api.cc chrome/browser/extensions/api/sessions/sessions_api.cc index 23722ce395352..e7e7d70dd312c 100644 --- chrome/browser/extensions/api/sessions/sessions_api.cc +++ chrome/browser/extensions/api/sessions/sessions_api.cc @@ -333,6 +333,7 @@ SessionsGetDevicesFunction::CreateWindowModel( state = api::windows::WindowState::kNormal; break; case ui::SHOW_STATE_MINIMIZED: + case ui::SHOW_STATE_HIDDEN: state = api::windows::WindowState::kMinimized; break; case ui::SHOW_STATE_MAXIMIZED: diff --git chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc index cef40af382b1e..a2cf4691edc37 100644 --- chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc +++ chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.cc @@ -43,6 +43,7 @@ ChromeNativeAppWindowViewsAura::GetRestorableState( case ui::SHOW_STATE_DEFAULT: case ui::SHOW_STATE_MINIMIZED: + case ui::SHOW_STATE_HIDDEN: case ui::SHOW_STATE_INACTIVE: case ui::SHOW_STATE_END: return ui::SHOW_STATE_NORMAL; diff --git components/sessions/core/session_service_commands.cc components/sessions/core/session_service_commands.cc index 124bf0bf470e5..30845be4a6a88 100644 --- components/sessions/core/session_service_commands.cc +++ components/sessions/core/session_service_commands.cc @@ -165,9 +165,10 @@ enum PersistedWindowShowState { PERSISTED_SHOW_STATE_MAXIMIZED = 3, // SHOW_STATE_INACTIVE (4) never persisted. PERSISTED_SHOW_STATE_FULLSCREEN = 5, - PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 6, - PERSISTED_SHOW_STATE_DOCKED_DEPRECATED = 7, - PERSISTED_SHOW_STATE_END = 8, + // SHOW_STATE_HIDDEN (6) never persisted. + PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 7, + PERSISTED_SHOW_STATE_DOCKED_DEPRECATED = 8, + PERSISTED_SHOW_STATE_END = 9, }; // TODO(crbug.com/40946710): Remove this around December 2024. This is part of a @@ -191,6 +192,7 @@ PersistedWindowShowState ShowStateToPersistedShowState( case ui::SHOW_STATE_NORMAL: return PERSISTED_SHOW_STATE_NORMAL; case ui::SHOW_STATE_MINIMIZED: + case ui::SHOW_STATE_HIDDEN: return PERSISTED_SHOW_STATE_MINIMIZED; case ui::SHOW_STATE_MAXIMIZED: return PERSISTED_SHOW_STATE_MAXIMIZED; diff --git components/sessions/core/tab_restore_service_impl.cc components/sessions/core/tab_restore_service_impl.cc index 552bf87379e34..b37e04b676de7 100644 --- components/sessions/core/tab_restore_service_impl.cc +++ components/sessions/core/tab_restore_service_impl.cc @@ -197,6 +197,7 @@ int SerializeWindowShowState(ui::WindowShowState show_state) { case ui::SHOW_STATE_NORMAL: return kSerializedShowStateNormal; case ui::SHOW_STATE_MINIMIZED: + case ui::SHOW_STATE_HIDDEN: return kSerializedShowStateMinimized; case ui::SHOW_STATE_MAXIMIZED: return kSerializedShowStateMaximized; diff --git content/browser/renderer_host/render_widget_host_view_base.cc content/browser/renderer_host/render_widget_host_view_base.cc index 60d2748ffebf8..cb16f27ee8d5f 100644 --- content/browser/renderer_host/render_widget_host_view_base.cc +++ content/browser/renderer_host/render_widget_host_view_base.cc @@ -674,6 +674,14 @@ float RenderWidgetHostViewBase::GetScaleOverrideForCapture() const { return scale_override_for_capture_; } +void RenderWidgetHostViewBase::SetHasExternalParent(bool val) { + has_external_parent_ = val; +} + +bool RenderWidgetHostViewBase::HasExternalParent() const { + return has_external_parent_; +} + void RenderWidgetHostViewBase::OnAutoscrollStart() { if (!GetMouseWheelPhaseHandler()) return; diff --git content/browser/renderer_host/render_widget_host_view_base.h content/browser/renderer_host/render_widget_host_view_base.h index 36ed537b555aa..2cf5fe3b03f0d 100644 --- content/browser/renderer_host/render_widget_host_view_base.h +++ content/browser/renderer_host/render_widget_host_view_base.h @@ -72,6 +72,7 @@ class CursorManager; class DevicePosturePlatformProvider; class MouseWheelPhaseHandler; class RenderWidgetHostImpl; +class RenderWidgetHostViewGuest; class RenderWidgetHostViewInputObserver; class ScopedViewTransitionResources; class TextInputManager; @@ -194,6 +195,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase float GetDeviceScaleFactor() const final; bool IsPointerLocked() override; + void SetHasExternalParent(bool val) override; + bool HasExternalParent() const override; + // Identical to `CopyFromSurface()`, except that this method issues the // `viz::CopyOutputRequest` against the exact `viz::Surface` currently // embedded by this View, while `CopyFromSurface()` may return a copy of any @@ -255,6 +259,10 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // Called when screen information or native widget bounds change. virtual void UpdateScreenInfo(); + // Generates the most current set of ScreenInfos from the current set of + // displays in the system for use in UpdateScreenInfo. + virtual display::ScreenInfos GetNewScreenInfosForUpdate(); + // Called by the TextInputManager to notify the view about being removed from // the list of registered views, i.e., TextInputManager is no longer tracking // TextInputState from this view. The RWHV should reset |text_input_manager_| @@ -383,6 +391,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase const gfx::Rect& bounds, const gfx::Rect& anchor_rect) = 0; + // Perform all the initialization steps necessary for this object to represent + // the platform widget owned by |guest_view| and embedded in + // |parent_host_view|. + virtual void InitAsGuest(RenderWidgetHostView* parent_host_view, + RenderWidgetHostViewGuest* guest_view) {} + // Indicates whether the page has finished loading. virtual void SetIsLoading(bool is_loading) = 0; @@ -645,6 +659,10 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // to all displays. gfx::Size system_cursor_size_; + // True if the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + bool has_external_parent_ = false; + private: FRIEND_TEST_ALL_PREFIXES( BrowserSideFlingBrowserTest, @@ -666,10 +684,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase void SynchronizeVisualProperties(); - // Generates the most current set of ScreenInfos from the current set of - // displays in the system for use in UpdateScreenInfo. - display::ScreenInfos GetNewScreenInfosForUpdate(); - // Called when display properties that need to be synchronized with the // renderer process changes. This method is called before notifying // RenderWidgetHostImpl in order to allow the view to allocate a new diff --git content/browser/renderer_host/render_widget_host_view_event_handler.cc content/browser/renderer_host/render_widget_host_view_event_handler.cc index d1df19bfcb6c9..c55b89a119046 100644 --- content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ content/browser/renderer_host/render_widget_host_view_event_handler.cc @@ -52,6 +52,10 @@ namespace { // of the border area, in percentage of the corresponding dimension. const int kMouseLockBorderPercentage = 15; +#if BUILDFLAG(IS_LINUX) +#include "ui/aura/window_tree_host.h" +#endif + #if BUILDFLAG(IS_WIN) // A callback function for EnumThreadWindows to enumerate and dismiss // any owned popup windows. @@ -821,6 +825,14 @@ void RenderWidgetHostViewEventHandler::MoveCursorToCenter( } return; } +#endif +#if BUILDFLAG(IS_LINUX) + if (host_view_->HasExternalParent() && + window_ && window_->delegate()->CanFocus()) { + aura::WindowTreeHost* host = window_->GetHost(); + if (host) + host->Show(); + } #endif synthetic_move_position_ = center_in_screen; } @@ -851,6 +863,17 @@ bool RenderWidgetHostViewEventHandler::MatchesSynthesizedMovePosition( } void RenderWidgetHostViewEventHandler::SetKeyboardFocus() { +#if BUILDFLAG(IS_WIN) + if (host_view_->HasExternalParent() && + window_ && window_->delegate()->CanFocus()) { + aura::WindowTreeHost* host = window_->GetHost(); + if (host) { + gfx::AcceleratedWidget hwnd = host->GetAcceleratedWidget(); + if (!(::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_NOACTIVATE)) + ::SetFocus(hwnd); + } + } +#endif // TODO(wjmaclean): can host_ ever be null? if (host_ && set_focus_on_mouse_down_or_key_event_) { set_focus_on_mouse_down_or_key_event_ = false; diff --git content/public/browser/render_widget_host_view.h content/public/browser/render_widget_host_view.h index b4ff7c11d8e3c..b21417f89e6e1 100644 --- content/public/browser/render_widget_host_view.h +++ content/public/browser/render_widget_host_view.h @@ -254,6 +254,14 @@ class CONTENT_EXPORT RenderWidgetHostView { // This must always return the same device scale factor as GetScreenInfo. virtual float GetDeviceScaleFactor() const = 0; + // Set whether the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + virtual void SetHasExternalParent(bool val) = 0; + + // Returns true if the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + virtual bool HasExternalParent() const = 0; + #if BUILDFLAG(IS_MAC) // Set the view's active state (i.e., tint state of controls). virtual void SetActive(bool active) = 0; diff --git ui/aura/native_window_occlusion_tracker_win.cc ui/aura/native_window_occlusion_tracker_win.cc index 0893f87550cc9..2a52012e5059d 100644 --- ui/aura/native_window_occlusion_tracker_win.cc +++ ui/aura/native_window_occlusion_tracker_win.cc @@ -101,6 +101,13 @@ void NativeWindowOcclusionTrackerWin::Enable(Window* window) { // when it's no longer true that all windows are minimized, and when the // window is destroyed. HWND root_window_hwnd = window->GetHost()->GetAcceleratedWidget(); + + // Delay occlusion tracking for initially-minimized windows. + // See CEF issue #3638. + if (IsIconic(root_window_hwnd)) { + return; + } + window->AddObserver(this); // Remember this mapping from hwnd to Window*. hwnd_root_window_map_[root_window_hwnd] = window; diff --git ui/base/mojom/ui_base_types_mojom_traits.h ui/base/mojom/ui_base_types_mojom_traits.h index 1d79fc2dc34cc..ce5bf0ebf531f 100644 --- ui/base/mojom/ui_base_types_mojom_traits.h +++ ui/base/mojom/ui_base_types_mojom_traits.h @@ -172,6 +172,7 @@ struct EnumTraits { case ui::SHOW_STATE_INACTIVE: return ui::mojom::WindowShowState::SHOW_STATE_INACTIVE; case ui::SHOW_STATE_MINIMIZED: + case ui::SHOW_STATE_HIDDEN: return ui::mojom::WindowShowState::SHOW_STATE_MINIMIZED; case ui::SHOW_STATE_MAXIMIZED: return ui::mojom::WindowShowState::SHOW_STATE_MAXIMIZED; diff --git ui/base/ui_base_types.h ui/base/ui_base_types.h index 2cf9330a4e24b..4bf0890ae000b 100644 --- ui/base/ui_base_types.h +++ ui/base/ui_base_types.h @@ -26,7 +26,8 @@ enum WindowShowState { SHOW_STATE_MAXIMIZED = 3, SHOW_STATE_INACTIVE = 4, // Views only, not persisted. SHOW_STATE_FULLSCREEN = 5, - SHOW_STATE_END = 6 // The end of show state enum. + SHOW_STATE_HIDDEN = 6, // Views and MacOS only. + SHOW_STATE_END = 7 // The end of show state enum. }; // Specifies which edges of the window are tiled. diff --git ui/ozone/platform/x11/x11_window.cc ui/ozone/platform/x11/x11_window.cc index f1c5f06fb2966..649a206664a00 100644 --- ui/ozone/platform/x11/x11_window.cc +++ ui/ozone/platform/x11/x11_window.cc @@ -1862,7 +1862,8 @@ void X11Window::CreateXWindow(const PlatformWindowInitProperties& properties) { req.border_pixel = 0; bounds_in_pixels_ = SanitizeBounds(bounds); - req.parent = x_root_window_; + req.parent = properties.parent_widget == gfx::kNullAcceleratedWidget ? + x_root_window_ : static_cast(properties.parent_widget); req.x = bounds_in_pixels_.x(); req.y = bounds_in_pixels_.y(); req.width = bounds_in_pixels_.width(); diff --git ui/views/widget/desktop_aura/desktop_screen_win.cc ui/views/widget/desktop_aura/desktop_screen_win.cc index e31c5b4cb6726..1b724948c2868 100644 --- ui/views/widget/desktop_aura/desktop_screen_win.cc +++ ui/views/widget/desktop_aura/desktop_screen_win.cc @@ -23,6 +23,8 @@ DesktopScreenWin::~DesktopScreenWin() { } HWND DesktopScreenWin::GetHWNDFromNativeWindow(gfx::NativeWindow window) const { + if (!window) + return nullptr; aura::WindowTreeHost* host = window->GetHost(); return host ? host->GetAcceleratedWidget() : nullptr; } diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc index 87179d2dfc301..92d31c96bb0b1 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc @@ -194,6 +194,18 @@ Widget::MoveLoopResult DesktopWindowTreeHostLinux::RunMoveLoop( return result; } +gfx::Rect DesktopWindowTreeHostLinux::GetWindowBoundsInScreen() const { + if (!screen_bounds_.IsEmpty()) + return screen_bounds_; + return DesktopWindowTreeHostPlatform::GetWindowBoundsInScreen(); +} + +gfx::Point DesktopWindowTreeHostLinux::GetLocationOnScreenInPixels() const { + if (!screen_bounds_.IsEmpty()) + return screen_bounds_.origin(); + return DesktopWindowTreeHostPlatform::GetLocationOnScreenInPixels(); +} + void DesktopWindowTreeHostLinux::DispatchEvent(ui::Event* event) { // In Windows, the native events sent to chrome are separated into client // and non-client versions of events, which we record on our LocatedEvent @@ -329,6 +341,8 @@ void DesktopWindowTreeHostLinux::AddAdditionalInitProperties( properties->wayland_app_id = params.wayland_app_id; + properties->parent_widget = params.parent_widget; + DCHECK(!properties->x11_extension_delegate); properties->x11_extension_delegate = this; } diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h index e698f71577c51..8a6e28128564d 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h +++ ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h @@ -62,6 +62,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux // client-drawn shadow. virtual void UpdateFrameHints(); + void set_screen_bounds(const gfx::Rect& bounds) { screen_bounds_ = bounds; } + protected: // Overridden from DesktopWindowTreeHost: void Init(const Widget::InitParams& params) override; @@ -71,6 +73,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux const gfx::Vector2d& drag_offset, Widget::MoveLoopSource source, Widget::MoveLoopEscapeBehavior escape_behavior) override; + gfx::Rect GetWindowBoundsInScreen() const override; + gfx::Point GetLocationOnScreenInPixels() const override; // PlatformWindowDelegate: void DispatchEvent(ui::Event* event) override; @@ -120,6 +124,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostLinux uint32_t modal_dialog_counter_ = 0; + // Override the screen bounds when the host is a child window. + gfx::Rect screen_bounds_; + // The display and the native X window hosting the root window. base::WeakPtrFactory weak_factory_{this}; }; diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index 0490b0f83b8e6..66c2858145e42 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc @@ -281,8 +281,8 @@ void DesktopWindowTreeHostPlatform::Init(const Widget::InitParams& params) { if (properties.parent_widget) { window_parent_ = DesktopWindowTreeHostPlatform::GetHostForWidget( properties.parent_widget); - DCHECK(window_parent_); - window_parent_->window_children_.insert(this); + if (window_parent_) + window_parent_->window_children_.insert(this); } // Calculate initial bounds. diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index 288a76d86ed87..1fd024d1645c3 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc @@ -20,6 +20,7 @@ #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/client/focus_client.h" +#include "ui/aura/native_window_occlusion_tracker.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/base/class_property.h" #include "ui/base/cursor/cursor.h" @@ -183,22 +184,42 @@ void DesktopWindowTreeHostWin::Init(const Widget::InitParams& params) { native_widget_delegate_.get()); HWND parent_hwnd = nullptr; - if (params.parent && params.parent->GetHost()) + if (params.parent_widget) { + parent_hwnd = params.parent_widget; + has_external_parent_ = true; + } else if (params.parent && params.parent->GetHost()) { parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget(); + } remove_standard_frame_ = params.remove_standard_frame; has_non_client_view_ = Widget::RequiresNonClientView(params.type); z_order_ = params.EffectiveZOrderLevel(); - // We don't have an HWND yet, so scale relative to the nearest screen. - gfx::Rect pixel_bounds = - display::win::ScreenWin::DIPToScreenRect(nullptr, params.bounds); + gfx::Rect pixel_bounds; + if (has_external_parent_ && params.type != Widget::InitParams::TYPE_MENU) { + // Scale relative to the screen that contains the parent window. + // Child windows always have origin (0,0). + pixel_bounds.set_size(display::win::ScreenWin::DIPToScreenSize( + parent_hwnd, params.bounds.size())); + } else { + // We don't have an HWND yet, so scale relative to the nearest screen. + pixel_bounds = + display::win::ScreenWin::DIPToScreenRect(nullptr, params.bounds); + } + message_handler_->Init(parent_hwnd, pixel_bounds); CreateCompositor(params.force_software_compositing); OnAcceleratedWidgetAvailable(); InitHost(); window()->Show(); + if (params.show_state == ui::SHOW_STATE_MINIMIZED) { + // Delay enablement of native occlusion tracking until the + // initially-minimized window is restored for the first time. + // See CEF issue #3638. + initially_minimized_first_restore_pending_ = true; + } + // Stack immediately above its parent so that it does not cover other // root-level windows, with the exception of menus, to allow them to be // displayed on top of other windows. @@ -1025,10 +1046,23 @@ void DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored(bool restored) { if (!native_widget_delegate_->IsNativeWidgetInitialized()) return; - if (restored) + if (restored) { window()->Show(); - else + + if (initially_minimized_first_restore_pending_) { + initially_minimized_first_restore_pending_ = false; + + // Enable native occlusion tracking for initially-minimized windows here + // to avoid incorrect hidden state after restore. See CEF issue #3638. + if (aura::NativeWindowOcclusionTracker:: + IsNativeWindowOcclusionTrackingAlwaysEnabled(this)) { + aura::NativeWindowOcclusionTracker:: + EnableNativeWindowOcclusionTracking(this); + } + } + } else { window()->Hide(); + } } void DesktopWindowTreeHostWin::HandleClientSizeChanged( @@ -1045,11 +1079,15 @@ void DesktopWindowTreeHostWin::HandleFrameChanged() { } void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) { - // TODO(beng): inform the native_widget_delegate_. + // See comments in CefBrowserPlatformDelegateNativeWin::SetFocus. + if (has_external_parent_ && CanActivate()) + HandleActivationChanged(true); } void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) { - // TODO(beng): inform the native_widget_delegate_. + // See comments in CefBrowserPlatformDelegateNativeWin::SetFocus. + if (has_external_parent_ && CanActivate()) + HandleActivationChanged(false); } bool DesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { @@ -1057,6 +1095,12 @@ bool DesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { if (ui::PlatformEventSource::ShouldIgnoreNativePlatformEvents()) return true; + // See comments in CefBrowserPlatformDelegateNativeWin::SetFocus. + if (has_external_parent_ && CanActivate() && event->IsAnyButton() && + ::GetFocus() != GetHWND()) { + ::SetFocus(GetHWND()); + } + SendEventToSink(event); return event->handled(); } @@ -1235,8 +1279,16 @@ void DesktopWindowTreeHostWin::SetBoundsInDIP(const gfx::Rect& bounds) { // positions in variable-DPI situations. See https://crbug.com/1224715 for // details. aura::Window* root = nullptr; - const gfx::Rect bounds_in_pixels = + if (has_external_parent_) { + // Scale relative to the screen that contains the parent window. + root = AsWindowTreeHost()->window(); + } + gfx::Rect bounds_in_pixels = display::Screen::GetScreen()->DIPToScreenRectInWindow(root, bounds); + if (has_external_parent_) { + // Child windows always have origin (0,0). + bounds_in_pixels.set_origin(gfx::Point(0, 0)); + } AsWindowTreeHost()->SetBoundsInPixels(bounds_in_pixels); } diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_win.h ui/views/widget/desktop_aura/desktop_window_tree_host_win.h index 8d5b01098915d..ae5b6a2193031 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ ui/views/widget/desktop_aura/desktop_window_tree_host_win.h @@ -322,6 +322,14 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin // True if the window should have the frame removed. bool remove_standard_frame_; + // True if the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + bool has_external_parent_ = false; + + // True if the first call to HandleWindowMinimizedOrRestored for an initially- + // minimized window is pending. + bool initially_minimized_first_restore_pending_ = false; + // Visibility of the cursor. On Windows we can have multiple root windows and // the implementation of ::ShowCursor() is based on a counter, so making this // member static ensures that ::ShowCursor() is always called exactly once diff --git ui/views/widget/native_widget_mac.mm ui/views/widget/native_widget_mac.mm index 6383110804d44..e5bc85f63fab9 100644 --- ui/views/widget/native_widget_mac.mm +++ ui/views/widget/native_widget_mac.mm @@ -640,6 +640,7 @@ void NativeWidgetMac::Show(ui::WindowShowState show_state, break; case ui::SHOW_STATE_MAXIMIZED: case ui::SHOW_STATE_FULLSCREEN: + case ui::SHOW_STATE_HIDDEN: NOTIMPLEMENTED(); break; case ui::SHOW_STATE_END: diff --git ui/views/widget/widget.cc ui/views/widget/widget.cc index e113e926b324c..572eccab19085 100644 --- ui/views/widget/widget.cc +++ ui/views/widget/widget.cc @@ -410,7 +410,8 @@ void Widget::Init(InitParams params) { } params.child |= (params.type == InitParams::TYPE_CONTROL); - is_top_level_ = !params.child; + is_top_level_ = !params.child || + params.parent_widget != gfx::kNullAcceleratedWidget; is_headless_ = params.ShouldInitAsHeadless(); is_autosized_ = params.autosize; @@ -502,9 +503,14 @@ void Widget::Init(InitParams params) { if (show_state == ui::SHOW_STATE_MAXIMIZED) { Maximize(); + saved_show_state_ = ui::SHOW_STATE_MAXIMIZED; } else if (show_state == ui::SHOW_STATE_MINIMIZED) { Minimize(); saved_show_state_ = ui::SHOW_STATE_MINIMIZED; + } else if (show_state == ui::SHOW_STATE_FULLSCREEN) { + SetFullscreen(true); + } else if (show_state == ui::SHOW_STATE_HIDDEN) { + Hide(); } #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -518,7 +524,12 @@ void Widget::Init(InitParams params) { } else if (delegate) { SetContentsView(delegate->TransferOwnershipOfContentsView()); if (should_set_initial_bounds) { - SetInitialBoundsForFramelessWindow(bounds); + if (params.parent_widget != gfx::kNullAcceleratedWidget) { + // Set the bounds directly instead of applying an inset. + SetBounds(bounds); + } else { + SetInitialBoundsForFramelessWindow(bounds); + } } } @@ -1704,10 +1715,16 @@ void Widget::OnNativeWidgetParentChanged(gfx::NativeView parent) { } gfx::Size Widget::GetMinimumSize() const { + gfx::Size size; + if (widget_delegate_->MaybeGetMinimumSize(&size)) + return size; return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size(); } gfx::Size Widget::GetMaximumSize() const { + gfx::Size size; + if (widget_delegate_->MaybeGetMaximumSize(&size)) + return size; return non_client_view_ ? non_client_view_->GetMaximumSize() : gfx::Size(); } @@ -1958,7 +1975,8 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) { return false; View* v = widget_delegate_->GetInitiallyFocusedView(); if (!focus_on_creation_ || show_state == ui::SHOW_STATE_INACTIVE || - show_state == ui::SHOW_STATE_MINIMIZED) { + show_state == ui::SHOW_STATE_MINIMIZED || + show_state == ui::SHOW_STATE_HIDDEN) { // If not focusing the window now, tell the focus manager which view to // focus when the window is restored. if (v) diff --git ui/views/widget/widget.h ui/views/widget/widget.h index 68c2ac9da74ac..94f75266c6917 100644 --- ui/views/widget/widget.h +++ ui/views/widget/widget.h @@ -358,6 +358,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, // the concept with bubble anchoring a la BubbleDialogDelegateView. gfx::NativeView parent = gfx::NativeView(); + gfx::AcceleratedWidget parent_widget = gfx::kNullAcceleratedWidget; + // Specifies the initial bounds of the Widget. Default is empty, which means // the NativeWidget may specify a default size. If the parent is specified, // |bounds| is in the parent's coordinate system. If the parent is not @@ -764,7 +766,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, void ShowInactive(); // Activates the widget, assuming it already exists and is visible. - void Activate(); + virtual void Activate(); // Deactivates the widget, making the next window in the Z order the active // window. diff --git ui/views/widget/widget_delegate.h ui/views/widget/widget_delegate.h index d1f6be37fcf45..ca2fd8ce00561 100644 --- ui/views/widget/widget_delegate.h +++ ui/views/widget/widget_delegate.h @@ -402,6 +402,10 @@ class VIEWS_EXPORT WidgetDelegate // Returns true if the title text should be centered. bool ShouldCenterWindowTitleText() const; + // CEF supports override of min/max size values. + virtual bool MaybeGetMinimumSize(gfx::Size* size) const { return false; } + virtual bool MaybeGetMaximumSize(gfx::Size* size) const { return false; } + bool focus_traverses_out() const { return params_.focus_traverses_out; } bool enable_arrow_key_traversal() const { return params_.enable_arrow_key_traversal; diff --git ui/views/widget/widget_hwnd_utils.cc ui/views/widget/widget_hwnd_utils.cc index 3b9b00b7d79ae..e759e3c1a9f34 100644 --- ui/views/widget/widget_hwnd_utils.cc +++ ui/views/widget/widget_hwnd_utils.cc @@ -63,7 +63,8 @@ void CalculateWindowStylesFromInitParams( if (!widget_delegate->CanResize()) *style &= static_cast(~(WS_THICKFRAME | WS_MAXIMIZEBOX)); if (params.remove_standard_frame) - *style &= static_cast(~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX)); + *style &= static_cast(~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | + WS_CAPTION | WS_SYSMENU)); if (native_widget_delegate->IsDialogBox()) { *style |= DS_MODALFRAME; diff --git ui/views/win/hwnd_message_handler.cc ui/views/win/hwnd_message_handler.cc index 3bfc5b2257908..0d4437e091daa 100644 --- ui/views/win/hwnd_message_handler.cc +++ ui/views/win/hwnd_message_handler.cc @@ -772,7 +772,11 @@ bool HWNDMessageHandler::IsVisible() const { } bool HWNDMessageHandler::IsActive() const { - return ::GetActiveWindow() == hwnd(); + // This active state is checked via FocusManager::SetFocusedViewWithReason. + // With CEF external parent hwnd() may be a child window, whereas + // GetActiveWindow() will return the root window, so make sure that we always + // compare root windows. + return ::GetActiveWindow() == ::GetAncestor(hwnd(), GA_ROOT); } bool HWNDMessageHandler::IsMinimized() const { @@ -3225,10 +3229,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message, } else if (event.type() == ui::ET_MOUSEWHEEL) { ui::MouseWheelEvent mouse_wheel_event(msg); // Reroute the mouse wheel to the window under the pointer if applicable. - return (ui::RerouteMouseWheel(hwnd(), w_param, l_param) || - delegate_->HandleMouseEvent(&mouse_wheel_event)) - ? 0 - : 1; + if (ui::RerouteMouseWheel(hwnd(), w_param, l_param) || + delegate_->HandleMouseEvent(&mouse_wheel_event)) { + SetMsgHandled(TRUE); + return 0; + } else { + return 1; + } } // Suppress |ET_MOUSE_MOVED| and |ET_MOUSE_DRAGGED| events from WM_MOUSE*