diff options
-rw-r--r-- | ash/accelerators/accelerator_dispatcher.cc | 15 | ||||
-rw-r--r-- | ash/accelerators/accelerator_dispatcher.h | 37 | ||||
-rw-r--r-- | ash/accelerators/accelerator_dispatcher_linux.cc | 46 | ||||
-rw-r--r-- | ash/accelerators/accelerator_dispatcher_win.cc | 39 | ||||
-rw-r--r-- | ash/accelerators/nested_dispatcher_controller.cc | 31 | ||||
-rw-r--r-- | ash/accelerators/nested_dispatcher_controller.h | 34 | ||||
-rw-r--r-- | ash/ash.gyp | 6 | ||||
-rw-r--r-- | ash/shell.cc | 2 | ||||
-rw-r--r-- | ash/shell.h | 3 | ||||
-rw-r--r-- | ui/aura/aura.gyp | 2 | ||||
-rw-r--r-- | ui/aura/client/dispatcher_client.cc | 31 | ||||
-rw-r--r-- | ui/aura/client/dispatcher_client.h | 29 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_controller.cc | 5 |
13 files changed, 280 insertions, 0 deletions
diff --git a/ash/accelerators/accelerator_dispatcher.cc b/ash/accelerators/accelerator_dispatcher.cc new file mode 100644 index 0000000..46d7bec --- /dev/null +++ b/ash/accelerators/accelerator_dispatcher.cc @@ -0,0 +1,15 @@ +// 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 "ash/accelerators/accelerator_dispatcher.h" + +namespace ash { + +AcceleratorDispatcher::AcceleratorDispatcher( + MessageLoop::Dispatcher* nested_dispatcher) + : nested_dispatcher_(nested_dispatcher) { + DCHECK(nested_dispatcher_); +} + +} // namespace ash diff --git a/ash/accelerators/accelerator_dispatcher.h b/ash/accelerators/accelerator_dispatcher.h new file mode 100644 index 0000000..9de596c --- /dev/null +++ b/ash/accelerators/accelerator_dispatcher.h @@ -0,0 +1,37 @@ +// 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 ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_ +#define ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_ +#pragma once + +#include "ash/ash_export.h" +#include "base/message_loop.h" + +namespace ash { + +// Dispatcher for handling accelerators in ash. +// Wraps a nested dispatcher to which control is passed if no accelerator key +// has been pressed. +// TODO(pkotwicz): Port AcceleratorDispatcher to mac. +class ASH_EXPORT AcceleratorDispatcher : public MessageLoop::Dispatcher { + public: + explicit AcceleratorDispatcher(MessageLoop::Dispatcher* nested_dispatcher); + +#if defined(USE_X11) + virtual base::MessagePumpDispatcher::DispatchStatus Dispatch( + XEvent* xev) OVERRIDE; +#elif defined(OS_WIN) + bool AcceleratorDispatcher::Dispatch(const MSG& msg) OVERRIDE; +#endif + + private: + MessageLoop::Dispatcher* nested_dispatcher_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratorDispatcher); +}; + +} // namespace ash + +#endif // ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_ diff --git a/ash/accelerators/accelerator_dispatcher_linux.cc b/ash/accelerators/accelerator_dispatcher_linux.cc new file mode 100644 index 0000000..82b98aa --- /dev/null +++ b/ash/accelerators/accelerator_dispatcher_linux.cc @@ -0,0 +1,46 @@ +// 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 "ash/accelerators/accelerator_dispatcher.h" + +#include <X11/Xlib.h> + +// Xlib defines RootWindow +#ifdef RootWindow +#undef RootWindow +#endif + +#include "ash/accelerators/accelerator_controller.h" +#include "ash/shell.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/base/accelerators/accelerator.h" + +namespace ash { + +namespace { + +const int kModifierMask = (ui::EF_SHIFT_DOWN | + ui::EF_CONTROL_DOWN | + ui::EF_ALT_DOWN); +} // namespace + +base::MessagePumpDispatcher::DispatchStatus AcceleratorDispatcher::Dispatch( + XEvent* xev) { + ash::Shell* shell = ash::Shell::GetInstance(); + if (shell->IsScreenLocked()) + return aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(xev); + + if (xev->type == KeyPress) { + ash::AcceleratorController* accelerator_controller = + shell->accelerator_controller(); + ui::Accelerator accelerator(ui::KeyboardCodeFromNative(xev), + ui::EventFlagsFromNative(xev) & kModifierMask); + if (accelerator_controller && accelerator_controller->Process(accelerator)) + return EVENT_PROCESSED; + } + return nested_dispatcher_->Dispatch(xev); +} + +} // namespace ash diff --git a/ash/accelerators/accelerator_dispatcher_win.cc b/ash/accelerators/accelerator_dispatcher_win.cc new file mode 100644 index 0000000..4682275 --- /dev/null +++ b/ash/accelerators/accelerator_dispatcher_win.cc @@ -0,0 +1,39 @@ +// 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 "ash/accelerators/accelerator_dispatcher.h" + +#include "ash/accelerators/accelerator_controller.h" +#include "ash/shell.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/base/accelerators/accelerator.h" + +namespace ash { + +namespace { + +const int kModifierMask = (ui::EF_SHIFT_DOWN | + ui::EF_CONTROL_DOWN | + ui::EF_ALT_DOWN); +} // namespace + +bool AcceleratorDispatcher::Dispatch(const MSG& msg) { + ash::Shell* shell = ash::Shell::GetInstance(); + if (shell->IsScreenLocked()) + return aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch(msg); + + if(msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) { + ash::AcceleratorController* accelerator_controller = + shell->accelerator_controller(); + ui::Accelerator accelerator(ui::KeyboardCodeFromNative(msg), + ui::EventFlagsFromNative(msg) & kModifierMask); + if (accelerator_controller && accelerator_controller->Process(accelerator)) + return true; + } + + return nested_dispatcher_->Dispatch(msg); +} + +} // namespace ash diff --git a/ash/accelerators/nested_dispatcher_controller.cc b/ash/accelerators/nested_dispatcher_controller.cc new file mode 100644 index 0000000..758b63d --- /dev/null +++ b/ash/accelerators/nested_dispatcher_controller.cc @@ -0,0 +1,31 @@ +// 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 "ash/accelerators/nested_dispatcher_controller.h" + +#include "ash/accelerators/accelerator_dispatcher.h" + +namespace ash { + +NestedDispatcherController::NestedDispatcherController() { + aura::client::SetDispatcherClient(this); +} + +NestedDispatcherController::~NestedDispatcherController() { +} + +void NestedDispatcherController::RunWithDispatcher( + MessageLoop::Dispatcher* nested_dispatcher, + bool nestable_tasks_allowed) { + MessageLoopForUI* loop = MessageLoopForUI::current(); + bool did_allow_task_nesting = loop->NestableTasksAllowed(); + loop->SetNestableTasksAllowed(nestable_tasks_allowed); + + AcceleratorDispatcher dispatcher(nested_dispatcher); + + loop->RunWithDispatcher(&dispatcher); + loop->SetNestableTasksAllowed(did_allow_task_nesting); +} + +} // namespace ash diff --git a/ash/accelerators/nested_dispatcher_controller.h b/ash/accelerators/nested_dispatcher_controller.h new file mode 100644 index 0000000..33acfd0 --- /dev/null +++ b/ash/accelerators/nested_dispatcher_controller.h @@ -0,0 +1,34 @@ +// 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 ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_ +#define ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_ +#pragma once + +#include "ash/ash_export.h" +#include "base/message_loop.h" +#include "ui/aura/client/dispatcher_client.h" + +namespace ash { + +// Creates a dispatcher which wraps another dispatcher. +// The outer dispatcher runs first and performs ash specific handling. +// If it does not consume the event it forwards the event to the nested +// dispatcher. +class ASH_EXPORT NestedDispatcherController + : public aura::client::DispatcherClient { + public: + NestedDispatcherController(); + virtual ~NestedDispatcherController(); + + virtual void RunWithDispatcher(MessageLoop::Dispatcher* dispatcher, + bool nestable_tasks_allowed) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(NestedDispatcherController); +}; + +} // namespace ash + +#endif // ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_ diff --git a/ash/ash.gyp b/ash/ash.gyp index 88f6c06..4af5092 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -36,8 +36,14 @@ # All .cc, .h under ash, except unittests 'accelerators/accelerator_controller.cc', 'accelerators/accelerator_controller.h', + 'accelerators/accelerator_dispatcher.cc', + 'accelerators/accelerator_dispatcher.h', + 'accelerators/accelerator_dispatcher_linux.cc', + 'accelerators/accelerator_dispatcher_win.cc', 'accelerators/accelerator_filter.cc', 'accelerators/accelerator_filter.h', + 'accelerators/nested_dispatcher_controller.cc', + 'accelerators/nested_dispatcher_controller.h', 'app_list/app_list.cc', 'app_list/app_list.h', 'app_list/app_list_groups_view.cc', diff --git a/ash/shell.cc b/ash/shell.cc index f47938c..5bfd3d4 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -8,6 +8,7 @@ #include "ash/accelerators/accelerator_controller.h" #include "ash/accelerators/accelerator_filter.h" +#include "ash/accelerators/nested_dispatcher_controller.h" #include "ash/app_list/app_list.h" #include "ash/ash_switches.h" #include "ash/drag_drop/drag_drop_controller.h" @@ -205,6 +206,7 @@ Shell* Shell::instance_ = NULL; Shell::Shell(ShellDelegate* delegate) : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + nested_dispatcher_controller_(new NestedDispatcherController), accelerator_controller_(new AcceleratorController), delegate_(delegate), window_mode_(MODE_OVERLAPPING), diff --git a/ash/shell.h b/ash/shell.h index 374015d..9e48aa2 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -37,6 +37,7 @@ namespace ash { class AcceleratorController; class Launcher; +class NestedDispatcherController; class PowerButtonController; class ShellDelegate; class VideoDetector; @@ -183,6 +184,8 @@ class ASH_EXPORT Shell { base::WeakPtrFactory<Shell> method_factory_; + scoped_ptr<NestedDispatcherController> nested_dispatcher_controller_; + scoped_ptr<AcceleratorController> accelerator_controller_; scoped_ptr<ShellDelegate> delegate_; diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index c84a74e..8c4bc99 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -32,6 +32,8 @@ 'client/activation_delegate.h', 'client/aura_constants.cc', 'client/aura_constants.h', + 'client/dispatcher_client.cc', + 'client/dispatcher_client.h', 'client/drag_drop_client.cc', 'client/drag_drop_client.h', 'client/drag_drop_delegate.cc', diff --git a/ui/aura/client/dispatcher_client.cc b/ui/aura/client/dispatcher_client.cc new file mode 100644 index 0000000..f9cd3ac --- /dev/null +++ b/ui/aura/client/dispatcher_client.cc @@ -0,0 +1,31 @@ +// 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/client/dispatcher_client.h" + +#include "ui/aura/root_window.h" + +namespace aura { + +namespace client { + +namespace { + +// A property key to store the nested dispatcher controller. The type of the +// value is |aura::client::DispatcherClient*|. +const char kDispatcherClient[] = "AuraDispatcherClient"; + +} // namespace + +void SetDispatcherClient(DispatcherClient* client) { + RootWindow::GetInstance()->SetProperty(kDispatcherClient, client); +} + +DispatcherClient* GetDispatcherClient() { + return reinterpret_cast<DispatcherClient*>( + RootWindow::GetInstance()->GetProperty(kDispatcherClient)); +} + +} // namespace client +} // namespace aura diff --git a/ui/aura/client/dispatcher_client.h b/ui/aura/client/dispatcher_client.h new file mode 100644 index 0000000..099e370 --- /dev/null +++ b/ui/aura/client/dispatcher_client.h @@ -0,0 +1,29 @@ +// 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_CLIENT_DISPATCHER_CLIENT_H_ +#define UI_AURA_CLIENT_DISPATCHER_CLIENT_H_ +#pragma once + +#include "ui/aura/aura_export.h" +#include "base/message_loop.h" + +namespace aura { + +namespace client { + +// An interface implemented by an object which handles nested dispatchers. +class AURA_EXPORT DispatcherClient { + public: + virtual void RunWithDispatcher(MessageLoop::Dispatcher* dispatcher, + bool nestable_tasks_allowed) = 0; +}; + +AURA_EXPORT void SetDispatcherClient(DispatcherClient* client); +AURA_EXPORT DispatcherClient* GetDispatcherClient(); + +} // namespace client +} // namespace aura + +#endif // UI_AURA_CLIENT_DISPATCHER_CLIENT_H_ diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 87199dc9..0f16a60 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc @@ -25,6 +25,7 @@ #include "ui/views/widget/widget.h" #if defined(USE_AURA) +#include "ui/aura/client/dispatcher_client.h" #include "ui/aura/root_window.h" #elif defined(TOOLKIT_USES_GTK) #include "ui/base/keycodes/keyboard_code_conversion_gtk.h" @@ -318,11 +319,15 @@ MenuItemView* MenuController::Run(Widget* parent, // one) the menus are run from a task. If we don't do this and are invoked // from a task none of the tasks we schedule are processed and the menu // appears totally broken. +#if defined(USE_AURA) + aura::client::GetDispatcherClient()->RunWithDispatcher(this, true); +#else MessageLoopForUI* loop = MessageLoopForUI::current(); bool did_allow_task_nesting = loop->NestableTasksAllowed(); loop->SetNestableTasksAllowed(true); loop->RunWithDispatcher(this); loop->SetNestableTasksAllowed(did_allow_task_nesting); +#endif if (ViewsDelegate::views_delegate) ViewsDelegate::views_delegate->ReleaseRef(); |