<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>An Experiment in Bloggery &#187; Uncategorized</title>
	<atom:link href="http://kevin.sb.org/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://kevin.sb.org</link>
	<description>The occasional view into my life</description>
	<lastBuildDate>Wed, 30 Jun 2010 18:48:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>TinEye Safari Extensions</title>
		<link>http://kevin.sb.org/2010/06/12/tineye-safari-extensions/</link>
		<comments>http://kevin.sb.org/2010/06/12/tineye-safari-extensions/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 05:43:14 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[tineye]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/?p=242</guid>
		<description><![CDATA[TinEye is a cool reverse image search engine. It lets you take an image and search for it on the web, even finding uncropped, expanded, or unwatermarked versions of the image. Sadly, while TinEye provides plugins for both Firefox and Chrome, they don&#8217;t provide one for Safari. Because of this, I have written my own [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tineye.com">TinEye</a> is a cool reverse image search engine. It lets you take an image and search for it on the web, even finding uncropped, expanded, or unwatermarked versions of the image. Sadly, while TinEye provides plugins for both Firefox and Chrome, they don&#8217;t provide one for Safari. Because of this, I have written my own extension. Just install it, then right-click on any image and you should see &#8220;Search Image on TinEye&#8221;. You can <a href="http://github.com/kballard/TinEye-for-Safari">get it here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2010/06/12/tineye-safari-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CleanGoogle Safari extension</title>
		<link>http://kevin.sb.org/2010/06/10/cleangoogle-safari-extension/</link>
		<comments>http://kevin.sb.org/2010/06/10/cleangoogle-safari-extension/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 07:43:09 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/?p=226</guid>
		<description><![CDATA[If you&#8217;re like anybody else that I know, you were rather shocked and appalled to see Google follow the likes of Bing and add background images to their home page. If you&#8217;re also like anybody else that I know, you&#8217;re aware that Safari 5 was released with support for extensions. And if you&#8217;re like me, [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like anybody else that I know, you were rather shocked and appalled to see Google follow the likes of <a href="bing.com">Bing</a> and add background images to their home page. If you&#8217;re also like anybody else that I know, you&#8217;re aware that Safari 5 was released with support for extensions. And if you&#8217;re like me, you thought that the new extensions behavior might be a great way to, erm, &#8220;fix&#8221; Google. Inspired by a tweet from <a href="http://twitter.com/rentzsch/status/15831330366">@rentzsch</a>, I decided to figure out how this might be done. I am, of course, not a JavaScript programmer, and Google&#8217;s front page code is quite obfuscated, but after playing around with it for a bit over an hour, I got something that worked. Unfortunately it also has the side-effect of blocking the fairly nice fade-in of all the text content, and it&#8217;s also a bit fragile, but if you absolutely cannot stand the background image, feel free to <a href="/files/CleanGoogle.safariextz">download the extension</a> and try it out.</p>

<p><strong>Update</strong>: I played around for a few more hours and got something much better. It&#8217;s still fragile, but not nearly so much as before, and it restores the fade effect for all the google content. Same <a href="/files/CleanGoogle.safariextz">download link</a> as before.</p>

<p><strong>Update 2</strong>: Looks like Google fixed their homepage sometime this morning, so this extension is now officially obsolete. I will continue to host the download if anybody is interested in the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2010/06/10/cleangoogle-safari-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>1Password extension loading in Snow Leopard</title>
		<link>http://kevin.sb.org/2009/09/02/1password-extension-loading-in-snow-leopard/</link>
		<comments>http://kevin.sb.org/2009/09/02/1password-extension-loading-in-snow-leopard/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 22:11:11 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[1Password]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[osax]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[Snow Leopard]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/?p=201</guid>
		<description><![CDATA[One of the big changes in Snow Leopard is the move to 64-bit applications system-wide. This includes Safari. Unfortunately, this change breaks all of the Safari plugins out there, including mine. There&#8217;s two reasons for this. The first is simply that these plugins are all 32-bit binaries, and a 64-bit app cannot load a 32-bit [...]]]></description>
			<content:encoded><![CDATA[<p>One of the big changes in Snow Leopard is the move to 64-bit applications system-wide. This includes Safari. Unfortunately, this change breaks all of the Safari plugins out there, including mine. There&#8217;s two reasons for this. The first is simply that these plugins are all 32-bit binaries, and a 64-bit app cannot load a 32-bit binary. The second, and significantly harder obstacle, is that the entire Input Manager mechanism has been eliminated in 64-bit apps.</p>

<p>Read more to find out how 1Password gets around these limitations.</p>

<p><span id="more-201"></span></p>

<h4>A bit of history</h4>

<p>When Cocoa was introduced, one of the behaviors that every Cocoa application automatically acquired was the loading of Input Managers. These Input Managers were intended to allow developers to extend the text input system of OS X in ways that the system did not provide by default. However, these Input Managers were really nothing more than Cocoa bundles that got loaded by every single Cocoa app at launch. This means that it was very quickly abused to become a general plugin mechanism for applications that do not natively support plugins (such as Safari). In recent OS updates, Apple has been deprecating this mechanism, and now in Snow Leopard it&#8217;s completely gone for 64-bit apps.</p>

<h4>How can I use Safari plugins?</h4>

<p>The simplest way is to simply right-click Safari in the Finder, select Get Info, and check the Open in 32-bit mode checkbox. However, this has the downside of removing all of the performance benefits of 64-bit apps. Besides the normal benefits of an improved instruction set and a more modern Objective-C runtime, Safari&#8217;s JavaScript engine particularly benefits from running in 64-bit mode. So while this is a stopgap measure, it isn&#8217;t suitable for long-term use.</p>

<p>Luckily, the smart folks who make <a href="http://agilewebsolutions.com/products/1Password" title="Agile Web Solutions">1Password</a> came up with a solution for their upcoming 1Password 3.0 (which is in public beta right now). I have only done some minimal poking around, but I believe I&#8217;ve figured out the mechanism they use to load their plugin into Safari in the absence of Input Managers.</p>

<h4>Sow how does it work already?</h4>

<p>First, an introduction to <a href="http://en.wikipedia.org/wiki/AppleScript">AppleScript</a> and <a href="http://developer.apple.com/mac/library/technotes/tn/tn1164.html">Scripting Additions</a>. AppleScript is a rather old technology, first introduced in <a href="http://en.wikipedia.org/wiki/System_7" title="Mac OS 7">System 7</a>. It is a human-readable scripting language that can control any application that implements support for it, along with a slew of system functions and, more recently, generic control of UI elements<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>. Under the hood, it sends <a href="http://en.wikipedia.org/wiki/Apple_events">Apple events</a> to actually talk to each process. Scripting additions are bundles that provide additional functionality to AppleScript, generally by installing Apple event handlers or doing Apple event data coercion. Several scripting additions are bundled with the system, such as the Keychain Scripting addition which provides access to the Keychain from within AppleScripts.</p>

<h4>What does this have to do with 1Password?</h4>

<p>I&#8217;m getting there. The thing about scripting additions is that they will be potentially loaded by any process on the system. Generally, they get loaded into a process that attempts to use an AppleEvent that the scripting addition handles. Here it gets a little fuzzy, as the documentation does not specify whether the sending process or the receiving process loads the scripting addition. In general, it doesn&#8217;t matter, and so I suspect the sending process is usually the one that handles the event<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>. In fact, up through Mac OS X 10.5, the &#8220;context&#8221; for a scripting addition was always assumed to be &#8220;Machine&#8221;, which means the AppleEvent can be handled by any process on the machine it was sent to<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>. New in 10.6 is the ability to specify exactly which context the scripting addition handler must execute in, including &#8220;Any&#8221;, &#8220;Machine&#8221;, &#8220;User&#8221;, or &#8220;Process&#8221;. That last context is the important one, as it means the scripting addition handler must be executed in the Apple event&#8217;s target process.</p>

<p>There is one caveat here which is that if a process has not initialized AppleScript, it will not have loaded any scripting additions. You can get around this by sending the kASAppleScriptSuite/kGetAEUT (ascr/gdut) Apple event to a process (according to <a href="http://developer.apple.com/mac/library/qa/qa2001/qa1070.html" title="Technical Q&#038;A QA1070">QA1070</a> the system automatically installs the handler for kASAppleScriptSuite/kGetAEUT on Mac OS X 10.2 or later). This event causes the &#8220;system handler table&#8221; for that process to be initialized, which loads the scripting additions.</p>

<h4>So we can load Scripting Additions. What now?</h4>

<p>The ability to load a scripting addition into a target process simply by sending it an Apple event is the key mechanism that allows us to restore the old Input Manager functionality. And this is exactly what 1Password does. 1Password includes a scripting addition that handles the ONEP/Load Apple event with a context of &#8220;Process&#8221;. This handler takes a single argument, the path to a given bundle, and it loads that specified bundle into the target process. The last component is a background daemon called 1PasswordAgent. This daemon sends the ONEP/Load Apple event to Safari immediately after Safari is launched<sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup>, causing Safari to load the 1Password WebKit plugin. You can see this in the following AppleEvent log:</p>

<pre><code>{ 1 } 'aevt':  ONEP/Load (i386){
          return id: 284 (0x11c)
     transaction id: 0 (0x0)
  interaction level: 64 (0x40)
     reply required: 0 (0x0)
             remote: 0 (0x0)
      for recording: 0 (0x0)
         reply port: 37635 (0x9303)
  target:
    { 1 } 'psn ':  8 bytes {
      { 0x0, 0x1a01a } (1PasswordAgent)
    }
  fEventSourcePSN: { 0x0,0x1a01a } (1PasswordAgent)
  optional attributes:
    &lt; empty record &gt;
  event data:
    { 1 } 'aevt':  - 1 items {
      key '----' - 
        { 1 } 'TEXT':  70 bytes {
          "/Applications/1Password.app/Contents/Extensions/WebKitExtension.bundle"
        }
    }
}
</code></pre>

<h4>Is that it?</h4>

<p>Yep, that&#8217;s it. Through the use of the Scripting Additions mechanism and a daemon, 1Password is able to load its bundle into 64-bit processes. This is actually fairly similar to how applications that use <a href="http://rentzsch.com/mach_inject/">mach_inject</a> work, except instead of injecting code at the mach level, it leverages existing higher-level interprocess communication mechanisms, which is likely to be far safer.</p>

<p>There is one more step. Safari sends an AppleEvent back to 1PasswordAgent (1Pwd/UNLK) after the bundle has been loaded. I am not sure what the purpose of this is, but I suspect UNLK stands for &#8220;Unlock&#8221; and is used for some sort of synchronization between the 1Password extension and 1PasswordAgent. It should not be necessary for most plugins.</p>

<h4>How do I use this in my own Safari plugin?</h4>

<p>At the moment, the only way is to do all the work that the 1Password guys did, and run your own daemon in the background to load your plugin into Safari. Perhaps if enough people ask, the 1Password guys will generalize their solution into something like SIMBL, e.g. a generic application plugin loader. Or maybe someone who reads this will be inspired to do it themselves.</p>

<p>One last thing: Apple clearly does not like bundles loading themselves into arbitrary processes on the system. And for a good reason. A lot of crashes and instability in the system are caused by poorly-written Input Managers or APE Haxies. This is why they removed the Input Manager system entirely. Unfortunately, as long as Safari continues to have no plugin API, such hacks are necessary to be able to use products like 1Password. If you choose to use this mechanism yourself, just be aware that Apple will most certainly frown upon it, and may try and take steps to eliminate this hole in future versions of the OS. And please, make sure your plugin is bug-free and future-compatible<sup id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup>. The absolute worst thing you can do is cause users to experience crashes in applications.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Controlling UI elements requires turning on the &#8220;Enable access for assistive devices&#8221; checkbox in the Universal Access preference pane.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>At least, on Snow Leopard. It seems Leopard always loaded the scripting addition into the target process, as it did not have the concept of a context.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:3">
<p>AppleEvents can be sent between machines if Remote Apple Events is enabled in the Sharing preference pane.&#160;<a href="#fnref:3" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:4">
<p>As I suggested earlier, it actually sends the kASAppleScriptSuite/kGetAEUT (ascr/gdut) Apple event to Safari first, to ensure the scripting addition has been loaded.&#160;<a href="#fnref:4" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:5">
<p>One of the big wins of SIMBL was that it made it so easy to specify a maximum supported bundle version for your plugin, and it strongly encouraged that you always set this to the current bundle version. In other words, whenever Safari got updated, you would be forced to test your plugin against the latest version of Safari and re-certify it as correct, or it would simply disable itself.&#160;<a href="#fnref:5" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2009/09/02/1password-extension-loading-in-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>MediaLink</title>
		<link>http://kevin.sb.org/2008/07/13/medialink/</link>
		<comments>http://kevin.sb.org/2008/07/13/medialink/#comments</comments>
		<pubDate>Sun, 13 Jul 2008 05:45:39 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MediaLink]]></category>
		<category><![CDATA[PS3]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[TV]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/?p=156</guid>
		<description><![CDATA[As a PlayStation™ 3 owner and an Apple TV owner, I can&#8217;t recommend MediaLink enough. It fills the missing link in my tv/movie-watching habits. Everything in my iTunes library I can watch on my Apple TV, but I have plenty of video files that iTunes can&#8217;t handle. Until recently, I&#8217;ve been forced to watch them [...]]]></description>
			<content:encoded><![CDATA[<p>As a PlayStation™ 3 owner and an <a href="http://www.apple.com/appletv">Apple TV</a> owner, I can&#8217;t recommend <a href="http://www.nullriver.com/products/medialink">MediaLink</a> enough. It fills the missing link in my tv/movie-watching habits. Everything in my iTunes library I can watch on my Apple TV, but I have plenty of video files that iTunes can&#8217;t handle. Until recently, I&#8217;ve been forced to watch them on my computer. But I have an HDTV for a reason, and I&#8217;d like to watch my shows there. <a href="http://www.nullriver.com/">Nullriver&#8217;s</a> <a href="http://www.nullriver.com/products/medialink">MediaLink</a> solves this problem. Anything that I can&#8217;t watch on my Apple TV, I can watch on my PS3, and it works flawlessly. I can fast-forward and rewind smoothly, I can jump to any point in the movie (using the PS3&#8217;s Go To feature), and it handles everything. Even when my computer lost wifi briefly (the microwave interferes with my desktop&#8217;s wifi), the video stream just paused until the wifi came back and then resumed as if nothing happened. If you own a PlayStation™ 3, you should go out and purchase <a href="http://www.nullriver.com/products/medialink">MediaLink</a> right now.</p>

<p>Disclaimer: I have no personal stake in <a href="http://www.nullriver.com/">Nullriver</a> or <a href="http://www.nullriver.com/products/medialink">MediaLink</a>, I am simply a happy customer.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2008/07/13/medialink/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Return to Dark Castle released</title>
		<link>http://kevin.sb.org/2008/03/15/return-to-dark-castle-released/</link>
		<comments>http://kevin.sb.org/2008/03/15/return-to-dark-castle-released/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 02:54:41 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Dark Castle]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://kevin.sb.org/2008/03/15/return-to-dark-castle-released/</guid>
		<description><![CDATA[Big news for Mac gaming today. Return to Dark Castle has finally been released for OS X! This game has been in development for about 7 years now, and it should be very familiar to anybody who played Mac games 15-20 years ago. Heck, I&#8217;m only 22 and I remember Beyond Dark Castle.]]></description>
			<content:encoded><![CDATA[<p>Big news for Mac gaming today. <a href="http://www.superhappyfunfun.com/games/gam_returntodc.html">Return to Dark Castle</a> has finally been released for OS X! This game has been in development for about 7 years now, and it should be very familiar to anybody who played Mac games 15-20 years ago. Heck, I&#8217;m only 22 and I remember Beyond Dark Castle.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2008/03/15/return-to-dark-castle-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wonky memory usage</title>
		<link>http://kevin.sb.org/2007/09/13/wonky-memory-usage/</link>
		<comments>http://kevin.sb.org/2007/09/13/wonky-memory-usage/#comments</comments>
		<pubDate>Thu, 13 Sep 2007 12:28:19 +0000</pubDate>
		<dc:creator>Kevin Ballard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://222febb3-a06f-47b9-aef9-30d6878edd5c</guid>
		<description><![CDATA[Can anybody explain what&#8217;s going on with that memory usage? I&#8217;ve been seeing this for a few months now. These days I tend to restart a handful of apps at least once a day (sometimes more often) to combat this apparent memory problem. I&#8217;ve tried just ignoring it, but my system also tends to become [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://kevin.sb.org/files/Memory-Usage.png" alt="Memory-Usage.png"><img src="http://kevin.sb.org/files/Memory-Usage.png" alt="Memory-Usage.png" border="0" width="50%" height="50%" /></a></p>

<p>Can anybody explain what&#8217;s going on with that memory usage? I&#8217;ve been seeing this for a few months now. These days I tend to restart a handful of apps at least once a day (sometimes more often) to combat this apparent memory problem. I&#8217;ve tried just ignoring it, but my system also tends to become less responsive over time, especially when accessing apps that I haven&#8217;t used in the last few minutes, so I can only assume that apps are getting paged out frequently. Running <code>sysctl vm.swapusage</code> seems to bear that out as well, at the moment I&#8217;m using 1.6GiB and when I checked 2 days ago (before a reboot) I was using close to 3GiB (quitting apps brought that down to about 2.2GiB). Unfortunately I can&#8217;t seem to get anywhere on figuring out what&#8217;s going on with all this memory. If I run <code>vmmap</code> on one of these processes I just see a lot of malloc blocks.</p>
]]></content:encoded>
			<wfw:commentRss>http://kevin.sb.org/2007/09/13/wonky-memory-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->