diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-30 23:14:03 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-30 23:14:03 +0000 |
commit | de4ec531ed531ea578a783f7da16f67ce0f6d658 (patch) | |
tree | 4ec6d291f8da0240e153e4ce126d625d5fe89c5d /ui/aura | |
parent | 6a73c3006dde579493a5b070fe9bd3008608d5b1 (diff) | |
download | chromium_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/aura')
-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 |
9 files changed, 438 insertions, 0 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, |