diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/aura.gyp | 6 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_activation_client.cc | 101 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_activation_client.h | 56 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_dispatcher_client.cc | 32 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_dispatcher_client.h | 30 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_root_window_event_filter.cc | 109 | ||||
-rw-r--r-- | ui/aura/desktop/desktop_root_window_event_filter.h | 63 | ||||
-rw-r--r-- | ui/aura/event.cc | 21 | ||||
-rw-r--r-- | ui/aura/event.h | 20 | ||||
-rw-r--r-- | ui/gfx/screen_ash.cc | 25 | ||||
-rw-r--r-- | ui/views/examples/examples_main.cc | 53 | ||||
-rw-r--r-- | ui/views/views.gyp | 6 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 57 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.h | 6 |
14 files changed, 581 insertions, 4 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index f4dbf96..b862a70 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -50,6 +50,12 @@ 'client/window_move_client.h', 'client/window_types.h', 'cursor.h', + 'desktop/desktop_activation_client.cc', + 'desktop/desktop_activation_client.h', + 'desktop/desktop_dispatcher_client.cc', + 'desktop/desktop_dispatcher_client.h', + 'desktop/desktop_root_window_event_filter.cc', + 'desktop/desktop_root_window_event_filter.h', 'dispatcher_linux.cc', 'dispatcher_linux.h', 'dispatcher_win.cc', diff --git a/ui/aura/desktop/desktop_activation_client.cc b/ui/aura/desktop/desktop_activation_client.cc new file mode 100644 index 0000000..6704317 --- /dev/null +++ b/ui/aura/desktop/desktop_activation_client.cc @@ -0,0 +1,101 @@ +// Copyright (c) 2012 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/aura/desktop/desktop_activation_client.h" + +#include "base/auto_reset.h" +#include "ui/aura/client/activation_delegate.h" +#include "ui/aura/focus_manager.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" + +namespace aura { + +DesktopActivationClient::DesktopActivationClient(RootWindow* root_window) + : root_window_(root_window), + current_active_(NULL), + updating_activation_(false) { + root_window->AddRootWindowObserver(this); +} + +DesktopActivationClient::~DesktopActivationClient() { + root_window_->RemoveRootWindowObserver(this); +} + +void DesktopActivationClient::ActivateWindow(Window* window) { + // Prevent recursion when called from focus. + if (updating_activation_) + return; + + AutoReset<bool> in_activate_window(&updating_activation_, true); + // Nothing may actually have changed. + aura::Window* old_active = GetActiveWindow(); + if (old_active == window) + return; + // The stacking client may impose rules on what window configurations can be + // activated or deactivated. + if (window && !CanActivateWindow(window)) + return; + // Switch internal focus before we change the activation. Will probably cause + // recursion. + if (window && + !window->Contains(window->GetFocusManager()->GetFocusedWindow())) { + window->GetFocusManager()->SetFocusedWindow(window, NULL); + } + + // Send a deactivation to the old window + if (current_active_ && aura::client::GetActivationDelegate(current_active_)) + aura::client::GetActivationDelegate(current_active_)->OnLostActive(); + + current_active_ = window; + + // Send an activation event to the new window + if (window && aura::client::GetActivationDelegate(window)) + aura::client::GetActivationDelegate(window)->OnActivated(); +} + +void DesktopActivationClient::DeactivateWindow(Window* window) { + if (window == current_active_) + current_active_ = NULL; +} + +aura::Window* DesktopActivationClient::GetActiveWindow() { + return current_active_; +} + +bool DesktopActivationClient::OnWillFocusWindow(Window* window, + const Event* event) { + // TODO(erg): Is this OK? Logic is much more nuanced in ash. + return TRUE; +} + +void DesktopActivationClient::OnWindowFocused(aura::Window* window) { + ActivateWindow(GetActivatableWindow(window)); +} + +bool DesktopActivationClient::CanActivateWindow(aura::Window* window) const { + return window && + window->IsVisible() && + (!aura::client::GetActivationDelegate(window) || + aura::client::GetActivationDelegate(window)->ShouldActivate(NULL)); +} + +aura::Window* DesktopActivationClient::GetActivatableWindow( + aura::Window* window) { + aura::Window* parent = window->parent(); + aura::Window* child = window; + while (parent) { + if (CanActivateWindow(child)) + return child; + // If |child| isn't activatable, but has transient parent, trace + // that path instead. + if (child->transient_parent()) + return GetActivatableWindow(child->transient_parent()); + parent = parent->parent(); + child = child->parent(); + } + return NULL; +} + +} // namespace aura diff --git a/ui/aura/desktop/desktop_activation_client.h b/ui/aura/desktop/desktop_activation_client.h new file mode 100644 index 0000000..5d2f12c --- /dev/null +++ b/ui/aura/desktop/desktop_activation_client.h @@ -0,0 +1,56 @@ +// Copyright (c) 2012 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_AURA_DESKTOP_DESTKOP_ACTIVATION_CLIENT_H_ +#define UI_AURA_DESKTOP_DESTKOP_ACTIVATION_CLIENT_H_ +#pragma once + +#include "base/basictypes.h" +#include "ui/aura/aura_export.h" +#include "ui/aura/client/activation_client.h" +#include "ui/aura/root_window_observer.h" + +namespace aura { +class RootWindow; + +// An activation client that handles activation events in a single +// RootWindow. Used only on the Desktop where there can be multiple RootWindow +// objects. +class AURA_EXPORT DesktopActivationClient : public client::ActivationClient, + public RootWindowObserver { + public: + explicit DesktopActivationClient(RootWindow* root_window); + virtual ~DesktopActivationClient(); + + // ActivationClient: + virtual void ActivateWindow(Window* window) OVERRIDE; + virtual void DeactivateWindow(Window* window) OVERRIDE; + virtual aura::Window* GetActiveWindow() OVERRIDE; + virtual bool OnWillFocusWindow(Window* window, const Event* event) OVERRIDE; + virtual bool CanActivateWindow(Window* window) const OVERRIDE; + + // RootWindowObserver: + virtual void OnWindowFocused(aura::Window* window) OVERRIDE; + + protected: + // Walks up the chain to find the correct parent window to activate when we + // try to activate |window|. + aura::Window* GetActivatableWindow(aura::Window* window); + + // The root window that we handle. + RootWindow* root_window_; + + // The current active window. + Window* current_active_; + + // True inside ActivateWindow(). Used to prevent recursion of focus + // change notifications causing activation. + bool updating_activation_; + + DISALLOW_COPY_AND_ASSIGN(DesktopActivationClient); +}; + +} // namespace aura + +#endif // UI_AURA_DESKTOP_DESTKOP_ACTIVATION_CLIENT_H_ diff --git a/ui/aura/desktop/desktop_dispatcher_client.cc b/ui/aura/desktop/desktop_dispatcher_client.cc new file mode 100644 index 0000000..d9a33cf --- /dev/null +++ b/ui/aura/desktop/desktop_dispatcher_client.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2012 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/aura/desktop/desktop_dispatcher_client.h" + +namespace aura { + +DesktopDispatcherClient::DesktopDispatcherClient() {} + +DesktopDispatcherClient::~DesktopDispatcherClient() {} + +void DesktopDispatcherClient::RunWithDispatcher( + MessageLoop::Dispatcher* nested_dispatcher, + aura::Window* associated_window, + bool nestable_tasks_allowed) { + // TODO(erg): This class has been copypastad from + // ash/accelerators/nested_dispatcher_controller.cc. I have left my changes + // commented out because I don't entirely understand the implications of the + // change. + MessageLoopForUI* loop = MessageLoopForUI::current(); + bool did_allow_task_nesting = loop->NestableTasksAllowed(); + loop->SetNestableTasksAllowed(nestable_tasks_allowed); + + // DefaultAcceleratorDispatcher dispatcher(nested_dispatcher, + // associated_window); + loop->RunWithDispatcher(nested_dispatcher); + loop->SetNestableTasksAllowed(did_allow_task_nesting); +} + +} // namespace aura + diff --git a/ui/aura/desktop/desktop_dispatcher_client.h b/ui/aura/desktop/desktop_dispatcher_client.h new file mode 100644 index 0000000..3d7f1dd --- /dev/null +++ b/ui/aura/desktop/desktop_dispatcher_client.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012 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_AURA_DESKTOP_DESKTOP_DISPATCHER_CLIENT_H_ +#define UI_AURA_DESKTOP_DESKTOP_DISPATCHER_CLIENT_H_ +#pragma once + +#include "base/basictypes.h" +#include "ui/aura/client/dispatcher_client.h" + +namespace aura { + +// TODO(erg): I won't lie to you; I have no idea what this is or what it does. +class AURA_EXPORT DesktopDispatcherClient : public client::DispatcherClient { + public: + DesktopDispatcherClient(); + virtual ~DesktopDispatcherClient(); + + virtual void RunWithDispatcher(MessageLoop::Dispatcher* dispatcher, + aura::Window* associated_window, + bool nestable_tasks_allowed) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(DesktopDispatcherClient); +}; + +} // namespace aura + +#endif // UI_AURA_DESKTOP_DESKTOP_DISPATCHER_CLIENT_H_ diff --git a/ui/aura/desktop/desktop_root_window_event_filter.cc b/ui/aura/desktop/desktop_root_window_event_filter.cc new file mode 100644 index 0000000..a1d4bf6 --- /dev/null +++ b/ui/aura/desktop/desktop_root_window_event_filter.cc @@ -0,0 +1,109 @@ +// Copyright (c) 2012 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/aura/desktop/desktop_root_window_event_filter.h" + +#include "ui/aura/client/activation_client.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/event.h" +#include "ui/aura/focus_manager.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/base/ime/input_method.h" +#include "ui/base/ime/input_method_factory.h" + +namespace aura { + +namespace { + +aura::Window* FindFocusableWindowFor(aura::Window* window) { + while (window && !window->CanFocus()) + window = window->parent(); + return window; +} + +} // namespace + +DesktopRootWindowEventFilter::DesktopRootWindowEventFilter( + RootWindow* root_window) + : root_window_(root_window), + ALLOW_THIS_IN_INITIALIZER_LIST( + input_method_(ui::CreateInputMethod(this))) { + // TODO(yusukes): Check if the root window is currently focused and pass the + // result to Init(). + input_method_->Init(true); + root_window_->SetProperty( + aura::client::kRootWindowInputMethodKey, + input_method_.get()); +} + +DesktopRootWindowEventFilter::~DesktopRootWindowEventFilter() {} + +bool DesktopRootWindowEventFilter::PreHandleKeyEvent(Window* target, + KeyEvent* event) { + const ui::EventType type = event->type(); + if (type == ui::ET_TRANSLATED_KEY_PRESS || + type == ui::ET_TRANSLATED_KEY_RELEASE) { + // TODO(erg): what is this? + // The |event| is already handled by this object, change the type of the + // event to ui::ET_KEY_* and pass it to the next filter. + static_cast<TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); + return false; + } else { + input_method_->DispatchKeyEvent(event->native_event()); + return true; + } +} + +bool DesktopRootWindowEventFilter::PreHandleMouseEvent( + Window* target, + MouseEvent* event) { + if (event->type() == ui::ET_MOUSE_PRESSED) { + // Get the active window? + Window* active = aura::client::GetActivationClient( + root_window_)->GetActiveWindow(); + + if (active != target) { + target->GetFocusManager()->SetFocusedWindow( + FindFocusableWindowFor(target), event); + } + } + + return false; +} + +ui::TouchStatus DesktopRootWindowEventFilter::PreHandleTouchEvent( + Window* target, + TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +ui::GestureStatus DesktopRootWindowEventFilter::PreHandleGestureEvent( + Window* target, + GestureEvent* event) { + return ui::GESTURE_STATUS_UNKNOWN; +} + +//////////////////////////////////////////////////////////////////////////////// +// DesktopInputMehtodEventFilter, ui::InputMethodDelegate implementation: + +void DesktopRootWindowEventFilter::DispatchKeyEventPostIME( + const base::NativeEvent& event) { +#if defined(OS_WIN) + DCHECK(event.message != WM_CHAR); +#endif + TranslatedKeyEvent aura_event(event, false /* is_char */); + root_window_->DispatchKeyEvent(&aura_event); +} + +void DesktopRootWindowEventFilter::DispatchFabricatedKeyEventPostIME( + ui::EventType type, + ui::KeyboardCode key_code, + int flags) { + TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code, flags); + root_window_->DispatchKeyEvent(&aura_event); +} + +} // namespace aura + diff --git a/ui/aura/desktop/desktop_root_window_event_filter.h b/ui/aura/desktop/desktop_root_window_event_filter.h new file mode 100644 index 0000000..8c552b2 --- /dev/null +++ b/ui/aura/desktop/desktop_root_window_event_filter.h @@ -0,0 +1,63 @@ +// Copyright (c) 2012 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_AURA_DESKTOP_DESTKOP_ROOT_WINDOW_EVENT_FILTER_H_ +#define UI_AURA_DESKTOP_DESTKOP_ROOT_WINDOW_EVENT_FILTER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/aura_export.h" +#include "ui/aura/event_filter.h" +#include "ui/base/ime/input_method_delegate.h" + +namespace ui { +class InputMethod; +} + +namespace aura { +class KeyEvent; +class GestureEvent; +class MouseEvent; +class RootWindow; +class TouchEvent; +class Window; + +// An aura::EventFilter that takes care of events just for the desktop. It is a +// mix of the ash::internal::RootWindowEventFilter and +// ash::internal::InputMethodEventFilter. +class AURA_EXPORT DesktopRootWindowEventFilter + : public aura::EventFilter, + public ui::internal::InputMethodDelegate { + public: + DesktopRootWindowEventFilter(aura::RootWindow* root_window); + virtual ~DesktopRootWindowEventFilter(); + + // EventFilter: + virtual bool PreHandleKeyEvent(Window* target, + KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(Window* target, + MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(Window* target, + TouchEvent* event) OVERRIDE; + virtual ui::GestureStatus PreHandleGestureEvent( + Window* target, + GestureEvent* event) OVERRIDE; + + private: + // Overridden from ui::internal::InputMethodDelegate. + virtual void DispatchKeyEventPostIME(const base::NativeEvent& event) OVERRIDE; + virtual void DispatchFabricatedKeyEventPostIME(ui::EventType type, + ui::KeyboardCode key_code, + int flags) OVERRIDE; + + RootWindow* root_window_; + + scoped_ptr<ui::InputMethod> input_method_; +}; + +} // namespace aura + +#endif // UI_AURA_DESKTOP_DESTKOP_ROOT_WINDOW_EVENT_FILTER_H_ diff --git a/ui/aura/event.cc b/ui/aura/event.cc index e05db5c..b8b2879 100644 --- a/ui/aura/event.cc +++ b/ui/aura/event.cc @@ -366,6 +366,27 @@ KeyEvent* KeyEvent::Copy() { return copy; } +TranslatedKeyEvent::TranslatedKeyEvent(const base::NativeEvent& native_event, + bool is_char) + : KeyEvent(native_event, is_char) { + set_type(type() == ui::ET_KEY_PRESSED ? + ui::ET_TRANSLATED_KEY_PRESS : ui::ET_TRANSLATED_KEY_RELEASE); +} + +TranslatedKeyEvent::TranslatedKeyEvent(bool is_press, + ui::KeyboardCode key_code, + int flags) + : KeyEvent((is_press ? + ui::ET_TRANSLATED_KEY_PRESS : ui::ET_TRANSLATED_KEY_RELEASE), + key_code, + flags) { +} + +void TranslatedKeyEvent::ConvertToKeyEvent() { + set_type(type() == ui::ET_TRANSLATED_KEY_PRESS ? + ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED); +} + ScrollEvent::ScrollEvent(const base::NativeEvent& native_event) : MouseEvent(native_event) { if (type() == ui::ET_SCROLL) { diff --git a/ui/aura/event.h b/ui/aura/event.h index f5e6f71..daa01eb 100644 --- a/ui/aura/event.h +++ b/ui/aura/event.h @@ -260,6 +260,26 @@ class AURA_EXPORT KeyEvent : public Event { uint16 unmodified_character_; }; +// A key event which is translated by an input method (IME). +// For example, if an IME receives a KeyEvent(ui::VKEY_SPACE), and it does not +// consume the key, the IME usually generates and dispatches a +// TranslatedKeyEvent(ui::VKEY_SPACE) event. If the IME receives a KeyEvent and +// it does consume the event, it might dispatch a +// TranslatedKeyEvent(ui::VKEY_PROCESSKEY) event as defined in the DOM spec. +class AURA_EXPORT TranslatedKeyEvent : public aura::KeyEvent { + public: + TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char); + + // Used for synthetic events such as a VKEY_PROCESSKEY key event. + TranslatedKeyEvent(bool is_press, + ui::KeyboardCode key_code, + int flags); + + // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so + // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event. + void ConvertToKeyEvent(); +}; + class AURA_EXPORT DropTargetEvent : public LocatedEvent { public: DropTargetEvent(const ui::OSExchangeData& data, diff --git a/ui/gfx/screen_ash.cc b/ui/gfx/screen_ash.cc index 9df6b84..091c2b0 100644 --- a/ui/gfx/screen_ash.cc +++ b/ui/gfx/screen_ash.cc @@ -23,56 +23,81 @@ void Screen::SetInstance(Screen* screen) { // static gfx::Point Screen::GetCursorScreenPoint() { + // TODO(erg): Figure out what to do about the Screen class. For now, I've + // added default values for when a Screen instance class isn't passed in, but + // this is the wrong thing. + if (!instance_) + return gfx::Point(); return instance_->GetCursorScreenPointImpl(); } // static gfx::Rect Screen::GetMonitorWorkAreaNearestWindow(gfx::NativeWindow window) { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorWorkAreaNearestWindowImpl(window); } // static gfx::Rect Screen::GetMonitorAreaNearestWindow(gfx::NativeWindow window) { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorAreaNearestWindowImpl(window); } // static gfx::Rect Screen::GetMonitorWorkAreaNearestPoint(const gfx::Point& point) { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorWorkAreaNearestPointImpl(point); } // static gfx::Rect Screen::GetMonitorAreaNearestPoint(const gfx::Point& point) { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorAreaNearestPointImpl(point); } // static gfx::Rect Screen::GetPrimaryMonitorWorkArea() { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorWorkAreaNearestPoint(gfx::Point()); } // static gfx::Rect Screen::GetPrimaryMonitorBounds() { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorAreaNearestPoint(gfx::Point()); } // static gfx::Rect Screen::GetMonitorWorkAreaMatching(const gfx::Rect& match_rect) { + if (!instance_) + return gfx::Rect(0, 0, 800, 800); return instance_->GetMonitorWorkAreaNearestPoint(gfx::Point()); } // static gfx::NativeWindow Screen::GetWindowAtCursorScreenPoint() { + if (!instance_) + return NULL; return instance_->GetWindowAtCursorScreenPointImpl(); } // static gfx::Size Screen::GetPrimaryMonitorSize() { + if (!instance_) + return gfx::Size(800, 800); return instance_->GetPrimaryMonitorSizeImpl(); } // static int Screen::GetNumMonitors() { + if (!instance_) + return 1; return instance_->GetNumMonitorsImpl(); } diff --git a/ui/views/examples/examples_main.cc b/ui/views/examples/examples_main.cc index f27a3e8..cd48f6b 100644 --- a/ui/views/examples/examples_main.cc +++ b/ui/views/examples/examples_main.cc @@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/i18n/icu_util.h" #include "base/logging.h" +#include "base/message_loop.h" #include "base/process_util.h" #include "base/stl_util.h" #include "base/utf_string_conversions.h" @@ -20,6 +21,37 @@ #include "ui/base/win/scoped_ole_initializer.h" #endif +#if defined(USE_AURA) +#include "ui/aura/client/stacking_client.h" +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/aura/root_window.h" +#include "ui/gfx/compositor/compositor.h" +#include "ui/gfx/compositor/test/compositor_test_support.h" +#include "ui/views/widget/native_widget_aura.h" +#endif + +#if defined(USE_AURA) +class RootWindowStackingClient : public aura::client::StackingClient { + public: + explicit RootWindowStackingClient() { + aura::client::SetStackingClient(this); + } + + virtual ~RootWindowStackingClient() { + aura::client::SetStackingClient(NULL); + } + + // Overridden from aura::client::StackingClient: + virtual aura::Window* GetDefaultParent(aura::Window* window) OVERRIDE { + return window->GetRootWindow(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(RootWindowStackingClient); +}; +#endif + int main(int argc, char** argv) { #if defined(OS_WIN) ui::ScopedOleInitializer ole_initializer; @@ -43,13 +75,34 @@ int main(int argc, char** argv) { ui::ResourceBundle::InitSharedInstanceWithLocale("en-US"); MessageLoop main_message_loop(MessageLoop::TYPE_UI); +#if defined(USE_AURA) + + // TURN ON THE HAX. + views::NativeWidgetAura::set_aura_desktop_hax(); + + ui::CompositorTestSupport::Initialize(); + + { + RootWindowStackingClient root_window_stacking_client; +#endif views::TestViewsDelegate delegate; views::examples::ShowExamplesWindow(true); + // xxx: Hax here because this kills event handling. +#if !defined(USE_AURA) views::AcceleratorHandler accelerator_handler; MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler); +#else + MessageLoopForUI::current()->Run(); +#endif + +#if defined(USE_AURA) + } + aura::Env::DeleteInstance(); + ui::CompositorTestSupport::Terminate(); +#endif return 0; } diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 64db0ec..ca86f19 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -650,6 +650,12 @@ }, }, }], + ['use_aura==1', { + 'dependencies': [ + '../gfx/compositor/compositor.gyp:compositor', + '../gfx/compositor/compositor.gyp:compositor_test_support', + ], + }], ], }, # target_name: views_examples_lib ], diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 44f1926..19292d5 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -9,9 +9,13 @@ #include "third_party/skia/include/core/SkRegion.h" #include "ui/aura/client/activation_client.h" #include "ui/aura/client/aura_constants.h" +#include "ui/aura/client/dispatcher_client.h" #include "ui/aura/client/drag_drop_client.h" #include "ui/aura/client/window_move_client.h" #include "ui/aura/client/window_types.h" +#include "ui/aura/desktop/desktop_activation_client.h" +#include "ui/aura/desktop/desktop_dispatcher_client.h" +#include "ui/aura/desktop/desktop_root_window_event_filter.h" #include "ui/aura/env.h" #include "ui/aura/event.h" #include "ui/aura/root_window.h" @@ -38,6 +42,8 @@ namespace views { +bool NativeWidgetAura::g_aura_desktop_hax = false; + namespace { aura::client::WindowType GetAuraWindowTypeForWidgetType( @@ -127,6 +133,7 @@ class NativeWidgetAura::ActiveWindowObserver : public aura::WindowObserver { NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate) : delegate_(delegate), + root_window_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(window_(new aura::Window(this))), ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), @@ -160,6 +167,25 @@ gfx::Font NativeWidgetAura::GetWindowTitleFont() { void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { ownership_ = params.ownership; + // TODO(erg): What kind of windows do we want to have their own root windows? + if (g_aura_desktop_hax) { + gfx::Rect bounds = params.bounds; + if (bounds.IsEmpty()) { + // We must pass some non-zero value when we initialize a RootWindow. This + // will probably be SetBounds()ed soon. + bounds.set_size(gfx::Size(100, 100)); + } + root_window_.reset(new aura::RootWindow(bounds)); + root_window_->SetEventFilter( + new aura::DesktopRootWindowEventFilter(root_window_.get())); + + aura::client::SetActivationClient( + root_window_.get(), + new aura::DesktopActivationClient(root_window_.get())); + aura::client::SetDispatcherClient(root_window_.get(), + new aura::DesktopDispatcherClient); + } + window_->set_user_data(this); window_->SetType(GetAuraWindowTypeForWidgetType(params.type)); window_->SetProperty(aura::client::kShowStateKey, params.show_state); @@ -171,7 +197,9 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { window_->Show(); delegate_->OnNativeWidgetCreated(); - if (params.child) { + if (root_window_.get()) { + window_->SetParent(root_window_.get()); + } else if (params.child) { window_->SetParent(params.GetParent()); } else { // Set up the transient child before the window is added. This way the @@ -179,19 +207,29 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { gfx::NativeView parent = params.GetParent(); if (parent && parent->type() != aura::client::WINDOW_TYPE_UNKNOWN) { parent->AddTransientChild(window_); - parent = NULL; + + // TODO(erg): The StackingClient interface implies that there is only a + // single root window. Solving this would require setting a stacking + // client per root window instead. For now, we hax our way around this by + // forcing the parent to be the root window instead of passing NULL as + // the parent which will dispatch to the stacking client. + if (g_aura_desktop_hax) + parent = parent->GetRootWindow(); + else + parent = NULL; } // SetAlwaysOnTop before SetParent so that always-on-top container is used. SetAlwaysOnTop(params.keep_on_top); window_->SetParent(parent); } + // Wait to set the bounds until we have a parent. That way we can know our // true state/bounds (the LayoutManager may enforce a particular // state/bounds). if (IsMaximized()) SetRestoreBounds(window_, params.bounds); else - window_->SetBounds(params.bounds); + SetBounds(params.bounds); window_->set_ignore_events(!params.accept_events); can_activate_ = params.can_activate; DCHECK(GetWidget()->GetRootView()); @@ -207,6 +245,9 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) { } aura::client::SetActivationDelegate(window_, this); + + if (root_window_.get()) + root_window_->ShowRootWindow(); } NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() { @@ -407,7 +448,15 @@ gfx::Rect NativeWidgetAura::GetRestoredBounds() const { return restore_bounds ? *restore_bounds : window_->bounds(); } -void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) { +void NativeWidgetAura::SetBounds(const gfx::Rect& in_bounds) { + gfx::Rect bounds = in_bounds; + + if (root_window_.get() && !bounds.IsEmpty()) { + root_window_->SetHostBounds(bounds); + bounds.set_x(0); + bounds.set_y(0); + } + window_->SetBounds(bounds); } diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h index 8ba42f3..2621918 100644 --- a/ui/views/widget/native_widget_aura.h +++ b/ui/views/widget/native_widget_aura.h @@ -16,6 +16,7 @@ #include "ui/views/widget/native_widget_private.h" namespace aura { +class RootWindow; class Window; } namespace gfx { @@ -35,6 +36,8 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate); virtual ~NativeWidgetAura(); + static void set_aura_desktop_hax() { g_aura_desktop_hax = true; } + // TODO(beng): Find a better place for this, and the similar method on // NativeWidgetWin. static gfx::Font GetWindowTitleFont(); @@ -167,6 +170,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, internal::NativeWidgetDelegate* delegate_; + scoped_ptr<aura::RootWindow> root_window_; aura::Window* window_; // See class documentation for Widget in widget.h for a note about ownership. @@ -191,6 +195,8 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, scoped_ptr<DropHelper> drop_helper_; int last_drop_operation_; + static bool g_aura_desktop_hax; + DISALLOW_COPY_AND_ASSIGN(NativeWidgetAura); }; |