The world is a bridge; pass over it, but build no houses upon it.
—Attributed to Jesus on the Buland Darwaza
What is contentment? To renounce all craving for what is not obtained unsought and to be satisfied with what comes unsought, without being elated or depressed even by them—this is contentment. As long as one is not satisfied in the self, he will be subjected to sorrow. With the rise of contentment the purity of one's heart blooms. The contented man who possesses nothing owns the world.
Jesus said, "Be passersby."
—The Gospel of Thomas, Logion 42
/misc | Dec 08, 2024
Adobe's 8-step guide on How to flatten a PDF file ends with the instruction to "Print document"; sadly, this feature is missing in the macOS version:
Printing to PDF missing: "The Mac OS dropped the ability to print directly to a PDF several versions ago."
Print to PDF: "The Adobe PDF printer is not available on Mac."
Here's a 3-step alternative:
Tools → Print Production → Preflight (or use the keyboard shortcut Cmd+Shift+X to save a few clicks)
In PDF Fixups, double-click Flatten annotations and form fields
Save the new PDF when prompted
and similarly-concise console approach:
Press Cmd+J to open the JavaScript Debugger console
Enter this.flattenPages();
and press Cmd+Return
Save the PDF as desired
this.flattenPages();
applies to the current PDF. To flatten all open PDFs, use Thom Parker's script: app.activeDocs.forEach(oDoc=>oDoc.flattenPages());
Both commands generally display "undefined" when run, since the flattenPages()
method does not produce any return value.
However, you might encounter the error "NotAllowedError: Security settings prevent access to this property or method" for protected documents; check File → Properties → Security → Changing the Document.
Tested in Adobe Acrobat Pro 2024
Sanity-preserver: View → Disable new Acrobat
/mac | Oct 18, 2024
with IOPaint's erase models:
Install: pip3 install iopaint
(see Quick Start for GPU instructions)
Run: iopaint start --model=lama --device=cpu --port=8080
Access: open http://localhost:8080 in your web browser
Seated Buddha, courtesy of The Cleveland Museum of Art
Besides watermark/object removal, IOPaint also supports inpainting, outpainting, paint-by-example, and text generation.
Photographer Files $1 Billion Suit Against Getty for Licensing Her Public Domain Images
The macOS Photos app has a retouching tool that can remove objects or touch up portrait photos.
/nix | Sep 28, 2024
Twocanoes (developer of Winclone) has updated DFU Blaster Pro, which reduces the process of entering DFU mode on a Mac to a single click. After connecting to the target Mac's DFU port, simply press the "DFU Mode" button on the host Mac. The tool can also retrieve the target Mac's model type, serial number, and ECID.
/mac | Sep 25, 2024
See update below for important change in macOS 15.1.
The widely-reported "foo is requesting to bypass the system private window picker and directly access your screen and audio" prompt in Sequoia (which Apple has moved from daily to weekly to monthly (though for some apparently it is minute-by-minute)) can be disabled by quitting the app, setting the system date far into the future, opening and using the affected app to trigger the nag, clicking "Allow For One Month", then restoring the correct date.
Tested by setting the date to 1/1/2040 then clicking "Allow For One Month"; no amount of changing to dates before 1/1/2040 triggered the nag, while setting the date to a month after 1/1/2040 or anytime thereafter triggered it again.
Apple's latest security enhancement defeated by a "hack" from the '90s shareware scene?
skrrtww: "Failing to respond to the prompt…does not even revoke the existing permission."
nox101: "AFAICT, Apple excludes all their own apps."
angulardragon03: "[T]he mechanism seems like it's primarily for shaming developers that don’t use the new API"
kranner: "I'm getting this alert even for code that uses only the new ScreenCaptureKit framework, specifically the SCScreenshotManager class introduced in WWDC23. Hopefully this is a bug and Apple meant to show this only for apps that still use deprecated functions like CGWindowListCreateImage."
skrrtww: "Any material use of ScreenCaptureKit that doesn't involve that content sharing picker specifically will trigger this prompt. That means asking for SCShareableContent, or a couple other generic uses I forget.
Jeff Johnson credits Ricci Adams with discovering that ~/Library/Group Containers/group.com.apple.replayd/ScreenCaptureApprovals.plist stores screen capture approval dates. He reports that the file is protected by TCC and suggests granting Full Disk Access to Terminal, using defaults
to read and modify the file, then logging off and on to permanently disable the prompt. In testing, I was able to edit ScreenCaptureApprovals.plist in both PlistEdit Pro and BBEdit without granting Full Disk Access or any other special permissions. Rather than logging off, I force-quit replayd
via Activity Monitor, and macOS automatically restarted the process. Thanks to both for the tip!
Amnesia by Jordi Bruin "allows you to disable the monthly reminders for Screen Capture Access on an app by app basis."
Luke Hamburg's macOS 15 screencapture nag remover Bash script is a FOSS alternative to Amnesia, which also takes Apple's latest shenanigans into account:
macOS 15.1 made a change to replayd whereby upon each invocation of an app that requests ScreenCapture permission, the timestamp in the plist is overwritten with the current date/time. The net effect is that if you use an app once, and then don't use it again for >30 days, you will be nagged again, even if you had previously disabled the nag.
v1.3.0 of this script added a workaround for this: an option to install a LaunchAgent which runs every 24h and keeps the timestamps updated. This ensures that nags are kept hidden even as apps are used or if your system clock abruptly changes.
Luke also points out that Apple has provided a workaround for business customers to disable the nag:
macOS 15.1 introduces a new method for suppressing these alerts across the board. This leverages a configuration profile which must be provisioned by an MDM server (e.g. Jamf, Addigy, Mosyle, etc). Apple unfortunately prohibits self-installing configuration profiles for certain TCC settings, ScreenCapture being one of them.
/mac | Sep 18, 2024
// This script automates the removal of all shared links from your Dropbox account. // Navigate to https://www.dropbox.com/share/links, open the browser console, and paste the JavaScript code below. // Optional: To delete only specific types of links (i.e., View or Edit links), // edit the `deleteLinkTexts` array to include only the types of links you want to remove. // By default, the script will target both "Delete view link" and "Delete edit link" options. // Script source: https://www.dropboxforum.com/t5/Create-upload-and-share/remove-all-shared-links/m-p/710562/highlight/true#M73731async function pause(ms) { return new Promise(resolve => { setTimeout(() => { resolve(); }, ms); }); } async function deleteLinks() { const deleteLinkTexts = ["Delete view link", "Delete edit link"];
// Both optionslet items = document.querySelectorAll('.share-page-row-actions [data-testid="open-menu-button"]'); for (let i = 0; i < items.length; i++) { items[i].click();
// Click the submenu button to open the menuawait pause(1000);
// Adjust the pause duration as needed// Find and click the appropriate delete link option const deleteLinkOption = Array.from(document.querySelectorAll('.dig-Menu-row-title')).find(item => deleteLinkTexts.includes(item.textContent)); if (deleteLinkOption) { deleteLinkOption.click();
// Click the delete link optionawait pause(1000);
// Adjust the pause duration as needed// Find and click the delete button const deleteButton = document.getElementsByClassName("dbmodal-button"); if (deleteButton.length > 0) { deleteButton[0].click(); await pause(1000);
// Adjust the pause duration as needed} } items = document.querySelectorAll('.share-page-row-actions [data-testid="open-menu-button"]');
// Refresh items} } deleteLinks();
List shared links:
% tbx dropbox file sharedlink list
...
| tag | url | name | expires | path_lower | visibility |
|--------|----------------------------|---------|---------|-----------------|------------|
| file | https://www.dropbox.com... | foo.jpg | | /photos/foo.jpg | public |
| file | https://www.dropbox.com... | bar.jpg | | /photos/bar.jpg | public |
| folder | https://www.dropbox.com... | Baz | | /baz | public |
The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.csv
The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.json
The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.xlsx
The command finished: 2.16s
Delete a single shared link:
% tbx dropbox file sharedlink delete -path /photos/foo.jpg
Removing link `https://www.dropbox.com...` that point to `/photos/foo.jpg`
| status | reason | input.tag | input.url | input.name | input.expires | input.path_lower | input.visibility | result |
|---------|--------|-----------|----------------------------|------------|---------------|------------------|------------------|--------|
| Success | | file | https://www.dropbox.com... | foo.jpg | | /photos/foo.jpg | public | |
...
or all shared links by extracting the paths from the path_lower
column in shared_link.csv with awk
and feeding them to tbx
via xargs
:
% awk -F ',' 'NR>1 {print $5}' shared_link.csv | xargs -I {} tbx dropbox file sharedlink delete -path "{}"
(tbx
includes a dropbox team sharedlink delete links
command to batch delete shared links for Teams accounts.)
From the How to manage your default sharing settings section of How to manage your Dropbox file and folder sharing permissions:
Log in to dropbox.com.
Click your avatar (profile picture or initials) in the top right.
Click Settings.
Click the Sharing tab.
Choose your default settings.
Use Who has access to manage who can open your shared links.
Anyone with the link: All the links you share are public. Anyone can open them.
Only people invited: Only people you invite can access your files and folders. If someone who wasn’t invited receives the link, they can’t open it.
Team members: Only other members on your team account can access your files and folders.
Use What people can do to manage whether people can edit the files and folders you share.
Can edit: Anyone who can open the shared link can edit the file.
Can view: Anyone who can open the shared link can view and comment on the file, but not edit it.
Note: These settings won’t apply when you share from a mobile device, or when you copy and paste a link from the address bar. The changes you make to default sharing settings won’t be applied to existing shared links. Only new links will use this setting.
/misc | Sep 14, 2024
Tried the native Screenshot.app, Shottr, CleanShot X, Flameshot, ksnip, Skitch, Xnapper, among others to no avail.
Snagit 2024's Capture Multiple Areas on the Screen did the trick:
In the Capture window, select the All-in-One tab (rather than the usual Image for screenshots)
Enable Capture Cursor and 5 Second Delay:
Click the Capture button or press Control+Shift+C
When the orange crosshairs appear, position your cursor over the main application window and click to capture it, including any context menus, drop-downs, or other elements that appear within the frame
Click the camera icon in the popup menu to edit or save the screenshot
/mac | Sep 08, 2024
(Spent way too much time in UTM's Drives → New… and mucking about in config.plist before this brain-wave):
Create a new blank image in Disk Utility (Cmd+N)
Set filename, size, format, etc. as desired
Select the VM in UTM's sidebar → click the "Edit selected VM" button in the toolbar
Under "Drives" click New… → check "Removable" → click "Create" then "Save" to close the settings window
In the VM's main pane, scroll down to the "External Drive" dropdown menu (which has now appeared) → select Browse… → double click the DMG file created in step 2
/mac | Sep 07, 2024
(without hack workarounds) via RDP shadowing.
Warning: Do not proceed without fully understanding the steps involved and how to secure your network.
System Properties (sysdm.cpl) → Remote
Enable "Allow remote connections to this computer" → OK
Group Policy Editor (gpedit.msc) → Local Computer Policy → Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Connections
Double click "Set rules for remote control of Remote Desktop Services user sessions" → select "Enabled" → set "Options:" to "Full Control without user's permission" → OK
Windows Defender Firewall with Advanced Security (wf.msc) → check "File and Printer Sharing (SMB-In)" and "Remote Desktop - Shadow (TCP-In)" are enabled for LAN connections (see Restrict Windows Remote Desktop connections to LAN only)
If the local and remote credentials differ, store the remote username and password in Windows Credential Manager:
cmdkey /add:
<hostname|IP> /user:
<remote_user> /pass:
<remote_pass>
Retrieve the remote user's session ID (will generally be "1" or "2" on single-user systems):
qwinsta /server:
<hostname|IP>
Connect:
mstsc.exe /shadow:
<sessionID> /v:
<hostname|IP> /noconsentprompt /control
Modify and save this batch file, then run it to automatically retrieve the user session ID and establish a connection:
@echo off setlocal enabledelayedexpansion :: Set your remote username and hostname or IP address set remote_user=
<USERNAME>set remote_host=
<HOSTNAME|IP>:: Get the session ID for the specified username where the session state is Active for /f "tokens=2,3,4" %%a in ('qwinsta /server:%remote_host% ^| findstr /R "^ %remote_user%"') do ( if "%%c"=="Active" ( set session_id=%%b ) ) :: If an active session ID was found for the specified user, connect automatically if defined session_id ( start "" mstsc /v:%remote_host% /shadow:%session_id% /control /noConsentPrompt ) else ( echo No active session found for user "%remote_user%". ) exit
Errors:
Long delay on initial login followed by "Shadow Error: This computer name is invalid" – Resolved by enabling the "File and Printer Sharing (SMB-In)" and "Remote Desktop - Shadow (TCP-In)" rules in the server's firewall settings.
"Shadow Error: Access is denied" – Fixed by saving remote credentials in the Credential Manager using cmdkey
. Alternatively, you can use the /prompt
flag with mstsc.exe
to manually enter credentials. However, this option isn't available for qwinsta.exe /server:
or query.exe
<username|session> /server:
, so they will return Error [5]: Access is denied
unless local and remote credentials match.
"Shadow Error: The session identification does not specify a valid session." – For manual login, this is resolved by retrieving the correct session ID on the server with query user
. The batch script automatically finds the correct session ID, so no manual intervention is needed.
In Microsoft's Remote Desktop lexicon, the terms "local session", "interactive session", and "console session" all refer to the session in which the user is physically present at the computer.
View stored credentials via cmdkey /list
and delete them with cmdkey /delete:
<hostname|IP>. Both actions can also be performed through the Credential Manager GUI (control keymgr.dll
).
Viewing a Remote User’s Desktop Session with Shadow Mode in Windows
Windows Server 2008 R2 Remote Desktop Services Resource Kit; "Shadowing a User Session" in the "Providing Help with Remote Control" section of Chapter 11, "Managing Remote Desktop Sessions"
Shadow Remote Desktop Session (RDS) Without Permission Prompt
Spying on users using Remote Desktop Shadowing - Living off the Land
How to perform RDP shadowing from Win10 Pro to another Win10 Pro
How to Shadow (Remote Control) a User’s RDP session on Windows Server RDS
/windows | Sep 04, 2024
TightVNC Service Configuration → Access Control
Click Add… → set "First matching" and "Last matching IP" values to cover desired LAN range (e.g., 192.168.0.1 and 192.168.0.254) → set "Action" to Allow → click OK
Click Add… → set "First matching" to 0.0.0.0 and "Last matching IP" to 255.255.255.255 → set "Action" to Deny → click OK
Click Apply
Optionally adjust local and remote IP address scope for TightVNC's default inbound rule in Windows Defender Firewall with Advanced Security; see Restrict Windows Remote Desktop connections to LAN only.
/windows | Aug 31, 2024
Open Windows Defender Firewall with Advanced Security (Win+R → wf.msc → Enter)
Click "Inbound Rules" under "Windows Defender Firewall with Advanced Security on Local Computer"
For each Remote Desktop entry, double click to open Properties then select the "Scope" tab
Under "Remote IP address" select "These IP addresses:"
Click Add…
Select "Predefined set of computers", choose "Local subnet", then click OK twice
Thanks to @void_in for the pointer.
/windows | Aug 31, 2024
Although disc burning was removed from Disk Utility in OS X 10.11 El Capitan, two native methods and a venerable open-source app still work even in macOS Sonoma:
Finder: With an optical disc drive connected, the context menu for an ISO file will display "Burn to Disk…":
Terminal: hdiutil burn /path/to/ISO
# terser than dd + no sudo
Burn: Compatible with OS X 10.9 through macOS 14(!). Besides burning ISO files, Burn can author a wide range of data, audio, and video discs.
/mac | Aug 30, 2024
with Demucs, an open source "state-of-the-art music source separation model, currently capable of separating drums, bass, and vocals from the rest of the accompaniment."
Install: pip3 install demucs soundfile
Run: /path/to/demucs --two-stems=vocals --out=
/path/to/output_dir/ /path/to/audio.flac
Listen: Find vocals.wav & no_vocals.wav inside output_dir/audio/.
Including soundfile
resolved RuntimeError: Couldn't find appropriate backend to handle uri.
The --jobs
flag (e.g., demucs --jobs
10 audio.flac) significantly speeds up processing when multiple cores are available, albeit at the cost of increased memory usage.
vocals.wav contained a few brief instrumental segments; removed the vocal segments in Fission (by selecting and silencing them) then overlaid vocals.wav with no_vocals.wav to preserve all non-vocal elements like so:
pip3 install pydub
In Python:
from pydub import AudioSegment # Load the two WAV files sound1 = AudioSegment.from_wav("vocals.wav") sound2 = AudioSegment.from_wav("no_vocals.wav") # Combine the two audio files combined = sound1.overlay(sound2) # Export the combined file combined.export("
combined.wav", format="wav")
/mac | Aug 28, 2024
My meager guide to mounting exFAT partitions with unsupported cluster sizes in macOS clearly needed a dollop of detail. The following steps were tested in macOS 14.6.1 with macFUSE 4.8.0 and exFAT 1.4.0:
(Though required as of Sonoma, Sequoia's FSKit (which implements a file system in user space) may render this unnecessary. In the meantime, Apple warns: "Kexts are no longer recommended for macOS. Kexts risk the integrity and reliability of the operating system. Users should prefer solutions that don’t require extending the kernel and use system extensions instead.")
Start up in macOS Recovery
Click Options → Continue Utilities → Startup Security Utility → Security Policy...
Change from "Full Security" to "Reduced Security" → enable "Allow user management of kernel extensions from identified developers" → click OK → enter password → click OK → Restart
Download and run the PKG installer (Universal binary that supports macOS 10.9 through 14(!))
When "System Extension Blocked" appears, click "Open System Settings"
Click "Allow" under "System software from developer 'Benjamin Fleischer' was blocked from loading." → enter password twice when prompted → click "Restart"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install autoconf automake pkg-config
git clone https://github.com/relan/exfat.git && cd exfat && autoreconf --install && ./configure && make
While installing to /usr/local/sbin/ is possible via sudo make install
, running from the fuse subdirectory after compiling is fine, e.g., sudo ./fuse/mount.exfat-fuse /dev/disk2s2 ~/mnt
exFAT for FUSE: If you opted to install in step 5.2, run sudo make uninstall
from the exfat directory. Otherwise, simply delete the exfat directory created in step 5.1.
Homebrew:
Uninstall packages installed via brew: brew list | xargs brew uninstall --force
Clean up any remaining files: brew cleanup --prune=all
Uninstall Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"
If you ran (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/yourusername/.zprofile
and eval "$(/opt/homebrew/bin/brew shellenv)"
as instructed after the Homebrew installation completed, you may also want to remove eval "$(/opt/homebrew/bin/brew shellenv)"
from ~/.zprofile or simply delete ~/.zprofile altogether if there are no other lines in it.
macFUSE: Run /Extras/Uninstaller.app from the mounted DMG.
Security Settings: Repeat steps 1.1 & 1.2, then switch "Reduced Security" back to "Full Security".
Apple's Virtualization Framework cannot load third party kexts by default, returning: "System Extension Error - An error occurred with your system extensions during startup and they need to be rebuilt before they can be used. Go to Privacy & Security System Settings to re-enable them." Steven Michaud outlines a workaround in his Running Third Party Kernel Extensions on Virtualization Framework macOS Guest VMs.
Homebrew alternatives include MacPorts (replace pkg-config
with pkgconfig
), Conda, pkgsrc, and Fink.
/mac | Aug 10, 2024
Windows lacks an equivalent to macOS's Preview app, but these free tools can handle simple PDF markup tasks:
/windows | Jul 10, 2024
Spent far too long trying to troubleshoot a new App Shortcut for Messages with commands like defaults find NSUserKeyEquivalents
and mucking about with files such as com.apple.MobileSMS
and .GlobalPreferences.plist
before stumbling onto App Keyboard Shortcuts Don't Work in Sonoma. Newly-added App Shortcuts in Sonoma do not work for Messages.app; other tested apps (Calendar, Contacts, Dictionary) appear unaffected.
As jamesfromhaymarket points out, one workaround is to set the desired keyboard shortcut for All Applications instead of just Messages; assigning "Delete Conversation…" (press Opt
+;
for the ellipsis) to Cmd
+D
this way was successful.
/mac | Jun 23, 2024
Launch ActivePresenter 9 (free for trial and non-commercial use; watermark-free output)
Click Open → select desired video
Click on the time axis to reveal the playhead then drag it to the desired location
Click the "Insert Time" icon on the timeline toolbar → enter desired duration (default is 2000 ms) → OK
Click the Insert tab → Spotlight → use the crosshairs cursor in the video player to highlight the desired athlete
Adjust the spotlight in the timeline by clicking and dragging its box or outer edges
Optionally slow down or speed up frames:
How to Insert Time to Videos in ActivePresenter 8 | Embedded video tutorial
How to Insert Freeze-Frames in ActivePresenter. | Embedded video tutorial
Define a Range Before Editing Audio/Video - ActivePresenter 8
/misc | Jun 15, 2024
Edit Python script below, adjusting fade_duration
and input_folder
as desired, then save (e.g., combine_videos.py
):
import os from moviepy.editor import VideoFileClip, concatenate_videoclips def add_fade_effects(clips, duration=2): faded_clips = [] for i, clip in enumerate(clips): if i != 0: clip = clip.set_start(clips[i-1].end) clip = clip.crossfadein(duration) clip = clip.fadein(duration).fadeout(duration) # Apply fade-in and fade-out to each clip faded_clips.append(clip) return faded_clips def combine_videos_with_fades(input_folder, output_file, fade_duration=
0.5): video_files = [os.path.join(input_folder, f) for f in sorted(os.listdir(input_folder)) if f.endswith('.mp4')] video_clips = [VideoFileClip(video) for video in video_files] video_clips = add_fade_effects(video_clips, fade_duration) final_clip = concatenate_videoclips(video_clips, method="compose") final_clip.write_videofile(output_file, codec="libx264") if __name__ == "__main__": input_folder = "
/path/to/mp4s" # Replace with the path to your folder containing MP4 files output_file = "combined_video_with_fades.mp4" combine_videos_with_fades(input_folder, output_file)
python3 combine_videos.py
/nix | Jun 15, 2024
Launch PLAY by Metrica Sports1 → click "New Workspace" → enter desired name for workspace → Save
Click plus symbol under PLAYLISTS2 → enter desired name for playlist (e.g., "Goals")
Hover over the Goals playlist → click three dots at bottom right of playlist entry → click "Add video file as a clip..." → select desired video clip(s)
Click the dropdown arrow under Goals → click and drag video clips to order as desired
Select a video clip in Goals → open the Annotations Module by clicking the crossed pencil and ruler icon (or using the keyboard shortcut, Cmd+5)
Click the large blue button with the white plus symbol → Player Visualizations → select an effect (Spotlight, Ring, Magnifier, etc.)3 → select desired player → click Player Tracking4 button5
When finished, hover over the Goals playlist → click three dots at bottom right → click "Export Playlist as Video..." → check "Annotations" and optionally "Export all clips as a single video file" → browse to desired destination → click Export
If tracking proves too tedious, pause and highlight instead:
In step 6 above, rather than "Player Visualizations", click "Pause & Drawings"
Set desired Pause Duration (default is 5 seconds)
Click desired highlighting option:
Highlight unwanted clip(s)
Hover over playlist name
Click three dots at lower right of playlist
Click "Delete Clips"
For importing long videos instead of clips, click the plus symbol under VIDEO MANAGER. ↩
On very brief segments, the exported annotations/effects can start later and linger longer than expected, despite attempts to adjust their duration beforehand. ↩
Only available in the paid LITE plan or higher, though a 7-day free trial (sans credit card) is available (exported videos display a smallish "PLAY by METRICA SPORTS" watermark in the bottom right corner) ↩
Depending on video quality, amount of motion, etc., you may need to backtrack a few frames, manually reposition the visualization, and click "Player Tracking" repeatedly. The keyboard shortcuts come in handy during this process, especially Cmd+Alt+left or right arrow to move 1 frame backwards or forwards, and Shift+Space to start/stop Player Tracking. ↩
/misc | Jun 14, 2024
Because switching between Windows VMs and their macOS host via Cmd+Tab launches the Start menu every time and PowerToys Keyboard Manager utility only works sporadically.
Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
Create a new binary value named Scancode Map
and assign value data of 00 00 00 00 00 00 00 00 03 00 00 00 00 00 5B E0 00 00 5C E0 00 00 00 00
Reboot
Neither HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\[NoWinKeys]
nor Local Computer Policy → User Configuration → Administrative Templates → Windows Components → File Explorer → "Turn off Windows Key hotkeys" had any discernible effect in a Windows 11 Pro 23H2 UTM VM.
The Scancode Map value is a series of hexadecimal numbers that instruct the operating system to remap or disable certain keys:
00 00 00 00
: Header (always zeros, used for header padding)00 00 00 00
: Header (also zeros, continuing the header padding)03 00 00 00
: Number of mappings (including the null terminator)00 00 5B E0
: Disables the left Windows key (by mapping E0 5B
to 00 00
)00 00 5C E0
: Disables the right Windows key (by mapping E0 5C
to 00 00
)00 00 00 00
: Null terminator (marks the end of the Scancode Map)Bytes are reversed in the Scancode Map registry entry because Windows uses the little-endian format, storing the least significant byte first.
Windows Platform Design Notes: Keyboard Scan Code Specification, Revision 1.3a — March 16, 2000: "This specification was previous published, with the same content, as 'Windows Hardware Quality Labs Keyboard Specification' and also referred to as 'Windows Keys Specification' and 'New Keys Specification.'"
/windows | Jun 12, 2024
"When you create a VM in macOS 15 from a macOS 15 software image (an .ipsw file) using a VZMacHardwareModel that you obtain from a VZMacOSRestoreImage, Virtualization configures an identity for the VM that it derives from security information in the host’s Secure Enclave. Just as individual physical devices have distinct identities based on their Secure Enclaves, this identity is distinct from other VMs."
"If someone moves a VM to a different Mac host and restarts it, the Virtualization framework automatically creates a new identity for the VM using the information from the Secure Enclave of the new Mac host. This identity change requires the person using the VM to reauthenticate to allow iCloud to restart syncing data to the VM."
"Using a macOS 15 installer to upgrade an older VM doesn’t provide support for iCloud."
Sadly, signing in to the App Store or iCloud does not appear to be supported (for now?), returning "An unknown error occurred."
Preview macOS Sequoia 15 with Parallels Desktop: "Signing into an Apple ID in a virtual machine is not supported: you won't be able to sign into your Apple ID within the VM."
/mac | Jun 10, 2024
"They say...that the aim of the ignorant is pleasure; the pursuit of the wise, happiness. Pray, under which category would you class marriage? I suppose it comes under one or the other."
...
"Both," I answered. "Could you see the ideal woman as I would fain paint her to you, you would understand me better. The pleasure you enjoy in the society of a noble and beautiful woman should be but the refreshment by the wayside as you journey through life together. The day will come when she will be beautiful no longer, only noble and good, and true to you as to herself; and then, if pleasure has been to you what it should be, you will find that in the happiness attained it is no longer counted, or needed, or thought of. It will have served its end, as the crib holds the ship in her place while she is building; and when your white-winged vessel has smoothly glided off into the great ocean of happiness, the crib and the stocks and the artificial supports will fall to pieces and be forgotten for ever. Yet have they had a purpose, and have borne a very important part in the life of your ship."
—Francis Marion Crawford in Mr. Isaacs: A Tale of Modern India
Calls to mind u/lucky_ducker's 2016 comment and Rufus' reflections on the fruit of action.
/misc | Jun 05, 2024
Repeating an answer here for posterity that I made earlier today on AskDifferent:
The only native method I've found for iOS 17 (that does not require using a Mac or PC) is via GarageBand:
If anyone knows of a more elegant native method for importing an M4R ringtone without a Mac or PC, please share. One might be forgiven for imagining that Apple intentionally keeps the process abstruse to encourage ringtone sales through the iTunes Store.
/misc | May 25, 2024
A breath of fresh air in this age of IAPs, subscriptions, and multi-gig downloads:
Free Ruler 2.0.8 [608k] {S} Floating horizontal and vertical screen rulers with measurements in pixels, inches, or millimeters. Available on both the Mac App Store and GitHub. 📺
/mac | May 25, 2024
Unlike some cPanel-based shared hosting platforms that allow mapping subdomains to subdirectories, NearlyFreeSpeech.NET requires a new site setup for each subdomain. However, multiple aliases can be created for a single site. For example, both foo.example.com and bar.example.com can point to shortname.nfshost.com with the hostname example.com.
These steps outline how to create a new subdomain for an NFS-hosted domain with an external DNS host:
NFS Member Login → sites → under "Actions", click "Create a New Site" (even if your domain is already hosted with them).
Select your NFS account from the dropdown menu → assign a unique "Site Short Name" (which serves as a unique identifier for the subdomain within the NFS system).
Enter desired subdomain URL (e.g., docs.example.com) into Canonical Name field.
Click No for "Set up DNS for new domains?" → Next.
Select desired Server Type → Next.
Select desired Site Plan → Finish.
Verify the site details on the summary page → click Create This Site.
When "Success! Everything looks OK, though it will take a minute or two to finish setting up." appears, click Continue.
/misc | May 25, 2024
with Matijs van Zuijlen's open source MSGConvert (aka Email::Outlook::Message).
Install:
sudo apt install libemail-outlook-message-perl
Recursively convert MSG files to EML files, saving in their respective directories:
find
/path/to/msgs/ -iname "*.msg" -type f -print0 | xargs -0 -I{} bash -c 'msgconvert "{}" -o "$(dirname "{}")/$(basename "{}" .msg).eml"'
Recursively convert and combine MSG files into a single MBOX file:
find
/path/to/msgs/ -iname "*.msg" -type f -print0 | xargs -0 msgconvert --mbox
combined.mbox
Other install options include cpan -i Email::Outlook::Message
or building from source with dependencies.
MSG files remain intact.
Current version of msgconvert is 0.921; check via grep '^\$VERSION' /usr/bin/msgconvert
or perl -MEmail::Outlook::Message -e 'print $Email::Outlook::Message::VERSION, "\n";'
In WSL's Ubuntu 22.04.3 LTS, sudo apt install libemail-outlook-message-perl
returned E: Unable to locate package libemail-outlook-message-perl; ran sudo apt update
to resolve.
Under Ubuntu 24.04 LTS ARM, msgconvert 0.921 returned Value for 'Subject' header with wide characters at /usr/share/perl5/Email/Outlook/Message.pm line 320. when converting a certain email, though the conversion appeared to complete normally (this error did not occur under Ubuntu 22.04.4 LTS ARM with the same version of msgconvert). Changing header_set
to header_str_set
in line 320 of /usr/share/perl5/Email/Outlook/Message.pm
, as described in PR 44 and Issue 49, resolved the error.
H/T: Georg Jung
/nix | May 24, 2024
By far the easiest, while also offering the most options. Slight hitch on ARM when attempting to run the installer, dvdaudioextractor.exe:
This program can only be installed on versions of Windows designed for the following processor architectures: x64
Worked around by extracting the contents via innoextract, then running .\app\dvdae-gui.exe.
FFmpeg 7 has recently merged dvdvideo, a "DVD-Video demuxer powered by libdvdnav and libdvdread" which
"can directly ingest DVD titles, specifically sequential PGCs, into a conversion pipeline. Menu assets, such as background video or audio, can also be demuxed given the menu’s coordinates (at best effort). Seeking is not supported at this time. Block devices (DVD drives), ISO files, and directory structures are accepted. Activate with -f dvdvideo in front of one of these inputs."
While the documentation includes four examples, it took some tweaking to find the right combination for losslessly extracting audio from a DVD in drive d:\ to WAV:
ffmpeg -f dvdvideo -title 2 -i d: -vn -acodec pcm_s16le -ar 48000 -ac 2 output.wav
and Apple Lossless (ALAC):
ffmpeg -f dvdvideo -title 2 -i d: -vn -acodec alac -ar 48000 -ac 2 output.m4a
(Found the correct title number via VLC (Playback → Title) and the audio format and bitrate via ffmpeg -i D:\VIDEO_TS\VTS_01_1.VOB
: Stream #0:2[0xa0]: Audio: pcm_dvd, 48000 Hz, stereo, s16, 1536 kb/s.)
Building FFmpeg is a little tricky, but nightly builds linked from ffmpeg.org are available.
A 17-year-old, multi-step method leveraging DVD Shrink, vStrip GUI, and DB PowerAmp Music Converter.
/windows | May 21, 2024
Cropping PDFs in Preview merely hides content (rather than erasing it) as explained in the alert dialog:
Cropping a PDF document doesn’t delete the content outside the selection.
The content outside the selection is hidden in Preview, but you might be able to view it in other applications.
Mac OS X 10.6.8 Snow Leopard’s Preview 5.0.3 (504.1) was the last version to support viewing the hidden data, as shown in its very different alert dialog:1
Cropping a document doesn’t destroy its contents.
You can view the uncropped document by choosing View > PDF Display > Media Box
Happily, Skim can do what modern versions of Preview cannot, revealing hidden content outside of the crop box: click PDF in the app menu → PDF Display → toggle Crop Box to Media Box.2
To permanently eliminate cropped content and adjust the PDF dimensions, execute the following Ghostscript command after cropping and saving in Preview:
gs -sDEVICE=pdfwrite -dUseCropBox -o output.pdf input.pdf
then verify in Skim as above.
Ghostscript can be built and installed from source (./configure && make && make install
), downloaded as a PKG installer from MacTeX, or installed via brew install ghostscript
.
Unlike Preview, Java-based Briss 0.9 and Briss 2.0 permanently eliminate content during the cropping process.
Is there something that crops or resizes the pdf page by its TrimBox?
PSA - You can crop all pages in a PDF using Preview: Select desired area with the Rectangular Selection tool → select all page thumbnails in the sidebar → Press Cmd+K to crop all pages.
Skim sports a slew of awesome features, including a real dark mode (that applies to content as well as the interface) and the ability to integrate with LaTeX. ↩
/mac | May 16, 2024
A newly-installed Dell Mobile Broadband (WWAN) module was not detected in Windows Device Manager (even under hidden devices) despite "WWAN/GPS" being enabled in BIOS Setup → Connection.
u/Dan-in-Va's reddit comment contained the solution:
I disconnected the battery and removed the card, reseated it, reconnected the four antenna cable pins, reconnected the battery, and powered back on. It was immediately recognized. I re-ran the firmware/driver update which worked, where the driver applied on the subsequent reboot.
(The only modification made was to press and hold the power button for some seconds after disconnecting the battery to discharge capacitors (of course, be sure the power cord is unplugged as well).)
The WWAN card appeared in Device Manager under "Other devices" as "PCI Device". Clicked "Update Driver..." and pointed to the directory containing the extracted Dell Wireless 5823e and Intel L860-R LTE Firmware and GNSS Driver; it then appeared under "System devices" as "DW5823e Intel(R) XMM7560 R+ LTE-A UDE Device".
The module disappeared once more after several power cycles, but reappeared after running Windows update and rebooting; the message "Configuring mobile broadband device | Do not shut down or restart Windows." displayed just above the Notification area briefly.
Environment: Dell Precision 3581, Dell/Fibocom DW5823E 4G module, BIOS version 1.12.0, Windows 11 Pro (23H2).
Dell Mobile Broadband (WWAN) Module Not Detected on a Re-imaged Dell Personal Computer (updated yesterday), only suggests reinstalling the driver or contacting Dell support, though it also includes these details:
/windows | May 10, 2024
Inno Setup is "a free installer for Windows programs by Jordan Russell and Martijn Laan, [f]irst introduced in 1997". Resources like EXEs and DLLs can be liberated from these archives via:
innounp 0.50: "The Inno Setup Unpacker. Supports Inno Setup versions 2.0.7 through 6.1.2". CLI.
innoextract 1.9: "A tool to unpack installers created by Inno Setup. ... Currently supports installers created by Inno Setup 1.2.10 to 6.2.2". CLI.
/windows | Apr 07, 2024
while also tracking each individual session with optional notes:
Timemator (30-day trial, then $7.99 one-time purchase) by Gleb Kotov/Catforce Studio
/misc | Mar 27, 2024
When the Thunderbird Message Pane is enabled (View → Layout → Message Pane), the Header Pane and Buttons (Reply, Forward, Delete, etc.) take up an inordinate amount of space; here's how to hide them:
In Config Editor, set toolkit.legacyUserProfileCustomizations.stylesheets to true
Help → Troubleshooting Information → open Profile Folder
In the profile folder, open or create "chrome" directory
Edit or create "userChrome.css" inside of "chrome", adding this line:.main-header-area {display:none !important;}
Restart Thunderbird
On a related note, alternating row colors in the Message List pane can be enabled by adding the following to userChrome.css:
table[is="tree-view-table"] tr:nth-child(even):not(.selected):not(tr:hover) {
-moz-appearance: none !important;
background-color: rgb(240,240,240) !important;
}
/misc | Mar 02, 2024
After almost 5 years of hosting at Netlify (at $9/month for basic, anonymized analytics), just moved to Cloudflare Pages after reading this r/webdev post:
along with the related HN comments.
The previous server migration, from Slicehost/Rackspace to Netlify, had been largely to avoid just such unlimited billing exposure.
Custom apex domains require moving Name Servers to Cloudflare DNS.
Trailing exclamation marks in _redirects need to be removed for the redirects to work in Cloudflare Pages.
Cloudflare Pages forcefully strips .html extensions, though an option for their preservation was promised in June 2022. UPDATE: For now, have settled on doubling .html extensions (except for index.html pages) to prevent the 308 redirects to extensionless pages.
Disabled "Email Address Obfuscation" in Cloudflare dashboard → tinyapps.org → Scrape Shield to prevent HTML validation errors (e.g., "there is no attribute 'DATA-CFEMAIL'" and remove unwanted JavaScript (email-decode.min.js) from being served.
Redirect www to non-www (H/T cloonan & Rickard):
www.example.com/*
https://example.com/$1
Disable access to *.pages.dev subdomain:
*.{project}.pages.dev
). Refer to Customize preview deployments access.*.pages.dev
URL associated with your production Pages project to a custom domain. You can use the account-level Bulk Redirect feature to redirect your *.pages.dev
URL to a custom domain."Prevent your pages.dev deployments showing in search results:
"Google and other search engines often support the X-Robots-Tag
header to instruct its crawlers how your website should be indexed. For example, to prevent your *.pages.dev
deployment from being indexed, add the following to your _headers file:"
https://:project.pages.dev/*
X-Robots-Tag: noindex
After deleting the Netlify site, revoke their access to any connected GitHub repository via GH account settings → Applications → Installed GitHub Apps.
/misc | Feb 26, 2024
no extension necessary: Tools → Page Info → Media → Select All → Save As...
/misc | Feb 25, 2024
Tested on a UniFi Express, which comes with a preset IP address of 192.168.1.1. Note that the Express is limited to managing 5 UniFi devices, including itself.
Go to Networks: https://192.168.1.1/network/default/settings/networks
Click "New Virtual Network"
Set Network Name and Gateway IP/Subnet as desired
Next to "Advanced" click "Manual"
Set VLAN ID as desired
Check "Network" next to "Isolation" → click "Add"
Go to WiFi: https://192.168.1.1/network/default/settings/wifi
Click "Create New"
Set Name and Password as desired, and set Network to VLAN created above.
Optionally enable "Client Device Isolation" under Advanced → Manual
Click "Add WiFi Network"
Go to Landing Page settings: https://192.168.1.1/network/default/hotspot/portal → "Settings" (This page was not discoverable via "Search Settings" using the terms "landing", "hotspot", "portal", or "guest".)
Under "Landing Page Settings", uncheck "Show Landing Page" → click "Save"
/misc | Jan 20, 2024