cannot find code object on disk

A quick note for anyone googling this particular problem:

Getting “cannot find code object on disk” when compiling with latest XCode with code signing turned on?

Hard to find the solution on the net, but eventually I figured it out – latest xcode does not have all the tools bundled yet. Do this:

ln -s /usr/bin/codesign_allocate /Applications/Xcode.app/Contents/Developer/usr/bin/codesign_allocate

 

Change Space grows up

Changespace

At the end of August I posted about Change Space.app, which seeks to replace the sorely missed 2D grid spaces feature that was in Snow Leopard for those unlucky enough to be using OSX Lion.

Now it’s two and a half months and over 50 commits later, and I have just released version 2.2.0. I think the app is getting pretty usable.

The last post I mentioned how I was using MacRuby to write the app, and indeed this was a pretty quick and easy way to get it off the ground.

But there are a couple of issues with MacRuby. Firstly, you need to set your Xcode up to include the MacRuby framework and runtime in the .app file otherwise users will have to install it themselves. And the runtime adds about 10Mb to your app size.

Secondly, when integrating with other libraries and certain calls to the Cocoa libraries and other APIs you find yourself having to write bridge code where the structures you are dealing with do not map easily to ruby objects.

Given these issues, I decided to rewrite the app completely in Objective C.

By mid October I had the App running nicely in the new language, and it was coming in at about half a meg as opposed to just under ten.

Some great libraries helped with the features I needed. Shortcutrecorder provided an ability to change the global hotkeys.

Change_space
Change Space also displays the current desktop number in the status bar at the top of your screen.

At this time, rather than fade the desktop number out as I had been doing previously, the number was shown in the status bar permanently by polling the system for which desktop was active each second. I was to find a better way to do this though – it turns out that there is a notification for desktop change, so I can just subscribe to that and remove the polling altogether.
NSNotificationCenter *notCenter;    notCenter = [[NSWorkspace sharedWorkspace] notificationCenter];    [notCenter addObserver:self               selector:@selector(workspaceObserver:)               name:NSWorkspaceActiveSpaceDidChangeNotification object:nil];

I also wanted to add central screen notifications of the direction of movement between your spaces, and which you went from and to.

I started off with a simple arrow, but it would be far nicer to see an entire grid of the right dimensions. Step in Harry Groover, who provided code for a very nice looking grid. I added the arrow, and we had a really great looking result.

Change-space-1

Next up I wanted the desktops to move in the right direction.

The importan APIs are defined like this:

extern OSStatus CGSNewTransition(const CGSConnection cid,   const CGSTransitionSpec* spec, int *pTransitionHandle);        extern OSStatus CGSInvokeTransition(const CGSConnection cid,   int transitionHandle, float duration);

The reverse engineering has already been done for us by previous apps such as DesktopManager, so the enum documentation can be found.

Not everything seems to work in Lion, but we have enough to work with. Calling CGSNewTransition will freeze the existing desktop, and wait for a transition to be invoked.

CGSInvokeTransition will perform the specified transition.

Unfortunately I do not have (as yet) a way to disable the standard left or right lion transitions, so when I want the desktop to move up or down I need to wait for the left or right transition to happen between creating the new transition and invoking it. Experimentation tells me that 0.3s is a long enough wait for that.

So the vertical transitions have a slight delay before they activate, but I think it’s worth it to preserve illusion of a grid.

For those who can’t stand the extra wait, I added a preference option to allow these transitions to be turned off.

So now, I think Change Space.app has come of age.

There are still a few problems to iron out, in particular the space 1 issue (I must use the AppleScript bridge to navigate to it, which is slower and is affected by which modifier keys you are holding down).

I hope to have this problem licked soon though.

Download Change Space.app v2.2.0 here.

Fixing the lack of 2D spaces in Lion

Tl;dr See my Change Space app

In OSX Lion Apple dispensed with the simple and effective 2D spaces grids many people loved and relied on.

In its place, there is the more dynamic concept of ‘Desktops’, which can be created by the system on the fly, for instance when running a full screen app. Also, the system can re-order the desktops according to your use.

These dynamic features are of little use to power users, who know where their apps and windows are, and like to navigate fast between them. A common layout is a 3×3 grid – then from the central space you can reach 4 others with just one keypress. Very useful for flicking between your code editor, and the browser, and perhaps mail, or iTunes for instance.

Even the animation when moving between desktops on Lion is slower than with the old Spaces system, making it really feel like a big step backwards for usability.

I’m not the only who feels this way – see stackoverflow here http://stackoverflow.com/questions/6768684/osx-lion-applescript-how-to-get-cu… … and there’s even a facebook page here https://www.facebook.com/pages/Save-Spaces/216451795053936

While many still hope that Apple will bring back the old Spaces system as an option, in the mean time something needed to be done.

Having found some clues on the stackoverflow post mentioned above, I thought I’d have a go at writing an app to do the directional switching.

Applescript

If there’s one thing I hate it’s applescript. But, it has its uses. The first thing to do was to try a few little scripts to see if I could get to a particular desktop.

To run this from the command line I needed this kind of incantation

arch -i386 osascript changespace.applescript 4

And it worked – if you don’t happen to have any modifier keys other than control pressed, and if you don’t try to go to any desktop above number 4

Not good enough, but the information will come in use later.

CFNotificationCenter

There was a gist linked from the stackoverflow post that contains a few lines of code that can both find the id number of a desktop (they are no longer numbered sequentially – see here for an interesting post about this), and can move you to a particular desktop by sending a message to CFNotificationCenter.

This is almost everything we need. There is a wrinkle though – it appears that desktop 1 is special, and this code cannot navigate to it.

Also desktop 1 always returns the id number 1 (as opposed to some random 5 or 6 digit number).

Putting it together

At first, I made a short shell script for each direction, that ran the compiled C code or some applescript, and hooked those scripts up to Alfred.app using the Global Hotkeys feature (which is very handy by the way).

This was a disaster. Alfred starts a shell to run the shell script in, but this inteferes with the current showing desktop (because I have my terminals set to appear on desktop 5). So although I could see movement, it wasn’t useful.

So I need an app

What better time to have a play with macruby?

There are plenty of resources on the net to help you get started.

So I got macruby installed, and got myself set up in Xcode with a new app, Change Space.app.

One of the really cool things about macruby is the total integration with Objective C message passing. Everything just works together with Ruby method calls like magic. Really, it’s great – skim through this introduction if you are interested.

As I don’t know a way of directly calling C functions from macruby, I wrote a bridge class that calls them for me using Objective C messages that I can send from macruby.

So with this bridge over to the existing C code for changing and identifying spaces, I’m part of the way there.

For switching to desktop 1 I still need to send a keypress – after some investigation I found that the ScriptingBridge framework is the answer.

Here’s how I send a keypress using it:

It was rather opaque how to send the control down, and to be honest I have no idea how you would send something like control-shift. But no matter, we have what we need.

I still needed to hook the hotkeys. And I have davedelong to thank for the answer, DDHotKeyCenter.

For the next part, I wanted a status bar icon like the old spaces app. This gist was helpful, and the code is simple to adapt.

As people have different layouts for their spaces, I needed to set some preferences. In fact you can set a preferences panel up in the interface builder without much effort, see this guide from Apple.

To access the settings from macruby is simple:

defaults = NSUserDefaultsController.sharedUserDefaultsControllerlayout = defaults.values.valueForKey("gridLayout")

I added a few icons, and Bob’s your uncle – Change Space.app v1.

Celebrate with Champagne

Well, maybe not (oh ok just a sip). The app is not perfect in any way – the biggest niggle is that holding the shift key down after commanding a move to space 1 causes that movement to fail. Hopefully that can be solved.

But there are other niggles – it would be really nice if we could make the desktops move in the right directions. And if we could get notification of when the active desktop changes then the desktop number indicator on the status bar could be there at all times.

Anyway, the beauty of github is anyone can contribute – so please go ahead and fix it!

 

Rails 3 with jumploader

Java applets went out of fashion some years ago, and you don’t see them very often now. But they still can be useful. We had a file upload problem that was not solved by plupload, uploadify, swfupload or any other common solutions.The answer was JumpLoader – with this we can upload files bigger than 2Gb, and it’s got a host of other nice options and features. (Yeh, I know it may not be a good idea to try to send files >2Gb through a browser, but that’s what we need to offer – and at least we can arrange to resume failures.)The downside is that it needs to be code-signed if you do not want your users to see a self signed certificate warning when they run it for the first time. Those certificates are quite expensive ($200 per year depending). But assuming that’s not a problem, let’s dive in and get it working with Rails 3.There are two things you need to send when posting a file upload to rails – the request forgery protection token in with the post params, and the cookie that identifies you in the header.Fortunately, JumpLoader offers us both possibilities.I’ve installed the java files in public/java.  So this is how my applet tag looks, in HAML:And the resulting tag in the HTML output:Here we have set the requestProperties to the session cookie, which ensures it is sent with the request headers.We also tell the applet to ‘fireAppletInitialized’ which is a javascript function.Here is the javascript from the head of the document, in ERB this time:This sets the token in a parameter that will be sent with the posted file. Now the upload should pass the csrf check.Note the 1 second delay before setting the parameter in the applet. This is because I was seeing hangs in Safari when setting the parameter directly from the appletInitialized function.

Much faster Rails tests if you use MyISAM

Here’s a little insight I had the other day.If you use MyISAM tables, and there are various performance related reasons you might, then you’ve been stuck having to turn transactional fixtures off in your tests.But unless you are using some special feature of MyISAM that is not present in InnoDB, then why not use InnoDB tables in your test database?I wrote a simple plugin that has a rake task that clones the development database to the test while changing the ENGINE to InnoDB.You just run the task, turn transational fixtures on in test/test_helper.rb, and you’re off.Result: our tests used to take 8.5 minutes to run. Now they take just 3 minutes. That’s about 65% less time than it used to take.The plugin is here: http://github.com/sdsykes/fast_fixture

FastImageInline – inline images in your html code

You may not know this, and I didn’t until recently, but you can place images directly in your img tags. Not just the address of them, but the whole binary data – base 64 encoded.The technique is based on the Data URI scheme.Take a look at the source of Google News. Scroll down a bit and you should start to see image tags that contain base64 encoded data (well you will if you are on IE8 or another make of browser – not IE7). That’s what I’m talking about.The technique is particularly suitable if you have have small images that change often and you do not need the browser to cache them. In this case, the saved http connection and fetch that inlining the images affords you is a performance win.In case you find it useful I have extended my FastImage series with FastImage Inline, which is a gem and rails plugin that will take care of inlining your images.It’s simple to use – just like image_tag there is now a helper method inline_image_tag (and inline_image_path for image_path). Example

inline_image_tag("bullet.gif")

Result for request from a data-uri capable browser:

<img alt="Bullet" src="data:image/gif;base64,R0lGODlhCAANAJECAAAAAP///////wA  AACH5BAEAAAIALAAAAAAIAA0AAAITlI+pyxgPI5gAUvruzJpfi0ViAQA7" />

Result for a non-capable browser (eg IE7 or below):

<img alt="Bullet" src="/images/bullet.gif?1206090639" />

 InstallationNote that the FastImage gem must be installed first, check the requirements section below. As a Rails plugin

./script/plugin install git://github.com/sdsykes/fastimage_inline.git

 As a Gem

sudo gem install sdsykes-fastimage_inline -s http://gems.github.com

Install the gem as above, and configure it in your environment.rb file as below:

...  Rails::Initializer.run do |config|    ...    config.gem "sdsykes-fastimage_inline", :lib=>"fastimage_inline"    ...  end  ...

 Requirements* FastImage http://github.com/sdsykes/fastimage Browser supportAll modern browsers support this technique except for IE versions 7 and below. This is still a major segment of the market of course, but as IE users migrate to IE 8 this will become less of a problem. FastImage Inline uses a simple browser detection mechanism by looking at the user agent string. If the browser is known to not have support, or if we do not recognise it at all, we serve a normal image tag which includes the path to the image file in the src attribute. But if we know the browser can handle it, we send the image inline, and the browser won’t need to fetch it separately. LimitsReportedly IE8 will not handle data strings longer than 32k bytes. But it is probably unwise to inline images this big anyway. Google news serves images that are up to about 3.5k in length, and this seems a reasonable approach. However, FastImage Inline does not enforce any particular constraints, it is for you to decide.FastImage Inline does not cache the images it has read – so every time an image is sent it will be read from disk. This feature may be added in a later release. ConclusionInlining images is not for everyone, but it’s a useful technique in your toolbox for optimising delivery of certain kinds of pages or content. For more information check the comprehensive list of advantages and disadvantages on the Data URI scheme wikipedia page.

Recent code – FastImage resize, Scrooge and Read From Slave

A roundup of some of my projects that may be of interest:1. FastImage ResizeThis builds on my work on FastImage to provide an image resize facility.  The resize code calls libgd to do the work of resampling and resizing the image – this is a library that is very likely to be already installed on your system if it is some flavour of unix / linux or even OSX.  And if not, it is very easy to install.  This is a light and simple option if you don’t wish to install heavier libraries such as RMagick (which relies on ImageMagick or GraphicsMagick) or ImageScience (which relies on FreeImage).2. ScroogeThis is a plugin and gem to optimise queries to the database based on a learning algorithm that looks at how the results of each query are used.  I worked on this with Lourens Naudé earlier this year, and I will shortly make a minor release with a few further optimisations and tests.  Try this if your database is slowing you down, but also see slim-attributes if you are using MySQL.3. Read From SlaveA gem to force your database reads to a slave database while your writes go to the master.  It’s fast and simple, it works a treat, and we have it in production use.