summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorsky <sky@chromium.org>2015-11-04 19:47:28 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-05 03:48:49 +0000
commit56961cd296980da6de2b537d65a104da24af2b60 (patch)
tree9dbe306b91ce0147729b1aa5977439a0d9f3b3c9 /ui
parentbec4cde315b6911e8a943edbae7db97d54af35f3 (diff)
downloadchromium_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.mojom7
-rw-r--r--ui/views/mus/BUILD.gn5
-rw-r--r--ui/views/mus/display_converter.cc24
-rw-r--r--ui/views/mus/display_converter.h22
-rw-r--r--ui/views/mus/native_widget_mus.cc88
-rw-r--r--ui/views/mus/native_widget_mus.h17
-rw-r--r--ui/views/mus/window_manager_client_area_insets.h19
-rw-r--r--ui/views/mus/window_manager_connection.cc20
-rw-r--r--ui/views/window/non_client_view.h7
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: