summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 23:14:03 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-30 23:14:03 +0000
commitde4ec531ed531ea578a783f7da16f67ce0f6d658 (patch)
tree4ec6d291f8da0240e153e4ce126d625d5fe89c5d /ui
parent6a73c3006dde579493a5b070fe9bd3008608d5b1 (diff)
downloadchromium_src-de4ec531ed531ea578a783f7da16f67ce0f6d658.zip
chromium_src-de4ec531ed531ea578a783f7da16f67ce0f6d658.tar.gz
chromium_src-de4ec531ed531ea578a783f7da16f67ce0f6d658.tar.bz2
Ash/aura split: Get views_examples_exe semi-running on linux/X11.
This adds tons of hacks, most of which should be clearly labeled with TODOs. BUG=119759 TEST= Review URL: http://codereview.chromium.org/9873035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129990 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/aura.gyp6
-rw-r--r--ui/aura/desktop/desktop_activation_client.cc101
-rw-r--r--ui/aura/desktop/desktop_activation_client.h56
-rw-r--r--ui/aura/desktop/desktop_dispatcher_client.cc32
-rw-r--r--ui/aura/desktop/desktop_dispatcher_client.h30
-rw-r--r--ui/aura/desktop/desktop_root_window_event_filter.cc109
-rw-r--r--ui/aura/desktop/desktop_root_window_event_filter.h63
-rw-r--r--ui/aura/event.cc21
-rw-r--r--ui/aura/event.h20
-rw-r--r--ui/gfx/screen_ash.cc25
-rw-r--r--ui/views/examples/examples_main.cc53
-rw-r--r--ui/views/views.gyp6
-rw-r--r--ui/views/widget/native_widget_aura.cc57
-rw-r--r--ui/views/widget/native_widget_aura.h6
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);
};