Files
magpie/internal/gui/mainwindow.go
T
yetone 4a2f538c61 gui: lightweight mode, off by default, lets a closed panel's or window's webview go and makes it again when it is opened (somls on #580: GUI版可否增加轻量模式,关闭面板退出webview,减少资源占用) — closing the tray panel or the main window only hid it, so each kept its page and, on a Mac, its WebKit WebContent process (about 65 MB each at start, 95–100 MB after use) for as long as magpie ran. Settings → General now has Lightweight mode (轻量模式), shown in the app only (not on a browser's page) and kept as this computer's own through a sync or a restored backup (KeepOwn): with it on, a window found closed on two looks in a row 30 s apart (lightStep) is let go 30–60 s after it was closed, so a panel opened again soon after is still the same one at once. Letting go happens on the main thread under a new h.winMu: the window field is set to nil, the panel is unhooked from the tray icon (AttachWindow(nil); left click goes through magpie's own OnClick), and the main window is marked gone so its closing hook, which otherwise cancels a close and hides, lets it close; on the Mac the WKWebView is taken out of the window first (stopLoading, delegates and script handlers cleared, removed from its superview), since Wails' NSWindow close alone left the WebContent process alive for minutes. Opening it again (the tray icon, ShowMain, an import link, the Dock) makes the window anew with the options it was started with (makeMain/makePanel, moved out of Run with their hooks), its text size and title bar or Hyprland name (madeAgain), on Windows shown only once its page has loaded; every other path that reached h.main or h.panel (fit, tint, zoom, hide, glide, the Windows title-bar tint, the Hyprland click watch, the folder picker) now goes through the main thread and does nothing to a window let go; Linux keeps running with no window left (DisableQuitOnLastWindowClosed). Measured in a sandbox build under a temp HOME on other ports: started in the tray with the setting on, two WebContent processes of ~65 MB each; about a minute later both windows were let go and both processes ended (GPU and Networking, ~56 MB, are shared and stay; magpie's own process is unchanged), so the saving is ~130 MB idle and up to ~200 MB after use; the main window and the panel were then opened again with their pages, tinted and at the tray icon, closed, let go a second time, and magpie quit cleanly, with fit/tint/zoom calls every 0.2 s through a release crashing nothing. Windows and Linux build but were not run. TestLightStep and TestLightweightKeptAndOwn are new; lightweight.test.cjs (WebKit, en and zh: the row, off by default, On/Off posted as lightweight true/false, another setting's save keeping it, no scroll, no left-border accent, no row on a browser's page) is new and passes, as do click-scroll, settings-sections and searcher-pick. go vet ./internal/..., go build (darwin GUI), go build -tags nogui (darwin, GOOS=linux), GOOS=windows go build, go test -tags nogui -count=1 ./... under a temp HOME pass.
2026-10-03 00:24:49 +08:00

73 lines
2.2 KiB
Go

//go:build !nogui
package gui
import (
"time"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/yetone/magpie/internal/settings"
)
// mainMacWindow: the main window's Mac options. A window belongs to the
// Space it was last shown on, and showing it again takes the user there; one
// first shown while another app was full screen (a restart to update, with
// the user in that app) belonged to that app's Space from then on, and every
// Open went back to it. It moves to the Space the user is on whenever it is
// shown instead, and can still be made full screen itself.
func mainMacWindow() application.MacWindow {
return application.MacWindow{
// no InvisibleTitleBarHeight: that strip drags from anywhere in
// it, tabs included; the header marks what drags instead
TitleBar: application.MacTitleBarHiddenInset,
CollectionBehavior: application.MacWindowCollectionBehaviorMoveToActiveSpace |
application.MacWindowCollectionBehaviorFullScreenPrimary,
}
}
type closeAction int
const (
closeHide closeAction = iota // hide the window now
closeLeaveFullscreen // leave full screen, then hide it
)
// closeStep: what closing the main window does. A full-screen window on the
// Mac hidden as it is leaves its Space behind, black, with nothing in it; it
// leaves full screen first and is hidden once it has.
func closeStep(goos string, fullscreen bool) closeAction {
if goos == "darwin" && fullscreen {
return closeLeaveFullscreen
}
return closeHide
}
// hideMain hides the main window, and takes magpie out of the Dock if it is
// there only while the window is shown.
func (h *host) hideMain() {
application.InvokeSync(func() {
if h.main != nil {
h.main.Hide()
}
})
h.dock(settings.Load(), false)
}
// leaveFullscreenThenHide takes the closed full-screen window out of full
// screen; WindowDidExitFullScreen hides it. Should that never come (the
// system refused to leave), it is hidden after a while all the same.
func (h *host) leaveFullscreenThenHide() {
h.closing.Store(true)
application.InvokeSync(func() {
if h.main != nil {
h.main.UnFullscreen()
}
})
time.AfterFunc(3*time.Second, func() {
if h.closing.Swap(false) {
application.InvokeAsync(h.hideMain)
}
})
}