Commit 11699976 authored by jianli@chromium.org's avatar jianli@chromium.org

Switch to doing user-resizing via system for panels on Mac

We used to track and handle user-resizing by ourselves. This brings up a few problems and makes the user-resizing hard to use on Mac. For example, the user-resizing could not be triggered outside or on the edge. Switching to doing it via system solve all these problems.

Also removed EnableResizeByMouse which is not really used in our code.

BUG=282652,282657
TEST=manual test by user-resizing panels

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=221651

Review URL: https://chromiumcodereview.appspot.com/23918002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221765 0039d316-1c4b-4281-b951-d872f2087c98
parent ce5effe4
...@@ -46,7 +46,6 @@ class PanelCocoa : public NativePanel { ...@@ -46,7 +46,6 @@ class PanelCocoa : public NativePanel {
virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE; virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE;
virtual bool IsPanelAlwaysOnTop() const OVERRIDE; virtual bool IsPanelAlwaysOnTop() const OVERRIDE;
virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE; virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE;
virtual void EnableResizeByMouse(bool enable) OVERRIDE;
virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE;
virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE; virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE;
virtual void PanelExpansionStateChanging( virtual void PanelExpansionStateChanging(
......
...@@ -261,10 +261,6 @@ void PanelCocoa::SetPanelAlwaysOnTop(bool on_top) { ...@@ -261,10 +261,6 @@ void PanelCocoa::SetPanelAlwaysOnTop(bool on_top) {
[controller_ updateWindowCollectionBehavior]; [controller_ updateWindowCollectionBehavior];
} }
void PanelCocoa::EnableResizeByMouse(bool enable) {
[controller_ enableResizeByMouse:enable];
}
void PanelCocoa::UpdatePanelMinimizeRestoreButtonVisibility() { void PanelCocoa::UpdatePanelMinimizeRestoreButtonVisibility() {
[controller_ updateTitleBarMinimizeRestoreButtonVisibility]; [controller_ updateTitleBarMinimizeRestoreButtonVisibility];
} }
......
...@@ -12,18 +12,23 @@ ...@@ -12,18 +12,23 @@
namespace cocoa_utils { namespace cocoa_utils {
// TODO(dcheng): Move elsewhere so BrowserWindowCocoa can use them too. // TODO(dcheng): Move elsewhere so BrowserWindowCocoa can use them too.
// Converts a rect from the platfrom-independent screen coordinates (with the // Converts a rect from the platform-independent screen coordinates (with the
// (0,0) in the top-left corner of the primary screen) to the Cocoa screen // (0,0) in the top-left corner of the primary screen) to the Cocoa screen
// coordinates (with (0,0) in the low-left corner). // coordinates (with (0,0) in the low-left corner).
NSRect ConvertRectToCocoaCoordinates(const gfx::Rect& bounds); NSRect ConvertRectToCocoaCoordinates(const gfx::Rect& bounds);
// Converts a point from the platfrom-independent screen coordinates (with the // Converts a rect from the Cocoa screen oordinates (with (0,0) in the low-left
// corner) to the platform-independent screen coordinates (with the (0,0) in
// the top-left corner of the primary screen).
gfx::Rect ConvertRectFromCocoaCoordinates(NSRect bounds);
// Converts a point from the platform-independent screen coordinates (with the
// (0,0) in the top-left corner of the primary screen) to the Cocoa screen // (0,0) in the top-left corner of the primary screen) to the Cocoa screen
// coordinates (with (0,0) in the low-left corner). // coordinates (with (0,0) in the low-left corner).
NSPoint ConvertPointToCocoaCoordinates(const gfx::Point& point); NSPoint ConvertPointToCocoaCoordinates(const gfx::Point& point);
// Converts a point from the Cocoa screen coordinates (with (0,0) in the // Converts a point from the Cocoa screen coordinates (with (0,0) in the
// low-left corner of the primary screen) to the platfrom-independent screen // low-left corner of the primary screen) to the platform-independent screen
// coordinates (with the (0,0) in the top-left corner). // coordinates (with the (0,0) in the top-left corner).
gfx::Point ConvertPointFromCocoaCoordinates(NSPoint point); gfx::Point ConvertPointFromCocoaCoordinates(NSPoint point);
......
...@@ -15,6 +15,15 @@ NSRect ConvertRectToCocoaCoordinates(const gfx::Rect& bounds) { ...@@ -15,6 +15,15 @@ NSRect ConvertRectToCocoaCoordinates(const gfx::Rect& bounds) {
bounds.width(), bounds.height()); bounds.width(), bounds.height());
} }
gfx::Rect ConvertRectFromCocoaCoordinates(NSRect bounds) {
// Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
return gfx::Rect(
NSMinX(bounds), NSHeight([screen frame]) - NSMaxY(bounds),
NSWidth(bounds), NSHeight(bounds));
}
NSPoint ConvertPointToCocoaCoordinates(const gfx::Point& point) { NSPoint ConvertPointToCocoaCoordinates(const gfx::Point& point) {
// Flip coordinates based on the primary screen. // Flip coordinates based on the primary screen.
NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#import "chrome/browser/ui/cocoa/chrome_browser_window.h" #import "chrome/browser/ui/cocoa/chrome_browser_window.h"
#include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel.h"
#import "ui/base/cocoa/tracking_area.h"
class PanelCocoa; class PanelCocoa;
@class PanelTitlebarViewCocoa; @class PanelTitlebarViewCocoa;
...@@ -42,12 +43,17 @@ class PanelCocoa; ...@@ -42,12 +43,17 @@ class PanelCocoa;
// window over other application windows due to panels having a higher // window over other application windows due to panels having a higher
// priority NSWindowLevel, so we distinguish between the two scenarios. // priority NSWindowLevel, so we distinguish between the two scenarios.
BOOL activationRequestedByPanel_; BOOL activationRequestedByPanel_;
base::scoped_nsobject<NSView> overlayView_; // Is user resizing in progress?
BOOL userResizing_;
// Tracks the whole window in order to receive NSMouseMoved event.
ui::ScopedCrTrackingArea trackingArea_;
} }
// Load the window nib and do any Cocoa-specific initialization. // Load the window nib and do any Cocoa-specific initialization.
- (id)initWithPanel:(PanelCocoa*)window; - (id)initWithPanel:(PanelCocoa*)window;
- (Panel*)panel;
- (void)webContentsInserted:(content::WebContents*)contents; - (void)webContentsInserted:(content::WebContents*)contents;
- (void)webContentsDetached:(content::WebContents*)contents; - (void)webContentsDetached:(content::WebContents*)contents;
...@@ -137,8 +143,9 @@ class PanelCocoa; ...@@ -137,8 +143,9 @@ class PanelCocoa;
// Adjusts NSWindowCollectionBehavior based on whether panel is always on top. // Adjusts NSWindowCollectionBehavior based on whether panel is always on top.
- (void)updateWindowCollectionBehavior; - (void)updateWindowCollectionBehavior;
// Turns on user-resizable corners/sides indications and enables live resize. // Updates the tracking area per the window size change. This is needed in
- (void)enableResizeByMouse:(BOOL)enable; // order to receive the NSMouseMoved notification.
- (void)updateTrackingArea;
// Turns on/off shadow effect around the window shape. // Turns on/off shadow effect around the window shape.
- (void)showShadow:(BOOL)show; - (void)showShadow:(BOOL)show;
...@@ -148,6 +155,10 @@ class PanelCocoa; ...@@ -148,6 +155,10 @@ class PanelCocoa;
// Returns true if the window is minimized to the dock. // Returns true if the window is minimized to the dock.
- (BOOL)isMiniaturized; - (BOOL)isMiniaturized;
// Returns true if the user-resizing is allowed for the edge/corner close to
// current mouse location.
- (BOOL)canResizeByMouseAtCurrentLocation;
- (NSRect)frameRectForContentRect:(NSRect)contentRect; - (NSRect)frameRectForContentRect:(NSRect)contentRect;
- (NSRect)contentRectForFrameRect:(NSRect)frameRect; - (NSRect)contentRectForFrameRect:(NSRect)frameRect;
......
...@@ -28,16 +28,15 @@ ...@@ -28,16 +28,15 @@
#include "chrome/browser/ui/panels/panel_collection.h" #include "chrome/browser/ui/panels/panel_collection.h"
#include "chrome/browser/ui/panels/panel_constants.h" #include "chrome/browser/ui/panels/panel_constants.h"
#include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_manager.h"
#include "chrome/browser/ui/panels/stacked_panel_collection.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/encoding_menu_controller.h" #include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h" #include "content/public/browser/web_contents_view.h"
#include "grit/ui_resources.h" #include "grit/ui_resources.h"
#include "third_party/WebKit/public/web/WebCursorInfo.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "webkit/common/cursors/webcursor.h"
using content::WebContents; using content::WebContents;
...@@ -45,8 +44,8 @@ const int kMinimumWindowSize = 1; ...@@ -45,8 +44,8 @@ const int kMinimumWindowSize = 1;
const double kBoundsAnimationSpeedPixelsPerSecond = 1000; const double kBoundsAnimationSpeedPixelsPerSecond = 1000;
const double kBoundsAnimationMaxDurationSeconds = 0.18; const double kBoundsAnimationMaxDurationSeconds = 0.18;
// Resize edge thickness, in screen pixels. // Edge thickness to trigger user resizing via system, in screen pixels.
const double kWidthOfMouseResizeArea = 4.0; const double kWidthOfMouseResizeArea = 15.0;
@interface PanelWindowControllerCocoa (PanelsCanBecomeKey) @interface PanelWindowControllerCocoa (PanelsCanBecomeKey)
// Internal helper method for extracting the total number of panel windows // Internal helper method for extracting the total number of panel windows
...@@ -108,253 +107,49 @@ const double kWidthOfMouseResizeArea = 4.0; ...@@ -108,253 +107,49 @@ const double kWidthOfMouseResizeArea = 4.0;
return; return;
[super sendEvent:anEvent]; [super sendEvent:anEvent];
} }
@end
// Transparent view covering the whole panel in order to intercept mouse
// messages for custom user resizing. We need custom resizing because panels
// use their own constrained layout.
@interface PanelResizeByMouseOverlay : NSView <MouseDragControllerClient> {
@private
Panel* panel_;
base::scoped_nsobject<MouseDragController> dragController_;
base::scoped_nsobject<NSCursor> dragCursor_;
base::scoped_nsobject<NSCursor> eastWestCursor_;
base::scoped_nsobject<NSCursor> northSouthCursor_;
base::scoped_nsobject<NSCursor> northEastSouthWestCursor_;
base::scoped_nsobject<NSCursor> northWestSouthEastCursor_;
NSRect leftCursorRect_;
NSRect rightCursorRect_;
NSRect topCursorRect_;
NSRect bottomCursorRect_;
NSRect topLeftCursorRect_;
NSRect topRightCursorRect_;
NSRect bottomLeftCursorRect_;
NSRect bottomRightCursorRect_;
}
@end
namespace {
NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
return WebCursor(WebCursor::CursorInfo(type)).GetNativeCursor();
}
}
@implementation PanelResizeByMouseOverlay
- (PanelResizeByMouseOverlay*)initWithFrame:(NSRect)frame panel:(Panel*)panel {
if ((self = [super initWithFrame:frame])) {
panel_ = panel;
dragController_.reset([[MouseDragController alloc] initWithClient:self]);
eastWestCursor_.reset(
[LoadWebKitCursor(WebKit::WebCursorInfo::TypeEastWestResize) retain]);
northSouthCursor_.reset(
[LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthSouthResize) retain]);
northEastSouthWestCursor_.reset(
[LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthEastSouthWestResize)
retain]);
northWestSouthEastCursor_.reset(
[LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthWestSouthEastResize)
retain]);
}
return self;
}
- (BOOL)acceptsFirstMouse:(NSEvent*)event {
return YES;
}
// |pointInWindow| is in window coordinates.
- (panel::ResizingSides)edgeHitTest:(NSPoint)pointInWindow {
panel::Resizability resizability = panel_->CanResizeByMouse();
DCHECK_NE(panel::NOT_RESIZABLE, resizability);
NSPoint point = [self convertPoint:pointInWindow fromView:nil];
BOOL flipped = [self isFlipped];
if ((resizability & panel::RESIZABLE_TOP_LEFT) &&
NSMouseInRect(point, topLeftCursorRect_, flipped)) {
return panel::RESIZE_TOP_LEFT;
}
if ((resizability & panel::RESIZABLE_TOP_RIGHT) &&
NSMouseInRect(point, topRightCursorRect_, flipped)) {
return panel::RESIZE_TOP_RIGHT;
}
if ((resizability & panel::RESIZABLE_BOTTOM_LEFT) &&
NSMouseInRect(point, bottomLeftCursorRect_, flipped)) {
return panel::RESIZE_BOTTOM_LEFT;
}
if ((resizability & panel::RESIZABLE_BOTTOM_RIGHT) &&
NSMouseInRect(point, bottomRightCursorRect_, flipped)) {
return panel::RESIZE_BOTTOM_RIGHT;
}
if ((resizability & panel::RESIZABLE_LEFT) &&
NSMouseInRect(point, leftCursorRect_, flipped)) {
return panel::RESIZE_LEFT;
}
if ((resizability & panel::RESIZABLE_RIGHT) &&
NSMouseInRect(point, rightCursorRect_, flipped)) {
return panel::RESIZE_RIGHT;
}
if ((resizability & panel::RESIZABLE_TOP) &&
NSMouseInRect(point, topCursorRect_, flipped)) {
return panel::RESIZE_TOP;
}
if ((resizability & panel::RESIZABLE_BOTTOM) &&
NSMouseInRect(point, bottomCursorRect_, flipped)) {
return panel::RESIZE_BOTTOM;
}
return panel::RESIZE_NONE;
}
// NSWindow uses this method to figure out if this view is under the mouse
// and hence the one to handle the incoming mouse event.
// Since this view covers the whole panel, it is asked first.
// See if this is the mouse event we are interested in (in the resize areas)
// and return 'nil' to let NSWindow find another candidate otherwise.
// |point| is in coordinate system of the parent view.
- (NSView*)hitTest:(NSPoint)point {
// If panel is not resizable, let the mouse events fall through.
if (panel::NOT_RESIZABLE == panel_->CanResizeByMouse())
return nil;
NSPoint pointInWindow = [[self superview] convertPoint:point toView:nil];
return [self edgeHitTest:pointInWindow] == panel::RESIZE_NONE ? nil : self;
}
// Delegate these to MouseDragController, it will call back on
// MouseDragControllerClient protocol.
- (void)mouseDown:(NSEvent*)event {
[dragController_ mouseDown:event];
}
- (void)mouseDragged:(NSEvent*)event {
[dragController_ mouseDragged:event];
}
- (void)mouseUp:(NSEvent*)event {
[dragController_ mouseUp:event];
}
// MouseDragControllerClient protocol.
- (void)prepareForDrag {
// If the panel is not resizable, hitTest should have failed and no mouse
// events should have come here.
DCHECK_NE(panel::NOT_RESIZABLE, panel_->CanResizeByMouse());
// Make sure the cursor stays the same during whole resize operation.
// The cursor rects normally do not guarantee the same cursor, since the
// mouse may temporarily leave the cursor rect area (or even the window) so
// the cursor will flicker. Disable cursor rects and grab the current cursor
// so we can set it on mouseDragged: events to avoid flicker.
[[self window] disableCursorRects];
dragCursor_.reset([[NSCursor currentCursor] retain]);
}
- (void)cleanupAfterDrag {
[[self window] enableCursorRects];
dragCursor_.reset();
}
- (void)dragStarted:(NSPoint)initialMouseLocation {
NSPoint initialMouseLocationScreen =
[[self window] convertBaseToScreen:initialMouseLocation];
panel_->manager()->StartResizingByMouse(
panel_,
cocoa_utils::ConvertPointFromCocoaCoordinates(initialMouseLocationScreen),
[self edgeHitTest:initialMouseLocation]);
}
- (void)dragProgress:(NSPoint)mouseLocation {
NSPoint mouseLocationScreen =
[[self window] convertBaseToScreen:mouseLocation];
panel_->manager()->ResizeByMouse(
cocoa_utils::ConvertPointFromCocoaCoordinates(mouseLocationScreen));
// Set the resize cursor on every mouse drag event in case the mouse
// wandered outside the window and was switched to another one.
// This does not produce flicker, seems the real cursor is updated after
// mouseDrag is processed.
[dragCursor_ set];
}
- (void)dragEnded:(BOOL)cancelled {
panel_->manager()->EndResizingByMouse(cancelled);
}
- (void)resetCursorRects {
panel::Resizability resizability = panel_->CanResizeByMouse();
if (panel::NOT_RESIZABLE == resizability)
return;
NSRect bounds = [self bounds];
// Left vertical edge. - (void)mouseMoved:(NSEvent*)event {
if (resizability & panel::RESIZABLE_LEFT) { // Cocoa does not support letting the application determine the edges that
leftCursorRect_ = NSMakeRect( // can trigger the user resizing. To work around this, we track the mouse
NSMinX(bounds), // location. When it is close to the edge/corner where the user resizing
NSMinY(bounds) + kWidthOfMouseResizeArea, // is not desired, we force the min and max size of the window to be same
kWidthOfMouseResizeArea, // as current window size. For all other cases, we restore the min and max
NSHeight(bounds) - 2 * kWidthOfMouseResizeArea); // size.
[self addCursorRect:leftCursorRect_ cursor:eastWestCursor_]; PanelWindowControllerCocoa* controller =
} base::mac::ObjCCast<PanelWindowControllerCocoa>([self windowController]);
NSRect frame = [self frame];
// Right vertical edge. if ([controller canResizeByMouseAtCurrentLocation]) {
if (resizability & panel::RESIZABLE_RIGHT) { // Mac window server limits window sizes to 10000.
rightCursorRect_ = leftCursorRect_; NSSize maxSize = NSMakeSize(10000, 10000);
rightCursorRect_.origin.x = NSMaxX(bounds) - kWidthOfMouseResizeArea;
[self addCursorRect:rightCursorRect_ cursor:eastWestCursor_]; // If the user is resizing a stacked panel by its bottom edge, make sure its
} // height cannot grow more than what the panel below it could offer. This is
// because growing a stacked panel by y amount will shrink the panel below
// Top horizontal edge. // it by same amount and we do not want the panel below it being shrunk to
if (resizability & panel::RESIZABLE_TOP) { // be smaller than the titlebar.
topCursorRect_ = NSMakeRect(NSMinX(bounds) + kWidthOfMouseResizeArea, Panel* panel = [controller panel];
NSMaxY(bounds) - kWidthOfMouseResizeArea, NSPoint point = [NSEvent mouseLocation];
NSWidth(bounds) - 2 * kWidthOfMouseResizeArea, if (point.y < NSMinY(frame) + kWidthOfMouseResizeArea && panel->stack()) {
kWidthOfMouseResizeArea); Panel* belowPanel = panel->stack()->GetPanelBelow(panel);
[self addCursorRect:topCursorRect_ cursor:northSouthCursor_]; if (belowPanel && !belowPanel->IsMinimized()) {
} maxSize.height = panel->GetBounds().height() +
belowPanel->GetBounds().height() - panel::kTitlebarHeight;
// Top left corner. }
if (resizability & panel::RESIZABLE_TOP_LEFT) { }
topLeftCursorRect_ = NSMakeRect(NSMinX(bounds),
NSMaxY(bounds) - kWidthOfMouseResizeArea,
kWidthOfMouseResizeArea,
NSMaxY(bounds));
[self addCursorRect:topLeftCursorRect_ cursor:northWestSouthEastCursor_];
}
// Top right corner.
if (resizability & panel::RESIZABLE_TOP_RIGHT) {
topRightCursorRect_ = topLeftCursorRect_;
topRightCursorRect_.origin.x = NSMaxX(bounds) - kWidthOfMouseResizeArea;
[self addCursorRect:topRightCursorRect_ cursor:northEastSouthWestCursor_];
}
// Bottom horizontal edge.
if (resizability & panel::RESIZABLE_BOTTOM) {
bottomCursorRect_ = topCursorRect_;
bottomCursorRect_.origin.y = NSMinY(bounds);
[self addCursorRect:bottomCursorRect_ cursor:northSouthCursor_];
}
// Bottom right corner. // Enable the user-resizing by setting both min and max size to the right
if (resizability & panel::RESIZABLE_BOTTOM_RIGHT) { // values.
bottomRightCursorRect_ = topRightCursorRect_; [self setMinSize:NSMakeSize(panel::kPanelMinWidth,
bottomRightCursorRect_.origin.y = NSMinY(bounds); panel::kPanelMinHeight)];
[self addCursorRect:bottomRightCursorRect_ [self setMaxSize:maxSize];
cursor:northWestSouthEastCursor_]; } else {
// Disable the user-resizing by setting both min and max size to be same as
// current window size.
[self setMinSize:frame.size];
[self setMaxSize:frame.size];
} }
// Bottom left corner. [super mouseMoved:event];
if (resizability & panel::RESIZABLE_BOTTOM_LEFT) {
bottomLeftCursorRect_ = bottomRightCursorRect_;
bottomLeftCursorRect_.origin.x = NSMinX(bounds);
[self addCursorRect:bottomLeftCursorRect_ cursor:northEastSouthWestCursor_];
}
} }
@end @end
...@@ -389,6 +184,10 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -389,6 +184,10 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
return self; return self;
} }
- (Panel*)panel {
return windowShim_->panel();
}
- (void)awakeFromNib { - (void)awakeFromNib {
NSWindow* window = [self window]; NSWindow* window = [self window];
...@@ -411,16 +210,13 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -411,16 +210,13 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
frame.size.height = panelBounds.height(); frame.size.height = panelBounds.height();
[window setFrame:frame display:NO]; [window setFrame:frame display:NO];
// Add a transparent overlay on top of the whole window to process mouse // MacOS will turn the user-resizing to the user-dragging if the direction of
// events - for example, user-resizing. // the dragging is orthogonal to the direction of the arrow cursor. We do not
NSView* superview = [[window contentView] superview]; // want this since it will bypass our dragging logic. The panel window is
NSRect bounds = [superview bounds]; // still draggable because we track and handle the dragging in our custom way.
overlayView_.reset( [[self window] setMovable:NO];
[[PanelResizeByMouseOverlay alloc] initWithFrame:bounds
panel:windowShim_->panel()]); [self updateTrackingArea];
// Set autoresizing behavior: glued to edges.
[overlayView_ setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)];
[superview addSubview:overlayView_ positioned:NSWindowAbove relativeTo:nil];
} }
- (void)updateWebContentsViewFrame { - (void)updateWebContentsViewFrame {
...@@ -802,6 +598,10 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -802,6 +598,10 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
} }
windowShim_->panel()->OnActiveStateChanged(true); windowShim_->panel()->OnActiveStateChanged(true);
// Make the window user-resizable when it gains the focus.
[[self window] setStyleMask:
[[self window] styleMask] | NSResizableWindowMask];
} }
- (void)windowDidResignKey:(NSNotification*)notification { - (void)windowDidResignKey:(NSNotification*)notification {
...@@ -813,10 +613,64 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -813,10 +613,64 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
return; return;
[self onWindowDidResignKey]; [self onWindowDidResignKey];
// Make the window not user-resizable when it loses the focus. This is to
// solve the problem that the bottom edge of the active panel does not
// trigger the user-resizing if this panel stacks with another inactive
// panel at the bottom.
[[self window] setStyleMask:
[[self window] styleMask] & ~NSResizableWindowMask];
}
- (void)windowWillStartLiveResize:(NSNotification*)notification {
// Check if the user-resizing is allowed for the triggering edge/corner.
// This is an extra safe guard because we are not able to track the mouse
// movement outside the window and Cocoa could trigger the user-resizing
// when the mouse moves a bit outside the edge/corner.
if (![self canResizeByMouseAtCurrentLocation])
return;
userResizing_ = YES;
windowShim_->panel()->OnPanelStartUserResizing();
}
- (void)windowDidEndLiveResize:(NSNotification*)notification {
if (!userResizing_)
return;
userResizing_ = NO;
Panel* panel = windowShim_->panel();
panel->OnPanelEndUserResizing();
gfx::Rect newBounds =
cocoa_utils::ConvertRectFromCocoaCoordinates([[self window] frame]);
if (windowShim_->panel()->GetBounds() == newBounds)
return;
windowShim_->set_cached_bounds_directly(newBounds);
panel->IncreaseMaxSize(newBounds.size());
panel->set_full_size(newBounds.size());
panel->collection()->RefreshLayout();
}
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)newSize {
// As an extra safe guard, we avoid the user resizing if it is deemed not to
// be allowed (see comment in windowWillStartLiveResize).
if ([[self window] inLiveResize] && !userResizing_)
return [[self window] frame].size;
return newSize;
} }
- (void)windowDidResize:(NSNotification*)notification { - (void)windowDidResize:(NSNotification*)notification {
Panel* panel = windowShim_->panel(); Panel* panel = windowShim_->panel();
if (userResizing_) {
panel->collection()->OnPanelResizedByMouse(
panel,
cocoa_utils::ConvertRectFromCocoaCoordinates([[self window] frame]));
}
[self updateTrackingArea];
if (![self isAnimatingBounds] || if (![self isAnimatingBounds] ||
panel->collection()->type() != PanelCollection::DOCKED) panel->collection()->type() != PanelCollection::DOCKED)
return; return;
...@@ -972,10 +826,20 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -972,10 +826,20 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
[[self window] setCollectionBehavior:collectionBehavior]; [[self window] setCollectionBehavior:collectionBehavior];
} }
- (void)enableResizeByMouse:(BOOL)enable { - (void)updateTrackingArea {
if (![self isWindowLoaded]) NSView* superview = [[[self window] contentView] superview];
return;
[[self window] invalidateCursorRectsForView:overlayView_]; if (trackingArea_.get())
[superview removeTrackingArea:trackingArea_.get()];
trackingArea_.reset(
[[CrTrackingArea alloc] initWithRect:[superview bounds]
options:NSTrackingInVisibleRect |
NSTrackingMouseMoved |
NSTrackingActiveInKeyWindow
owner:superview
userInfo:nil]);
[superview addTrackingArea:trackingArea_.get()];
} }
- (void)showShadow:(BOOL)show { - (void)showShadow:(BOOL)show {
...@@ -992,6 +856,46 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { ...@@ -992,6 +856,46 @@ NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) {
return [[self window] isMiniaturized]; return [[self window] isMiniaturized];
} }
- (BOOL)canResizeByMouseAtCurrentLocation {
panel::Resizability resizability = windowShim_->panel()->CanResizeByMouse();
NSRect frame = [[self window] frame];
NSPoint point = [NSEvent mouseLocation];
if (point.y < NSMinY(frame) + kWidthOfMouseResizeArea) {
if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_BOTTOM_LEFT) == 0) {
return NO;
}
if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_BOTTOM_RIGHT) == 0) {
return NO;
}
if ((resizability & panel::RESIZABLE_BOTTOM) == 0)
return NO;
} else if (point.y > NSMaxY(frame) - kWidthOfMouseResizeArea) {
if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_TOP_LEFT) == 0) {
return NO;
}
if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_TOP_RIGHT) == 0) {
return NO;
}
if ((resizability & panel::RESIZABLE_TOP) == 0)
return NO;
} else {
if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_LEFT) == 0) {
return NO;
}
if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea &&
(resizability & panel::RESIZABLE_RIGHT) == 0) {
return NO;
}
}
return YES;
}
// We have custom implementation of these because our titlebar height is custom // We have custom implementation of these because our titlebar height is custom
// and does not match the standard one. // and does not match the standard one.
- (NSRect)frameRectForContentRect:(NSRect)contentRect { - (NSRect)frameRectForContentRect:(NSRect)contentRect {
......
...@@ -1068,9 +1068,6 @@ void PanelGtk::SetPanelAlwaysOnTop(bool on_top) { ...@@ -1068,9 +1068,6 @@ void PanelGtk::SetPanelAlwaysOnTop(bool on_top) {
gtk_window_unstick(window_); gtk_window_unstick(window_);
} }
void PanelGtk::EnableResizeByMouse(bool enable) {
}
void PanelGtk::UpdatePanelMinimizeRestoreButtonVisibility() { void PanelGtk::UpdatePanelMinimizeRestoreButtonVisibility() {
titlebar_->UpdateMinimizeRestoreButtonVisibility(); titlebar_->UpdateMinimizeRestoreButtonVisibility();
} }
......
...@@ -78,7 +78,6 @@ class PanelGtk : public NativePanel, ...@@ -78,7 +78,6 @@ class PanelGtk : public NativePanel,
virtual int TitleOnlyHeight() const OVERRIDE; virtual int TitleOnlyHeight() const OVERRIDE;
virtual bool IsPanelAlwaysOnTop() const OVERRIDE; virtual bool IsPanelAlwaysOnTop() const OVERRIDE;
virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE; virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE;
virtual void EnableResizeByMouse(bool enable) OVERRIDE;
virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE;
virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE; virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE;
virtual void MinimizePanelBySystem() OVERRIDE; virtual void MinimizePanelBySystem() OVERRIDE;
......
...@@ -239,7 +239,6 @@ void DetachedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { ...@@ -239,7 +239,6 @@ void DetachedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) {
static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION |
Panel::USE_SYSTEM_ATTENTION)); Panel::USE_SYSTEM_ATTENTION));
panel->ShowShadow(true); panel->ShowShadow(true);
panel->EnableResizeByMouse(true);
panel->UpdateMinimizeRestoreButtonVisibility(); panel->UpdateMinimizeRestoreButtonVisibility();
panel->SetWindowCornerStyle(panel::ALL_ROUNDED); panel->SetWindowCornerStyle(panel::ALL_ROUNDED);
} }
......
...@@ -765,7 +765,6 @@ void DockedPanelCollection::CloseAll() { ...@@ -765,7 +765,6 @@ void DockedPanelCollection::CloseAll() {
void DockedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { void DockedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) {
panel->set_attention_mode(Panel::USE_PANEL_ATTENTION); panel->set_attention_mode(Panel::USE_PANEL_ATTENTION);
panel->ShowShadow(true); panel->ShowShadow(true);
panel->EnableResizeByMouse(true);
panel->UpdateMinimizeRestoreButtonVisibility(); panel->UpdateMinimizeRestoreButtonVisibility();
panel->SetWindowCornerStyle(panel::TOP_ROUNDED); panel->SetWindowCornerStyle(panel::TOP_ROUNDED);
} }
......
...@@ -72,9 +72,6 @@ class NativePanel { ...@@ -72,9 +72,6 @@ class NativePanel {
virtual bool IsPanelAlwaysOnTop() const = 0; virtual bool IsPanelAlwaysOnTop() const = 0;
virtual void SetPanelAlwaysOnTop(bool on_top) = 0; virtual void SetPanelAlwaysOnTop(bool on_top) = 0;
// Enables resizing by dragging edges/corners.
virtual void EnableResizeByMouse(bool enable) = 0;
// Updates the visibility of the minimize and restore buttons. // Updates the visibility of the minimize and restore buttons.
virtual void UpdatePanelMinimizeRestoreButtonVisibility() = 0; virtual void UpdatePanelMinimizeRestoreButtonVisibility() = 0;
......
...@@ -667,11 +667,6 @@ void Panel::SetPreviewMode(bool in_preview) { ...@@ -667,11 +667,6 @@ void Panel::SetPreviewMode(bool in_preview) {
in_preview_mode_ = in_preview; in_preview_mode_ = in_preview;
} }
void Panel::EnableResizeByMouse(bool enable) {
DCHECK(native_panel_);
native_panel_->EnableResizeByMouse(enable);
}
void Panel::UpdateMinimizeRestoreButtonVisibility() { void Panel::UpdateMinimizeRestoreButtonVisibility() {
native_panel_->UpdatePanelMinimizeRestoreButtonVisibility(); native_panel_->UpdatePanelMinimizeRestoreButtonVisibility();
} }
......
...@@ -252,10 +252,6 @@ class Panel : public ui::BaseWindow, ...@@ -252,10 +252,6 @@ class Panel : public ui::BaseWindow,
// being dragged, it is in preview mode. // being dragged, it is in preview mode.
void SetPreviewMode(bool in_preview_mode); void SetPreviewMode(bool in_preview_mode);
// Sets up the panel for being resizable by the user - for example,
// enables the resize mouse cursors when mouse is hovering over the edges.
void EnableResizeByMouse(bool enable);
// Sets whether the minimize or restore button, if any, are visible. // Sets whether the minimize or restore button, if any, are visible.
void UpdateMinimizeRestoreButtonVisibility(); void UpdateMinimizeRestoreButtonVisibility();
......
...@@ -1254,7 +1254,7 @@ IN_PROC_BROWSER_TEST_F(StackedPanelBrowserTest, ClosePanels) { ...@@ -1254,7 +1254,7 @@ IN_PROC_BROWSER_TEST_F(StackedPanelBrowserTest, ClosePanels) {
// Skip the test since active state might not be fully supported for some window // Skip the test since active state might not be fully supported for some window
// managers. // managers.
#if defined(TOOLKIT_GTK) #if defined(TOOLKIT_GTK) || defined(OS_MACOSX)
#define MAYBE_FocusNextPanelOnPanelClose DISABLED_FocusNextPanelOnPanelClose #define MAYBE_FocusNextPanelOnPanelClose DISABLED_FocusNextPanelOnPanelClose
#else #else
#define MAYBE_FocusNextPanelOnPanelClose FocusNextPanelOnPanelClose #define MAYBE_FocusNextPanelOnPanelClose FocusNextPanelOnPanelClose
......
...@@ -626,7 +626,6 @@ void StackedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { ...@@ -626,7 +626,6 @@ void StackedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) {
static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION | static_cast<Panel::AttentionMode>(Panel::USE_PANEL_ATTENTION |
Panel::USE_SYSTEM_ATTENTION)); Panel::USE_SYSTEM_ATTENTION));
panel->ShowShadow(false); panel->ShowShadow(false);
panel->EnableResizeByMouse(true);
panel->UpdateMinimizeRestoreButtonVisibility(); panel->UpdateMinimizeRestoreButtonVisibility();
UpdatePanelCornerStyle(panel); UpdatePanelCornerStyle(panel);
} }
......
...@@ -599,10 +599,6 @@ void PanelView::SetPanelAlwaysOnTop(bool on_top) { ...@@ -599,10 +599,6 @@ void PanelView::SetPanelAlwaysOnTop(bool on_top) {
window_->client_view()->Layout(); window_->client_view()->Layout();
} }
void PanelView::EnableResizeByMouse(bool enable) {
// Nothing to do since we use system resizing.
}
void PanelView::UpdatePanelMinimizeRestoreButtonVisibility() { void PanelView::UpdatePanelMinimizeRestoreButtonVisibility() {
GetFrameView()->UpdateTitlebarMinimizeRestoreButtonVisibility(); GetFrameView()->UpdateTitlebarMinimizeRestoreButtonVisibility();
} }
......
...@@ -63,7 +63,6 @@ class PanelView : public NativePanel, ...@@ -63,7 +63,6 @@ class PanelView : public NativePanel,
virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE; virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE;
virtual bool IsPanelAlwaysOnTop() const OVERRIDE; virtual bool IsPanelAlwaysOnTop() const OVERRIDE;
virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE; virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE;
virtual void EnableResizeByMouse(bool enable) OVERRIDE;
virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE;
virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE; virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE;
virtual void PanelExpansionStateChanging( virtual void PanelExpansionStateChanging(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment