summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-09 16:46:25 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-09 16:46:25 +0000
commit3941c026ba6576a4e21c93f3f08b917505c369a1 (patch)
tree2dbaad011bd9b20eadfbc25477c20a51a7f60a6e /chrome
parentf61b898ba829ce8b1393f5a518a0f28eaafa1408 (diff)
downloadchromium_src-3941c026ba6576a4e21c93f3f08b917505c369a1.zip
chromium_src-3941c026ba6576a4e21c93f3f08b917505c369a1.tar.gz
chromium_src-3941c026ba6576a4e21c93f3f08b917505c369a1.tar.bz2
Adding support for tab notifications and initializing the focus of an automated tab.
Review URL: http://codereview.chromium.org/20125 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9388 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc54
-rw-r--r--chrome/browser/automation/automation_provider.h5
-rw-r--r--chrome/browser/external_tab_container.cc57
-rw-r--r--chrome/browser/external_tab_container.h8
-rw-r--r--chrome/test/automation/automation_messages_internal.h20
-rw-r--r--chrome/test/automation/tab_proxy.cc8
-rw-r--r--chrome/test/automation/tab_proxy.h3
7 files changed, 119 insertions, 36 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index dc1cb10..b6f8462 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -770,6 +770,8 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
SetAcceleratorsForTab)
IPC_MESSAGE_HANDLER(AutomationMsg_ProcessUnhandledAccelerator,
ProcessUnhandledAccelerator)
+ IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus,
+ SetInitialFocus)
IPC_MESSAGE_HANDLER(AutomationMsg_WaitForTabToBeRestored,
WaitForTabToBeRestored)
IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState,
@@ -2105,18 +2107,10 @@ void AutomationProvider::SetAcceleratorsForTab(const IPC::Message& message,
HACCEL accel_table,
int accel_entry_count) {
bool status = false;
- if (tab_tracker_->ContainsHandle(handle)) {
- NavigationController* tab = tab_tracker_->GetResource(handle);
- TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
- ExternalTabContainer* external_tab_container =
- ExternalTabContainer::GetContainerForTab(
- tab_contents->GetContainerHWND());
- // This call is only valid on an externally hosted tab
- if (external_tab_container) {
- external_tab_container->SetAccelerators(accel_table,
- accel_entry_count);
- status = true;
- }
+ ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
+ if (external_tab) {
+ external_tab->SetAccelerators(accel_table, accel_entry_count);
+ status = true;
}
Send(new AutomationMsg_SetAcceleratorsForTabResponse(message.routing_id(),
status));
@@ -2124,16 +2118,18 @@ void AutomationProvider::SetAcceleratorsForTab(const IPC::Message& message,
void AutomationProvider::ProcessUnhandledAccelerator(
const IPC::Message& message, int handle, const MSG& msg) {
- if (tab_tracker_->ContainsHandle(handle)) {
- NavigationController* tab = tab_tracker_->GetResource(handle);
- TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
- ExternalTabContainer* external_tab_container =
- ExternalTabContainer::GetContainerForTab(
- tab_contents->GetContainerHWND());
- // This call is only valid on an externally hosted tab
- if (external_tab_container) {
- external_tab_container->ProcessUnhandledAccelerator(msg);
- }
+ ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
+ if (external_tab) {
+ external_tab->ProcessUnhandledAccelerator(msg);
+ }
+ // This message expects no response.
+}
+
+void AutomationProvider::SetInitialFocus(const IPC::Message& message,
+ int handle, bool reverse) {
+ ExternalTabContainer* external_tab = GetExternalTabForHandle(handle);
+ if (external_tab) {
+ external_tab->SetInitialFocus(reverse);
}
// This message expects no response.
}
@@ -2391,6 +2387,20 @@ WebContents* AutomationProvider::GetWebContentsForHandle(
return web_contents;
}
+ExternalTabContainer* AutomationProvider::GetExternalTabForHandle(int handle) {
+ if (tab_tracker_->ContainsHandle(handle)) {
+ NavigationController* tab = tab_tracker_->GetResource(handle);
+ TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
+ DCHECK(tab_contents);
+ if (tab_contents) {
+ HWND hwnd = tab_contents->GetContainerHWND();
+ return ExternalTabContainer::GetContainerForTab(hwnd);
+ }
+ }
+
+ return NULL;
+}
+
TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
: AutomationProvider(profile) {
BrowserList::AddObserver(this);
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index c223d3d..a8ca47f 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -30,6 +30,7 @@
class LoginHandler;
class NavigationControllerRestoredObserver;
+class ExternalTabContainer;
class AutomationProvider : public base::RefCounted<AutomationProvider>,
public IPC::Channel::Listener,
@@ -248,6 +249,8 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void ProcessUnhandledAccelerator(const IPC::Message& message, int handle,
const MSG& msg);
+ void SetInitialFocus(const IPC::Message& message, int handle, bool reverse);
+
// See comment in AutomationMsg_WaitForTabToBeRestored.
void WaitForTabToBeRestored(const IPC::Message& message, int tab_handle);
@@ -370,6 +373,8 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
// is not of the WebContents type.
WebContents* GetWebContentsForHandle(int handle, NavigationController** tab);
+ ExternalTabContainer* GetExternalTabForHandle(int handle);
+
// Callback for history redirect queries.
virtual void OnRedirectQueryComplete(
HistoryService::Handle request_handle,
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index e80a01b..6e1d58e 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -74,12 +74,22 @@ bool ExternalTabContainer::Init(Profile* profile, HWND parent,
// Create a TabContentsContainerView to handle focus cycling using Tab and
// Shift-Tab.
- // TODO(sanjeevr): We need to create a dummy FocusTraversable object to
- // represent the frame of the external host. This will allow Tab and
- // Shift-Tab to cycle into the external frame.
tab_contents_container_ = new TabContentsContainerView();
root_view_.AddChildView(tab_contents_container_);
+ // Note that SetTabContents must be called after AddChildView is called
tab_contents_container_->SetTabContents(tab_contents_);
+ // Add a dummy view to catch when the user tabs out of the tab
+ // Create a dummy FocusTraversable object to represent the frame of the
+ // external host. This will allow Tab and Shift-Tab to cycle into the
+ // external frame. When the tab_contents_container_ loses focus,
+ // the focus will be moved to this class (See OnSetFocus in this file).
+ // An alternative to using views::View and catching when the focus manager
+ // shifts the focus to the dummy view could be to implement our own view
+ // and handle AboutToRequestFocusFromTabTraversal.
+ views::View* dummy = new views::View();
+ dummy->SetFocusable(true);
+ DCHECK(dummy->IsFocusable());
+ root_view_.AddChildView(dummy);
NavigationController* controller = tab_contents_->controller();
DCHECK(controller);
@@ -104,7 +114,7 @@ bool ExternalTabContainer::Init(Profile* profile, HWND parent,
}
void ExternalTabContainer::OnDestroy() {
- views::FocusManager * focus_manager =
+ views::FocusManager* focus_manager =
views::FocusManager::GetFocusManager(GetHWND());
if (focus_manager) {
focus_manager->RemoveKeystrokeListener(this);
@@ -140,9 +150,21 @@ LRESULT ExternalTabContainer::OnSize(UINT, WPARAM, LPARAM, BOOL& handled) {
return 0;
}
-// TODO(sanjeevr): The implementation of the TabContentsDelegate interface
-// needs to be fully fleshed out based on the requirements of the
-// "Chrome tab in external browser" feature.
+LRESULT ExternalTabContainer::OnSetFocus(UINT msg, WPARAM wp, LPARAM lp,
+ BOOL& handled) {
+ if (automation_) {
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManager(GetHWND());
+ DCHECK(focus_manager);
+ if (focus_manager) {
+ focus_manager->ClearFocus();
+ automation_->Send(new AutomationMsg_TabbedOut(win_util::IsShiftPressed(),
+ false));
+ }
+ }
+
+ return 0;
+}
void ExternalTabContainer::OpenURLFromTab(TabContents* source,
const GURL& url,
@@ -164,10 +186,10 @@ void ExternalTabContainer::OpenURLFromTab(TabContents* source,
}
void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
- unsigned changed_flags) {
+ unsigned changed_flags) {
if (automation_) {
automation_->Send(
- new AutomationMsg_NavigationStateChanged(0,changed_flags));
+ new AutomationMsg_NavigationStateChanged(0, changed_flags));
}
}
@@ -190,14 +212,16 @@ void ExternalTabContainer::LoadingStateChanged(TabContents* source) {
void ExternalTabContainer::CloseContents(TabContents* source) {
}
-void ExternalTabContainer::MoveContents(TabContents* source, const gfx::Rect& pos) {
+void ExternalTabContainer::MoveContents(TabContents* source,
+ const gfx::Rect& pos) {
}
bool ExternalTabContainer::IsPopup(TabContents* source) {
return false;
}
-void ExternalTabContainer::URLStarredChanged(TabContents* source, bool starred) {
+void ExternalTabContainer::URLStarredChanged(TabContents* source,
+ bool starred) {
}
void ExternalTabContainer::UpdateTargetURL(TabContents* source,
@@ -213,7 +237,7 @@ void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
}
void ExternalTabContainer::ToolbarSizeChanged(TabContents* source,
- bool finished) {
+ bool finished) {
}
void ExternalTabContainer::ForwardMessageToExternalHost(
@@ -281,7 +305,7 @@ bool ExternalTabContainer::IsActive() {
}
bool ExternalTabContainer::ProcessKeyDown(HWND window, UINT message,
- WPARAM wparam, LPARAM lparam) {
+ WPARAM wparam, LPARAM lparam) {
if (!automation_) {
return false;
}
@@ -324,6 +348,13 @@ void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
DispatchMessage(&msg);
}
+void ExternalTabContainer::SetInitialFocus(bool reverse) {
+ DCHECK(tab_contents_);
+ if (tab_contents_) {
+ tab_contents_->SetInitialFocus(reverse);
+ }
+}
+
// static
bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
std::wstring class_name = win_util::GetClassName(window);
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index b09f032..29c0d81 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -39,6 +39,7 @@ class ExternalTabContainer : public TabContentsDelegate,
public:
BEGIN_MSG_MAP(ExternalTabContainer)
MESSAGE_HANDLER(WM_SIZE, OnSize)
+ MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MSG_WM_DESTROY(OnDestroy)
END_MSG_MAP()
@@ -114,6 +115,9 @@ class ExternalTabContainer : public TabContentsDelegate,
// message it did not process
void ProcessUnhandledAccelerator(const MSG& msg);
+ // See TabContents::SetInitialFocus
+ void SetInitialFocus(bool reverse);
+
// A helper method that tests whether the given window is an
// ExternalTabContainer window
static bool IsExternalTabContainer(HWND window);
@@ -124,11 +128,13 @@ class ExternalTabContainer : public TabContentsDelegate,
protected:
LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL& handled);
+ LRESULT OnSetFocus(UINT msg, WPARAM wp, LPARAM lp, BOOL& handled);
+
void OnDestroy();
void OnFinalMessage(HWND window);
protected:
- TabContents *tab_contents_;
+ TabContents* tab_contents_;
AutomationProvider* automation_;
NotificationRegistrar registrar_;
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index 09c8390..9b31477 100644
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -553,6 +553,26 @@ IPC_BEGIN_MESSAGES(Automation)
IPC_MESSAGE_ROUTED2(AutomationMsg_ProcessUnhandledAccelerator, int, MSG)
#endif // defined(OS_WIN)
+ // Sent by the external tab to the host to notify that the user has tabbed
+ // out of the tab.
+ // Request:
+ // - bool: |reverse| set to true when shift-tabbing out of the tab, false
+ // otherwise.
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED1(AutomationMsg_TabbedOut, bool)
+
+ // Sent by the external tab host to ask focus to be set to either the first
+ // or last element on the page.
+ // Request:
+ // - int: handle of the tab
+ // - bool: |reverse|
+ // true: Focus will be set to the last focusable element
+ // false: Focus will be set to the first focusable element
+ // Response:
+ // None expected
+ IPC_MESSAGE_ROUTED2(AutomationMsg_SetInitialFocus, int, bool)
+
// This message is an outgoing message from Chrome to an external host.
// It is a request to open a url
// Request:
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index 61b50cf..e0e6102 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -641,6 +641,14 @@ bool TabProxy::ProcessUnhandledAccelerator(const MSG& msg) {
// This message expects no response
}
+bool TabProxy::SetInitialFocus(bool reverse) {
+ if (!is_valid())
+ return false;
+ return sender_->Send(
+ new AutomationMsg_SetInitialFocus(0, handle_, reverse));
+ // This message expects no response
+}
+
bool TabProxy::WaitForTabToBeRestored(uint32 timeout_ms) {
if (!is_valid())
return false;
diff --git a/chrome/test/automation/tab_proxy.h b/chrome/test/automation/tab_proxy.h
index 932f5c7..f9a8339 100644
--- a/chrome/test/automation/tab_proxy.h
+++ b/chrome/test/automation/tab_proxy.h
@@ -219,6 +219,9 @@ class TabProxy : public AutomationResourceProxy {
// to handle the keys
bool ProcessUnhandledAccelerator(const MSG& msg);
+ // Ask the tab to set focus to either the first or last element on the page.
+ bool SetInitialFocus(bool reverse);
+
// Waits for the tab to finish being restored. Returns true on success.
// timeout_ms gives the max amount of time to wait for restore to complete.
bool WaitForTabToBeRestored(uint32 timeout_ms);