starplast.glass
Translucent black, rounded-corner windows: spaCR's glass on Starplast's palette.
Menus, tooltips, drop-down lists and Starplast's own dialogs are drawn as rounded panes of translucent black (translucent white on a light theme) rather than solid grey rectangles. This is the look spaCR already has, and the one the user asked for: "use the opacity, rounded corner windows whenever you can, black opacity is better than solid gray".
WHAT CAN BE MADE TRANSLUCENT, AND WHEN. A top-level window gets an alpha channel only if it asks for one BEFORE its native window exists; asking afterwards is silently ignored. Measured on this Qt:
- a menu, a tooltip and a combo box's drop-down list are polished before their native window is
created, so :class:
GlassStylecan dress every one of them, whoever built it, from the application style's polish hook; - a dialog is polished only after its native window exists, so a dialog cannot be dressed from the
style. :func:
dressis called on each window Starplast builds, before its first show. AQMessageBoxraised through Qt's static functions keeps its native frame and takes the black palette from the stylesheet instead of being rebuilt behind the user's back.
WITHOUT A COMPOSITOR, TRANSLUCENCY IS NOT AVAILABLE, and a translucent window there shows garbage or
black squares where its corners should be. :func:compositing_available asks the display: Wayland,
Windows and macOS always composite; on X11 the answer is whether anything owns the
_NET_WM_CM_S<screen> selection. When nothing composites, the same windows are drawn OPAQUE
near-black and their corners are cut with a window mask, which rounds them on any display. The
STARPLAST_TRANSLUCENT environment variable (0 or 1) overrides the check.
A dressed window has no title bar -- the rounded card is the window -- so :func:dress gives it back
what the title bar did: the title painted at the top, a close mark, dragging by the background, and
resizing from the edges. Escape still closes a dialog.
Whether top-level windows can be translucent on this display.
Decided once per process and cached: the answer only changes if the user starts or stops a compositor while Starplast is running, and a window already built keeps what it was built with.
:param refresh: ask the display again instead of using the cached answer.
A rounded rectangle as a region, for cutting a window's corners without a compositor.
Built at four times the size and scaled down, so the polygon Qt fills has enough points on each arc that the corner reads as a curve rather than as three steps.
The application style, unchanged, plus one thing: it dresses every popup as Qt polishes it.
One hook for the whole program rather than a line at every QMenu(...): menus are built all over
it -- the menu bar, the map's right-click menu, the category lists, the jobs panel -- and by Qt
itself for a combo box or a tooltip, and a look applied by hand is a look missing from the next.
A STYLE, NOT AN APPLICATION EVENT FILTER. A filter sees every event of every object, including
the ones a widget receives while it is being destroyed, and PyQt must wrap each of those objects
to hand it to Python -- which, for an object half torn down, crashed the process. It did, in the
suite, on every module that closes a window. polish is only ever called on a live widget, at
the moment it is about to need its style, which is exactly the moment wanted here.
Only popups whose native window does not exist yet are touched, which is every one of them the first time it is polished; one that already has a window is left as it is rather than rebuilt.
Make one popup translucent and frameless, or give it a rounded mask. True if dressed.
Must run before the popup's native window exists; afterwards the alpha channel cannot be added, so a created popup is left alone and False is returned.
Put the popup-dressing style under the application, once. Returns it, or None without an app.
The wrapped style is the platform's default -- what the application would have used anyway --
and the application palette is put back afterwards, because setStyle otherwise replaces it
with the style's standard palette and every palette-drawn colour would move.
The rounded body of a dressed window: translucent fill, a hairline rim, and the title.
A child laid BEHIND the window's own contents and kept at its size, holding no layout, so it cannot disturb one. It ignores the mouse; presses on it reach the window, which is what makes the background draggable.
Make a window Starplast built into a rounded glass card. True if it was dressed.
Call it after the window's layout exists and before its first show. A window already shown (its
native window exists) is left with its frame: the alpha channel cannot be added any more, and
rebuilding the native window under a visible dialog is how a dialog vanishes on some window
managers. Idempotent, and a window carrying the starplastNoGlass property is never touched.
:param window: a top-level QDialog or QMainWindow.
:param title: paint the window title in the top band (dropping the title bar would lose it).
:param closable: add a close mark in the top-right corner.
Whether a window or popup has been given the glass treatment.
Colour a widget's links with the theme's accent.
Qt's default link colour is a dark blue chosen for a white page; on black glass it is close to invisible, and a link nobody can see is a reference nobody follows.
A glass window carrying a passage of explanation, shown beside the map and returned.
Not modal: an explanation is read while looking at the thing it explains, and a modal box froze the map behind it -- the reason Preferences stopped being modal as well.