diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-29 19:32:06 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-29 19:32:06 +0000 |
commit | 81585f3fa532dbe0355991b56c8d5bbb7b9ae321 (patch) | |
tree | 69f78267fc35600fec11a9533fe5d7af18ed42dc | |
parent | f1aa3566cb4b397eb4f567e8b88610d81de17566 (diff) | |
download | chromium_src-81585f3fa532dbe0355991b56c8d5bbb7b9ae321.zip chromium_src-81585f3fa532dbe0355991b56c8d5bbb7b9ae321.tar.gz chromium_src-81585f3fa532dbe0355991b56c8d5bbb7b9ae321.tar.bz2 |
Shell of implementation for embedded windows. At this point this is
just a proof of concept. Next step is going to be pulling code from
the window manager into this. Desktop will likely be renamed to
WindowManager.
At this point just make sure you think I'm not going off into the
weeds.
BUG=none
TEST=none
R=derat@chromium.org
Review URL: http://codereview.chromium.org/7534002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94733 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | aura/aura.gyp | 58 | ||||
-rw-r--r-- | aura/demo/demo_main.cc | 78 | ||||
-rw-r--r-- | aura/desktop.cc | 46 | ||||
-rw-r--r-- | aura/desktop.h | 58 | ||||
-rw-r--r-- | aura/desktop_host.h | 45 | ||||
-rw-r--r-- | aura/desktop_host_win.cc | 54 | ||||
-rw-r--r-- | aura/desktop_host_win.h | 42 | ||||
-rw-r--r-- | aura/window.cc | 83 | ||||
-rw-r--r-- | aura/window.h | 92 | ||||
-rw-r--r-- | aura/window_delegate.h | 24 | ||||
-rw-r--r-- | build/all.gyp | 1 | ||||
-rw-r--r-- | views/view_unittest.cc | 4 | ||||
-rw-r--r-- | views/widget/widget.h | 4 |
13 files changed, 584 insertions, 5 deletions
diff --git a/aura/aura.gyp b/aura/aura.gyp new file mode 100644 index 0000000..6a555d0 --- /dev/null +++ b/aura/aura.gyp @@ -0,0 +1,58 @@ +# Copyright (c) 2011 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'aura', + 'type': 'static_library', + 'dependencies': [ + '../base/base.gyp:base', + '../base/base.gyp:base_i18n', + '../skia/skia.gyp:skia', + '../ui/gfx/compositor/compositor.gyp:compositor', + '../ui/ui.gyp:gfx_resources', + '../ui/ui.gyp:ui', + '../ui/ui.gyp:ui_resources', + ], + 'sources': [ + 'desktop_host.h', + 'desktop_host_win.cc', + 'desktop_host_win.h', + 'desktop.cc', + 'desktop.h', + 'window.cc', + 'window.h', + 'window_delegate.h', + ], + }, + { + 'target_name': 'aura_demo', + 'type': 'executable', + 'dependencies': [ + '../base/base.gyp:base', + '../base/base.gyp:base_i18n', + '../skia/skia.gyp:skia', + '../third_party/icu/icu.gyp:icui18n', + '../third_party/icu/icu.gyp:icuuc', + '../ui/gfx/compositor/compositor.gyp:compositor', + '../ui/ui.gyp:gfx_resources', + '../ui/ui.gyp:ui', + '../ui/ui.gyp:ui_resources', + 'aura', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'demo/demo_main.cc', + '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc', + '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', + ], + }, + ], +} diff --git a/aura/demo/demo_main.cc b/aura/demo/demo_main.cc new file mode 100644 index 0000000..ccb77de --- /dev/null +++ b/aura/demo/demo_main.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2011 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 "aura/desktop.h" +#include "aura/desktop_host.h" +#include "aura/window.h" +#include "aura/window_delegate.h" +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/i18n/icu_util.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "third_party/skia/include/core/SkXfermode.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/canvas_skia.h" +#include "ui/gfx/rect.h" +#include "ui/base/ui_base_paths.h" + +namespace { + +// Trivial WindowDelegate implementation that draws a blue background. +class DemoWindowDelegate : public aura::WindowDelegate { + public: + explicit DemoWindowDelegate(aura::Window* window); + + virtual void OnPaint(const gfx::Rect& bounds) OVERRIDE; + + private: + aura::Window* window_; + + DISALLOW_COPY_AND_ASSIGN(DemoWindowDelegate); +}; + +DemoWindowDelegate::DemoWindowDelegate(aura::Window* window) + : window_(window) { +} + +void DemoWindowDelegate::OnPaint(const gfx::Rect& bounds) { + scoped_ptr<gfx::Canvas> canvas( + gfx::Canvas::CreateCanvas(bounds.width(), bounds.height(), false)); + canvas->AsCanvasSkia()->drawColor( + SK_ColorBLUE, SkXfermode::kSrc_Mode); + window_->SetCanvas(*canvas->AsCanvasSkia(), bounds.origin()); +} + +} // namespace + +int main(int argc, char** argv) { + CommandLine::Init(argc, argv); + + // The exit manager is in charge of calling the dtors of singleton objects. + base::AtExitManager exit_manager; + + ui::RegisterPathProvider(); + icu_util::Initialize(); + ResourceBundle::InitSharedInstance("en-US"); + + // Create the DesktopHost and Desktop. + scoped_ptr<aura::DesktopHost> host( + aura::DesktopHost::Create(gfx::Rect(200, 200, 1024, 768))); + aura::Desktop desktop(host->GetAcceleratedWidget(), host->GetSize()); + host->SetDesktop(&desktop); + + // Create a test window and give it a size. + aura::Window window(&desktop); + window.SetBounds(gfx::Rect(100, 100, 400, 400), 0); + window.SetVisibility(aura::Window::VISIBILITY_SHOWN); + DemoWindowDelegate window_delegate(&window); + window.set_delegate(&window_delegate); + + host->Show(); + + MessageLoop main_message_loop(MessageLoop::TYPE_UI); + MessageLoopForUI::current()->Run(NULL); + return 0; +} diff --git a/aura/desktop.cc b/aura/desktop.cc new file mode 100644 index 0000000..c8b9187 --- /dev/null +++ b/aura/desktop.cc @@ -0,0 +1,46 @@ +// Copyright (c) 2011 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 "aura/desktop.h" + +#include <algorithm> + +#include "aura/window.h" +#include "base/logging.h" +#include "ui/gfx/compositor/compositor.h" + +namespace aura { + +Desktop::Desktop(gfx::AcceleratedWidget widget, const gfx::Size& size) + : compositor_(ui::Compositor::Create(widget, size)) { + DCHECK(compositor_.get()); +} + +Desktop::~Desktop() { +} + +void Desktop::Draw() { + // First pass updates the layer bitmaps. + for (Windows::iterator i = windows_.begin(); i != windows_.end(); ++i) + (*i)->UpdateLayerCanvas(); + + // Second pass renders the layers. + compositor_->NotifyStart(); + for (Windows::iterator i = windows_.begin(); i != windows_.end(); ++i) + (*i)->Draw(); + compositor_->NotifyEnd(); +} + +void Desktop::AddWindow(Window* window) { + DCHECK(std::find(windows_.begin(), windows_.end(), window) == windows_.end()); + windows_.push_back(window); +} + +void Desktop::RemoveWindow(Window* window) { + Windows::iterator i = std::find(windows_.begin(), windows_.end(), window); + DCHECK(i != windows_.end()); + windows_.erase(i); +} + +} // namespace aura diff --git a/aura/desktop.h b/aura/desktop.h new file mode 100644 index 0000000..4bed643 --- /dev/null +++ b/aura/desktop.h @@ -0,0 +1,58 @@ +// Copyright (c) 2011 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 AURA_DESKTOP_H_ +#define AURA_DESKTOP_H_ +#pragma once + +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "ui/gfx/native_widget_types.h" + +namespace gfx { +class Size; +} + +namespace ui { +class Compositor; +class Window; +} + +namespace aura { + +// Desktop is responsible for hosting a set of windows. +class Desktop { + public: + Desktop(gfx::AcceleratedWidget widget, const gfx::Size& size); + ~Desktop(); + + // Draws the necessary set of windows. + void Draw(); + + // Compositor we're drawing to. + ui::Compositor* compositor() { return compositor_.get(); } + + private: + friend class Window; + + typedef std::vector<Window*> Windows; + + // Methods invoked by Window. + // TODO: move these into an interface that Window uses to talk to Desktop. + void AddWindow(Window* window); + void RemoveWindow(Window* window); + + scoped_refptr<ui::Compositor> compositor_; + + // The windows. Topmost window is last. + std::vector<Window*> windows_; + + DISALLOW_COPY_AND_ASSIGN(Desktop); +}; + +} // namespace aura + +#endif // AURA_DESKTOP_H_ diff --git a/aura/desktop_host.h b/aura/desktop_host.h new file mode 100644 index 0000000..d0e7d4a --- /dev/null +++ b/aura/desktop_host.h @@ -0,0 +1,45 @@ +// Copyright (c) 2011 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 AURA_DESKTOP_HOST_H_ +#define AURA_DESKTOP_HOST_H_ +#pragma once + +#include "ui/gfx/native_widget_types.h" + +namespace gfx { +class Rect; +class Size; +} + +namespace aura { + +class Desktop; + +// DesktopHost bridges between a native window and the embedded Desktop. It +// provides the accelerated widget and maps events from the native os to aura. +class DesktopHost { + public: + virtual ~DesktopHost() {} + + // Creates a new DesktopHost. The caller owns the returned value. + static DesktopHost* Create(const gfx::Rect& bounds); + + // Sets the Desktop this DesktopHost is hosting. DesktopHost does not own the + // Desktop. + virtual void SetDesktop(Desktop* desktop) = 0; + + // Returns the accelerated widget. + virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; + + // Shows the DesktopHost. + virtual void Show() = 0; + + // Returns the size of the DesktopHost. + virtual gfx::Size GetSize() = 0; +}; + +} // namespace aura + +#endif // AURA_DESKTOP_HOST_H_ diff --git a/aura/desktop_host_win.cc b/aura/desktop_host_win.cc new file mode 100644 index 0000000..70489ea --- /dev/null +++ b/aura/desktop_host_win.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2011 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 "aura/desktop_host_win.h" + +#include "aura/desktop.h" +#include "base/message_loop.h" + +namespace aura { + +// static +DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) { + return new DesktopHostWin(bounds); +} + +DesktopHostWin::DesktopHostWin(const gfx::Rect& bounds) : desktop_(NULL) { + Init(NULL, bounds); +} + +DesktopHostWin::~DesktopHostWin() { + DestroyWindow(hwnd()); +} + +void DesktopHostWin::SetDesktop(Desktop* desktop) { + desktop_ = desktop; +} + +gfx::AcceleratedWidget DesktopHostWin::GetAcceleratedWidget() { + return hwnd(); +} + +void DesktopHostWin::Show() { + ShowWindow(hwnd(), SW_SHOWNORMAL); +} + +gfx::Size DesktopHostWin::GetSize() { + RECT r; + GetClientRect(hwnd(), &r); + return gfx::Rect(r).size(); +} + +void DesktopHostWin::OnClose() { + // TODO: this obviously shouldn't be here. + MessageLoopForUI::current()->Quit(); +} + +void DesktopHostWin::OnPaint(HDC dc) { + if (desktop_) + desktop_->Draw(); + ValidateRect(hwnd(), NULL); +} + +} // namespace aura diff --git a/aura/desktop_host_win.h b/aura/desktop_host_win.h new file mode 100644 index 0000000..9513a37 --- /dev/null +++ b/aura/desktop_host_win.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 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 AURA_DESKTOP_HOST_WIN_H_ +#define AURA_DESKTOP_HOST_WIN_H_ +#pragma once + +#include "aura/desktop_host.h" +#include "base/compiler_specific.h" +#include "ui/base/win/window_impl.h" + +namespace aura { + +class DesktopHostWin : public DesktopHost, public ui::WindowImpl { + public: + DesktopHostWin(const gfx::Rect& bounds); + virtual ~DesktopHostWin(); + + // DesktopHost: + virtual void SetDesktop(Desktop* desktop) OVERRIDE; + virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; + virtual void Show() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + + private: + BEGIN_MSG_MAP_EX(DesktopHostWin) + MSG_WM_CLOSE(OnClose) + MSG_WM_PAINT(OnPaint) + END_MSG_MAP() + + void OnClose(); + void OnPaint(HDC dc); + + Desktop* desktop_; + + DISALLOW_COPY_AND_ASSIGN(DesktopHostWin); +}; + +} // namespace aura + +#endif // AURA_DESKTOP_HOST_WIN_H_ diff --git a/aura/window.cc b/aura/window.cc new file mode 100644 index 0000000..41a4af2 --- /dev/null +++ b/aura/window.cc @@ -0,0 +1,83 @@ +// Copyright (c) 2011 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 "aura/window.h" + +#include "aura/desktop.h" +#include "aura/window_delegate.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "ui/gfx/compositor/compositor.h" +#include "ui/gfx/compositor/layer.h" + +namespace aura { + +// TODO: do we need to support child windows? +Window::Window(Desktop* desktop) + : desktop_(desktop), + delegate_(NULL), + visibility_(VISIBILITY_HIDDEN), + // TODO: Need to make layers lazily create the texture. + layer_(new ui::Layer(desktop->compositor())), + needs_paint_all_(true) { +} + +Window::~Window() { +} + +void Window::SetVisibility(Visibility visibility) { + if (visibility_ == visibility) + return; + + visibility_ = visibility; + if (visibility_ == VISIBILITY_SHOWN) { + // TODO: move to top of window stack? + desktop_->AddWindow(this); + } else { + // TODO: hide? + desktop_->RemoveWindow(this); + } +} + +void Window::SetBounds(const gfx::Rect& bounds, int anim_ms) { + // TODO: support anim_ms + // TODO: funnel this through the Desktop. + bounds_ = bounds; + layer_->set_bounds(bounds); +} + +void Window::SchedulePaint(const gfx::Rect& bounds) { + if (dirty_rect_.IsEmpty()) + dirty_rect_ = bounds; + else + dirty_rect_ = dirty_rect_.Union(bounds); +} + +void Window::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) { + // TODO: figure out how this is going to work when animating the layer. In + // particular if we're animating the size then the underyling Texture is going + // to be unhappy if we try to set a texture on a size bigger than the size of + // the texture. + layer_->SetCanvas(canvas, origin); +} + +void Window::Draw() { + if (visibility_ != VISIBILITY_HIDDEN) + layer_->Draw(); +} + +void Window::UpdateLayerCanvas() { + if (needs_paint_all_) { + needs_paint_all_ = false; + dirty_rect_ = gfx::Rect(0, 0, bounds().width(), bounds().height()); + } + gfx::Rect dirty_rect = dirty_rect_.Intersect( + gfx::Rect(0, 0, bounds().width(), bounds().height())); + dirty_rect_.SetRect(0, 0, 0, 0); + if (dirty_rect.IsEmpty()) + return; + if (delegate_) + delegate_->OnPaint(dirty_rect); +} + +} // namespace aura diff --git a/aura/window.h b/aura/window.h new file mode 100644 index 0000000..14c3ea4 --- /dev/null +++ b/aura/window.h @@ -0,0 +1,92 @@ +// Copyright (c) 2011 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 AURA_WINDOW_H_ +#define AURA_WINDOW_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/rect.h" + +class SkCanvas; + +namespace ui { +class Layer; +} + +namespace aura { + +class Desktop; +class WindowDelegate; + +// Aura window implementation. Interesting events are sent to the +// WindowDelegate. +class Window { + public: + enum Visibility { + // Don't display the window onscreen and don't let it receive mouse + // events. This is the default. + VISIBILITY_HIDDEN = 1, + + // Display the window and let it receive mouse events. + VISIBILITY_SHOWN = 2, + + // Display the window but prevent it from receiving mouse events. + VISIBILITY_SHOWN_NO_INPUT = 3, + }; + + explicit Window(Desktop* desktop); + ~Window(); + + void set_delegate(WindowDelegate* d) { delegate_ = d; } + + // Changes the visbility of the window. + void SetVisibility(Visibility visibility); + Visibility visibility() const { return visibility_; } + + // Changes the bounds of the window. + void SetBounds(const gfx::Rect& bounds, int anim_ms); + const gfx::Rect& bounds() const { return bounds_; } + + // Marks the window as needing to be painted. + void SchedulePaint(const gfx::Rect& bounds); + + // Sets the contents of the window. + void SetCanvas(const SkCanvas& canvas, const gfx::Point& origin); + + // If the window is visible its layer is drawn. + void Draw(); + + // If SchedulePaint has been invoked on the Window the delegate is notified. + void UpdateLayerCanvas(); + + private: + // The desktop we're in. + Desktop* desktop_; + + WindowDelegate* delegate_; + + Visibility visibility_; + + scoped_ptr<ui::Layer> layer_; + + // Union of regions passed to SchedulePaint. Cleaned when UpdateLayerCanvas is + // invoked. + gfx::Rect dirty_rect_; + + // If true UpdateLayerCanvas paints all. This is set when the window is first + // created to trigger painting the complete bounds. + bool needs_paint_all_; + + // Bounds of the window in the desktop's coordinate system. + gfx::Rect bounds_; + + DISALLOW_COPY_AND_ASSIGN(Window); +}; + +} // namespace aura + +#endif // AURA_WINDOW_H_ diff --git a/aura/window_delegate.h b/aura/window_delegate.h new file mode 100644 index 0000000..69637cf --- /dev/null +++ b/aura/window_delegate.h @@ -0,0 +1,24 @@ +// Copyright (c) 2011 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 AURA_WINDOW_DELEGATE_H_ +#define AURA_WINDOW_DELEGATE_H_ +#pragma once + +namespace aura { + +// Delegate interface for aura::Window. +class WindowDelegate { + public: + // Asks the delegate to paint to the window. The delegate should call back + // to the window with SetCanvas. + virtual void OnPaint(const gfx::Rect& bounds) = 0; + + protected: + virtual ~WindowDelegate() {} +}; + +} // namespace aura + +#endif // AURA_WINDOW_DELEGATE_H_ diff --git a/build/all.gyp b/build/all.gyp index fff0f7d..599685b 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -105,6 +105,7 @@ }], ], 'dependencies': [ + '../aura/aura.gyp:*', '../breakpad/breakpad.gyp:*', '../chrome/app/locales/locales.gyp:*', '../chrome_frame/chrome_frame.gyp:*', diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 915104f1..e4ed9e5 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -2402,7 +2402,7 @@ class ViewLayerTest : public ViewsTestBase { TestTexture::reset_live_count(); - Widget::set_compositor_factory(&TestCreateCompositor); + Widget::set_compositor_factory_for_testing(&TestCreateCompositor); widget_ = new Widget; Widget::InitParams params(Widget::InitParams::TYPE_POPUP); params.bounds = gfx::Rect(50, 50, 200, 200); @@ -2412,7 +2412,7 @@ class ViewLayerTest : public ViewsTestBase { virtual void TearDown() OVERRIDE { View::set_use_acceleration_when_possible(old_use_acceleration_); widget_->CloseNow(); - Widget::set_compositor_factory(NULL); + Widget::set_compositor_factory_for_testing(NULL); Widget::SetPureViews(false); } diff --git a/views/widget/widget.h b/views/widget/widget.h index 372b5a8..9af6481 100644 --- a/views/widget/widget.h +++ b/views/widget/widget.h @@ -486,11 +486,9 @@ class VIEWS_API Widget : public internal::NativeWidgetDelegate, return non_client_view_ ? non_client_view_->client_view() : NULL; } -#if defined(UNIT_TEST) - static void set_compositor_factory(ui::Compositor*(*factory)()) { + static void set_compositor_factory_for_testing(ui::Compositor*(*factory)()) { compositor_factory_ = factory; } -#endif static ui::Compositor* (*compositor_factory())() { return compositor_factory_; } |