<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Cocoa Tips and Tricks</title>
	
	<link>http://cocoatutorial.grapewave.com</link>
	<description>Penetrating the Apple docs</description>
	<lastBuildDate>Sun, 26 Dec 2010 20:13:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/CocoaTipsAndTricks" /><feedburner:info uri="cocoatipsandtricks" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>CocoaTipsAndTricks</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Release of Movie Reminder v1.0</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/A2MXVDsksGs/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/12/release-of-movie-reminder-v1-0/#comments</comments>
		<pubDate>Sun, 26 Dec 2010 20:13:08 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=81</guid>
		<description><![CDATA[I have been working on Android apps for a while and just released my first one! It allows you to remind yourself of movies that are upcoming.
Check it out at Android Market with the below QR code or head to the app website Movie Reminder.

]]></description>
			<content:encoded><![CDATA[<p>I have been working on Android apps for a while and just released my first one! It allows you to remind yourself of movies that are upcoming.</p>
<p>Check it out at Android Market with the below QR code or head to the app website <a href="http://www.stripedapps.com/moviereminder.html">Movie Reminder</a>.</p>
<p><img src="http://qrcode.kaywa.com/img.php?s=5&amp;d=market%3A%2F%2Fdetails%3Fid%3Dcom.stripedapps.mr.android" alt="qrcode" /></p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/A2MXVDsksGs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/12/release-of-movie-reminder-v1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/12/release-of-movie-reminder-v1-0/</feedburner:origLink></item>
		<item>
		<title>Shift It v1.1</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/JjgNr7u764Y/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/04/shift-it-v1-1/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 11:43:03 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=78</guid>
		<description><![CDATA[Hi All,
Shift It version 1.1 has just been released. It has added an auto update feature and support for multiple monitors.
Check it out at Shift It [Google Code]
]]></description>
			<content:encoded><![CDATA[<p>Hi All,<br />
Shift It version 1.1 has just been released. It has added an auto update feature and support for multiple monitors.</p>
<p>Check it out at <a href="http://code.google.com/p/shiftit">Shift It</a> [Google Code]</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/JjgNr7u764Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/04/shift-it-v1-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/04/shift-it-v1-1/</feedburner:origLink></item>
		<item>
		<title>Release of Shift It</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/aDQ81NJ6h8A/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/02/release-of-shift-it/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 03:23:01 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Application]]></category>
		<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[hot keys]]></category>
		<category><![CDATA[Shift it]]></category>
		<category><![CDATA[window management]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=66</guid>
		<description><![CDATA[Hi everyone,
I have been working on this app for a while now. Shift it is an application that will allow you to manage your windows easily. The application can shift your focused window to a particular corner of the screen or fill the whole screen. All this is done using hotkeys. The application is open [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everyone,</p>
<p>I have been working on this app for a while now. Shift it is an application that will allow you to manage your windows easily. The application can shift your focused window to a particular corner of the screen or fill the whole screen. All this is done using hotkeys. The application is open source,so you can download the source and have a go a it. The whole application was made using the previous posts. If you ever get stuck, please refer to the previous posts or leave comment here.</p>
<p>Please check out <a href="http://code.google.com/p/shiftit/">Shift It </a> and <a href="http://code.google.com/p/shiftit/wiki/HotKeys">Shift it &#8211; Hot Keys</a> for more details.</p>
<p><a href="http://mac.softpedia.com/get/Utilities/Shift-It.shtml"><img border="0" src="http://www.softpedia.com/images/softpedia_download_small.gif"/></a><br />
<a href="http://mac.softpedia.com/progClean/Shift-It-Clean-72219.html"><img src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/02/softpedia_free_award_f.gif" alt="100% Clean" title="softpedia_free_award_f" width="170" height="116" class="alignCenter size-full wp-image-74" /></a><br />
As always, <strong>any</strong> suggestions are welcome.</p>
<p>Cheers,<br />
Aravind</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/aDQ81NJ6h8A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/02/release-of-shift-it/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/02/release-of-shift-it/</feedburner:origLink></item>
		<item>
		<title>Creating and/or Removing a Login Item</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/_7Eh6Z2abnE/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/02/creating-andor-removing-a-login-item/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 23:01:53 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Login Item]]></category>
		<category><![CDATA[LSSharedFileList.h]]></category>
		<category><![CDATA[LSSharedFileListCreate]]></category>
		<category><![CDATA[LSSharedFileListInsertItemURL]]></category>
		<category><![CDATA[LSSharedFileListItemResolve]]></category>
		<category><![CDATA[Startup Item]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=57</guid>
		<description><![CDATA[
Hi all,
Today, we will look at how to programmatically add an application to the Login Items. We will also look at removing it from the Login Items.
Pre-requirements
We are going to be using the LaunchServices/LSSharedFileList.h to modify the list of login items. This is only available in OS X 10.5 and above. To support systems less [...]]]></description>
			<content:encoded><![CDATA[<hr />
Hi all,<br />
Today, we will look at how to programmatically add an application to the Login Items. We will also look at removing it from the Login Items.<br />
<strong>Pre-requirements</strong></p>
<p><strong><span style="font-weight: normal;">We are going to be using the LaunchServices/LSSharedFileList.h to modify the list of login items. This is only available in OS X 10.5 and above. To support systems less than 10.5, you would have to use Apple Events. This will not be covered in this post.</span></strong></p>
<p><strong>Methods </strong></p>
<p>There are basically four methods we will have to use to add/remove a LoginItem. One will retrieve the list of LoginItems, the second will add a new item to that list, the third will remove an item from the list and that one is used to resolve the LoginItem with an URL.</p>
<p>The following method will retrieve the list of existing LoginItems</p>
<pre><code>extern LSSharedFileListRef
  LSSharedFileListCreate(
  CFAllocatorRef   inAllocator,
  CFStringRef      inListType,
  CFTypeRef        listOptions)
</code></pre>
<p>Parameters:</p>
<ol>
<li>inAllocator - CFAllocatorRef used to allocate the LSSharedFileListRef . NULL means default allocator.</li>
<li>inListType - A constant indicating list type to create (in our case, it will be kLSSharedFileListSessionLoginItems or<br />
kLSSharedFileListGlobalLoginItems).</li>
<li>listOptions &#8211; Other options. This is generally NULL.</li>
</ol>
<p>The second that we are going to look at will insert a new Login Item into the list, if it already does not exist. If it already exists, it will just move the item to the particular location in the list specified by the <em>insertAfterThisItem</em> parameter</p>
<pre><code>extern LSSharedFileListItemRef
  LSSharedFileListInsertItemURL(
  LSSharedFileListRef       inList,
  LSSharedFileListItemRef   insertAfterThisItem,
  CFStringRef               inDisplayName,
  IconRef                   inIconRef,
  CFURLRef                  inURL,
  CFDictionaryRef           inPropertiesToSet,
  CFArrayRef                inPropertiesToClear)
</code></pre>
<p>Parameters:</p>
<ol>
<li>inList &#8211; The list to which we want to add a new Login Item.</li>
<li>insertAfterThisItem - Item after which new item has to be inserted. To insert at the beginning of<br />
the list use kLSSharedFileListItemBeforeFirst or to insert at the end of the list use kLSSharedFileListItemLast.</li>
<li>inDisplayName &#8211; Display name of the new item. Can be NULL. If NULL, it will use the application&#8217;s name.</li>
<li>inIconRef &#8211; Icon of the new item. Can be NULL. If NULL, it will use the default application icon.</li>
<li>inURL &#8211; URL of the new item. This will be the full path where the .app is found(includes <em>dummy.app</em>).</li>
</ol>
<p>The other two parameters are not that important at this point of time and they can be NULL.<br />
The third method will allow the application to be removed from the list of Login Items.</p>
<pre><code>extern OSStatus
  LSSharedFileListItemRemove(
  LSSharedFileListRef       inList,
  LSSharedFileListItemRef   inItem)
</code></pre>
<p>Parameters:</p>
<ol>
<li>inList &#8211; The list from which the item will be removed.</li>
<li>inItem &#8211; The item to be removed</li>
</ol>
<p>The last method is used to resolve the LoginItem with an URL when we are searching through the list of Login Items.</p>
<div id="_mcePaste">extern OSStatus</div>
<div id="_mcePaste">LSSharedFileListItemResolve(</div>
<div id="_mcePaste">LSSharedFileListItemRef   inItem,</div>
<div id="_mcePaste">UInt32                    inFlags,</div>
<div id="_mcePaste">CFURLRef *                outURL,</div>
<div id="_mcePaste">FSRef *                   outRef)</div>
<div></div>
<div>Parameters:</div>
<div>
<ol>
<li>inItem &#8211; The item we are trying to resolve.</li>
<li>inFlags &#8211; This is generally NULL.</li>
<li>outURL &#8211; The URL to which we are trying to resolve the item to.</li>
<li>outRef &#8211; FSRef of original item. Can be NULL.</li>
</ol>
</div>
<p><strong> Implementation</strong></p>
<p>For this example, I have created two methods. The first method will add your application to the login item and the second will remove the application from the list of Login Items.</p>
<pre><code>
-(void) addAppAsLoginItem{
	NSString * appPath = [[NSBundle mainBundle] bundlePath];

	// This will retrieve the path for the application
	// For example, /Applications/test.app
	CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; 

	// Create a reference to the shared file list.
        // We are adding it to the current user only.
        // If we want to add it all users, use
        // kLSSharedFileListGlobalLoginItems instead of
        //kLSSharedFileListSessionLoginItems
	LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL,
                                                     kLSSharedFileListSessionLoginItems, NULL);
	if (loginItems) {
		//Insert an item to the list.
		LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems,
                                                     kLSSharedFileListItemLast, NULL, NULL,
                                                     url, NULL, NULL);
		if (item){
			CFRelease(item);
                }
	}	

	CFRelease(loginItems);
}

-(void) deleteAppFromLoginItem{
	NSString * appPath = [[NSBundle mainBundle] bundlePath];

	// This will retrieve the path for the application
	// For example, /Applications/test.app
	CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; 

	// Create a reference to the shared file list.
	LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL,
                                               kLSSharedFileListSessionLoginItems, NULL);

	if (loginItems) {
		UInt32 seedValue;
		//Retrieve the list of Login Items and cast them to
		// a NSArray so that it will be easier to iterate.
		NSArray  *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &#038;seedValue);
		int i = 0;
		for(i ; i< [loginItemsArray count]; i++){
			LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[loginItemsArray
                                                                               objectAtIndex:i];
			//Resolve the item with URL
			if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &#038;url, NULL) == noErr) {
				NSString * urlPath = [(NSURL*)url path];
				if ([urlPath compare:appPath] == NSOrderedSame){
					LSSharedFileListItemRemove(loginItems,itemRef);
				}
			}
		}
		[loginItemsArray release];
	}
}</code></pre>
<p>That is it. You can basically have a preference that asks the user whether he wants the app to open at login. Depending on the answer, you can invoke one of the method. </p>
<p>Good Luck. </p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/_7Eh6Z2abnE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/02/creating-andor-removing-a-login-item/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/02/creating-andor-removing-a-login-item/</feedburner:origLink></item>
		<item>
		<title>Accessing and modifying window properties</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/DUwKsnl0bIQ/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/accessing-and-modifying-window-properties/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 04:56:01 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[AXUIElementCopyAttributeValue]]></category>
		<category><![CDATA[AXUIElementSetAttributeValue]]></category>
		<category><![CDATA[CFTypeRef]]></category>
		<category><![CDATA[NSAccessibility]]></category>
		<category><![CDATA[NSAccessibilityPositionAttribute]]></category>
		<category><![CDATA[NSAccessibilitySizeAttribute]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=47</guid>
		<description><![CDATA[In the previous two posts, we looked at how to retrieve a window that had focus and how to open a system preference pane. To recap, check out the previous two posts here and here. In this post, we will look how to retrieve certain properties of the window that we retrieve using the Accessibility [...]]]></description>
			<content:encoded><![CDATA[<hr />In the previous two posts, we looked at how to retrieve a window that had focus and how to open a system preference pane. To recap, check out the previous two posts <a href="http://cocoatutorial.grapewave.com/2010/01/opening-system-preferences-pane/">here</a> and <a href="http://cocoatutorial.grapewave.com/2010/01/retrieving-the-window-that-has-focus/">here</a>. In this post, we will look how to retrieve certain properties of the window that we retrieve using the Accessibility API. We will look at how to modify the window&#8217;s position and size so that the window will occupy the left half of the screen.<br />
<strong>Pre-Requisites</strong></p>
<div id="attachment_41" class="wp-caption alignright" style="width: 310px"><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/accessibility.png"><img class="size-medium wp-image-41" title="accessibility" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/accessibility-300x268.png" alt="" width="300" height="268" /></a><p class="wp-caption-text">Ensure the &quot;Enable access for assistive devices&quot;  is checked</p></div>
<ol>
<li>Know how to retrieve the focused window. To recap, check out the previous <a href="http://cocoatutorial.grapewave.com/2010/01/retrieving-the-window-that-has-focus/">post.</a></li>
<li>Should have checked &#8220;Enable access for assitive devices&#8221; in the Universal Access preference pane</li>
</ol>
<p><strong>Implementation</strong></p>
<p>First, we will look at how to retrieve the window&#8217;s properties. In this example, we will look at how to retrieve the window&#8217;s position and size. To make it easier to modify these properties, we create a few variables to temporarily store the properties.</p>
<pre><code>    AXUIElementRef _systemWideElement;
    AXUIElementRef _focusedApp;
    CFTypeRef _focusedWindow;
    CFTypeRef _position;
    CFTypeRef _size;
</code></pre>
<p>I have assumed that you have already initialized the _systemWideElement. If not, you can use the following line to do so.</p>
<pre><code>    _systemWideElement = AXUIElementCreateSystemWide();
</code></pre>
<p>Then, we are going to use this AXUiElement to first retrieve the app that focus. Then we will retrieve the window that has focus. After which, we can get its properties by using the following method:</p>
<pre><code>    extern AXError AXUIElementCopyAttributeValue (
        AXUIElementRef element,
        CFStringRef attribute,
        CFTypeRef *value);
</code></pre>
<p>Parameters:</p>
<ol>
<li>element &#8211; It is the system wide element</li>
<li>attribute &#8211; For this example, the attribute will be size(NSAccessibilitySizeAttribute) and position(NSAccessibilityPositionAttribute). There are a lot more attributes that you can get. Go <a title="NSAccessibility Protocol Reference" href="http://developer.apple.com/Mac/library/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSAccessibility_Protocol/Reference/Reference.html#//apple_ref/doc/uid/20000945-BCIIHIGG" target="_blank">here</a> for other properties.</li>
<li>value. This is where the value of the attribute will be copied to.</li>
</ol>
<p>Lets look at how this method can be used.</p>
<pre><code>    //Get the app that has the focus
    AXUIElementCopyAttributeValue(_systemWideElement,
                                 (CFStringRef)kAXFocusedApplicationAttribute,
                                 (CFTypeRef*)&#038;_focusedApp);

    //Get the window that has the focus
    if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedApp,
                                    (CFStringRef)NSAccessibilityFocusedWindowAttribute,
                                    (CFTypeRef*)&#038;_focusedWindow) == kAXErrorSuccess) {

	if(CFGetTypeID(_focusedWindow) == AXUIElementGetTypeID()) {
           //Get the Window's Current Position
	   if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedWindow,
                                           (CFStringRef)NSAccessibilityPositionAttribute,
                                           (CFTypeRef*)&#038;_position) != kAXErrorSuccess) {
	       NSLog(@"Can't Retrieve Window Position");
	   }
          //Get the Window's Current Size
          if(AXUIElementCopyAttributeValue((AXUIElementRef)_focusedWindow,
                                           (CFStringRef)NSAccessibilitySizeAttribute,
                                           (CFTypeRef*)&#038;_size) != kAXErrorSuccess) {
		NSLog(@"Can't Retrieve Window Size");
          }
	}
    }else {
	NSLog(@"Problem with App");
    }
</code></pre>
<p>Now that we have retrieved the position and size of the window, we will look at how to modify these properties. In the following example, we are trying to move the window to the (0,0) coordinate and fill left half of the screen. To set a property, we will use the following method,</p>
<pre><code>
    extern AXError AXUIElementSetAttributeValue (
        AXUIElementRef element,
        CFStringRef attribute,
        CFTypeRef value);
</code></pre>
<p>The parameters are the same as the <code>AXUIElementCopyAttributeValue</code> method.</p>
<pre><code>    NSPoint thePoint;
    thePoint.x = 0;
    thePoint.y = 0;
    //convert the NSPoint to CFTypeRef
    _position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&#038;thePoint));

    if(AXUIElementSetAttributeValue((AXUIElementRef)_focusedWindow,
                                    (CFStringRef)NSAccessibilityPositionAttribute,
                                    (CFTypeRef*)_position) != kAXErrorSuccess){
	NSLog(@"Position cannot be changed");
    }

    NSSize theSize;
    NSSize _fullScreenSize = [[[NSScreen mainScreen] frame] size];
    if(AXValueGetType(_size) == kAXValueCGSizeType) {
	theSize.width = ((_fullScreenSize.width)/2);
	theSize.height = _fullScreenSize.height;
       // convert from NSSize to CFTypeRef
       _size = (CFTypeRef)(AXValueCreate(kAXValueCGSizeType, (const void *)&#038;theSize));
    }

    if(AXUIElementSetAttributeValue((AXUIElementRef)_focusedWindow,
         (CFStringRef)NSAccessibilitySizeAttribute,
         (CFTypeRef*)_size) != kAXErrorSuccess){
         NSLog(@"Size cannot be modified");
    }
</code></pre>
<p>There we go! That should do it.</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/DUwKsnl0bIQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/accessing-and-modifying-window-properties/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/accessing-and-modifying-window-properties/</feedburner:origLink></item>
		<item>
		<title>Opening System Preferences Pane</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/12xXprOxufo/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/opening-system-preferences-pane/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 04:04:47 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[prefPane]]></category>
		<category><![CDATA[System Preferences]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=25</guid>
		<description><![CDATA[Hi All,
In this post, we are going to look at how to programatically open a Preference Pane in the Mac OS X. It is really simple and there are no special requirements to it. In the previous post, we saw how to retrieve the focused window using the Accessibility APIs. In this post, we are going [...]]]></description>
			<content:encoded><![CDATA[<hr />Hi All,<br />
In this post, we are going to look at how to programatically open a Preference Pane in the Mac OS X. It is really simple and there are no special requirements to it. In the previous <a href="../2010/01/retrieving-the-window-that-has-focus/" target="_blank">post</a>, we saw how to retrieve the focused window using the Accessibility APIs. In this post, we are going to add on to it by opening the Universal Access Preference pane if the user does not have assistive devices enabled.</p>
<p>Since all the preferences are stored in file with a .prefPane extension, all we basically have to do it is</p>
<pre><code>    //opening the Universal Access Preference Pane.
    [[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/UniversalAccessPref.prefPane"];</code></pre>
<p>The list of Preference Pane are the .prefPane files in the folder /System/Library/PreferencePanes/. Adding on to the previous post, we would open the Preferences if the Accessibility API is not enabled.</p>
<pre><code>    if(!AXAPIEnabled()){
        [[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/UniversalAccessPref.prefPane"];
        [NSApp terminate:self];
    }
    AXUIElementRef _systemWideElement;
    AXUIElementRef _focusedApp;
    CFTypeRef _focusedWindow;
    _systemWideElement = AXUIElementCreateSystemWide();
    AXUIElementCopyAttributeValue(_systemWideElement,
                         (CFStringRef)kAXFocusedApplicationAttribute,(CFTypeRef*)&amp;_focusedApp);
    AXUIElementCopyAttributeValue((AXUIElementRef)_focusedApp,
                         (CFStringRef)NSAccessibilityFocusedWindowAttribute,(CFTypeRef*)&amp;_focusedWindow)</code></pre>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/12xXprOxufo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/opening-system-preferences-pane/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/opening-system-preferences-pane/</feedburner:origLink></item>
		<item>
		<title>Retrieving the window that has focus</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/OO1I1P4acSw/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/retrieving-the-window-that-has-focus/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 04:02:32 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[AXUIElementCreateSystemWide]]></category>
		<category><![CDATA[Focused Window]]></category>
		<category><![CDATA[prefPane]]></category>
		<category><![CDATA[System wide element]]></category>
		<category><![CDATA[UiElement]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=19</guid>
		<description><![CDATA[In this post, we are going to look at how to retrieve the window that has focus, that does not necessarily belong to your app. For this to be possible, you MUST have enabled access for assistive devices in the “Universal Access” Preference Pane.
Firstly, we need to check if the preference has been set. To do [...]]]></description>
			<content:encoded><![CDATA[<hr />In this post, we are going to look at how to retrieve the window that has focus, that does not necessarily belong to your app. For this to be possible, you <strong>MUST </strong>have enabled access for assistive devices in the “Universal Access” Preference Pane.</p>
<div id="attachment_41" class="wp-caption aligncenter" style="width: 310px"><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/accessibility.png"><img class="size-medium wp-image-41" title="accessibility" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/accessibility-300x268.png" alt="" width="300" height="268" /></a><p class="wp-caption-text">Ensure the &quot;Enable access for assistive devices&quot; is checked</p></div>
<p>Firstly, we need to check if the preference has been set. To do this we have to use one of the Accessibility APIs.</p>
<pre><code>    Boolean AXAPIEnabled (void);</code></pre>
<p>This method returns true if the access for assistive devices have been enabled. False, otherwise. If access has not been enabled, we will inform the user to enable it and quit the app(for now. Next post we will look at how to open the preference pane).</p>
<p>Secondly, we need to create a system wide element that can listen to focused accessibility object regardless of which application is currently active.</p>
<pre><code>    AXUIElementRef AXUIElementCreateSystemWide (void);</code></pre>
<p>We have to use this element to retrieve information about the focused application and then focused window. We cannot get the focused window directly. Therefore, we have to first get the application that is in focus and the get the window that is in focus. <strong>Note</strong>: We can only get copies of the above mentioned information. To do this, we have to use the following method.</p>
<pre><code>    AXError AXUIElementCopyAttributeValue (
        AXUIElementRef element,
        CFStringRef attribute,
        CFTypeRef *value);</code></pre>
<p>The allowed attributes can be found <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Accessibility/Reference/AccessibilityCarbonRef/Reference/reference.html#//apple_ref/doc/uid/TP40001082-CH1g-DontLinkElementID_5" target="_blank">here</a>. ‘Value’ refers to the value associated with the specified attribute. Thats it folks. Now we can look at the actual implementation.</p>
<p><strong>Implementation</strong></p>
<pre><code>    AXUIElementRef _systemWideElement;
    if(!AXAPIEnabled()){
        //exit
    }
    AXUIElementRef _focusedApp;
    CFTypeRef _focusedWindow;
    _systemWideElement = AXUIElementCreateSystemWide();
    AXUIElementCopyAttributeValue(_systemWideElement,
                         (CFStringRef)kAXFocusedApplicationAttribute,(CFTypeRef*)&amp;_focusedApp);
    AXUIElementCopyAttributeValue((AXUIElementRef)_focusedApp,
                         (CFStringRef)NSAccessibilityFocusedWindowAttribute,(CFTypeRef*)&amp;_focusedWindow)</code></pre>
<p>That is all for now! Good luck. Comments are welcome.</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/OO1I1P4acSw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/retrieving-the-window-that-has-focus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/retrieving-the-window-that-has-focus/</feedburner:origLink></item>
		<item>
		<title>Adding a HotKey Listener</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/ANWgqOBsUjU/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/adding-a-hotkey-listener/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 04:00:28 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Carbon]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Eventhotkeyref]]></category>
		<category><![CDATA[HotKey]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=8</guid>
		<description><![CDATA[In this post, we will look at how to register your hot key listeners with the OS. It is not rocket science, really. All you have to do is implement one method and call two methods. First, we will look at what exactly are HotKeys. Then the three methods need to implement a HotKey and finally, [...]]]></description>
			<content:encoded><![CDATA[<hr />In this post, we will look at how to register your hot key listeners with the OS. It is not rocket science, <em>really</em>. All you have to do is implement one method and call two methods. First, we will look at what exactly are HotKeys. Then the three methods need to implement a HotKey and finally, the implementation itself.</p>
<p><strong>What are HotKeys?</strong><br />
HotKeys are combinations of key presses that user uses to take advantage of a feature. For example, the Spotlight in Mac OS X has a default HotKey of Cmd+Space. Similarly, different applications use different HotKeys to simply the usage of the application.</p>
<p><strong>Methods Required</strong></p>
<pre><code>OSStatus MyHotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent,void *userData);</code></pre>
<p>The above method is the one you would have to implement to handle the hot keys. The function name is not a issue, you can be creative with it.</p>
<pre><code>InstallApplicationEventHandler( handler, numTypes, list, userData, outHandlerRef );</code></pre>
<p>The above method will install the event handler with the OS. When the user presses the appropriate keys, the OS will invoke the handler with the userData and the EventRef.</p>
<pre><code>extern OSStatus RegisterEventHotKey(
     UInt32            inHotKeyCode,
     UInt32            inHotKeyModifiers,
     EventHotKeyID     inHotKeyID,
     EventTargetRef    inTarget,
     OptionBits        inOptions,
     EventHotKeyRef *  outRef);</code></pre>
<p>This is the method that actually registers for the HotKeys. The points below will give you some idea of how to use this method.</p>
<ol>
<li>inHotKeyModifiers: This parameter takes the key codes for the command(cmdKey),alt/option(optionKey),crtl(controlKey) and shift(shiftKey) keys. The variables in the brackets are the key codes that you would have to use. You can mix and the match the key codes. For example, you can say cmdKey+shiftKey or controlKey+cmdKey, etc…</li>
<li>inHotKeyCode: This parameter takes the virtual key codes of the keyboard. The virtual key codes can be found <a href="http://boredzo.org/blog/archives/2007-05-22/virtual-key-codes" target="_blank">here </a>. For example, if you want to use cmdKey+m as your HotKey. You would register the cmdKey in the previous parameter and the char ‘m’ in the this parameter.</li>
<li>inHotKeyID: This parameter will be used to differentiate one HotKey from another. The EventHotKeyID will contain a signature and a id. The signature is to ensure the HotKey is registered with your app and the id will identify which hot key was invoked.</li>
<li>inTarget: This is generally GetEventDispatcherTarget();</li>
<li>outRef: The EventHotKeyRef is required for the unregistering the HotKey later on. Be sure to keep track of one EventHotKeyRef for each HotKey. This will help you when you are trying to modify just one HotKey.</li>
</ol>
<p><strong>Implementation</strong><br />
First we are going to implement the method that handles the HotKey events.</p>
<pre><code>OSStatus MyHotKeyHander(EventHandlerCallRef nextHandler,EventRef theEvent,void *userData){
	//Do something once the key is pressed
	EventHotKeyID hotKeyID;
	GetEventParameter(theEvent,kEventParamDirectObject,typeEventHotKeyID,
                                        NULL,sizeof(hotKeyID),NULL,&amp;amp;hotKeyID);
	int temphotKeyId = hotKeyID.id; //Get the id, so we can know which HotKey we are handling.
        switch(temphotKeyId){
             //Now you know which HotKey. Do something...
       }
}</code></pre>
<p>Then we are going to install a ApplicationEventHandler.</p>
<pre><code>     EventTypeSpec _eventType;
     _eventType.eventClass = kEventClassKeyboard;
     _eventType.eventKind = kEventHotKeyPressed;
     InstallApplicationEventHandler(&amp;MyHotKeyHander,1,_eventType,self,NULL);
     //Here i am returning '<em>self</em>' as the user data. So when the MyHotKeyHandler
     // is called, it will contain <em>self</em> as the data. You can
     // declare any object you want and that will end up as the userData in
     // MyHotKeyHandler.</code></pre>
<p>Now the final step to register the HotKeys.</p>
<pre><code>	OSStatus error;
	EventHotKeyID hotKeyID;
	EventHotKeyRef hotKeyRef;

	hotKeyID.signature='hk';
	hotKeyID.id	= 1;

	error = RegisterEventHotKey(cmdKey+optionKey, 123 , hotKeyID,
                                 GetEventDispatcherTarget(), 0, &amp;hotKeyRef);
                                 // cmd+option+(left arrow)

	if(error){
		//handle error
	}</code></pre>
<p>If you want to unregister the HotKey, all you would have to do is call the UnregisterEventHotKey method with the EventHotKeyRef.</p>
<pre><code>        OSStatus error;
	EventHotKeyRef hotKeyRef = // The HotKeyRef for the HotKey you want to unregister;
	error = UnregisterEventHotKey(hotKeyRef);
	if(error){
		//handle error
	}
</code></pre>
<p>Thats it folks! Good luck! Comments are always welcome.</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/ANWgqOBsUjU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/adding-a-hotkey-listener/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/adding-a-hotkey-listener/</feedburner:origLink></item>
		<item>
		<title>Creating a Status Bar Application</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/a68TDP-nVXM/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 03:55:56 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Menulet]]></category>
		<category><![CDATA[NSMenuExtra]]></category>
		<category><![CDATA[Status Bar]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=4</guid>
		<description><![CDATA[This tutorial assumes you have a basic knowledge of Objective-C.  In this tutorial, we will walk-through on how to create a status bar only application for the Mac OS X. The final project can be downloaded from here.
What is a Menu Bar Extra?
They are extra menus that are visible at the right side of the [...]]]></description>
			<content:encoded><![CDATA[<hr />This tutorial assumes you have a basic knowledge of Objective-C.  In this tutorial, we will walk-through on how to create a status bar only application for the Mac OS X. The final project can be downloaded from here.</p>
<p><strong>What is a Menu Bar Extra?</strong></p>
<p>They are extra menus that are visible at the right side of the menu bar. Some of the in-built menu extras are the battery indicator, time indicator. Menu bar extras are typically used to display application/system status information. Two things to note about the Menu bar extras are that</p>
<ul>
<li>If there are too many menu bar extras, the OS will remove some of them to avoid crowding and to provide space for application menus.</li>
<li>The menu can also be disabled by the user.</li>
</ul>
<p>Some websites call this kind of application a menulet application or a status bar application.</p>
<p><strong>Implementation</strong></p>
<p>To start off, we create a new Project in Xcode.</p>
<p>Open Xcode. File-&gt;New Project. Choose the <em>“Cocoa Application” </em>and click<em> “Choose”. </em>Next, Xcode should ask you to give a name for the project. Pick a name and directory for the project. In this example, the project name will be “StatusMenuApp”. Once you have chosen a project name and location, click <em>“Save”</em>.</p>
<p>Xcode should have created a new project with some default files. The two folders “Classes” and “Resources” are the most important folders for this walk-through. You can ignore the remaining folders for this example.</p>
<p>First, we will add an NSMenu outlet in the In the StatusMenuAppAppDelegate.h to which the menus can be referenced to. Also we will add a NSStatusItem that will eventually become the status bar menu item.</p>
<pre><code>@interface StatusMenuAppAppDelegate : NSObject  {
    NSWindow *window;
    IBOutlet NSMenu *statusMenu;
    NSStatusItem * statusItem;
}
@property (assign) IBOutlet NSWindow *window;

@end
</code></pre>
<div id="attachment_29" class="wp-caption alignleft" style="width: 310px"><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/outletMenu.png"><img class="size-medium wp-image-29" title="outletMenu" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/outletMenu-300x145.png" alt="" width="300" height="145" /></a><p class="wp-caption-text">List  of &#39;Outlets&#39; available in the class</p></div>
<div id="attachment_30" class="wp-caption alignright" style="width: 310px"><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/finalMenu.png"><img class="size-medium wp-image-30 " title="finalMenu" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/finalMenu-300x253.png" alt="" width="300" height="253" /></a><p class="wp-caption-text">Final  view of nib file</p></div>
<p>We will now create the MenuItems that will be available in the application. To do this, we open the <em>MainMenu.xib</em> in the Interface Builder. For this example, we will not touch the existing Menu in nib. Drag and drop another “Menu” object from the Library into the Document window. Give each of the MenuItem a unique title. Now we have to link the Menu object to the statusMenu outlet. To do this, CTRL+click on the StatusMenuAppDelegate object and drag and release the pointer on the Menu object. This should open up a panel titled “Outlets”. This panel will show all the Outlets available in the StatusMenuAppDelegate class. In our example, there is only one outlet. Click on the ’statusMenu’ to link the Menu object to statusMenu. Finally, delete the Window object. Save the nib file and close Interface Builder.</p>
<p>Now we move on to actually creating the Status Bar Menu. In the “StatusMenuAppDelegate.m”, we override the function <em>awakeFromNib. </em>A <em>awakeFromNib</em>message is sent to every object that is loaded from a Nib(.nib or .xib) file. Firstly, we will create the NSStatusItem. To do so, we have to call</p>
<pre><code>- (NSStatusItem *)statusItemWithLength:(CGFloat)length</code></pre>
<p>The parameter <em>length</em> can take the following two values:</p>
<ol>
<li>NSVariableStatusItemLength -Makes the status item length dynamic, adjusting to the width of its contents.</li>
<li>NSSquareStatusItemLength – Sets the status item length to the status bar thickness.</li>
</ol>
<p>For this example, we will use the NSVariableStatusItemLength.</p>
<pre><code>statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain]; </code></pre>
<p>Secondly, we have to add the statusMenu to the statusItem. To do so, we all the following code:</p>
<pre><code>[statusItem setMenu:statusMenu];</code></pre>
<p>Thirdly, we give a title for the statusItem. This will be seen in the Menu Extras.</p>
<pre><code>[statusItem setTitle:@"Status"];</code></pre>
<p>If you would like to see an image instead of text, you can use the following methods:</p>
<pre><code>- (void)setImage:(NSImage *)image
-(void)setAlternateImage:(NSImage *)image</code></pre>
<p>Lastly, we want to highlight the menu when the user clicks on it. So we use the following code.</p>
<pre><code>[statusItem setHighlightMode:YES];</code></pre>
<p>By default, the highlight mode will be set to NO.</p>
<p>The StatusMenuAppDelegate.m file should look like this now.</p>
<pre><code>#import "StatusMenuAppDelegate.h"

@implementation StatusMenuAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
 // Insert code here to initialize your application
}

-(void)awakeFromNib{
 statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
 [statusItem setMenu:statusMenu];
 [statusItem setTitle:@"Status"];
 [statusItem setHighlightMode:YES];
}
@end</code></pre>
<p>Since we want the app to only appear on the status menu, the last step is the most important one.We need to modify the StatusMenu-Info.plist file. Double click to open this file. Add a new property with key “Application is agent (UIElement)” and value as TRUE(i.e. check the box). Your .plist should look like this.</p>
<div id="attachment_32" class="wp-caption aligncenter" style="width: 310px"><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/plistFinal.png"><img class="size-medium wp-image-32 " title="plistFinal" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/plistFinal-300x181.png" alt="" width="300" height="181" /></a><p class="wp-caption-text">Final  view of pList</p></div>
<p>Final output of the program should look like this:</p>
<p><a href="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/FINAL.png"><img class="aligncenter size-full wp-image-31" title="FINAL" src="http://cocoatutorial.grapewave.com/wp-content/uploads/2010/01/FINAL.png" alt="" width="167" height="103" /></a></p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/a68TDP-nVXM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/creating-a-status-bar-application/</feedburner:origLink></item>
		<item>
		<title>ARGH!!! Data Corruption</title>
		<link>http://feedproxy.google.com/~r/CocoaTipsAndTricks/~3/116sHjO6upw/</link>
		<comments>http://cocoatutorial.grapewave.com/2010/01/hello-world/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 22:53:04 +0000</pubDate>
		<dc:creator>aravind88</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cocoatutorial.grapewave.com/?p=1</guid>
		<description><![CDATA[Hi All,
There was a database corruption. I will re-post everything in the next few days
]]></description>
			<content:encoded><![CDATA[<p>Hi All,<br />
There was a database corruption. I will re-post everything in the next few days</p>
<img src="http://feeds.feedburner.com/~r/CocoaTipsAndTricks/~4/116sHjO6upw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://cocoatutorial.grapewave.com/2010/01/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://cocoatutorial.grapewave.com/2010/01/hello-world/</feedburner:origLink></item>
	</channel>
</rss>

