Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(910)

Unified Diff: chrome/browser/cocoa/chrome_browser_window.mm

Issue 260009: Several background pattern fixes on the Mac.... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/cocoa/chrome_browser_window.mm
===================================================================
--- chrome/browser/cocoa/chrome_browser_window.mm (revision 28537)
+++ chrome/browser/cocoa/chrome_browser_window.mm (working copy)
@@ -6,13 +6,262 @@
#include "base/logging.h"
#import "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/browser_frame_view.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
#import "chrome/browser/renderer_host/render_widget_host_view_mac.h"
#include "chrome/browser/global_keyboard_shortcuts_mac.h"
+// Our browser window does some interesting things to get the behaviors that
+// we want. We replace the standard window controls (zoom, close, miniaturize)
+// with our own versions, so that we can position them slightly differently than
+// the default window has them. To do this, we hide the ones that Apple provides
+// us with, and create our own. This requires us to handle tracking for the
+// buttons (so that they highlight and activate correctly) as well as implement
+// the private method _mouseInGroup in our frame view class which is required
+// to get the rollover highlight drawing to draw correctly.
+@interface ChromeBrowserWindow(ChromeBrowserWindowPrivateMethods)
+// Return the view that does the "frame" drawing.
+- (NSView*)frameView;
+@end
+
typedef int (*KeyToCommandMapper)(bool, bool, bool, int);
@implementation ChromeBrowserWindow
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)aStyle
+ backing:(NSBackingStoreType)bufferingType
+ defer:(BOOL)flag {
+ if ((self = [super initWithContentRect:contentRect
+ styleMask:aStyle
+ backing:bufferingType
+ defer:flag])) {
+ NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
+ [defaultCenter addObserver:self
+ selector:@selector(themeDidChangeNotification:)
+ name:kGTMThemeDidChangeNotification
+ object:nil];
+ // Hook ourselves up to get notified if the user changes the system
+ // theme on us.
+ NSDistributedNotificationCenter* distCenter =
+ [NSDistributedNotificationCenter defaultCenter];
+ [distCenter addObserver:self
+ selector:@selector(systemThemeDidChangeNotification:)
+ name:@"AppleAquaColorVariantChanged"
+ object:nil];
+ [self setOpaque:NO];
+ // Set up our buttons how we like them.
+ NSView* frameView = [self frameView];
+ NSRect frameViewBounds = [frameView bounds];
+
+ // Find all the "original" buttons, and hide them. We can't use the original
+ // buttons because the OS likes to move them around when we resize windows
+ // and will put them back in what it considers to be their "preferred"
+ // locations.
+ NSButton* oldButton = [self standardWindowButton:NSWindowCloseButton];
+ [oldButton setHidden:YES];
+ oldButton = [self standardWindowButton:NSWindowMiniaturizeButton];
+ [oldButton setHidden:YES];
+ oldButton = [self standardWindowButton:NSWindowZoomButton];
+ [oldButton setHidden:YES];
+
+ // Create and position our new buttons.
+ closeButton_ = [NSWindow standardWindowButton:NSWindowCloseButton
+ forStyleMask:aStyle];
+ NSRect closeButtonFrame = [closeButton_ frame];
+ closeButtonFrame.origin =
+ NSMakePoint(kChromeWindowButtonsOffsetFromLeft,
+ (NSHeight(frameViewBounds) -
+ NSHeight(closeButtonFrame) -
+ kChromeWindowButtonsOffsetFromTop));
+ [closeButton_ setFrame:closeButtonFrame];
+ [closeButton_ setTarget:self];
+ [closeButton_ setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
+ [frameView addSubview:closeButton_];
+
+ miniaturizeButton_ =
+ [NSWindow standardWindowButton:NSWindowMiniaturizeButton
+ forStyleMask:aStyle];
+ NSRect miniaturizeButtonFrame = [miniaturizeButton_ frame];
+ miniaturizeButtonFrame.origin =
+ NSMakePoint((NSMaxX(closeButtonFrame) +
+ kChromeWindowButtonsInterButtonSpacing),
+ NSMinY(closeButtonFrame));
+ [miniaturizeButton_ setFrame:miniaturizeButtonFrame];
+ [miniaturizeButton_ setTarget:self];
+ [miniaturizeButton_ setAutoresizingMask:(NSViewMaxXMargin |
+ NSViewMinYMargin)];
+ [frameView addSubview:miniaturizeButton_];
+
+ zoomButton_ = [NSWindow standardWindowButton:NSWindowZoomButton
+ forStyleMask:aStyle];
+ NSRect zoomButtonFrame = [zoomButton_ frame];
+ zoomButtonFrame.origin =
+ NSMakePoint((NSMaxX(miniaturizeButtonFrame) +
+ kChromeWindowButtonsInterButtonSpacing),
+ NSMinY(miniaturizeButtonFrame));
+ [zoomButton_ setFrame:zoomButtonFrame];
+ [zoomButton_ setTarget:self];
+ [zoomButton_ setAutoresizingMask:(NSViewMaxXMargin |
+ NSViewMinYMargin)];
+
+ [frameView addSubview:zoomButton_];
+ [self updateTrackingAreas];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
+- (NSView*)frameView {
+ return [[self contentView] superview];
+}
+
+// The tab strip view covers our window buttons. So we add hit testing here
+// to find them properly and return them to the accessibility system.
+- (id)accessibilityHitTest:(NSPoint)point {
+ NSPoint windowPoint = [self convertScreenToBase:point];
+ NSControl* controls[] = { closeButton_, zoomButton_, miniaturizeButton_ };
+ id value = nil;
+ for (size_t i = 0; i < sizeof(controls) / sizeof(controls[0]); ++i) {
+ if (NSPointInRect(windowPoint, [controls[i] frame])) {
+ value = [controls[i] accessibilityHitTest:point];
+ break;
+ }
+ }
+ if (!value) {
+ value = [super accessibilityHitTest:point];
+ }
+ return value;
+}
+
+// Map our custom buttons into the accessibility hierarchy correctly.
+- (id)accessibilityAttributeValue:(NSString*)attribute {
+ id value = nil;
+ struct {
+ NSString* attribute_;
+ id value_;
+ } attributeMap[] = {
+ { NSAccessibilityCloseButtonAttribute, [closeButton_ cell]},
+ { NSAccessibilityZoomButtonAttribute, [zoomButton_ cell]},
+ { NSAccessibilityMinimizeButtonAttribute, [miniaturizeButton_ cell]},
+ };
+
+ for (size_t i = 0; i < sizeof(attributeMap) / sizeof(attributeMap[0]); ++i) {
+ if ([attributeMap[i].attribute_ isEqualToString:attribute]) {
+ value = attributeMap[i].value_;
+ break;
+ }
+ }
+ if (!value) {
+ value = [super accessibilityAttributeValue:attribute];
+ }
+ return value;
+}
+
+- (void)updateTrackingAreas {
+ NSView* frameView = [self frameView];
+ if (widgetTrackingArea_) {
+ [frameView removeTrackingArea:widgetTrackingArea_];
+ }
+ NSRect trackingRect = [closeButton_ frame];
+ trackingRect.size.width = NSMaxX([zoomButton_ frame]) - NSMinX(trackingRect);
+ widgetTrackingArea_.reset(
+ [[NSTrackingArea alloc] initWithRect:trackingRect
+ options:(NSTrackingMouseEnteredAndExited |
+ NSTrackingActiveAlways)
+ owner:self
+ userInfo:nil]);
+ [frameView addTrackingArea:widgetTrackingArea_];
+}
+
+- (void)windowMainStatusChanged {
+ [closeButton_ setNeedsDisplay];
+ [zoomButton_ setNeedsDisplay];
+ [miniaturizeButton_ setNeedsDisplay];
+ NSView* frameView = [self frameView];
+ NSView* contentView = [self contentView];
+ NSRect updateRect = [frameView frame];
+ NSRect contentRect = [contentView frame];
+ CGFloat tabStripHeight = [TabStripController defaultTabHeight];
+ updateRect.size.height -= NSHeight(contentRect) - tabStripHeight;
+ updateRect.origin.y = NSMaxY(contentRect) - tabStripHeight;
+ [[self frameView] setNeedsDisplayInRect:updateRect];
+}
+
+- (void)becomeMainWindow {
+ [self windowMainStatusChanged];
+ [super becomeMainWindow];
+}
+
+- (void)resignMainWindow {
+ [self windowMainStatusChanged];
+ [super resignMainWindow];
+}
+
+- (void)themeDidChangeNotification:(NSNotification*)aNotification {
+ GTMTheme* theme = [aNotification object];
+ if ([theme isEqual:[self gtm_theme]]) {
+ [[self frameView] setNeedsDisplay:YES];
+ }
+}
+
+- (void)systemThemeDidChangeNotification:(NSNotification*)aNotification {
+ [closeButton_ setNeedsDisplay];
+ [zoomButton_ setNeedsDisplay];
+ [miniaturizeButton_ setNeedsDisplay];
+}
+
+- (void)sendEvent:(NSEvent*)event {
+ // For cocoa windows, clicking on the close and the miniaturize (but not the
+ // zoom buttons) while a window is in the background does NOT bring that
+ // window to the front. We don't get that behavior for free, so we handle
+ // it here. Zoom buttons do bring the window to the front. Note that
+ // Finder windows (in Leopard) behave differently in this regard in that
+ // zoom buttons don't bring the window to the foreground.
+ BOOL eventHandled = NO;
+ if (![self isMainWindow]) {
+ if ([event type] == NSLeftMouseDown) {
+ NSView* frameView = [self frameView];
+ NSPoint mouse = [frameView convertPointFromBase:[event locationInWindow]];
+ if (NSPointInRect(mouse, [closeButton_ frame])) {
+ [closeButton_ mouseDown:event];
+ eventHandled = YES;
+ } else if (NSPointInRect(mouse, [miniaturizeButton_ frame])) {
+ [miniaturizeButton_ mouseDown:event];
+ eventHandled = YES;
+ }
+ }
+ }
+ if (!eventHandled) {
+ [super sendEvent:event];
+ }
+}
+
+// Update our buttons so that they highlight correctly.
+- (void)mouseEntered:(NSEvent*)event {
+ entered_ = YES;
+ [closeButton_ setNeedsDisplay];
+ [zoomButton_ setNeedsDisplay];
+ [miniaturizeButton_ setNeedsDisplay];
+}
+
+// Update our buttons so that they highlight correctly.
+- (void)mouseExited:(NSEvent*)event {
+ entered_ = NO;
+ [closeButton_ setNeedsDisplay];
+ [zoomButton_ setNeedsDisplay];
+ [miniaturizeButton_ setNeedsDisplay];
+}
+
+- (BOOL)mouseInGroup:(NSButton*)widget {
+ return entered_;
+}
+
- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable:
(KeyToCommandMapper)commandForKeyboardShortcut {
// Extract info from |event|.
Property changes on: chrome/browser/cocoa/chrome_browser_window.mm
___________________________________________________________________
Name: svn:eol-style
+ LF
« no previous file with comments | « chrome/browser/cocoa/chrome_browser_window.h ('k') | chrome/browser/cocoa/chrome_browser_window_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698