Commit 3a1381d6 authored by jennb@chromium.org's avatar jennb@chromium.org

Handle keyboard shortcuts in Mac Panels.

Common code from browser_window_cocoa separated into cocoa/browser_window_utils.

Panel.xib changed to make the NSWindow for the PanelWindowControllerCocoa a ChromeEventProcessingWindow.

BUG=None
TEST=Manual testing with Panels and keyboard shortcuts to find/next/previous/close window/quit chrome.

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=98112 (Reverted by http://codereview.chromium.org/7747011/)

Review URL: http://codereview.chromium.org/7719016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98452 0039d316-1c4b-4281-b951-d872f2087c98
parent 0c2830d9
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<integer value="6"/>
<integer value="1"/> <integer value="1"/>
<integer value="6"/>
</object> </object>
<object class="NSArray" key="IBDocument.PluginDependencies"> <object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
<string key="NSWindowRect">{{196, 240}, {480, 270}}</string> <string key="NSWindowRect">{{196, 240}, {480, 270}}</string>
<int key="NSWTFlags">544736256</int> <int key="NSWTFlags">544736256</int>
<string key="NSWindowTitle">Window</string> <string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string> <string key="NSWindowClass">ChromeEventProcessingWindow</string>
<nil key="NSViewClass"/> <nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string> <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<object class="NSView" key="NSWindowView" id="1006"> <object class="NSView" key="NSWindowView" id="1006">
...@@ -204,6 +204,14 @@ ...@@ -204,6 +204,14 @@
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">ChromeEventProcessingWindow</string>
<string key="superclassName">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription"> <object class="IBPartialClassDescription">
<string key="className">FirstResponder</string> <string key="className">FirstResponder</string>
<string key="superclassName">NSObject</string> <string key="superclassName">NSObject</string>
......
...@@ -132,8 +132,6 @@ class BrowserWindowCocoa : public BrowserWindow, ...@@ -132,8 +132,6 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void DestroyBrowser(); virtual void DestroyBrowser();
private: private:
int GetCommandId(const NativeWebKeyboardEvent& event);
bool HandleKeyboardEventInternal(NSEvent* event);
NSWindow* window() const; // Accessor for the (current) |NSWindow|. NSWindow* window() const; // Accessor for the (current) |NSWindow|.
void UpdateSidebarForContents(TabContents* tab_contents); void UpdateSidebarForContents(TabContents* tab_contents);
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/download/download_shelf.h" #include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/global_keyboard_shortcuts_mac.h"
#include "chrome/browser/page_info_window.h" #include "chrome/browser/page_info_window.h"
#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -21,6 +20,7 @@ ...@@ -21,6 +20,7 @@
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
#import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h" #import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_utils.h"
#import "chrome/browser/ui/cocoa/bug_report_window_controller.h" #import "chrome/browser/ui/cocoa/bug_report_window_controller.h"
#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
#import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h" #import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h"
...@@ -449,130 +449,27 @@ void BrowserWindowCocoa::ShowAppMenu() { ...@@ -449,130 +449,27 @@ void BrowserWindowCocoa::ShowAppMenu() {
bool BrowserWindowCocoa::PreHandleKeyboardEvent( bool BrowserWindowCocoa::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char) if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
return false; return false;
DCHECK(event.os_event != NULL); int id = [BrowserWindowUtils getCommandId:event];
int id = GetCommandId(event);
if (id == -1) if (id == -1)
return false; return false;
if (browser_->IsReservedCommandOrKey(id, event)) if (browser_->IsReservedCommandOrKey(id, event)) {
return HandleKeyboardEventInternal(event.os_event); return [BrowserWindowUtils handleKeyboardEvent:event.os_event
inWindow:window()];
}
DCHECK(is_keyboard_shortcut != NULL); DCHECK(is_keyboard_shortcut);
*is_keyboard_shortcut = true; *is_keyboard_shortcut = true;
return false; return false;
} }
void BrowserWindowCocoa::HandleKeyboardEvent( void BrowserWindowCocoa::HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) { const NativeWebKeyboardEvent& event) {
if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char) if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
return; [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
DCHECK(event.os_event != NULL);
HandleKeyboardEventInternal(event.os_event);
}
@interface MenuWalker : NSObject
+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
menu:(NSMenu*)menu;
@end
@implementation MenuWalker
+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
menu:(NSMenu*)menu {
NSMenuItem* result = nil;
for (NSMenuItem *item in [menu itemArray]) {
NSMenu* submenu = [item submenu];
if (submenu) {
if (submenu != [NSApp servicesMenu])
result = [self itemForKeyEquivalent:key
menu:submenu];
} else if ([item cr_firesForKeyEventIfEnabled:key]) {
result = item;
}
if (result)
break;
}
return result;
}
@end
int BrowserWindowCocoa::GetCommandId(const NativeWebKeyboardEvent& event) {
if ([event.os_event type] != NSKeyDown)
return -1;
// Look in menu.
NSMenuItem* item = [MenuWalker itemForKeyEquivalent:event.os_event
menu:[NSApp mainMenu]];
if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0)
return [item tag];
// "Close window" doesn't use the |commandDispatch:| mechanism. Menu items
// that do not correspond to IDC_ constants need no special treatment however,
// as they can't be blacklisted in |Browser::IsReservedCommandOrKey()| anyhow.
if (item && [item action] == @selector(performClose:))
return IDC_CLOSE_WINDOW;
// "Exit" doesn't use the |commandDispatch:| mechanism either.
if (item && [item action] == @selector(terminate:))
return IDC_EXIT;
// Look in secondary keyboard shortcuts.
NSUInteger modifiers = [event.os_event modifierFlags];
const bool cmdKey = (modifiers & NSCommandKeyMask) != 0;
const bool shiftKey = (modifiers & NSShiftKeyMask) != 0;
const bool cntrlKey = (modifiers & NSControlKeyMask) != 0;
const bool optKey = (modifiers & NSAlternateKeyMask) != 0;
const int keyCode = [event.os_event keyCode];
const unichar keyChar = KeyCharacterForEvent(event.os_event);
int cmdNum = CommandForWindowKeyboardShortcut(
cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
if (cmdNum != -1)
return cmdNum;
cmdNum = CommandForBrowserKeyboardShortcut(
cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
if (cmdNum != -1)
return cmdNum;
return -1;
}
bool BrowserWindowCocoa::HandleKeyboardEventInternal(NSEvent* event) {
ChromeEventProcessingWindow* event_window =
static_cast<ChromeEventProcessingWindow*>(window());
DCHECK([event_window isKindOfClass:[ChromeEventProcessingWindow class]]);
// Do not fire shortcuts on key up.
if ([event type] == NSKeyDown) {
// Send the event to the menu before sending it to the browser/window
// shortcut handling, so that if a user configures cmd-left to mean
// "previous tab", it takes precedence over the built-in "history back"
// binding. Other than that, the |-redispatchKeyEvent:| call would take care
// of invoking the original menu item shortcut as well.
if ([[NSApp mainMenu] performKeyEquivalent:event])
return true;
if ([event_window handleExtraBrowserKeyboardShortcut:event])
return true;
if ([event_window handleExtraWindowKeyboardShortcut:event])
return true;
if ([event_window handleDelayedWindowKeyboardShortcut:event])
return true;
}
return [event_window redispatchKeyEvent:event];
} }
void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog( void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog(
......
// Copyright (c) 2011 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 CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_UTILS_H_
#define CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_UTILS_H_
#pragma once
#import <Cocoa/Cocoa.h>
class Browser;
struct NativeWebKeyboardEvent;
@interface BrowserWindowUtils : NSObject
// Returns YES if keyboard event should be handled.
+ (BOOL)shouldHandleKeyboardEvent:(const NativeWebKeyboardEvent&)event;
// Determines the command associated with the keyboard event.
// Returns -1 if no command found.
+ (int)getCommandId:(const NativeWebKeyboardEvent&)event;
// NSWindow must be a ChromeEventProcessingWindow.
+ (BOOL)handleKeyboardEvent:(NSEvent*)event
inWindow:(NSWindow*)window;
@end
#endif // CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_UTILS_H_
// Copyright (c) 2011 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.
#import "chrome/browser/ui/cocoa/browser_window_utils.h"
#include "base/logging.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/global_keyboard_shortcuts_mac.h"
#include "chrome/browser/ui/browser.h"
#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
#import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
#include "content/common/native_web_keyboard_event.h"
@interface MenuWalker : NSObject
+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
menu:(NSMenu*)menu;
@end
@implementation MenuWalker
+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
menu:(NSMenu*)menu {
NSMenuItem* result = nil;
for (NSMenuItem* item in [menu itemArray]) {
NSMenu* submenu = [item submenu];
if (submenu) {
if (submenu != [NSApp servicesMenu])
result = [self itemForKeyEquivalent:key
menu:submenu];
} else if ([item cr_firesForKeyEventIfEnabled:key]) {
result = item;
}
if (result)
break;
}
return result;
}
@end
@implementation BrowserWindowUtils
+ (BOOL)shouldHandleKeyboardEvent:(const NativeWebKeyboardEvent&)event {
if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char)
return NO;
DCHECK(event.os_event != NULL);
return YES;
}
+ (int)getCommandId:(const NativeWebKeyboardEvent&)event {
if ([event.os_event type] != NSKeyDown)
return -1;
// Look in menu.
NSMenuItem* item = [MenuWalker itemForKeyEquivalent:event.os_event
menu:[NSApp mainMenu]];
if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0)
return [item tag];
// "Close window" doesn't use the |commandDispatch:| mechanism. Menu items
// that do not correspond to IDC_ constants need no special treatment however,
// as they can't be blacklisted in |Browser::IsReservedCommandOrKey()| anyhow.
if (item && [item action] == @selector(performClose:))
return IDC_CLOSE_WINDOW;
// "Exit" doesn't use the |commandDispatch:| mechanism either.
if (item && [item action] == @selector(terminate:))
return IDC_EXIT;
// Look in secondary keyboard shortcuts.
NSUInteger modifiers = [event.os_event modifierFlags];
const bool cmdKey = (modifiers & NSCommandKeyMask) != 0;
const bool shiftKey = (modifiers & NSShiftKeyMask) != 0;
const bool cntrlKey = (modifiers & NSControlKeyMask) != 0;
const bool optKey = (modifiers & NSAlternateKeyMask) != 0;
const int keyCode = [event.os_event keyCode];
const unichar keyChar = KeyCharacterForEvent(event.os_event);
int cmdNum = CommandForWindowKeyboardShortcut(
cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
if (cmdNum != -1)
return cmdNum;
cmdNum = CommandForBrowserKeyboardShortcut(
cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
if (cmdNum != -1)
return cmdNum;
return -1;
}
+ (BOOL)handleKeyboardEvent:(NSEvent*)event
inWindow:(NSWindow*)window {
ChromeEventProcessingWindow* event_window =
static_cast<ChromeEventProcessingWindow*>(window);
DCHECK([event_window isKindOfClass:[ChromeEventProcessingWindow class]]);
// Do not fire shortcuts on key up.
if ([event type] == NSKeyDown) {
// Send the event to the menu before sending it to the browser/window
// shortcut handling, so that if a user configures cmd-left to mean
// "previous tab", it takes precedence over the built-in "history back"
// binding. Other than that, the |-redispatchKeyEvent:| call would take care
// of invoking the original menu item shortcut as well.
if ([[NSApp mainMenu] performKeyEquivalent:event])
return true;
if ([event_window handleExtraBrowserKeyboardShortcut:event])
return true;
if ([event_window handleExtraWindowKeyboardShortcut:event])
return true;
if ([event_window handleDelayedWindowKeyboardShortcut:event])
return true;
}
return [event_window redispatchKeyEvent:event];
}
@end
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
#import "chrome/browser/ui/cocoa/browser_window_utils.h"
#include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel.h"
#include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_manager.h"
#import "chrome/browser/ui/panels/panel_window_controller_cocoa.h" #import "chrome/browser/ui/panels/panel_window_controller_cocoa.h"
...@@ -156,13 +157,29 @@ bool PanelBrowserWindowCocoa::IsDrawingAttention() const { ...@@ -156,13 +157,29 @@ bool PanelBrowserWindowCocoa::IsDrawingAttention() const {
bool PanelBrowserWindowCocoa::PreHandlePanelKeyboardEvent( bool PanelBrowserWindowCocoa::PreHandlePanelKeyboardEvent(
const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
NOTIMPLEMENTED(); if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
return false;
int id = [BrowserWindowUtils getCommandId:event];
if (id == -1)
return false;
if (browser()->IsReservedCommandOrKey(id, event)) {
return [BrowserWindowUtils handleKeyboardEvent:event.os_event
inWindow:GetNativePanelHandle()];
}
DCHECK(is_keyboard_shortcut);
*is_keyboard_shortcut = true;
return false; return false;
} }
void PanelBrowserWindowCocoa::HandlePanelKeyboardEvent( void PanelBrowserWindowCocoa::HandlePanelKeyboardEvent(
const NativeWebKeyboardEvent& event) { const NativeWebKeyboardEvent& event) {
NOTIMPLEMENTED(); if ([BrowserWindowUtils shouldHandleKeyboardEvent:event]) {
[BrowserWindowUtils handleKeyboardEvent:event.os_event
inWindow:GetNativePanelHandle()];
}
} }
Browser* PanelBrowserWindowCocoa::GetPanelBrowser() const { Browser* PanelBrowserWindowCocoa::GetPanelBrowser() const {
......
...@@ -2368,6 +2368,8 @@ ...@@ -2368,6 +2368,8 @@
'browser/ui/cocoa/browser_window_controller_private.h', 'browser/ui/cocoa/browser_window_controller_private.h',
'browser/ui/cocoa/browser_window_controller_private.mm', 'browser/ui/cocoa/browser_window_controller_private.mm',
'browser/ui/cocoa/browser_window_factory.mm', 'browser/ui/cocoa/browser_window_factory.mm',
'browser/ui/cocoa/browser_window_utils.h',
'browser/ui/cocoa/browser_window_utils.mm',
'browser/ui/cocoa/bubble_view.h', 'browser/ui/cocoa/bubble_view.h',
'browser/ui/cocoa/bubble_view.mm', 'browser/ui/cocoa/bubble_view.mm',
'browser/ui/cocoa/bug_report_window_controller.h', 'browser/ui/cocoa/bug_report_window_controller.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment