desktop

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package desktop is Exhale installed as a desktop app (ADR 0029, 0030, 0032). Opening the app makes sure the server runs in the background, as the person who opened it and from the next login on, then shows the web UI in a window of its own (package window), or in the browser where there is none. The window's process also shows Exhale's icon in the menu bar or tray, from login on too; its menu is built here (menubar.go).

Index

Constants

View Source
const (
	ActOpen    = "open"    // show the window, at Path
	ActStart   = "start"   // keep awake for Minutes (0: until stopped)
	ActExtend  = "extend"  // add Minutes to the session
	ActStop    = "stop"    // end the session
	ActLid     = "lid"     // keep going with the lid closed: On
	ActOnPower = "onPower" // only while plugged in: On
	ActQuit    = "quit"    // end the icon and the window, not the server
)

Menu actions.

View Source
const BackgroundFlag = "--background"

BackgroundFlag is the flag of `exhale open` and exhale-window that starts only the icon, with the window hidden: what runs at login.

View Source
const ID = "io.github.akamachinecode.exhale"

ID names Exhale to the operating system: the bundle identifier of the macOS app and the label of its launchd agent (as in deploy/launchd).

View Source
const MenuBarID = ID + ".menubar"

MenuBarID labels the launchd agent that starts the menu bar icon.

View Source
const TokenFile = "desktop-token"

TokenFile is the file, in the data directory, where the server keeps the menu bar icon's token (auth.DesktopTokenFile).

View Source
const VersionHeader = "X-Exhale-Version"

VersionHeader carries the server's version in the answer of /healthz, so an upgraded app can tell that an older server is still running.

Variables

View Source
var ErrNoToken = errors.New("menu bar: no token to read Exhale with")

ErrNoToken is a menu bar icon that cannot read the API yet: the server has no owner (a new install), or its data directory is not this person's (the Linux system service). The icon shows what it can and tries again.

Functions

func DefaultLogFile

func DefaultLogFile(dataDir string) string

DefaultLogFile is the log of a server started without a terminal.

func HasWindow added in v0.4.0

func HasWindow(exe string) bool

HasWindow reports whether exhale-window is installed next to exe.

func IconPNG added in v0.4.0

func IconPNG(size int, template, awake bool) []byte

IconPNG draws the icon: size pixels square, as a template image (black on transparent) or on the gradient tile, with the dot when awake.

func SystemLanguage added in v0.4.0

func SystemLanguage() string

SystemLanguage is the person's language, of those Exhale speaks.

Types

type App

type App struct {
	Exe     string // this program, with symlinks resolved
	Listen  string // address the server listens on, as given to serve
	Version string // version of this program
	DataDir string // the server's data directory
	LogFile string // where a server started from here writes its log
	// Login is set in the desktop builds (Exhale.app, Exhale.exe): they
	// also make Exhale start when the person logs in.
	Login bool
	// Window shows the web UI in a window of its own, with the icon; with
	// background, only the icon. It is set in builds with the desktop tag;
	// without it, a window program next to this one (exhale-window in the
	// Linux packages) is used, or else the browser.
	Window func(url string, background bool) error
	// Browser opens the browser even where there is a window.
	Browser bool
	// Background starts only the icon, with the window hidden (at login).
	// Nothing is shown when the server cannot start: the icon says so.
	Background bool
}

App is this program, about to be opened.

func (App) Open

func (a App) Open(ctx context.Context) error

Open shows the web UI, first starting the server in the background when it does not answer.

type Client added in v0.4.0

type Client struct {
	Base    string // the web UI, http://127.0.0.1:8484
	DataDir string // where the token file is
	HTTP    *http.Client
}

Client talks to the local server for the menu bar icon.

func (*Client) Glance added in v0.4.0

func (c *Client) Glance(ctx context.Context, limit int) (Glance, error)

Glance reads the next charges and the keep-awake status.

func (*Client) Session added in v0.4.0

func (c *Client) Session(ctx context.Context, action string, minutes int) error

Session starts (minutes 0: until stopped), extends or stops a session that keeps the computer awake now.

func (*Client) SetKeepAwake added in v0.4.0

func (c *Client) SetKeepAwake(ctx context.Context, fields map[string]any) error

SetKeepAwake changes the fields given, such as lidClosed or onlyOnPower.

func (*Client) SetupLid added in v0.4.0

func (c *Client) SetupLid(ctx context.Context) error

SetupLid asks the computer for the permission to keep it awake with its lid closed: on a Mac the server shows the administrator's password dialog, so this waits for the person.

type Glance added in v0.4.0

type Glance struct {
	Language  string         `json:"language"`
	Today     string         `json:"today"`
	Charges   []GlanceCharge `json:"charges"`
	Totals    []string       `json:"totals"`
	Overdue   int            `json:"overdue"`
	KeepAwake KeepAwake      `json:"keepAwake"`
}

Glance is what GET /api/v1/glance answers (app.Glance).

type GlanceCharge added in v0.4.0

type GlanceCharge struct {
	SubscriptionID string `json:"subscriptionId"`
	Name           string `json:"name"`
	Amount         string `json:"amount"`
	Date           string `json:"date"`
	DaysUntil      int    `json:"daysUntil"`
	Kind           string `json:"kind"` // renewal, trial or expiry
}

GlanceCharge is one of the next charges, its amount already written.

type KeepAwake added in v0.4.0

type KeepAwake struct {
	Mode        string `json:"mode"`
	From        string `json:"from"`
	To          string `json:"to"`
	LidClosed   bool   `json:"lidClosed"`
	OnlyOnPower bool   `json:"onlyOnPower"`
	Session     struct {
		Active bool   `json:"active"`
		Until  string `json:"until"`
	} `json:"session"`
	Status struct {
		State  string `json:"state"`
		Reason string `json:"reason"`
		Until  string `json:"until"`
		Lid    string `json:"lid"`
		Power  struct {
			HasBattery bool `json:"hasBattery"`
			OnBattery  bool `json:"onBattery"`
			Percent    int  `json:"percent"`
		} `json:"power"`
	} `json:"status"`
}

KeepAwake is the keep-awake setting with its status (app.KeepAwakeInfo).

type Menu struct {
	Items   []MenuItem
	Tooltip string
	Awake   bool
}

Menu is the whole menu, with the icon's tooltip and whether the icon shows the computer kept awake.

func BuildMenu added in v0.4.0

func BuildMenu(in MenuInput) Menu

BuildMenu builds the menu from a glance.

type MenuAction struct {
	Kind    string
	Path    string // ActOpen: where in the web UI
	Minutes int    // ActStart, ActExtend
	On      bool   // ActLid, ActOnPower: the new value
	Setup   bool   // ActLid: ask the computer for the permission after turning it on
}

MenuAction is what clicking an item does.

type MenuInput struct {
	Glance *Glance // nil while the API cannot be read
	Lang   string  // the language when there is no glance
	Now    time.Time
	OS     string // runtime.GOOS: the words for the icon differ
}

MenuInput is what the menu is built from.

type MenuItem struct {
	Label     string
	Separator bool
	Enabled   bool
	Check     bool // a checkbox, ticked when Checked
	Checked   bool
	Action    MenuAction
	Items     []MenuItem // a submenu
}

MenuItem is one row of the menu.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL