<feed xmlns='http://www.w3.org/2005/Atom'>
<title>MASShortcut/Demo, branch 2.1.0</title>
<subtitle>Modern framework for managing global keyboard shortcuts compatible with Mac App Store. More details:</subtitle>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/'/>
<entry>
<title>Added support for older OS X releases back to 10.6 included.</title>
<updated>2015-01-12T16:10:20+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2015-01-09T11:54:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=86a32313986fb9da606df40bc937298b2abeed35'/>
<id>86a32313986fb9da606df40bc937298b2abeed35</id>
<content type='text'>
Apart from turning off Auto Layout for the Demo project, the only
thing remaining was several __weak qualifiers to prevent retain
cycles in blocks. I have replaced them with __unsafe_unretained
since __weak is not supported on 10.6. There should be no safety
concerns here, since we are certain the pointers will remain valid.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Apart from turning off Auto Layout for the Demo project, the only
thing remaining was several __weak qualifiers to prevent retain
cycles in blocks. I have replaced them with __unsafe_unretained
since __weak is not supported on 10.6. There should be no safety
concerns here, since we are certain the pointers will remain valid.
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove Xcode warnings and fix the hard-coded shortcut.</title>
<updated>2015-01-09T19:04:10+00:00</updated>
<author>
<name>Vadim Shpakovski</name>
</author>
<published>2015-01-09T19:04:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=0a0619461d473085608af0aa1e00540bf6253a9c'/>
<id>0a0619461d473085608af0aa1e00540bf6253a9c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Expanded demo functionality (preparing for 2.0.0, see #54).</title>
<updated>2015-01-09T09:53:45+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2015-01-09T09:51:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=f63c21e11cfad4fb8408effae2efb07164ad5760'/>
<id>f63c21e11cfad4fb8408effae2efb07164ad5760</id>
<content type='text'>
Mostly back to the previous version with enable/disable checkboxes &amp;
one settable and one hard-coded shortcut. I have tried to come up with
a nicer pattern to watch the enabled/disabled checkboxes, but without
external dependencies like Facebook’s KVOController I didn’t come up
with anything better than plain old KVO.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Mostly back to the previous version with enable/disable checkboxes &amp;
one settable and one hard-coded shortcut. I have tried to come up with
a nicer pattern to watch the enabled/disabled checkboxes, but without
external dependencies like Facebook’s KVOController I didn’t come up
with anything better than plain old KVO.
</pre>
</div>
</content>
</entry>
<entry>
<title>Simplified and updated the demo project.</title>
<updated>2015-01-08T13:16:26+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2015-01-08T13:16:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=fc43b570c7ea4802c648670b39586425ce330cec'/>
<id>fc43b570c7ea4802c648670b39586425ce330cec</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Added a simplified binding API for MASShortcutView.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:55:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=46aa323115c2ebe7128aba39c0296634d232bbf6'/>
<id>46aa323115c2ebe7128aba39c0296634d232bbf6</id>
<content type='text'>
This returns the associatedUserDefaultsKey property used in previous code
versions, only the implementation uses less magic.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This returns the associatedUserDefaultsKey property used in previous code
versions, only the implementation uses less magic.
</pre>
</div>
</content>
</entry>
<entry>
<title>Redesigned demo app layout &amp; feedback.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:23:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=5f5f6cb9d086853065b2546e72d71a38230c6b59'/>
<id>5f5f6cb9d086853065b2546e72d71a38230c6b59</id>
<content type='text'>
I have replaced the modal alert with a beep, it’s faster to test
without having to close the alert.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I have replaced the modal alert with a beep, it’s faster to test
without having to close the alert.
</pre>
</div>
</content>
</entry>
<entry>
<title>Added a shared binder instance singleton.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T10:12:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=118abba104a1eeabc5c449ac86e25a6d87f1954c'/>
<id>118abba104a1eeabc5c449ac86e25a6d87f1954c</id>
<content type='text'>
This adds a really simple API to set up some bindings without having
to keep a binder instance around by hand. If somebody wants to, it’s
not a problem to allocate a separate instance and have precise control
over its lifetime.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This adds a really simple API to set up some bindings without having
to keep a binder instance around by hand. If somebody wants to, it’s
not a problem to allocate a separate instance and have precise control
over its lifetime.
</pre>
</div>
</content>
</entry>
<entry>
<title>Turned MASShortcutMonitor into a singleton.</title>
<updated>2015-01-07T14:42:21+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T08:10:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=be9358bf32dc402f3bc77c6cc20957047ab363af'/>
<id>be9358bf32dc402f3bc77c6cc20957047ab363af</id>
<content type='text'>
There can only be one Carbon event handler, so it doesn’t make sense
to create multiple instances of the shortcut monitor.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There can only be one Carbon event handler, so it doesn’t make sense
to create multiple instances of the shortcut monitor.
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactored the shortcut dispatcher and bindings to user defaults.</title>
<updated>2015-01-07T14:39:39+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-06T16:05:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=444d1bccb9770738fa4ea40383c23f44a55089c2'/>
<id>444d1bccb9770738fa4ea40383c23f44a55089c2</id>
<content type='text'>
This is a big change that was hard to split into smaller commits. There’s now
a new class to bind shortcuts to actions, a new class to bind user defaults’
keys to actions, and a new way to associate user defaults with the recorder
control (MASShortcutView). I have also updated the demo app to go with the
changes.

The new class to associate shortcuts with actions is called MASShortcutMonitor.
It wraps the Carbon hotkey magic and offers a simple interface to add a
shortcut along with a block that should be run when the shortcut is pressed.
It’s the lowest-level interface.

Since the usual requirement is to store the shortcuts into user defaults,
there’s also a higher-level interface offered by the MASShortcutBinder class.
That takes a defaults key and associates it with a block. When the shortcut
stored under the defaults key changes, the binder automatically switches to the
new shortcut. The class is a wrapper built atop of the previous one, the
MASShortcutMonitor – it simply adds, updates and removes shortcuts as the
user defaults change.

I have removed the special user defaults integration code from the recorder
control (MASShortcutView) and replaced it with a small Cocoa Bindings shim.
This means that in order to keep the recorder control in sync with the defaults
you just have to call the usual bind:toObject:withKeyPath:options: method,
like this:

[_shortcutView bind:MASShortcutBinding
    toObject:[NSUserDefaultsController sharedUserDefaultsController]
    withKeyPath[@"values.ExampleDefaultsKey"
    options:@{NSValueTransformerNameBindingOption:NSKeyedUnarchiveFromDataTransformerName}];

That’s more verbose than the previous solution, but it’s much cleaner and can
be swept under a convenience call if needed. I might also add a dictionaryValue
property later that would make it possible to bind the value to user defaults
directly, without a transformer, and would enable backward compatibility with
Shortcut Recorder.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a big change that was hard to split into smaller commits. There’s now
a new class to bind shortcuts to actions, a new class to bind user defaults’
keys to actions, and a new way to associate user defaults with the recorder
control (MASShortcutView). I have also updated the demo app to go with the
changes.

The new class to associate shortcuts with actions is called MASShortcutMonitor.
It wraps the Carbon hotkey magic and offers a simple interface to add a
shortcut along with a block that should be run when the shortcut is pressed.
It’s the lowest-level interface.

Since the usual requirement is to store the shortcuts into user defaults,
there’s also a higher-level interface offered by the MASShortcutBinder class.
That takes a defaults key and associates it with a block. When the shortcut
stored under the defaults key changes, the binder automatically switches to the
new shortcut. The class is a wrapper built atop of the previous one, the
MASShortcutMonitor – it simply adds, updates and removes shortcuts as the
user defaults change.

I have removed the special user defaults integration code from the recorder
control (MASShortcutView) and replaced it with a small Cocoa Bindings shim.
This means that in order to keep the recorder control in sync with the defaults
you just have to call the usual bind:toObject:withKeyPath:options: method,
like this:

[_shortcutView bind:MASShortcutBinding
    toObject:[NSUserDefaultsController sharedUserDefaultsController]
    withKeyPath[@"values.ExampleDefaultsKey"
    options:@{NSValueTransformerNameBindingOption:NSKeyedUnarchiveFromDataTransformerName}];

That’s more verbose than the previous solution, but it’s much cleaner and can
be swept under a convenience call if needed. I might also add a dictionaryValue
property later that would make it possible to bind the value to user defaults
directly, without a transformer, and would enable backward compatibility with
Shortcut Recorder.
</pre>
</div>
</content>
</entry>
<entry>
<title>Created an umbrella header.</title>
<updated>2015-01-07T14:05:11+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T11:34:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=0b08de641530f6537e4a3b7dbf26601fc927e1ad'/>
<id>0b08de641530f6537e4a3b7dbf26601fc927e1ad</id>
<content type='text'>
Now you can just `#import &lt;MASShortcut/Shortcut.h&gt;`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now you can just `#import &lt;MASShortcut/Shortcut.h&gt;`.
</pre>
</div>
</content>
</entry>
</feed>
