shift-shell/components/mobileshell/qml/components/StartupFeedbackWindows.qml
Devin Lin 3ce21b972e startupfeedback: Always tint background with theme color
Currently with a light theme, often colors calculated from icons are incredible bright and vivid. This can cause the user to be flashed all of a sudden with a bright color when launching an app. This commit adopt the dark background blending scheme for all usecases.
2025-10-08 21:49:10 -04:00

227 lines
8.8 KiB
QML

// SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
import QtQuick
import QtQuick.Effects
import org.kde.kirigami as Kirigami
import org.kde.plasma.components 3.0 as PC3
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
Item {
id: root
property int screen
property real topMargin
property real bottomMargin
property real leftMargin
property real rightMargin
onScreenChanged: {
repeater.model.setFilterFixedString(root.screen);
}
Component.onCompleted: {
repeater.model.setFilterFixedString(root.screen);
}
Repeater {
id: repeater
model: MobileShellState.StartupFeedbackFilterModel {
startupFeedbackModel: MobileShellState.ShellDBusObject.startupFeedbackModel
}
delegate: Item {
Window {
id: window
property var startupFeedback: model.delegate
visibility: Window.Maximized
flags: Qt.FramelessWindowHint
color: 'transparent'
title: startupFeedback.title
Component.onCompleted: {
// root is anchored to the homescreen which fills up the whole screen,
// but the startup feedback window will have margins (ex. status bar)
const realHeight = root.height - root.topMargin - root.bottomMargin;
const realWidth = root.width - root.leftMargin - root.rightMargin;
iconParent.scale = startupFeedback.iconSize / iconParent.width;
background.scale = 0;
if (startupFeedback.iconStartX === -1 && startupFeedback.iconStartY === -1) {
backgroundParent.x = 0;
backgroundParent.y = 0;
} else {
backgroundParent.x = -realWidth/2 + startupFeedback.iconStartX - root.leftMargin;
backgroundParent.y = -realHeight/2 + startupFeedback.iconStartY - root.topMargin;
}
if (ShellSettings.Settings.animationsEnabled) {
openAnimComplex.restart();
} else {
openAnimSimple.restart();
}
}
// animation that moves the icon
SequentialAnimation {
id: openAnimComplex
// pause for background color to catch up
PauseAnimation { duration: 1 }
ParallelAnimation {
id: parallelAnim
property real animationDuration: Kirigami.Units.longDuration
ScaleAnimator {
target: background
from: background.scale
to: 1
duration: parallelAnim.animationDuration
easing.type: Easing.InOutQuad
}
ScaleAnimator {
target: iconParent
from: iconParent.scale
to: 1
duration: parallelAnim.animationDuration
easing.type: Easing.InOutQuad
}
XAnimator {
target: backgroundParent
from: backgroundParent.x
to: 0
duration: parallelAnim.animationDuration
easing.type: Easing.InOutQuad
}
YAnimator {
target: backgroundParent
from: backgroundParent.y
to: 0
duration: parallelAnim.animationDuration
easing.type: Easing.InOutQuad
}
}
ScriptAction {
script: {
// Animation has finished, trigger event for panels to update color
MobileShellState.ShellDBusClient.triggerAppLaunchMaximizePanelAnimation(root.screen, background.color);
// close the app drawer after it isn't visible
MobileShellState.ShellDBusClient.resetHomeScreenPosition();
}
}
}
// animation that just fades in
SequentialAnimation {
id: openAnimSimple
ScriptAction {
script: {
background.scale = 1;
iconParent.scale = 1;
backgroundParent.x = 0;
backgroundParent.y = 0;
}
}
NumberAnimation {
target: windowRoot
properties: "opacity"
from: 0
to: 1
duration: Kirigami.Units.longDuration
easing.type: Easing.OutCubic
}
ScriptAction {
script: {
// Animation has finished, trigger event for panels to update color
MobileShellState.ShellDBusClient.triggerAppLaunchMaximizePanelAnimation(root.screen, background.color);
// close the app drawer after it isn't visible
MobileShellState.ShellDBusClient.resetHomeScreenPosition();
}
}
}
Item {
id: windowRoot
anchors.fill: parent
Item {
id: backgroundParent
width: windowRoot.width
height: windowRoot.height
Rectangle {
id: background
anchors.fill: parent
// Tint the background color so that it is less prominent
// This avoids flashing the user all of a sudden with bright colors
color: Kirigami.ColorUtils.tintWithAlpha(colorGenerator.dominant, Kirigami.Theme.backgroundColor, 0.7)
Kirigami.ImageColors {
id: colorGenerator
source: icon.source
}
}
Item {
id: iconParent
anchors.centerIn: background
width: Kirigami.Units.iconSizes.enormous
height: Kirigami.Units.iconSizes.enormous
Kirigami.Icon {
id: icon
anchors.fill: parent
source: window.startupFeedback.iconName
}
MultiEffect {
anchors.fill: icon
source: icon
shadowEnabled: true
blurMax: 16
shadowColor: "#80000000"
}
Timer {
running: true
interval: 2000
onTriggered: loadingIndicator.opacity = 1
}
// Show loading indicator after two seconds have passed
PC3.BusyIndicator {
id: loadingIndicator
anchors.top: icon.bottom
anchors.horizontalCenter: icon.horizontalCenter
anchors.topMargin: Kirigami.Units.gridUnit
opacity: 0
Behavior on opacity {
NumberAnimation {}
}
implicitHeight: Kirigami.Units.iconSizes.smallMedium
implicitWidth: Kirigami.Units.iconSizes.smallMedium
}
}
}
}
}
}
}
}