Preliminary Review of Stage Manager on iPadOS 16

Some Thoughts on Stage Manager

I have turned on Stage Manager on my iPad Pro 12.9 for some time without interruptions. My initial thoughts when it’s just released was not very positive. It felt like too much trouble for too little gain. But I decided I should give it a fair chance before dismissing it entirely. I just used Stage Manager to write my thesis for an entire week. Here are some thoughts as of iPadOS 16 Beta 6.


Stage Manager does bring some compelling advantages over the Split View multi-tasking paradigm.

  • It makes every app device and orientation independent. All apps are launched into windows of sizes the app can support. Those iPhone only apps don’t feel like second class citizens anymore. Portrait or landscape only apps are no longer bounded to the actual device orientation.
  • It makes background tasks possible, albeit limited to three apps confined on a single stage. For example, I can now download a video with yt-dlp in a-Shell in the background by shoving its window behind. It’s also possible to run a web server in a similar fashion without it being terminated quickly.
  • It is now possible to vertically split the screen into two fairly usable areas for two different apps in portrait orientation. This requires the Dock to be turned off. For example, I could read a PDF document open in GoodReader on the top half and take notes with Apple Pencil in GoodNotes. I prefer this layout to the horizontal split in Split View. Previously this is only possible with apps like LiquidText where I have to use a single app to read and write. But it is almost impossible to find the perfect app for both writing and reading.
  • Almost all apps work in Stage Manager without the developers specifically optimising for it. It took a significant amount of time for developers to adopt Split View. But it will not be a problem for Stage Manager.
  • It has full external display support. Although it makes sense, the fact that this requires both a mouse and a keyboard attached makes the experience very inconsistent.


It brings a lot of difficulties as well.

  • It is difficult to switch focus between windows when some are fully hidden behind. There should be a function like Mission Control on macOS to shrink all windows temporarily to facilitate switching.
  • There is no access to Slide Over. I always put a few highly frequently used utility apps in Slide Over, e.g., DEVONthink, KeePassium, and Surge. Without Slide Over it becomes significantly more cumbersome to have quick access to a few apps. I think it is technically possible to retain Slide Over access in Stage Manager.
  • It is difficult to move windows between stages. Currently I need to drag the app icon into a new stage. But I always feel confused to if this would move over an existing window, or make a new window when the app supports multi-window. It would be much better if windows could be dragged over stages in App Switcher, just like with the Split View system.
  • The limit to have a maximum of four windows on a stage on the internal display is too low. With the Split View system, we can already have three apps on the same screen. It is too much hassle to gain one addition app. The limit should be at lest six as on an external display.
  • There is no access to the Recent Apps sidebar in portrait orientation. Although I turn it off anyway, it would be great if there is a way to summon it temporarily.
  • The frequent flickering during window resizing is really disturbing. I cannot be sure if this is a design choice or a bug. But I hope Apple would cover windows up with a blur to hide the flickering in later builds.
  • The single tap gesture to scroll to top no longer works in Stage Manager.


Currently Stage Manager is still quite buggy.

  • It is almost impossible to predict which corner the app window drag target would be.
  • The scrolling performance is terrible in App Switcher.
  • When the Dock is turned off, the Status Bar is often fully hidden when an app is zoomed in fullscreen.
  • Apps that only support fullscreen are often squashed together with its content, and often doesn’t rotate properly with device orientation.
  • A lot of animation quirks and inconsistencies.


  • Use lighter wallpapers so black windows such as video players do not get lost.
  • It is possible to have a fullscreen app on a stage with other windows running simultaneously behind it.
  • Those old apps that are not optimised to accommodate the Home Bar can now be forced into fullscreen without black borders.
  • Quick Notes can still be accessed via Control Centre.

A More Reliable “Copy to Clipboard” Shortcuts Action

Since the release of iOS/iPadOS 15.0, the Shortcuts app re-written in SwiftUI has been a constant disaster1.

One of the major problems affecting my workflow is that the “Copy to Clipboard” action often refuses to work. It usually starts to work if it’s run twice consecutively. To make sure things are copied into my clipboard reliably, I have made a shortcut as a custom “Copy to Clipboard” action, which attempts to copy its input up to three times and presents a Share Sheet for manual copying if all failed.

This custom shortcut works as a drop-in replacement for the native “Copy to Clipboard” action:

  • Download the shortcut, or build it on your own from the diagram.
  • Replace any “Copy to Clipboard” action with “Run Shortcut”.
  • Select this custom shortcut as the parameter.
  • Set appropriate input as the data to copy.
Custom Copy to Clipboard Action
Custom Copy to Clipboard Action

  1. This article is written at the time of iOS 15.1. ↩︎

1Password Refugee’s Guide to KeePass


Passwords are the gateway to our digital identities. I have been relying on 1Password to manage my passwords in local vaults for a few years. But as you may know from the recent news, the company is moving in a controversal direction, which I do not support. You can find more discussion on this topic in the links 1, 2. As a 1Password refugee, I have been on the quest of finding a reliable and trustworthy alternative since then.

I will talk about the reasoning behind my choice, the migration process, choices of client apps on both desktop and mobile, and the setup of one-time passwords.

As a disclaimer, I am in no way affiliated with any software or developer mentioned in this article.


I have examined many alternative systems, including BitWarden, Secrets, and Enpass. But in the end I settled on KeePass, which is a free and open source password manager operating on its open standard database format, kdbx. The are several reasons for this choice.

  • Firstly, I will not be locked-in by the original software itself. There exist many excellent clients across all platforms that read and write the same database format. If one of them is going in a direction I dislike, I can always switch apps while keeping the same database.
  • Secondly, the open source nature means the code and standard can be freely reviewed. There have been many independent audits for KeePass, making it more trustworthy than a typical proprietary software.
  • Lastly, the database is a single encrypted document ending in .kdbx, which can be stored anywhere. I can choose to sync it via any standard cloud storage, without needing to subscribe to any additional services, nor setting up my own server.


The migration process from 1Password to KeePass is not exactly straightforward. It has to be done on a desktop computer, as 1Password only exports data from their desktop clients. It also seems that 1Password does not want you to export your data too easily. Their support article guides to export to 1pif format or plain text csv format, both of which are less than ideal. The 1pif format is not documented well 3, while the csv requires extensive manual calibration to properly transfer all data. So the best solution is to import from the 1Password local vault format opvault directly.

This requires an extra step for 1Password account users, because their data is not stored in opvault. To obtain the local opvault database, one needs to create a local vault and copy all items in the 1Password account to the new local vault. This requires enabling “Allow creation of vaults outside of 1Password accounts” in the 1Password settings, and sync it to a local folder to expose the database.

Once the opvault database is prepared and located, the conversion to kdbx format of KeePass can be done the most easily by using the KeePassXC client, which is a modernised port of the original KeePass. The import option “1Password Vault” in KeePassXC directly opens the opvault database and converts it to kdbx. Although KeePass can also import it with the help of the OneVault plug-in.

Now all data should have been migrated from 1Password to the kdbx database. You can choose to store it anywhere, or sync it with any cloud storage. But as a pre-caution, you should still keep the 1Password database in the rare case of data loss during conversion.



The best desktop client is probably KeePassXC, which runs natively across Windows, macOS, and Linux. It supports time-based one-time password (TOTP), and integrates with browsers (Chromium, Firefox) out of the box. The original KeePass client only runs natively on Windows, requiring extra setup to run on macOS and Linux. But it is more extensible with plug-ins. For most use cases, I would recommend KeePassXC over KeePass.


There are two actively maintained KeePass apps on iOS, namely KeePassium by Andrei Popleteev, and Strongbox by Mark McGuill. Both are commercial apps in the App store, but with a dual GPL license as open source projects. They both offer a generous free version, and a more convenient premium version that can be accessed with either a subscription or a one-off license. KeePassium also offers a so-called “perpetual fallback license” for annual subscribers, which means those who subscribe for more a year get to keep access to all previous premium features, forever. Roughly speaking, KeePassium is more minimalist and polished; while Strongbox has more features and options, e.g., checking compromised passwords with “” (HIBP), fetching favicons automatically.

One major difference is that KeePassium is a completely offline app without any networking code 4, while Strongbox directly connects to the internet to integrate with Dropbox, Google Drive, and haveibeenpwned. These convinient features in Strongbox do come with some risks. It is more secure if the app that can read my secret cannot communicate with the internet. While I use and like both of them, I prefer KeePassium slightly for the above reasons.


Although I am not an avid user of Android anymore, a quick search shows that there is no shortage of good KeePass apps on Android, like KeePassDX.

One-Time Password

One-time password requires a bit more attention in KeePass. The standard practice is to create two additional attributes: “TOTP Seed”, and “TOTP Settings”. The “TOTP Seed” field holds the secret key, while the “TOTP Settings” field usually holds “30;6” which means “generating 6 digits every 30 seconds”.

As a bonus, this can also be used to generate TOTP for Steam, by filling in the Steam Authenticator key in “TOTP Seed”, and “30;S” in “TOTP Settings”. It is a little tricky to get the secret key. But with some patience and caution, this can be obtained following 5 using the Steam Desktop Autheticator, which is an open source port of the Steam Mobile Authenticator running on Windows. When the encryption passphrase is set to empty, the secret key can be found in the .maFile as the string following otpauth://totp/Steam:<username>?secret= before the next & symbol.


It is sad to see 1Password to become increasingly more money-driven and customer-hostile. But fortunately, there are excellent open source alternatives like KeePass and BitWarden. So far I have been very satisfied with my adoption of KeePass.

In terms of features, KeePass has both advantages and disadvantages compared to 1Password. For example, KeePass supports additional security with key file, and hardware authentication like YubiKey. There is also attachment support on the mobile KeePass apps. But the lack of group sharing features in KeePass might be a dealbreaker for some, in which case BitWarden should be considered instead.

As a lesson learnt, I shall always try to keep important long-term data in some open standard format.

Multitasking like a Pro on iPad


Multitasking is essential to get the most out of iPadOS [^This arricle is written in the context of iPadOS 14.], especially if it is run on the larger pro models to achieve some productivity.

Unfortunately, the access to multitasking is quite limited. If you have a physical keyboard attached, the most efficient way to multitask is to Command-Space to open Spotlight. But if there’s no external keyboard attached to the iPad, the only way to open an app in “Split View” or “Slide Over” is to drag it from the dock into appropriate places. The issue is that there’re only so many slots on the dock: 15 on the iPad Pro 12.9, or 12 on all other models. What if I want to multitask with other apps? There’re two relatively obvious options with some drawbacks:

  • First go back to “Home Screen” and launch the app into fullscreen. Now the app is shown on the dock, assuming the “Show Suggested and Recent Apps in Dock” is turned on in “Settings”. Then we can drag it into multitasking like any other app on the dock. But this is way too convoluted to execute.
  • Put all apps in a folder and put the folder on the dock. But I am not a fan of app folders because it’s hard to find apps in them and the aesthetics is off my chart;

Basically it is almost impossible to efficiently fire up an arbitrary app into multitasking, without an external keyboard.


But this is not the full story today. There’s actually another way, a better and more efficient way. That is to assign “Spotlight” to “AssistiveTouch”, and multitask directly by searching and dragging apps from “Spotlight”. This gives us the same efficiency just like with a physical keyboard. The full steps to enable this are

  • Open “Settings”, and navigate to “Accessibility” – “Touch” – “AssistiveTouch”;
  • Turn on the “AssistiveTouch” toggle on the top;
  • Tap on “Single-Tap” under the “CUSTOM ACTIONS” heading;
  • Choose “Spotlight” under the “SYSTEM” heading as the action.

Now multitasking on iPadOS just gets a lot more efficient. I can simply tap on the virtual home button floating on the screen to invoke “Spotlight” and search for the app I want. Then I can drag the app icon out of the search box into the sides of the screen to put it into “Slide Over” or “Split View”.


It is well-known that dragging an app to the left/right on the screen puts it into “Slide Over”. But it is not obvious how to put floating apps into fullscreen. This can be done by dragging the top bar of the floating window to the top in the middle of the screen. The full list of gestures of a multitasking master is

  • Drag to Left Edge –> Split View on Left,
  • Drag to Right Edge –> Split View on Right,
  • Drag to Left –> Slide Over on Left,
  • Drag to Right –> Slide Over on Right,
  • Drag Middle Bar –> Resize Split View,
  • Drag Top Bar to Top Centre –> Fullscreen.

Build a Firewall to Protect our Privacy on iOS/iPadOS

Updated on 29 Aug 2021


In the recent years, privacy invasion has become one of the most heated topics in the digital era. The online advertisers are trying their very best to gather our private information, build our profiles, and track us across the internet for targeted ad delivery.

With the introduction of App Tracking Transparency in iOS/iPadOS 14.5, we have gained the ability to reject the collection of our IDFAs, which are the device identifiers for advertisers. This is a big step forward to protect our privacy.

However, this identifier is far from the only information collected by the advertisers. I know everyone is slamming on Facebook on this. But it is well deserved so let’s join the crowd. Here is the list of data collected by Facebook as shown on the Privacy Label in the App Store:

  • Purchases
  • Financial Info
  • Contact Info
  • Contacts
  • User Content
  • Search History
  • Browsing History
  • Identifiers
  • Usage Data
  • Diagnostics
  • Other Data

The more concerning issue is that not only the Facebook app itself collects these data, a massive amount of other apps also collect them by implementing the Facebook Platform SDK. The only piece of information we can deny access to on iOS is just one of the identifiers, namely the IDFA.

Traditionally, firewalls are one of the weapons we have to fend ourselves against non-consensual tracking, by denying internet connection to a list of servers belonging to the trackers. However, iOS does not have a built-in firewall. So we need to use some third-party solutions. The app of focus today is Surge [1], which is marketed as an advanced networking toolbox.

I’ll outline how to set up the app as a system wide local firewall in the next section, followed by a brief guide on how to enable DNS over HTTPS.


In this section, we’ll set up Surge to block all traffic to a list of IP addresses of known trackers. We’ll use the Steven Black’s Unified Hosts as an example list. But it can be customised to include any address. We’ll walk this whole process once so you understand what is going on.

First, we need to obtain the hosts and convert in into the required format. After downloading it, open it in a regular-expression-capable text editor, say Textastic. We only need the list of IP addresses that we want to block. So we remove the at the beginning of each line, as well as the section of local hosts. This can be done in a single step by using the following regular expression


to replace the matches with an empty string. Then we save the file as hosts.txt. If this is not something you are comfortable with, I also have the resulting hosts.txt available on GitHub. I’ll try to update it regularly but obviously it won’t be as up-to-date as the original.

The next step is to load this list into the configuration of Surge. First copy the hosts.txt into the profile folder Surge, which is located in “Under My iPhone/iPad” by default. If you have set “Profile Sync” with iCloud Drive in Surge, then obviously this folder is located under “iCloud Drive”. Now we have the block list in place. We just need to add a single line in the configuration file, which can be accessed by tapping the profile name on the top-left in Surge followed by “Edit in Text Mode”. Here we paste the rule


immediately before the line FINAL,DIRECT. This line basically tells Surge that hosts.txt is a set of domains to reject their connections.

In case you don’t want to go through this process, you can directly add the following rule to the configuration profile instead


which will be kept up to date automatically by Surge. You can also skip editing the profile altogether by directly “Download Profile from URL” in Surge from

In addition to blocking specific domains, Surge can also block traffic from certain apps by matching user agents. For example, the rule


will reject all traffic from Instagram [2]

Finally we want to start up this firewall. First select “Rule-Based Proxy” in the “Outbound Mode” so Surge will process the rule we just added. Next tap on “SETUP” and follow the instructions to set up a local VPN. Now the firewall should be working to reject connections to those trackers and advertisers. A quick test is to visit “” and see that is rejected under “Recent Requests”. In addition to trackers, the firewall will also block most ads served in apps.

We can set up Surge to automatically start after device reboots. This setting can be accessed in Surge under “More – Always On – Turn on Surge Automatically”. You can also hide the “VPN” label on the status bar by turning on “Hide VPN Icon”, although this may cause errors when there’s a shortage of RAM.


Besides rejecting connections to certain domains, Surge has a lot of advanced features to offer, which are far beyond the scope of this article. But one of them I would like to include is the capability to run DNS over HTTPS (DoH), which is an encrypted protocol to resolve Domain Name System. It adds another layer of security and privacy for web browsing, by preventing DNS queries being eavesdropped or manipulated.

This can be configured by tapping the “DNS Servers” button on the “DNS” card in Surge. You just need to fill in the DoH URL in the “DNS-OVER-HTTPS” section, say provided by Cloudflare or by Quad9.


Surge also has the capability to descrypt and intercept https traffic, by doing a so-called “man-in-the-middle” (MitM), on your own network, from your own device. This can be used to block persistent in-app ads, which usually cannot be blocked without a jailbreak.

For example, the following steps enable ad-blocking for YouTube videos:

  • Enable “MitM” in Surge and follow the instructions to install a certificate. (Do not share the certificate with anyone, unless you know what you are doing.)
  • Add and under the “Hostname” section in the “MitM” card. Surge only performs “MitM” attacks on the hostnames listed here.
  • Download YouTube.sgmodule and YouTube.js from my repository to the Surge configuration folder.
  • Tap on “Modules” on the “Module” card and add YouTube.sgmodule as “New Local Module”. A module is basically an isolated configuration in addition to the main conf file, which can be easily turned on and off.
  • Turn on “Scripting” in Surge, which enables the YouTube.js file as subsection of the module. This step can be skipped. But I find the blockign more reliable when it is on.


Setting up Firewall and DoH drastically improves the security and privacy of surfing the modern web with an iOS device. I am aware that there exist partial alternatives like AdGuard Pro and 1Blocker, which are primarily Safari Content Blockers. There’re also some VPN services bundling a firewall into their app, like Lockdown. But Surge is the best, dedicated tool for this task in terms of both flexibility and performance. The pricing is quite steep on the first sight. But considering its feature set and one-off license nature, it is well worth the cost.

  1. This article is written in the context of Surge 4.7.0.  ↩
  2. For more rule types, please consult the user manual.  ↩