feat(qt): two Wallpaper background modes, with the desktop's picture or your own
"Dynamic background" gains "Wallpaper" and "Wallpaper, blurred". The picture is the desktop's wallpaper — Plasma's appletsrc (the containment on screen 0, image plugin only; a wallpaper package resolves to its largest bitmap, a slideshow folder to its first image), GNOME through gsettings (the dark variant under a dark scheme), Windows' current TranscodedWallpaper, macOS through System Events — or an image the user picks (Settings > Appearance > Background image), which outranks it. The resolved path and its mtime are memoised, so the frequent refreshes (session entry, a mode switch, the window coming to the front) republish nothing while the file holds. "Wallpaper, blurred" sends the picture through the same atmosphere pass Blurred art gives the cover, held still. "Wallpaper" shows the part of the wallpaper that lies behind the window, lightly blurred under the half-alpha chrome, at most a screen-sized texture: the window's place on the screen comes from Qt where the platform tells it (X11, macOS, Windows); Wayland hides window positions, so there the crop is centred until the Plasma window-management protocol is wired. Neither mode waits for a playing track. Six new strings in eight catalogs. cc
This commit is contained in:
1 parent
7167866286
commit
47b5c14d32
18 files changed
+825
-3
No files matched your search
@@ -121,6 +121,55 @@ Rectangle {
|
||||
opacity: root.veilStrength
|
||||
}
|
||||
|
||||
// Mode 3 — Wallpaper: the desktop wallpaper, the part of it that lies
|
||||
// BEHIND this window (where the platform tells the window its place:
|
||||
// X11, macOS, Windows — Wayland hides it, so a centred crop stands in),
|
||||
// lightly blurred under the half-alpha chrome. Static: it costs a frame
|
||||
// only when the window moves or resizes (shell/WallpaperField.qml).
|
||||
// Mode 4 — Wallpaper, blurred: the wallpaper through the SAME atmosphere
|
||||
// pass Blurred art gives the cover, held still (no transport to follow).
|
||||
// Neither waits for a playing track (QbzTheme.ambientOn).
|
||||
readonly property bool wallpaperModeOn: root.ambientOn && QbzShell.ambientMode === 3
|
||||
readonly property bool wallpaperBlurOn: root.ambientOn && QbzShell.ambientMode === 4
|
||||
WallpaperField {
|
||||
anchors.fill: parent
|
||||
visible: root.wallpaperModeOn
|
||||
source: root.wallpaperModeOn ? QbzShell.wallpaperUrl : ""
|
||||
hostWindow: root.hostWindow
|
||||
blur: 0.35
|
||||
dim: theme.isDark ? QbzShell.ambientDim : 0.0
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: root.wallpaperModeOn && !theme.isDark
|
||||
color: theme.surfaceMain
|
||||
opacity: root.veilStrength
|
||||
}
|
||||
ImmersiveAtmosphere {
|
||||
anchors.fill: parent
|
||||
visible: root.wallpaperBlurOn
|
||||
source: root.wallpaperBlurOn ? QbzShell.wallpaperAtmosphereUrl : ""
|
||||
animated: false
|
||||
dim: theme.isDark ? QbzShell.ambientDim : 0.0
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: root.wallpaperBlurOn && !theme.isDark
|
||||
color: theme.surfaceMain
|
||||
opacity: root.veilStrength
|
||||
}
|
||||
// The wallpaper can change while QBZ runs: re-resolve when the window
|
||||
// comes back to the front (wallpaper_qt memoises path + mtime, so a
|
||||
// wallpaper that did not change republishes nothing).
|
||||
Connections {
|
||||
target: root.hostWindow
|
||||
ignoreUnknownSignals: true
|
||||
function onActiveChanged() {
|
||||
if (root.hostWindow && root.hostWindow.active && QbzShell.ambientMode >= 3)
|
||||
QbzShell.refreshWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
// The host ApplicationWindow (custom chrome: drag / maximize / resize).
|
||||
property var hostWindow: null
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// WallpaperField — the desktop wallpaper behind the window (2026-09-14): the
|
||||
// part of it that lies UNDER this window, so moving the window slides the
|
||||
// picture the way a translucent window would, lightly blurred beneath the
|
||||
// half-alpha chrome. Nothing animates: it costs a frame only when the window
|
||||
// moves or resizes, and a screen-sized texture at most (`sourceSize` caps the
|
||||
// decode — a 3x-upscaled wallpaper never reaches the GPU whole).
|
||||
//
|
||||
// WHERE THE WINDOW IS. X11, macOS and Windows report the window's position;
|
||||
// Wayland hides it from clients by design, so there the crop is centred on
|
||||
// the screen until the Plasma window-management protocol is wired
|
||||
// (wallpaper_qt.rs header). `hostWindow` is the ApplicationWindow.
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Effects
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/// file:// URL of the wallpaper (QbzShell.wallpaperUrl).
|
||||
property string source: ""
|
||||
property var hostWindow: null
|
||||
/// MultiEffect blur amount, 0 = crisp.
|
||||
property real blur: 0.0
|
||||
/// Darkening on top (the dark-theme legibility veil).
|
||||
property real dim: 0.0
|
||||
|
||||
clip: true
|
||||
|
||||
readonly property bool positionKnown: root.hostWindow !== null
|
||||
&& Qt.platform.pluginName !== "wayland"
|
||||
readonly property real screenW: Math.max(1, Screen.width)
|
||||
readonly property real screenH: Math.max(1, Screen.height)
|
||||
// The window's origin inside its screen; centred when unknown.
|
||||
readonly property real offX: root.positionKnown
|
||||
? root.hostWindow.x - Screen.virtualX
|
||||
: Math.max(0, (root.screenW - root.width) / 2)
|
||||
readonly property real offY: root.positionKnown
|
||||
? root.hostWindow.y - Screen.virtualY
|
||||
: Math.max(0, (root.screenH - root.height) / 2)
|
||||
|
||||
Image {
|
||||
id: picture
|
||||
source: root.source
|
||||
x: -root.offX
|
||||
y: -root.offY
|
||||
width: root.screenW
|
||||
height: root.screenH
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
cache: false
|
||||
sourceSize.width: Math.round(root.screenW * Screen.devicePixelRatio)
|
||||
sourceSize.height: Math.round(root.screenH * Screen.devicePixelRatio)
|
||||
smooth: true
|
||||
}
|
||||
MultiEffect {
|
||||
visible: root.blur > 0 && picture.status === Image.Ready
|
||||
source: picture
|
||||
x: picture.x
|
||||
y: picture.y
|
||||
width: picture.width
|
||||
height: picture.height
|
||||
autoPaddingEnabled: false
|
||||
blurEnabled: true
|
||||
blur: root.blur
|
||||
blurMax: 48
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#000000"
|
||||
opacity: root.dim
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user