diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 18:44:21 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 18:44:21 +0000 |
commit | 22eeb168b8bfd02c8a4a9521a819067e25674b95 (patch) | |
tree | 7301665e67526024260e52478ebebde760f1ec1f /chrome | |
parent | d37fe632a386d29653f91564677186ff7403d8dc (diff) | |
download | chromium_src-22eeb168b8bfd02c8a4a9521a819067e25674b95.zip chromium_src-22eeb168b8bfd02c8a4a9521a819067e25674b95.tar.gz chromium_src-22eeb168b8bfd02c8a4a9521a819067e25674b95.tar.bz2 |
Mac: Only show one per-tab sheet at a time per tab.
BUG=26900
TEST=Go to http://www/~thakis/cgi-bin/test.html . Test that two sheets show up (the first expects "u" as user and no pass, the other "v" and no pass). The first sheet appears immediately, the second after 2 seconds. Try entering u for the first faster than 2 seconds and switch tabs, when coming back to the original tab, the 2nd sheet should wait for you. Try closing the window and the tab while a sheet is showing, both when the tab with the sheet is in the background and in the foreground.
Review URL: http://codereview.chromium.org/384113
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31920 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.h | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 4 | ||||
-rw-r--r-- | chrome/browser/cocoa/constrained_window_mac.h | 5 | ||||
-rw-r--r-- | chrome/browser/cocoa/constrained_window_mac.mm | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.h | 13 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 51 |
6 files changed, 79 insertions, 14 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index 849ba04..7156778 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -160,7 +160,15 @@ class TabStripModelObserverBridge; // for the per-tab sheets. - (GTMWindowSheetController*)sheetController; -- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window; +// 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; + +// Closes the tab sheet |window| and potentially shows the next sheet in the +// tab's sheet queue. - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window; // Delegate method called when window is resized. diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index b3cc20c..65d0475 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -266,8 +266,8 @@ willPositionSheet:(NSWindow*)sheet afterDelay:0]; } -- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { - [tabStripController_ attachConstrainedWindow:window]; +- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window { + return [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 612b459..83331c7 100644 --- a/chrome/browser/cocoa/constrained_window_mac.h +++ b/chrome/browser/cocoa/constrained_window_mac.h @@ -125,9 +125,12 @@ class ConstrainedWindowMac : public ConstrainedWindow { // Returns the window's delegate. ConstrainedWindowMacDelegate* delegate() { return delegate_; } - // Makes the constrained window visible, if it is not yet visible. + // Tells |controller_| that the sheet would like to be displayed. void Realize(BrowserWindowController* controller); + // Called by |controller_| to inform the sheet that it now is visible. + void SetVisible(); + private: friend class ConstrainedWindow; diff --git a/chrome/browser/cocoa/constrained_window_mac.mm b/chrome/browser/cocoa/constrained_window_mac.mm index ed5cba0..ad090a8 100644 --- a/chrome/browser/cocoa/constrained_window_mac.mm +++ b/chrome/browser/cocoa/constrained_window_mac.mm @@ -82,7 +82,13 @@ void ConstrainedWindowMac::Realize(BrowserWindowController* controller) { // Remember the controller we're adding ourselves to, so that we can later // remove us from it. - controller_ = controller; - [controller_ attachConstrainedWindow:this]; + 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). delegate_->set_sheet_open(true); } diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h index 0ee2fc4..fae7831 100644 --- a/chrome/browser/cocoa/tab_strip_controller.h +++ b/chrome/browser/cocoa/tab_strip_controller.h @@ -7,6 +7,9 @@ #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" @@ -96,6 +99,12 @@ class ToolbarModel; // Manages per-tab sheets. scoped_nsobject<GTMWindowSheetController> sheetController_; + + // 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 @@ -169,7 +178,9 @@ class ToolbarModel; // for the per-tab sheets. - (GTMWindowSheetController*)sheetController; -- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window; +// See comments in browser_window_controller.h for documentation about these +// functions. +- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window; - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window; @end diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index dfc70a7..a971808 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -370,11 +370,13 @@ 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]]); - for (it = newTab->constrained_window_begin(); it != end; ++it) { + // GTMWindowSheetController supports only one sheet at a time. + if (it != end) { + NSWindowController* controller = [[newView window] windowController]; + DCHECK([controller isKindOfClass:[BrowserWindowController class]]); ConstrainedWindow* constrainedWindow = *it; static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( static_cast<BrowserWindowController*>(controller)); @@ -1292,7 +1294,7 @@ private: tabModel_->SelectTabContentsAt(index, false /* not a user gesture */); } -- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { +- (BOOL)attachConstrainedWindow:(ConstrainedWindowMac*)window { // TODO(thakis, avi): Figure out how to make this work when tabs are dragged // out or if fullscreen mode is toggled. @@ -1305,7 +1307,6 @@ 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 @@ -1317,8 +1318,23 @@ private: DCHECK(controller != nil); DCHECK(index >= 0); if (index >= 0) { - [controller setTab:[self viewAtIndex:index] isDraggable:NO]; + 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; + } } + return NO; } - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window { @@ -1334,7 +1350,28 @@ private: (BrowserWindowController*)[[switchView_ window] windowController]; DCHECK(index >= 0); if (index >= 0) { - [controller setTab:[self viewAtIndex:index] isDraggable:YES]; + 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)); + } } } |