diff options
Diffstat (limited to 'views')
-rw-r--r-- | views/event.h | 2 | ||||
-rw-r--r-- | views/event_gtk.cc | 8 | ||||
-rw-r--r-- | views/focus/accelerator_handler.h | 40 | ||||
-rw-r--r-- | views/focus/accelerator_handler_gtk.cc | 61 | ||||
-rw-r--r-- | views/focus/accelerator_handler_win.cc (renamed from views/widget/accelerator_handler.cc) | 17 | ||||
-rw-r--r-- | views/focus/focus_manager.cc | 74 | ||||
-rw-r--r-- | views/focus/focus_manager.h | 14 | ||||
-rw-r--r-- | views/focus/focus_manager_unittest.cc | 185 | ||||
-rw-r--r-- | views/view.cc | 3 | ||||
-rw-r--r-- | views/view_unittest.cc | 4 | ||||
-rw-r--r-- | views/views.gyp | 8 | ||||
-rw-r--r-- | views/widget/accelerator_handler.h | 30 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 13 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 15 | ||||
-rw-r--r-- | views/window/dialog_client_view.cc | 32 |
15 files changed, 289 insertions, 217 deletions
diff --git a/views/event.h b/views/event.h index 70d0abc..843ed00 100644 --- a/views/event.h +++ b/views/event.h @@ -234,7 +234,7 @@ class KeyEvent : public Event { // Create a new key event KeyEvent(EventType type, int ch, int repeat_count, int message_flags); #elif defined(OS_LINUX) - explicit KeyEvent(GdkEventKey* event); + KeyEvent(GdkEventKey* event, bool make_upper_case); #endif int GetCharacter() const { diff --git a/views/event_gtk.cc b/views/event_gtk.cc index ed55628..d1b9d88 100644 --- a/views/event_gtk.cc +++ b/views/event_gtk.cc @@ -8,12 +8,16 @@ namespace views { -KeyEvent::KeyEvent(GdkEventKey* event) +// TODO(jcampan): the same physical key can send different keyvals (ex: a or A). +// In order for accelerators to work, we need to normalize that. The right +// solution should probably to get the key-code out of the keystate. +KeyEvent::KeyEvent(GdkEventKey* event, bool make_upper_case) : Event(event->type == GDK_KEY_PRESS ? Event::ET_KEY_PRESSED : Event::ET_KEY_RELEASED, GetFlagsFromGdkState(event->state)), // TODO(erg): All these values are iffy. - character_(event->keyval), + character_(make_upper_case ? gdk_keyval_to_upper (event->keyval) : + event->keyval), repeat_count_(0), message_flags_(0) { } diff --git a/views/focus/accelerator_handler.h b/views/focus/accelerator_handler.h new file mode 100644 index 0000000..618f541 --- /dev/null +++ b/views/focus/accelerator_handler.h @@ -0,0 +1,40 @@ +// Copyright (c) 2006-2008 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 VIEWS_FOCUS_ACCELERATOR_HANDLER_H_ +#define VIEWS_FOCUS_ACCELERATOR_HANDLER_H_ + +#if defined(OS_LINUX) +#include <gdk/gdk.h> +#endif + +#include "base/message_loop.h" + +namespace views { + +// This class delegates the key messages to the associated FocusManager class +// for the window that is receiving these messages for accelerator processing. +class AcceleratorHandler : public MessageLoopForUI::Dispatcher { + public: + AcceleratorHandler(); + // Dispatcher method. This returns true if an accelerator was processed by the + // focus manager +#if defined(OS_WIN) + virtual bool Dispatch(const MSG& msg); +#else + virtual bool Dispatch(GdkEvent* event); +#endif + + private: +#if defined(OS_LINUX) + // Last key pressed and consumed as an accelerator. + guint last_key_pressed_; +#endif + + DISALLOW_COPY_AND_ASSIGN(AcceleratorHandler); +}; + +} // namespace views + +#endif // VIEWS_FOCUS_ACCELERATOR_HANDLER_H_ diff --git a/views/focus/accelerator_handler_gtk.cc b/views/focus/accelerator_handler_gtk.cc new file mode 100644 index 0000000..938dfcc --- /dev/null +++ b/views/focus/accelerator_handler_gtk.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2009 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 <gtk/gtk.h> + +#include "views/focus/accelerator_handler.h" + +#include "views/focus/focus_manager.h" +#include "views/widget/widget_gtk.h" +#include "views/window/window_gtk.h" + +namespace views { + +AcceleratorHandler::AcceleratorHandler() : last_key_pressed_(0) { +} + +bool AcceleratorHandler::Dispatch(GdkEvent* event) { + if (event->type != GDK_KEY_PRESS && event->type != GDK_KEY_RELEASE) { + gtk_main_do_event(event); + return true; + } + + GdkEventKey* key_event = reinterpret_cast<GdkEventKey*>(event); + // Let's retrieve the focus manager for the GdkWindow. + GdkWindow* window = gdk_window_get_toplevel(key_event->window); + gpointer ptr; + gdk_window_get_user_data(window, &ptr); + DCHECK(ptr); // The top-level window is expected to always be associated + // with the top-level gtk widget. + WindowGtk* widget = + WidgetGtk::GetWindowForNative(reinterpret_cast<GtkWidget*>(ptr)); + FocusManager* focus_manager = widget->GetFocusManager(); + if (!focus_manager) { + NOTREACHED(); + return true; + } + + if (event->type == GDK_KEY_PRESS) { + KeyEvent view_key_event(key_event, true); + // FocusManager::OnKeyPressed and OnKeyReleased return false if this + // message has been consumed and should not be propagated further. + if (!focus_manager->OnKeyEvent(view_key_event)) { + last_key_pressed_ = key_event->keyval; + return true; + } + } + + // Key release, make sure to filter-out the key release for key press consumed + // as accelerators to avoid unpaired key release. + if (event->type == GDK_KEY_RELEASE && + key_event->keyval == last_key_pressed_) { + last_key_pressed_ = 0; + return true; + } + + gtk_main_do_event(event); + return true; +} + +} // namespace views diff --git a/views/widget/accelerator_handler.cc b/views/focus/accelerator_handler_win.cc index 7d1f991..eb8bfb9 100644 --- a/views/widget/accelerator_handler.cc +++ b/views/focus/accelerator_handler_win.cc @@ -1,9 +1,10 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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 "views/widget/accelerator_handler.h" +#include "views/focus/accelerator_handler.h" +#include "views/event.h" #include "views/focus/focus_manager.h" namespace views { @@ -18,14 +19,16 @@ bool AcceleratorHandler::Dispatch(const MSG& msg) { FocusManager* focus_manager = FocusManager::GetFocusManagerForNativeView(msg.hwnd); if (focus_manager) { - // FocusManager::OnKeyDown and OnKeyUp return false if this message has - // been consumed and should not be propagated further. switch (msg.message) { case WM_KEYDOWN: - case WM_SYSKEYDOWN: - process_message = focus_manager->OnKeyDown(msg.hwnd, msg.message, - msg.wParam, msg.lParam); + case WM_SYSKEYDOWN: { + KeyEvent event(Event::ET_KEY_PRESSED, + msg.wParam, + msg.lParam & 0xFFFF, + (msg.lParam & 0xFFFF0000) >> 16); + process_message = focus_manager->OnKeyEvent(event); break; + } } } } diff --git a/views/focus/focus_manager.cc b/views/focus/focus_manager.cc index 04f1f9b..1a0f7ae 100644 --- a/views/focus/focus_manager.cc +++ b/views/focus/focus_manager.cc @@ -12,6 +12,7 @@ #include <gtk/gtk.h> #endif +#include "base/keyboard_codes.h" #include "base/logging.h" #include "views/accelerator.h" #include "views/focus/view_storage.h" @@ -19,10 +20,6 @@ #include "views/widget/root_view.h" #include "views/widget/widget.h" -#if defined(OS_WIN) -#include "base/win_util.h" -#endif - namespace views { // FocusManager ----------------------------------------------------- @@ -41,49 +38,36 @@ FocusManager::~FocusManager() { DCHECK(focus_change_listeners_.empty()); } -#if defined(OS_WIN) -// Message handlers. -bool FocusManager::OnKeyDown(HWND window, UINT message, WPARAM wparam, - LPARAM lparam) { - DCHECK((message == WM_KEYDOWN) || (message == WM_SYSKEYDOWN)); - HWND hwnd = widget_->GetNativeView(); - - if (!IsWindowVisible(hwnd)) { - // We got a message for a hidden window. Because WidgetWin::Close hides the - // window, then destroys it, it it possible to get a message after we've - // hidden the window. If we allow the message to be dispatched chances are - // we'll crash in some weird place. By returning false we make sure the - // message isn't dispatched. - return false; - } - - int virtual_key_code = static_cast<int>(wparam); - int repeat_count = LOWORD(lparam); - int flags = HIWORD(lparam); - KeyEvent key_event(Event::ET_KEY_PRESSED, - virtual_key_code, repeat_count, flags); - +bool FocusManager::OnKeyEvent(const KeyEvent& event) { // If the focused view wants to process the key event as is, let it be. - if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(key_event)) + if (focused_view_ && focused_view_->SkipDefaultKeyEventProcessing(event)) return true; // Intercept Tab related messages for focus traversal. // Note that we don't do focus traversal if the root window is not part of the // active window hierarchy as this would mean we have no focused view and // would focus the first focusable view. +#if defined(OS_WIN) HWND top_window = widget_->GetNativeView(); HWND active_window = ::GetActiveWindow(); if ((active_window == top_window || ::IsChild(active_window, top_window)) && - IsTabTraversalKeyEvent(key_event)) { - AdvanceFocus(win_util::IsShiftPressed()); + IsTabTraversalKeyEvent(event)) { + AdvanceFocus(event.IsShiftDown()); return false; } +#else + if (IsTabTraversalKeyEvent(event)) { + AdvanceFocus(event.IsShiftDown()); + return false; + } +#endif // Intercept arrow key messages to switch between grouped views. + int key_code = event.GetCharacter(); if (focused_view_ && focused_view_->GetGroup() != -1 && - (virtual_key_code == VK_UP || virtual_key_code == VK_DOWN || - virtual_key_code == VK_LEFT || virtual_key_code == VK_RIGHT)) { - bool next = (virtual_key_code == VK_RIGHT || virtual_key_code == VK_DOWN); + (key_code == base::VKEY_UP || key_code == base::VKEY_DOWN || + key_code == base::VKEY_LEFT || key_code == base::VKEY_RIGHT)) { + bool next = (key_code == base::VKEY_RIGHT || key_code == base::VKEY_DOWN); std::vector<View*> views; focused_view_->GetParent()->GetViewsWithGroup(focused_view_->GetGroup(), &views); @@ -103,22 +87,19 @@ bool FocusManager::OnKeyDown(HWND window, UINT message, WPARAM wparam, } // Process keyboard accelerators. - // We process accelerators here as we have no way of knowing if a HWND has - // really processed a key event. If the key combination matches an - // accelerator, the accelerator is triggered, otherwise we forward the - // event to the HWND. - Accelerator accelerator(Accelerator(static_cast<int>(virtual_key_code), - win_util::IsShiftPressed(), - win_util::IsCtrlPressed(), - win_util::IsAltPressed())); + // If the key combination matches an accelerator, the accelerator is + // triggered, otherwise the key event is proceed as usual. + Accelerator accelerator(event.GetCharacter(), + event.IsShiftDown(), + event.IsControlDown(), + event.IsAltDown()); if (ProcessAccelerator(accelerator)) { // If a shortcut was activated for this keydown message, do not propagate - // the message further. + // the event further. return false; } return true; } -#endif void FocusManager::ValidateFocusedView() { if (focused_view_) { @@ -410,7 +391,6 @@ bool FocusManager::ProcessAccelerator(const Accelerator& accelerator) { return true; } } - return false; } @@ -424,12 +404,8 @@ AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator( // static bool FocusManager::IsTabTraversalKeyEvent(const KeyEvent& key_event) { -#if defined(OS_WIN) - return key_event.GetCharacter() == VK_TAB && !win_util::IsCtrlPressed(); -#else - NOTIMPLEMENTED(); - return false; -#endif + return key_event.GetCharacter() == base::VKEY_TAB && + !key_event.IsControlDown(); } void FocusManager::ViewRemoved(View* parent, View* removed) { diff --git a/views/focus/focus_manager.h b/views/focus/focus_manager.h index b1c87b6..3106f72 100644 --- a/views/focus/focus_manager.h +++ b/views/focus/focus_manager.h @@ -5,9 +5,6 @@ #ifndef VIEWS_FOCUS_FOCUS_MANAGER_H_ #define VIEWS_FOCUS_FOCUS_MANAGER_H_ -#if defined(OS_WIN) -#include <windows.h> -#endif #include <vector> #include <map> #include <list> @@ -140,13 +137,10 @@ class FocusManager { explicit FocusManager(Widget* widget); ~FocusManager(); -#if defined(OS_WIN) - // OnKeyDown covers WM_KEYDOWN and WM_SYSKEYDOWN. - bool OnKeyDown(HWND window, - UINT message, - WPARAM wparam, - LPARAM lparam); -#endif + // Processes the passed key event for accelerators and tab traversal. + // Returns false if the event has been consumed and should not be processed + // further. + bool OnKeyEvent(const KeyEvent& event); // Returns true is the specified is part of the hierarchy of the window // associated with this FocusManager. diff --git a/views/focus/focus_manager_unittest.cc b/views/focus/focus_manager_unittest.cc index 2ae52e1..fe5b8d0 100644 --- a/views/focus/focus_manager_unittest.cc +++ b/views/focus/focus_manager_unittest.cc @@ -10,6 +10,7 @@ #include "app/resource_bundle.h" #include "base/gfx/rect.h" +#include "base/keyboard_codes.h" #include "base/string_util.h" #include "third_party/skia/include/core/SkColor.h" #include "views/background.h" @@ -21,19 +22,28 @@ #include "views/controls/combobox/native_combobox_wrapper.h" #include "views/controls/label.h" #include "views/controls/link.h" +#if defined(OS_WIN) #include "views/controls/native_control.h" #include "views/controls/scroll_view.h" #include "views/controls/tabbed_pane/native_tabbed_pane_wrapper.h" #include "views/controls/tabbed_pane/tabbed_pane.h" #include "views/controls/textfield/textfield.h" -#include "views/widget/accelerator_handler.h" +#endif +#include "views/focus/accelerator_handler.h" #include "views/widget/root_view.h" -#include "views/widget/widget_win.h" +#include "views/window/window.h" #include "views/window/window_delegate.h" + +#if defined(OS_WIN) +#include "views/widget/widget_win.h" #include "views/window/window_win.h" +#else +#include "views/window/window_gtk.h" +#endif namespace views { +#if defined(OS_WIN) static const int kWindowWidth = 600; static const int kWindowHeight = 500; @@ -93,9 +103,95 @@ static const int kHelpLinkID = count++; // 45 static const int kThumbnailContainerID = count++; static const int kThumbnailStarID = count++; static const int kThumbnailSuperStarID = count++; +#endif + +class FocusManagerTest : public testing::Test, public WindowDelegate { + public: + FocusManagerTest() + : window_(NULL), + content_view_(NULL), + focus_change_listener_(NULL) { +#if defined(OS_WIN) + OleInitialize(NULL); +#endif + } + + ~FocusManagerTest() { +#if defined(OS_WIN) + OleUninitialize(); +#endif + } -class FocusManagerTest; + virtual void SetUp() { + window_ = Window::CreateChromeWindow(NULL, bounds(), this); + InitContentView(); + window_->Show(); + } + + virtual void TearDown() { + if (focus_change_listener_) + GetFocusManager()->RemoveFocusChangeListener(focus_change_listener_); + // window_->CloseNow(); + window_->Close(); + + // Flush the message loop to make Purify happy. + message_loop()->RunAllPending(); + } + + FocusManager* GetFocusManager() { +#if defined(OS_WIN) + return static_cast<WindowWin*>(window_)->GetFocusManager(); +#elif defined(OS_LINUX) + return static_cast<WindowGtk*>(window_)->GetFocusManager(); +#elif + NOTIMPLEMENTED(); +#endif + } + + // WindowDelegate Implementation. + virtual View* GetContentsView() { + if (!content_view_) + content_view_ = new View(); + return content_view_; + } + + virtual void InitContentView() { + } + + protected: + virtual gfx::Rect bounds() { + return gfx::Rect(0, 0, 500, 500); + } + +#if defined(OS_WIN) + // Mocks activating/deactivating the window. + void SimulateActivateWindow() { + ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL); + } + void SimulateDeactivateWindow() { + ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_INACTIVE, NULL); + } +#endif + + MessageLoopForUI* message_loop() { return &message_loop_; } + + Window* window_; + View* content_view_; + + void AddFocusChangeListener(FocusChangeListener* listener) { + ASSERT_FALSE(focus_change_listener_); + focus_change_listener_ = listener; + GetFocusManager()->AddFocusChangeListener(listener); + } + + private: + FocusChangeListener* focus_change_listener_; + MessageLoopForUI message_loop_; + + DISALLOW_COPY_AND_ASSIGN(FocusManagerTest); +}; +#if defined(OS_WIN) // BorderView is a NativeControl that creates a tab control as its child and // takes a View to add as the child of the tab control. The tab control is used // to give a nice background for the view. At some point we'll have a real @@ -183,81 +279,6 @@ class DummyComboboxModel : public Combobox::Model { } }; -class FocusManagerTest : public testing::Test, public WindowDelegate { - public: - FocusManagerTest() - : window_(NULL), - focus_change_listener_(NULL), - content_view_(NULL) { - OleInitialize(NULL); - } - - ~FocusManagerTest() { - OleUninitialize(); - } - - virtual void SetUp() { - window_ = static_cast<WindowWin*>( - Window::CreateChromeWindow(NULL, bounds(), this)); - InitContentView(); - window_->Show(); - } - - virtual void TearDown() { - if (focus_change_listener_) - GetFocusManager()->RemoveFocusChangeListener(focus_change_listener_); - window_->CloseNow(); - - // Flush the message loop to make Purify happy. - message_loop()->RunAllPending(); - } - - FocusManager* GetFocusManager() { - return FocusManager::GetFocusManagerForNativeView( - window_->GetNativeWindow()); - } - - // WindowDelegate Implementation. - virtual View* GetContentsView() { - if (!content_view_) - content_view_ = new View(); - return content_view_; - } - - virtual void InitContentView() { - } - - protected: - virtual gfx::Rect bounds() { - return gfx::Rect(0, 0, 500, 500); - } - - // Mocks activating/deactivating the window. - void SimulateActivateWindow() { - ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_ACTIVE, NULL); - } - void SimulateDeactivateWindow() { - ::SendMessage(window_->GetNativeWindow(), WM_ACTIVATE, WA_INACTIVE, NULL); - } - - MessageLoopForUI* message_loop() { return &message_loop_; } - - WindowWin* window_; - View* content_view_; - - void AddFocusChangeListener(FocusChangeListener* listener) { - ASSERT_FALSE(focus_change_listener_); - focus_change_listener_ = listener; - GetFocusManager()->AddFocusChangeListener(listener); - } - - private: - FocusChangeListener* focus_change_listener_; - MessageLoopForUI message_loop_; - - DISALLOW_COPY_AND_ASSIGN(FocusManagerTest); -}; - class FocusTraversalTest : public FocusManagerTest { public: ~FocusTraversalTest(); @@ -975,6 +996,8 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) { } } +#endif // WIN_OS + // Counts accelerator calls. class TestAcceleratorTarget : public AcceleratorTarget { public: @@ -997,8 +1020,8 @@ class TestAcceleratorTarget : public AcceleratorTarget { TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) { FocusManager* focus_manager = GetFocusManager(); - Accelerator return_accelerator(VK_RETURN, false, false, false); - Accelerator escape_accelerator(VK_ESCAPE, false, false, false); + Accelerator return_accelerator(base::VKEY_RETURN, false, false, false); + Accelerator escape_accelerator(base::VKEY_ESCAPE, false, false, false); TestAcceleratorTarget return_target(true); TestAcceleratorTarget escape_target(true); @@ -1115,7 +1138,7 @@ class SelfUnregisteringAcceleratorTarget : public AcceleratorTarget { TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) { FocusManager* focus_manager = GetFocusManager(); - Accelerator return_accelerator(VK_RETURN, false, false, false); + Accelerator return_accelerator(base::VKEY_RETURN, false, false, false); SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager); EXPECT_EQ(target.accelerator_count(), 0); EXPECT_EQ(NULL, diff --git a/views/view.cc b/views/view.cc index 820f3ec..4adef5b 100644 --- a/views/view.cc +++ b/views/view.cc @@ -995,8 +995,6 @@ void View::RegisterPendingAccelerators() { return; } - // TODO(port): Fix this once we have a FocusManger for Linux. -#if defined(OS_WIN) FocusManager* focus_manager = GetFocusManager(); if (!focus_manager) { // Some crash reports seem to show that we may get cases where we have no @@ -1011,7 +1009,6 @@ void View::RegisterPendingAccelerators() { focus_manager->RegisterAccelerator(*iter, this); } registered_accelerator_count_ = accelerators_->size(); -#endif } void View::UnregisterAccelerators() { diff --git a/views/view_unittest.cc b/views/view_unittest.cc index 8591e3b..6778135 100644 --- a/views/view_unittest.cc +++ b/views/view_unittest.cc @@ -7,6 +7,7 @@ #include "app/gfx/canvas.h" #include "app/gfx/path.h" #include "base/clipboard.h" +#include "base/keyboard_codes.h" #include "base/message_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "views/background.h" @@ -1058,7 +1059,8 @@ class DefaultButtonTest : public ViewTest { void SimularePressingEnterAndCheckDefaultButton(ButtonID button_id) { #if defined(OS_WIN) - focus_manager_->OnKeyDown(native_window_, WM_KEYDOWN, VK_RETURN, 0); + KeyEvent event(Event::ET_KEY_PRESSED, VK_RETURN, 0, 0); + focus_manager_->OnKeyEvent(event); #else // TODO(platform) return; diff --git a/views/views.gyp b/views/views.gyp index a9b09d3..b9c7a26 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -177,6 +177,9 @@ 'event_win.cc', 'fill_layout.cc', 'fill_layout.h', + 'focus/accelerator_handler.h', + 'focus/accelerator_handler_gtk.cc', + 'focus/accelerator_handler_win.cc', 'focus/external_focus_tracker.cc', 'focus/external_focus_tracker.h', 'focus/focus_manager_gtk.cc', @@ -205,8 +208,6 @@ 'view_constants.h', 'view_gtk.cc', 'view_win.cc', - 'widget/accelerator_handler.cc', - 'widget/accelerator_handler.h', 'widget/aero_tooltip_manager.cc', 'widget/aero_tooltip_manager.h', 'widget/default_theme_provider.cc', @@ -281,7 +282,6 @@ 'controls/tree/tree_view.cc', 'event_win.cc', 'resize_corner.cc', - 'widget/accelerator_handler.cc', 'widget/aero_tooltip_manager.cc', 'widget/root_view_drop_target.cc', 'widget/tooltip_manager.cc', @@ -302,6 +302,6 @@ ], }], ], - }, + } ], } diff --git a/views/widget/accelerator_handler.h b/views/widget/accelerator_handler.h deleted file mode 100644 index 5ee896c..0000000 --- a/views/widget/accelerator_handler.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2006-2008 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 VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ -#define VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ - -#include "base/message_loop.h" - -namespace views { - -// This class delegates WM_KEYDOWN and WM_SYSKEYDOWN messages to -// the associated FocusManager class for the window that is receiving -// these messages for accelerator processing. The BrowserProcess object -// holds a singleton instance of this class which can be used by other -// custom message loop dispatcher objects to implement default accelerator -// handling. -class AcceleratorHandler : public MessageLoopForUI::Dispatcher { - public: - AcceleratorHandler(); - // Dispatcher method. This returns true if an accelerator was - // processed by the focus manager - virtual bool Dispatch(const MSG& msg); - private: - DISALLOW_EVIL_CONSTRUCTORS(AcceleratorHandler); -}; - -} // namespace views - -#endif // VIEWS_WIDGET_ACCELERATOR_HANDLER_H_ diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index a77bd14..677e58c 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -70,6 +70,8 @@ WidgetGtk::WidgetGtk(Type type) ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), delete_on_destroy_(true), transparent_(false) { + if (type_ != TYPE_CHILD) + focus_manager_.reset(new FocusManager(this)); } WidgetGtk::~WidgetGtk() { @@ -398,9 +400,16 @@ ThemeProvider* WidgetGtk::GetThemeProvider() const { return default_theme_provider_.get(); } +FocusManager* WidgetGtk::GetFocusManager() { + return focus_manager_.get(); +} + //////////////////////////////////////////////////////////////////////////////// // WidgetGtk, MessageLoopForUI::Observer implementation: +void WidgetGtk::WillProcessEvent(GdkEvent* event) { +} + void WidgetGtk::DidProcessEvent(GdkEvent* event) { if (root_view_->NeedsPainting(true)) PaintNow(root_view_->GetScheduledPaintRect()); @@ -518,12 +527,12 @@ gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { } gboolean WidgetGtk::OnKeyPress(GtkWidget* widget, GdkEventKey* event) { - KeyEvent key_event(event); + KeyEvent key_event(event, false); return root_view_->ProcessKeyEvent(key_event); } gboolean WidgetGtk::OnKeyRelease(GtkWidget* widget, GdkEventKey* event) { - KeyEvent key_event(event); + KeyEvent key_event(event, false); return root_view_->ProcessKeyEvent(key_event); } diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 61a85d9..fbb6c0e 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -99,11 +99,15 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { virtual Window* GetWindow(); virtual const Window* GetWindow() const; virtual ThemeProvider* GetThemeProvider() const; + virtual FocusManager* GetFocusManager(); // MessageLoopForUI::Observer. - virtual void WillProcessEvent(GdkEvent* event) {} + virtual void WillProcessEvent(GdkEvent* event); virtual void DidProcessEvent(GdkEvent* event); + // Retrieves the WindowGtk associated with |widget|. + static WindowGtk* GetWindowForNative(GtkWidget* widget); + protected: virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation); virtual void OnPaint(GtkWidget* widget, GdkEventExpose* event); @@ -135,8 +139,7 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { // is true. virtual bool ReleaseCaptureOnMouseReleased() { return true; } - // Sets and retrieves the WidgetGtk in the userdata section of the widget. - static WindowGtk* GetWindowForNative(GtkWidget* widget); + // Sets the WindowGtk in the userdata section of the widget. static void SetWindowForNative(GtkWidget* widget, WindowGtk* window); // Are we a subclass of WindowGtk? @@ -215,6 +218,12 @@ class WidgetGtk : public Widget, public MessageLoopForUI::Observer { // must be destroyed AFTER root_view_. scoped_ptr<TooltipManagerGtk> tooltip_manager_; + // The focus manager keeping track of focus for this Widget and any of its + // children. NULL for non top-level widgets. + // WARNING: RootView's destructor calls into the FocusManager. As such, this + // must be destroyed AFTER root_view_. + scoped_ptr<FocusManager> focus_manager_; + // The root of the View hierarchy attached to this window. scoped_ptr<RootView> root_view_; diff --git a/views/window/dialog_client_view.cc b/views/window/dialog_client_view.cc index 612b1c5..9c40b7f 100644 --- a/views/window/dialog_client_view.cc +++ b/views/window/dialog_client_view.cc @@ -8,6 +8,7 @@ #include "app/gfx/font.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "base/keyboard_codes.h" #include "grit/app_strings.h" #include "views/controls/button/native_button.h" #include "views/standard_layout.h" @@ -128,13 +129,9 @@ void DialogClientView::ShowDialogButtons() { ok_button_->SetGroup(kButtonGroup); if (is_default_button) default_button_ = ok_button_; -#if defined(OS_WIN) if (!(buttons & MessageBoxFlags::DIALOGBUTTON_CANCEL)) - ok_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); -#else - NOTIMPLEMENTED(); - // TODO(port): add accelerators -#endif + ok_button_->AddAccelerator(Accelerator(base::VKEY_ESCAPE, + false, false, false)); AddChildView(ok_button_); } if (buttons & MessageBoxFlags::DIALOGBUTTON_CANCEL && !cancel_button_) { @@ -154,12 +151,8 @@ void DialogClientView::ShowDialogButtons() { MessageBoxFlags::DIALOGBUTTON_CANCEL, label, is_default_button); cancel_button_->SetGroup(kButtonGroup); -#if defined(OS_WIN) - cancel_button_->AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); -#else - NOTIMPLEMENTED(); - // TODO(port): add accelerators -#endif + cancel_button_->AddAccelerator(Accelerator(base::VKEY_ESCAPE, + false, false, false)); if (is_default_button) default_button_ = ok_button_; AddChildView(cancel_button_); @@ -167,12 +160,7 @@ void DialogClientView::ShowDialogButtons() { if (!buttons) { // Register the escape key as an accelerator which will close the window // if there are no dialog buttons. -#if defined(OS_WIN) - AddAccelerator(Accelerator(VK_ESCAPE, false, false, false)); -#else - NOTIMPLEMENTED(); - // TODO(port): add accelerators -#endif + AddAccelerator(Accelerator(base::VKEY_ESCAPE, false, false, false)); } } @@ -370,12 +358,8 @@ gfx::Size DialogClientView::GetPreferredSize() { } bool DialogClientView::AcceleratorPressed(const Accelerator& accelerator) { -#if defined(OS_WIN) - DCHECK(accelerator.GetKeyCode() == VK_ESCAPE); // We only expect Escape key. -#else - NOTIMPLEMENTED(); - // TODO(port): add accelerators -#endif + // We only expect Escape key. + DCHECK(accelerator.GetKeyCode() == base::VKEY_ESCAPE); Close(); return true; } |