summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-13 18:44:21 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-13 18:44:21 +0000
commit22eeb168b8bfd02c8a4a9521a819067e25674b95 (patch)
tree7301665e67526024260e52478ebebde760f1ec1f /chrome
parentd37fe632a386d29653f91564677186ff7403d8dc (diff)
downloadchromium_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.h10
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm4
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.h5
-rw-r--r--chrome/browser/cocoa/constrained_window_mac.mm10
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h13
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm51
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));
+ }
}
}