summaryrefslogtreecommitdiffstats
path: root/ui/aura
diff options
context:
space:
mode:
Diffstat (limited to 'ui/aura')
-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
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,