home *** CD-ROM | disk | FTP | other *** search
/ db.tidbits.com / db.tidbits.com.tar / db.tidbits.com / getbits.acgi?tbart=07102.orig < prev    next >
Text File  |  2010-09-23  |  52KB  |  824 lines

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2.         "http://www.w3.org/TR/html4/loose.dtd">
  3.  
  4. <html lang="en">
  5. <head>
  6.     <meta http-equiv="content-type" content="text/html;charset=utf-8">
  7.     <meta http-equiv="Content-Language" content="en">
  8.     <title>TidBITS : Scripting the Unscriptable in Mac OS X</title>
  9.  
  10.     <meta name="title" content="TidBITS : Scripting the Unscriptable in Mac OS X">
  11.     <meta name="description" content="TidBITS is a free email and Web publication covering the Macintosh Internet community.">
  12.     <link rel="image_src" href="/images/tblogo9.gif" />
  13.     <meta name="keywords" content="Apple, Mac, Macintosh, Mac OS, Mac OS X, newsletter, Internet, analysis, reviews, technology, news, TidBITS, TidBITS Talk, Engst">
  14.     <link rel="Help" href="http://www.tidbits.com/about/about-tidbits.html" title="About TidBITS">
  15.     <link rel="Search" href="http://www.tidbits.com/search/" title="Search All TidBITS Content">
  16.     <link rel="Author" href="http://www.tidbits.com/about/contact-info.html" title="Contact Information">
  17.     <link rel="Contents" href="tb-issues/" title="TidBITS Issue Archive">
  18.     <link rel="alternate" type="application/rss+xml" href="http://db.tidbits.com/feeds/tidbits.rss" title="TidBITS Full Text Feed">
  19.     <link rel="alternate" type="application/rss+xml" href="http://db.tidbits.com/commentfeeds/firehose.xml" title="TidBITS Full Comments Feed">
  20.  
  21.     <link rel="stylesheet" href="/tidbits_2010_001.css" type="text/css">
  22.     <LINK rel="stylesheet" type="text/css" media="print" href="/tb-new-print.css">
  23.     <script src="/javascript/tb.js" type="text/javascript"></script>
  24.     <meta name="viewport" content="width:940">
  25.     <script type='text/javascript' src='http://db.tidbits.com/ads/delivery/spcjs.php?id=2'></script>
  26.     <script src="/javascript/prototype.js" type="text/javascript"></script>
  27. <script src="/javascript/scriptaculous.js" type="text/javascript"></script>
  28. <script src="/js-global/FancyZoom.js" type="text/javascript"></script>
  29. <script src="/js-global/FancyZoomHTML.js" type="text/javascript"></script>
  30. <script type="text/javascript"  src="http://api.recaptcha.net/js/recaptcha_ajax.js"></script>
  31.  
  32. </head>
  33. <body onLoad="setupZoom()">
  34. <!-- popup query -->
  35. <div id="big_ole_background" style="display:none"> </div>
  36. <div id="tipbits_enclosure_preview" style="display:none">
  37. <div class="tearoffbox_wide_container">
  38. <div class="tearoffbox_wide_tips">
  39.  
  40. <div class="tip_display">
  41. <div class="preview">
  42. <h6><span id="p_tips_title"></span></h6>
  43. <p id="p_tips_text"></p>
  44. <p>Visit <a href="javascript:void(0)" id="p_url"><span id="p_label"></span></a></p>
  45. <p class="credit">Submitted by <span id="p_reader"></span></p>
  46. <p><input type="submit" value="Back" name="preview_tip" onClick="preview_box('ts','tipbits_enclosure_preview'); return false;"></p>
  47. </div>
  48. </div>
  49. <div class="tearoffbox_wide_bottom_tips">
  50. </div>
  51.  
  52. </div><!-- end tearoffbox_wide_tips -->
  53. </div><!-- end tearoffbox_wide_container for tips-->
  54. <!-- end tearoff box wide -->
  55. </div><!-- end enclosure -->
  56.  
  57. <div class="popup_box_with_captcha" id="ts" style="display:none">
  58.     <div id="popup_box_thanks" style="display:none" onClick="close_popup_thanks('popup_box_thanks', 'ts')"><br>Thanks for submitting your tip! All submissions are moderated by an editor before appearing online. We've reset the form so you can enter another tip. Or you can close the tip submission box.    <div class="x_close" id="thanks_upper_right"><a href="javascript:void(0)" onmousedown="close_popup_thanks('popup_box_thanks', 'ts'); return true;">Close</a></div></div>
  59.     <div class="tip_box_format">
  60.     <div id="ts_innards" onClick="close_popup_thanks('popup_box_thanks', 'ts')">
  61.         <div class="tip_box_head">TipBITS Submission</div>
  62.         <div class="tip_box_form">        
  63.                 
  64.             <div class="tbf_row" id="ts_message_box" style="display:none">
  65.                 <div class="tbf_wide"><div class="tbf_alert" id="ts_top_message"></div></div>
  66.             </div>
  67.             <div class="spacer"></div>
  68.  
  69.             <form action="foobar.cgi" method="get" name="submit_tip">
  70.  
  71.             <div class="tbf_row"><div class="tbf_wide_extra_top not_bold">Please submit only technical tips that will help other TidBITS readers better use their Macs, iPhones, and related software and hardware. All product announcements should be sent to <a href="mailto:releases@tidbits.com">releases@tidbits.com</a>.</div></div>
  72.             <div class="spacer"></div>
  73.             <div class="tbf_row">
  74.                 <div class="tbf_left">Tip title<span class="required_field">*</span></div><div class="tbf_right"><input type="text" value="" id="tip_title_id" name="tip_title" tabindex="1"></div>
  75.             </div>
  76.             <div class="spacer"></div>
  77.             <div class="tbf_row">
  78.                 <div class="tbf_left">Your tip<span class="required_field">*</span></div><div class="tbf_right"><textarea name="tip_text" rows="3" cols="40" tabindex="2"></textarea></div>
  79.             </div>
  80.             <div class="spacer"></div>
  81.             <div class="tbf_row">
  82.                 <div class="tbf_left">URL</div><div class="tbf_right"><input type="text" value="" name="tip_link_url" tabindex="3"><span class="tip_description"><br>Enter the URL to a Web page that supports your tip.</span></div>
  83.             </div>
  84.             <div class="spacer"></div>
  85.             <div class="tbf_row">
  86.                 <div class="tbf_left">Linked text</div><div class="tbf_right"><input type="text" value="" name="tip_link_label" tabindex="4"><span class="tip_description"><br>Enter the name of the page linked above.</span></div>
  87.             </div>
  88.             <div class="spacer"></div>
  89.             <div class="tbf_row">
  90.                 <div class="tbf_left">Your name<span class="required_field">*</span></div><div class="tbf_right"><input type="text" value="" name="tip_reader_name" tabindex="5"></div>
  91.             </div>
  92.             <div class="spacer"></div>
  93.             <div class="tbf_row">
  94.                 <div class="tbf_left">Your email<span class="required_field">*</span></div><div class="tbf_right"><input type="text" value="" name="tip_reader_email" tabindex="6"></div>
  95.             </div>
  96.             <div class="spacer"></div>
  97.             <div class="spacer"></div>
  98.                 <div class="tbf_wide"><span class="fine_print"><span class="required_field">* indicates required fields</span></span></div>
  99.             <div class="spacer"></div>
  100.             <div class="tbf_row">
  101.                 <div class="tbf_wide_extra_top"><span class="fine_print">To help us avoid automated posts and spam, please enter the words below.</span></div>
  102.             </div>
  103.             <div class="spacer"></div>
  104.             <div class="tbf_row">
  105.                 <div class="tbf_wide"><div id="ts_recaptcha"></div></div>
  106.             </div>
  107.             <div class="spacer"></div>
  108.             <div class="tbf_row">
  109.                 <div class="tbf_wide"><input type="submit" value="Preview Your Tip" name="preview_tip" onClick="fill_preview('tipbits_enclosure_preview', 'ts', this.form); return false;" tabindex="7"> <input type="submit" value="Send Us Your Tip!" name="submit_this_tip" onClick="handle_tip_submission('ts', '', this.form, 'tip'); return false;" tabindex="8"></div>
  110.             </div>
  111.             <div class="spacer"></div>
  112.             <div class="tbf_row">
  113.                 <div class="tbf_wide"><span class="fine_print">When you submit a tip, you give us permission to use it. Read <a href="javascript:void(0)" onClick="generic_show_hide('tip_terms')">our terms</a> for more details. All submissions are reviewed before publication.</span></div>
  114.             </div>
  115.             
  116.             <div class="tbf_row" id="tip_terms" style="display: none">
  117.                 <div class="tbf_wide"><span class="fine_print">Our terms: By submitting a tip, you agree to assign TidBITS Publishing Inc., a non-exclusive, worldwide, perpetual license to reproduce, publish, and distribute your tip in connection with the TidBITS Web site and associated products in any media. You agree that you created the content you submitted, and that you have the right to assign us this license. You give us permission to use your name, but your email address won't be publicly displayed or shared. We review all submissions before publication, and reserve the right to select which submissions we feel are appropriate for our readers and to edit those we publish.</span></div>
  118.             </div>
  119.             <div class="spacer"></div>
  120.             </form>
  121.         </div><!-- end tip_box_form -->
  122.     </div><!-- end tip box innards -->
  123.     </div><!-- end tip box format -->
  124.     
  125.     <div class="x_close" id="ts_upper_right"><a href="javascript:void(0)" onmousedown="HidePopupContent('ts', 'ts', ''); return true;">Close</a></div>
  126.     
  127. </div><!-- end tip_submit box-->
  128.  
  129. <div class="popup_box_with_captcha" id="article_reference" style="display:none"><div class="article_ref_format"><textarea style="width:350px; height:100px;" name="article_ref" id="article_ref_box"></textarea></div>    <div class="x_close" id="article_reference_upper_right"><a href="javascript:void(0)" onmousedown="HidePopupContent('article_reference', 'article_reference', ''); return true;">Close</a></div>
  130. </div>
  131.  
  132. <div class="popup_box_with_captcha" id="comm" style="display:none">
  133.     <div class="tip_box_format">
  134.     <div id="comment_thanks" style="display:none" onClick="close_popup_thanks('comment_thanks', 'comm')"><br>Thanks for submitting a comment! Please check your email for a link that, when clicked, will verify that you're a real person and cause your comment to appear immediately. <div class="x_close" id="comment_upper_right"><a href="javascript:void(0)" onmousedown="close_popup_thanks('comment_thanks', 'comm'); return true;">Close</a></div></div>
  135.     <div id="comm_innards" onClick="close_popup_thanks('comment_thanks', 'comm')">
  136.         <div class="tip_box_head" id="comm_headline">Post a Comment</div>
  137.         <div class="tip_box_form">        
  138.                 
  139.             <div class="tbf_row" id="comm_message_box" style="display:none">
  140.                 <div class="tbf_wide"><div class="tbf_alert" id="comm_top_message"></div></div>
  141.             </div>
  142.             <div class="spacer"></div>
  143.  
  144.             <form action="foobar.cgi" method="get" name="post_comment" id="post_comment">
  145.             <input type="hidden" name="comment_nest" value=''>
  146.             <input type="hidden" name="comment_id" value=''>
  147.             <input type="hidden" name="article_id" value='5716'>
  148.             <input type="hidden" name="edit" value=''>
  149.             <div class="tbf_row">
  150.                 <div class="tbf_left">In reply to</div>
  151.                 <div class="tbf_right">
  152.                     <div id="cb_quoted_row">
  153.                         <div class='cb_open_quote'>“</div>
  154.                         <div id="cb_quoted"></div>
  155.                         <div class='cb_close_quote'>”</div>
  156.                     </div>
  157.                     <div class="spacer"></div>
  158.                 </div>
  159.             </div>
  160.             <div class="spacer"></div>
  161.  
  162.             <div class="tbf_row">
  163.                 <div class="tbf_left" style="padding-top:0">Your comment</div>
  164.                 <div class="tbf_right"><textarea tabindex="1" name="cb_item_add" id="cb_item_add" rows="4" cols="50" onKeyDown="count_insert('cb_item_add','cb_char_count')"></textarea><br><div class="cb_char_count" id="cb_add_count">Remaining characters: <span id="cb_char_count">0</span></div></div>
  165.             </div>
  166.             <div class="spacer"></div>            
  167.  
  168.             <div class="tbf_row">
  169.                 <div class="tbf_left">Your name</div><div class="tbf_right" style="margin-top:8px"><input tabindex="2" type="text" value="" name="cb_add_name" id="cb_add_name" style="margin-top: -4px"></div>
  170.             </div>
  171.             <div class="spacer"></div>
  172.             
  173.             <div class="tbf_row">
  174.                 <div class="tbf_left">Your email</div><div class="tbf_right"><input tabindex="3" type="text" name="cb_add_email" id="cb_add_email"></div>
  175.             </div>
  176.             <div class="spacer"></div>
  177.             
  178.             <div class="tbf_row">
  179.                 <div class="tbf_left"> </div><div class="tbf_right"><input id="comm_post_comment" tabindex="4" type="submit" value="Post Comment" name="submit_this_comment" style="width:100px; float:right" onClick="cb_post_submit(); return false;"></div>
  180.             </div>
  181.             <div class="spacer"></div>
  182.             
  183.             <div class="tbf_row" id="comment_terms">
  184.                 <div class="tbf_wide"><span class="fine_print">Our terms: We reserve the right to edit or delete any comment, so please post thoughtfully. We use your email address <i>only</i> to send you a one-time verification message confirming that you posted this comment. We also store your address to allow you to verify using other Web browsers in the future. For more info, see our <a href="http://db.tidbits.com/privacy.html">privacy policy</a>.</span></div>
  185.             </div>
  186.             <div class="spacer"></div>
  187.  
  188.             </form>
  189.         </div><!-- end comm_form -->
  190.     </div><!-- end comm box innards -->
  191.     </div><!-- end comm box format -->
  192.     
  193.     <div class="x_close" id="comm_upper_right"><a href="javascript:void(0)" onmousedown="HidePopupContent('comm', 'comm', ''); return true;">Close</a></div>
  194.     
  195. </div><!-- end comm_submit box-->
  196.  
  197.  
  198. <!-- start mainbody -->
  199. <div id="mainbody">
  200.  
  201. <!-- start header -->
  202. <div id="header">
  203.  
  204.  
  205.  
  206.     <div id="tblogo">
  207.     <a href="/"><img src="/images/tblogo20_01.gif" alt="TidBITS: Apple News for the Rest of Us" width="177" height="84" border="0"></a>
  208.  
  209.     </div><!-- end tblogo -->
  210.  
  211.  
  212. <!-- leaderboard ad -->
  213. <div id="top_banner">
  214. <script type='text/javascript'><!--// <![CDATA[
  215.     OA_show(3);
  216. // ]]> --></script><noscript><a target='_blank' href='http://db.tidbits.com/ads/delivery/ck.php?n=TBe5f7021'><img border='0' alt='' src='http://db.tidbits.com/ads/delivery/avw.php?zoneid=3&n=TBe5f7021'></a></noscript>
  217. </div><!-- end top_banner style -->
  218. <!-- end leaderboard ad -->
  219.  
  220.  
  221. </div><!-- end header  -->
  222.  
  223.  
  224. <!-- start content_container -->
  225. <div id="content_container">
  226.  
  227.  
  228. <!-- begin leftcolumn -->
  229. <div id="leftcolumn">
  230.  
  231. <!-- begin leftnav /left navigation -->
  232. <div>
  233.     <ul class="leftnav">
  234.         <!-- start search -->
  235.         <li class="topcorner">
  236.             <form action="http://db.tidbits.com" method="POST" name="search_form"><input type="hidden" name="advanced_search" value=''><input type="text" name="search_text" size="8" maxlength="70" value="Search" onFocus="this.value=''" onBlur="if (this.value == '') { this.value = 'Search'; }"> <span style="margin: 0 5px 0 5px; vertical-align: -2px"><span style="vertical-align: -2px"><input type="image" name="submit_search" src="/images/go_search_button.gif"></span>  <img src="/images/adv_search_button.gif" title="Click for Advanced Search" onClick="var f = document.search_form; f.search_text.value =''; f.advanced_search.value = '1'; f.submit();"></span></form>
  237.         </li>
  238.     </ul>
  239. </div>
  240. <!-- end search -->
  241.  
  242. <!-- Get TidBITS box (temp) -->
  243. <div>
  244.     <ul class="leftnav">
  245.         <li class="gettb"><strong>Get TidBITS via...</strong></li>
  246.     
  247.         <li><a href="http://www.tidbits.com/list" title="Subscribe via email" class="gettb">Email <img src="/images/gettb_button_email.gif" width="12" height="12" border="0" class="nav_img" alt="Email subscription options"></a></li>
  248.         <li><a href="/feeds/tidbits.rss" title="Subscribe via RSS" class="gettb">RSS <img src="/images/feed-icon-12x12.gif" width="12" height="12" border="0" class="nav_img" alt="Subscribe via RSS"></a></li>
  249.         <li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=276986548" title="Subscribe to the podcast" class="gettb">Podcast <img src="/images/feed-icon-12x12_podcast.gif" width="12" height="12" border="0" class="nav_img" alt="Subscribe to the postcast"></a></li>
  250.         <li><a href="http://www.twitter.com/TidBITS" title="Get Article Updates via Twitter" class="gettb">Twitter <img src="/images/feed_icon_12x12_twitter.png" width="12" height="12" border="0" class="nav_img" alt="Get Article Updates via Twitter"></a></li>
  251.         <li><a href="http://www.facebook.com/pages/TidBITS/195314925519" title="Go to the TidBITS Page at Facebook" class="gettb">Facebook <img src="/images/feed_icon_12x12_facebook.gif" width="12" height="12" border="0" class="nav_img" alt="Go to the TidBITS Page at Facebook"></a></li>
  252.     </ul>
  253. </div>
  254. <!-- end Get TidBITS box -->
  255.     
  256.     <ul class="leftnav">
  257.         <li><a href="/" class="tabhead">TidBITS Home</a></li>
  258.  
  259.         <li><a href="javascript:void(0)" title="Sections" class="tabhead" onClick="return showhide('articleslist')">Sections <span id="articleslist_triangle"><img src="/images/nav_triangle_open.gif" width="9" height="9" border="0" class="navtriangle" id="articleslist_tri_image" alt="Click to show or hide the contents of this section."></span></a></li>
  260.     
  261.     
  262.     </ul>
  263.  
  264. <div id="articleslist" style="display: none"><ul class="leftnav"><li><a href="/section/business" >Business Apps</a></li>
  265. <li><a href="/section/entertainment" >Entertainment</a></li>
  266. <li><a href="/section/links" >External Links</a></li>
  267. <li><a href="/section/home" >Home Macs</a></li>
  268. <li><a href="/section/inside" >Inside TidBITS</a></li>
  269. <li><a href="/section/iphone-ipad-ipod" >iPhone iPad iPod</a></li>
  270. <li><a href="/section/fun" >Just for Fun</a></li>
  271. <li><a href="/section/macs" >Macs & Mac OS X</a></li>
  272. <li><a href="/section/creative" >Media Creation</a></li>
  273. <li><a href="/section/net" >Networking</a></li>
  274. <li><a href="/section/opinion" >Opinion</a></li>
  275. <li><a href="/section/support" >Problem Solving</a></li>
  276. <li><a href="/section/security" >Safe Computing</a></li>
  277. <li><a href="/section/tech" >Tech News</a></li>
  278. <li><a href="/section/watchlist" >Watchlist</a></li>
  279. </ul></div>
  280.  
  281. <div>
  282. <ul class="leftnav">
  283.     <li><a href="javascript:void(0)" onClick="return showhide('stafflist')" title="Staff" class="tabhead">Staff <span id="stafflist_triangle"><img src="/images/nav_triangle_closed.gif" width="9" height="9" border="0" class="navtriangle" id="stafflist_tri_image" alt="Click to show or hide the contents of this section."></span></a></li>
  284. </ul>
  285. </div>
  286.  
  287. <div id="stafflist" style="display:block"><ul class="leftnav"><li><a href="/author/Adam+C+Engst" title="Adam Engst, Publisher">Adam Engst</a></li>
  288.     <li><a href="/author/Tonya+Engst" title="Tonya Engst, Editor in Chief">Tonya Engst</a></li>
  289.     <li><a href="/author/Jeff+Carlson" title="Jeff Carlson, Managing Editor">Jeff Carlson</a></li>
  290.     <li><a href="/author/Joe+Kissell" title="Joe Kissell, Senior Editor">Joe Kissell</a></li>
  291.     <li><a href="/author/Glenn+Fleishman" title="Glenn Fleishman, Contributing Editor">Glenn Fleishman</a></li>
  292.     <li><a href="/author/Mark+Anbinder" title="Mark Anbinder, Contributing Editor">Mark H. Anbinder</a></li>
  293.     <li><a href="/author/Matt+Neuburg" title="Matt Neuburg, Contributing Editor">Matt Neuburg</a></li>
  294.     <li><a href="/author/Rich+Mogull" title="Rich Mogull, Contributing Editor">Rich Mogull</a></li>
  295.     <li><a href="/author/Lex+Friedman" title="Lex Friedman, Staff Writer">Lex Friedman</a></li>
  296.     </ul>
  297.     </div>
  298.  
  299. <div>
  300. <ul class="leftnav">
  301.  
  302.     <li><a href="javascript:void(0)" title="Issues" class="tabhead" onClick="return showhide('issuelist')">Weekly Issues <span id="issuelist_triangle"><img src="/images/nav_triangle_closed.gif" width="9" height="9" border="0" class="navtriangle" id="issuelist_tri_image" alt="Click to show or hide the contents of this section."></span></a></li>
  303. </ul>
  304. </div>
  305.  
  306. <div id="issuelist" style="display:none"><ul class="leftnav"><li><div class="special"><form method="post" action="noaction.cgi" onsubmit="return false" id="issue_search_form" name="issue_search_form">Issue # <input type="text" onkeydown="if (event.keyCode == 13) { redirect_issue(this.form); }" id="issue_searchvalue" name="issue_number" style="width:35px; height: 10px"> <input onclick="redirect_issue(this.form)" type="image" name="submit_search" src="/images/go_search_button_blk.gif"></form></div></li><li><A HREF="/issue/674" >#674, 01 Apr 03</A></li>
  307. <li><A HREF="/issue/673" >#673, 31 Mar 03</A></li>
  308. <li><A HREF="/issue/672" >#672, 24 Mar 03</A></li>
  309. <li><A HREF="/issue/671" >#671, 17 Mar 03</A></li>
  310. <li><A HREF="/issue/670" >#670, 10 Mar 03</A></li>
  311. <li><A HREF="/issue/669" >#669, 03 Mar 03</A></li>
  312. <li><A HREF="/issue/668" >#668, 24 Feb 03</A></li>
  313. <li><A HREF="/issue/667" >#667, 17 Feb 03</A></li>
  314. <li><A HREF="/issue/666" >#666, 10 Feb 03</A></li>
  315.  
  316.  
  317. <li><a href="/backissues">Back Issues</a></li></ul></div>
  318.  
  319.  
  320. <div>
  321. <ul class="leftnav">
  322.  
  323.     <li><a href="/tidbitstalk" title="TidBITS Talk" class="tabhead">TidBITS Talk</a></li>
  324. </ul>
  325. </div>
  326.  
  327.  
  328.  
  329. <div>    
  330. <ul class="leftnav">
  331.     <li><a href="javascript:void(0)" onClick="return showhide('abouttidbits')" title="About TidBITS" class="tabhead">About TidBITS <span id="abouttidbits_triangle"><img src="/images/nav_triangle_closed.gif" width="9" height="9" border="0" class="navtriangle" id="abouttidbits_tri_image" alt="Click to show or hide the contents of this section."></span></a></li>
  332. </ul>
  333. </div>
  334.  
  335. <div id="abouttidbits" style="display:none">
  336. <ul class="leftnav"><li><a href="/about.html" title="About TidBITS">About Us</a></li><li><a href="/account.html" title="Account Help">Account Help</a></li><li><a href="/advertising.html" title="Advertise with TidBITS!">Advertise</a></li><li><a href="/contact.html" title="Contact Info">Contact</a></li><li><a href="/copyright.html" title="Copyright Terms">Copyright</a></li>
  337. </ul>
  338. </div>
  339.  
  340. <div>
  341. <ul class="leftnav">
  342. <li class="bottom"> </li>
  343. </ul>
  344. </div>
  345. <!-- end leftnav/left navigation -->
  346.  
  347. <!-- making sure nav elements hide/show before page loads --><script type="text/javascript"><!--
  348.     showhide('articleslist','show'); 
  349. // --></script>
  350.  
  351. <!-- begin sponsor_sidebox -->
  352.  
  353. <div class="sponsor_sidebox">
  354.  
  355. <ul>
  356.  
  357. <li><a href="http://www.thedatarescuecenter.com/">The Data Rescue Center</a></li>
  358.  
  359. <li><a href="http://www.smithmicro.com/tidbits">Smith Micro</a></li>
  360.  
  361. <li><a href="http://markspace.com/bits?source=tidbits">Mark/Space</a></li>
  362.  
  363. <li><a href="http://macte.ch/conf_tidbits">MacTech Conference</a></li>
  364.  
  365. <li><a href="http://www.smilesoftware.com/">Smile</a></li>
  366.  
  367. <li><a href="http://www.usefulfruit.com/tb">Useful Fruit</a></li>
  368.  
  369. <li><a href="http://www.webcrossing.com/">Web Crossing</a></li>
  370.  
  371. <li><a href="http://www.econtechnologies.com/tb">Econ Technologies</a></li>
  372.  
  373. <li><a href="http://www.tidbits.com/about/support/contributors.html">Readers Like You!</a></li>
  374.  
  375. <li><a href="http://nuance.com/dragon/mac">Nuance</a></li>
  376.  
  377. <li><a href="http://crashplan.com/ref/tidbits.html">CrashPlan</a></li>
  378.  
  379. </ul><div class='sponsor_sidebox_bottom'> </div>
  380. </div>
  381.  
  382.  
  383. <!-- end sponsor_sidebox -->
  384.  
  385.  
  386. </div> <!-- end leftcolumn div -->
  387.  
  388. <!-- end left column -->
  389.  
  390.  
  391. <!-- begin centercolumn_border -->
  392.  
  393. <div id="centercolumn_border">
  394.  
  395. <div class="center_top">Thoughtful, detailed coverage of the Mac, iPhone, and iPad, plus the best-selling <a href="http://www.takecontrolbooks.com/?pt=TB-TAGLINE" style="color:yellow">Take Control</a> ebooks.</div>
  396.  
  397. <!-- begin centercolumn -->
  398. <div id="centercolumn">
  399.  
  400.  
  401.  
  402. <!-- begin rightcolumn_container -->
  403. <div id="rightcolumn_container">
  404.  
  405. <!-- begin rightcolumn -->
  406.     <!-- rightcolumn is embedded within centercolumn so featured text wraps around it -->
  407.     <div id="rightcolumn">
  408.  
  409. <p class="top"> </p>
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420. <!-- Watchlist items -->
  421. <div class="tearoffbox_wide_container">
  422. <div class="tearoffbox_wide_watchlist">
  423. <p class="tearoffbox_wide_top_watchlist"> </p>
  424.  
  425. <h6><a href="/section/watchlist">TidBITS Watchlist</a></h6>
  426. <ul>
  427.  
  428. <LI><a href="/article/11622">DEVONthink and DEVONnote 2.0.4</a></LI>
  429.  
  430. <LI><a href="/article/11620">Security Update 2010-006</a></LI>
  431.  
  432. <LI><a href="/article/11619">TinkerTool 4.2</a></LI>
  433.  
  434. <LI><a href="/article/11618">Mailplane 2.2</a></LI>
  435.  
  436. <LI><a href="/article/11617">Pro Applications Update 2010-02</a></LI>
  437.  
  438. <LI><a href="/article/11611">Dialectic 1.7</a></LI>
  439.  
  440. <LI><a href="/article/11604">Transmit 4.1.1</a></LI>
  441.  
  442. <LI><a href="/article/11603">MarsEdit 3.1.1</a></LI>
  443.  
  444. <LI><a href="/article/11600">Savescreenie 2.0</a></LI>
  445.  
  446. <LI><a href="/article/11598">1Password 3.4.1</a></LI>
  447.  
  448. </ul>
  449.  
  450. <div class="tearoffbox_wide_bottom_watchlist"> </div>
  451.  
  452. </div><!-- end tearoffbox_wide -->
  453.  
  454. </div><!-- end tearoffbox_wide_container for watchlist items -->
  455.  
  456. <!-- begin tearoff box wide -->
  457.  
  458. <div class="tearoffbox_wide_container">
  459. <div class="tearoffbox_wide_tips">
  460.  
  461. <div class="tip_display">
  462. <div class="tips_sponsor_logo">
  463.  
  464. </div>
  465. <h6>Sleep (and Lock) Your Screen</h6>
  466. <p><p>When you are walking away from your computer, it's fairly common practice to start your screen saver and lock your screen. But did you know that there is a built-in keyboard shortcut in Mac OS X to sleep the screen?</p><p>Press Control-Shift-Eject and your monitor sleeps without engaging the screen saver.</p></p>
  467. <p>Visit <a href="http://discussions.apple.com/thread.jspa?messageID=10350660&tstart=0">Apple Support Discussions</a></p>
  468. </div>
  469.  
  470. <div class="tearoffbox_wide_bottom_tips">
  471. <div style="padding-bottom:35px"><div class="tip_display" style="float:left"><p><br><a href="/tipbits/169">Link to this tip</a></p></div><div class="tip_display" style="float:right; width:150px">
  472. <p class="credit">Submitted by<br>Lewis</p>
  473. </div></div>
  474.  
  475. </div>
  476.  
  477. <div class="tearoffbox_wide_tips_submit">
  478. <form method="post" onsubmit="return false" id="tipbits_form" name="tipbits_form" action="noaction.cgi"><p><a href="javascript:void(0)" onmousedown="ShowTipBox('ts','ts_recaptcha', 50, 'tip_title_id'); return true;">Share your own tip!</a> | <a href="javascript:void(0)" onClick="generic_show_hide('search_tipbits'); document.tipbits_form.tipbits_searchvalue.focus()">Search TipBITS</a></p>
  479. <p style="display:none" id="search_tipbits"><input type="text" onkeydown="if (event.keyCode == 13) { search_tipbits('tipbits_searchvalue'); }" id="tipbits_searchvalue" name="tipbits_searchvalue"> <a href="javascript:void(0)" onClick="search_tipbits('tipbits_searchvalue')">Search</a></p></form>
  480. </div>
  481. <div class="tearoffbox_wide_bottom_tips_submit">
  482.  
  483. </div>
  484.  
  485. </div><!-- end tearoffbox_wide_tips -->
  486. </div><!-- end tearoffbox_wide_container for tips-->
  487. <!-- end tearoff box wide -->
  488.  
  489.  
  490.  
  491. <!-- begin 300 x 250 ad -->
  492.  
  493. <div id="content_ad_square">
  494. <script type='text/javascript'><!--// <![CDATA[
  495.     OA_show(5);
  496. // ]]> --></script><noscript><a target='_blank' href='http://db.tidbits.com/ads/delivery/ck.php?n=TB7671f69'><img border='0' alt='' src='http://db.tidbits.com/ads/delivery/avw.php?zoneid=5&n=TB7671f69'></a></noscript>
  497. </div><!-- end 300 x 250 ad -->
  498.  
  499. <!-- TBTalk items -->
  500. <div class="tearoffbox_wide_container">
  501.  
  502. <div class="tearoffbox_wide_p">
  503. <p class="tearoffbox_wide_top_p"> </p>
  504.  
  505. <h5>Recent TidBITS Talk Discussions</h5>
  506. <ul>
  507.  
  508. <LI><a href="http://emperor.tidbits.com/webx?50@@.3cf95241">Alternatives to MobileMe for syncing calendars between iPad/Mac</a> (1 message)</LI>
  509.  
  510. <LI><a href="http://emperor.tidbits.com/webx?50@@.3cf94dbb">Free anti-virus for the Mac</a> (20 messages)</LI>
  511.  
  512. <LI><a href="http://emperor.tidbits.com/webx?50@@.3cf934e6">iTunes 10 syncing iPod Touch 4.1</a> (2 messages)</LI>
  513.  
  514. <LI><a href="http://emperor.tidbits.com/webx?50@@.3cf92a22">Thoughts about Ping</a> (16 messages)</LI>
  515.  
  516. </ul>
  517.  
  518. <div class="tearoffbox_wide_bottom_p"> </div>
  519.  
  520. </div><!-- end tearoffbox_wide -->
  521.  
  522. </div><!-- end tearoffbox_wide_container for TBtalk items -->
  523.  
  524. <!-- start takecontrol_ad -->
  525. <script type='text/javascript'><!--// <![CDATA[
  526.     OA_show(7);
  527. // ]]> --></script><noscript><a target='_blank' href='http://db.tidbits.com/ads/delivery/ck.php?n=TBe46d56f'><img border='0' alt='' src='http://db.tidbits.com/ads/delivery/avw.php?zoneid=7&n=TBe46d56f'></a></noscript><!-- end takecontrol_ad -->
  528.  
  529. <!-- begin tearoff box 2 -->
  530.  
  531. <div class="tearoffbox_wide_container">
  532.  
  533. <div class="tearoffbox_wide_p">
  534. <p class="tearoffbox_wide_top_p"> </p>
  535.  
  536. <h5>Related Articles</h5>
  537. <ul>
  538. <li><a href="/article/9897">Fix Your Clicks With Klicko</a> (01 Dec 08)</li>
  539. <li><a href="/article/9026">Typinator Turns Two</a> (11 Jun 07)</li>
  540. <li><a href="/article/8801">PreFab UI Browser 2.0 Better Than Ever</a> (08 Jan 07)</li>
  541. <li><a href="/article/8629">TypeIt4Me Returns Again, Again</a> (07 Aug 06)</li>
  542. <li><a href="/article/8151">You Type, It Typinates</a> (27 Jun 05)</li>
  543. <li><a href="/article/7993">QuicKeys X3 at the Crossroads</a> (21 Feb 05)</li>
  544. <li><a href="/article/7690">Ergonis's KeyCue Offers Keyboard Shortcut Cheat Sheet</a> (07 Jun 04)</li>
  545. <li><a href="/article/7320">Salling Clicker in Action</a> (25 Aug 03)</li>
  546. <li><a href="/article/7022">QuicKeys X 1.5.4 Improves Menu Selections</a> (16 Dec 02)</li>
  547. <li><a href="/article/6786">QuicKeys X 1.5 Adds Menu Support</a> (15 Apr 02)</li>
  548. <li><a href="/article/6603">QuicKeys X: The Return of the Ghost</a> (22 Oct 01)</li>
  549. <li><a href="/article/4198">Win One For the Grepper: Text Machine</a> (20 Oct 97)</li>
  550. <li><a href="/article/801">The User Over Your Shoulder - Of Macs and Macros</a> (09 Dec 96)</li>
  551.  
  552. </ul>
  553.  
  554. <p class="tearoffbox_wide_bottom_p"> </p>
  555.  
  556. </div><!-- end tearoffbox_wide -->
  557. </div><!-- end tearoffbox_wide_container -->
  558.  
  559. <!-- end tearoff box 2 -->
  560.  
  561.  
  562. <!-- begin tearoff box for series -->
  563.  
  564. <div class="tearoffbox_wide_container">
  565.  
  566. <div class="tearoffbox_wide_p">
  567. <p class="tearoffbox_wide_top_p"> </p>
  568.  
  569. <h5>Other articles in the series <a href="/series/1044">Mac Macros</a></h5>
  570. <ul>
  571. <li><a href="/article/6603">QuicKeys X: The Return of the Ghost</a> (22 Oct 01)</li>
  572. <li><a href="/article/5881">Freedom of the Button Press - OneClick 2.0</a> (03 Apr 00)</li>
  573. <li><a href="/article/5500">QuicKeys 4 Presses My Buttons</a> (09 Aug 99)</li>
  574. <li><a href="/article/838">KeyQuencer - QuicKeys Quencher?</a> (28 Oct 96)</li>
  575. <li><a href="/article/844">OneClick - A Super Utility</a> (21 Oct 96)</li>
  576. <li><a href="/article/858">Form, Function, and QuicKeys 3.5, Part 2</a> (07 Oct 96)</li>
  577. <li><a href="/article/862">Form, Function, and QuicKeys 3.5, Part 1</a> (30 Sep 96)</li>
  578. <li><a href="/article/801">The User Over Your Shoulder - Of Macs and Macros</a> (09 Dec 96)</li>
  579.  
  580. </ul>
  581.  
  582. <p class="tearoffbox_wide_bottom_p"> </p>
  583.  
  584. </div><!-- end tearoffbox_wide -->
  585. </div><!-- end tearoffbox_wide_container -->
  586.  
  587. <!-- end tearoff box -->
  588.  
  589.  
  590.  
  591.  
  592. <!-- begin tearoff box 1 -->
  593.  
  594. <div class="tearoffbox_wide_container">
  595.  
  596. <div class="tearoffbox_wide">
  597. <p class="tearoffbox_wide_top"> </p>
  598.  
  599. <h5>Published in <a href="/issue/670">TidBITS 670</a>.<br><a href="http://www.tidbits.com/list">Subscribe</a> to our weekly email edition.</h5>
  600. <ul>
  601. <li><A HREF="/article/7097">Java 1.4.1 Update</A></li>
  602. <li><A HREF="/article/7098">Keynote 1.0.1 Update</A></li>
  603. <li><A HREF="/article/7099">Security Update 2003-03-03</A></li>
  604. <li><A HREF="/article/7100">iMovie 3.0.2 Update</A></li>
  605. <li><A HREF="/article/7101">Getting Attached to Networked Storage</A></li>
  606.  
  607. </ul>
  608.  
  609. <p class="tearoffbox_wide_bottom"> </p>
  610.  
  611. </div><!-- end tearoffbox_wide -->
  612. </div><!-- end tearoffbox_wide_container -->
  613.  
  614. <!-- end tearoff box 1 -->
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622. <div id="rightcolumn_bottom">
  623.  
  624. </div>
  625.  
  626.     </div><!-- end rightcolumn -->
  627.  
  628.  
  629. </div><!-- end rightcolumn_container -->
  630.  
  631.  
  632.  
  633. <!-- featured articles -->
  634.  
  635. <div id="center_ajax_sub" class="instapaper_body">
  636.  
  637. <!-- google_ad_section_start -->
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658. <!-- issue, article, or series -->
  659.  
  660.     
  661.     
  662.     
  663.     
  664.     
  665.         
  666.     <!-- show article(s) -->
  667.     <div class="article"><a name="5716"></a>
  668.     
  669. <!-- comment initialization routine as needed -->
  670. <div class="popup_box_with_captcha" id="hc_5716" style="display: none">
  671.     <div class="tip_box_format">
  672.     <div id="hc_innards_alt_5716" style="display: none">
  673.             <div class="tbf_row">
  674.                 <div class="tbf_wide_80" id="hc_small_response_5716"></div><div class="x_close_row" id="hc_upper_right1_5716"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_5716', 'hc', '5716'); return true;">Close</a></div>
  675.  
  676.             </div>
  677.     </div>
  678.     <div id="hc_innards_5716">
  679.         <div class="tip_box_form">        
  680.             <form action="foobar.cgi" method="get" name="check_human_5716">
  681.             <div class="tbf_row">
  682.                 <div class="tbf_wide_80" id="hc_rc_5716">To help us avoid automated posts and misuse of our site, please enter the words below.</div><div class="x_close_row" id="hc_upper_right2_5716"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_5716', 'hc', '5716'); return true;">Close</a></div>
  683.  
  684.             </div>
  685.             <div class="spacer"></div>
  686.             <div class="tbf_row" id="hc_message_box_5716" style="display:none">
  687.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_5716"></div></div>
  688.             </div>
  689.             <div class="spacer"></div>
  690.             <div class="tbf_row">
  691.                 <div class="tbf_wide"><div id="hc_recaptcha_5716"></div></div>
  692.             </div>
  693.             <div class="spacer"></div>
  694.             <div class="tbf_row">
  695.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '5716', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="7102"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  696.             </div>
  697.             <div class="spacer"></div>
  698.             </form>
  699.         </div><!-- end tip_box_form -->
  700.     </div><!-- end hum box innards -->
  701.     </div><!-- end tip box format -->
  702. </div><!-- end tip_submit box-->
  703.  
  704.  
  705.  
  706.         
  707.         
  708.         <!-- specific article details here -->
  709.         
  710.         
  711.             
  712.         
  713.     
  714.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  715.         
  716.         <div class="featured_meta"><div class="meta_article">10 Mar 2003 | <a href="/article/7102?print_version=1">Print <span class="shift_up"><img src="/images/printer_icon.gif" alt="Printer-Friendly Version of This Article" border="0" width="9" height="10"></span></a></div></div>
  717.  
  718.         <H2>Scripting the Unscriptable in Mac OS X</H2>
  719.  
  720.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_5716.submit_type.value='email'; document.check_human_5716.author_id.value='7'; ShowTipBox('hc_5716', 'hc_recaptcha_5716')"><span class="shift_down"><img src="/images/gettb_button_email.gif" height="12" width="12" border="0" alt="Send Email to Author"></span></a></P>
  721.  
  722.         <!-- article text -->
  723.         
  724.         <div id="article_box_5716"><P>This is the tale of a U.S. government statute, a certain Cupertino-based computer company, and a small revolution taking place quietly on your computer, if you use Mac OS X 10.2 Jaguar.</P><P>To understand this revolution, you need to know what a macro program is. I've been writing in TidBITS about such programs for years. Simply put, there are certain frequent or repetitive computer tasks that one would like to be able to automate. This is often straightforward if the program that performs these tasks is scriptable, meaning that it responds to a repertory of AppleScript commands: you just write a script expressing what you want done. But what if the program is not scriptable?</P><P><STRONG>Of Macs and Macros, Take Two</STRONG> -- One solution that worked pretty well for me in previous incarnations of the Mac OS was to use a macro program. Such a program must hack into the Mac OS itself so as to be able to simulate the presence of a "ghost" user who can press keys and move and click the mouse just as a real user would. By stringing together such actions, the computer could sometimes be forced to make up for the lack of scriptability in certain applications. Macro programs that I formerly used include PreFab Player, QuicKeys, OneClick, and KeyQuencer.</P><P><<A HREF="http://db.tidbits.com/article/00801">http://db.tidbits.com/article/00801</A>><BR><<A HREF="http://db.tidbits.com/series/1044">http://db.tidbits.com/series/1044</A>></P><P>Now wind the clock forward to Mac OS X. The trouble here is the word "hack" in the previous paragraph. One of the main points of Mac OS X is that you can't hack the operating system; to preserve stability, Apple has abolished the kind of extensions that used to make such hacks possible. Unfortunately, this means that macro programs don't work all that well on Mac OS X. When QuicKeys was migrated to Mac OS X, I was appalled how poorly it worked. It had trouble performing certain kinds of actions, such as choosing from menus and pushing buttons; and, more important, it couldn't "see" what menu items and buttons were present, so it couldn't make intelligent decisions or wait for the right window to appear.</P><P><<A HREF="http://db.tidbits.com/article/06603">http://db.tidbits.com/article/06603</A>></P><P>These limitations, of course, were not the fault of QuicKeys. Since QuicKeys couldn't hack into Mac OS X, it could see and act only in ways permitted to it by the various legitimate application programming interfaces (APIs) provided by Apple. And Apple, concerned with stability, wasn't about to let just any old program reach in and start meddling with some other program's windows and menus. Knowing this, however, did not solve the problem; and users were left staring at QuicKeys, waiting for it to improve. It did; but not much.</P><P><<A HREF="http://db.tidbits.com/article/07022">http://db.tidbits.com/article/07022</A>><BR><<A HREF="http://db.tidbits.com/article/06786">http://db.tidbits.com/article/06786</A>></P><P>Now for the revolution. While we were all staring the wrong way - at QuicKeys - the problem was being solved by Apple itself. And the solution (in general, and for future versions of QuicKeys as well) is in place, right now. You can script unscriptable applications, manipulating their menus and windows and buttons, and typing text, right now. It's just that Apple hasn't bothered to say much about it, so few people know.</P><P><STRONG>Enter Uncle Sam</STRONG> -- How could this happen? And why did it happen? It all goes back to a U.S. statute called the Workforce Investment Act of 1998, commonly known as Section 508. This statute says that when federal agencies procure electronic information technology, that technology must give disabled people access to information that's comparable to the access it gives non-disabled people. In plain English, if you manufacture computers, and you want any government agency to be able to buy any of them, they must be fully operable by people with disabilities.</P><P><<A HREF="http://www.usdoj.gov/crt/508/508law.html">http://www.usdoj.gov/crt/508/508law.html</A>></P><P>To see what this statute might mean for Apple Computer, Inc., let's put ourselves inside the mind of someone at Apple Computer, Inc. This person is imagining a Mac being operated by someone with a disability. And he or she is thinking: "Suppose this disability is such that the user can't work with the keyboard or the mouse. Holy cow! Unless we want our government sales to be zero, we'd better provide a way, in Mac OS X, for some other device, such as one of those sip-and-puff joysticks, to be able to operate all parts of the user interface." Clearly such operation implies something far beyond merely a few keyboard shortcuts that substitute for the mouse some of the time, as in the Universal Access and Keyboard preferences panes. It means that the system itself must be able to "see" and access all the individual interface elements of any application, so as to provide a pathway whereby a joystick, or any other assistive device, can press every button and click in every text box and somehow reach every interface element that appears on the screen.</P><P><<A HREF="http://www.apple.com/macosx/jaguar/universalaccess.html">http://www.apple.com/macosx/jaguar/ universalaccess.html</A>><BR><<A HREF="http://www.abilityhub.com/mouse/joystick.htm">http://www.abilityhub.com/mouse/joystick.htm</A>></P><P>The idea, then, is this. Given any application on Mac OS X, it needs to be possible for some other application to discover what interface elements it is displaying. The other application needs to be able to "read" these elements ("There's a button that says OK") and it needs to be able to access them (click the OK button). Apple went to work on the problem, and the result, which first emerged to public view in Jaguar, is the Accessibility API. Actually, there are two things going on. Under the surface, Apple has provided some deep magic, in the operating system itself, that does the reading and the accessing of all the interface elements present on the screen. Closer to the surface, Apple has provided the API, which is a set of commands a programmer can use to take advantage of this magic.</P><P><<A HREF="http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/Accessibility/">http://developer.apple.com/techpubs/macosx/ Cocoa/TasksAndConcepts/ProgrammingTopics /Accessibility/</A>><BR><<A HREF="http://developer.apple.com/techpubs/macosx/Carbon/HumanInterfaceToolbox/Accessibility/MakingAppsAccessible/">http://developer.apple.com/techpubs/macosx/ Carbon/HumanInterfaceToolbox/ Accessibility/MakingAppsAccessible/</A>></P><P>Now stop and think about what I just said. This is all present in Jaguar, right now. So anyone can write a program that can see and access the interface elements of any other program, right now. But such a program would, in effect, be a macro program! In short, the various things QuicKeys couldn't do when it first appeared on Mac OS X, because it couldn't hack into the Mac OS, any program can now do, thanks to the Accessibility API.</P><P>But it gets better. Read on.</P><P><STRONG>Blessed (System) Events</STRONG> -- At some point, someone at Apple put two and two together, as follows. "On the one hand, we've got the Accessibility API, which lets any program access the interface elements of any other program. On the other hand, we've got AppleScript, which lets any user write a script to give commands to any scriptable program. So what would happen if we put them together? Any user would be able to write a script to give commands to a scriptable program which would use the Accessibility API to access the interface elements of any program." To see the significance of this, just take out the middle terms, and what have you got? Any user can write a script that can access the interface elements of any program. Any user can script an unscriptable program, using AppleScript! You wouldn't need any special macro program, because AppleScript itself, which is already on your computer, would become a macro language.</P><P>Of course, for this to work, there has to be that "middle term" - the go-between, the application that receives AppleScript commands and talks to the Accessibility API. That application is called System Events. It's on your computer right now, in /System/Library/Core Services. But the version of System Events that knows about the Accessibility API is probably not on your computer, because it's in beta and is not part of the standard Mac OS X release. You must download and install it separately, from Apple's GUI Scripting Web page.</P><P><<A HREF="http://www.apple.com/applescript/GUI/">http://www.apple.com/applescript/GUI/</A>></P><P>Let's try it out! There are two preliminary steps.</P><OL><LI><P>Download and install the beta version of System Events.</P></LI><LI><P>In the Universal Access preferences pane, check the box at the bottom that says "Enable access for assistive devices." This is crucial because it throws the virtual switch that brings the Accessibility API into play.</P></LI></OL><P>We'll also need an unscriptable application to operate on. For this example, we'll use my own freeware MemoryStick, so download it (and shame on you) if you haven't got it.</P><P><<A HREF="http://pages.sbcglobal.net/mattneub/downloads/MemoryStick%20Installer.dmg.gz">http://pages.sbcglobal.net/mattneub/downloads/ MemoryStick%20Installer.dmg.gz</A>></P><P>MemoryStick isn't scriptable, and was never intended to be. Nevertheless, as if by magic, we're going to open its Preferences window, find the Poll tab item, read how often MemoryStick is set to poll the system, and click the spinner up or down the right number of times so that the setting ends up at "5 seconds" - and then close the Preferences window. Ready?</P><P>Start up MemoryStick if it isn't running. Start up Script Editor (it's in /Applications/AppleScript). Paste in the following script:</P><PRE><SMALL>tell application "MemoryStick" to activatetell application "System Events"  tell application process "MemoryStick"    click menu item "Preferences..." of menu "MemoryStick" of menu bar 1    tell tab group 1 of window "MemoryStick Preferences"      click radio button "Poll"      get value of static text 3      copy the result as number to theVal      set theDec to theVal - 5      if theDec > 0 then        repeat theDec times          decrement incrementor 1        end repeat      else if theDec < 0 then        set theDec to 0 - theDec        repeat theDec times          increment incrementor 1        end repeat      end if    end tell    click button "Done" of window "MemoryStick Preferences"  end tellend tell</SMALL></PRE><P>Now run the script, and watch the fun. Don't blink, or you'll miss it!</P><P><STRONG>Future Directions</STRONG> -- By now, you're probably saying, "Wow! That was great! How can I learn to give these sorts of commands to any application, so that I can script unscriptable applications and turn AppleScript into a macro programming language?"</P><P>Luckily, there's a splendid way to do this. It's called PreFab UI Browser, the work of Scott Lawton of PreFab Software, who brought us PreFab Player and TextMachine, and Bill Cheeseman, the well-known AppleScript guru and author of Cocoa Recipes for Mac OS X. This brilliant little program uses the Accessibility API to "look" at all the interface elements of any running application, and generates the AppleScript commands you'd use to click them, read them, type into them, or whatever. It's $25 (until mid-April, when the price goes up), and a 30-day demo is available.</P><P><<A HREF="http://www.prefab.com/uibrowser/">http://www.prefab.com/uibrowser/</A>><BR><<A HREF="http://db.tidbits.com/article/04198">http://db.tidbits.com/article/04198</A>><BR><<A HREF="http://www.applescriptsourcebook.com/">http://www.applescriptsourcebook.com/</A>><BR><<A HREF="http://www.amazon.com/dp/0201878011/?tag=tidbitselectro00">http://www.amazon.com/exec/obidos/ASIN/ 0201878011/tidbitselectro00</A>></P><P>It will be interesting to see what further applications will emerge that take advantage of the Accessibility API. For example, one of my favorite utilities in earlier days was an extension that listed all the windows in all running applications, so that you could switch directly to the right window, no matter what application you were in now. Before the Accessibility API, such a utility was impossible in Mac OS X, because no application could "see" another application's windows, let alone switch amongst them - the Dock could do it, but only because it belonged to Apple and was privy to System-level secrets no one else had. But now, writing such a utility should be easy.</P><P>The story is not over, not least because both the Accessibility API and the Scripting Events beta are still young, still in development, and still buggy. Nevertheless, they do work, as the example proves; and eventually, perhaps as part of the next major update to Mac OS X, I would expect the special version of System Events to come out of beta and be made part of the standard release. Meanwhile, now that you know the secret, you can start playing with AppleScript in its wonderful new role as a macro language on Mac OS X.</P><P>As you do, keep in mind that even the Accessibility API can't perform miracles; it can't detect interface items that are not constructed by way of Mac OS X's built-in toolbox. A program that uses non-standard interface items can be written deliberately to provide Accessibility API access to them; but if it isn't, the Accessibility API is blind. For example, the Accessibility API can't see any of Microsoft Word's menus, toolbars, or even the text of a document.</P><P>Not that this matters, of course, because Microsoft Word is completely scriptable already. Which raises another point: There's no substitute for true scriptability. To write an application of any serious power without giving it the ability to be driven with AppleScript is simply poor programming practice. So, if you're able to automate some previously unscriptable area of your workflow through Accessibility API scripting, that's splendid; but if the target program is still being actively developed, please do also write to the developers and ask that they make that same functionality genuinely scriptable.</P><P class="paybits">PayBITS: If Matt's article makes a difference for what you<BR>   can script, consider sending him a few bucks via PayPal!<BR>   <<A HREF="https://www.paypal.com/xclick/business=matt%40tidbits.com">https://www.paypal.com/xclick/ business=matt%40tidbits.com</A>><BR>   Read more about PayBITS: <<A HREF="http://www.tidbits.com/paybits/">http://www.tidbits.com/paybits/</A>></P><!-- Scripting the Unscriptable in Mac OS X Matt Neuburg --></div>
  725.         
  726.  
  727.         <!-- end article text -->
  728.     
  729.         
  730.         <!-- PayBITS -->
  731.         
  732.  
  733.         
  734. <p> </p><div class="sponsorbox">
  735. <div class="sponsortext"><A HREF="http://www.usefulfruit.com/tb"><IMG SRC="http://db.tidbits.com/images/badges/pear-note-icon50x50.png" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>Pear Note 2: More complete, understandable notes on your Mac.<br />Typed notes are blended with recorded audio, video, and slides<br />to create notes that make more sense when you need them most.<br />Learn more at <<a href="http://www.usefulfruit.com/tb">http://www.usefulfruit.com/tb</a>>!</div>
  736. </div>
  737. <div class="sponsorbox_bottom"> </div>
  738.  
  739.  
  740.         <!-- comments section -->
  741.         
  742.         <!-- end comment show-->
  743.         
  744.         <!-- end comments section -->
  745.  
  746.  
  747.         <!-- end article loop details -->
  748.         
  749.         
  750.  
  751.         
  752.     </div><!-- end show article -->
  753.     
  754.     
  755.  
  756.  
  757. <!-- article_plus end -->
  758. <!--
  759. </DIV>
  760. --><!-- end main_column DIV -->
  761.  
  762.  
  763. <!-- google_ad_section_end -->
  764.  
  765. </div><!-- end center AJAX insert -->
  766.  
  767. <!-- TipBITS Search Results Lozenge -->
  768. <div id="tipbits_results_loz" style="display:none">
  769. <form method="post" onsubmit="return false" id="tipbits_form_loz" name="tipbits_form_loz" action="noaction.cgi">
  770. <div class="tip_footer">
  771. <p id="search_tipbits_loz"><input type="text" onkeydown="if (event.keyCode == 13) { search_tipbits('tipbits_searchvalue_loz', 'tipbits_results_loz'); }" id="tipbits_searchvalue_loz" name="tipbits_searchvalue_loz"> <a href="javascript:void(0)" onClick="search_tipbits('tipbits_searchvalue_loz', 'tipbits_results_loz')">Search</a></p>
  772. </div>
  773. <div class="tip_footer_bottom">
  774.  </div>
  775. </form>
  776. </div><!-- end TipBITS Search Results lozenge -->
  777.  
  778.  
  779.  
  780.  
  781. <!-- begin footer -->
  782. <div id="footer">
  783.  
  784. <div id="qr_tag_right"><div id="qr_tag_image"><img src="http://db.tidbits.com/tags/7102.png"></div><div id="qr_tag_text"><a href="http://db.tidbits.com/article/10616">What's this image?</a></div></div>
  785. <p>Special thanks to <a href="http://www.forest.net/">digital.forest</a>, our
  786. Web and mailing list host.</p>
  787. <p>Unless otherwise noted, this article is copyright © 2003 <a href="/author/Matt%20Neuburg">Matt Neuburg</a></p>
  788. <p>TidBITS is copyright © 2010 TidBITS Publishing Inc.</p>
  789. <p>Reuse governed by <a href="http://www.tidbits.com/terms/">Creative Commons License</a>.</p>
  790.  
  791. <p><a href="/about.html" title="About TidBITS">About TidBITS</a> | <a href="/account.html" title="Account Help">Account Help</a> | <a href="/advertising.html" title="Advertise with TidBITS!">Advertise with TidBITS!</a> | <a href="/contact.html" title="Contact Info">Contact Info</a> | <a href="/copyright.html" title="Copyright Terms">Copyright Terms</a></p>
  792.  
  793. </div><!-- end footer -->
  794.  
  795.  
  796. </div> <!-- end centercolumn -->
  797.  
  798. <div class="center_bottom"> </div>
  799.  
  800. </div> <!-- end centercolumn_border -->
  801.  
  802.  
  803. </div> <!-- end content_container -->
  804.  
  805. </div> <!-- end mainbody -->
  806.  
  807.  
  808. <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
  809. </script>
  810. <script type="text/javascript">
  811. _uacct = "UA-276924-3";
  812. urchinTracker();
  813. </script>
  814. <script type="text/javascript"
  815. src="http://tidbitscom.skimlinks.com/api/skimlinks.js"></script>
  816. <script type="text/javascript">
  817. var skimlinks_pub_id = '2559X585851';
  818. var skimlinks_domain = 'go.tidbits.com';
  819. skimlinks();
  820. </script>
  821. </body>
  822. </html>
  823.  
  824.