diff options
author | sky <sky@chromium.org> | 2015-11-04 19:47:28 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-05 03:48:49 +0000 |
commit | 56961cd296980da6de2b537d65a104da24af2b60 (patch) | |
tree | 9dbe306b91ce0147729b1aa5977439a0d9f3b3c9 /ui | |
parent | bec4cde315b6911e8a943edbae7db97d54af35f3 (diff) | |
download | chromium_src-56961cd296980da6de2b537d65a104da24af2b60.zip chromium_src-56961cd296980da6de2b537d65a104da24af2b60.tar.gz chromium_src-56961cd296980da6de2b537d65a104da24af2b60.tar.bz2 |
Makes windowmanager draw non-client area
The high level bits are the following:
. Client area is now expressed as insets. This avoids resetting the
client area any time the bounds changes.
. WindowManager now exposes preferred insets.
. Client side creates a NonClientFrameView that reflects insets
exposed from WM.
. WM's NonClientFrameView (which draws underneat the client's surface)
draws the frame decorations. It fills in the client area as black.
BUG=548420
TEST=none
R=ben@chromium.org
Review URL: https://codereview.chromium.org/1419793006
Cr-Commit-Position: refs/heads/master@{#357995}
Diffstat (limited to 'ui')
-rw-r--r-- | ui/mojo/geometry/geometry.mojom | 7 | ||||
-rw-r--r-- | ui/views/mus/BUILD.gn | 5 | ||||
-rw-r--r-- | ui/views/mus/display_converter.cc | 24 | ||||
-rw-r--r-- | ui/views/mus/display_converter.h | 22 | ||||
-rw-r--r-- | ui/views/mus/native_widget_mus.cc | 88 | ||||
-rw-r--r-- | ui/views/mus/native_widget_mus.h | 17 | ||||
-rw-r--r-- | ui/views/mus/window_manager_client_area_insets.h | 19 | ||||
-rw-r--r-- | ui/views/mus/window_manager_connection.cc | 20 | ||||
-rw-r--r-- | ui/views/window/non_client_view.h | 7 |
9 files changed, 195 insertions, 14 deletions
diff --git a/ui/mojo/geometry/geometry.mojom b/ui/mojo/geometry/geometry.mojom index 62bc6c8..95a4336 100644 --- a/ui/mojo/geometry/geometry.mojom +++ b/ui/mojo/geometry/geometry.mojom @@ -37,3 +37,10 @@ struct Transform { // Row major order. array<float, 16> matrix; }; + +struct Insets { + int32 top; + int32 left; + int32 bottom; + int32 right; +}; diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn index fa6741f..1384128 100644 --- a/ui/views/mus/BUILD.gn +++ b/ui/views/mus/BUILD.gn @@ -8,6 +8,8 @@ source_set("mus") { sources = [ "aura_init.cc", "aura_init.h", + "display_converter.cc", + "display_converter.h", "input_method_mus.cc", "input_method_mus.h", "native_widget_mus.cc", @@ -18,6 +20,7 @@ source_set("mus") { "surface_binding.h", "surface_context_factory.cc", "surface_context_factory.h", + "window_manager_client_area_insets.h", "window_manager_connection.cc", "window_manager_connection.h", "window_tree_host_mus.cc", @@ -53,6 +56,8 @@ source_set("mus") { "//ui/compositor", "//ui/events", "//ui/events:events_base", + "//ui/gfx", + "//ui/gfx/geometry", "//ui/gl", "//ui/mojo/ime:interfaces_cpp_sources", "//ui/mojo/init", diff --git a/ui/views/mus/display_converter.cc b/ui/views/mus/display_converter.cc new file mode 100644 index 0000000..954aad7 --- /dev/null +++ b/ui/views/mus/display_converter.cc @@ -0,0 +1,24 @@ +// Copyright 2015 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/mus/display_converter.h" + +#include "components/mus/public/cpp/window.h" +#include "mojo/converters/geometry/geometry_type_converters.h" + +namespace views { + +std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window) { + static int64 synthesized_display_id = 2000; + gfx::Display display; + display.set_id(synthesized_display_id++); + display.SetScaleAndBounds( + window->viewport_metrics().device_pixel_ratio, + gfx::Rect(window->viewport_metrics().size_in_pixels.To<gfx::Size>())); + std::vector<gfx::Display> displays; + displays.push_back(display); + return displays; +} + +} // namespace views diff --git a/ui/views/mus/display_converter.h b/ui/views/mus/display_converter.h new file mode 100644 index 0000000..a747455 --- /dev/null +++ b/ui/views/mus/display_converter.h @@ -0,0 +1,22 @@ +// Copyright 2015 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_MUS_DISPLAY_CONVERTER_H_ +#define UI_VIEWS_MUS_DISPLAY_CONVERTER_H_ + +#include <vector> + +#include "ui/gfx/display.h" + +namespace mus { +class Window; +} + +namespace views { + +std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window); + +} // namespace views + +#endif // UI_VIEWS_MUS_DISPLAY_CONVERTER_H_ diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc index f9b43d3..507e83f 100644 --- a/ui/views/mus/native_widget_mus.cc +++ b/ui/views/mus/native_widget_mus.cc @@ -10,9 +10,15 @@ #include "ui/aura/client/default_capture_client.h" #include "ui/aura/layout_manager.h" #include "ui/aura/window.h" +#include "ui/base/hit_test.h" +#include "ui/compositor/clip_transform_recorder.h" +#include "ui/compositor/paint_recorder.h" +#include "ui/gfx/canvas.h" #include "ui/native_theme/native_theme_aura.h" +#include "ui/views/mus/window_manager_client_area_insets.h" #include "ui/views/mus/window_tree_host_mus.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/window/custom_frame_view.h" #include "ui/wm/core/base_focus_rules.h" #include "ui/wm/core/capture_controller.h" #include "ui/wm/core/focus_controller.h" @@ -20,6 +26,8 @@ namespace views { namespace { +WindowManagerClientAreaInsets* window_manager_client_area_insets = nullptr; + // TODO: figure out what this should be. class FocusRulesImpl : public wm::BaseFocusRules { public: @@ -61,6 +69,60 @@ class ContentWindowLayoutManager : public aura::LayoutManager { DISALLOW_COPY_AND_ASSIGN(ContentWindowLayoutManager); }; +// As the window manager renderers the non-client decorations this class does +// very little but honor the client area insets from the window manager. +class ClientSideNonClientFrameView : public NonClientFrameView { + public: + explicit ClientSideNonClientFrameView(views::Widget* widget) + : widget_(widget) {} + ~ClientSideNonClientFrameView() override {} + + private: + // Returns the default values of client area insets from the window manager. + static gfx::Insets GetDefaultWindowManagerInsets(bool is_maximized) { + if (!window_manager_client_area_insets) + return gfx::Insets(); + return is_maximized ? window_manager_client_area_insets->maximized_insets + : window_manager_client_area_insets->normal_insets; + } + + // NonClientFrameView: + gfx::Rect GetBoundsForClientView() const override { + gfx::Rect result(GetLocalBounds()); + result.Inset(GetDefaultWindowManagerInsets(widget_->IsMaximized())); + return result; + } + gfx::Rect GetWindowBoundsForClientBounds( + const gfx::Rect& client_bounds) const override { + const gfx::Insets insets( + GetDefaultWindowManagerInsets(widget_->IsMaximized())); + return gfx::Rect(client_bounds.x() - insets.left(), + client_bounds.y() - insets.top(), + client_bounds.width() + insets.width(), + client_bounds.height() + insets.height()); + } + int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; } + void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override { + // The window manager provides the shape; do nothing. + } + void ResetWindowControls() override { + // TODO(sky): push to wm? + } + void UpdateWindowIcon() override { + // NOTIMPLEMENTED(); + } + void UpdateWindowTitle() override { + // NOTIMPLEMENTED(); + } + void SizeConstraintsChanged() override { + // NOTIMPLEMENTED(); + } + + views::Widget* widget_; + + DISALLOW_COPY_AND_ASSIGN(ClientSideNonClientFrameView); +}; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -78,6 +140,15 @@ NativeWidgetMus::NativeWidgetMus(internal::NativeWidgetDelegate* delegate, content_(new aura::Window(this)) {} NativeWidgetMus::~NativeWidgetMus() {} +// static +void NativeWidgetMus::SetWindowManagerClientAreaInsets( + const WindowManagerClientAreaInsets& insets) { + delete window_manager_client_area_insets; + // This is called early on, so we don't bother trying to relayout existing + // NativeWidgetMus. When we support restarting the WM we'll need to do that. + window_manager_client_area_insets = new WindowManagerClientAreaInsets(insets); +} + //////////////////////////////////////////////////////////////////////////////// // NativeWidgetMus, private: @@ -87,12 +158,20 @@ void NativeWidgetMus::UpdateClientAreaInWindowManager() { if (!non_client_view || !non_client_view->client_view()) return; - window_->SetClientArea(non_client_view->client_view()->bounds()); + const gfx::Rect client_area_rect(non_client_view->client_view()->bounds()); + window_->SetClientArea(gfx::Insets( + client_area_rect.y(), client_area_rect.x(), + non_client_view->bounds().height() - client_area_rect.bottom(), + non_client_view->bounds().width() - client_area_rect.right())); } //////////////////////////////////////////////////////////////////////////////// // NativeWidgetMus, internal::NativeWidgetPrivate implementation: +NonClientFrameView* NativeWidgetMus::CreateNonClientFrameView() { + return new ClientSideNonClientFrameView(GetWidget()); +} + void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) { window_tree_host_.reset( new WindowTreeHostMus(shell_, window_, surface_type_)); @@ -119,11 +198,6 @@ void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) { // TODO(beng): much else, see [Desktop]NativeWidgetAura. } -NonClientFrameView* NativeWidgetMus::CreateNonClientFrameView() { - // NOTIMPLEMENTED(); - return nullptr; -} - bool NativeWidgetMus::ShouldUseNativeFrame() const { // NOTIMPLEMENTED(); return false; @@ -386,7 +460,7 @@ void NativeWidgetMus::RunShellDrag( } void NativeWidgetMus::SchedulePaintInRect(const gfx::Rect& rect) { - // NOTIMPLEMENTED(); + content_->SchedulePaintInRect(rect); } void NativeWidgetMus::SetCursor(gfx::NativeCursor cursor) { diff --git a/ui/views/mus/native_widget_mus.h b/ui/views/mus/native_widget_mus.h index 61df1cc..dbfbba0 100644 --- a/ui/views/mus/native_widget_mus.h +++ b/ui/views/mus/native_widget_mus.h @@ -23,6 +23,10 @@ class Shell; namespace mus { class Window; + +namespace mojom { +class WindowManager; +} } namespace wm { @@ -30,6 +34,7 @@ class FocusController; } namespace views { +struct WindowManagerClientAreaInsets; class WindowTreeHostMus; // An implementation of NativeWidget that binds to a mus::Window. Because Aura @@ -47,12 +52,22 @@ class NativeWidgetMus : public internal::NativeWidgetPrivate, mus::mojom::SurfaceType surface_type); ~NativeWidgetMus() override; + // Sets the insets for the client area. These values come from the window + // manager. + static void SetWindowManagerClientAreaInsets( + const WindowManagerClientAreaInsets& insets); + + mus::Window* window() { return window_; } + + protected: + // internal::NativeWidgetPrivate: + NonClientFrameView* CreateNonClientFrameView() override; + private: void UpdateClientAreaInWindowManager(); // internal::NativeWidgetPrivate: void InitNativeWidget(const Widget::InitParams& params) override; - NonClientFrameView* CreateNonClientFrameView() override; bool ShouldUseNativeFrame() const override; bool ShouldWindowContentsBeTransparent() const override; void FrameTypeChanged() override; diff --git a/ui/views/mus/window_manager_client_area_insets.h b/ui/views/mus/window_manager_client_area_insets.h new file mode 100644 index 0000000..20a27f6 --- /dev/null +++ b/ui/views/mus/window_manager_client_area_insets.h @@ -0,0 +1,19 @@ +// Copyright 2015 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_MUS_WINDOW_MANAGER_CLIENT_AREA_INSETS_H_ +#define UI_VIEWS_MUS_WINDOW_MANAGER_CLIENT_AREA_INSETS_H_ + +#include "ui/gfx/geometry/insets.h" + +namespace views { + +struct WindowManagerClientAreaInsets { + gfx::Insets normal_insets; + gfx::Insets maximized_insets; +}; + +} // namespace views + +#endif // UI_VIEWS_MUS_WINDOW_MANAGER_CLIENT_AREA_INSETS_H_ diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc index b46ac10..006a8b3 100644 --- a/ui/views/mus/window_manager_connection.cc +++ b/ui/views/mus/window_manager_connection.cc @@ -17,6 +17,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/mojo/init/ui_init.h" #include "ui/views/mus/native_widget_mus.h" +#include "ui/views/mus/window_manager_client_area_insets.h" #include "ui/views/views_delegate.h" namespace mojo { @@ -58,6 +59,8 @@ struct TypeConverter<gfx::Display, mus::mojom::DisplayPtr> { } // namespace mojo +namespace views { + namespace { using WindowManagerConnectionPtr = @@ -69,18 +72,23 @@ base::LazyInstance<WindowManagerConnectionPtr>::Leaky lazy_tls_ptr = std::vector<gfx::Display> GetDisplaysFromWindowManager( mus::mojom::WindowManagerPtr* window_manager) { + WindowManagerClientAreaInsets client_insets; std::vector<gfx::Display> displays; - (*window_manager)->GetDisplays( - [&displays](mojo::Array<mus::mojom::DisplayPtr> mojom_displays) { - displays = mojom_displays.To<std::vector<gfx::Display>>(); + (*window_manager) + ->GetConfig([&displays, + &client_insets](mus::mojom::WindowManagerConfigPtr results) { + displays = results->displays.To<std::vector<gfx::Display>>(); + client_insets.normal_insets = + results->normal_client_area_insets.To<gfx::Insets>(); + client_insets.maximized_insets = + results->maximized_client_area_insets.To<gfx::Insets>(); }); CHECK(window_manager->WaitForIncomingResponse()); + NativeWidgetMus::SetWindowManagerClientAreaInsets(client_insets); return displays; } -} - -namespace views { +} // namespace // static void WindowManagerConnection::Create( diff --git a/ui/views/window/non_client_view.h b/ui/views/window/non_client_view.h index 762ccf1..4efde57 100644 --- a/ui/views/window/non_client_view.h +++ b/ui/views/window/non_client_view.h @@ -73,12 +73,19 @@ class VIEWS_EXPORT NonClientFrameView : public View, // the parent NonClientView because that makes it more difficult to calculate // hittests for regions that are partially obscured by the ClientView, e.g. // HTSYSMENU. + // Return value is one of the windows HT constants (see ui/base/hit_test.h). virtual int NonClientHitTest(const gfx::Point& point) = 0; + + // Used to make the hosting widget shaped (non-rectangular). For a + // rectangular window do nothing. For a shaped window update |window_mask| + // accordingly. |size| is the size of the widget. virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) = 0; virtual void ResetWindowControls() = 0; virtual void UpdateWindowIcon() = 0; virtual void UpdateWindowTitle() = 0; + + // Whether the widget can be resized or maximized has changed. virtual void SizeConstraintsChanged() = 0; // View: |