Open stefnotch opened 6 months ago
Apparently there are webview libraries for Go, such as https://github.com/webview/webview_go and https://github.com/pojntfx/hydrapp . There are also a few others which either seem to be unmaintained, or which don't support important browsers.
Hey, just to clarify a bit -- is this a problem you're running into on Windows? An open issue is that Backrest's windows operations aren't very streamlined.
I'd happily accept community contributions to improve the state of things here, my windows knowledge isn't particular deep so it's not something I've been working on. Ideally Backrest should include an installer that runs the binary as a background service.
On MacOS / Linux the installer should already be setup to run the binary in the background (no visible window).
On the GUI front, this is another place where I'd happily accept community work to shim an electron app around Backrest as I can definitely understand the utility but probably it isn't a focus for me and isn't something I'm interested to maintain at the moment.
Yes, I'm running into this on Windows. If my target audience were tech-y enough to use Linux, then I'd just show them the restic CLI.
I suggested the webview option, because if such a library is mature enough, then using it is relatively simple, see https://github.com/webview/webview_go/blob/master/examples/basic/main.go . Of course that doesn't cover other parts that one might want, like a tray icon.
I'm interested in this for commercial reasons so we can definitely help with contributions if there's a consensus.
I don't think an "native app" really is required tho. In my opinion it's completely fine to open the default Webbrowser.
What's more important is a desktop shortcut that does that.
@aep I've gotten feedback from multiple people that apps which just open the webbrowser are somewhat disliked. They pretty much need a tray icon to tell the user that the app is still running, and to let the user close the app. It also looks very confusing when the user closes the app, but the website is still open. So one has to get the website to regularly check if the app is still running, and if not, the website has to show some sort of message. And then there's the tidbit about having to support weirder configurations, like a user who has NoScript or an overzealous adblocker installed.
Hence my request to use a webview library. They open an already installed and webbrowser as a separated window, with a separate profile, which makes them very lightweight and shockingly easy to integrate. And they avoid all the annoyances mentioned above.
Fully agree on the systray. That's a thing windows users expect.
Not sure about the wrapper app yet, but if someone else wants to pick that up why not. Currently considering if we can help with the installer first.
Sounds like a reasonable plan, improving the status quo one step at a time.
I wish I knew enough Go to quickly whip up a prototype, but I currently do not.
Hey all, just chiming in to say that community contributions re: a windows installer would be very welcome.
I think the right place to put the code for any contributions would be in a build
subfolder (following the rough example here https://github.com/golang-standards/project-layout/tree/master/build) and I should probably consolidate the Dockerfiles and other release related code in there.
There's a bug tracking an installer https://github.com/garethgeorge/backrest/issues/163 but I don't think any recent progress has been made. Ideally we are able to offer a simple binary that we can package with the release (given a PR adding a codegen for a windows installer I can easily add it to the release workflow). Feel free to chime in on that bug if it's something you're interested to take up.
Beyond that, I think I can see a system tray release as something worth supporting in this repo, I found https://github.com/getlantern/systray as a good option here. I think the way to go here would be a separate binary e.g. backrestmon
which is installed along with backrest and which forks and manages the backrest process (e.g. perhaps supporting a start / stop button? Backrest could be configured to write it's PID into a tmp file to support this) and provides a tray icon with a link that opens the backrest UI. In this model the backrestmon
binary is largely independent / doesn't need to share code with backrest. It's just an optional extra binary that can be included with the macOS and Windows releases along side the installer.
@ThaUnknown
@garethgeorge by far the easiest way to solve this is with nsis, I created a simple NSIS script for this, I think it's the best solution because it also can be compiled cross platform, as there are nsis compilers for linux.
However there are some key issues with this software on windows: it needs an always open CMD window to run, from a sysadmin perspective it's annoying, because if the user closes it, it kills the software, it would be nice if we could simply launch the software with some --as-service flag which simply runs it in background.
The script needs 2 dynamic changes, the build directory [where the files included in the build dist are stored], and the out dir [where the installer is outputted], those are configured in the first 2 lines. Additionally it also needs an icon in the build directory, which I also made based on the WebUI logo.
The NSIS script:
!define BUILD_DIR "D:\change_me"
!define OUT_DIR "D:\change_me_2"
!define APP_NAME "Backrest"
!define COMP_NAME "garethgeorge"
!define WEB_SITE "https://github.com/garethgeorge/backrest"
!define VERSION "00.00.00.00"
!define COPYRIGHT "garethgeorge 2024"
!define DESCRIPTION "Application"
!define LICENSE_TXT "${BUILD_DIR}\LICENSE.txt"
!define INSTALLER_NAME "${OUT_DIR}\Backrest-setup.exe"
!define MAIN_APP_EXE "backrest.exe"
!define INSTALL_TYPE "SetShellVarContext current"
!define REG_ROOT "HKCU"
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
!define REG_START_MENU "Start Menu Folder"
var SM_Folder
######################################################################
VIProductVersion "${VERSION}"
VIAddVersionKey "ProductName" "${APP_NAME}"
VIAddVersionKey "CompanyName" "${COMP_NAME}"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
VIAddVersionKey "FileVersion" "${VERSION}"
######################################################################
SetCompressor ZLIB
Name "${APP_NAME}"
Caption "${APP_NAME}"
OutFile "${INSTALLER_NAME}"
BrandingText "${APP_NAME}"
XPStyle on
InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
InstallDir "$PROGRAMFILES\Backrest"
######################################################################
!include "MUI.nsh"
!define MUI_ABORTWARNING
!define MUI_UNABORTWARNING
!insertmacro MUI_PAGE_WELCOME
!ifdef LICENSE_TXT
!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}"
!endif
!insertmacro MUI_PAGE_DIRECTORY
!ifdef REG_START_MENU
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Backrest"
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
!insertmacro MUI_PAGE_STARTMENU Application $SM_Folder
!endif
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN "$INSTDIR\${MAIN_APP_EXE}"
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
######################################################################
Section -MainProgram
${INSTALL_TYPE}
SetOverwrite ifnewer
SetOutPath "$INSTDIR"
File "${BUILD_DIR}\backrest.exe"
File "${BUILD_DIR}\CHANGELOG.md"
File "${BUILD_DIR}\LICENSE.txt"
File "${BUILD_DIR}\README.md"
SectionEnd
######################################################################
Section "Run at startup"
CreateDirectory $SMSTARTUP
CreateShortcut "$SMSTARTUP\$(^Name).lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "${BUILD_DIR}\icon.ico" 0
SectionEnd
Section -Icons_Reg
SetOutPath "$INSTDIR"
WriteUninstaller "$INSTDIR\uninstall.exe"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$SM_Folder"
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "${BUILD_DIR}\icon.ico" 0
CreateShortCut "$DESKTOP\${APP_NAME} Console.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "${BUILD_DIR}\icon.ico" 0
CreateShortCut "$DESKTOP\${APP_NAME} UI.lnk" "http://localhost:9898/" "" "${BUILD_DIR}\icon.ico" 0
CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe" "" "${BUILD_DIR}\icon.ico" 0
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url" "" "${BUILD_DIR}\icon.ico" 0
!endif
!insertmacro MUI_STARTMENU_WRITE_END
!endif
!ifndef REG_START_MENU
CreateDirectory "$SMPROGRAMS\Backrest"
CreateShortCut "$SMPROGRAMS\Backrest\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "${BUILD_DIR}\icon.ico" 0
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}" "" "${BUILD_DIR}\icon.ico" 0
CreateShortCut "$SMPROGRAMS\Backrest\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe" "" "${BUILD_DIR}\icon.ico" 0
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\Backrest\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url" "" "${BUILD_DIR}\icon.ico" 0
!endif
!endif
WriteRegStr ${REG_ROOT} "${REG_APP_PATH}" "" "$INSTDIR\${MAIN_APP_EXE}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayIcon" "$INSTDIR\${MAIN_APP_EXE}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}"
!ifdef WEB_SITE
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}"
!endif
SectionEnd
######################################################################
Section Uninstall
${INSTALL_TYPE}
Delete "$INSTDIR\backrest.exe"
Delete "$INSTDIR\CHANGELOG.md"
Delete "$INSTDIR\install.sh"
Delete "$INSTDIR\LICENSE.txt"
Delete "$INSTDIR\README.md"
Delete "$INSTDIR\uninstall.sh"
Delete "$INSTDIR\uninstall.exe"
Delete "$SMSTARTUP\$(^Name).lnk"
!ifdef WEB_SITE
Delete "$INSTDIR\${APP_NAME} website.url"
!endif
RmDir "$INSTDIR"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_GETFOLDER "Application" $SM_Folder
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk"
!endif
Delete "$DESKTOP\${APP_NAME}.lnk"
RmDir "$SMPROGRAMS\$SM_Folder"
!endif
!ifndef REG_START_MENU
Delete "$SMPROGRAMS\Backrest\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\Backrest\Uninstall ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\Backrest\${APP_NAME} Website.lnk"
!endif
Delete "$DESKTOP\${APP_NAME}.lnk"
RmDir "$SMPROGRAMS\Backrest"
!endif
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
SectionEnd
the icon: icon.zip
Another great possibility can be Wails. I'm thinking about making a try in the near future
@garethgeorge by far the easiest way to solve this is with nsis, I created a simple NSIS script for this, I think it's the best solution because it also can be compiled cross platform, as there are nsis compilers for linux.
This looks great, thanks for putting that install script (and icon) together! I can run forward with this to setup an installer for windows. I agree that I need to create a new windows build that doesn't open a console. I'll take a look at using https://github.com/getlantern/systray to provide a separate skew of the binary for windows that both opens a system tray icon to make it visible that it's running (and additionally hides it's console window).
Another great possibility can be Wails. I'm thinking about making a try in the near future
I'd be very interested to hear how that goes. I think Backrest should operate as a daemon irrespective of the GUI but a Wails GUI as a client for the daemon makes sense to me.
Started on integrating the installer and setting up a tray application in https://github.com/garethgeorge/backrest/pull/294/files. Using the tray app to fork backrest with the right options solves the console window problem.
Merged with a working first pass, the solution I landed on is
Tested the x86 binary and working nicely on my windows machine (I don't have an arm64 machine to test the other builds), preview binaries available on the CI/CD runs for the merged run:
@garethgeorge I noticed there's an issue in the build script i provided, all the icon shortcuts are wrong, instead of "${BUILD_DIR}\icon.ico"
they should be "$INSTDIR\icon.ico"
, I haven't checked if you fixed it in your binaries, didn't have time, sorry
No problem, it was a really good start point & worked with a few edits. I found and fixed that, thanks for calling it out. I did do some debugging / wrangling of the script to make it compatible with the setup the ci/cd pipeline needs.
1st I really like this project but to recommend it to mostly windows user there a couple considerations.
EDIT: Here is MSI (installer file) generating action scrip since you have .exe
files for running https://github.com/AliceOh/ExampleUseWindowsInstallerGithubAction
In the config it has shortcuts section, so if you add a shortcut to tray.exe to C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
it would launch automatically on every restart.
Fully agree on the systray. That's a thing windows users expect.
Not sure about the wrapper app yet, but if someone else wants to pick that up why not. Currently considering if we can help with the installer first.
Agreed, and I'd add even on Linux a system tray icon is appreciated for those of us using a desktop manager that supports it - e.g. KDE Plasma, GNOME, etc.
I'm interested in this for commercial reasons so we can definitely help with contributions if there's a consensus.
I don't think an "native app" really is required tho. In my opinion it's completely fine to open the default Webbrowser.
What's more important is a desktop shortcut that does that.
It's a chicken and egg problem: if apps keep reinforcing that only native apps are serious/trustworthy/etc. by de-emphasizing web UIs or making them secondary to native apps, users will continue to see them as second class; on the other hand, if enough apps push for web UIs to normalise that as equal to native apps, perceptions will change.
With the massive caveat that I'm a web and not native developer, I'd also recommend Neutron as an alternative to Electron if you want help chip away at Google's near monopoly: https://github.com/gamingdoom/neutron
To add on to this -- agreed with all of the points @Ambient-Impact impact makes :) . I think Backrest aims to stay a webUI as it's by far the easiest way to provide a good cross platform experience & focus on feature work instead of issues with platform ports.
Happy to discuss packaging if anyone is interested in porting the tray app to new platforms, it's not a priority on my road map at the moment but agree that it would be very nice to have.
Edit: on reflection, I'm not strongly opposed to an electron type wrapper if it can be done as a capability of the tray application (e.g. opening a chrome-less window instead of the system browser to display backrest?). Backrest itself will probably always be a daemon serving on a port however.
Note: if you have a question or want discussion please post in the discussions area.
Is your feature request related to a problem? Please describe.
I would like to be able to recommend backup programs, like restic/rustic to non-techy family members. This means that a GUI, like what backrest offers, is awesome.
However, it currently seems to not be designed to be a program where I can simply
Instead, it is
Describe the solution you'd like
Would it be reasonable to offer a variant of the GUI which comes with an embedded web browser? (e.g. Tauri or Electron) Then, it'd be possible for backrest to work like