home *** CD-ROM | disk | FTP | other *** search
/ db.tidbits.com / db.tidbits.com.tar / db.tidbits.com / getbits.acgi?tbser=1044.orig < prev    next >
Text File  |  2010-09-23  |  180KB  |  1,300 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: Mac Macros</title>
  9.  
  10.     <meta name="title" content="TidBITS: Mac Macros">
  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=''>
  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/1045" >#1045, 20 Sep 10</A></li>
  307. <li><A HREF="/issue/1044" >#1044, 13 Sep 10</A></li>
  308. <li><A HREF="/issue/1043" >#1043, 06 Sep 10</A></li>
  309. <li><A HREF="/issue/1042" >#1042, 30 Aug 10</A></li>
  310. <li><A HREF="/issue/1041" >#1041, 23 Aug 10</A></li>
  311. <li><A HREF="/issue/1040" >#1040, 16 Aug 10</A></li>
  312. <li><A HREF="/issue/1039" >#1039, 09 Aug 10</A></li>
  313. <li><A HREF="/issue/1038" >#1038, 02 Aug 10</A></li>
  314. <li><A HREF="/issue/1037" >#1037, 26 Jul 10</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.smithmicro.com/tidbits">Smith Micro</a></li>
  358.  
  359. <li><a href="http://www.smilesoftware.com/">Smile</a></li>
  360.  
  361. <li><a href="http://crashplan.com/ref/tidbits.html">CrashPlan</a></li>
  362.  
  363. <li><a href="http://nuance.com/dragon/mac">Nuance</a></li>
  364.  
  365. <li><a href="http://www.usefulfruit.com/tb">Useful Fruit</a></li>
  366.  
  367. <li><a href="http://www.thedatarescuecenter.com/">The Data Rescue Center</a></li>
  368.  
  369. <li><a href="http://markspace.com/bits?source=tidbits">Mark/Space</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://www.webcrossing.com/">Web Crossing</a></li>
  376.  
  377. <li><a href="http://macte.ch/conf_tidbits">MacTech Conference</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/11625">Adobe Flash Player 10.1.85.3</a></LI>
  429.  
  430. <LI><a href="/article/11622">DEVONthink and DEVONnote 2.0.4</a></LI>
  431.  
  432. <LI><a href="/article/11620">Security Update 2010-006</a></LI>
  433.  
  434. <LI><a href="/article/11619">TinkerTool 4.2</a></LI>
  435.  
  436. <LI><a href="/article/11618">Mailplane 2.2</a></LI>
  437.  
  438. <LI><a href="/article/11617">Pro Applications Update 2010-02</a></LI>
  439.  
  440. <LI><a href="/article/11611">Dialectic 1.7</a></LI>
  441.  
  442. <LI><a href="/article/11604">Transmit 4.1.1</a></LI>
  443.  
  444. <LI><a href="/article/11603">MarsEdit 3.1.1</a></LI>
  445.  
  446. <LI><a href="/article/11600">Savescreenie 2.0</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>Printing onto Forms from Preview</h6>
  466. <p><p>Having trouble accurately printing onto pre-printed forms from Preview? First, save your file as a PDF and review it carefully onscreen, then choose Print. Next, within Preview's Print dialog, under Scaling options, select "No automatic page scaling," to ensure proper alignment with the pre-printed form.</p></p>
  467.  
  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/143">Link to this tip</a></p></div><div class="tip_display" style="float:right; width:150px">
  472.  
  473. <p class="credit">Written by<br><a href="/author/Tonya%20Engst">Tonya Engst</a></p></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.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543. <div id="rightcolumn_bottom">
  544.  
  545. </div>
  546.  
  547.     </div><!-- end rightcolumn -->
  548.  
  549.  
  550. </div><!-- end rightcolumn_container -->
  551.  
  552.  
  553.  
  554. <!-- featured articles -->
  555.  
  556. <div id="center_ajax_sub" class="instapaper_body">
  557.  
  558. <!-- google_ad_section_start -->
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579. <!-- issue, article, or series -->
  580.  
  581.     
  582.     
  583.     
  584.         <!-- start pagehead -->
  585.         <div id="pagehead">
  586.         <h2>Series: Mac Macros</h2>
  587.         <p class="pagesubtitle">Automation programs that can add speed, precision, and utility to your daily life </p>
  588.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_all_articles('2739,2675,2684,2696,2700,4175,4523,5219,5716')"><span id="showhide_arts_top">Show the full text of all articles</span></a>
  589.         </div><!-- end pagehead -->
  590.     
  591.     
  592.     
  593.         
  594.     <!-- show article(s) -->
  595.     <div class="article"><a name="2739"></a>
  596.     
  597. <!-- comment initialization routine as needed -->
  598. <div class="popup_box_with_captcha" id="hc_2739" style="display: none">
  599.     <div class="tip_box_format">
  600.     <div id="hc_innards_alt_2739" style="display: none">
  601.             <div class="tbf_row">
  602.                 <div class="tbf_wide_80" id="hc_small_response_2739"></div><div class="x_close_row" id="hc_upper_right1_2739"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2739', 'hc', '2739'); return true;">Close</a></div>
  603.  
  604.             </div>
  605.     </div>
  606.     <div id="hc_innards_2739">
  607.         <div class="tip_box_form">        
  608.             <form action="foobar.cgi" method="get" name="check_human_2739">
  609.             <div class="tbf_row">
  610.                 <div class="tbf_wide_80" id="hc_rc_2739">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_2739"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2739', 'hc', '2739'); return true;">Close</a></div>
  611.  
  612.             </div>
  613.             <div class="spacer"></div>
  614.             <div class="tbf_row" id="hc_message_box_2739" style="display:none">
  615.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_2739"></div></div>
  616.             </div>
  617.             <div class="spacer"></div>
  618.             <div class="tbf_row">
  619.                 <div class="tbf_wide"><div id="hc_recaptcha_2739"></div></div>
  620.             </div>
  621.             <div class="spacer"></div>
  622.             <div class="tbf_row">
  623.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '2739', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="801"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  624.             </div>
  625.             <div class="spacer"></div>
  626.             </form>
  627.         </div><!-- end tip_box_form -->
  628.     </div><!-- end hum box innards -->
  629.     </div><!-- end tip box format -->
  630. </div><!-- end tip_submit box-->
  631.  
  632.  
  633.  
  634.         
  635.         
  636.         <!-- specific article details here -->
  637.         
  638.         
  639.             <p class="series_number">Article 1 of 9 in series</p>
  640.         
  641.     
  642.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  643.         
  644.         <div class="featured_meta"><div class="meta_article">09 Dec 1996 | <a href="/article/801?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>
  645.  
  646.         <H2><a href="/article/801">The User Over Your Shoulder - Of Macs and Macros</a></H2>
  647.  
  648.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_2739.submit_type.value='email'; document.check_human_2739.author_id.value='7'; ShowTipBox('hc_2739', 'hc_recaptcha_2739')"><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>
  649.  
  650.         <!-- article text -->
  651.         <div id="article_blurb_2739"><p>TidBITS not long ago discussed three macro programs: QuicKeys (beginning in TidBITS-347), OneClick (in TidBITS-350), and KeyQuencer (in TidBITS-351.) Consideration of these has led me to some reflections on the state of the Mac<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('2739')">Show full article</a></span></p></div>
  652.         <div id="article_text_2739" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2739')">Hide full article</a></p><P>TidBITS not long ago discussed three macro programs: QuicKeys (beginning in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-347.html">TidBITS-347</A>), OneClick (in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-350.html">TidBITS-350</A>), and KeyQuencer (in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-351.html">TidBITS-351</A>.) Consideration of these has led me to some reflections on the state of the Mac. In the best of all possible worlds, I think, we wouldn't need macro programs at all: the Mac would be easily scriptable without them. Until then, macro programs offer much-needed relief.</P><P><STRONG>The Prison and the Promise</STRONG> -- Here's the problem: our software still rules us instead of the other way round. My Mac, full of "Grand Unified Applications" that compel me to adjust my work habits to their structures and my needs to their feature sets, sometimes feels more like a lair of corporate priests than a liberation of my individuality. The Mac has fallen short of the promise of Apple's famed "1984" commercial: despite the supposedly user-driven event loop, we remain prisoners of modalities and restricted choices.</P><P>One escape would be to write your own applications, but that would involve unnecessary reinventing of the wheel. (I do think the Mac ought to be much easier to program, but that's another story.) For most operations, programs you already own can probably perform all the needed tasks - if only they better understood your needs, or you could combine them as desired.</P><P>For example, a dozen times a day, after some Find-and-Replace operation with Nisus Writer, I press Command-S and nothing happens. Why? I'm watching the document, but the Find/Replace window is frontmost, and in Nisus Writer that disables the Save command. Now, wouldn't you think that after a while, the computer would get the idea? "Say, Matt, I notice you keep hitting Command-S with the Find/Replace window frontmost. I've been wondering - are you doing that because you'd like me to save?" Alas, the computer probably won't talk (or think) this way any time soon. So, if a program doesn't work as you want, you should be able to customize it.</P><P>[The closest attempt to this sort of agent technology is the shareware Open Sesame from Charles River Analytics, but in my testing in the past it never made any useful suggestions. If you're interested in programming by demonstration, check out Allen Cypher's Eager demos. -Adam]</P><P><<A HREF="http://www.cra.com/products/sesame/sesameinfo.html">http://www.cra.com/products/sesame/ sesameinfo.html</A>><BR><<A HREF="http://www.atg.apple.com/Allen_Cypher/Eager/Eager.html">http://www.atg.apple.com/Allen_Cypher/Eager/ Eager.html</A>></P><P><STRONG>Mapping the Mess</STRONG> -- The ability to customize programs is not built into the Mac. Rather, each program's developers must write it in such a way that its functions are exposed to public control. Loosely speaking, this makes the program "scriptable."</P><P>But no standard for customizability has taken hold. In the Mac's early days, Apple lobbied developers to accept uniformity by voluntary convention: make windows look like <EM>this</EM>, make menus work like <EM>this</EM>, make dialogs work like <EM>this</EM>. They succeeded so well that Apple's Human Interface Guidelines significantly informed the look and feel of Windows and other graphical interfaces. But Apple did not insist upon scriptability, even after System 7 made it easier.</P><P>As a result, developers often don't grasp the importance of scriptability. The MACSCRPT mailing list is a place to watch veteran scripters slapping their virtual foreheads in anguish over developers who don't "get it" - such as when a major developer challenged readers to persuade them the next version of their program should be scriptable. (If you're interested in subscribing to the MACSCRPT list, send email to <<A HREF="mailto:listserv@dartmouth.edu">listserv@dartmouth.edu</A>> with the command "subscribe macscrpt <your full name>" as the body of the message.)</P><P>I take it as axiomatic that a computer is meant to be programmed, and so ideally every program should be scriptable. But how and how much you can customize a program's behavior varies immensely. Some programs expose all their functionality, some expose only a fraction, and some expose nothing. Then there's the "platform" from which a user is enabled to command an application: a program may include its own internal scripting language, respond to commands via the Mac's messaging system (Apple events), or a mixture of both. Then there's the degree to which one may detach the program's interface from its functionality; for example, menus or dialogs might be customizable, or a program could perform tasks behind the scenes rather than in a window or in the foreground.</P><P>You can probably think of other measures of scriptability. The point is that if we made a scriptability map, existing programs would be scattered all over it. For instance, Microsoft Word 6 exposes all of its functionality through an internal scripting language (and some of it to Apple events as well), lets you customize menus, and even build new interface elements such as custom dialogs and palettes. Nisus Writer 4.1 only exposes some of its functionality through an internal scripting language (and not at all to Apple events), and its interface is only minimally customizable (keyboard shortcuts can be changed). MoviePlayer isn't scriptable. And so on.</P><P><STRONG>Scripting in Tongues</STRONG> -- The Word 6 model of complete scriptability is the exception rather than the rule: scriptability in general is frustratingly incomplete. Nisus Writer won't tell me the font or style of the current selection, and I can't tell Eudora to select message so-and-so without opening it. Word's degree of interface detachability (where I get to decide what each of its menu items does) is even rarer - perhaps Mac OS 8 will make writing this style of application easier, but I'm not holding my breath. There are also internal scripting languages which can't be hooked to other programs at all: it's maddening.</P><P>Still, suppose that every internally scriptable program also had an external hook, so scripts written in an internal scripting language could at least be sent from another program. You might think that external scriptability would be better, because every internal scripting language is different (and may not be very good), whereas external scriptability can be based on one language, such as AppleScript. However, many internal scripting languages are superb (like Excel's Visual Basic), and, almost paradoxically, AppleScript-savvy programs can each introduce their own AppleScript syntax, so scripting those programs is <EM>still</EM> like learning a new language - or even harder because the syntax usually isn't obvious or documented. (How often I've seen letters to the MACSCRPT list from people stumped on how to make Eudora delete the selected message: the magic AppleScript formula 'move message 0 to end of mailbox "Trash"' isn't obvious.) Plus, external scriptability doesn't solve the fundamental problem: you're still at the mercy of any particular program as to how much functionality it chooses to expose.</P><P><STRONG>Macro Management</STRONG> -- Customization should permit you to link a program's existing functions in new ways. It should also allow you to incorporate functions of other programs, combining the strengths of each in a milieu which can sense and respond to the state of each program, draw upon the power of the system as a whole, and support some basic programming using common types of information (such as numbers and text).</P><P>Until scriptability is more uniform, a system-level macro program is the best central command post for customization. The downside to system-level macro programs is that, no matter how well-engineered, they have the potential to expose problems and bugs in other programs or system extensions. For instance, if an application has troubles with window management, displaying a palette or a dialog box with a macro program might cause problems - even if the macro program does everything by the book. Nonetheless, a system-level macro program can type, click the mouse button, choose from menus, and generally simulate user actions so as to drive most non-scriptable or partially scriptable applications. It can intervene in normal operations, respond to user actions such as keystroke commands, deal with system information (such as what windows are present, what's on the clipboard, what files are in a folder), and talk back and forth with other scripting environments. Plus, ideally, it has genuine programmability, preferably in some easy but flexible form.</P><P>Of the three macro programs we looked at in TidBITS, WestCode's OneClick is the most programmable: its intuitive, elegant language has lots of user-simulating power, system-level functionality, and programming constructs. A comparison with HyperCard is apt because OneClick is more than just a macro program: it's a mini programming environment. The buttons you place on its palettes respond to clicks, display menus, and respond to your choices. Plus, OneClick buttons can accept text files via drag & drop; show or hide themselves; and display icons, textual information, or progress bars.</P><P>I currently resort to OneClick whenever the question pops into my mind, "Why can't this program do <EM>this</EM>?" For instance, Eudora's filters don't include an option to automate saving messages as text files based on their subject or sender: it was easy to write a OneClick button that does so. In Nisus Writer, I always had to peek at several menus to find out the font, size, and styles of the current selection: now, I have a OneClick palette that always displays that information textually. These are things that QuicKeys could never have done for me, so I've been able to dispense with QuicKeys (and other utilities as well).</P><P><<A HREF="http://www.westcodesoft.com/">http://www.westcodesoft.com/</A>></P><P>Still, OneClick requires some compromises. Like other system-level macro programs, it operates at a low level and can come to loggerheads with some applications and extensions, at least on my machine. It's also somewhat in its infancy; that's great if you want to participate in the excitement of its evolution or invest time in developing your own tools, but right now it may not have the pre-made functionality you want.</P><P>KeyQuencer is the best choice for those who want a simple interface and minimal RAM requirements, or who particularly need some of its functions (such as its remote control of other machines, printer selection, cursor animation, and so forth). Binary Software, like WestCode, is very responsive to suggestions, so this is another chance to involve yourself in a program's growth process.</P><P><<A HREF="http://www.binarysoft.com/keyquencer/keyquencer.html">http://www.binarysoft.com/keyquencer/ keyquencer.html</A>></P><P>For those who prefer something rather more tried and true - or would rather not learn a text-based language - QuicKeys remains an important option. Its use of dialogs and recording helps the user assemble functionality without feeling like any programming is going on. What's more, QuicKeys has been around and solid for a long time, and has learned to deal with many non-standard system extensions and user interfaces, though support for the product at CE seems to have weakened to a trickle.</P><P><<A HREF="http://www.cesoft.com/quickeys/qkhome.html">http://www.cesoft.com/quickeys/qkhome.html</A>></P><P>The important thing is that you can and should have a macro program so that you, not your computer, are boss. It's great so many options are available now, and you can't go really wrong with any of these programs. They can all drive unscriptable programs, they can all use Apple events to cooperate with scriptable ones, and they're all affordable. Your preference will ultimately be a matter of personal style or need. Treat yourself to one as a holiday present! You can even get more than one and combine them. Whatever you do, take control of your computer: don't let 1997 be like 1984.</P><P><STRONG>DealBITS</STRONG> -- Cyberian Outpost's deal on KeyQuencer for $33.95 ($4 off) is still available from the URL below. Note that this page doesn't explicitly say it's a deal, but it is.</P><P><<A HREF="http://www.tidbits.com/products/key-quencer.html">http://www.tidbits.com/products/key- quencer.html</A>></P><P>Also, WestCode Software has set up a deal on OneClick for TidBITS readers. You can purchase it for $59.98 ($10 off regular WestCode pricing) through the URL below:</P><P><<A HREF="http://www.tidbits.com/products/one-click.html">http://www.tidbits.com/products/one-click.html</A>></P><!-- The User Over Your Shoulder - Of Macs and Macros Matt Neuburg --></div>
  653.         <div id="article_text_bottom_2739" style="display:none">
  654.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2739')">Hide full article</a></p><div class="sponsorbox">
  655. <div class="sponsortext"><A HREF="http://www.smilesoftware.com/"><IMG SRC="http://db.tidbits.com/images/badges/SmileLogo2010-50x50.gif" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>Get more productive with software from Smile: PDFpen for<br />editing PDFs; TextExpander for saving time and keystrokes while you<br />type; DiscLabel for designing CD/DVD labels and inserts. Free demos,
  656. <br />fast and friendly customer support. <<a href="http://www.smilesoftware.com/">http://www.smilesoftware.com/</a>></div>
  657. </div>
  658. <div class="sponsorbox_bottom"> </div>
  659. </div>
  660.  
  661.         <!-- end article text -->
  662.     
  663.         
  664.  
  665.         
  666.     </div><div class="article"><a name="2675"></a>
  667.     
  668. <!-- comment initialization routine as needed -->
  669. <div class="popup_box_with_captcha" id="hc_2675" style="display: none">
  670.     <div class="tip_box_format">
  671.     <div id="hc_innards_alt_2675" style="display: none">
  672.             <div class="tbf_row">
  673.                 <div class="tbf_wide_80" id="hc_small_response_2675"></div><div class="x_close_row" id="hc_upper_right1_2675"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2675', 'hc', '2675'); return true;">Close</a></div>
  674.  
  675.             </div>
  676.     </div>
  677.     <div id="hc_innards_2675">
  678.         <div class="tip_box_form">        
  679.             <form action="foobar.cgi" method="get" name="check_human_2675">
  680.             <div class="tbf_row">
  681.                 <div class="tbf_wide_80" id="hc_rc_2675">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_2675"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2675', 'hc', '2675'); return true;">Close</a></div>
  682.  
  683.             </div>
  684.             <div class="spacer"></div>
  685.             <div class="tbf_row" id="hc_message_box_2675" style="display:none">
  686.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_2675"></div></div>
  687.             </div>
  688.             <div class="spacer"></div>
  689.             <div class="tbf_row">
  690.                 <div class="tbf_wide"><div id="hc_recaptcha_2675"></div></div>
  691.             </div>
  692.             <div class="spacer"></div>
  693.             <div class="tbf_row">
  694.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '2675', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="862"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  695.             </div>
  696.             <div class="spacer"></div>
  697.             </form>
  698.         </div><!-- end tip_box_form -->
  699.     </div><!-- end hum box innards -->
  700.     </div><!-- end tip box format -->
  701. </div><!-- end tip_submit box-->
  702.  
  703.  
  704.  
  705.         
  706.         
  707.         <!-- specific article details here -->
  708.         
  709.         
  710.             <p class="series_number">Article 2 of 9 in series</p>
  711.         
  712.     
  713.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  714.         
  715.         <div class="featured_meta"><div class="meta_article">30 Sep 1996 | <a href="/article/862?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>
  716.  
  717.         <H2><a href="/article/862">Form, Function, and QuicKeys 3.5, Part 1</a></H2>
  718.  
  719.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_2675.submit_type.value='email'; document.check_human_2675.author_id.value='7'; ShowTipBox('hc_2675', 'hc_recaptcha_2675')"><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>
  720.  
  721.         <!-- article text -->
  722.         <div id="article_blurb_2675"><p>"The question is," said Humpty Dumpty, "which is to be master - that's all."       - Lewis CarrollPerfecting the relationship between form and function is no easy thing for a software developer<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('2675')">Show full article</a></span></p></div>
  723.         <div id="article_text_2675" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2675')">Hide full article</a></p><blockquote><P>"The question is," said Humpty Dumpty, "which is to be master - that's all."<BR>       - Lewis Carroll</P></blockquote><P>Perfecting the relationship between form and function is no easy thing for a software developer. To be sure, no amount of graphical bells and whistles can compensate for flawed functionality. Nevertheless, there's no denying that interface makes a difference - a huge difference. No matter how valuable a particular feature, if triggering its performance involves steps too numerous, obscure, counter-intuitive, repetitive, annoying, or daunting (for reasons rooted in the peculiarities of the human psyche), people won't use it, or (if they must) they'll dislike it.</P><P>CE Software's QuicKeys (QK) first appeared in 1987; TidBITS has been mentioning it since version 2.0 came out in mid-1990 (issue #16!). [In part, this is because QuicKeys played an invaluable role in the weekly distribution of TidBITS for our first five years. -Adam] Its function is to help you get round the formal shortcomings of other programs. It's splendid that CE has recently promulgated QK 3.5, even though 3.5 is primarily an "interfacelift." The current version, 3.0, has been in place since mid-1993. In this first part of a two-part article, we'll provide a general description of QK 3.5; next week, we'll put this upgrade under the microscope.</P><P><STRONG>Baby, You Can Drive My Computer</STRONG> -- QK's function centers on an extension which can perform certain fundamental Macintosh actions - hit a key, choose a menu item, click or drag the mouse, open a file - as if there were an invisible user at the controls. Its form comes from the various ways you can access, or trigger, that functionality, such as by pressing a certain keystroke, and from the dialogs that let you configure QK by associating a particular trigger with a particular action.</P><P>Why is this useful? Four main reasons come to mind. But, before I describe them, I should explain that a QK action is either "universal" to the computer as a whole or specific to a particular application. An application-specific action and its keystroke are available only when that particular application is frontmost. This means the same key combination can be used to trigger different QK effects in different applications, or a keystroke can invoke a universal action regardless of the application. You can have application-specific keystrokes override or nullify universal ones: thus, a universal keystroke could be made to apply to all but one particular application.</P><UL><LI><p>The first use of QK would be to customize an application so that it behaves more like other applications, reducing the number of different keyboard shortcuts I must memorize. For instance, I sometimes use an application which does not use Command-W as the keyboard shortcut for closing the frontmost window; instead, it uses it to mean Save. But I have a habit of using Command-W to mean Close, and Command-S to mean Save. So, I set up QK so that, in this application, when I hit Command-W, QK closes the window (by clicking its close box), and when I hit Command-S, it saves the document (by choosing the Save menu item).</p><LI><p>Secondly, sometimes QK can perform a basic function that an application cannot. For instance, some applications have no menu command to move the frontmost window to the back, bringing the next window to the front. QK can perform this action in any application, so I can use the same keystroke to perform it universally.</p><LI><p>Third, substituting a keystroke action for a mouse action saves me both time and muscle strain. Many applications lack a command to scroll the window up or down, or jump to the start or end of the document; one must click in the scrollbar. With QK, I press a key, and QK does the clicking.</p><LI><p>Fourth, QK can string actions together. Such a string is called a "sequence." Where you find yourself performing the same set of actions repetitively, QK may be able to perform them for you. Are there certain phrases which, for one reason or another, you often use in your email? A single action from you, and QK can type any of them. Do you sometimes need to silence your computer quickly? You hit one keystroke, and QK opens the Sound control panel, chooses Volumes from the pop-up menu, clicks the Mute button, and closes the control panel. Are there certain combinations of font and size that you frequently use? No need to select twice from the menubar each time you change; you perform one action, QK does the rest.</p></UL><P>Sequences can help you circumvent an application's irritating interface, too. When I used CE's QuickMail 3.5, the steps required to address a new message to go out over the Internet were numerous and tedious; as I recall, you had to ask to address the email, click the "special" button, type something in the "first name" box, replace the contents of the "server" box with "Internet", type the address in the "address" box, click OK, and click OK again. With QK, a single keystroke triggered a sequence that created and addressed a new Internet email from the contents of the clipboard.</P><P><STRONG>Hiyo, Trigger</STRONG> -- Sooner or later you will run out of easily remembered keystrokes to serve as triggers; and over the years QK has evolved various additional types of triggering event.</P><P>One of these is Time: the action is performed in response to the arrival of a certain moment. Time, for QK, can be reckoned absolutely or in seconds from the startup of a particular application (or the Mac as a whole). Using absolute reckoning, you might have your Mac perform unattended routine actions, such as running a disk optimization or a backup once a week late at night. Using application-relative reckoning, you might automate responses to an application starting up, like clicking away a splash screen or dialog.</P><P>You can also trigger actions by choosing from a special QuicKeys menu. This menu can appear hierarchically in your Apple menu, in the menubar, and/or as a pop-up menu. You decide which QK actions should appear in the menu, and at any moment the menu limits itself to universal actions plus those specific to the frontmost application.</P><P>There is also the reference card, a QK action which, when triggered, displays a modal dialog containing all currently available QK actions; clicking one triggers it. The reference card is also good for reminding you of specific keystrokes for actions (the QK menu listing doesn't).</P><P>You can also create a tiny double-clickable application to trigger a QK action; such an application is like an alias, and can be located and started up in the same convenient ways.</P><P>In mid-1992, QK 2.1.2 introduced a new type of trigger, SoftKeys. This was itself a QK action which, when triggered, displayed a previously configured modal dialog consisting of ten buttons, numbered 1 through 0 as on the top row of your keyboard, plus the name of a QK action written next to each. Clicking a button or typing the corresponding number-key dismissed the dialog and triggered that QK action. Since the QK action triggered through a SoftKeys dialog might be to put up a different SoftKeys dialog, you could have a series of such dialogs referencing one another until you reached the action you actually wanted to perform. SoftKeys was supposed to bring your various QK actions under a convenient category-based control, but in reality it was horribly reminiscent of those DOS-based successions of modal "menus" that many of us switched to the Mac to escape from in the first place.</P><P>In 3.5, QK has wisely abandoned SoftKeys, and sensibly implemented toolbars take its place. Toolbars can be universal or application-specific; an application can have multiple toolbars. You can customize the icons, and there is "hot help," with the name of the QK action appearing when the mouse is over its icon. Toolbars come in three types. The first two are "floating" (windoid) and "embedded" (movable but docked to the edge of the screen); their visibility can be toggled by a keystroke or in the QK menu (the floating type can also be clicked away), and is contextual in that a visible application-specific toolbar vanishes when you leave that application and reappears when you re-enter that application. The third toolbar type is "click-and-go," which behaves more like SoftKeys did: you must invoke it to make it visible, and it vanishes when you click an icon.</P><P>Some Mac users have strong negative feelings about toolbars in general, but no one is compelled to use this feature; others will surely welcome the capacity to add powerful customized toolbars to any application. I hope users will be able to navigate the toolbar editing interface, though; it's confusing and clumsy. For instance, you can't create or edit an action while you're working on a toolbar; and you're able to install in a toolbar destined for one application an icon for an action belonging to another application (clicking it does nothing).</P><P><STRONG>Cliffhanger</STRONG> -- So much for what QK 3.5 does. But what about what you must do to configure it? How well does QK fit in with other ways of driving your Mac, such as AppleScript? And how good is 3.5 as an upgrade? Find out when this article continues next week!</P><!-- Form, Function, and QuicKeys 3.5, Part 1 Matt Neuburg --></div>
  724.         <div id="article_text_bottom_2675" style="display:none">
  725.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2675')">Hide full article</a></p><div class="sponsorbox">
  726. <div class="sponsortext"><A HREF="http://nuance.com/dragon/mac"><IMG SRC="http://db.tidbits.com/images/badges/dragondictatelockup_vertical_onlight.png" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>Dragon speech recognition software for Macintosh, iPhone, and iPad!<br />Get the all-new Dragon Dictate for Mac from Nuance Communications<br />and experience Simply Smarter Speech Recognition.<br />Learn more about Dragon Dictate: <<a href="http://nuance.com/dragon/mac">http://nuance.com/dragon/mac</a>></div>
  727. </div>
  728. <div class="sponsorbox_bottom"> </div>
  729. </div>
  730.  
  731.         <!-- end article text -->
  732.     
  733.         
  734.  
  735.         
  736.     </div><div class="article"><a name="2684"></a>
  737.     
  738. <!-- comment initialization routine as needed -->
  739. <div class="popup_box_with_captcha" id="hc_2684" style="display: none">
  740.     <div class="tip_box_format">
  741.     <div id="hc_innards_alt_2684" style="display: none">
  742.             <div class="tbf_row">
  743.                 <div class="tbf_wide_80" id="hc_small_response_2684"></div><div class="x_close_row" id="hc_upper_right1_2684"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2684', 'hc', '2684'); return true;">Close</a></div>
  744.  
  745.             </div>
  746.     </div>
  747.     <div id="hc_innards_2684">
  748.         <div class="tip_box_form">        
  749.             <form action="foobar.cgi" method="get" name="check_human_2684">
  750.             <div class="tbf_row">
  751.                 <div class="tbf_wide_80" id="hc_rc_2684">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_2684"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2684', 'hc', '2684'); return true;">Close</a></div>
  752.  
  753.             </div>
  754.             <div class="spacer"></div>
  755.             <div class="tbf_row" id="hc_message_box_2684" style="display:none">
  756.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_2684"></div></div>
  757.             </div>
  758.             <div class="spacer"></div>
  759.             <div class="tbf_row">
  760.                 <div class="tbf_wide"><div id="hc_recaptcha_2684"></div></div>
  761.             </div>
  762.             <div class="spacer"></div>
  763.             <div class="tbf_row">
  764.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '2684', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="858"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  765.             </div>
  766.             <div class="spacer"></div>
  767.             </form>
  768.         </div><!-- end tip_box_form -->
  769.     </div><!-- end hum box innards -->
  770.     </div><!-- end tip box format -->
  771. </div><!-- end tip_submit box-->
  772.  
  773.  
  774.  
  775.         
  776.         
  777.         <!-- specific article details here -->
  778.         
  779.         
  780.             <p class="series_number">Article 3 of 9 in series</p>
  781.         
  782.     
  783.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  784.         
  785.         <div class="featured_meta"><div class="meta_article">07 Oct 1996 | <a href="/article/858?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>
  786.  
  787.         <H2><a href="/article/858">Form, Function, and QuicKeys 3.5, Part 2</a></H2>
  788.  
  789.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_2684.submit_type.value='email'; document.check_human_2684.author_id.value='7'; ShowTipBox('hc_2684', 'hc_recaptcha_2684')"><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>
  790.  
  791.         <!-- article text -->
  792.         <div id="article_blurb_2684"><p>Last week in TidBITS-347, the first part of this article described CE Software's QuicKeys (QK) and mentioned a new feature of the recent 3.5 release: toolbar triggers<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('2684')">Show full article</a></span></p></div>
  793.         <div id="article_text_2684" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2684')">Hide full article</a></p><P>Last week in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-347.html">TidBITS-347</A>, the first part of this article described CE Software's QuicKeys (QK) and mentioned a new feature of the recent 3.5 release: toolbar triggers. Here, we conclude with some serious evaluation.</P><P><STRONG>Creative Constraint</STRONG> -- For QK to be usable, the process of creating or editing a QK action must be simple and convenient. You want to spend your time using the computer, not configuring a program that makes it easier to use. Many actions are going to be spur-of-the-moment, ad hoc creations; if you're copying a series of pictures to the Scrapbook, you won't add automation to the process unless that's faster and more convenient than just finishing the job by hand.</P><P>Nonetheless, QK users over the years have had to put up with varying degrees of inconvenience and confusion in the interface used to create and edit actions. QK actions come in various types, and the desired type must be chosen from a poorly structured hierarchical menu. Many action types are created and edited via awkwardly designed dialog boxes, which often lead to other dialogs, all of which are modal and block one's view of things on the screen, including each other. (In 3.5, the main dialog is now movable and resizable, but it's still modal, and since windows behind it don't update, moving it is pointless.)</P><P>Once you've made a QK action, it isn't easy to know what it does without opening and editing it (and here come those dialogs again); you can't give an action an informative name. In some cases you can change its name, but you're limited to a few characters. In other cases you can't change the name at all. For example, an action that chooses the Close menu item and another that chooses the same menu item while pressing the Shift and Option keys (Close All in Nisus Writer) are both called Close. You can include a comment, but the comment isn't visible in the main window - you must click an action's comment icon to read it.</P><P>Assembling actions into sequences is even more daunting. In the sequence editor, you can't drag & drop an action to change its place in the sequence, and it isn't even intuitively obvious how move it by cut and paste. There's the same problem of non-descriptive action names, aggravated by the fact that there are no comments at all in the sequence editor! I don't understand why CE doesn't look at the interfaces of programs that do a successful job of letting you build sequences of editable action types; FileMaker Pro comes to mind.</P><P>For much of its history, QK sequences lacked any programming constructs, such as looping and branching; apart from calling one another (or themselves, infinitely), sequences were linear. Some clumsy if-branching appeared in version 2.1.2, and was much improved in 3.0. Version 3.5 improves the Jump command, and adds one new looping construct, the Batch Processor, which runs through all the files in a folder, opening each one and running a sequence on it. Note, though, that this won't help if what you need to do to each file doesn't involve opening it. All the branching commands remain limited as to what things QK is able to test for, and are clumsy and inconvenient to use.</P><P><STRONG>OSA, Can You CE?</STRONG> History lesson: In 1991, System 7 introduced Apple events, which enabled inter-application communication (IAC) for those applications that understood how to send and receive them. In 1992, System 7.1 added the Open Scripting Architecture (OSA), which made it possible to create alternate programming languages that operated on Apple events. And in 1993, Apple released its own such language, AppleScript.</P><P>CE responded to System 7 by incorporating into QK 2.1 an extension, CEIAC (get it?), that allowed QK to send and receive Apple events. But bare Apple events are hard to use, and the important change came in mid-1993 when QK 3.0 made three major innovations:</P><UL><LI><P>It replaced CEIAC with a faceless background application, QuicKeys Toolbox. This application, among other things, responds directly to some useful AppleScript commands.</P><LI><P>It added the ability to perform AppleScript scripts. Thus a QK action can be a place to store, and a way to trigger, an AppleScript script.</P><LI><P>It included its own recordable OSA dialect. An application that executes OSA scripts (such as Frontier, HyperCard, or Apple's Script Editor) could now talk QK's language. Instead of triggering a previously defined QK action or sequence, it sends QK a script for the action or sequence. So, from within such an application, you can take advantage of QK's "invisible user" powers to script applications that aren't AppleScript-savvy.</P></UL><P>For instance, I had an AppleScript script that copied multiple pictures from QuarkXPress and pasted them into Microsoft Word, but on the way I wanted to pass them through GraphicConverter to reduce their bit depth, and GraphicConverter isn't scriptable. So as my script handled each picture, it talked to Quark and Word in AppleScript, but in between, it talked in QK's language to make QK choose menus and click buttons in GraphicConverter.</P><P>Unfortunately, the integration between QK and other scripting dialects isn't very good, because QK has no variables, so it's hard to pass information back and forth.</P><P>For example, when I had to use Pegasus Mail, which was not scriptable, I wanted to make it automatically download each message in my mailbox from the Novell server to my hard disk, and then delete it from the server. With QK, I could select the next message and choose Save; but at this point I was faced with a blank Save dialog, and, lacking variables, there was no way QK was going to type a different filename for each message ("Temp1", "Temp2", etc.). So I had to drive QK from some other scripting application which <EM>could</EM> generate the successive filenames. I chose HyperCard. It worked, but it was tricky. On each pass through the loop, HyperCard had to let QK know the next filename; conversely, when all the messages were deleted, QK knew it (the "Save" button was no longer active), but it had to alert HyperCard to stop the loop.</P><P>Since I wrote that script, the world has progressed, but QK has not. I now handle such tasks with PreFab Player. Player has no interface: it isn't a way for the user to trigger actions and sequences directly, as QK is. But as a way for a scripting application to drive non-scriptable applications, it's better, because Player's commands are AppleScript or Frontier's UserTalk commands, so you can seamlessly use the variables and looping constructs of either of those languages; you don't have to hand any information across the OSA dialect boundary, or change dialects at all.</P><P><<A HREF="http://www.tiac.net/prefab/player.html">http://www.tiac.net/prefab/player.html</A>></P><P><STRONG>It Might Have Been</STRONG> -- For many years, QK has been a reliable workhorse in my Mac stable; I call upon it constantly to modify and automate my Mac's behavior. A computer, I am fond of saying, is to program; or at least, it is the user who should command the computer, not the other way round. QK has helped defend me from operations and application behaviors that smelt of inconvenience, of routine, of liturgical action and response, and that threatened to make me the automaton instead of the computer.</P><P>QK has long been acclaimed as a top-ranked, essential Mac tool. Yet CE was not content, in the past, to rest on its laurels. Successive releases of QK have always had an air of fiddling and tweaking, as if CE were seeking, while improving the experience of established users, to attract new converts by increased ease of use. QK 3.5, however, aside from the toolbars feature and the batch processor command, is basically a maintenance release. It's disappointing to think that, after a silence of three years, this is the best CE could come up with. In the interim, what else might CE have been doing?</P><P>CE might have resolved the nature and extent of QK's programming power. It might have improved QK's internal programming constructs, perhaps adding variables and arithmetic operations; conversely, it might have better integrated QK with existing scripting dialects. Instead, QK remains weak as an independent scripting tool and has been surpassed by PreFab Player as an AppleScript- or UserTalk-dependent one.</P><P>CE might have decided to educate and assist the user with improved manuals. Instead, the manual, which has gone steadily downhill since the sparkling clarity of the 2.0 edition (by the redoubtable Fred Terry), is now flimsy, ugly, poorly produced, skimpy, and uninformative; all printed reference information has been abandoned in favor of online help, which is in sluggish, clumsy, inappropriate Apple Guide format.</P><P>CE might have made 3.5 widely usable, but instead has cut off perhaps half the installed base by restricting this version to System 7.5 or higher.</P><P>CE might have increased QK's basic abilities. Here are some possibilities:</P><UL><LI><P>Allow QK's if-branching to "see" and test for a larger repertoire of features of a dialog. For instance, PreFab Player can see icons and read static text.</P><LI><P>Allow QK to "see" the contents of a list box in a dialog, so it could select a particular item. To take an example: if you're using something like MacJanet, where you connect over the network to a server but not through the Chooser, you must bring up a dialog, pick a zone from one list, pick a machine from another list, then click OK and type your name and password. The list of zones and machines that are online changes constantly, so you can't automate this procedure unless QK can somehow read the lists.</P><LI><P>Allow QK to take a screen shot within certain coordinates and compare it to a template. This would allow QK to "see" and test for graphic screen features it can't get at in any other way. Tempo (a rival macro program) and Ivy (a Virtual User plug-in) can do this.</P><LI><P>Allow selection from a non-QK menu to be a trigger. For instance, Alessandro Levi Montalcini's NoDesktopCleanup can interfere when you select any menu item in any application, put up a confirmation dialog, and, if you click Cancel, prevent that menu item from carrying out its usual function. QK could expand on this technique, invoking an action or sequence before, or instead of, the application's response to its own menu. This would essentially make any application "attachable."</P></UL><P><<A HREF="ftp://mirror.aol.com/pub/info-mac/gui/no-desktop-cleanup-121.hqx">ftp://mirror.aol.com/pub/info-mac/gui/no- desktop-cleanup-121.hqx</A>></P><P>Finally, CE might have made some genuine improvements to QK's interface. The new look of the main dialog and sequence editor is mere window dressing; what's needed is a rethinking of the interface, from the ground up.</P><P><STRONG>In the End</STRONG> -- QK remains a staple; I can't imagine myself doing without it. QK owners running System 7.5 or later will probably wish to upgrade, if only to take advantage of any bug fixes I don't know about. However, after three years' hiatus, both new and long-standing users deserved a more full-featured release than 3.5 has turned out to be.</P><P><<A HREF="http://www.cesoft.com/quickeys/qkhome.html">http://www.cesoft.com/quickeys/qkhome.html</A>></P><P>[We hope to publish reviews of the main competition for QuicKeys, WestCode Software's OneClick and Binary Software's KeyQuencer 2.0, in the near future. -Adam]</P><BLOCKQUOTE><P class="paybits"> CE Software, Inc. -- 515/221-1801 -- 800/523-7638</P></BLOCKQUOTE><!-- Form, Function, and QuicKeys 3.5, Part 2 Matt Neuburg --></div>
  794.         <div id="article_text_bottom_2684" style="display:none">
  795.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2684')">Hide full article</a></p><div class="sponsorbox">
  796. <div class="sponsortext"><A HREF="http://nuance.com/dragon/mac"><IMG SRC="http://db.tidbits.com/images/badges/dragondictatelockup_vertical_onlight.png" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>Dragon speech recognition software for Macintosh, iPhone, and iPad!<br />Get the all-new Dragon Dictate for Mac from Nuance Communications<br />and experience Simply Smarter Speech Recognition.<br />Learn more about Dragon Dictate: <<a href="http://nuance.com/dragon/mac">http://nuance.com/dragon/mac</a>></div>
  797. </div>
  798. <div class="sponsorbox_bottom"> </div>
  799. </div>
  800.  
  801.         <!-- end article text -->
  802.     
  803.         
  804.  
  805.         
  806.     </div><div class="article"><a name="2696"></a>
  807.     
  808. <!-- comment initialization routine as needed -->
  809. <div class="popup_box_with_captcha" id="hc_2696" style="display: none">
  810.     <div class="tip_box_format">
  811.     <div id="hc_innards_alt_2696" style="display: none">
  812.             <div class="tbf_row">
  813.                 <div class="tbf_wide_80" id="hc_small_response_2696"></div><div class="x_close_row" id="hc_upper_right1_2696"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2696', 'hc', '2696'); return true;">Close</a></div>
  814.  
  815.             </div>
  816.     </div>
  817.     <div id="hc_innards_2696">
  818.         <div class="tip_box_form">        
  819.             <form action="foobar.cgi" method="get" name="check_human_2696">
  820.             <div class="tbf_row">
  821.                 <div class="tbf_wide_80" id="hc_rc_2696">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_2696"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2696', 'hc', '2696'); return true;">Close</a></div>
  822.  
  823.             </div>
  824.             <div class="spacer"></div>
  825.             <div class="tbf_row" id="hc_message_box_2696" style="display:none">
  826.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_2696"></div></div>
  827.             </div>
  828.             <div class="spacer"></div>
  829.             <div class="tbf_row">
  830.                 <div class="tbf_wide"><div id="hc_recaptcha_2696"></div></div>
  831.             </div>
  832.             <div class="spacer"></div>
  833.             <div class="tbf_row">
  834.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '2696', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="844"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  835.             </div>
  836.             <div class="spacer"></div>
  837.             </form>
  838.         </div><!-- end tip_box_form -->
  839.     </div><!-- end hum box innards -->
  840.     </div><!-- end tip box format -->
  841. </div><!-- end tip_submit box-->
  842.  
  843.  
  844.  
  845.         
  846.         
  847.         <!-- specific article details here -->
  848.         
  849.         
  850.             <p class="series_number">Article 4 of 9 in series</p>
  851.         
  852.     
  853.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  854.         
  855.         <div class="featured_meta"><div class="meta_article">21 Oct 1996 | <a href="/article/844?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>
  856.  
  857.         <H2><a href="/article/844">OneClick - A Super Utility</a></H2>
  858.  
  859.         <p class="byline">by <a href="/author/Steve%20Becker">Steve Becker</a> <a href="javascript:void(0)" onClick="document.check_human_2696.submit_type.value='email'; document.check_human_2696.author_id.value='22'; ShowTipBox('hc_2696', 'hc_recaptcha_2696')"><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>
  860.  
  861.         <!-- article text -->
  862.         <div id="article_blurb_2696"><p>Late last year, WestCode Software introduced OneClick, their answer to the need for a flexible, easy-to-use, comprehensive, highly customizable utility program<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('2696')">Show full article</a></span></p></div>
  863.         <div id="article_text_2696" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2696')">Hide full article</a></p><P>Late last year, WestCode Software introduced OneClick, their answer to the need for a flexible, easy-to-use, comprehensive, highly customizable utility program. OneClick incorporates some of the best features of Apple's Control Strip, QuicKeys, Square One, SuperClock, PopChar, PopUp Folder, and other utilities, integrating them into a single program with a low memory overhead, low price, and relatively low learning curve.</P><P>I have tried many Macintosh utilities over the years. In total, these programs cost a lot of money, resulted in extension conflicts, had overlapping feature sets in some areas, and still failed to provide all the features I wanted. I consider my computer needs to be fairly eclectic: they cover the gamut from word processing and email, to business accounting and trading stocks on the Web. My equipment ranges from a 68030-based IIsi to a Power Mac 6100/66. I've been extremely happy with OneClick, a single program that adapts to my wide-ranging hardware and software needs.</P><P><STRONG>Nuts and Bolts</STRONG> -- OneClick consists of a single control panel that uses under 300K of RAM. After installing OneClick and restarting your Mac, you'll see a one-time, brief tutorial, as well as several Global palettes: the System Bar comes pre-configured with many useful buttons; the Task Bar displays buttons for each launched program; and the Launch Strip quickly opens anything that the Finder can open, including programs, files, and folders. OneClick also supports application-specific palettes that are only available when a particular program is active - including a pre-configured palette for the Finder as well as palettes for several popular applications (I particularly like the ones for ClarisWorks). You use the OneClick Editor to customize each of these palettes and to create more palettes - I'll talk more about that in a bit.</P><P>Palette buttons cause programs to launch, files to open, or scripts to run. Each button shows an icon, or text - or both - that indicates its function, so you don't have to remember key combinations. (You may assign keyboard shortcuts to buttons if you wish.) If a button's function is not self-evident, OneClick thoughtfully provides either Balloon Help or a less-obtrusive, yellow, pop-up description tag. It's easy to toggle either help option, and you can also edit the help text - a thoughtful feature.</P><P>Many OneClick buttons perform basic functions like Paste, Insert Date, Change Font (displays a pop-up list of available fonts in their actual typefaces - very neat), Change Font Size, Page Setup, Empty Trash, Make Alias, and Get Info. A small sampling of some of the more powerful buttons that come with the program includes Insert Character (like PopChar, this lets you select and quickly insert any character available in a given font), Glossary (create a glossary of commonly used bits of text and then quickly insert those bits; I use this button to create a signature glossary), Pop-up Hierarchical File List (shades of PopUp Folder), Pop-up Phone Book/Dialer, Pop-up Hierarchical List of files in the System Folder, Auto Save (at user specified time intervals), and Tile Windows. [Additionally, OneClick can use modules from Apple's Control Strip. -Tonya]</P><P>I think new users will find the basic buttons especially helpful. Even as an experienced user, buttons such as Insert Date, Change Font, and Change Font Size save me time. It is easy to create additional basic buttons, such as Print One Copy and Customized Page Setup (to apply pre-determined setup characteristics) - I use these with most of my applications. Some of the more powerful buttons like Insert Character, Hierarchical File Pop-ups, and Phone Book/Dialer replace entire utility programs and I find them a significant enhancement to my Mac's capabilities.</P><P>OneClick also adds a OneClick menu to the menu bar, though you can also access this menu from any palette. The OneClick menu lets you quickly show and hide palettes and switch to the OneClick Editor.</P><P><STRONG>Customizing the Interface</STRONG> -- Using the OneClick Editor, you can create a new palette for any program, or modify an existing palette. To add a button to a new palette, you simply drag it from the OneClick Library to the palette, or you drag it from an existing palette.</P><P>In practice, the customization options for buttons and palettes appear nearly endless. You can assign any icon, or multiple icons, to any button; change a button's background color, size, and palette position (adjusted down to a resolution of one pixel); assign different styles to a button; and more. Similarly, palettes have a range of customization options, including background patterns and colors.</P><P>Although I like the tabbed organization and layout of the OneClick Editor, many features are not labeled and are not intuitive as to their use. Also, an Undo option is not available. WestCode is aware of these concerns and plans to address them in a future release.</P><P><STRONG>Avoid Screen Clutter</STRONG> -- If you are thinking all these palettes cause screen clutter, WestCode has done a good job of preempting this potential problem. Palettes can be collapsed (iconified, in OneClick lingo) to a small icon with a single click. Many of the palettes can also be reduced to a small Title Bar. To hide all palettes, you choose Hide Palettes from the OneClick pop-up menu or press a keyboard shortcut. Palettes may also be configured as to their location on the Desktop and several other parameters. One possible enhancement in a future release will be an option to have a palette automatically get out of the way of the active window, so as to not obscure any part of it. [WestCode hopes to add this to version 1.5, due out later this year. -Tonya]</P><P><STRONG>Be Creative</STRONG> -- If OneClick did nothing more than what I've already covered, it would be a fine program. In reality though, I've only begun to discuss what it can do. Just use the Record feature to make a button script for almost any action you perform with regularly with your Mac, and voila - you have a button that performs the recorded task.</P><P>You can record keys presses and actions like clicking a radio button or choosing a menu option. OneClick records such actions not in terms of mouse movements, but in terms of what you did, making for scripts that do not depend on the mouse being in a particular location when the script begins running. Once a script is recorded, you can edit it in the OneClick Editor window, which offers built-in help and error checking. I've encountered a few a situations where a program will not properly run a recorded action, but most of the time I've found recording to be easy, fast, and wonderfully effective.</P><P>If you know AppleScript, or want to learn OneClick's own (easier) EasyScript, you can create button scripts from scratch. If you are new to using a scripting language or programming, be sure to read the appropriate manual carefully.</P><P>[In addition, Matt Neuburg <<A HREF="mailto:matt@tidbits.com">matt@tidbits.com</A>> notes "OneClick's language is spectacularly well thought out and easy to learn, with splendid data types and object-oriented messaging and a full battery of control structures. OneClick can gather all sorts of information about what's happening on your system, in real time, and make it available in fascinating ways. A OneClick button is programmable - you can drag & drop things onto it, press it with or without modifier keys, and have it react in different ways; it can display a pop-up menu for you to choose from. OneClick has superb abilities for communicating with other scripting milieus." -Tonya]</P><P>OneClick's Editor includes a basic graphics editor and the ability to borrow icons from other files. This, plus the ability to add text to a button's icon and create help text lets your buttons be self-descriptive.</P><P>I put my own words into practice. WriteNow is my favorite word processor, but the interface lacks toolbars. Combining the Record feature and the EasyScript Editor, I was able to create - okay, maybe I'm not objective about this - a <EM>terrific</EM> palette of buttons for WriteNow. Now WriteNow maintains its small memory footprint and quickness while providing me with the customizable toolbar features found in higher-end word processors like WordPerfect and ClarisWorks.</P><P><STRONG>Warning</STRONG> -- This program should have a warning label attached saying "This program can become addictive." In addition to the customization features and productivity boosts - and the temptation to explore them fully- there is an active and helpful OneClick mailing list. (You can join the list through WestCode's Web site.) You'll also find a regularly updated collection of free buttons on WestCode's Web site (including my WriteNow palette, along with a few other palettes I made). In addition, a group of OneClickers has formed the Button Circle, where they regularly upload new freeware buttons.</P><P><<A HREF="http://www.westcodesoft.com/">http://www.westcodesoft.com/</A>><BR><<A HREF="http://rhino.harvard.edu/dan/ButtonCircle.html">http://rhino.harvard.edu/dan/ButtonCircle.html</A>></P><P>The WestCode and Button Circle Web sites include palettes for programs like Eudora, Photoshop, Netscape Navigator, Emailer, and AOL, as well as buttons that provide an almost unbelievable array of features, such as saving multiple text clippings, printing selected text on or across pages, creating notebooks or address books, displaying available memory, and pasting quoted text.</P><P>Owning this program is like having your own personal utility factory. Its dynamic and flexible nature invites you to use your imagination in creating new scripts, or to just record common operations. If you don't think of yourself as the adventurous type, you can look forward to a free stream of buttons and palettes that others have created.</P><P><STRONG>Some Commentary</STRONG> -- It is rare to find such an innovative program as OneClick. It eliminates the need for many other programs, uses little memory, adds only one extension to your System Folder, comes pre-configured with a large list of buttons that greatly enhance both the Mac OS and most of your applications, is regularly expanded through a steady stream of freeware buttons and palettes, is highly customizable to your individual needs, and it is fun to work with. To me, this program exemplifies much of what the Macintosh is all about - it empowers users to get much more out of their Macs while enjoying the experience.</P><P>Recently, Heidi Roizen (Apple VP of Developer Relations) gave an enjoyable talk at a BMUG (Berkeley Macintosh Users Group) main meeting, discussing Apple's new focus on needs of the developer community. WestCode represents a small, independent, innovative developer that is dedicated to working only on the Macintosh platform. I hope that both she and Gil Amelio put WestCode on their list of developers that will receive as much support as possible from Apple. In fact, bundling this product with Macs - or striking a deal to incorporate its technology into the Mac OS - strikes me as a way to further increase the benefit of the Mac OS over Windows. Also, though Mac OS 8 is still but a dream, this might breathe new life and excitement into System 7.x. In the meantime, other developers recognize the potential of OneClick; for example, the next version of Quicken will incorporate OneClick's Shortcut Technology into its Tool Bar.</P><P><STRONG>Final Observations</STRONG> -- By now, you know that I am impressed with this product. Although most users report no or few problems with OneClick, I have encountered numerous bugs, most of which are fixed in the current 1.0.2 release. None of these problems resulted in data loss, and they have been worth putting up with in exchange for the overall benefits of the software. I have found WestCode technical support to be exceptionally friendly and helpful. The call is not toll free, but if no one answers your call immediately, you may leave your number and WestCode returns the call.</P><P>WestCode plans to release OneClick 1.5 later this year. Important enhancements center on more powerful Task Bar and Launcher palettes. A Task Bar button will display and launch recently used applications (think Apple Menu Options), and another Task Bar button will pop up the Launcher; especially useful should you keep the Launcher hidden. The new Launcher will be able to keep file sets, such as a separate Internet Applications set.</P><P>The street price for OneClick is around $75, and QuicKeys users can purchase a competitive upgrade for about $40 (the exact price depends on what version you have). OneClick requires System 7.0 or higher, and a 68020 or later processor.</P><P>[Steve Becker has been a BMUG member since purchasing his first Mac and runs his own Mac consulting business, MacEase, in Berkeley, California.]</P><P>[Those of you hoping to compare OneClick to its strongest competitors, QuicKeys 3.5, which we reviewed in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-348.html">TidBITS-348</A> and KeyQuencer 2.0, for which we have a review underway, should stay tuned. After reviewing all three products, we plan to compare them. -Adam]</P><BLOCKQUOTE><P class="paybits"> WestCode Software -- 800/448-4250 -- 619/487-9200<BR>      619/487-9255 (fax) -- <<A HREF="mailto:westcode@westcodesoft.com">westcode@westcodesoft.com</A>></P></BLOCKQUOTE><!-- OneClick - A Super Utility Steve Becker --></div>
  864.         <div id="article_text_bottom_2696" style="display:none">
  865.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2696')">Hide full article</a></p><div class="sponsorbox">
  866. <div class="sponsortext"><A HREF="http://macte.ch/conf_tidbits"><IMG SRC="http://db.tidbits.com/images/badges/mactech-twitter-icon-48x48.jpg" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>MacTech Conference, for IT Pros and Apple developers, is Nov 3-5,<br />in Los Angeles. The 3-day event is packed with sessions & evening<br />activities. Learn from the best. Meet and spend time with peers.<br />TidBITS readers save $50 at <<a href="http://macte.ch/conf_tidbits">http://macte.ch/conf_tidbits</a>>!</div>
  867. </div>
  868. <div class="sponsorbox_bottom"> </div>
  869. </div>
  870.  
  871.         <!-- end article text -->
  872.     
  873.         
  874.  
  875.         
  876.     </div><div class="article"><a name="2700"></a>
  877.     
  878. <!-- comment initialization routine as needed -->
  879. <div class="popup_box_with_captcha" id="hc_2700" style="display: none">
  880.     <div class="tip_box_format">
  881.     <div id="hc_innards_alt_2700" style="display: none">
  882.             <div class="tbf_row">
  883.                 <div class="tbf_wide_80" id="hc_small_response_2700"></div><div class="x_close_row" id="hc_upper_right1_2700"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2700', 'hc', '2700'); return true;">Close</a></div>
  884.  
  885.             </div>
  886.     </div>
  887.     <div id="hc_innards_2700">
  888.         <div class="tip_box_form">        
  889.             <form action="foobar.cgi" method="get" name="check_human_2700">
  890.             <div class="tbf_row">
  891.                 <div class="tbf_wide_80" id="hc_rc_2700">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_2700"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_2700', 'hc', '2700'); return true;">Close</a></div>
  892.  
  893.             </div>
  894.             <div class="spacer"></div>
  895.             <div class="tbf_row" id="hc_message_box_2700" style="display:none">
  896.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_2700"></div></div>
  897.             </div>
  898.             <div class="spacer"></div>
  899.             <div class="tbf_row">
  900.                 <div class="tbf_wide"><div id="hc_recaptcha_2700"></div></div>
  901.             </div>
  902.             <div class="spacer"></div>
  903.             <div class="tbf_row">
  904.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '2700', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="838"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  905.             </div>
  906.             <div class="spacer"></div>
  907.             </form>
  908.         </div><!-- end tip_box_form -->
  909.     </div><!-- end hum box innards -->
  910.     </div><!-- end tip box format -->
  911. </div><!-- end tip_submit box-->
  912.  
  913.  
  914.  
  915.         
  916.         
  917.         <!-- specific article details here -->
  918.         
  919.         
  920.             <p class="series_number">Article 5 of 9 in series</p>
  921.         
  922.     
  923.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  924.         
  925.         <div class="featured_meta"><div class="meta_article">28 Oct 1996 | <a href="/article/838?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>
  926.  
  927.         <H2><a href="/article/838">KeyQuencer - QuicKeys Quencher?</a></H2>
  928.  
  929.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_2700.submit_type.value='email'; document.check_human_2700.author_id.value='7'; ShowTipBox('hc_2700', 'hc_recaptcha_2700')"><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>
  930.  
  931.         <!-- article text -->
  932.         <div id="article_blurb_2700"><p>Those wishing to automate their Macs without spending the money or yielding the RAM required to run one of the big commercial macro programs may wish to consider KeyQuencer<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('2700')">Show full article</a></span></p></div>
  933.         <div id="article_text_2700" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2700')">Hide full article</a></p><P>Those wishing to automate their Macs without spending the money or yielding the RAM required to run one of the big commercial macro programs may wish to consider KeyQuencer. Once a $10 shareware program, the product of the ingenuity and generosity of the well-known Alessandro Levi Montalcini, it has now been upgraded to version 2.0 and sells as a commercial macro utility from Binary Software for $40. It runs quickly and cleanly in a small RAM footprint (less than 200K) under System 7.x, and most features are said to run (though without official support) under System 6.0.4 and later.</P><P><<A HREF="http://www.binarysoft.com/keyquencer/keyquencer.html">http://www.binarysoft.com/keyquencer/ keyquencer.html</A>></P><P><STRONG>What It's Like</STRONG> -- KeyQuencer macros live in "suitcases." The default suitcase loads at startup, and its macros (the active macros) can be triggered by a keystroke combination. Macros in other suitcases can't be triggered by a keystroke, but are available through a small application, KeyQuencer Launcher, which displays any suitcase as a double-clickable list. Macro names can be up to 31 characters, so the lists can be informative. You might leave the Launcher running all the time, with multiple suitcase windows open; your commonly used macros can be triggered with keystrokes, and if you need a less-frequently used macro (or if you forget an active macro's keystroke), there it is in one of the Launcher's lists. (Remember, though, the Launcher is an application, not a dialog or palette, so if you double-click a macro that affects the frontmost window, it will be the Launcher's window.)</P><P>This technique might help make up for the fact that in KeyQuencer, unlike QuicKeys or OneClick, there's no such thing as an application-specific macro. Once you've assigned a keystroke to a macro and made that macro active, that keystroke is unavailable for anything else, system-wide. It takes some planning to come up with keystrokes that have no meaning in any extension, control panel, or application. The danger is that you'll run out of possible keystrokes, or that you'll trigger a macro inadvertently. KeyQuencer installs itself with numerous macros already active, so before I knew it, I had accidentally stuffed a HyperCard stack while trying to read its stack script, and moved an important item into the Trash even though I wasn't in the Finder. A macro can check to see if a certain application is frontmost and either pass along the triggering keystroke or abort. Many of the pre-installed macros perform no such check, though, so be cautious.</P><P>Macros are created, edited, named, assigned keystrokes, and copied between suitcases in another application, KeyQuencer Editor. It's a simple, pleasant place to work. You don't have to "open" a macro to edit it: when you click a macro's name in the list, its contents appear in a word-processing pane for viewing and editing. Every macro consists of one or more text commands. You can type these commands, or you can enter them by double-clicking their names in a floating Commands window, which lists all commands and (when a command is selected) possible parameters. An online Help window updates dynamically with a description of the command's function and parameters.</P><P>The contrast between the whole milieu and that of QuicKeys couldn't be greater. QuicKeys has short macro names and confusingly arranged menus for selecting macro types, and editing happens in cascades of modal dialogs that must be completely dismissed before you can test a macro, discover that it doesn't work properly, and open everything up again. In KeyQuencer, both Launcher and Editor are applications, with normal windows - which, if you have about 700K of RAM to spare, you could leave open all the time. Editing is textual, and you can save the macro you're currently editing and test it without closing anything.</P><P><STRONG>Communication</STRONG> -- There is no special KeyQuencer menu trigger, comparable to the QuicKeys menu; but James Walker's shareware OtherMenu, which is included, can trigger a KeyQuencer macro. Similarly, KeyQuencer has no time trigger, but if all you need is absolute time (as opposed to time since an application has started) you can use Chris Johnson's shareware Cron, which is also included. You can install a Control Strip module or NowTabs plug-in, from which you can choose and launch an active macro. You can talk to KeyQuencer from AppleScript or Frontier, including passing variables back and forth. Macros can even be incorporated into the CodeWarrior build process.</P><P><<A HREF="ftp://mirror.aol.com/pub/info-mac/gui/other-menu-183.hqx">ftp://mirror.aol.com/pub/info-mac/gui/other- menu-183.hqx</A>><BR><<A HREF="ftp://mirror.aol.com/pub/info-mac/cfg/chris-cron-10a7.hqx">ftp://mirror.aol.com/pub/info-mac/cfg/chris- cron-10a7.hqx</A>></P><P>KeyQuencer can perform any of its functions on a remote networked computer that is also running KeyQuencer; you may, but do not have to, set up the desired functionality as a KeyQuencer macro on the remote computer. (I have not tested this.)</P><P><STRONG>The Language</STRONG> -- KeyQuencer comes with about 260 pre-written macros; if you want to modify one or write a new one, you must use the KeyQuencer language, a rigid, hard-to-remember, command-plus-parameters idiom, where you just know you'll never wean yourself off online help and the reference manual.</P><P>In fact, it's not a language so much as a collection of commands. There are no subroutines: the only way to invoke one macro from another is to tell the first macro to type the second's keystroke. There are no looping, branching, or conditional constructs, but there's a Repeat command (that takes as its parameter a quoted string consisting of one or more macro commands) and commands that abort a macro if a certain application is frontmost or if two strings match. There are no arithmetic operators, but there's an Evaluate command which stores arithmetic expressions in the clipboard and a Counter command that maintains a temporary increment-decrement counter. There are no string-processing functions, but there's a clipboard-munging command that can do some. There are variables, but the syntax for passing them around is hair-raising.</P><P>To set A to 1 and B to 2 and then add them and put the result into C, you say:</P><PRE>SetVariable A "1"SetVariable B "2"Evaluate "\[a]+\[b]" copy -- this puts the result in the clipboardSetVariable C clipboard -- this gets it out again</PRE><P>To type the numbers 1 through 10, each followed by a tab and a return, you say:</P><PRE>Repeat 10 "Counter increment save\rType $counter \q\\t\\r\q"</PRE><P><STRONG>What It Can Do</STRONG> -- Every KeyQuencer command corresponds to a small file living in a folder (in your System Folder) called KeyQuencer Extensions. Removing one of these files from the KeyQuencer Extensions folder and restarting disables that command; adding a new one, if a new one is written, expands the repertoire of commands. (If there are commands you aren't using, disabling them lets you save still more memory; if you've just a few macros using just a few commands you can run KeyQuencer in less than 80K!)</P><P>There are the usual macro behaviors such as pressing a key, typing a string, choosing from a menu, clicking the mouse, waiting for various types of events. There are also extras similar to those in QuicKeys - and some rather more capable, such as changing applications or windows, setting speaker volume and monitor depth, choosing a printer, and mounting a server. There is a powerful Batcher application: for each copy you make, you preconfigure what macro it should run, then drag & drop files or folders onto it for processing.</P><P>KeyQuencer also has an eclectic miscellany of commands, such as: force a window or screen refresh; take a screen shot of a window or region; launch or close your PPP connection; get file info; dramatically show the cursor's position; relocate the frontmost window; drive an audio CD; alter the contents of the clipboard; manipulate ten clipboards; and read and write between the clipboard and a file.</P><P><STRONG>Minor Annoyances</STRONG> -- These are things I noticed in passing, which probably shouldn't affect one's overall judgment of KeyQuencer. A few commands may not work perfectly: the sound-volume commands had no effect on my computer; the "scroll top/bottom" commands don't work in Nisus Writer. Some keystroke-combination triggers (such as the one that toggles KeyQuencer on and off) are not user-configurable. On my computer, Now SuperBoomerang sometimes didn't work within the Editor, and opening a suitcase sometimes writes garbage in the Online Help window and crashes. Within the Launcher, you can't configure the sort order in which the lists appear (by name versus by keystroke); you're stuck with the sort order you were using in the Editor the last time you saved. The syntax of the HyperCard XCMDs is not documented, and, finally, the manual could use more clarity of explanation and design.</P><P><STRONG>Slouch To Judgment</STRONG> -- Here I'm supposed to sum up and tell you whether this is the macro utility you've been waiting for all your life. Truthfully, I just don't know. Though this is one heck of a program, I suspect it's not everyone's cup of tea; a great deal depends upon your mindset, your priorities, and your present repertoire of tools. Your best bet is to download the demo version that is supposed to appear soon on Binary's Web site and see how you like it. Meanwhile, some provocative reflections.</P><P>For sheer functionality, there's probably little QuicKeys can do that KeyQuencer can't somehow be made to do, and KeyQuencer has some abilities that QuicKeys lacks. Still, to some, the language might feel too daunting, or not fully-featured. My personal macro Holy Grail is to be given tools to build tools, and my mind runs along a one-program-one-function organizational track; so to me, KeyQuencer feels like a miscellany of extensions bundled together by an intractable language. I prefer OneClick's fuller programming and informational constructs that permit me to build my own multiple clipboards (vs. KeyQuencer's Clipboard command), to drive AppleScript to open or close MacPPP (vs. KeyQuencer's PPPSwitch), to obtain a list of windows and close all but the front one (which, as far as I can tell, KeyQuencer can't do at all). Also, since no one program does everything I want, I don't mind calling upon a battery of scripting tools to help me - Frontier, AppleScript, HyperCard, and so on. Possibly I'm just weird. I suspect your own feelings about these philosophical questions will be more decisive than feature issues such as KeyQuencer's lack of application-specific macros and recordability. For those who like a collection of ready-built high-level tools, KeyQuencer should prove attractive.</P><P>Most important, KeyQuencer operates to a high rigorous standard, something that not every macro program does. In the case of something so simple as a keystroke that scrolls the active window up one line, OneClick can't cope with Nisus Writer's windows because the scroll bar's up-arrow isn't in the normal location, but KeyQuencer "tells" the window to scroll in some deeper way and has no problem. KeyQuencer can simulate double-control-clicking on a window's title bar, which on my system activates WindowShade; I can't get OneClick to do that. This testifies to the dedication, the know-how, and the philosophical outlook of KeyQuencer's author, Alessandro Levi Montalcini. It's wonderful that such clean, powerful functionality can emanate from one person's brain in this day and age of megalithic software development corporations.</P><P><STRONG>Another Deal</STRONG> -- We've also worked out a deal for TidBITS readers who wish to purchase KeyQuencer from Cyberian Outpost. If you use the specific URL below, you can order KeyQuencer 2.0 online and receive a $4 discount (think of it as free shipping).</P><P><<A HREF="http://www.tidbits.com/products/key-quencer.html">http://www.tidbits.com/products/key- quencer.html</A>></P><P>[Those of you hoping to compare KeyQuencer, OneClick (<A HREF="http://www.tidbits.com/tb-issues/TidBITS-350.html">TidBITS-350</A>), and QuicKeys (<A HREF="http://www.tidbits.com/tb-issues/TidBITS-348.html">TidBITS-348</A>) should stay tuned for a future issue. -Adam]</P><BLOCKQUOTE><P class="paybits"> Binary Software, Inc. -- 310/449-1481 -- 310/449-1473 (fax)<BR>      <<A HREF="mailto:binary@binarysoft.com">binary@binarysoft.com</A>></P></BLOCKQUOTE><!-- KeyQuencer - QuicKeys Quencher? Matt Neuburg --></div>
  934.         <div id="article_text_bottom_2700" style="display:none">
  935.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('2700')">Hide full article</a></p><div class="sponsorbox">
  936. <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>
  937. </div>
  938. <div class="sponsorbox_bottom"> </div>
  939. </div>
  940.  
  941.         <!-- end article text -->
  942.     
  943.         
  944.  
  945.         
  946.     </div><div class="article"><a name="4175"></a>
  947.     
  948. <!-- comment initialization routine as needed -->
  949. <div class="popup_box_with_captcha" id="hc_4175" style="display: none">
  950.     <div class="tip_box_format">
  951.     <div id="hc_innards_alt_4175" style="display: none">
  952.             <div class="tbf_row">
  953.                 <div class="tbf_wide_80" id="hc_small_response_4175"></div><div class="x_close_row" id="hc_upper_right1_4175"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_4175', 'hc', '4175'); return true;">Close</a></div>
  954.  
  955.             </div>
  956.     </div>
  957.     <div id="hc_innards_4175">
  958.         <div class="tip_box_form">        
  959.             <form action="foobar.cgi" method="get" name="check_human_4175">
  960.             <div class="tbf_row">
  961.                 <div class="tbf_wide_80" id="hc_rc_4175">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_4175"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_4175', 'hc', '4175'); return true;">Close</a></div>
  962.  
  963.             </div>
  964.             <div class="spacer"></div>
  965.             <div class="tbf_row" id="hc_message_box_4175" style="display:none">
  966.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_4175"></div></div>
  967.             </div>
  968.             <div class="spacer"></div>
  969.             <div class="tbf_row">
  970.                 <div class="tbf_wide"><div id="hc_recaptcha_4175"></div></div>
  971.             </div>
  972.             <div class="spacer"></div>
  973.             <div class="tbf_row">
  974.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '4175', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="5500"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  975.             </div>
  976.             <div class="spacer"></div>
  977.             </form>
  978.         </div><!-- end tip_box_form -->
  979.     </div><!-- end hum box innards -->
  980.     </div><!-- end tip box format -->
  981. </div><!-- end tip_submit box-->
  982.  
  983.  
  984.  
  985.         
  986.         
  987.         <!-- specific article details here -->
  988.         
  989.         
  990.             <p class="series_number">Article 6 of 9 in series</p>
  991.         
  992.     
  993.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  994.         
  995.         <div class="featured_meta"><div class="meta_article">09 Aug 1999 | <a href="/article/5500?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>
  996.  
  997.         <H2><a href="/article/5500">QuicKeys 4 Presses My Buttons</a></H2>
  998.  
  999.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_4175.submit_type.value='email'; document.check_human_4175.author_id.value='7'; ShowTipBox('hc_4175', 'hc_recaptcha_4175')"><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>
  1000.  
  1001.         <!-- article text -->
  1002.         <div id="article_blurb_4175"><p>Back in 1988, when Microsoft Word couldn't search and replace styles, a Classics student of mine named Adam Engst (what ever became of him?) put me wise to a solution involving macro automation, using CE Software's QuicKeys<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('4175')">Show full article</a></span></p></div>
  1003.         <div id="article_text_4175" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('4175')">Hide full article</a></p><P>Back in 1988, when Microsoft Word couldn't search and replace styles, a Classics student of mine named Adam Engst (what ever became of him?) put me wise to a solution involving macro automation, using CE Software's QuicKeys. QuicKeys could simulate user actions, such as clicking a button or choosing a menu item; each such action is called a shortcut. And it could string shortcuts together into little programs called sequences. You could trigger a shortcut or a sequence by pressing a combination of keys or by choosing from a special QuicKeys menu. With QuicKeys, you could automate, or provide keystroke-based access to, all sorts of common or repetitive tasks.</P><P>QuicKeys immediately became indispensable on my computer, but shortly after reviewing version 3.5 in 1996, I stopped using it (see the "Mac Macros" series of articles beginning in <A HREF="http://www.tidbits.com/tb-issues/TidBITS-347.html">TidBITS-347</A>). The Finder, and other programs I commonly use, were becoming more scriptable through AppleScript or Frontier; QuicKeys was having trouble with newer systems; and OneClick provided more programmable access to a greater range of functionalities.</P><P><<A HREF="http://db.tidbits.com/series/1044">http://db.tidbits.com/series/1044</A>></P><P>Now QuicKeys is back, with version 4. What's new? Not much, really. CE Software added some new ways to create shortcuts: in the Finder, Control-click a file or folder, or drag it into a QuicKeys toolbar, to create a shortcut that opens it. Two types of shortcuts, when expressed as buttons on a QuicKeys toolbar, can now accept drag & drop of files and folders. There are some new shortcut abilities, such as locking a file, or changing Finder views. But what's really important is that QuicKeys now works with recent versions of the Mac OS.</P><P><<A HREF="http://www.cesoft.com/quickeys/qkhome.html">http://www.cesoft.com/quickeys/qkhome.html</A>></P><P><STRONG>Macro My Mac</STRONG> -- Installation is greatly simplified, without so many pieces spread out over so many folders, and with only one extension required (the QuicKeys control panel). However, if you're upgrading, the time-consuming and confusing task of cleaning up from previous versions is left to you.</P><P>It's a pleasure to have QuicKeys back on my machine, and to greet old shortcuts as old friends. I'd forgotten how accustomed I was to typing a certain command to hide the current application, or to bring the Finder to the front. I restored custom keyboard shortcuts for menu items that lack them, or whose real shortcuts I dislike. On my PowerBook, which lacks an extended keyboard, I immediately restored ways of typing Home, End, Page Up, Page Down, and so forth.</P><P>While testing, I removed OneClick; and this reminded me that QuicKeys's abilities, though splendid, are fairly narrow. I have OneClick buttons that cascade my window positions, or present a list of windows so I can bring one to the front, or remember recently used applications and let me launch one from a list. QuicKeys's inability to do those things made me feel initially hamstrung.</P><P>Still, QuicKeys quite adequately handles most of my habitual needs. It can cycle through windows in an application. It can collapse or expand the frontmost window. It lets me maintain a palette of commonly needed folders; using the palette, I can open a folder, or copy a file into it. And some of what QuicKeys can't do can be accomplished by other utilities: it can't keep a list of recent applications, but Apple Menu Options can; it can't present a pop-up hierarchy of my hard disks, but The Tilery can; it can't present a list of open windows, but TitlePop can.</P><P><<A HREF="http://www2.semicolon.com/Rick/Tilery.html">http://www2.semicolon.com/Rick/Tilery.html</A>><BR><<A HREF="http://www.datavasara.fi/titlepop/">http://www.datavasara.fi/titlepop/</A>></P><P>On the other hand, QuicKeys is not a full-fledged scripting language (with variables and arithmetic and strings and the like), and generally can't perform actions that require one. For example, I commonly ask OneClick to collapse all but the frontmost window of the current application; QuicKeys is incapable of that, because it can't count the windows or cycle through them. QuicKeys can rename files according to certain preset templates, such as appending a serial number, but not in accordance with criteria that you create. QuicKeys can switch your TCP/IP configuration to one you've specified beforehand, but it can't present a list of your configurations and let you switch to one - even though it <EM>can</EM> do just that with your running applications. In short, QuicKeys's abilities are all highly specific and compartmentalized; it has no mechanism for generalizing them.</P><P>From another point of view, though, this limitation is an asset. QuicKeys isn't a scripting language because it doesn't want to be one. Many people are frightened by scripting languages: they can't program, or they think they can't, or they can't be bothered to learn. So QuicKeys lets you create shortcuts and sequences through familiar interface features such as lists and menus and dialog boxes that present simple sets of predetermined options. It may not permit customization to the degree that a scripting language does, but there's comfort in its confinement and clarity.</P><P><STRONG>Ossify My Interface</STRONG> -- One of the big troubles is that QuicKeys's interface is far from clear. Its dialog boxes are rigid in infuriating, unnecessary ways. For example, you can't give certain shortcuts a descriptive title; a shortcut that chooses a menu item automatically has a title which is the same as the text of the menu item. And for certain shortcuts where you can assign a title, the title is limited to 15 characters. The result is that, viewing your list of shortcuts by their tiny or predetermined titles, you don't know what they do.</P><P>The native capabilities of certain shortcuts are so limited as to render them almost unusable. For example, ScrapEase lets you maintain multiple clipboards: you trigger a ScrapEase shortcut to copy selected text, which you then name in a dialog; then later you can trigger another ScrapEase shortcut to let you paste whatever scrap you choose from a list. But you can't easily delete a scrap: you must open the QuicKeys editor, find any ScrapEase shortcut, open it for editing in a dialog, press a button to bring up another dialog listing your scraps, select one and press Delete, confirm the deletion in yet <EM>another</EM> dialog, and then dismiss the whole nest of dialogs one by one. The result is a reluctance to use this feature, because management is so inconvenient.</P><P>Creating a shortcut requires navigating a mysterious nest of hierarchical menu items. Consider the following actions: collapse a window; switch to the rear window; switch to the next application. Who would ever have guessed that these are accessed, respectively, through System Tools -> Mousies, System Tools -> Specials, and System Tools -> MacOS [sic] Specials? And each of these choices just brings up a dialog; you must still find the desired function in yet another menu. So even if you know that a certain shortcut type exists, you don't know where to find it; either you spend all your time guessing, trying different menus and dialogs, or you look in the manual.</P><P>CE has done nothing to resolve the problems engendered by dependencies of one shortcut on another. Such dependencies can make understanding your shortcuts difficult, and editing them hazardous. For example, in a sequence you can include a Decision shortcut, which is the QuicKeys version of an "if" statement: if a certain situation is the case, QuicKeys triggers a certain other shortcut. But this other shortcut must exist separately. So when you examine your Decision shortcut, in a modal dialog, you don't know what it does, because it calls another shortcut, which you can't examine because you're in a modal dialog. Conversely, when you look at the list of your shortcuts, you see that other shortcut, with no understanding of why it exists: there's no indication that it is called by a separate Decision shortcut. So you might easily delete it, thereby rendering your Decision shortcut powerless; or, more likely, you're afraid to delete anything, because you have no way of knowing what dependencies you might destroy. In effect, as soon as you have shortcuts or sequences of even the slightest complexity, they become unmanageable.</P><P>The same is true of toolbars. To include a shortcut on a toolbar, the shortcut must exist separately. But when you're looking at the list of your shortcuts, nothing tells you that a shortcut is associated with a toolbar, so you can easily delete it, thereby accidentally removing its button from the toolbar. Conversely, when you're editing a toolbar, you're shown a list of your toolbars and a list of your shortcuts, but you're not shown any association between the two. And if you're editing a toolbar, what's one of the main things you'd probably like to do? Edit one of its shortcuts, of course. But you can't; shortcut editing and toolbar editing happen on two different tab panels.</P><P>It appalls me that CE has given no attention to these and similar problems. Far from taking the opportunity of this revision to address such long-standing issues, they've maintained an arcane and archaic interface that dates back twelve years, merely dressing it up with some colors and Appearance Manager-compliant buttons.</P><P><STRONG>Shoot Myself in the Foot</STRONG> -- None of the above means that I don't like QuicKeys 4. I love it! It's stable, it's fast, it's reliable, it doesn't seem to slow or interfere with my Mac's operation. And it has always had these interface problems, so I'm used to them. But I'm disappointed with CE Software for not fixing them, especially since I've been writing about them in TidBITS for years. Of course, this is the company that acquired WebArranger, one of the coolest programs in history, then failed to understand it, failed to support it, and eventually discontinued it. CE Software has no record of following my advice. But if this is the best that CE can offer its customers who have waited patiently for three years, it's a bad sign. And why would such a clumsy interface attract new users?</P><P><<A HREF="http://db.tidbits.com/article/01149">http://db.tidbits.com/article/01149</A>></P><P>The QuicKeys manual is poor. Too much of it is devoted to self-promotion; phrases like "time-saving" and "work more efficiently" appear frequently, as if the reader needed constant reminding why the program was purchased in the first place. Far too little of it is devoted to teaching and explaining. There are many errors. It's also badly laid out, with fonts that don't harmonize, and a short, wide two-column format that makes the PDF version illegible on most any monitor.</P><P>In one respect, though, CE improved the manual. QuicKeys Script, CE's OSA-compliant scripting language for driving QuicKeys from other programs, is no longer hidden away from view; it is described in the manual, and in place of syntax specifications using arcane mathematics-like symbols, there are now easy-to-read tables.</P><P>I've explained, in an earlier essay, why you need a macro program. And once upon a time, QuicKeys was the only game in town; so you needed QuicKeys. But no longer. There's OneClick. There's KeyQuencer. There's PreFab Player. Plus, the Mac OS itself is more scriptable than it used to be, through AppleScript or Frontier. With QuicKeys 4, CE Software has failed to acknowledge this competition; so far from taking renewed responsibility for the care and feeding of this fine, classic program, they've left it with a poor interface, a muddy manual, and limited capabilities. The result is that users have few reasons to choose QuicKeys over the younger and hungrier competition. That's sad.</P><P><<A HREF="http://db.tidbits.com/article/00801">http://db.tidbits.com/article/00801</A>></P><P>QuicKeys retails for $100; competitive upgrades are $50. A 2.3 MB 30-day demo version is available for download.</P><P><<A HREF="http://www.cesoft.com/quickeys/qkmac40demo.sea.hqx">http://www.cesoft.com/quickeys/ qkmac40demo.sea.hqx</A>></P><!-- QuicKeys 4 Presses My Buttons Matt Neuburg --></div>
  1004.         <div id="article_text_bottom_4175" style="display:none">
  1005.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('4175')">Hide full article</a></p><div class="sponsorbox">
  1006. <div class="sponsortext"><A HREF="http://crashplan.com/ref/tidbits.html"><IMG SRC="http://db.tidbits.com/images/badges/CrashPlan.png" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>CrashPlan is easy, secure backup that works everywhere. Back up<br />to your own drives, computers, and online with unlimited storage.<br />With unlimited online backup, this is one resolution you can keep.<br />Back Up Your Life Today! <<a href="http://crashplan.com/ref/tidbits.html">http://crashplan.com/ref/tidbits.html</a>></div>
  1007. </div>
  1008. <div class="sponsorbox_bottom"> </div>
  1009. </div>
  1010.  
  1011.         <!-- end article text -->
  1012.     
  1013.         
  1014.  
  1015.         
  1016.     </div><div class="article"><a name="4523"></a>
  1017.     
  1018. <!-- comment initialization routine as needed -->
  1019. <div class="popup_box_with_captcha" id="hc_4523" style="display: none">
  1020.     <div class="tip_box_format">
  1021.     <div id="hc_innards_alt_4523" style="display: none">
  1022.             <div class="tbf_row">
  1023.                 <div class="tbf_wide_80" id="hc_small_response_4523"></div><div class="x_close_row" id="hc_upper_right1_4523"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_4523', 'hc', '4523'); return true;">Close</a></div>
  1024.  
  1025.             </div>
  1026.     </div>
  1027.     <div id="hc_innards_4523">
  1028.         <div class="tip_box_form">        
  1029.             <form action="foobar.cgi" method="get" name="check_human_4523">
  1030.             <div class="tbf_row">
  1031.                 <div class="tbf_wide_80" id="hc_rc_4523">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_4523"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_4523', 'hc', '4523'); return true;">Close</a></div>
  1032.  
  1033.             </div>
  1034.             <div class="spacer"></div>
  1035.             <div class="tbf_row" id="hc_message_box_4523" style="display:none">
  1036.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_4523"></div></div>
  1037.             </div>
  1038.             <div class="spacer"></div>
  1039.             <div class="tbf_row">
  1040.                 <div class="tbf_wide"><div id="hc_recaptcha_4523"></div></div>
  1041.             </div>
  1042.             <div class="spacer"></div>
  1043.             <div class="tbf_row">
  1044.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '4523', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="5881"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  1045.             </div>
  1046.             <div class="spacer"></div>
  1047.             </form>
  1048.         </div><!-- end tip_box_form -->
  1049.     </div><!-- end hum box innards -->
  1050.     </div><!-- end tip box format -->
  1051. </div><!-- end tip_submit box-->
  1052.  
  1053.  
  1054.  
  1055.         
  1056.         
  1057.         <!-- specific article details here -->
  1058.         
  1059.         
  1060.             <p class="series_number">Article 7 of 9 in series</p>
  1061.         
  1062.     
  1063.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  1064.         
  1065.         <div class="featured_meta"><div class="meta_article">03 Apr 2000 | <a href="/article/5881?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>
  1066.  
  1067.         <H2><a href="/article/5881">Freedom of the Button Press - OneClick 2.0</a></H2>
  1068.  
  1069.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_4523.submit_type.value='email'; document.check_human_4523.author_id.value='7'; ShowTipBox('hc_4523', 'hc_recaptcha_4523')"><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>
  1070.  
  1071.         <!-- article text -->
  1072.         <div id="article_blurb_4523"><p>In the struggle to return control of the computer to the user, macro utilities are indispensable. Such a utility acts as a ghostly simulacrum of a live user, choosing from menus, typing keys, and clicking the mouse; an assemblage of such actions can essentially script the unscriptable, driving any application to customize or automate frequent or repetitive tasks<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('4523')">Show full article</a></span></p></div>
  1073.         <div id="article_text_4523" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('4523')">Hide full article</a></p><P>In the struggle to return control of the computer to the user, macro utilities are indispensable. Such a utility acts as a ghostly simulacrum of a live user, choosing from menus, typing keys, and clicking the mouse; an assemblage of such actions can essentially script the unscriptable, driving any application to customize or automate frequent or repetitive tasks. From my earliest days with the Macintosh, QuicKeys was my constant companion; I've also looked at KeyQuencer. But if I had to use just one macro utility, forsaking all others, my choice, despite its faults, would be OneClick, from WestCode Software.</P><P><<A HREF="http://db.tidbits.com/series/1044">http://db.tidbits.com/series/1044</A>><BR><<A HREF="http://www.westcodesoft.com/">http://www.westcodesoft.com/</A>></P><P><STRONG>Refined Palettes</STRONG> -- OneClick creates floating windows (palettes), each of which can be either global or associated with a specific application. A palette contains buttons; every button has a script, a sequence of actions which you create and edit as text in an easy programming language appropriately named EasyScript. A script can contain various subroutines, called handlers. Handlers are the code that actually gets triggered, and in forming a mental picture of OneClick, it helps to know how this occurs. (Bear in mind that an application-specific palette cannot be visible, nor can its scripts run, unless the application is frontmost.) Here are the triggers:</P><UL><LI><P>You click and release the button. This triggers the button's MouseUp handler.</P><LI><P>You click the button and hold down. This triggers the button's MouseDown handler. Such a handler can construct a menu and make it pop up from the button, and then proceed in response to the user's menu choice. Since pop-up menus require that the mouse button be down, this would make no sense in a MouseUp handler. If a button has both a MouseDown handler and a MouseUp handler, the latter will never be automatically triggered; they are mutually exclusive.</P><LI><P>You type the button's keyboard shortcut. This triggers the button's MouseDown handler if there is one, otherwise its MouseUp handler. A palette does not have to be visible for its keyboard shortcut to work, and buttons on palettes belonging to different applications can use the same keyboard shortcut. Thus, OneClick actions can be triggered purely from the keyboard, as with QuicKeys; this should satisfy those who, like several members of the TidBITS staff, dislike most palettes.</P><LI><P>You drop something on the button. This triggers the button's DragAndDrop handler. You can drag text (from an application that can initiate true text drag & drop), or Finder items; the script receives the text or the pathnames, respectively, and can respond as desired.</P><LI><P>Something causes the button to be redrawn - for example, the palette becomes visible, or the button changes its appearance through being pressed by the user or commanded by a script. This triggers the button's DrawButton handler.</P><LI><P>The palette's associated application (or, for a global palette, the computer) starts up. This triggers the button's Startup handler. For example, if a badly behaved application requires a click from the user to dismiss its opening splash screen, OneClick can perform the click.</P><LI><P>A certain time period elapses, or a system event occurs. This triggers the button's Scheduled handler. You configure what time period(s) or event(s) will act as triggers, which you typically do in the Startup handler. Common events to which OneClick can respond are: an application starts up or quits, a new window comes to the front, or a OneClick palette is shown or hidden. Suppose you wanted a certain palette to appear in response to the mouse moving over a "hot spot" such as the lower left corner of the monitor. You could configure a Scheduled handler to be called every second, polling the mouse's position and showing the palette if the mouse is at the hot spot.</P><LI><P>Another handler calls the one in question by name. The calling handler need not be in the same button, nor even in the same palette. In fact, a handler can be called from an AppleScript running <EM>anywhere</EM>; thus, HyperCard or QuicKeys or even Microsoft Word could trigger a OneClick script.</P></UL><P>Clearly there is great power and flexibility in this capacity of button scripts to be triggered in so many different ways. And OneClick's buttons are also customizable: they can contain text or icons, they can be drawn in various ways, in any size or color, and so forth. Thus, a OneClick palette can be made to look just right for its application. Nonetheless, it isn't its system of buttons and palettes which makes OneClick the place I'd prefer to be when writing a macro script - it's the nature of the scripts themselves.</P><P><STRONG>It's the Scriptability, Stupid</STRONG> -- OneClick scripts are text, written in a real programming language with real programming features such as variables, looping and branching constructs, arithmetic calculation and string manipulation, and even a pleasant object-based syntax. And OneClick provides oodles of built-in functions for letting this language do powerful things.</P><P>Naturally, you can perform all the ghostly user-like actions you'd expect from a macro utility. You can click the mouse at given coordinates, possibly with modifier keys or dragging. You can type. You can examine menu items, and choose one. You can inspect a button's state, and push it. You can select, scroll, resize, reposition, zoom, or collapse a window; you can even read its text.</P><P>You can perform various system- and Finder-level activities. You can manipulate the clipboard; show, hide, and reorder running processes; obtain screen resolutions, sizes, and positions; create, copy, open, and delete files and folders; read or change a file's text or Finder information; and mount or obtain information about a volume.</P><P>You can interact with the user. You can put up a dialog, give it customized buttons, let the user type some text into it, let the user choose an item from a list, and show the standard File Open or Save dialog or even the Color Picker dialog. You can supply help text that will appear when the user holds Shift-Option with the mouse over a button. You can change the cursor. You can play sounds, or have the Speech Manager speak some text. You can poll the mouse button or the keyboard; so, by learning what modifiers the user is holding, you can give a button multiple functionalities. You can allow a button to receive something using drag & drop; you can also permit text to be dragged <EM>from</EM> a button. You can cause various sorts of pop-up menu to appear for the user to choose from: a menu that you construct from scratch, a hierarchical menu of files and folders on disk, a menu showing all the characters of any font, or even an entire palette behaving like a pop-up menu.</P><P>You can run an AppleScript script, thus scripting the scriptable as well as the unscriptable. This can be a compiled script file created in Apple's Script Editor, but in most cases it can simply appear inline within a button script.</P><P>Finally, everything about OneClick's own buttons and palettes can be controlled from scripts. You can change a button's text or appearance, make a button display a thermometer or pie-chart as feedback, dictate conditions under which the user can reposition a button or palette by dragging, even create a palette and populate it with buttons "on the fly." Thus, palettes themselves become powerful interface tools, where the buttons combine to form some complex live functionality, such as a calendar.</P><P>With such power and flexibility, it's little wonder that OneClick is put to a great variety of ingenious uses - some sense of which may be gleaned from WestCode's page of user-contributed palettes. In fact, WestCode sells a number of its own palettes extracted from the full OneClick distribution separately, along with a runtime version of the OneClick engine.</P><P><<A HREF="http://www.westcodesoft.com/FTP-Buttons.html">http://www.westcodesoft.com/FTP-Buttons.html</A>><BR></P><P>Compared to this, my own use of OneClick is rather tame, mostly because I'm conservative about using buttons scripted by others. Still, a survey of my own habits yields a taste of OneClick's possibilities. On my computer are palettes, buttons, and keyboard shortcuts that do the following.</P><UL><LI><P>Show the font, size, and styles of the currently selected text in Nisus Writer (because otherwise you have to peep into half a dozen different menus to learn this information).</P><LI><P>Position and size the frontmost Acrobat Reader window nicely, and to zoom it to Fit Width.</P><LI><P>Fix capitalization and remove extra spaces in clipboard text (to make up for ViaVoice's mistakes).</P><LI><P>Connect to or disconnect from the Internet, by driving the Remote Access control panel.</P><LI><P>Implement multiple simultaneous clipboards.</P><LI><P>Toggle the collapsed setting of the frontmost window or of all other windows.</P><LI><P>Interfere with the Help key, which I often strike accidentally.</P><LI><P>Supply PageUp, PageDown, Home, End, Forward Delete, and Help keys, which are missing from my PowerBook.</P><LI><P>Hide the frontmost application or all others, or bring the Finder to the front.</P><LI><P>Use the pathname on the clipboard to open a file or folder.</P><LI><P>Speak the selected text.</P><LI><P>Toggle the visibility of the Application Switcher.</P><LI><P>Choose among my various TCP/IP configurations.</P></UL><P>Plus, I use some buttons supplied by WestCode to manage text clippings, change speaker volume, open various system folders, manipulate windows and processes, and navigate the Finder hierarchy. Much of the above are functionalities I was previously achieving in some other way; OneClick all by itself makes many other extensions and utilities superfluous.</P><P>Yet though I love OneClick and wouldn't want to be without it, using it can be unpleasant and risky. Next topic: the downsides of OneClick.</P><P><STRONG>Cold Shower</STRONG> -- The script editing environment, despite its nice online help and compile-time syntax checking, is crude. OneClick lacks a Find command, a built-in debugger, and notification of runtime errors. So OneClick becomes what I call "guessware": constructing, debugging, or just understanding a script can range from painful to well-nigh impossible. One can develop workaround tools and techniques, but one shouldn't have to, and besides, this will be hardest for the beginners who most need them. The trouble is compounded by hidden traps in the EasyScript language; for example, "for x = 1 to n" will execute its loop even if n is zero, and complex nested function evaluations often don't work - you have to evaluate all the pieces as separate variables first.</P><P>If you're not prepared to crash now and then, or for things to go mysteriously wrong, OneClick isn't for you. At various times, such as when I was writing my first book, I had to stop using OneClick altogether, because I couldn't afford such frequent crashes and corrupted data. Even in just the few days writing this review, I crashed trying to open a script for editing, again trying to save a script, and again trying to import a saved button; numerous attempts to load a saved palette failed without notification. Users have reported finding scripts replaced with nonsense, or unaccountable automated actions suddenly taking over their computer; in the past few days I myself have seen weird unsummoned windows flash on the screen, Finder items spontaneously duplicated, and other unexplained phenomena. Palette corruption is a constant danger. Some of these problems may relate to Scheduled handlers: when they fire, they give no indication of what is happening; they can interrupt one another; and there is no way to learn what schedules are pending. This is one reason I am chary of buttons I didn't write myself.</P><P>Even OneClick's most basic level of functionality, which presumably involves interfering with the user's mouse-clicks and generating its own to press buttons and choose menu items, is not completely reliable. Sometimes OneClick is just unaccountably slow: I've seen it take well over a second to bring a window to the front in Acrobat Reader; in REALbasic, buttons can be so unresponsive as to be useless; in DiskTop, it's far worse. In Eudora, activating a window through OneClick sometimes activates the wrong one. I've seen arithmetically calculated values occasionally come out the negative of what they should have been. Users report that typing in the script editor window sometimes "falls through" to the application behind.</P><P>Nor does WestCode Software's record of commitment to the survival and support of its product inspire confidence. In late 1996, WestCode cautioned me not to review OneClick 1.03, because 1.5 was about to appear; the next actual upgrade turned out to be 2.0, three years later. The 2.0 beta development process was heartening, but progress was glacial, and WestCode often seemed more inclined to fend off the bug reports than to fix the bugs. Many glitches have been left in this release: there is script window corruption when you make a syntax error, keyboard shortcuts involving "a" don't work, and despite claims of Mac OS 9 compatibility, OneClick doesn't work properly with some Appearance Manager or Navigation Services dialogs. Potential users must judge for themselves whether this sort of laxity is venial or suggestive of possible deeper trouble.</P><P>The manuals are quite good, but rather out of synch with how OneClick actually works; for example, installation doesn't work the way the manual describes it, some screen shots don't match reality, some documented features (such as the ability of control strip modules to be OneClick buttons) don't actually work, and some important and potentially confusing features, such as the ability to "lock" a button (so that it can be pressed while you're editing a script), are completely undocumented. Also, there are two manuals, one for EasyScript, one for everything else, because WestCode wants to convey that OneClick can be useful even if you don't do any of your own scripting; and some 70 pages of material is repeated in both, which is cumbersome and confusing.</P><P><STRONG>Bottom Line</STRONG> -- For me, OneClick's scriptability, power, flexibility, and downright usefulness outweigh all the negatives I've outlined; and the price is extremely competitive. I do wish that OneClick worked a bit more cleanly, and that I felt more encouraged about its future. Nonetheless, whether you want to take advantage of the many powerful palettes available online, want to clean up and rationalize your computer's interface, or want to tinker, customize, and automate with code of your own, OneClick is a superb macro program with a wonderful interface that deserves your serious consideration.</P><P>OneClick typically occupies less than 500K of RAM, and is about a 7 MB installation. OneClick costs $60 for the downloadable version with two PDF manuals, or $80 on CD with one printed manual; the printed scripting manual is $20 more. OneClick requires System 7 and a 68020 processor or later.</P><!-- Freedom of the Button Press - OneClick 2.0 Matt Neuburg --></div>
  1074.         <div id="article_text_bottom_4523" style="display:none">
  1075.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('4523')">Hide full article</a></p><div class="sponsorbox">
  1076. <div class="sponsortext"><A HREF="http://www.smithmicro.com/tidbits"><IMG SRC="http://db.tidbits.com/images/badges/StuffItDeluxe2010.gif" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>StuffIt Deluxe 2011 has everything you need to backup, encrypt,<br />share, and compress all of your photos, audio and documents.<br />Compress it. Secure it. Send it. Try StuffIt Deluxe 2011 today!<br />Click here for a free 30-day trial: <<a href="http://stuffIt.com/tidbits/">http://stuffIt.com/tidbits/</a>></div>
  1077. </div>
  1078. <div class="sponsorbox_bottom"> </div>
  1079. </div>
  1080.  
  1081.         <!-- end article text -->
  1082.     
  1083.         
  1084.  
  1085.         
  1086.     </div><div class="article"><a name="5219"></a>
  1087.     
  1088. <!-- comment initialization routine as needed -->
  1089. <div class="popup_box_with_captcha" id="hc_5219" style="display: none">
  1090.     <div class="tip_box_format">
  1091.     <div id="hc_innards_alt_5219" style="display: none">
  1092.             <div class="tbf_row">
  1093.                 <div class="tbf_wide_80" id="hc_small_response_5219"></div><div class="x_close_row" id="hc_upper_right1_5219"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_5219', 'hc', '5219'); return true;">Close</a></div>
  1094.  
  1095.             </div>
  1096.     </div>
  1097.     <div id="hc_innards_5219">
  1098.         <div class="tip_box_form">        
  1099.             <form action="foobar.cgi" method="get" name="check_human_5219">
  1100.             <div class="tbf_row">
  1101.                 <div class="tbf_wide_80" id="hc_rc_5219">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_5219"><a href="javascript:void(0)" onmousedown="HidePopupContent('hc_5219', 'hc', '5219'); return true;">Close</a></div>
  1102.  
  1103.             </div>
  1104.             <div class="spacer"></div>
  1105.             <div class="tbf_row" id="hc_message_box_5219" style="display:none">
  1106.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_5219"></div></div>
  1107.             </div>
  1108.             <div class="spacer"></div>
  1109.             <div class="tbf_row">
  1110.                 <div class="tbf_wide"><div id="hc_recaptcha_5219"></div></div>
  1111.             </div>
  1112.             <div class="spacer"></div>
  1113.             <div class="tbf_row">
  1114.                 <div class="tbf_wide"><input type="submit" value="Submit" name="submit_this_tip" onClick="handle_tip_submission('hc', '5219', this.form, this.form.submit_type.value); return false;"><input name="calling_routine" type="hidden"><input type="hidden" name="getbits" value="6603"><input type="hidden" name="author_id"><input type="hidden" name="submit_type" value=""></div>
  1115.             </div>
  1116.             <div class="spacer"></div>
  1117.             </form>
  1118.         </div><!-- end tip_box_form -->
  1119.     </div><!-- end hum box innards -->
  1120.     </div><!-- end tip box format -->
  1121. </div><!-- end tip_submit box-->
  1122.  
  1123.  
  1124.  
  1125.         
  1126.         
  1127.         <!-- specific article details here -->
  1128.         
  1129.         
  1130.             <p class="series_number">Article 8 of 9 in series</p>
  1131.         
  1132.     
  1133.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  1134.         
  1135.         <div class="featured_meta"><div class="meta_article">22 Oct 2001 | <a href="/article/6603?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>
  1136.  
  1137.         <H2><a href="/article/6603">QuicKeys X: The Return of the Ghost</a></H2>
  1138.  
  1139.         <p class="byline">by <a href="/author/Matt%20Neuburg">Matt Neuburg</a> <a href="javascript:void(0)" onClick="document.check_human_5219.submit_type.value='email'; document.check_human_5219.author_id.value='7'; ShowTipBox('hc_5219', 'hc_recaptcha_5219')"><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>
  1140.  
  1141.         <!-- article text -->
  1142.         <div id="article_blurb_5219"><p>With the advent of Mac OS X 10.1, I'm using Mac OS X nearly all the time, but many of my long-standing work habits have become useless. That's because those habits rely on third-party utilities that haven't made the transition - and, one fears, may never do so<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('5219')">Show full article</a></span></p></div>
  1143.         <div id="article_text_5219" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('5219')">Hide full article</a></p><P>With the advent of Mac OS X 10.1, I'm using Mac OS X nearly all the time, but many of my long-standing work habits have become useless. That's because those habits rely on third-party utilities that haven't made the transition - and, one fears, may never do so. In Mac OS X, after all, the system works in a whole new way, and developers must learn entirely different methods to hack into it and modify its functionality. Still, it's far from clear what the limits ultimately will be, and we should never underestimate the ingenuity of Macintosh developers.</P><P>Even as Mac OS X first shipped, I was wondering what in particular would become of macro utilities, those "ghosts in the machine" that perform preset actions by fooling your computer into thinking that an actual user is typing keys and wielding the mouse. So it's with some joy and relief that I find that CE Software's QuicKeys has followed me down the rabbit-hole and into the garden of Wonderland - but alas, only, like Alice, by drinking from the bottle that makes you smaller.</P><P><<A HREF="http://www.cesoft.com/products/qkx.html">http://www.cesoft.com/products/qkx.html</A>><BR><<A HREF="http://db.tidbits.com/series/1044">http://db.tidbits.com/series/1044</A>></P><P>In Mac OS X, QuicKeys X is an ordinary application that must be running for you to trigger any shortcuts, so you'll probably make it a startup item by way of the Login preferences panel. Being an ordinary application, QuicKeys X now has ordinary windows and menus, which means that its interface is much improved. Gone are the impenetrable layers of modal dialogs. Indeed, CE has made QuicKeys's windows wonderfully Mac OS X-like, with splendid use of drawers, customizable toolbars, and drag & drop. It's so easy and intuitive that you probably won't even have to read the manual. However, there's still no straightforward list of all your triggers, and there's no way to learn what sequences or floating palettes an action is used in; these are problems I've pointed out for years, and it would have been nice to see CE take this opportunity to tackle them.</P><P><<A HREF="http://db.tidbits.com/series/1044">http://db.tidbits.com/series/1044</A>></P><P>A QuicKeys action can have various triggers, and these can be universal or confined to a particular application being frontmost. The possible triggers for an action are: a keyboard combination or sequence of keyboard combinations; an absolute time, a time interval after startup, or a repeated time interval; clicking in a QuicKeys floating palette; or choosing from the QuicKeys menu (at the right end of the menu bar or in the Dock).</P><P>The narrow range of available actions suggests the limitations imposed upon QuicKeys by Mac OS X. QuicKeys X can type; it can move and click the mouse; it can sleep and shut down the computer; it can send a command to the Unix shell. These are invaluable. The remaining things that QuicKeys can do are achievable in other ways, and are notably less interesting, though welcome for enhancing sequences of actions. QuicKeys can open a file or folder, run an AppleScript script, switch among applications, open a URL, change the Finder's view of a folder, and switch between folders in an Open or Save dialog.</P><P>But QuicKeys can no longer click buttons or choose menu items by name, switch or scroll windows, access the clipboard, or send a raw Apple event. Also, QuicKeys X is now unable to "see" the screen, so it can't make decisions based on a certain window being frontmost or a certain menu item being enabled. QuicKeys's scriptability is also greatly curtailed; basically, it can run an action that you've previously created and named, and that's all.</P><P>QuicKeys X is a welcome and pleasant release, and I'm already putting it to good use. I've stocked it with some boilerplate phrases to be typed into any application, and I've made certain menu items accessible through keyboard shortcuts (though these are slow and unreliable, because instead of choosing the menu item directly, QuicKeys must move the cursor to the item's location). But QuicKeys is only a part of my bag of tricks.</P><P>I don't wish to sound overly negative about QuicKeys X - it may not yet measure up to the full capabilities it provided under Mac OS 9, but it is essentially a 1.0 release because everything it knew how to do in the past has changed with Mac OS X. Just as it's taking us all some time to learn new ways of interacting with Mac OS X as users, so too it's taking time for Apple to expose the innards of Mac OS X to the depth necessary for CE's engineers to write a tool as downright magical as a macro utility. CE has said they will be extending QuicKeys X's capabilities in the future; we wish them luck in ferreting out the secrets to automating Mac OS X's internal workings.</P><P>CE will have to move quickly, since a number of small utilities are coming out for Mac OS X that replicate some of QuicKeys's features. Typing text into applications can be handled by Selznick Scientific Software's Typist or Michael Kamprath's Keyboard Maestro; programs like DragThing, LaunchBar and Sig Software's Drop Drawers offer ways of opening and switching between applications, and launching AppleScript scripts; and I'm sure utilities I haven't yet run across are nibbling at other QuicKeys features.</P><P><<A HREF="http://www.selznick.com/products/typist/">http://www.selznick.com/products/typist/</A>><BR><<A HREF="http://www.keyboardmaestro.com/">http://www.keyboardmaestro.com/</A>><BR><<A HREF="http://www.obdev.at/products/launchbar/">http://www.obdev.at/products/launchbar/</A>><BR><<A HREF="http://www.dragthing.com/">http://www.dragthing.com/</A>><BR><<A HREF="http://www.sigsoftware.com/dropdrawers/">http://www.sigsoftware.com/dropdrawers/</A>></P><P>QuicKeys X costs $60, and a 30-day demo version is available for download.</P><!-- QuicKeys X: The Return of the Ghost Matt Neuburg --></div>
  1144.         <div id="article_text_bottom_5219" style="display:none">
  1145.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('5219')">Hide full article</a></p><div class="sponsorbox">
  1146. <div class="sponsortext"><A HREF="http://macte.ch/conf_tidbits"><IMG SRC="http://db.tidbits.com/images/badges/mactech-twitter-icon-48x48.jpg" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>MacTech Conference, for IT Pros and Apple developers, is Nov 3-5,<br />in Los Angeles. The 3-day event is packed with sessions & evening<br />activities. Learn from the best. Meet and spend time with peers.<br />TidBITS readers save $50 at <<a href="http://macte.ch/conf_tidbits">http://macte.ch/conf_tidbits</a>>!</div>
  1147. </div>
  1148. <div class="sponsorbox_bottom"> </div>
  1149. </div>
  1150.  
  1151.         <!-- end article text -->
  1152.     
  1153.         
  1154.  
  1155.         
  1156.     </div><div class="article"><a name="5716"></a>
  1157.     
  1158. <!-- comment initialization routine as needed -->
  1159. <div class="popup_box_with_captcha" id="hc_5716" style="display: none">
  1160.     <div class="tip_box_format">
  1161.     <div id="hc_innards_alt_5716" style="display: none">
  1162.             <div class="tbf_row">
  1163.                 <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>
  1164.  
  1165.             </div>
  1166.     </div>
  1167.     <div id="hc_innards_5716">
  1168.         <div class="tip_box_form">        
  1169.             <form action="foobar.cgi" method="get" name="check_human_5716">
  1170.             <div class="tbf_row">
  1171.                 <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>
  1172.  
  1173.             </div>
  1174.             <div class="spacer"></div>
  1175.             <div class="tbf_row" id="hc_message_box_5716" style="display:none">
  1176.                 <div class="tbf_wide"><div class="tbf_alert" id="hc_top_message_5716"></div></div>
  1177.             </div>
  1178.             <div class="spacer"></div>
  1179.             <div class="tbf_row">
  1180.                 <div class="tbf_wide"><div id="hc_recaptcha_5716"></div></div>
  1181.             </div>
  1182.             <div class="spacer"></div>
  1183.             <div class="tbf_row">
  1184.                 <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>
  1185.             </div>
  1186.             <div class="spacer"></div>
  1187.             </form>
  1188.         </div><!-- end tip_box_form -->
  1189.     </div><!-- end hum box innards -->
  1190.     </div><!-- end tip box format -->
  1191. </div><!-- end tip_submit box-->
  1192.  
  1193.  
  1194.  
  1195.         
  1196.         
  1197.         <!-- specific article details here -->
  1198.         
  1199.         
  1200.             <p class="series_number">Article 9 of 9 in series</p>
  1201.         
  1202.     
  1203.         <article_link><script type="text/javascript">open_if_linked('')</script></article_link>
  1204.         
  1205.         <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>
  1206.  
  1207.         <H2><a href="/article/7102">Scripting the Unscriptable in Mac OS X</a></H2>
  1208.  
  1209.         <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>
  1210.  
  1211.         <!-- article text -->
  1212.         <div id="article_blurb_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.To understand this revolution, you need to know what a macro program is<span class="readmore_series"><a href="javascript:void(0)" onClick="return showhide_article('5716')">Show full article</a></span></p></div>
  1213.         <div id="article_text_5716" style="display:none"><p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('5716')">Hide full article</a></p><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>
  1214.         <div id="article_text_bottom_5716" style="display:none">
  1215.         <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_article('5716')">Hide full article</a></p><div class="sponsorbox">
  1216. <div class="sponsortext"><A HREF="http://www.smilesoftware.com/"><IMG SRC="http://db.tidbits.com/images/badges/SmileLogo2010-50x50.gif" ALT="" HEIGHT="50" WIDTH="50" BORDER="0" ALIGN="left"></A>Get more productive with software from Smile: PDFpen for<br />editing PDFs; TextExpander for saving time and keystrokes while you<br />type; DiscLabel for designing CD/DVD labels and inserts. Free demos,
  1217. <br />fast and friendly customer support. <<a href="http://www.smilesoftware.com/">http://www.smilesoftware.com/</a>></div>
  1218. </div>
  1219. <div class="sponsorbox_bottom"> </div>
  1220. </div>
  1221.  
  1222.         <!-- end article text -->
  1223.     
  1224.         
  1225.  
  1226.         
  1227.     </div><!-- end show article -->
  1228.     
  1229.     
  1230.     <p class="showhide_all_series"><a href="javascript:void(0)" onClick="return showhide_all_articles('2739,2675,2684,2696,2700,4175,4523,5219,5716')"><span id="showhide_arts_bottom">Show the full text of all articles</span></a>
  1231.  
  1232.  
  1233. <!-- article_plus end -->
  1234. <!--
  1235. </DIV>
  1236. --><!-- end main_column DIV -->
  1237.  
  1238.  
  1239. <!-- google_ad_section_end -->
  1240.  
  1241. </div><!-- end center AJAX insert -->
  1242.  
  1243. <!-- TipBITS Search Results Lozenge -->
  1244. <div id="tipbits_results_loz" style="display:none">
  1245. <form method="post" onsubmit="return false" id="tipbits_form_loz" name="tipbits_form_loz" action="noaction.cgi">
  1246. <div class="tip_footer">
  1247. <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>
  1248. </div>
  1249. <div class="tip_footer_bottom">
  1250.  </div>
  1251. </form>
  1252. </div><!-- end TipBITS Search Results lozenge -->
  1253.  
  1254.  
  1255.  
  1256.  
  1257. <!-- begin footer -->
  1258. <div id="footer">
  1259.  
  1260.  
  1261. <p>Special thanks to <a href="http://www.forest.net/">digital.forest</a>, our
  1262. Web and mailing list host.</p>
  1263.  
  1264. <p>TidBITS is copyright © 2010 TidBITS Publishing Inc.</p>
  1265. <p>Reuse governed by <a href="http://www.tidbits.com/terms/">Creative Commons License</a>.</p>
  1266.  
  1267. <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>
  1268.  
  1269. </div><!-- end footer -->
  1270.  
  1271.  
  1272. </div> <!-- end centercolumn -->
  1273.  
  1274. <div class="center_bottom"> </div>
  1275.  
  1276. </div> <!-- end centercolumn_border -->
  1277.  
  1278.  
  1279. </div> <!-- end content_container -->
  1280.  
  1281. </div> <!-- end mainbody -->
  1282.  
  1283.  
  1284. <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
  1285. </script>
  1286. <script type="text/javascript">
  1287. _uacct = "UA-276924-3";
  1288. urchinTracker();
  1289. </script>
  1290. <script type="text/javascript"
  1291. src="http://tidbitscom.skimlinks.com/api/skimlinks.js"></script>
  1292. <script type="text/javascript">
  1293. var skimlinks_pub_id = '2559X585851';
  1294. var skimlinks_domain = 'go.tidbits.com';
  1295. skimlinks();
  1296. </script>
  1297. </body>
  1298. </html>
  1299.  
  1300.