jeudi 17 décembre 2009

Cocoa and Tab-Modality

(Note: as regular readers know, we occasionally publish extra-geeky technical posts here on the Google Mac Blog. If this isn't your thing, don't worry; our usual non-technical stuff will be back soon.)

I'm part of the Chromium team working on Mac issues, and as I wrote on our blog, for Chromium we needed a way to provide modality to individual tabs of our web browser. Specifically, we needed to attach sheets to a Cocoa view rather than to just a Cocoa window. How would we accomplish this?

Like always, it's half following what's possible, and half sudden inspiration. What's possible? Putting a sheet on a window. That's done several ways. For an arbitrary sheet you can use
-[NSApplication beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:]. But nearly every class that can put up a sheet has its own -beginSheet: method. NSAlert has
-beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:. IKPictureTaker has

So we know that we need to hang our sheet on a window. That's where the inspiration comes in. I was talking with a fellow Mac team member who offhandedly mentioned invisible windows. Of course! If you have an invisible window that has a sheet attached, then for all practical purposes you have an independent sheet. Plus, if you make the invisible window the child window of the window that hosts the view that appears to run the sheet, then you can size the invisible window to cover the view and eat all the clicks, achieving the desired modality as well.

That was the easy part. The first implementation was quick, but quickly uncovered issues.

First, how do you hide the sheet when the view is hidden? At first I tried hiding the invisible window, but when you -orderOut: a window you kill any sheets on it. That wouldn't do. Then I remembered the good old days of the Mac Toolbox (and Cocoa before 10.3 when NSView got -setHidden:), where you'd just move windows or views off to infinity (or (-15000,-15000), whichever was closer). Exposé quickly revealed the folly of that approach. Turning the sheet's opacity to 0% worked under Leopard, but under Snow Leopard the sheet blurring effect stayed present. And if I resized the window to NSZeroSize, resizing it back to the original size wrecked the layout.

Eventually I settled on a combination that worked. First I set autoresizesSubviews of the content view of the sheet to NO, and then I resized the sheet down to nothing. Then I set the opacity to 0%. Once I set the invisible window to stop eating clicks, it all worked.

The second problem was all the different classes that provided methods to show a sheet. Even if you could get the sheet window from them, if you ran it using the NSApplication sheet method, it didn't work. A little (actually a lot) of NSInvocation magic helped smooth that issue over.

That's basically it. The API is really simple and the implementation is, if nothing else, amusing to read.

Should you go ahead and use this in your app? Probably not. This is a very specific tool for solving a very specific modality problem that we had. But if you have a similar modality problem, perhaps this is right for you. Give it a try and let us know what you think.

mardi 8 décembre 2009

Google Chrome for Mac goes beta!

73,804 lines of Mac-specific code and 29 developer builds later, we're excited to finally release Google Chrome for Mac in beta. We took a hefty dose of goodness from the Windows version to build a fast, polished browser for Mac -- with features such as the Omnibox (where you can both search and type in addresses), themes from artists, and most importantly, speed. Try downloading Google Chrome for Mac and see what you think.

We also took great care to make Google Chrome a native application for Mac. For example, we integrated the Keychain into Google Chrome for Mac, and incorporated Mac-style animations when you open the Bookmarks bar.

For more details on today's beta release of Google Chrome for Mac, check out the video below.

To our early users who tried the weekly developer channel builds and provided excellent feedback, we thank you. In bringing the Mac version of Google Chrome from its developer stages to a beta standard, we returned to the core principles of the Chromium project and focused on delivering rock-solid depth in a few critical areas for the browser, rather than a breadth of features that are rough around the edges. This first beta release for Mac does not yet incorporate extensions, bookmark sync, bookmark manager, and cookie manager. However, we focused on features such as sandboxing our renderer process to help provide a safer web experience for our users. We look forward to future releases of Google Chrome for Mac, which will fill in the gaps and provide a fast, clean browser for your enjoyment on Mac OS X.

Can't wait for more info? Read our frequently-updated detailed status, or keep an eye on some Mac-specific sections of the source code. Don't forget to give Google Chrome for Mac a try, and let us know what you think.

Google Chrome for Mac, on the New Tab page

Google Chrome for Mac, with an artist theme