OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/framed_browser_window.h" | 5 #import "chrome/browser/ui/cocoa/framed_browser_window.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/mac/sdk_forward_declarations.h" | 8 #include "base/mac/sdk_forward_declarations.h" |
9 #include "chrome/browser/global_keyboard_shortcuts_mac.h" | 9 #include "chrome/browser/global_keyboard_shortcuts_mac.h" |
10 #include "chrome/browser/profiles/profile_avatar_icon_util.h" | 10 #include "chrome/browser/profiles/profile_avatar_icon_util.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 } | 35 } |
36 | 36 |
37 @interface FramedBrowserWindow (Private) | 37 @interface FramedBrowserWindow (Private) |
38 | 38 |
39 - (void)adjustCloseButton:(NSNotification*)notification; | 39 - (void)adjustCloseButton:(NSNotification*)notification; |
40 - (void)adjustMiniaturizeButton:(NSNotification*)notification; | 40 - (void)adjustMiniaturizeButton:(NSNotification*)notification; |
41 - (void)adjustZoomButton:(NSNotification*)notification; | 41 - (void)adjustZoomButton:(NSNotification*)notification; |
42 - (void)adjustButton:(NSButton*)button | 42 - (void)adjustButton:(NSButton*)button |
43 ofKind:(NSWindowButton)kind; | 43 ofKind:(NSWindowButton)kind; |
44 - (NSView*)frameView; | |
45 | 44 |
46 @end | 45 @end |
47 | 46 |
48 // Undocumented APIs. They are really on NSGrayFrame rather than NSView. Take | 47 // Undocumented APIs. They are really on NSGrayFrame rather than NSView. Take |
49 // care to only call them on the NSView passed into | 48 // care to only call them on the NSView passed into |
50 // -[NSWindow drawCustomRect:forView:]. | 49 // -[NSWindow drawCustomRect:forView:]. |
51 @interface NSView (UndocumentedAPI) | 50 @interface NSView (UndocumentedAPI) |
52 | 51 |
53 - (float)roundedCornerRadius; | 52 - (float)roundedCornerRadius; |
54 - (CGRect)_titlebarTitleRect; | 53 - (CGRect)_titlebarTitleRect; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 name:NSViewFrameDidChangeNotification | 103 name:NSViewFrameDidChangeNotification |
105 object:closeButton_]; | 104 object:closeButton_]; |
106 [center addObserver:self | 105 [center addObserver:self |
107 selector:@selector(adjustMiniaturizeButton:) | 106 selector:@selector(adjustMiniaturizeButton:) |
108 name:NSViewFrameDidChangeNotification | 107 name:NSViewFrameDidChangeNotification |
109 object:miniaturizeButton_]; | 108 object:miniaturizeButton_]; |
110 [center addObserver:self | 109 [center addObserver:self |
111 selector:@selector(adjustZoomButton:) | 110 selector:@selector(adjustZoomButton:) |
112 name:NSViewFrameDidChangeNotification | 111 name:NSViewFrameDidChangeNotification |
113 object:zoomButton_]; | 112 object:zoomButton_]; |
114 [center addObserver:self | |
115 selector:@selector(themeDidChangeNotification:) | |
116 name:kBrowserThemeDidChangeNotification | |
117 object:nil]; | |
118 } | 113 } |
119 | 114 |
120 return self; | 115 return self; |
121 } | 116 } |
122 | 117 |
123 - (void)dealloc { | 118 - (void)dealloc { |
124 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 119 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
125 [super dealloc]; | 120 [super dealloc]; |
126 } | 121 } |
127 | 122 |
128 - (void)adjustCloseButton:(NSNotification*)notification { | 123 - (void)adjustCloseButton:(NSNotification*)notification { |
129 [self adjustButton:[notification object] | 124 [self adjustButton:[notification object] |
130 ofKind:NSWindowCloseButton]; | 125 ofKind:NSWindowCloseButton]; |
131 } | 126 } |
132 | 127 |
133 - (void)adjustMiniaturizeButton:(NSNotification*)notification { | 128 - (void)adjustMiniaturizeButton:(NSNotification*)notification { |
134 [self adjustButton:[notification object] | 129 [self adjustButton:[notification object] |
135 ofKind:NSWindowMiniaturizeButton]; | 130 ofKind:NSWindowMiniaturizeButton]; |
136 } | 131 } |
137 | 132 |
138 - (void)adjustZoomButton:(NSNotification*)notification { | 133 - (void)adjustZoomButton:(NSNotification*)notification { |
139 [self adjustButton:[notification object] | 134 [self adjustButton:[notification object] |
140 ofKind:NSWindowZoomButton]; | 135 ofKind:NSWindowZoomButton]; |
141 } | 136 } |
142 | 137 |
143 - (void)adjustButton:(NSButton*)button | 138 - (void)adjustButton:(NSButton*)button |
144 ofKind:(NSWindowButton)kind { | 139 ofKind:(NSWindowButton)kind { |
145 NSRect buttonFrame = [button frame]; | 140 NSRect buttonFrame = [button frame]; |
146 NSRect frameViewBounds = [[self frameView] bounds]; | |
147 | 141 |
148 CGFloat xOffset = hasTabStrip_ | 142 CGFloat xOffset = hasTabStrip_ |
149 ? kFramedWindowButtonsWithTabStripOffsetFromLeft | 143 ? kFramedWindowButtonsWithTabStripOffsetFromLeft |
150 : kFramedWindowButtonsWithoutTabStripOffsetFromLeft; | 144 : kFramedWindowButtonsWithoutTabStripOffsetFromLeft; |
151 CGFloat yOffset = hasTabStrip_ | 145 CGFloat yOffset = hasTabStrip_ |
152 ? kFramedWindowButtonsWithTabStripOffsetFromTop | 146 ? kFramedWindowButtonsWithTabStripOffsetFromTop |
153 : kFramedWindowButtonsWithoutTabStripOffsetFromTop; | 147 : kFramedWindowButtonsWithoutTabStripOffsetFromTop; |
154 buttonFrame.origin = | 148 buttonFrame.origin = |
155 NSMakePoint(xOffset, (NSHeight(frameViewBounds) - | 149 NSMakePoint(xOffset, (NSHeight([self frame]) - |
156 NSHeight(buttonFrame) - yOffset)); | 150 NSHeight(buttonFrame) - yOffset)); |
157 | 151 |
158 switch (kind) { | 152 switch (kind) { |
159 case NSWindowZoomButton: | 153 case NSWindowZoomButton: |
160 buttonFrame.origin.x += NSWidth([miniaturizeButton_ frame]); | 154 buttonFrame.origin.x += NSWidth([miniaturizeButton_ frame]); |
161 buttonFrame.origin.x += windowButtonsInterButtonSpacing_; | 155 buttonFrame.origin.x += windowButtonsInterButtonSpacing_; |
162 // fallthrough | 156 // fallthrough |
163 case NSWindowMiniaturizeButton: | 157 case NSWindowMiniaturizeButton: |
164 buttonFrame.origin.x += NSWidth([closeButton_ frame]); | 158 buttonFrame.origin.x += NSWidth([closeButton_ frame]); |
165 buttonFrame.origin.x += windowButtonsInterButtonSpacing_; | 159 buttonFrame.origin.x += windowButtonsInterButtonSpacing_; |
166 // fallthrough | 160 // fallthrough |
167 default: | 161 default: |
168 break; | 162 break; |
169 } | 163 } |
170 | 164 |
171 BOOL didPost = [button postsBoundsChangedNotifications]; | 165 BOOL didPost = [button postsBoundsChangedNotifications]; |
172 [button setPostsFrameChangedNotifications:NO]; | 166 [button setPostsFrameChangedNotifications:NO]; |
173 [button setFrame:buttonFrame]; | 167 [button setFrame:buttonFrame]; |
174 [button setPostsFrameChangedNotifications:didPost]; | 168 [button setPostsFrameChangedNotifications:didPost]; |
175 } | 169 } |
176 | 170 |
177 - (NSView*)frameView { | |
178 return [[self contentView] superview]; | |
179 } | |
180 | |
181 // The tab strip view covers our window buttons. So we add hit testing here | 171 // The tab strip view covers our window buttons. So we add hit testing here |
182 // to find them properly and return them to the accessibility system. | 172 // to find them properly and return them to the accessibility system. |
183 - (id)accessibilityHitTest:(NSPoint)point { | 173 - (id)accessibilityHitTest:(NSPoint)point { |
184 NSPoint windowPoint = [self convertScreenToBase:point]; | 174 NSPoint windowPoint = [self convertScreenToBase:point]; |
185 NSControl* controls[] = { closeButton_, zoomButton_, miniaturizeButton_ }; | 175 NSControl* controls[] = { closeButton_, zoomButton_, miniaturizeButton_ }; |
186 id value = nil; | 176 id value = nil; |
187 for (size_t i = 0; i < sizeof(controls) / sizeof(controls[0]); ++i) { | 177 for (size_t i = 0; i < sizeof(controls) / sizeof(controls[0]); ++i) { |
188 if (NSPointInRect(windowPoint, [controls[i] frame])) { | 178 if (NSPointInRect(windowPoint, [controls[i] frame])) { |
189 value = [controls[i] accessibilityHitTest:point]; | 179 value = [controls[i] accessibilityHitTest:point]; |
190 break; | 180 break; |
191 } | 181 } |
192 } | 182 } |
193 if (!value) { | 183 if (!value) { |
194 value = [super accessibilityHitTest:point]; | 184 value = [super accessibilityHitTest:point]; |
195 } | 185 } |
196 return value; | 186 return value; |
197 } | 187 } |
198 | 188 |
199 - (void)windowMainStatusChanged { | |
200 NSView* frameView = [self frameView]; | |
201 NSView* contentView = [self contentView]; | |
202 NSRect updateRect = [frameView frame]; | |
203 NSRect contentRect = [contentView frame]; | |
204 CGFloat tabStripHeight = [TabStripController defaultTabHeight]; | |
205 updateRect.size.height -= NSHeight(contentRect) - tabStripHeight; | |
206 updateRect.origin.y = NSMaxY(contentRect) - tabStripHeight; | |
207 [[self frameView] setNeedsDisplayInRect:updateRect]; | |
208 } | |
209 | |
210 - (void)becomeMainWindow { | |
211 [self windowMainStatusChanged]; | |
212 [super becomeMainWindow]; | |
213 } | |
214 | |
215 - (void)resignMainWindow { | |
216 [self windowMainStatusChanged]; | |
217 [super resignMainWindow]; | |
218 } | |
219 | |
220 // Called after the current theme has changed. | |
221 - (void)themeDidChangeNotification:(NSNotification*)aNotification { | |
222 [[self frameView] setNeedsDisplay:YES]; | |
223 } | |
224 | |
225 - (void)sendEvent:(NSEvent*)event { | |
226 // For Cocoa windows, clicking on the close and the miniaturize buttons (but | |
227 // not the zoom button) while a window is in the background does NOT bring | |
228 // that window to the front. We don't get that behavior for free (probably | |
229 // because the tab strip view covers those buttons), so we handle it here. | |
230 // Zoom buttons do bring the window to the front. Note that Finder windows (in | |
231 // Leopard) behave differently in this regard in that zoom buttons don't bring | |
232 // the window to the foreground. | |
233 BOOL eventHandled = NO; | |
234 if (![self isMainWindow]) { | |
235 if ([event type] == NSLeftMouseDown) { | |
236 NSView* frameView = [self frameView]; | |
237 NSPoint mouse = [frameView convertPoint:[event locationInWindow] | |
238 fromView:nil]; | |
239 if (NSPointInRect(mouse, [closeButton_ frame])) { | |
240 [closeButton_ mouseDown:event]; | |
241 eventHandled = YES; | |
242 } else if (NSPointInRect(mouse, [miniaturizeButton_ frame])) { | |
243 [miniaturizeButton_ mouseDown:event]; | |
244 eventHandled = YES; | |
245 } | |
246 } | |
247 } | |
248 if (!eventHandled) { | |
249 [super sendEvent:event]; | |
250 } | |
251 } | |
252 | |
253 - (void)setShouldHideTitle:(BOOL)flag { | 189 - (void)setShouldHideTitle:(BOOL)flag { |
254 shouldHideTitle_ = flag; | 190 shouldHideTitle_ = flag; |
255 } | 191 } |
256 | 192 |
257 - (BOOL)_isTitleHidden { | 193 - (BOOL)_isTitleHidden { |
258 return shouldHideTitle_; | 194 return shouldHideTitle_; |
259 } | 195 } |
260 | 196 |
261 - (CGFloat)windowButtonsInterButtonSpacing { | 197 - (CGFloat)windowButtonsInterButtonSpacing { |
262 return windowButtonsInterButtonSpacing_; | 198 return windowButtonsInterButtonSpacing_; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 // asked paint black first and blend the theme with black. | 296 // asked paint black first and blend the theme with black. |
361 NSCompositingOperation operation = NSCompositeCopy; | 297 NSCompositingOperation operation = NSCompositeCopy; |
362 if (forceBlackBackground) { | 298 if (forceBlackBackground) { |
363 [[NSColor blackColor] set]; | 299 [[NSColor blackColor] set]; |
364 NSRectFill(dirtyRect); | 300 NSRectFill(dirtyRect); |
365 operation = NSCompositeSourceOver; | 301 operation = NSCompositeSourceOver; |
366 } | 302 } |
367 | 303 |
368 NSPoint position = [[view window] themeImagePositionForAlignment: | 304 NSPoint position = [[view window] themeImagePositionForAlignment: |
369 THEME_IMAGE_ALIGN_WITH_FRAME]; | 305 THEME_IMAGE_ALIGN_WITH_FRAME]; |
370 | |
371 // Align the phase to physical pixels so resizing the window under HiDPI | |
372 // doesn't cause wiggling of the theme. | |
373 NSView* frameView = [[[view window] contentView] superview]; | |
374 position = [frameView convertPointToBase:position]; | |
375 position.x = floor(position.x); | |
376 position.y = floor(position.y); | |
377 position = [frameView convertPointFromBase:position]; | |
378 [[NSGraphicsContext currentContext] cr_setPatternPhase:position | 306 [[NSGraphicsContext currentContext] cr_setPatternPhase:position |
379 forView:view]; | 307 forView:view]; |
380 | 308 |
381 [themeImageColor set]; | 309 [themeImageColor set]; |
382 NSRectFillUsingOperation(dirtyRect, operation); | 310 NSRectFillUsingOperation(dirtyRect, operation); |
383 themed = YES; | 311 themed = YES; |
384 } else if (gradient) { | 312 } else if (gradient) { |
385 NSPoint startPoint = NSMakePoint(NSMinX(bounds), NSMaxY(bounds)); | 313 NSPoint startPoint = NSMakePoint(NSMinX(bounds), NSMaxY(bounds)); |
386 NSPoint endPoint = startPoint; | 314 NSPoint endPoint = startPoint; |
387 endPoint.y -= kBrowserFrameViewPaintHeight; | 315 endPoint.y -= kBrowserFrameViewPaintHeight; |
388 [gradient drawFromPoint:startPoint toPoint:endPoint options:0]; | 316 [gradient drawFromPoint:startPoint toPoint:endPoint options:0]; |
389 themed = YES; | 317 themed = YES; |
390 } | 318 } |
391 | 319 |
392 // Check to see if we have an overlay image. | 320 // Check to see if we have an overlay image. |
393 NSImage* overlayImage = nil; | 321 NSImage* overlayImage = nil; |
394 if (themeProvider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && !incognito && | 322 if (themeProvider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && !incognito && |
395 !popup) { | 323 !popup) { |
396 overlayImage = themeProvider-> | 324 overlayImage = themeProvider-> |
397 GetNSImageNamed(active ? IDR_THEME_FRAME_OVERLAY : | 325 GetNSImageNamed(active ? IDR_THEME_FRAME_OVERLAY : |
398 IDR_THEME_FRAME_OVERLAY_INACTIVE); | 326 IDR_THEME_FRAME_OVERLAY_INACTIVE); |
399 } | 327 } |
400 | 328 |
401 if (overlayImage) { | 329 if (overlayImage) { |
402 // Anchor to top-left and don't scale. | 330 // Anchor to top-left and don't scale. |
403 NSView* frameView = [[[view window] contentView] superview]; | |
404 NSPoint position = [[view window] themeImagePositionForAlignment: | 331 NSPoint position = [[view window] themeImagePositionForAlignment: |
405 THEME_IMAGE_ALIGN_WITH_FRAME]; | 332 THEME_IMAGE_ALIGN_WITH_FRAME]; |
406 position = [view convertPoint:position fromView:frameView]; | 333 position = [view convertPoint:position fromView:nil]; |
407 NSSize overlaySize = [overlayImage size]; | 334 NSSize overlaySize = [overlayImage size]; |
408 NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height); | 335 NSRect imageFrame = NSMakeRect(0, 0, overlaySize.width, overlaySize.height); |
409 [overlayImage drawAtPoint:NSMakePoint(position.x, | 336 [overlayImage drawAtPoint:NSMakePoint(position.x, |
410 position.y - overlaySize.height) | 337 position.y - overlaySize.height) |
411 fromRect:imageFrame | 338 fromRect:imageFrame |
412 operation:NSCompositeSourceOver | 339 operation:NSCompositeSourceOver |
413 fraction:1.0]; | 340 fraction:1.0]; |
414 } | 341 } |
415 | 342 |
416 return themed; | 343 return themed; |
417 } | 344 } |
418 | 345 |
419 - (NSColor*)titleColor { | 346 - (NSColor*)titleColor { |
420 ui::ThemeProvider* themeProvider = [self themeProvider]; | 347 ui::ThemeProvider* themeProvider = [self themeProvider]; |
421 if (!themeProvider) | 348 if (!themeProvider) |
422 return [NSColor windowFrameTextColor]; | 349 return [NSColor windowFrameTextColor]; |
423 | 350 |
424 ThemedWindowStyle windowStyle = [self themedWindowStyle]; | 351 ThemedWindowStyle windowStyle = [self themedWindowStyle]; |
425 BOOL incognito = windowStyle & THEMED_INCOGNITO; | 352 BOOL incognito = windowStyle & THEMED_INCOGNITO; |
426 | 353 |
427 if (incognito) | 354 if (incognito) |
428 return [NSColor whiteColor]; | 355 return [NSColor whiteColor]; |
429 else | 356 else |
430 return [NSColor windowFrameTextColor]; | 357 return [NSColor windowFrameTextColor]; |
431 } | 358 } |
432 | 359 |
433 @end | 360 @end |
OLD | NEW |