<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>MacOS · @jnjosh’s internet weblog</title>
    <link>https://jnjosh.com/categories/macos/</link>
    <description>Internet weblog of Software (Mac, iOS, Web) Developer, Josh Johnson.</description>
    <language>en</language>
    <lastBuildDate>Sun, 19 Apr 2015 01:39:32 -0500</lastBuildDate>
    <atom:link href="https://jnjosh.com/categories/macos/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>May the Force Touch be with You</title>
      <link>https://jnjosh.com/workshop/posts/may-the-forcetouch-be-with-you/</link>
      <pubDate>Sun, 19 Apr 2015 01:39:32 -0500</pubDate><guid isPermaLink="false">https://jnjosh.com/workshop/posts/may-the-forcetouch-be-with-you/</guid>
      <description>&lt;p&gt;Last week I bought a newly updated 13&amp;quot; MacBook Pro with an amazing new Force&#xA;Touch trackpad. I love it and it&amp;rsquo;s hard to go back to the older trackpad on my&#xA;MacBook Pro at work. I&amp;rsquo;ve already caught myself trying to press on the top&#xA;corners of the older version and have tried to press harder a few times. At this&#xA;week&amp;rsquo;s &lt;a href=&#34;http://www.meetup.com/nscoderrtp&#34;&gt;NSCoder Night&lt;/a&gt; I decided to play&#xA;around with the new Force Touch API to see how it works.&lt;/p&gt;&#xA;&lt;!-- more --&gt;&#xA;&lt;p&gt;Apple&amp;rsquo;s &lt;a href=&#34;https://developer.apple.com/osx/force-touch/&#34;&gt;site describing the APIs&lt;/a&gt;&#xA;don&amp;rsquo;t really go into much detail about how to use them. However it&amp;rsquo;s pretty&#xA;straightforward save a few oddities. Maybe they would be more expected had I&#xA;been spending more time with AppKit.&lt;/p&gt;&#xA;&lt;p&gt;I experimented with three different methods for detecting pressure with the new&#xA;APIs. Responding to events on the responder chain and two different types of&#xA;buttons added in 10.10.3. There are also new methods using NSGestureRecognizer&#xA;and with Drag and Drop. The gesture recognizer seemed pretty easy and close to&#xA;the events I was testing. I haven&amp;rsquo;t figured out the drag and drop capabilities&#xA;yet.&lt;/p&gt;&#xA;&lt;h3 id=&#34;pressure-in-the-responder-chain&#34;&gt;Pressure in the Responder Chain&lt;/h3&gt;&#xA;&lt;p&gt;The easiest method seems to be to simply respond to the correct method&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;- (void)pressureChangeWithEvent:(NSEvent *)event;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;in your application. Inspecting the &lt;code&gt;NSEventTypePressure&lt;/code&gt; type event&amp;rsquo;s&#xA;&lt;code&gt;pressure&lt;/code&gt;, &lt;code&gt;stage&lt;/code&gt;, and &lt;code&gt;stageTransition&lt;/code&gt; allow you to determine the pressure&#xA;across three stages (0, 1, 2). Looking at the &lt;code&gt;pressure&lt;/code&gt; property to see the&#xA;amount of pressure between 0.0 and 1.0.  The &lt;code&gt;stage&lt;/code&gt; property is aligned with&#xA;the clicks you feel when pressing on the trackpad. 0 is the stage before the&#xA;first click. 1 is the stage between the first and second click and, of course, 2&#xA;is the stage after the second click you feel. The &lt;code&gt;stageTransition&lt;/code&gt; property&#xA;describes the progress towards the next stage. When positive it is approaching&#xA;the next stage, when negative it is approaching the previous stage.&lt;/p&gt;&#xA;&lt;h3 id=&#34;accelerator-buttons&#34;&gt;Accelerator Buttons&lt;/h3&gt;&#xA;&lt;p&gt;Another way to detect pressure is using a normal NSButton with the new type&#xA;&lt;em&gt;Accelerator&lt;/em&gt; applied. These buttons will simply invoke their action repeatedly&#xA;as pressure increases. For example, if you send the action from a button to&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;- (void)buttonPressed:(id)sender;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;inspecting the &lt;code&gt;doubleValue&lt;/code&gt; of the sender will tell you the pressure between&#xA;1.0 and 1.99. The action is called repeatedly until it reaches the end. It does&#xA;not have any further clicks beyond the first click you feel. Here I bind the&#xA;alpha value of a label to this value normalized to 0.0 and 1.0.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;    &lt;img src=&#34;https://jnjosh.com/assets/images/forcetouch/forcetouch2.gif&#34; alt=&#34;Accelerator Button&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&#xA;  &lt;/figure&gt;&lt;h3 id=&#34;multi-level-accelerator-buttons&#34;&gt;Multi-level Accelerator Buttons&lt;/h3&gt;&#xA;&lt;p&gt;The multi-level button is similar to the regular accelerator button above except&#xA;you can specify how many levels, up to 5, the user feels when pressing the&#xA;trackpad. With this type you are notified of the level the user has reached, not&#xA;the actual pressure value. Inspecting &lt;code&gt;doubleValue&lt;/code&gt; on this type of button&#xA;responds with 1.0 to &lt;em&gt;n&lt;/em&gt; where &lt;em&gt;n&lt;/em&gt; is the value you set for the button&amp;rsquo;s&#xA;&lt;code&gt;maxAcceleratorLevel&lt;/code&gt; property. The really fun thing here is you feel an extra&#xA;click in the track pad at each level here. This is likely how Apple implemented&#xA;the fast forward feature in Quicktime Player. Pressing harder speeds up the fast&#xA;forward feature across five levels. Here I bind a button to a progress indicator&#xA;with a max of 5.&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;    &lt;img src=&#34;https://jnjosh.com/assets/images/forcetouch/forcetouch.gif&#34; alt=&#34;Multi-level Accelerator Button&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&#xA;  &lt;/figure&gt;&lt;p&gt;There are some other ways to take advantage of this new trackpad. Xcode will&#xA;actually produce extra clicks when you are dragging UI elements around in&#xA;Interface Builder. When the item you are dragging reaches a recommended&#xA;constraint, you feel it. I haven&amp;rsquo;t quite figured out how to do this yet.&lt;/p&gt;&#xA;&lt;p&gt;There is also this new concept for &lt;code&gt;springLoaded&lt;/code&gt; that allows you to do specific&#xA;pressure-sensitive behavior when dragging over a button.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s been a long time since I worked with AppKit, but I&amp;rsquo;ve been really wanting&#xA;to get back into it and do something cool. These new gestures have me extremely&#xA;excited about what I could build to support it.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>I&#39;m still working without a clock</title>
      <link>https://jnjosh.com/workshop/posts/clockless-environment/</link>
      <pubDate>Wed, 08 Aug 2012 22:23:32 -0500</pubDate><guid isPermaLink="false">https://jnjosh.com/workshop/posts/clockless-environment/</guid>
      <description>&lt;p&gt;Last year I &lt;a href=&#34;http://log.jsh.in/posts/back-to-blogging-and-working-without-a-clock/&#34;&gt;wrote a post about how I was going to work without a clock&lt;/a&gt;. This was completely inspired by &lt;a href=&#34;http://blog.zachwaugh.com/post/6290996753/working-without-a-clock&#34;&gt;Cocoa developer Zach Waugh who wrote about the same topic&lt;/a&gt;. As part of this post, he also talked about his small &lt;a href=&#34;http://zachwaugh.com/clock&#34;&gt;Mac app called Clock.app&lt;/a&gt; which is an open source project. Since you sometimes need to know the time, the app provides a quick way to get the time using Alfred or Quicksilver to launch this simple app. For example, you can type &lt;code&gt;cmd+space cl [enter]&lt;/code&gt; and I the time.&lt;/p&gt;&#xA;&lt;p&gt;I actually stopped doing this for awhile. I&amp;rsquo;m not sure why. I love working this way and recently went back to the clock-free environment. It works so well for me that when I&amp;rsquo;m working on an app on my phone and see the time, I get a little upset.&lt;/p&gt;&#xA;&lt;!-- more --&gt;&#xA;&lt;p&gt;One small problem I had was I often used the clock to identify the date. Since it was open source, I forked it and updated Clock.app to have the date.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;If you&amp;rsquo;d like to try it out, you can &lt;a href=&#34;https://github.com/jnjosh/Clock.app/downloads&#34;&gt;download the built version from Github&lt;/a&gt; or &lt;a href=&#34;https://github.com/jnjosh/Clock.app&#34;&gt;checkout the source&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;figure&gt;&#xA;    &lt;img&#xA;    src=&#34;https://jnjosh.com/assets/images/clock.app_hu_243e8f0c93eec9f0.webp&#34;&#xA;    alt=&#34;Clock.app customized&#34;&#xA;    width=&#34;600&#34;&#xA;    height=&#34;375&#34;&#xA;    loading=&#34;lazy&#34;&#xA;    decoding=&#34;async&#34;&gt;&#xA;  &lt;/figure&gt;</description>
    </item>
    <item>
      <title>Global hotkeys in Cocoa on Snow Leopard</title>
      <link>https://jnjosh.com/workshop/posts/global-hotkeys-in-cocoa-on-snow-leopard/</link>
      <pubDate>Fri, 23 Jul 2010 01:44:32 -0500</pubDate><guid isPermaLink="false">https://jnjosh.com/workshop/posts/global-hotkeys-in-cocoa-on-snow-leopard/</guid>
      <description>&lt;p&gt;I am working on a small app at the office for all our mac users to help locate files on the network (more on this later), I decided to go with a spotlight style NSStatusItem based app. I’ve been really inspired by these apps lately (when done right). Mostly thanks to Notify.&lt;/p&gt;&#xA;&lt;p&gt;To make this more handy I decided to include a global hotkey. For Leopard and earlier, one problem is you have to use the old Carbon-based events. Most likely due to my Carbon-naivety, I had troubles with this.&lt;/p&gt;&#xA;&lt;p&gt;Luckily, I found that starting with OS X Snow Leopard, Apple added a new method to NSEvent:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-Objective-C&#34; data-lang=&#34;Objective-C&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;addGlobalMonitorForEventsMatchingMask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;maskhandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;</description>
    </item>
  </channel>
</rss>
