diff --git content/browser/renderer_host/render_widget_host_view_base.cc content/browser/renderer_host/render_widget_host_view_base.cc index 6fc2ae557a26..0a704d1453a2 100644 --- content/browser/renderer_host/render_widget_host_view_base.cc +++ content/browser/renderer_host/render_widget_host_view_base.cc @@ -564,6 +564,14 @@ float RenderWidgetHostViewBase::GetDeviceScaleFactor() { return screen_info.device_scale_factor; } +void RenderWidgetHostViewBase::SetHasExternalParent(bool val) { + has_external_parent_ = val; +} + +bool RenderWidgetHostViewBase::HasExternalParent() const { + return has_external_parent_; +} + uint32_t RenderWidgetHostViewBase::RendererFrameNumber() { return renderer_frame_number_; } diff --git content/browser/renderer_host/render_widget_host_view_base.h content/browser/renderer_host/render_widget_host_view_base.h index fca7a56a4b7f..3691f64f2f95 100644 --- content/browser/renderer_host/render_widget_host_view_base.h +++ content/browser/renderer_host/render_widget_host_view_base.h @@ -65,6 +65,7 @@ class CursorManager; class MouseWheelPhaseHandler; class RenderWidgetHostImpl; class RenderWidgetHostViewBaseObserver; +class RenderWidgetHostViewGuest; class SyntheticGestureTarget; class TextInputManager; class TouchSelectionControllerClientManager; @@ -82,6 +83,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase float current_device_scale_factor() const { return current_device_scale_factor_; } + void set_current_device_scale_factor(float scale_factor) { + current_device_scale_factor_ = scale_factor; + } // Returns the focused RenderWidgetHost inside this |view|'s RWH. RenderWidgetHostImpl* GetFocusedWidget() const; @@ -116,6 +120,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase void DisableAutoResize(const gfx::Size& new_size) override; bool IsScrollOffsetAtTop() override; float GetDeviceScaleFactor() final; + void SetHasExternalParent(bool val) override; + bool HasExternalParent() const override; TouchSelectionControllerClientManager* GetTouchSelectionControllerClientManager() override; void SetRecordContentToVisibleTimeRequest( @@ -441,6 +447,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase // helps to position the full screen widget on the correct monitor. virtual void InitAsFullscreen(RenderWidgetHostView* reference_host_view) = 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) {} + // Sets the cursor for this view to the one associated with the specified // cursor_type. virtual void UpdateCursor(const WebCursor& cursor) = 0; @@ -605,6 +617,10 @@ class CONTENT_EXPORT RenderWidgetHostViewBase bool is_currently_scrolling_viewport_ = false; + // 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, 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 e571258b6046..ba1bb2e96b40 100644 --- content/browser/renderer_host/render_widget_host_view_event_handler.cc +++ content/browser/renderer_host/render_widget_host_view_event_handler.cc @@ -33,6 +33,10 @@ #include "ui/events/keycodes/dom/dom_code.h" #include "ui/touch_selection/touch_selection_controller.h" +#if defined(OS_LINUX) +#include "ui/aura/window_tree_host.h" +#endif + #if defined(OS_WIN) #include "content/browser/frame_host/render_frame_host_impl.h" #include "ui/aura/window_tree_host.h" @@ -896,6 +900,14 @@ void RenderWidgetHostViewEventHandler::SetKeyboardFocus() { ::SetFocus(hwnd); } } +#endif +#if defined(OS_LINUX) + if (host_view_->HasExternalParent() && + window_ && window_->delegate()->CanFocus()) { + aura::WindowTreeHost* host = window_->GetHost(); + if (host) + host->Show(); + } #endif // TODO(wjmaclean): can host_ ever be null? if (host_ && set_focus_on_mouse_down_or_key_event_) { diff --git content/public/browser/render_widget_host_view.h content/public/browser/render_widget_host_view.h index d7631d9b2246..853692333f9d 100644 --- content/public/browser/render_widget_host_view.h +++ content/public/browser/render_widget_host_view.h @@ -238,6 +238,14 @@ class CONTENT_EXPORT RenderWidgetHostView { // This must always return the same device scale factor as GetScreenInfo. virtual float GetDeviceScaleFactor() = 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 defined(OS_MACOSX) // Set the view's active state (i.e., tint state of controls). virtual void SetActive(bool active) = 0; diff --git ui/base/x/x11_window.cc ui/base/x/x11_window.cc index 2c9c97b81e74..01dd7ca2c9b8 100644 --- ui/base/x/x11_window.cc +++ ui/base/x/x11_window.cc @@ -251,8 +251,12 @@ void XWindow::Init(const Configuration& config) { attribute_mask |= CWBorderPixel; swa.border_pixel = 0; + gfx::AcceleratedWidget parent_widget = config.parent_widget; + if (parent_widget == gfx::kNullAcceleratedWidget) + parent_widget = x_root_window_; + bounds_in_pixels_ = SanitizeBounds(config.bounds); - xwindow_ = XCreateWindow(xdisplay_, x_root_window_, bounds_in_pixels_.x(), + xwindow_ = XCreateWindow(xdisplay_, parent_widget, bounds_in_pixels_.x(), bounds_in_pixels_.y(), bounds_in_pixels_.width(), bounds_in_pixels_.height(), 0, // border width diff --git ui/base/x/x11_window.h ui/base/x/x11_window.h index 9939835d80ad..61249e3fb8f2 100644 --- ui/base/x/x11_window.h +++ ui/base/x/x11_window.h @@ -19,6 +19,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_f.h" +#include "ui/gfx/native_widget_types.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h" @@ -85,6 +86,7 @@ class COMPONENT_EXPORT(UI_BASE_X) XWindow { std::string wm_class_name; std::string wm_class_class; std::string wm_role_name; + gfx::AcceleratedWidget parent_widget = gfx::kNullAcceleratedWidget; }; XWindow(); diff --git ui/platform_window/x11/x11_window.cc ui/platform_window/x11/x11_window.cc index fb6b7ac459ce..39a262afc8ca 100644 --- ui/platform_window/x11/x11_window.cc +++ ui/platform_window/x11/x11_window.cc @@ -85,6 +85,7 @@ ui::XWindow::Configuration ConvertInitPropertiesToXWindowConfig( config.wm_class_class = properties.wm_class_class; config.wm_role_name = properties.wm_role_name; config.activatable = properties.activatable; + config.parent_widget = properties.parent_widget; config.prefer_dark_theme = properties.prefer_dark_theme; config.background_color = properties.background_color; return config; diff --git ui/views/widget/desktop_aura/desktop_screen_win.cc ui/views/widget/desktop_aura/desktop_screen_win.cc index 70553b153c44..ecd99bc78373 100644 --- ui/views/widget/desktop_aura/desktop_screen_win.cc +++ ui/views/widget/desktop_aura/desktop_screen_win.cc @@ -30,6 +30,8 @@ display::Display DesktopScreenWin::GetDisplayMatching( } HWND DesktopScreenWin::GetHWNDFromNativeView(gfx::NativeView window) const { + if (!window) + return NULL; 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 6030f29ac64f..d7a679c4a1b8 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc @@ -329,6 +329,8 @@ void DesktopWindowTreeHostLinux::AddAdditionalInitProperties( properties->wm_class_class = params.wm_class_class; properties->wm_role_name = params.wm_role_name; + 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_win.cc ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc index d0825cdb2a1c..606400d2bcef 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc @@ -129,8 +129,12 @@ void DesktopWindowTreeHostWin::Init(const Widget::InitParams& params) { native_widget_delegate_); 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); @@ -905,11 +909,15 @@ void DesktopWindowTreeHostWin::HandleFrameChanged() { } void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) { - // TODO(beng): inform the native_widget_delegate_. + // See comments in CefBrowserHostImpl::PlatformSetFocus. + if (has_external_parent_ && CanActivate()) + HandleActivationChanged(true); } void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) { - // TODO(beng): inform the native_widget_delegate_. + // See comments in CefBrowserHostImpl::PlatformSetFocus. + if (has_external_parent_ && CanActivate()) + HandleActivationChanged(false); } bool DesktopWindowTreeHostWin::HandleMouseEvent(ui::MouseEvent* event) { 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 78925bf334d9..57519c817127 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_win.h +++ ui/views/widget/desktop_aura/desktop_window_tree_host_win.h @@ -288,6 +288,10 @@ 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; + // Owned by TooltipController, but we need to forward events to it so we keep // a reference. corewm::TooltipWin* tooltip_; diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 7439257da38c..4ccfd25c82e3 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc @@ -84,6 +84,9 @@ DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { // DesktopWindowTreeHostX11, DesktopWindowTreeHost implementation: void DesktopWindowTreeHostX11::Init(const Widget::InitParams& params) { + if (params.parent_widget != gfx::kNullAcceleratedWidget) + has_external_parent_ = true; + DesktopWindowTreeHostLinux::Init(params); // Set XEventDelegate to receive selection, drag&drop and raw key events. @@ -139,6 +142,18 @@ void DesktopWindowTreeHostX11::EndMoveLoop() { //////////////////////////////////////////////////////////////////////////////// // DesktopWindowTreeHostX11 implementation: +gfx::Rect DesktopWindowTreeHostX11::GetWindowBoundsInScreen() const { + if (!screen_bounds_.IsEmpty()) + return screen_bounds_; + return DesktopWindowTreeHostLinux::GetWindowBoundsInScreen(); +} + +gfx::Point DesktopWindowTreeHostX11::GetLocationOnScreenInPixels() const { + if (!screen_bounds_.IsEmpty()) + return screen_bounds_.origin(); + return DesktopWindowTreeHostLinux::GetLocationOnScreenInPixels(); +} + void DesktopWindowTreeHostX11::OnXWindowSelectionEvent(XEvent* xev) { DCHECK(xev); DCHECK(drag_drop_client_); diff --git ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h index 53da309c14d3..7a50560c8abc 100644 --- ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h @@ -31,6 +31,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux, DesktopNativeWidgetAura* desktop_native_widget_aura); ~DesktopWindowTreeHostX11() override; + void set_screen_bounds(const gfx::Rect& bounds) { screen_bounds_ = bounds; } + + // Returns true if the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + bool has_external_parent() const { return has_external_parent_; } + protected: // Overridden from DesktopWindowTreeHost: void Init(const Widget::InitParams& params) override; @@ -42,6 +48,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux, Widget::MoveLoopSource source, Widget::MoveLoopEscapeBehavior escape_behavior) override; void EndMoveLoop() override; + gfx::Rect GetWindowBoundsInScreen() const override; + gfx::Point GetLocationOnScreenInPixels() const override; private: friend class DesktopWindowTreeHostX11HighDPITest; @@ -56,10 +64,20 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 : public DesktopWindowTreeHostLinux, // directly. See https://crbug.com/990756. const ui::XWindow* GetXWindow() const; + // Override the screen bounds when the host is a child window. + gfx::Rect screen_bounds_; + + // True if the widget has a external parent view/window outside of the + // Chromium-controlled view/window hierarchy. + bool has_external_parent_ = false; + DesktopDragDropClientAuraX11* drag_drop_client_ = nullptr; std::unique_ptr x11_window_move_client_; + // True if the xwindow has already been destroyed. + bool xwindow_destroyed_ = false; + DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11); }; diff --git ui/views/widget/widget.cc ui/views/widget/widget.cc index 734e988c5a9a..02e30f2f8b7f 100644 --- ui/views/widget/widget.cc +++ ui/views/widget/widget.cc @@ -288,7 +288,8 @@ void Widget::Init(InitParams params) { params.name = params.delegate->GetContentsView()->GetClassName(); params.child |= (params.type == InitParams::TYPE_CONTROL); - is_top_level_ = !params.child; + is_top_level_ = !params.child || + params.parent_widget != gfx::kNullAcceleratedWidget; if (params.opacity == views::Widget::InitParams::WindowOpacity::kInferred && params.type != views::Widget::InitParams::TYPE_WINDOW) { @@ -370,7 +371,12 @@ void Widget::Init(InitParams params) { } } else if (delegate) { SetContentsView(delegate->GetContentsView()); - SetInitialBoundsForFramelessWindow(bounds); + if (params.parent_widget != gfx::kNullAcceleratedWidget) { + // Set the bounds directly instead of applying an inset. + SetBounds(bounds); + } else { + SetInitialBoundsForFramelessWindow(bounds); + } } observer_manager_.Add(GetNativeTheme()); @@ -1147,10 +1153,16 @@ void Widget::OnNativeWidgetDestroyed() { } 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(); } diff --git ui/views/widget/widget.h ui/views/widget/widget.h index e7070ef061d9..e8bb88da3631 100644 --- ui/views/widget/widget.h +++ ui/views/widget/widget.h @@ -282,6 +282,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, gfx::NativeView parent = nullptr; + 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 diff --git ui/views/widget/widget_delegate.h ui/views/widget/widget_delegate.h index a3ec229f11cb..714f608b7b58 100644 --- ui/views/widget/widget_delegate.h +++ ui/views/widget/widget_delegate.h @@ -202,6 +202,10 @@ class VIEWS_EXPORT WidgetDelegate { // be cycled through with keyboard focus. virtual void GetAccessiblePanes(std::vector* panes) {} + // 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; } + protected: virtual ~WidgetDelegate(); diff --git ui/views/widget/widget_hwnd_utils.cc ui/views/widget/widget_hwnd_utils.cc index 40e66a212e3e..08ee8523ab15 100644 --- ui/views/widget/widget_hwnd_utils.cc +++ ui/views/widget/widget_hwnd_utils.cc @@ -67,7 +67,7 @@ void CalculateWindowStylesFromInitParams( if (!widget_delegate->CanResize()) *style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX); if (params.remove_standard_frame) - *style &= ~(WS_MINIMIZEBOX | WS_MAXIMIZEBOX); + *style &= ~(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 10f39e919d56..787a92fefdce 100644 --- ui/views/win/hwnd_message_handler.cc +++ ui/views/win/hwnd_message_handler.cc @@ -2994,10 +2994,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*