<feed xmlns='http://www.w3.org/2005/Atom'>
<title>MASShortcut/MASShortcut.xcodeproj/project.pbxproj, branch 2.0.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>Treat build warnings as errors.</title>
<updated>2015-01-07T15:26:49+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-12T13:36:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=29cf3be3ad6998b3ab63ef82d9a53fb5a1b5950d'/>
<id>29cf3be3ad6998b3ab63ef82d9a53fb5a1b5950d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Updated header settings.</title>
<updated>2015-01-07T14:42:22+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T11:32:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=80808eb6d7590dc2f4ed0bd3f5873c7472010a7b'/>
<id>80808eb6d7590dc2f4ed0bd3f5873c7472010a7b</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>Added a custom transformer to store shortcuts as dictionaries.</title>
<updated>2015-01-07T14:42:21+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-07T08:47:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=942bbe849ed245d8b2e9afcb0a61d66b23beaef9'/>
<id>942bbe849ed245d8b2e9afcb0a61d66b23beaef9</id>
<content type='text'>
The MASDictionaryTransformer class is used to save shortcuts to
user defaults (and load them back) using a simple dictionary. The
value stored in the user defaults looks like this:

$ defaults read com.shpakovski.mac.Demo
{
    MASDemoShortcut =     {
        keyCode = 15;
        modifierFlags = 1048576;
    };
    …
}

This storage format has got the distinct advantage of being compatible
with the format used by Shortcut Recorder. In order to use it, you
have to set proper binding options for MASShortcutBinder and the
recorder control (MASShortcutView).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The MASDictionaryTransformer class is used to save shortcuts to
user defaults (and load them back) using a simple dictionary. The
value stored in the user defaults looks like this:

$ defaults read com.shpakovski.mac.Demo
{
    MASDemoShortcut =     {
        keyCode = 15;
        modifierFlags = 1048576;
    };
    …
}

This storage format has got the distinct advantage of being compatible
with the format used by Shortcut Recorder. In order to use it, you
have to set proper binding options for MASShortcutBinder and the
recorder control (MASShortcutView).
</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>Organized classes into Xcode folders.</title>
<updated>2015-01-07T14:27:51+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T15:11:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=90cf1f856c9d3714df6c173e770e94e50621ee82'/>
<id>90cf1f856c9d3714df6c173e770e94e50621ee82</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduced a standalone MASShortcutValidator class to validate shortcuts.</title>
<updated>2015-01-07T14:27:50+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T14:24:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=6383b054190d8bc4b7e059718cded0119d25d98c'/>
<id>6383b054190d8bc4b7e059718cded0119d25d98c</id>
<content type='text'>
It’s a natural simplification of the MASShortcut class. All MASShortcutView
objects use a shared validator by default, but can be reconfigured to use a
different validator if needed through the shortcutValidator property.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It’s a natural simplification of the MASShortcut class. All MASShortcutView
objects use a shared validator by default, but can be reconfigured to use a
different validator if needed through the shortcutValidator property.
</pre>
</div>
</content>
</entry>
<entry>
<title>Converted keycode macros to plain functions.</title>
<updated>2015-01-07T14:05:12+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T13:34:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=1c801726d35e56d3bbf4a33279213bc60935c244'/>
<id>1c801726d35e56d3bbf4a33279213bc60935c244</id>
<content type='text'>
Plain functions are less prone to bugs, the compiler understands
them better and can offer better error messages, and plain functions
can be refactored more easily.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Plain functions are less prone to bugs, the compiler understands
them better and can offer better error messages, and plain functions
can be refactored more easily.
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduced a separate header file for keycode definitions.</title>
<updated>2015-01-07T14:05:12+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T13:16:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=88392d1a6963cca5009b9b0c20b054ad9e911b6c'/>
<id>88392d1a6963cca5009b9b0c20b054ad9e911b6c</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 unit testing target.</title>
<updated>2015-01-07T14:05:11+00:00</updated>
<author>
<name>Tomáš Znamenáček</name>
</author>
<published>2014-08-05T13:10:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/fork/MASShortcut/commit/?id=42daeb6f1298c800b3d42a6b746e2e6ef6b0670e'/>
<id>42daeb6f1298c800b3d42a6b746e2e6ef6b0670e</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
