summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/tab_view.mm
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 22:03:17 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 22:03:17 +0000
commita9e8afc41dd0adfe4ac5900f2b73ff259276e2bd (patch)
tree7c82250d47888a4057e3048bfc7f54c07027fdb2 /chrome/browser/cocoa/tab_view.mm
parente819b55cf062822a23280b4da7760abfd2a86e64 (diff)
downloadchromium_src-a9e8afc41dd0adfe4ac5900f2b73ff259276e2bd.zip
chromium_src-a9e8afc41dd0adfe4ac5900f2b73ff259276e2bd.tar.gz
chromium_src-a9e8afc41dd0adfe4ac5900f2b73ff259276e2bd.tar.bz2
Add support for constrained windows on os x, based on Avi's GTMWindowSheetController. Add carpet bombing dialog as first per-tab sheet.
Depends http://codereview.appspot.com/105064 . The main issue with this patch is that GTMWindowSheetController doesn't provide an api to move sheets between windows, so this CL disables tab dragging for tabs with sheets, and fullscreen mode for windows with sheets. We can fix this later. Other stuff that should be done at some point, but not now: * Open/Save panels should be per-tab * Need an ui test that goes to page, then page with sheet, then hit back, forward, reload. * Bookmark sheets should not be sheets but in a separate window BUG=14666 TEST=Go to skypher.com/SkyLined/Repro/Chrome/carpet bombing/repro.html , a per-window sheet should appear. Things to test with this dialog: * Hitting cmd-q while a sheet is open in any tab should not quit but instead focus the sheet. * Hitting cmd-w while a sheet is open in any tab should not close the window but instead focus the sheet. * Dragging a tab with a sheet should move the window (and keep the tab visible), not detach the tab. * Going fullscreen should be disabled for windows with open tabs. * When a per-tab sheet is open in a non-active tab, it shouldn't steal the focus, i.e. going to the page above, then hitting cmd-t, and then hitting cmd-l should work. * Closing a non-frontmost tab with a per-tab sheet shouldn't crash. * Going to the url above and quickly opening a new tab, so that the sheet opens while its tab is not front-most should work (sheet should display only when you switch back to the tab with the sheet). * Go to google.com, then to skypher.com/SkyLined/Repro/Chrome/carpet bombing/repro.html , hit "backward" with open sheet, hit forward, focus location bar, hit enter. This shouldn't crash. * Hitting escape should dismiss the sheet * Hitting enter should confirm the sheet. Review URL: http://codereview.chromium.org/159780 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23091 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/tab_view.mm')
-rw-r--r--chrome/browser/cocoa/tab_view.mm54
1 files changed, 37 insertions, 17 deletions
diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm
index 4036b18..c5bc791 100644
--- a/chrome/browser/cocoa/tab_view.mm
+++ b/chrome/browser/cocoa/tab_view.mm
@@ -86,6 +86,17 @@ static const CGFloat kControlPoint2Multiplier = 3.0/8.0;
return nil;
}
+// Returns |YES| if this tab can be torn away into a new window.
+- (BOOL)canBeDragged {
+ NSWindowController *controller = [sourceWindow_ windowController];
+ if ([controller isKindOfClass:[TabWindowController class]]) {
+ TabWindowController* realController =
+ static_cast<TabWindowController*>(controller);
+ return [realController isTabDraggable:self];
+ }
+ return YES;
+}
+
// Handle clicks and drags in this button. We get here because we have
// overridden acceptsFirstMouse: and the click is within our bounds.
// TODO(pinkerton/alcor): This routine needs *a lot* of work to marry Cole's
@@ -124,7 +135,8 @@ static const double kDragStartDistance = 3.0;
// unit tests might have |-numberOfTabs| reporting zero since the model
// won't be fully hooked up. We need to be prepared for that and not send
// them into the "magnetic" codepath.
- isTheOnlyTab_ = [sourceController_ numberOfTabs] <= 1;
+ moveWindowOnDrag_ =
+ [sourceController_ numberOfTabs] <= 1 || ![self canBeDragged];
dragOrigin_ = [NSEvent mouseLocation];
@@ -148,11 +160,20 @@ static const double kDragStartDistance = 3.0;
}
- (void)mouseDragged:(NSEvent *)theEvent {
+ // Special-case this to keep the logic below simpler.
+ if (moveWindowOnDrag_) {
+ NSPoint thisPoint = [NSEvent mouseLocation];
+ NSPoint origin = sourceWindowFrame_.origin;
+ origin.x += (thisPoint.x - dragOrigin_.x);
+ origin.y += (thisPoint.y - dragOrigin_.y);
+ [sourceWindow_ setFrameOrigin:NSMakePoint(origin.x, origin.y)];
+ return;
+ }
+
// First, go through the magnetic drag cycle. We break out of this if
- // "stretchiness" ever exceeds the a set amount.
+ // "stretchiness" ever exceeds a set amount.
tabWasDragged_ = YES;
- if (isTheOnlyTab_) draggingWithinTabStrip_ = NO;
if (draggingWithinTabStrip_) {
NSRect frame = [self frame];
NSPoint thisPoint = [NSEvent mouseLocation];
@@ -190,7 +211,6 @@ static const double kDragStartDistance = 3.0;
// appropriate class, and visible (obviously).
if (![targets count]) {
for (NSWindow* window in [NSApp windows]) {
- if (window == sourceWindow_ && isTheOnlyTab_) continue;
if (window == dragWindow_) continue;
if (![window isVisible]) continue;
NSWindowController *controller = [window windowController];
@@ -235,16 +255,13 @@ static const double kDragStartDistance = 3.0;
// Create or identify the dragged controller.
if (!draggedController_) {
- if (isTheOnlyTab_) {
- draggedController_ = sourceController_;
- dragWindow_ = [draggedController_ window];
- } else {
- // Detach from the current window and put it in a new window.
- draggedController_ = [sourceController_ detachTabToNewWindow:self];
- dragWindow_ = [draggedController_ window];
- [dragWindow_ setAlphaValue:0.0];
- }
+ // Detach from the current window and put it in a new window.
+ draggedController_ = [sourceController_ detachTabToNewWindow:self];
+ dragWindow_ = [draggedController_ window];
+ [dragWindow_ setAlphaValue:0.0];
+ // If dragging the tab only moves the current window, do not show overlay
+ // so that sheets stay on top of the window.
// Bring the target window to the front and make sure it has a border.
[dragWindow_ setLevel:NSFloatingWindowLevel];
[dragWindow_ orderFront:nil];
@@ -255,10 +272,8 @@ static const double kDragStartDistance = 3.0;
[draggedController_ showNewTabButton:NO];
//if (![targets count])
// [dragOverlay_ setHasShadow:NO];
- if (!isTheOnlyTab_) {
- tearTime_ = [NSDate timeIntervalSinceReferenceDate];
- tearOrigin_ = sourceWindowFrame_.origin;
- }
+ tearTime_ = [NSDate timeIntervalSinceReferenceDate];
+ tearOrigin_ = sourceWindowFrame_.origin;
}
float tearProgress = [NSDate timeIntervalSinceReferenceDate] - tearTime_;
@@ -348,6 +363,10 @@ static const double kDragStartDistance = 3.0;
// The drag/click is done. If the user dragged the mouse, finalize the drag
// and clean up.
+ // Special-case this to keep the logic below simpler.
+ if (moveWindowOnDrag_)
+ return;
+
// We are now free to re-display the new tab button in the window we're
// dragging. It will show when the next call to -layoutTabs (which happens
// indrectly by several of the calls below, such as removing the placeholder).
@@ -369,6 +388,7 @@ static const double kDragStartDistance = 3.0;
fromController:draggedController_];
[targetController_ showWindow:nil];
} else {
+ // Tab dragging did move window only.
[dragWindow_ setAlphaValue:1.0];
[dragOverlay_ setHasShadow:NO];
[dragWindow_ setHasShadow:YES];