commit 497f1961ad921c08c381e53445d3361573065665 Spenser Truex <truex@equwal.com> 2026-09-21 00:26:03 -0700 Windows installer: Start menu entry, and bm-watch at each login The installer makes a Start menu entry. Only the desktop shortcut has the key Ctrl+Alt+Shift+F24, because Explorer can lose a key that two shortcuts share. A Startup entry runs bm-watch in a hidden mintty at each login, and the installer starts it at once, so the browser bookmarks come into bm during the installation. The installer and the uninstaller stop bm-watch before they change its files. The installer warns when the jq package of Cygwin is missing.
README | 13 +++++++++---- contrib/windows/sbm-setup | 38 +++++++++++++++++++++++++++++------- contrib/windows/sbm.nsi | 49 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/README b/README index d0f37b9..9de38dd 100644 --- a/README +++ b/README @@ -224,10 +224,15 @@ Printing nothing means the user cancelled. test/fakemenu is a small example. == Windows == bm runs under Cygwin. Get sbm-VERSION-setup.exe from a release on GitHub and start it. The installer puts bm and the bm-* tools in /usr/local/bin. It -makes a desktop shortcut that opens bm in a mintty window, and Esc closes -the window. The key of the shortcut is Ctrl+Alt+Shift+F24. Almost no keyboard -has an F24 key, so keyboard firmware can use this key combination without -conflicts. +makes a Start menu entry and a desktop shortcut that open bm in a mintty +window, and Esc closes the window. The key of the desktop shortcut is +Ctrl+Alt+Shift+F24. Almost no keyboard has an F24 key, so keyboard firmware +can use this key combination without conflicts. + +The installer imports the bookmarks of all profiles of the Chromium browsers +(Brave, Chrome, Chromium, Edge and Vivaldi). A Startup entry, sbm-watch, runs +bm-watch at each login, so new browser bookmarks come into bm a few seconds +after you add them. The import needs the jq package of Cygwin. The installer also puts fzf.exe, the Windows build of fzf, in /usr/local/libexec/sbm. Do not use the fzf package of Cygwin. That package is diff --git a/contrib/windows/sbm-setup b/contrib/windows/sbm-setup index b33dead..370737c 100755 --- a/contrib/windows/sbm-setup +++ b/contrib/windows/sbm-setup @@ -1,10 +1,34 @@ #!/bin/sh -# sbm-setup: give the user the example tags and search keywords of sbm. -# The installer runs this script. It keeps the files that the user has. +# sbm-setup: tasks of the Windows installer. +# +# sbm-setup data give the user the example tags and search keywords, +# and keep the files that the user has +# sbm-setup stop stop the bm-watch that the installer started -d=${XDG_DATA_HOME:-$HOME/.local/share}/sbm -mkdir -p "$d" -for f in engines usertags; do - [ -e "$d/$f" ] || cp "/usr/local/share/sbm/$f" "$d/" -done +case ${1-} in + data) + d=${XDG_DATA_HOME:-$HOME/.local/share}/sbm + mkdir -p "$d" + for f in engines usertags; do + [ -e "$d/$f" ] || cp "/usr/local/share/sbm/$f" "$d/" + done + ;; + stop) + # The hidden mintty of bm-watch has the class sbm-watch. When it + # stops, bm-watch gets SIGHUP and stops too. Cygwin shows the + # arguments of a process in /proc/PID/cmdline. + for f in /proc/[0-9]*/cmdline; do + case $(tr '\0' ' ' < "$f" 2>/dev/null) in + *'--class sbm-watch '*) + pid=${f#/proc/} + kill "${pid%/cmdline}" 2>/dev/null + ;; + esac + done + ;; + *) + printf 'usage: sbm-setup data | stop\n' >&2 + exit 2 + ;; +esac diff --git a/contrib/windows/sbm.nsi b/contrib/windows/sbm.nsi index 30b201c..25ba95e 100644 --- a/contrib/windows/sbm.nsi +++ b/contrib/windows/sbm.nsi @@ -3,12 +3,18 @@ ; ; The installer needs Cygwin with mintty. It puts bm and the bm-* tools in ; /usr/local/bin, fzf.exe in /usr/local/libexec/sbm, and the settings in -; /etc/profile.d/sbm.sh. It also makes a desktop shortcut that opens bm in a -; mintty window. The key of the shortcut is Ctrl+Alt+Shift+F24. Almost no -; keyboard has an F24 key, so keyboard firmware can use this key combination -; without conflicts. +; /etc/profile.d/sbm.sh. It makes a desktop shortcut and a Start menu entry +; that open bm in a mintty window. The key of the desktop shortcut is +; Ctrl+Alt+Shift+F24. Almost no keyboard has an F24 key, so keyboard firmware +; can use this key combination without conflicts. Only one shortcut has the +; key: when two shortcuts have the same key, Explorer can lose the key. ; -; The uninstaller removes these files. It keeps the bookmarks of the user. +; A Startup entry runs bm-watch in a hidden mintty at each login. bm-watch +; brings the bookmarks of the Chromium browsers into bm, and then the new +; bookmarks as you add them. The installer also starts bm-watch at once. +; +; The uninstaller stops bm-watch and removes these files. It keeps the +; bookmarks of the user. Unicode true ManifestDPIAware true @@ -29,6 +35,7 @@ ManifestDPIAware true !define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\sbm" !define MINTTYARGS "--class sbm -t sbm -s 120,32 -p center -o ConfirmExit=no -o Scrollbar=none /bin/bash -lc bm" +!define WATCHARGS '--class sbm-watch -w hide /bin/bash -lc "exec bm-watch brave chrome chromium edge vivaldi"' Name "sbm ${VERSION}" OutFile "${OUTFILE}" @@ -63,6 +70,12 @@ Function .onInit FunctionEnd Section + ; An earlier version can run bm-watch. Stop it before its files change. + ${If} ${FileExists} "$Cygwin\usr\local\libexec\sbm\sbm-setup" + nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup stop' + Pop $0 + ${EndIf} + SetOutPath "$Cygwin\usr\local\bin" File "${SRC}\bin\bm" File "${SRC}\bin\bm-check" @@ -71,6 +84,7 @@ Section File "${SRC}\bin\bm-import" File "${SRC}\bin\bm-migrate" File "${SRC}\bin\bm-title" + File "${SRC}\bin\bm-watch" File "${SRC}\bin\fzf" SetOutPath "$Cygwin\usr\local\libexec\sbm" File "${SRC}\libexec\fzf.exe" @@ -84,24 +98,39 @@ Section ; Cygwin does not see an execute permission on files that a Windows ; program makes. Cygwin chmod sets it. - nsExec::ExecToLog '"$Cygwin\bin\chmod.exe" 755 /usr/local/bin/bm /usr/local/bin/bm-check /usr/local/bin/bm-commit /usr/local/bin/bm-html /usr/local/bin/bm-import /usr/local/bin/bm-migrate /usr/local/bin/bm-title /usr/local/bin/fzf /usr/local/libexec/sbm/fzf.exe' + nsExec::ExecToLog '"$Cygwin\bin\chmod.exe" 755 /usr/local/bin/bm /usr/local/bin/bm-check /usr/local/bin/bm-commit /usr/local/bin/bm-html /usr/local/bin/bm-import /usr/local/bin/bm-migrate /usr/local/bin/bm-title /usr/local/bin/bm-watch /usr/local/bin/fzf /usr/local/libexec/sbm/fzf.exe' Pop $0 ${If} $0 != 0 Abort "chmod failed with exit status $0" ${EndIf} - nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup' + nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup data' Pop $0 ${If} $0 != 0 Abort "sbm-setup failed with exit status $0" ${EndIf} + ; bm-import reads the bookmarks of a browser with jq. + ${IfNot} ${FileExists} "$Cygwin\bin\jq.exe" + MessageBox MB_ICONEXCLAMATION|MB_OK "The browser import needs jq.$\r$\nInstall the jq package with Cygwin setup." /SD IDOK + ${EndIf} + WriteUninstaller "$Cygwin\usr\local\libexec\sbm\uninstall.exe" SetShellVarContext current CreateShortcut /NoWorkingDir "$DESKTOP\sbm.lnk" "$Cygwin\bin\mintty.exe" \ "${MINTTYARGS}" "$Cygwin\bin\mintty.exe" 0 SW_SHOWNORMAL \ ALT|CONTROL|SHIFT|F24 "sbm: bookmarks in fzf" + CreateShortcut /NoWorkingDir "$SMPROGRAMS\sbm.lnk" "$Cygwin\bin\mintty.exe" \ + "${MINTTYARGS}" "$Cygwin\bin\mintty.exe" 0 SW_SHOWNORMAL "" \ + "sbm: bookmarks in fzf" + CreateShortcut /NoWorkingDir "$SMSTARTUP\sbm-watch.lnk" "$Cygwin\bin\mintty.exe" \ + '${WATCHARGS}' "$Cygwin\bin\mintty.exe" 0 SW_SHOWMINIMIZED "" \ + "sbm: bring new browser bookmarks into bm" + + ; Start bm-watch now. Explorer starts it as the user, not as the + ; administrator that runs this installer. + Exec '"$WINDIR\explorer.exe" "$SMSTARTUP\sbm-watch.lnk"' WriteRegStr HKLM "${UNINSTKEY}" "DisplayName" "sbm" WriteRegStr HKLM "${UNINSTKEY}" "DisplayVersion" "${VERSION}" @@ -123,6 +152,9 @@ Function un.onInit FunctionEnd Section Uninstall + nsExec::ExecToLog '"$Cygwin\bin\sh.exe" /usr/local/libexec/sbm/sbm-setup stop' + Pop $0 + Delete "$Cygwin\usr\local\bin\bm" Delete "$Cygwin\usr\local\bin\bm-check" Delete "$Cygwin\usr\local\bin\bm-commit" @@ -130,6 +162,7 @@ Section Uninstall Delete "$Cygwin\usr\local\bin\bm-import" Delete "$Cygwin\usr\local\bin\bm-migrate" Delete "$Cygwin\usr\local\bin\bm-title" + Delete "$Cygwin\usr\local\bin\bm-watch" Delete "$Cygwin\usr\local\bin\fzf" Delete "$Cygwin\usr\local\libexec\sbm\fzf.exe" Delete "$Cygwin\usr\local\libexec\sbm\fzf-LICENSE.txt" @@ -142,5 +175,7 @@ Section Uninstall Delete "$Cygwin\etc\profile.d\sbm.sh" SetShellVarContext current Delete "$DESKTOP\sbm.lnk" + Delete "$SMPROGRAMS\sbm.lnk" + Delete "$SMSTARTUP\sbm-watch.lnk" DeleteRegKey HKLM "${UNINSTKEY}" SectionEnd