<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Virtual Sanity</title>
 <link href="https://www.virtualsanity.com/feed/" rel="self"/>
 <link href="https://www.virtualsanity.com/"/>
 <updated>2026-07-18T15:30:11-04:00</updated>
 <id>https://www.virtualsanity.com/</id>

 
 <entry>
   <title>NSTrackingSeparatorToolbarItem causes problems when putting a window in full screen on Golden Gate (macOS 27)</title>
   <link href="https://www.virtualsanity.com/202607/nstrackingseparatortoolbaritem-causes-problems-when-putting-a-window-in-full-screen-on-golden-gate-macos-27/"/>
   <updated>2026-07-18T15:30:41-04:00</updated>
   <id>https://www.virtualsanity.com/202607/nstrackingseparatortoolbaritem-causes-problems-when-putting-a-window-in-full-screen-on-golden-gate-macos-27</id>
   <author>
      <name>John Brayton</name>
      <uri>https://www.virtualsanity.com/</uri>
   </author>
   <content type="html">&lt;p&gt;NSTrackingSeparatorToolbarItem adds a white band over the top of the leading split view panes when in full screen mode on macOS 27. That white band appears to have the height of the toolbar.&lt;/p&gt;

&lt;p&gt;I have a &lt;a href=&quot;/media/2027-07-18-tracking-separator/FullScreenIssue.zip&quot;&gt;sample project&lt;/a&gt; that demonstrates the issue. To reproduce it:&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;Download and open the &lt;a href=&quot;/media/2027-07-18-tracking-separator/FullScreenIssue.zip&quot;&gt;sample project&lt;/a&gt;. Observe that the main window contains a simple three pane split view. Also observe that the window it creates has a toolbar with an NSTrackingSeparatorToolbarItem. The NSTrackingSeparatorToolbarItem tracks the divider between the second pane and the third pane.

&lt;li&gt;Run the attached sample project on a Mac running Golden Gate (macOS 27).

&lt;li&gt;Click the green traffic light button in the upper left corner of the window.

&lt;/ol&gt;

&lt;p&gt;&lt;b&gt;Expected results:&lt;/b&gt; I expected a smooth animation. I expected all three panes to be completely visible when in full screen.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Actual results:&lt;/b&gt; The animation looks janky near the top of the screen. When the animation is complete, a white band covers the top of the first two panes.&lt;/p&gt;

&lt;p&gt;The symptoms change if you repeat entering and exiting full screen mode during the same session.&lt;/p&gt;


&lt;p&gt;This is a video of my following these steps:&lt;/p&gt;

&lt;p&gt;&lt;video src=&quot;/media/2027-07-18-tracking-separator/full-screen-issue.mp4&quot; poster=&quot;/media/2027-07-18-tracking-separator/poster.png&quot; width=&quot;835&quot; height=&quot;540&quot; controls&gt;&lt;/p&gt;

&lt;p&gt;I filed this as &lt;b&gt;FB23827858&lt;/b&gt; and am hoping it gets attention.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Bug Involving Keyboard Shortcuts for Menu Items That Have No Modifier Keys on macOS 26.5</title>
   <link href="https://www.virtualsanity.com/202605/bug-involving-keyboard-shortcuts-for-menu-items-that-have-no-modifier-keys-on-macos-265/"/>
   <updated>2026-05-12T13:28:22-04:00</updated>
   <id>https://www.virtualsanity.com/202605/bug-involving-keyboard-shortcuts-for-menu-items-that-have-no-modifier-keys-on-macos-265</id>
   <author>
      <name>John Brayton</name>
      <uri>https://www.virtualsanity.com/</uri>
   </author>
   <content type="html">&lt;p&gt;I am seeing a bug that affects keyboard shortcuts that have no modifiers and are attached to menu items. For example, the bug would affect the keyboard shortcut J on a menu item, but not the keyboard shortcut &amp;#8984;J.&lt;/p&gt;

&lt;p&gt;I believe this bug was introduced in macOS 26.5. It is also present in the first developer beta of macOS 27.&lt;/p&gt;

&lt;p&gt;I filed this as &lt;b&gt;FB22762541&lt;/b&gt;, and am writing this to let others know about it.&lt;/p&gt;

&lt;p&gt;I do not have a macOS 26.4 environment to test against, but based on customer input I believe this is a new bug in macOS 26.5.&lt;/p&gt;

&lt;h2&gt;The Bug&lt;/h2&gt;

&lt;p&gt;When a menu item is invoked with a keyboard shortcut that has no modifiers and its validateMenuItem(_:) method returns false, the system beeps and refuses to perform the operation. This is expected.&lt;/p&gt; 

&lt;p&gt;But then even after validateMenuItem(_:) is returning true again, the app will continue refusing to perform that keyboard shortcut until the app is quit and relaunched. It will also do the same with all other keyboard shortcuts that have no modifiers and are attached to menu items.&lt;/p&gt;

&lt;p&gt;In addition, if a key is pressed for which there first responder to handle it, the system gets into the same state. The next valid key command without a modifier might get processed, but ones after that will not.&lt;/p&gt;

&lt;h2&gt;Sample App&lt;/h2&gt;

&lt;p&gt;To demonstrate this, I wrote a &lt;a href=&quot;/postimages/unmodified-keyboard-shortcuts/KeyboardShortcuts.zip&quot;&gt;sample project&lt;/a&gt;.

&lt;p&gt;&lt;img src=&quot;/postimages/unmodified-keyboard-shortcuts/app.png&quot; alt=&quot;&quot; width=&quot;492&quot; height=&quot;689&quot;&gt;&lt;/p&gt;

&lt;p&gt;Its app shows a counter. The File menu has these menu items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increment Counter (keyboard shortcut: &amp;#8984;J)
&lt;li&gt;Increment Counter (keyboard shortcut: J)
&lt;li&gt;Decrement Counter (keyboard shortcut: &amp;#8984;K)
&lt;li&gt;Decrement Counter (keyboard shortcut: K)
&lt;/ul&gt;

&lt;p&gt;The app also has an Enable Menu Items checkbox. When checked, validateMenuItem(_:) returns true for the four menu items above. When unchecked, it returns false.&lt;/p&gt;

&lt;p&gt;To see the issue:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the sample app.
&lt;li&gt;Take note of the Increment/Decrement Counter menu items in the File menu.
&lt;li&gt;Increment the counter with the &amp;#8984;J and J keyboard shortcuts. Decrement the counter with the &amp;#8984;K and K keyboard shortcuts. Observe that all four keyboard shortcuts work as one would expect.
&lt;li&gt;Uncheck the Enable Menu Items checkbox.
&lt;li&gt;Open the File menu, and observe that the four menu items are disabled.
&lt;li&gt;Press the J key to increment the counter. Observe that you get a system beep and that nothing happens,&amp;nbsp;as one would expect.
&lt;li&gt;Check the Enable Menu Items checkbox.
&lt;li&gt;Open the File menu, and observe that the four menu items are enabled.
&lt;li&gt;Try to increment the counter with the &amp;#8984;J and J keyboard shortcuts, and to decrement the counter with the &amp;#8984;K and K keyboard shortcuts. 
&lt;/ol&gt;

&lt;p&gt;&lt;b&gt;Expected result:&lt;/b&gt; One would expect that all four keyboard shortcuts (&amp;#8984;J, J, &amp;#8984;K, and K) work again.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Actual result:&lt;/b&gt; &amp;#8984;J and &amp;#8984;K work. When you press J or K, you get a system beep and nothing happens, as if validateMenuItem(_:) was still returning false.&lt;/p&gt;

&lt;p&gt;Another way to see the issue:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the sample app.
&lt;li&gt;Take note of the Increment/Decrement Counter menu items in the File menu.
&lt;li&gt;Increment the counter with the &amp;#8984;J and J keyboard shortcuts. Decrement the counter with the &amp;#8984;K and K keyboard shortcuts. Observe that all four keyboard shortcuts work as one would expect.
&lt;li&gt;Press the L key. The system beeps because nothing should handle that key press.
&lt;li&gt;Press the J or K key a few times.
&lt;/ol&gt;

&lt;p&gt;&lt;b&gt;Expected result:&lt;/b&gt; One would expect the J key presses to increment the counter, and the K presses to decrement the counter.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Actual result:&lt;/b&gt; The very first J or K key press after pressing L might work as expected. After that, pressing either J and K will consistently result in nothing happening, except for the system beeping.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;b&gt;Updated 2026-05-12 at 5:30 PM Boston time:&lt;/b&gt; After learning more about the symptoms, I added that pressing a key (such as L) without a corresponding keyboard shortcut also triggers the issue.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Updated 2026-06-11:&lt;/b&gt; Added that this issue also exists in macOS 27.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Murder</title>
   <link href="https://www.virtualsanity.com/202601/murder/"/>
   <updated>2026-01-12T10:13:51-05:00</updated>
   <id>https://www.virtualsanity.com/202601/murder</id>
   <author>
      <name>John Brayton</name>
      <uri>https://www.virtualsanity.com/</uri>
   </author>
   <content type="html">&lt;p&gt;In July, a man died less than two miles from my home while being pinned to the ground by police officers. The police had been called because the man was acting erratically and having some sort of health event. I was deeply concerned, and I wanted a thorough investigation of the incident. If the police officers used excessive force or acted with ill intent, I want them to be held accountable.&lt;/p&gt;

&lt;p&gt;There were a number of protests in the area shortly after this incident. I decided not to attend them. I anticipated that some attendees of those protests would accuse the police officers of murder. Since the deceased seemed to be having a health event before police were called, I did not know whether the police were to blame. Therefore I did not want to participate in a protest that might make such accusations.&lt;/p&gt;

&lt;p&gt;I was also confident that there would be a thorough investigation. I hope that this confidence was well placed.&lt;/p&gt;

&lt;p&gt;The death of Renee Nicole Good is a very different situation. The administration has made it clear that they are avoiding investigation. The FBI is trying to block state and local officials from investigating. I hope that state and local officials are able to investigate and prosecute despite this, but I am skeptical.&lt;/p&gt;

&lt;p&gt;JD Vance &lt;a href=&quot;https://x.com/JDVance/status/2009688858036986310&quot;&gt;suggests&lt;/a&gt; that we &lt;a href=&quot;https://x.com/AlphaNews/status/2009679932289626385&quot;&gt;watch video of the incident&lt;/a&gt;, so I did. I also watched several breakdowns of the video footage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ILyy5zT5pQ0&quot;&gt;Jen Psaki at MS NOW&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;https://www.thebulwark.com/p/breaking-new-footage-in-minneapolis&quot;&gt;Tim Miller at The Bulwark&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=F_7tjt_CdVg&quot;&gt;Jon Favreau and Tommy Vietor at Pod Save America&lt;/a&gt;
&lt;/ul&gt;

&lt;p&gt;Based on all that video footage, it looks like the car was moving slowly and away from the ICE thug. It also like looks the ICE thug walks away without a scratch from this slow-moving vehicle. It looks like he was in about as much danger as he would be walking through any grocery store parking lot. Based on the words uttered just after the shooting, it sounds like he shot her out of unwarranted anger &amp;mdash; not out of self-defense.&lt;/p&gt;

&lt;p&gt;This was a murder.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Moving from Linode to Hetzner</title>
   <link href="https://www.virtualsanity.com/202512/moving-from-linode-to-hetzner/"/>
   <updated>2025-12-08T09:53:42-05:00</updated>
   <id>https://www.virtualsanity.com/202512/moving-from-linode-to-hetzner</id>
   <author>
      <name>John Brayton</name>
      <uri>https://www.virtualsanity.com/</uri>
   </author>
   <content type="html">&lt;p&gt;Some of &lt;a href=&quot;https://www.goldenhillsoftware.com/unread/&quot;&gt;Unread&lt;/a&gt;&amp;rsquo;s functionality requires server infrastructure. I run servers to support both Unread Cloud and Unread&amp;rsquo;s webpage text functionality.&lt;/p&gt;

&lt;p&gt;Linode was my hosting provider of choice for a long time, but I recently moved these systems to Hetzner. I wanted to write a bit about how Linode and Hetzner compare.&lt;/p&gt;

&lt;h3&gt;Price and Performance&lt;/h3&gt;

&lt;p&gt;Hetzner is far more cost-effective for me. This is the pricing in US dollars for some of Linode&amp;rsquo;s low-end instances:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Nanode 1GB &amp;mdash; $5.00/month&lt;/b&gt;&lt;br&gt;
1GB RAM. 1 CPU.&lt;br&gt;
I was unable to get Geekbench scores for this because Geekbench requires 2GB of memory.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Linode 2GB &amp;mdash; $12.00/month&lt;/b&gt;&lt;br&gt;
2GB RAM. 1 CPU.&lt;br&gt;
Geekbench scores: 1323 single-core, 1317 multi-core.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Linode 4GB &amp;mdash; $24.00/month&lt;/b&gt;&lt;br&gt;
4GB RAM. 2 CPUs.&lt;br&gt;
Geekbench scores: 1095 single-core, 2036 multi-core.&lt;/p&gt;

&lt;p&gt;This is the pricing in US dollars for some of Hetzner&amp;rsquo;s low-end instances in Nuremberg, Falkenstein, and Helsinki:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;cx23 &amp;mdash; &lt;strike&gt;$3.49/month&lt;/strike&gt; $4.99/month effective April 1, 2026&lt;/b&gt;&lt;br&gt;
4GB RAM. 2 VCPUs.&lt;br&gt;
Geekbench scores: 769 single-core, 1377 multi-core.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;cpx22 &amp;mdash; &lt;strike&gt;$6.99/month&lt;/strike&gt; $9.49/month effective April 1, 2026&lt;/b&gt;&lt;br&gt;
4GB RAM. 2 VCPUs.&lt;br&gt;
Geekbench scores: 1902 single-core, 3484 multi-core.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;These systems all have shared CPUs. Geekbench scores are likely less meaningful for shared CPU instances than they would be for dedicated CPU instances.&lt;/i&gt;&lt;/p&gt;

&lt;h3&gt;IPv4 Addresses&lt;/h3&gt;

&lt;p&gt;Each Hetzner instance includes an IPv6 address. Hetzner charges an additional $0.60/month for an instance to have a public IPv4 address. Linode includes an IPv4 address and an IPv6 address with each instance. This additional cost needs to be taken into account for a Hetzner instance that needs an IPv4 address.&lt;/p&gt;

&lt;p&gt;An instance needs a public IPv4 address if it accepts incoming requests from arbitrary clients, or if it makes outgoing requests to arbitrary servers. I was able to skip IPv4 addresses on instances that just run backend services such as Redis and PostgreSQL.&lt;/p&gt;

&lt;p&gt;I find instances without IPv4 addresses to be inconvenient in unexpected ways. For example, accessing github.com and accessing Wasabi&amp;rsquo;s S3-compatible storage both require IPv4. While I am able to connect to IPv6 IP addresses from my home/office network, I am sometimes unable to do so from public Wi-Fi networks.&lt;/p&gt;

&lt;h3&gt;Server Limits&lt;/h3&gt;

&lt;p&gt;In a Linode account, I was always able to create servers that I wanted.&lt;/p&gt;

&lt;p&gt;Hetzner limits customers to a specific number of servers. A customer can request increases. I was initially limited to 5 servers. That would have been insufficient to move most of my cloud infrastructure to Hetzner. After requesting an increase, I now have a limit of 30 servers.&lt;/p&gt;

&lt;p&gt;I have occasionally been unable to create a server of a specific type in a specific data center. I have worked around that by choosing a different data center.&lt;/p&gt;

&lt;h3&gt;Accessing Websites&lt;/h3&gt;

&lt;p&gt;Much of Unread&amp;rsquo;s server work consists of accessing feeds and webpages from websites. Hetzner&amp;rsquo;s instances at the pricing above are available in Nuremberg, Falkenstein, and Helsinki &amp;mdash; all of which are in the European Union. Some websites outside the EU that do not have international audiences block access to clients in the EU, presumably because those websites do not want to comply with EU privacy laws. Since Unread operates on behalf of customers inside and outside of the EU, it needs to be able to access websites and webpages from such websites.&lt;/p&gt;

&lt;p&gt;Hetzner does have data centers outside the European Union: specifically in Singapore; in Hillsboro, Oregon; and in Ashburn, Virginia. However, servers available in those data centers are more limited and more expensive.&lt;/p&gt;

&lt;p&gt;My solution for Unread&amp;rsquo;s servers was to host a proxy in a United States data center. When Unread&amp;rsquo;s feed retrieval system or webpage retrieval system get a forbidden response, they retry the request using the proxy server hosted in the United States.&lt;/p&gt;

&lt;h3&gt;Private Networks&lt;/h3&gt;

&lt;p&gt;Hetzner has the concept of a private network. A customer can create a 10.* network for a specific stack of servers. I found communicating across these private networks unreliable, and slower than communicating across the public IP addresses. &lt;a href=&quot;https://www.reddit.com/r/hetzner/comments/1mdxa44/do_you_use_private_networks_of_hetzner/&quot;&gt;Others&lt;/a&gt; seem to have similar experiences.&lt;/p&gt;

&lt;p&gt;On Linode I used the default 192.168.* private network. These networks were not completely private. They were accessible to other Linode customers in the same data center. Linode also has an ability to create &lt;a href=&quot;https://techdocs.akamai.com/cloud-computing/docs/create-a-private-network-with-vlans-using-the-api&quot;&gt;VLANs&lt;/a&gt; but I never explored it.&lt;/p&gt;

&lt;p&gt;In the end I ended up making my Hetzner instances communicate exclusively through public IP addresses. That private communication requires authentication and is encrypted. I would have preferred this communication to happen over a private network, but that was slower and less reliable.&lt;/p&gt;

&lt;h3&gt;Referral Links&lt;/h3&gt;

&lt;p&gt;I am happy with my decision to move to Hetzner. My servers are more powerful and less expensive. But Linode does have advantages over Hetzner.&lt;/p&gt;

&lt;p&gt;Referral links: &lt;a href=&quot;https://hetzner.cloud/?ref=CO5YycliXqet&quot;&gt;Hetzner&lt;/a&gt;, &lt;a href=&quot;https://www.linode.com/lp/refer/?r=965210170e7f76c093d1c10e7f863b5ef839b325&quot;&gt;Linode&lt;/a&gt;.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;b&gt;Update February 26, 2026:&lt;/b&gt; Hetzner &lt;a href=&quot;https://www.hetzner.com/pressroom/statement-price-adjustment/&quot;&gt;recently announced&lt;/a&gt; a price increase effective April 1, 2026. I updated this post to reflect that price increase. I have not found any statement that the IPv4 prices are changing, so I assume that they are not.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Jimmy Kimmel Cancelled</title>
   <link href="https://www.virtualsanity.com/202509/jimmy-kimmel-cancelled/"/>
   <updated>2025-09-17T20:27:54-04:00</updated>
   <id>https://www.virtualsanity.com/202509/jimmy-kimmel-cancelled</id>
   <author>
      <name>John Brayton</name>
      <uri>https://www.virtualsanity.com/</uri>
   </author>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://daringfireball.net/2025/07/curse_not_the_king_cbs_colbert_trump&quot;&gt;John Gruber at Daring Fireball, when Colbert was cancelled&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
Even back in the now-comparatively-sane Trump 1.0 administration, it seemed palpably true to me that the best check against Trump&amp;rsquo;s authoritarian instincts wasn&amp;rsquo;t legal or Constitutional, but rather cultural. The culture of free speech, of being able to criticize&amp;thinsp;&amp;mdash;&amp;thinsp;in no uncertain terms, with no held punches&amp;thinsp;&amp;mdash;&amp;thinsp;anyone in authority is fundamental to the American mindset.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://www.nytimes.com/2025/09/17/business/media/abc-jimmy-kimmel.html&quot;&gt;John Koblin at The New York Times today&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ABC announced on Wednesday evening that it was pulling Jimmy Kimmel&amp;rsquo;s late night show &amp;ldquo;indefinitely&amp;rdquo; after criticism of comments he made on Monday about the motives of the man who is accused of fatally shooting the conservative activist Charlie Kirk last week.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are in serious trouble.&lt;/p&gt;</content>
 </entry>
  
</feed>