summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.cc9
-rw-r--r--chrome/browser/browser.h1
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h7
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm4
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.h9
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.mm23
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h17
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm53
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.cc16
-rw-r--r--chrome/browser/gtk/constrained_window_gtk.h4
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc11
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.h5
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc7
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h2
-rw-r--r--chrome/browser/login_prompt_gtk.cc30
-rw-r--r--chrome/browser/login_prompt_win.cc5
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc15
-rw-r--r--chrome/browser/renderer_host/render_view_host.h1
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h6
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc7
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h12
-rw-r--r--chrome/browser/tab_contents/constrained_window.h7
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc35
-rw-r--r--chrome/browser/tab_contents/tab_contents.h12
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h6
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc23
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h8
-rw-r--r--chrome/browser/tabs/tab_strip_model.cc14
-rw-r--r--chrome/browser/tabs/tab_strip_model.h17
-rw-r--r--chrome/browser/views/constrained_window_win.cc14
-rw-r--r--chrome/browser/views/constrained_window_win.h3
-rw-r--r--chrome/browser/views/login_view.cc6
-rw-r--r--chrome/browser/views/login_view.h2
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc11
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h5
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc6
-rw-r--r--chrome/browser/views/tabs/tab_strip.h1
-rw-r--r--views/view.cc2
38 files changed, 291 insertions, 125 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 0f00ab4..bcf74d1 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -2165,6 +2165,15 @@ void Browser::ContentsZoomChange(bool zoom_in) {
ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
}
+void Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
+ int index = tabstrip_model()->GetIndexOfTabContents(contents);
+ if (index == TabStripModel::kNoTab) {
+ NOTREACHED();
+ return;
+ }
+ tabstrip_model()->SetTabBlocked(index, blocked);
+}
+
void Browser::TabContentsFocused(TabContents* tab_content) {
window_->TabContentsFocused(tab_content);
}
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index a354a62..50fd49d 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -571,6 +571,7 @@ class Browser : public TabStripModelDelegate,
virtual void ContentsMouseEvent(
TabContents* source, const gfx::Point& location, bool motion);
virtual void ContentsZoomChange(bool zoom_in);
+ virtual void SetTabContentBlocked(TabContents* contents, bool blocked);
virtual void TabContentsFocused(TabContents* tab_content);
virtual bool TakeFocus(bool reverse);
virtual bool IsApplication() const;
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index ed2b18b..9a15e39 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -209,12 +209,7 @@ class TabStripModelObserverBridge;
- (GTMWindowSheetController*)sheetController;
// Requests that |window| is opened as a per-tab sheet to the current tab.
-// Returns YES if the window became the active per-tab sheet of the current tab,
-// or NO if the current tab already has a per-tab sheet. If this returns NO,
-// the window's |Realize()| method will be called again when the curren sheet
-// disappears. The window should then call |attachConstrainedWindow:| again.
-- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window;
-
+- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window;
// Closes the tab sheet |window| and potentially shows the next sheet in the
// tab's sheet queue.
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window;
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index d8be276..51d1ced 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -385,8 +385,8 @@ willPositionSheet:(NSWindow*)sheet
afterDelay:0];
}
-- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window {
- return [tabStripController_ attachConstrainedWindow:window];
+- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window {
+ [tabStripController_ attachConstrainedWindow:window];
}
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window {
diff --git a/chrome/browser/cocoa/constrained_window_mac.h b/chrome/browser/cocoa/constrained_window_mac.h
index 83331c7..0fd315d 100644
--- a/chrome/browser/cocoa/constrained_window_mac.h
+++ b/chrome/browser/cocoa/constrained_window_mac.h
@@ -117,6 +117,7 @@ class ConstrainedWindowMac : public ConstrainedWindow {
virtual ~ConstrainedWindowMac();
// Overridden from ConstrainedWindow:
+ virtual void ShowConstrainedWindow();
virtual void CloseConstrainedWindow();
// Returns the TabContents that constrains this Constrained Window.
@@ -125,12 +126,9 @@ class ConstrainedWindowMac : public ConstrainedWindow {
// Returns the window's delegate.
ConstrainedWindowMacDelegate* delegate() { return delegate_; }
- // Tells |controller_| that the sheet would like to be displayed.
+ // Makes the constrained window visible, if it is not yet visible.
void Realize(BrowserWindowController* controller);
- // Called by |controller_| to inform the sheet that it now is visible.
- void SetVisible();
-
private:
friend class ConstrainedWindow;
@@ -146,6 +144,9 @@ class ConstrainedWindowMac : public ConstrainedWindow {
// Controller of the window that contains this sheet.
BrowserWindowController* controller_;
+ // Stores if |ShowConstrainedWindow()| was called.
+ bool should_be_visible_;
+
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowMac);
};
diff --git a/chrome/browser/cocoa/constrained_window_mac.mm b/chrome/browser/cocoa/constrained_window_mac.mm
index ad090a8..eec4dba 100644
--- a/chrome/browser/cocoa/constrained_window_mac.mm
+++ b/chrome/browser/cocoa/constrained_window_mac.mm
@@ -46,10 +46,16 @@ ConstrainedWindowMac::ConstrainedWindowMac(
TabContents* owner, ConstrainedWindowMacDelegate* delegate)
: owner_(owner),
delegate_(delegate),
- controller_(nil) {
+ controller_(nil),
+ should_be_visible_(false) {
DCHECK(owner);
DCHECK(delegate);
+}
+
+ConstrainedWindowMac::~ConstrainedWindowMac() {}
+void ConstrainedWindowMac::ShowConstrainedWindow() {
+ should_be_visible_ = true;
// The TabContents only has a native window if it is currently visible. In
// this case, open the sheet now. Else, Realize() will be called later, when
// our tab becomes visible.
@@ -61,8 +67,6 @@ ConstrainedWindowMac::ConstrainedWindowMac(
}
}
-ConstrainedWindowMac::~ConstrainedWindowMac() {}
-
void ConstrainedWindowMac::CloseConstrainedWindow() {
// Note: controller_ can be `nil` here if the sheet was never realized. That's
// ok.
@@ -74,6 +78,9 @@ void ConstrainedWindowMac::CloseConstrainedWindow() {
}
void ConstrainedWindowMac::Realize(BrowserWindowController* controller) {
+ if (!should_be_visible_)
+ return;
+
if (controller_ != nil) {
DCHECK(controller_ == controller);
return;
@@ -82,13 +89,7 @@ void ConstrainedWindowMac::Realize(BrowserWindowController* controller) {
// Remember the controller we're adding ourselves to, so that we can later
// remove us from it.
- if ([controller attachConstrainedWindow:this])
- controller_ = controller;
-}
-
-void ConstrainedWindowMac::SetVisible() {
- // Only notify the delegate that the sheet is open after the sheet appeared
- // on screen (as opposed to when the sheet was added to the current tab's
- // sheet queue).
+ controller_ = controller;
+ [controller_ attachConstrainedWindow:this];
delegate_->set_sheet_open(true);
}
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
index f5f8d9d..8bc3b00 100644
--- a/chrome/browser/cocoa/tab_strip_controller.h
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -7,9 +7,6 @@
#import <Cocoa/Cocoa.h>
-#include <deque>
-#include <map>
-
#include "base/scoped_nsobject.h"
#include "base/scoped_ptr.h"
#import "chrome/browser/cocoa/tab_controller_target.h"
@@ -53,7 +50,7 @@ class ToolbarModel;
scoped_ptr<TabStripModelObserverBridge> bridge_;
Browser* browser_; // weak
TabStripModel* tabStripModel_; // weak
-
+
// Access to the TabContentsControllers (which own the parent view
// for the toolbar and associated tab contents) given an index. Call
// |indexFromModelIndex:| to convert a |tabStripModel_| index to a
@@ -110,12 +107,6 @@ class ToolbarModel;
// Is the mouse currently inside the strip;
BOOL mouseInside_;
-
- // GTMWindowSheetController supports only one per-tab sheet at a time.
- // Thus, keep a queue of sheets for every tab. The first element in the queue
- // is the currently visible sheet, and when this sheet is closed, the next
- // sheet in the queue will be shown.
- std::map<NSView*, std::deque<ConstrainedWindowMac*> > constrainedWindows_;
}
// Initialize the controller with a view and browser that contains
@@ -192,9 +183,9 @@ class ToolbarModel;
// Returns the currently active TabContentsController.
- (TabContentsController*)activeTabContentsController;
-// See comments in browser_window_controller.h for documentation about these
-// functions.
-- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window;
+ // See comments in browser_window_controller.h for documentation about these
+ // functions.
+- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window;
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window;
- (void)updateDevToolsForContents:(TabContents*)contents;
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index 14eb3c7..8c2eac0 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -417,13 +417,11 @@ private:
DCHECK(newTab);
if (newTab) {
TabContents::ConstrainedWindowList::iterator it, end;
- it = newTab->constrained_window_begin();
end = newTab->constrained_window_end();
+ NSWindowController* controller = [[newView window] windowController];
+ DCHECK([controller isKindOfClass:[BrowserWindowController class]]);
- // GTMWindowSheetController supports only one sheet at a time.
- if (it != end) {
- NSWindowController* controller = [[newView window] windowController];
- DCHECK([controller isKindOfClass:[BrowserWindowController class]]);
+ for (it = newTab->constrained_window_begin(); it != end; ++it) {
ConstrainedWindow* constrainedWindow = *it;
static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize(
static_cast<BrowserWindowController*>(controller));
@@ -1637,7 +1635,7 @@ private:
if (modelIndex < 0)
return nil;
NSInteger index = [self indexFromModelIndex:modelIndex];
- if (index < 0 ||
+ if (index < 0 ||
index >= (NSInteger)[tabContentsArray_ count])
return nil;
return [tabContentsArray_ objectAtIndex:index];
@@ -1656,7 +1654,7 @@ private:
tabStripModel_->SelectTabContentsAt(index, false /* not a user gesture */);
}
-- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window {
+- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window {
// TODO(thakis, avi): Figure out how to make this work when tabs are dragged
// out or if fullscreen mode is toggled.
@@ -1669,6 +1667,7 @@ private:
// to pass it to the sheet controller here.
NSView* tabContentsView =
[[window->owner()->GetNativeView() superview] superview];
+ window->delegate()->RunSheet([self sheetController], tabContentsView);
// TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets
// between windows. Until then, we have to prevent having to move a tabsheet
@@ -1680,23 +1679,8 @@ private:
DCHECK(controller != nil);
DCHECK(index >= 0);
if (index >= 0) {
- NSView* tab = [self viewAtIndex:index];
- [controller setTab:tab isDraggable:NO];
-
- std::deque<ConstrainedWindowMac*>& windows = constrainedWindows_[tab];
- std::deque<ConstrainedWindowMac*>::iterator it =
- find(windows.begin(), windows.end(), window);
- if (it == windows.end())
- constrainedWindows_[tab].push_back(window);
-
- if (constrainedWindows_[tab].size() == 1) {
- [controller setTab:tab isDraggable:NO];
- window->SetVisible();
- window->delegate()->RunSheet([self sheetController], tabContentsView);
- return YES;
- }
+ [controller setTab:[self viewAtIndex:index] isDraggable:NO];
}
- return NO;
}
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window {
@@ -1712,28 +1696,7 @@ private:
(BrowserWindowController*)[[switchView_ window] windowController];
DCHECK(index >= 0);
if (index >= 0) {
- NSView* tab = [self viewAtIndex:index];
-
- std::deque<ConstrainedWindowMac*>& windows = constrainedWindows_[tab];
- std::deque<ConstrainedWindowMac*>::iterator it =
- find(windows.begin(), windows.end(), window);
- DCHECK(it != windows.end());
-
- bool removedVisibleSheet = it == windows.begin();
-
- if (it != windows.end())
- windows.erase(it);
-
- if (windows.size() == 0) {
- [controller setTab:tab isDraggable:YES];
- constrainedWindows_.erase(tab);
- } else if (removedVisibleSheet && tab == [self selectedTabView]) {
- // Show next sheet
- NSWindowController* controller = [[tab window] windowController];
- DCHECK([controller isKindOfClass:[BrowserWindowController class]]);
- windows.front()->Realize(
- static_cast<BrowserWindowController*>(controller));
- }
+ [controller setTab:[self viewAtIndex:index] isDraggable:YES];
}
}
diff --git a/chrome/browser/gtk/constrained_window_gtk.cc b/chrome/browser/gtk/constrained_window_gtk.cc
index 1f53a59..c6380d6 100644
--- a/chrome/browser/gtk/constrained_window_gtk.cc
+++ b/chrome/browser/gtk/constrained_window_gtk.cc
@@ -11,7 +11,8 @@
ConstrainedWindowGtk::ConstrainedWindowGtk(
TabContents* owner, ConstrainedWindowGtkDelegate* delegate)
: owner_(owner),
- delegate_(delegate) {
+ delegate_(delegate),
+ visible_(false) {
DCHECK(owner);
DCHECK(delegate);
GtkWidget* dialog = delegate->GetWidgetRoot();
@@ -29,20 +30,25 @@ ConstrainedWindowGtk::ConstrainedWindowGtk(
gtk_container_add(GTK_CONTAINER(frame), alignment);
gtk_container_add(GTK_CONTAINER(ebox), frame);
border_.Own(ebox);
+}
+
+ConstrainedWindowGtk::~ConstrainedWindowGtk() {
+ border_.Destroy();
+}
+void ConstrainedWindowGtk::ShowConstrainedWindow() {
gtk_widget_show_all(border_.get());
// We collaborate with TabContentsViewGtk and stick ourselves in the
// TabContentsViewGtk's floating container.
ContainingView()->AttachConstrainedWindow(this);
-}
-ConstrainedWindowGtk::~ConstrainedWindowGtk() {
- border_.Destroy();
+ visible_ = true;
}
void ConstrainedWindowGtk::CloseConstrainedWindow() {
- ContainingView()->RemoveConstrainedWindow(this);
+ if (visible_)
+ ContainingView()->RemoveConstrainedWindow(this);
delegate_->DeleteDelegate();
owner_->WillClose(this);
diff --git a/chrome/browser/gtk/constrained_window_gtk.h b/chrome/browser/gtk/constrained_window_gtk.h
index f3ad8ec..fdfedf1 100644
--- a/chrome/browser/gtk/constrained_window_gtk.h
+++ b/chrome/browser/gtk/constrained_window_gtk.h
@@ -35,6 +35,7 @@ class ConstrainedWindowGtk : public ConstrainedWindow {
virtual ~ConstrainedWindowGtk();
// Overridden from ConstrainedWindow:
+ virtual void ShowConstrainedWindow();
virtual void CloseConstrainedWindow();
// Returns the TabContents that constrains this Constrained Window.
@@ -61,6 +62,9 @@ class ConstrainedWindowGtk : public ConstrainedWindow {
// Delegate that provides the contents of this constrained window.
ConstrainedWindowGtkDelegate* delegate_;
+ // Stores if |ShowConstrainedWindow()| has been called.
+ bool visible_;
+
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowGtk);
};
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index 501ecef..762f285 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -321,6 +321,17 @@ bool TabRendererGtk::is_pinned() const {
return data_.pinned;
}
+void TabRendererGtk::SetBlocked(bool blocked) {
+ if (data_.blocked == blocked)
+ return;
+ data_.blocked = blocked;
+ // TODO(zelidrag) bug 32399: Make tabs pulse on Linux as well.
+}
+
+bool TabRendererGtk::is_blocked() const {
+ return data_.blocked;
+}
+
void TabRendererGtk::set_animating_pinned_change(bool value) {
data_.animating_pinned_change = value;
}
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
index 3114f05..0c50f12 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
@@ -104,6 +104,10 @@ class TabRendererGtk : public AnimationDelegate {
virtual void UpdateData(TabContents* contents, bool loading_only);
// Sets the pinned state of the tab.
+ void SetBlocked(bool pinned);
+ bool is_blocked() const;
+
+ // Sets the pinned state of the tab.
void set_pinned(bool pinned);
bool is_pinned() const;
@@ -235,6 +239,7 @@ class TabRendererGtk : public AnimationDelegate {
bool off_the_record;
bool show_icon;
bool pinned;
+ bool blocked;
bool animating_pinned_change;
};
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 0b5fa53..e27cdd7 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -954,6 +954,7 @@ void TabStripGtk::TabInsertedAt(TabContents* contents,
tab->UpdateData(contents, false);
}
tab->set_pinned(model_->IsTabPinned(index));
+ tab->SetBlocked(model_->IsTabBlocked(index));
if (gtk_widget_get_parent(tab->widget()) != tabstrip_.get())
gtk_fixed_put(GTK_FIXED(tabstrip_.get()), tab->widget(), 0, 0);
@@ -1009,6 +1010,7 @@ void TabStripGtk::TabMoved(TabContents* contents,
tab_data_.erase(tab_data_.begin() + from_index);
TabData data = {tab, gfx::Rect()};
tab->set_pinned(model_->IsTabPinned(to_index));
+ tab->SetBlocked(model_->IsTabBlocked(to_index));
tab_data_.insert(tab_data_.begin() + to_index, data);
if (pinned_state_changed) {
StartPinAndMoveTabAnimation(from_index, to_index, start_bounds);
@@ -1038,6 +1040,11 @@ void TabStripGtk::TabPinnedStateChanged(TabContents* contents, int index) {
StartPinnedTabAnimation(index);
}
+void TabStripGtk::TabBlockedStateChanged(TabContents* contents, int index) {
+ GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index));
+}
+
+
////////////////////////////////////////////////////////////////////////////////
// TabStripGtk, TabGtk::TabDelegate implementation:
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h
index 082f616..4533e7a 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h
@@ -107,6 +107,8 @@ class TabStripGtk : public TabStripModelObserver,
virtual void TabChangedAt(TabContents* contents, int index,
TabChangeType change_type);
virtual void TabPinnedStateChanged(TabContents* contents, int index);
+ virtual void TabBlockedStateChanged(TabContents* contents,
+ int index);
// TabGtk::TabDelegate implementation:
virtual bool IsTabSelected(const TabGtk* tab) const;
diff --git a/chrome/browser/login_prompt_gtk.cc b/chrome/browser/login_prompt_gtk.cc
index 42f705c..272bd8f 100644
--- a/chrome/browser/login_prompt_gtk.cc
+++ b/chrome/browser/login_prompt_gtk.cc
@@ -106,17 +106,20 @@ class LoginHandlerGtk : public LoginHandler,
GtkWidget* hbox = gtk_hbox_new(FALSE, 12);
gtk_box_pack_start(GTK_BOX(root_.get()), hbox, FALSE, FALSE, 0);
- GtkWidget* ok = gtk_button_new_from_stock(GTK_STOCK_OK);
+ ok_ = gtk_button_new_from_stock(GTK_STOCK_OK);
gtk_button_set_label(
- GTK_BUTTON(ok),
+ GTK_BUTTON(ok_),
l10n_util::GetStringUTF8(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL).c_str());
- g_signal_connect(ok, "clicked", G_CALLBACK(OnOKClicked), this);
- gtk_box_pack_end(GTK_BOX(hbox), ok, FALSE, FALSE, 0);
+ g_signal_connect(ok_, "clicked", G_CALLBACK(OnOKClicked), this);
+ gtk_box_pack_end(GTK_BOX(hbox), ok_, FALSE, FALSE, 0);
GtkWidget* cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
g_signal_connect(cancel, "clicked", G_CALLBACK(OnCancelClicked), this);
gtk_box_pack_end(GTK_BOX(hbox), cancel, FALSE, FALSE, 0);
+ g_signal_connect(root_.get(), "hierarchy-changed",
+ G_CALLBACK(OnPromptShown), this);
+
SetModel(manager);
// Scary thread safety note: This can potentially be called *after* SetAuth
@@ -128,8 +131,8 @@ class LoginHandlerGtk : public LoginHandler,
// Now that we have attached ourself to the window, we can make our OK
// button the default action and mess with the focus.
- GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
- gtk_widget_grab_default(ok);
+ GTK_WIDGET_SET_FLAGS(ok_, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(ok_);
gtk_widget_grab_focus(username_entry_);
SendNotifications();
@@ -305,6 +308,20 @@ class LoginHandlerGtk : public LoginHandler,
handler->CancelAuth();
}
+ static void OnPromptShown(GtkButton* root,
+ GtkWidget* previous_toplevel,
+ LoginHandlerGtk* handler) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ if (!GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(handler->ok_)))
+ return;
+
+ // Now that we have attached ourself to the window, we can make our OK
+ // button the default action and mess with the focus.
+ GTK_WIDGET_SET_FLAGS(handler->ok_, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(handler->ok_);
+ gtk_widget_grab_focus(handler->username_entry_);
+}
+
// True if we've handled auth (SetAuth or CancelAuth has been called).
bool handled_auth_;
Lock handled_auth_lock_;
@@ -339,6 +356,7 @@ class LoginHandlerGtk : public LoginHandler,
// GtkEntry widgets that the user types into.
GtkWidget* username_entry_;
GtkWidget* password_entry_;
+ GtkWidget* ok_;
// If not null, points to a model we need to notify of our own destruction
// so it doesn't try and access this when its too late.
diff --git a/chrome/browser/login_prompt_win.cc b/chrome/browser/login_prompt_win.cc
index 72d4658..500c414 100644
--- a/chrome/browser/login_prompt_win.cc
+++ b/chrome/browser/login_prompt_win.cc
@@ -7,6 +7,8 @@
#include "app/l10n_util.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/password_manager/password_manager.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -62,6 +64,9 @@ class LoginHandlerWin : public LoginHandler,
virtual void WindowClosing() {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ GetTabContentsForLogin()->
+ render_view_host()->set_ignore_input_events(false);
+
// Reference is no longer valid.
dialog_ = NULL;
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 842e7b4..9a6c128 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -1664,6 +1664,11 @@ void RenderViewHost::ForwardMouseEvent(
case WebInputEvent::MouseLeave:
view->HandleMouseLeave();
break;
+ case WebInputEvent::MouseDown:
+ case WebInputEvent::MouseWheel:
+ if (ignore_input_events() && delegate_)
+ delegate_->OnIgnoredUIEvent();
+ break;
default:
// For now, we don't care about the rest.
break;
@@ -1671,6 +1676,16 @@ void RenderViewHost::ForwardMouseEvent(
}
}
+void RenderViewHost::ForwardKeyboardEvent(
+ const NativeWebKeyboardEvent& key_event) {
+ if (ignore_input_events()) {
+ if (key_event.type == WebInputEvent::RawKeyDown && delegate_)
+ delegate_->OnIgnoredUIEvent();
+ return;
+ }
+ RenderWidgetHost::ForwardKeyboardEvent(key_event);
+}
+
void RenderViewHost::ForwardEditCommand(const std::string& name,
const std::string& value) {
IPC::Message* message = new ViewMsg_ExecuteEditCommand(routing_id(),
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 831bd80..8dcec74 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -415,6 +415,7 @@ class RenderViewHost : public RenderWidgetHost,
virtual void GotFocus();
virtual bool CanBlur() const;
virtual void ForwardMouseEvent(const WebKit::WebMouseEvent& mouse_event);
+ virtual void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event);
virtual void ForwardEditCommand(const std::string& name,
const std::string& value);
virtual void ForwardEditCommandsForNextKeyEvent(
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index c3df62d..411840a 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -537,6 +537,12 @@ class RenderViewHostDelegate {
// associated with the owning render view host.
virtual WebPreferences GetWebkitPrefs();
+ // Notification from the renderer host that blocked UI event occurred.
+ // This happens when there are tab-modal dialogs. In this case, the
+ // notification is needed to let us draw attention to the dialog (i.e.
+ // refocus on the modal dialog, flash title etc).
+ virtual void OnIgnoredUIEvent() {}
+
// Notification from the renderer that JS runs out of memory.
virtual void OnJSOutOfMemory() {}
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 4798516..a721231 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -70,6 +70,7 @@ RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process,
is_unresponsive_(false),
in_get_backing_store_(false),
view_being_painted_(false),
+ ignore_input_events_(false),
text_direction_updated_(false),
text_direction_(WebKit::WebTextDirectionLeftToRight),
text_direction_canceled_(false),
@@ -351,7 +352,7 @@ void RenderWidgetHost::SystemThemeChanged() {
}
void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) {
- if (process_->ignore_input_events())
+ if (ignore_input_events_ || process_->ignore_input_events())
return;
// Avoid spamming the renderer with mouse move events. It is important
@@ -373,7 +374,7 @@ void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) {
void RenderWidgetHost::ForwardWheelEvent(
const WebMouseWheelEvent& wheel_event) {
- if (process_->ignore_input_events())
+ if (ignore_input_events_ || process_->ignore_input_events())
return;
ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent), false);
@@ -381,7 +382,7 @@ void RenderWidgetHost::ForwardWheelEvent(
void RenderWidgetHost::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) {
- if (process_->ignore_input_events())
+ if (ignore_input_events_ || process_->ignore_input_events())
return;
if (key_event.type == WebKeyboardEvent::Char &&
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index ddda002..1291f72 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -248,7 +248,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// when it has received a message.
virtual void ForwardMouseEvent(const WebKit::WebMouseEvent& mouse_event);
void ForwardWheelEvent(const WebKit::WebMouseWheelEvent& wheel_event);
- void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event);
+ virtual void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event);
virtual void ForwardEditCommand(const std::string& name,
const std::string& value);
virtual void ForwardEditCommandsForNextKeyEvent(
@@ -348,6 +348,13 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// Sets the active state (i.e., control tints).
virtual void SetActive(bool active);
+ void set_ignore_input_events(bool ignore_input_events) {
+ ignore_input_events_ = ignore_input_events;
+ }
+ bool ignore_input_events() const {
+ return ignore_input_events_;
+ }
+
protected:
// Internal implementation of the public Forward*Event() methods.
void ForwardInputEvent(const WebKit::WebInputEvent& input_event,
@@ -551,6 +558,9 @@ class RenderWidgetHost : public IPC::Channel::Listener,
// back to whatever unhandled handler instead of the returned version.
KeyQueue key_queue_;
+ // Set to true if we shouldn't send input events from the render widget.
+ bool ignore_input_events_;
+
// Set when we update the text direction of the selected input element.
bool text_direction_updated_;
WebKit::WebTextDirection text_direction_;
diff --git a/chrome/browser/tab_contents/constrained_window.h b/chrome/browser/tab_contents/constrained_window.h
index 057ee27..0eaec2a 100644
--- a/chrome/browser/tab_contents/constrained_window.h
+++ b/chrome/browser/tab_contents/constrained_window.h
@@ -39,8 +39,15 @@ class ConstrainedWindow {
TabContents* owner,
ConstrainedWindowDelegate* delegate);
+ // Makes the Constrained Window visible. Only one Constrained Window is shown
+ // at a time per tab.
+ virtual void ShowConstrainedWindow() = 0;
+
// Closes the Constrained Window.
virtual void CloseConstrainedWindow() = 0;
+
+ // Sets focus on the Constrained Window.
+ virtual void FocusConstrainedWindow() {}
};
#endif // CHROME_BROWSER_TAB_CONTENTS_CONSTRAINED_WINDOW_H_
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 097cb37..fdfa5ab 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -331,8 +331,10 @@ TabContents::~TabContents() {
int size = static_cast<int>(child_windows_.size());
for (int i = size - 1; i >= 0; --i) {
ConstrainedWindow* window = child_windows_[i];
- if (window)
+ if (window) {
window->CloseConstrainedWindow();
+ BlockTabContent(false);
+ }
}
if (blocked_popups_)
@@ -767,9 +769,21 @@ ConstrainedWindow* TabContents::CreateConstrainedDialog(
ConstrainedWindow* window =
ConstrainedWindow::CreateConstrainedDialog(this, delegate);
child_windows_.push_back(window);
+
+ if (child_windows_.size() == 1) {
+ window->ShowConstrainedWindow();
+ BlockTabContent(true);
+ }
+
return window;
}
+void TabContents::BlockTabContent(bool blocked) {
+ render_view_host()->set_ignore_input_events(blocked);
+ if (delegate_)
+ delegate_->SetTabContentBlocked(this, blocked);
+}
+
void TabContents::AddNewContents(TabContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
@@ -1003,8 +1017,15 @@ void TabContents::OnStartDownload(DownloadItem* download) {
void TabContents::WillClose(ConstrainedWindow* window) {
ConstrainedWindowList::iterator it =
find(child_windows_.begin(), child_windows_.end(), window);
+ bool removed_topmost_window = it == child_windows_.begin();
if (it != child_windows_.end())
child_windows_.erase(it);
+ if (removed_topmost_window && child_windows_.size() > 0) {
+ child_windows_[0]->ShowConstrainedWindow();
+ BlockTabContent(true);
+ } else {
+ BlockTabContent(false);
+ }
}
void TabContents::WillCloseBlockedPopupContainer(
@@ -1404,8 +1425,11 @@ void TabContents::MaybeCloseChildWindows(const GURL& previous_url,
int size = static_cast<int>(child_windows_.size());
for (int i = size - 1; i >= 0; --i) {
ConstrainedWindow* window = child_windows_[i];
- if (window)
+ if (window) {
+ DCHECK(delegate_);
window->CloseConstrainedWindow();
+ BlockTabContent(false);
+ }
}
// Close the popup container.
@@ -2406,6 +2430,13 @@ WebPreferences TabContents::GetWebkitPrefs() {
return RenderViewHostDelegateHelper::GetWebkitPrefs(prefs, is_dom_ui);
}
+void TabContents::OnIgnoredUIEvent() {
+ if (constrained_window_count()) {
+ ConstrainedWindow* window = *constrained_window_begin();
+ window->FocusConstrainedWindow();
+ }
+}
+
void TabContents::OnJSOutOfMemory() {
AddInfoBar(new SimpleAlertInfoBarDelegate(
this, l10n_util::GetString(IDS_JS_OUT_OF_MEMORY_PROMPT), NULL));
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 112675d..de1e3ab 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -7,6 +7,7 @@
#include "build/build_config.h"
+#include <deque>
#include <map>
#include <set>
#include <string>
@@ -348,9 +349,8 @@ class TabContents : public PageNavigator,
// Create a new window constrained to this TabContents' clip and visibility.
// The window is initialized by using the supplied delegate to obtain basic
- // window characteristics, and the supplied view for the content. The window
- // is sized according to the preferred size of the content_view, and centered
- // within the contents.
+ // window characteristics, and the supplied view for the content. Note that
+ // the returned ConstrainedWindow might not yet be visible.
ConstrainedWindow* CreateConstrainedDialog(
ConstrainedWindowDelegate* delegate);
@@ -379,7 +379,7 @@ class TabContents : public PageNavigator,
// Returns the number of constrained windows in this tab. Used by tests.
size_t constrained_window_count() { return child_windows_.size(); }
- typedef std::vector<ConstrainedWindow*> ConstrainedWindowList;
+ typedef std::deque<ConstrainedWindow*> ConstrainedWindowList;
// Return an iterator for the first constrained window in this tab contents.
ConstrainedWindowList::iterator constrained_window_begin()
@@ -912,6 +912,7 @@ class TabContents : public PageNavigator,
virtual GURL GetAlternateErrorPageURL() const;
virtual RendererPreferences GetRendererPrefs(Profile* profile) const;
virtual WebPreferences GetWebkitPrefs();
+ virtual void OnIgnoredUIEvent();
virtual void OnJSOutOfMemory();
virtual void OnCrossSiteResponse(int new_render_process_host_id,
int new_request_id);
@@ -935,6 +936,9 @@ class TabContents : public PageNavigator,
// RenderViewHostManager::Delegate -------------------------------------------
+ // Blocks/unblocks interaction with renderer process.
+ void BlockTabContent(bool blocked);
+
virtual void BeforeUnloadFiredFromRenderManager(
bool proceed,
bool* proceed_to_fire_unload);
diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h
index 817bd25..9cdd2cc 100644
--- a/chrome/browser/tab_contents/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents/tab_contents_delegate.h
@@ -183,6 +183,12 @@ class TabContentsDelegate {
return false;
}
+ // Changes the blocked state of the tab at |index|. TabContents are
+ // considered blocked while displaying a tab modal dialog. During that time
+ // renderer host will ignore any UI interaction within TabContent outside of
+ // the currently displaying dialog.
+ virtual void SetTabContentBlocked(TabContents* contents, bool blocked) { }
+
// Notification that |tab_contents| has gained focus.
virtual void TabContentsFocused(TabContents* tab_content) { }
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index 2c94b7d..a085ced 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -112,7 +112,8 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
: TabContentsView(tab_contents),
floating_(gtk_floating_container_new()),
expanded_(gtk_expanded_container_new()),
- popup_view_(NULL) {
+ popup_view_(NULL),
+ constrained_window_(NULL) {
gtk_widget_set_name(expanded_, "chrome-tab-contents-view");
g_signal_connect(expanded_, "size-allocate",
G_CALLBACK(OnSizeAllocate), this);
@@ -150,24 +151,20 @@ void TabContentsViewGtk::RemoveBlockedPopupView(
void TabContentsViewGtk::AttachConstrainedWindow(
ConstrainedWindowGtk* constrained_window) {
- DCHECK(find(constrained_windows_.begin(), constrained_windows_.end(),
- constrained_window) == constrained_windows_.end());
+ DCHECK(constrained_window_ == NULL);
- constrained_windows_.push_back(constrained_window);
+ constrained_window_ = constrained_window;
gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
constrained_window->widget());
}
void TabContentsViewGtk::RemoveConstrainedWindow(
ConstrainedWindowGtk* constrained_window) {
- std::vector<ConstrainedWindowGtk*>::iterator item =
- find(constrained_windows_.begin(), constrained_windows_.end(),
- constrained_window);
- DCHECK(item != constrained_windows_.end());
+ DCHECK(constrained_window == constrained_window_);
+ constrained_window_ = NULL;
gtk_container_remove(GTK_CONTAINER(floating_.get()),
constrained_window->widget());
- constrained_windows_.erase(item);
}
void TabContentsViewGtk::CreateView(const gfx::Size& initial_size) {
@@ -422,12 +419,8 @@ void TabContentsViewGtk::OnSetFloatingPosition(
// Place each ConstrainedWindow in the center of the view.
int half_view_width = std::max((allocation->x + allocation->width) / 2, 0);
int half_view_height = std::max((allocation->y + allocation->height) / 2, 0);
- std::vector<ConstrainedWindowGtk*>::iterator it =
- tab_contents_view->constrained_windows_.begin();
- std::vector<ConstrainedWindowGtk*>::iterator end =
- tab_contents_view->constrained_windows_.end();
- for (; it != end; ++it) {
- GtkWidget* widget = (*it)->widget();
+ if (tab_contents_view->constrained_window_) {
+ GtkWidget* widget = tab_contents_view->constrained_window_->widget();
DCHECK(widget->parent == tab_contents_view->floating_.get());
GtkRequisition requisition;
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 5b1d820..0c84e1e 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -7,8 +7,6 @@
#include <gtk/gtk.h>
-#include <vector>
-
#include "base/scoped_ptr.h"
#include "chrome/browser/gtk/focus_store_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
@@ -133,9 +131,9 @@ class TabContentsViewGtk : public TabContentsView,
// opened). |popup_view_| is owned by the TabContents, not the view.
BlockedPopupContainerViewGtk* popup_view_;
- // Each individual UI for constrained dialogs currently displayed. The
- // objects in this vector are owned by the TabContents, not the view.
- std::vector<ConstrainedWindowGtk*> constrained_windows_;
+ // The UI for the constrained dialog currently displayed. This is owned by
+ // TabContents, not the view.
+ ConstrainedWindowGtk* constrained_window_;
// The helper object that handles drag destination related interactions with
// GTK.
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc
index 783e27c..56ec106 100644
--- a/chrome/browser/tabs/tab_strip_model.cc
+++ b/chrome/browser/tabs/tab_strip_model.cc
@@ -342,6 +342,16 @@ bool TabStripModel::ShouldResetGroupOnSelect(TabContents* contents) const {
return contents_data_.at(index)->reset_group_on_select;
}
+void TabStripModel::SetTabBlocked(int index, bool blocked) {
+ DCHECK(ContainsIndex(index));
+ if (contents_data_[index]->blocked == blocked)
+ return;
+ contents_data_[index]->blocked = blocked;
+ FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
+ TabBlockedStateChanged(contents_data_[index]->contents,
+ index));
+}
+
void TabStripModel::SetTabPinned(int index, bool pinned) {
DCHECK(ContainsIndex(index));
if (contents_data_[index]->pinned == pinned)
@@ -373,6 +383,10 @@ bool TabStripModel::IsTabPinned(int index) const {
return contents_data_[index]->pinned;
}
+bool TabStripModel::IsTabBlocked(int index) const {
+ return contents_data_[index]->blocked;
+}
+
int TabStripModel::IndexOfFirstNonPinnedTab() const {
for (size_t i = 0; i < contents_data_.size(); ++i) {
if (!contents_data_[i]->pinned)
diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h
index fe94524..bdd92c3 100644
--- a/chrome/browser/tabs/tab_strip_model.h
+++ b/chrome/browser/tabs/tab_strip_model.h
@@ -105,6 +105,11 @@ class TabStripModelObserver {
// notified by way of the TabMoved method with |pinned_state_changed| true.
virtual void TabPinnedStateChanged(TabContents* contents, int index) { }
+ // Invoked when the blocked state of a tab changes.
+ // NOTE: This is invoked when a tab becomes blocked/unblocked by a tab modal
+ // window.
+ virtual void TabBlockedStateChanged(TabContents* contents, int index) { }
+
// The TabStripModel now no longer has any "significant" (user created or
// user manipulated) tabs. The implementer may use this as a trigger to try
// and close the window containing the TabStripModel, for example...
@@ -419,6 +424,9 @@ class TabStripModel : public NotificationObserver {
// should be reset when _any_ selection change occurs in the model.
bool ShouldResetGroupOnSelect(TabContents* contents) const;
+ // Changes the blocked state of the tab at |index|.
+ void SetTabBlocked(int index, bool blocked);
+
// Changes the pinned state of the tab at |index|. See description above
// class for details on this.
void SetTabPinned(int index, bool pinned);
@@ -426,6 +434,9 @@ class TabStripModel : public NotificationObserver {
// Returns true if the tab at |index| is pinned.
bool IsTabPinned(int index) const;
+ // Returns true if the tab at |index| is blocked by a tab modal dialog.
+ bool IsTabBlocked(int index) const;
+
// Returns the index of the first tab that is not pinned. This returns
// |count()| if all of the tabs are pinned, and 0 if no tabs are pinned.
int IndexOfFirstNonPinnedTab() const;
@@ -568,7 +579,8 @@ class TabStripModel : public NotificationObserver {
explicit TabContentsData(TabContents* a_contents)
: contents(a_contents),
reset_group_on_select(false),
- pinned(false) {
+ pinned(false),
+ blocked(false) {
SetGroup(NULL);
}
@@ -612,6 +624,9 @@ class TabStripModel : public NotificationObserver {
// Is the tab pinned?
bool pinned;
+
+ // Is the tab interaction blocked by a modal dialog?
+ bool blocked;
};
// The TabContents data currently hosted within this TabStripModel.
diff --git a/chrome/browser/views/constrained_window_win.cc b/chrome/browser/views/constrained_window_win.cc
index c94576e..e0ff52e 100644
--- a/chrome/browser/views/constrained_window_win.cc
+++ b/chrome/browser/views/constrained_window_win.cc
@@ -592,6 +592,16 @@ views::NonClientFrameView* ConstrainedWindowWin::CreateFrameViewForWindow() {
return new ConstrainedWindowFrameView(this);
}
+void ConstrainedWindowWin::FocusConstrainedWindow() {
+ focused_view_->RequestFocus();
+}
+
+void ConstrainedWindowWin::ShowConstrainedWindow() {
+ ActivateConstrainedWindow();
+ FocusConstrainedWindow();
+}
+
+
void ConstrainedWindowWin::CloseConstrainedWindow() {
// Broadcast to all observers of NOTIFY_CWINDOW_CLOSED.
// One example of such an observer is AutomationCWindowTracker in the
@@ -632,7 +642,9 @@ ConstrainedWindowWin::ConstrainedWindowWin(
set_focus_on_creation(false);
WindowWin::Init(owner_->GetNativeView(), gfx::Rect());
- ActivateConstrainedWindow();
+
+ focused_view_ = window_delegate->GetContentsView();
+ DCHECK(focused_view_);
}
void ConstrainedWindowWin::ActivateConstrainedWindow() {
diff --git a/chrome/browser/views/constrained_window_win.h b/chrome/browser/views/constrained_window_win.h
index d51dc8e..d5e3022 100644
--- a/chrome/browser/views/constrained_window_win.h
+++ b/chrome/browser/views/constrained_window_win.h
@@ -35,7 +35,9 @@ class ConstrainedWindowWin : public ConstrainedWindow,
virtual views::NonClientFrameView* CreateFrameViewForWindow();
// Overridden from ConstrainedWindow:
+ virtual void ShowConstrainedWindow();
virtual void CloseConstrainedWindow();
+ virtual void FocusConstrainedWindow();
virtual std::wstring GetWindowTitle() const;
virtual const gfx::Rect& GetCurrentBounds() const;
@@ -68,6 +70,7 @@ class ConstrainedWindowWin : public ConstrainedWindow,
// Current display rectangle (relative to owner_'s visible area).
gfx::Rect current_bounds_;
+ views::View* focused_view_;
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowWin);
};
diff --git a/chrome/browser/views/login_view.cc b/chrome/browser/views/login_view.cc
index 1682965..8564c2d 100644
--- a/chrome/browser/views/login_view.cc
+++ b/chrome/browser/views/login_view.cc
@@ -97,6 +97,12 @@ void LoginView::SetModel(LoginModel* model) {
if (login_model_)
login_model_->SetObserver(this);
}
+
+void LoginView::RequestFocus() {
+ MessageLoop::current()->PostTask(FROM_HERE,
+ focus_grabber_factory_.NewRunnableMethod(&LoginView::FocusFirstField));
+}
+
///////////////////////////////////////////////////////////////////////////////
// LoginView, views::View, views::LoginModelObserver overrides:
diff --git a/chrome/browser/views/login_view.h b/chrome/browser/views/login_view.h
index 330ff32..01b1b7c 100644
--- a/chrome/browser/views/login_view.h
+++ b/chrome/browser/views/login_view.h
@@ -36,6 +36,8 @@ class LoginView : public views::View, public LoginModelObserver {
// of the caller to inform this view if the model is deleted.
void SetModel(LoginModel* model);
+ virtual void RequestFocus();
+
protected:
// views::View overrides:
virtual void ViewHierarchyChanged(bool is_add, views::View *parent,
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index 8d5a4a3..8f6018c 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -893,3 +893,14 @@ void TabRenderer::LoadTabImages() {
loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
}
+
+void TabRenderer::SetBlocked(bool blocked) {
+ if (data_.blocked == blocked)
+ return;
+ data_.blocked = blocked;
+ if (blocked)
+ StartPulse();
+ else
+ StopPulse();
+}
+
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index bf71dfc..4cecfbe 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -48,6 +48,10 @@ class TabRenderer : public views::View,
void UpdateData(TabContents* contents, bool loading_only);
// Sets the pinned state of the tab.
+ void SetBlocked(bool blocked);
+ bool blocked() const { return data_.blocked; }
+
+ // Sets the pinned state of the tab.
void set_pinned(bool pinned) { data_.pinned = pinned; }
bool pinned() const { return data_.pinned; }
@@ -201,6 +205,7 @@ class TabRenderer : public views::View,
bool off_the_record;
bool show_icon;
bool pinned;
+ bool blocked;
bool animating_pinned_change;
};
TabData data_;
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index e8838a7..248506a 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -1110,6 +1110,7 @@ void TabStrip::TabInsertedAt(TabContents* contents,
tab->UpdateData(contents, false);
}
tab->set_pinned(model_->IsTabPinned(index));
+ tab->SetBlocked(model_->IsTabBlocked(index));
// We only add the tab to the child list if it's not already - an invisible
// tab maintained by the DraggedTabController will already be parented.
@@ -1160,6 +1161,7 @@ void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index,
tab_data_.erase(tab_data_.begin() + from_index);
TabData data = {tab, gfx::Rect()};
tab->set_pinned(model_->IsTabPinned(to_index));
+ tab->SetBlocked(model_->IsTabBlocked(to_index));
tab_data_.insert(tab_data_.begin() + to_index, data);
if (pinned_state_changed) {
StartPinAndMoveTabAnimation(from_index, to_index, start_bounds);
@@ -1189,6 +1191,10 @@ void TabStrip::TabPinnedStateChanged(TabContents* contents, int index) {
StartPinnedTabAnimation(index);
}
+void TabStrip::TabBlockedStateChanged(TabContents* contents, int index) {
+ GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index));
+}
+
///////////////////////////////////////////////////////////////////////////////
// TabStrip, Tab::Delegate implementation:
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index 8ef00c07..9ecece6 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -136,6 +136,7 @@ class TabStrip : public views::View,
virtual void TabChangedAt(TabContents* contents, int index,
TabChangeType change_type);
virtual void TabPinnedStateChanged(TabContents* contents, int index);
+ virtual void TabBlockedStateChanged(TabContents* contents, int index);
// Tab::Delegate implementation:
virtual bool IsTabSelected(const Tab* tab) const;
diff --git a/views/view.cc b/views/view.cc
index 566de01..9c5ab42 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -697,7 +697,7 @@ void View::ViewHierarchyChangedImpl(bool register_accelerators,
}
} else {
if (child == this)
- UnregisterAccelerators(false);
+ UnregisterAccelerators(true);
}
}