folio & halcyon: Use standardized containment config for settings

This switching Folio and Halcyon to define their settings as a
containment config so that it fits in with the other containment
options.

This removes the convoluted maze of nested settings windows due to
wrapping the containment settings with a custom settings window around
it.
This commit is contained in:
Devin Lin 2025-10-05 11:32:16 -04:00
parent 71f0cdd597
commit 3d8250c010
10 changed files with 421 additions and 560 deletions

View file

@ -18,6 +18,7 @@ plasma_add_applet(org.kde.plasma.mobile.homescreen.folio
qml/main.qml
qml/PlaceholderDelegate.qml
qml/WidgetDragItem.qml
qml/config.qml
CPP_SOURCES
applicationlistmodel.cpp
delegatetoucharea.cpp
@ -67,7 +68,7 @@ ecm_target_qml_sources(org.kde.plasma.mobile.homescreen.folio SOURCES
qml/settings/AppletListViewer.qml
qml/settings/SettingsButton.qml
qml/settings/SettingsComponent.qml
qml/settings/SettingsWindow.qml
qml/settings/ConfigGeneral.qml
PATH settings
)

View file

@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2025 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.configuration 2.0
/**
* Part of the applet/containment spec, config.qml defines the categories to show in the settings.
*/
ConfigModel {
ConfigCategory {
name: i18n("General")
icon: "go-home-symbolic"
source: "settings/ConfigGeneral.qml"
}
}

View file

@ -0,0 +1,312 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Controls as QQC2
import org.kde.kcmutils
import org.kde.kirigami as Kirigami
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.plasma.plasmoid
import '../delegate'
SimpleKCM {
id: page
property Folio.HomeScreen folio: Plasmoid.containment
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
FormCard.FormHeader {
title: i18n("Icons")
}
FormCard.FormCard {
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Item {
Layout.preferredHeight: folio.HomeScreenState.pageCellHeight
Layout.fillWidth: true
AbstractDelegate {
folio: page.folio
anchors.centerIn: parent
implicitHeight: folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
name: i18n("Application")
contentItem: DelegateAppIcon {
height: page.folio.FolioSettings.delegateIconSize
width: page.folio.FolioSettings.delegateIconSize
source: 'applications-system'
}
}
}
}
FormCard.FormCard {
id: iconsCard
readonly property bool isVerticalOrientation: folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RegularPosition ||
folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RotateUpsideDown
readonly property string numOfRowsText: i18n("Number of rows")
readonly property string numOfColumnsText: i18n("Number of columns")
FormCard.FormSpinBoxDelegate {
id: iconSizeSpinBox
label: i18n("Size of icons on homescreen")
from: 16
to: 128
value: folio.FolioSettings.delegateIconSize
onValueChanged: {
if (value !== folio.FolioSettings.delegateIconSize) {
folio.FolioSettings.delegateIconSize = value;
}
}
}
FormCard.FormSpinBoxDelegate {
id: rowsSpinBox
label: iconsCard.isVerticalOrientation ? iconsCard.numOfRowsText : iconsCard.numOfColumnsText
from: 3
to: 10
value: folio.FolioSettings.homeScreenRows
onValueChanged: {
if (value !== folio.FolioSettings.homeScreenRows) {
folio.FolioSettings.homeScreenRows = value;
}
}
}
FormCard.FormSpinBoxDelegate {
id: columnsSpinBox
label: iconsCard.isVerticalOrientation ? iconsCard.numOfColumnsText : iconsCard.numOfRowsText
from: 3
to: 10
value: folio.FolioSettings.homeScreenColumns
onValueChanged: {
if (value !== folio.FolioSettings.homeScreenColumns) {
folio.FolioSettings.homeScreenColumns = value;
}
}
}
}
FormCard.FormSectionText {
text: i18n("The rows and columns will swap depending on the screen rotation.")
}
FormCard.FormHeader {
title: i18n("Homescreen")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
id: showLabelsOnHomeScreen
text: i18n("Show labels on homescreen")
checked: folio.FolioSettings.showPagesAppLabels
onCheckedChanged: {
if (checked != folio.FolioSettings.showPagesAppLabels) {
folio.FolioSettings.showPagesAppLabels = checked;
}
}
}
FormCard.FormDelegateSeparator { above: showLabelsOnHomeScreen; below: showLabelsInFavourites }
FormCard.FormSwitchDelegate {
id: showLabelsInFavourites
text: i18n("Show labels in favorites bar")
checked: folio.FolioSettings.showFavouritesAppLabels
onCheckedChanged: {
if (checked != folio.FolioSettings.showFavouritesAppLabels) {
folio.FolioSettings.showFavouritesAppLabels = checked;
}
}
}
FormCard.FormDelegateSeparator { above: showLabelsInFavourites; below: lockLayout }
FormCard.FormSwitchDelegate {
id: lockLayout
text: i18n("Lock layout")
checked: folio.FolioSettings.lockLayout
onCheckedChanged: {
if (checked != folio.FolioSettings.lockLayout) {
folio.FolioSettings.lockLayout = checked;
}
}
}
FormCard.FormDelegateSeparator { above: lockLayout; below: pageTransitionCombobox }
FormCard.FormComboBoxDelegate {
id: pageTransitionCombobox
text: i18n("Page transition effect")
currentIndex: indexOfValue(folio.FolioSettings.pageTransitionEffect)
model: ListModel {
// we can't use i18n with ListElement
Component.onCompleted: {
append({"name": i18n("Slide"), "value": Folio.FolioSettings.SlideTransition});
append({"name": i18n("Cube"), "value": Folio.FolioSettings.CubeTransition});
append({"name": i18n("Fade"), "value": Folio.FolioSettings.FadeTransition});
append({"name": i18n("Stack"), "value": Folio.FolioSettings.StackTransition});
append({"name": i18n("Rotation"), "value": Folio.FolioSettings.RotationTransition});
// indexOfValue doesn't bind to model changes unfortunately, set currentIndex manually here
pageTransitionCombobox.currentIndex = pageTransitionCombobox.indexOfValue(folio.FolioSettings.pageTransitionEffect)
}
}
textRole: "name"
valueRole: "value"
onCurrentValueChanged: folio.FolioSettings.pageTransitionEffect = currentValue
}
FormCard.FormDelegateSeparator { above: pageTransitionCombobox; below: doubleTapToLockSwitch }
FormCard.FormSwitchDelegate {
id: doubleTapToLockSwitch
text: i18n("Double tap to lock device")
checked: folio.FolioSettings.doubleTapToLock
onCheckedChanged: {
if (checked != folio.FolioSettings.doubleTapToLock) {
folio.FolioSettings.doubleTapToLock = checked;
}
}
}
}
FormCard.FormHeader {
title: i18n("Favorites Bar")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
text: i18n("Show background")
checked: folio.FolioSettings.showFavouritesBarBackground
onCheckedChanged: {
if (checked !== folio.FolioSettings.showFavouritesBarBackground) {
folio.FolioSettings.showFavouritesBarBackground = checked;
}
}
}
}
FormCard.FormHeader {
title: i18nc("@title:group settings group", "Wallpaper")
}
FormCard.FormCard {
FormCard.FormComboBoxDelegate {
id: wallpaperBlurCombobox
text: i18n("Wallpaper blur effect")
model: [
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
]
textRole: "name"
valueRole: "value"
Component.onCompleted: {
currentIndex = indexOfValue(folio.FolioSettings.wallpaperBlurEffect);
}
onCurrentValueChanged: folio.FolioSettings.wallpaperBlurEffect = currentValue
}
}
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
Layout.bottomMargin: Kirigami.Units.gridUnit
FormCard.FormButtonDelegate {
id: exportSettings
text: i18n("Export layout")
icon.name: 'document-export'
onClicked: exportFileDialog.open()
}
FormCard.FormDelegateSeparator { above: exportSettings; below: importSettings }
FormCard.FormButtonDelegate {
id: importSettings
text: i18n("Import layout")
icon.name: 'document-import'
onClicked: importFileDialog.open()
}
}
}
data: [
FileDialog {
id: exportFileDialog
title: i18n("Export layout to")
fileMode: FileDialog.SaveFile
defaultSuffix: 'json'
nameFilters: ["JSON files (*.json)"]
onAccepted: {
console.log('saving layout to ' + selectedFile);
if (selectedFile) {
let status = folio.FolioSettings.saveLayoutToFile(selectedFile);
if (status) {
exportedSuccessfullyPrompt.open();
} else {
exportFailedPrompt.open();
}
}
}
},
FileDialog {
id: importFileDialog
title: i18n("Import layout from")
fileMode: FileDialog.OpenFile
nameFilters: ["JSON files (*.json)"]
onAccepted: {
console.log('about to load layout from ' + selectedFile);
confirmImportPrompt.open();
}
},
Kirigami.PromptDialog {
id: exportFailedPrompt
title: i18n("Export Status")
subtitle: i18n("Failed to export to %1", String(exportFileDialog.selectedFile).substring('file://'.length))
standardButtons: Kirigami.Dialog.Close
},
Kirigami.PromptDialog {
id: exportedSuccessfullyPrompt
title: i18n("Export Status")
subtitle: i18n("Homescreen layout exported successfully to %1", String(exportFileDialog.selectedFile).substring('file://'.length))
standardButtons: Kirigami.Dialog.Close
},
Kirigami.PromptDialog {
id: confirmImportPrompt
title: i18n("Confirm Import")
subtitle: i18n("This will overwrite your existing homescreen layout!")
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: folio.FolioSettings.loadLayoutFromFile(importFileDialog.selectedFile);
}
]
}

View file

@ -67,7 +67,7 @@ Item {
iconName: 'edit-image'
textLabel: i18n("Wallpapers")
onClicked: {
homeScreen.wallpaperSelectorTriggered();
root.homeScreen.wallpaperSelectorTriggered();
folio.HomeScreenState.closeSettingsView();
}
}
@ -76,9 +76,7 @@ Item {
iconName: 'settings-configure'
textLabel: i18n("Settings")
onClicked: {
// ensure that if the window is already opened, it gets raised to the top
settingsWindow.hide();
settingsWindow.showMaximized();
root.homeScreen.openConfigure()
}
}
@ -204,14 +202,4 @@ Item {
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
}
SettingsWindow {
id: settingsWindow
folio: root.folio
visible: false
onRequestConfigureMenu: {
homeScreen.openConfigure()
}
}
}

View file

@ -1,378 +0,0 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Controls as QQC2
import org.kde.kirigami 2.20 as Kirigami
import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import '../delegate'
Window {
id: root
property Folio.HomeScreen folio
flags: Qt.FramelessWindowHint
color: 'transparent'
onVisibleChanged: {
if (visible) {
opacityAnim.to = 1;
opacityAnim.restart();
}
}
onClosing: (close) => {
if (applicationItem.opacity !== 0) {
close.accepted = false;
opacityAnim.to = 0;
opacityAnim.restart();
}
}
signal requestConfigureMenu()
Kirigami.ApplicationItem {
id: applicationItem
anchors.fill: parent
opacity: 0
NumberAnimation on opacity {
id: opacityAnim
duration: Kirigami.Units.longDuration
easing.type: Easing.OutCubic
onFinished: {
if (applicationItem.opacity === 0) {
root.close();
}
}
}
scale: 0.7 + 0.3 * applicationItem.opacity
pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.ToolBar
pageStack.globalToolBar.showNavigationButtons: Kirigami.ApplicationHeaderStyle.NoNavigationButtons;
pageStack.initialPage: Kirigami.ScrollablePage {
id: page
opacity: applicationItem.opacity
titleDelegate: RowLayout {
QQC2.ToolButton {
Layout.leftMargin: -Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing
icon.name: "arrow-left"
onClicked: root.close()
}
Kirigami.Heading {
level: 1
text: page.title
}
}
title: i18n("Homescreen Settings")
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
FormCard.FormHeader {
title: i18n("Icons")
}
FormCard.FormCard {
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Item {
Layout.preferredHeight: folio.HomeScreenState.pageCellHeight
Layout.fillWidth: true
AbstractDelegate {
folio: root.folio
anchors.centerIn: parent
implicitHeight: folio.HomeScreenState.pageCellHeight
implicitWidth: folio.HomeScreenState.pageCellWidth
name: i18n("Application")
contentItem: DelegateAppIcon {
height: root.folio.FolioSettings.delegateIconSize
width: root.folio.FolioSettings.delegateIconSize
source: 'applications-system'
}
}
}
}
FormCard.FormCard {
id: iconsCard
readonly property bool isVerticalOrientation: folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RegularPosition ||
folio.HomeScreenState.pageOrientation === Folio.HomeScreenState.RotateUpsideDown
readonly property string numOfRowsText: i18n("Number of rows")
readonly property string numOfColumnsText: i18n("Number of columns")
FormCard.FormSpinBoxDelegate {
id: iconSizeSpinBox
label: i18n("Size of icons on homescreen")
from: 16
to: 128
value: folio.FolioSettings.delegateIconSize
onValueChanged: {
if (value !== folio.FolioSettings.delegateIconSize) {
folio.FolioSettings.delegateIconSize = value;
}
}
}
FormCard.FormSpinBoxDelegate {
id: rowsSpinBox
label: iconsCard.isVerticalOrientation ? iconsCard.numOfRowsText : iconsCard.numOfColumnsText
from: 3
to: 10
value: folio.FolioSettings.homeScreenRows
onValueChanged: {
if (value !== folio.FolioSettings.homeScreenRows) {
folio.FolioSettings.homeScreenRows = value;
}
}
}
FormCard.FormSpinBoxDelegate {
id: columnsSpinBox
label: iconsCard.isVerticalOrientation ? iconsCard.numOfColumnsText : iconsCard.numOfRowsText
from: 3
to: 10
value: folio.FolioSettings.homeScreenColumns
onValueChanged: {
if (value !== folio.FolioSettings.homeScreenColumns) {
folio.FolioSettings.homeScreenColumns = value;
}
}
}
}
FormCard.FormSectionText {
text: i18n("The rows and columns will swap depending on the screen rotation.")
}
FormCard.FormHeader {
title: i18n("Homescreen")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
id: showLabelsOnHomeScreen
text: i18n("Show labels on homescreen")
checked: folio.FolioSettings.showPagesAppLabels
onCheckedChanged: {
if (checked != folio.FolioSettings.showPagesAppLabels) {
folio.FolioSettings.showPagesAppLabels = checked;
}
}
}
FormCard.FormDelegateSeparator { above: showLabelsOnHomeScreen; below: showLabelsInFavourites }
FormCard.FormSwitchDelegate {
id: showLabelsInFavourites
text: i18n("Show labels in favorites bar")
checked: folio.FolioSettings.showFavouritesAppLabels
onCheckedChanged: {
if (checked != folio.FolioSettings.showFavouritesAppLabels) {
folio.FolioSettings.showFavouritesAppLabels = checked;
}
}
}
FormCard.FormDelegateSeparator { above: showLabelsInFavourites; below: lockLayout }
FormCard.FormSwitchDelegate {
id: lockLayout
text: i18n("Lock layout")
checked: folio.FolioSettings.lockLayout
onCheckedChanged: {
if (checked != folio.FolioSettings.lockLayout) {
folio.FolioSettings.lockLayout = checked;
}
}
}
FormCard.FormDelegateSeparator { above: lockLayout; below: pageTransitionCombobox }
FormCard.FormComboBoxDelegate {
id: pageTransitionCombobox
text: i18n("Page transition effect")
currentIndex: indexOfValue(folio.FolioSettings.pageTransitionEffect)
model: ListModel {
// we can't use i18n with ListElement
Component.onCompleted: {
append({"name": i18n("Slide"), "value": Folio.FolioSettings.SlideTransition});
append({"name": i18n("Cube"), "value": Folio.FolioSettings.CubeTransition});
append({"name": i18n("Fade"), "value": Folio.FolioSettings.FadeTransition});
append({"name": i18n("Stack"), "value": Folio.FolioSettings.StackTransition});
append({"name": i18n("Rotation"), "value": Folio.FolioSettings.RotationTransition});
// indexOfValue doesn't bind to model changes unfortunately, set currentIndex manually here
pageTransitionCombobox.currentIndex = pageTransitionCombobox.indexOfValue(folio.FolioSettings.pageTransitionEffect)
}
}
textRole: "name"
valueRole: "value"
onCurrentValueChanged: folio.FolioSettings.pageTransitionEffect = currentValue
}
FormCard.FormDelegateSeparator { above: pageTransitionCombobox; below: doubleTapToLockSwitch }
FormCard.FormSwitchDelegate {
id: doubleTapToLockSwitch
text: i18n("Double tap to lock device")
checked: folio.FolioSettings.doubleTapToLock
onCheckedChanged: {
if (checked != folio.FolioSettings.doubleTapToLock) {
folio.FolioSettings.doubleTapToLock = checked;
}
}
}
}
FormCard.FormHeader {
title: i18n("Favorites Bar")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
text: i18n("Show background")
checked: folio.FolioSettings.showFavouritesBarBackground
onCheckedChanged: {
if (checked !== folio.FolioSettings.showFavouritesBarBackground) {
folio.FolioSettings.showFavouritesBarBackground = checked;
}
}
}
}
FormCard.FormHeader {
title: i18nc("@title:group settings group", "Wallpaper")
}
FormCard.FormCard {
FormCard.FormComboBoxDelegate {
id: wallpaperBlurCombobox
text: i18n("Wallpaper blur effect")
model: [
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
]
textRole: "name"
valueRole: "value"
Component.onCompleted: {
currentIndex = indexOfValue(folio.FolioSettings.wallpaperBlurEffect);
dialog.parent = root;
}
onCurrentValueChanged: folio.FolioSettings.wallpaperBlurEffect = currentValue
}
}
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
Layout.bottomMargin: Kirigami.Units.gridUnit
FormCard.FormButtonDelegate {
id: containmentSettings
text: i18nc("@action:button", "Switch between homescreens and more wallpaper options")
icon.name: 'settings-configure'
onClicked: root.requestConfigureMenu()
}
FormCard.FormDelegateSeparator { above: containmentSettings; below: exportSettings }
FormCard.FormButtonDelegate {
id: exportSettings
text: i18n("Export layout")
icon.name: 'document-export'
onClicked: exportFileDialog.open()
}
FormCard.FormDelegateSeparator { above: exportSettings; below: importSettings }
FormCard.FormButtonDelegate {
id: importSettings
text: i18n("Import layout")
icon.name: 'document-import'
onClicked: importFileDialog.open()
}
}
}
FileDialog {
id: exportFileDialog
title: i18n("Export layout to")
fileMode: FileDialog.SaveFile
defaultSuffix: 'json'
nameFilters: ["JSON files (*.json)"]
onAccepted: {
console.log('saving layout to ' + selectedFile);
if (selectedFile) {
let status = folio.FolioSettings.saveLayoutToFile(selectedFile); if (status) {
exportedSuccessfullyPrompt.open();
} else {
exportFailedPrompt.open();
}
}
}
}
FileDialog {
id: importFileDialog
title: i18n("Import layout from")
fileMode: FileDialog.OpenFile
nameFilters: ["JSON files (*.json)"]
onAccepted: {
console.log('about to load layout from ' + selectedFile);
confirmImportPrompt.open();
}
}
Kirigami.PromptDialog {
id: exportFailedPrompt
title: i18n("Export Status")
subtitle: i18n("Failed to export to %1", String(exportFileDialog.selectedFile).substring('file://'.length))
standardButtons: Kirigami.Dialog.Close
}
Kirigami.PromptDialog {
id: exportedSuccessfullyPrompt
title: i18n("Export Status")
subtitle: i18n("Homescreen layout exported successfully to %1", String(exportFileDialog.selectedFile).substring('file://'.length))
standardButtons: Kirigami.Dialog.Close
}
Kirigami.PromptDialog {
id: confirmImportPrompt
title: i18n("Confirm Import")
subtitle: i18n("This will overwrite your existing homescreen layout!")
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
onAccepted: folio.FolioSettings.loadLayoutFromFile(importFileDialog.selectedFile);
}
}
}
}

View file

@ -15,6 +15,7 @@ plasma_add_applet(org.kde.plasma.mobile.homescreen.halcyon
qml/HomeScreen.qml
qml/main.qml
qml/SearchWidget.qml
qml/config.qml
CPP_SOURCES
application.cpp
applicationfolder.cpp
@ -27,7 +28,7 @@ plasma_add_applet(org.kde.plasma.mobile.homescreen.halcyon
ecm_target_qml_sources(org.kde.plasma.mobile.homescreen.halcyon SOURCES
qml/settings/SettingsScreen.qml
qml/settings/SettingsWindow.qml
qml/settings/ConfigGeneral.qml
PATH settings
)

View file

@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2025 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.configuration 2.0
/**
* Part of the applet/containment spec, config.qml defines the categories to show in the settings.
*/
ConfigModel {
ConfigCategory {
name: i18n("General")
icon: "go-home-symbolic"
source: "settings/ConfigGeneral.qml"
}
}

View file

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2023-2025 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Controls as QQC2
import org.kde.plasma.plasmoid
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
Kirigami.ScrollablePage {
id: page
title: i18n("Homescreen Settings")
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
FormCard.FormHeader {
title: i18n("Homescreen")
}
FormCard.FormCard {
FormCard.FormComboBoxDelegate {
id: wallpaperBlurCombobox
text: i18n("Wallpaper blur effect")
model: [
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
]
textRole: "name"
valueRole: "value"
Component.onCompleted: {
currentIndex = indexOfValue(Plasmoid.settings.wallpaperBlurEffect);
dialog.parent = root;
}
onCurrentValueChanged: Plasmoid.settings.wallpaperBlurEffect = currentValue
}
FormCard.FormDelegateSeparator { above: wallpaperBlurCombobox; below: doubleTapToSleepSwitch }
FormCard.FormSwitchDelegate {
id: doubleTapToSleepSwitch
text: i18n("Double tap to lock device")
checked: Plasmoid.settings.doubleTapToLock
onCheckedChanged: {
if (checked != Plasmoid.settings.doubleTapToLock) {
Plasmoid.settings.doubleTapToLock = checked;
}
}
}
}
}
}

View file

@ -103,36 +103,9 @@ Item {
onClicked: {
root.homeScreen.settingsOpen = false;
if (settingsWindowLoader.active) {
// Ensure that if the window is already opened, it gets raised to the top
settingsWindowLoader.item.hide();
settingsWindowLoader.item.showMaximized();
} else {
settingsWindowLoader.active = true;
}
root.homeScreen.openContainmentSettings();
}
}
}
}
// Only load settings window when visible
Loader {
id: settingsWindowLoader
asynchronous: true
active: false
onLoaded: item.showMaximized();
sourceComponent: SettingsWindow {
onVisibleChanged: {
if (!visible) {
settingsWindowLoader.active = false;
}
}
onRequestConfigureMenu: {
root.homeScreen.openContainmentSettings();
}
}
}
}

View file

@ -1,138 +0,0 @@
// SPDX-FileCopyrightText: 2023-2025 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Dialogs
import QtQuick.Controls as QQC2
import org.kde.plasma.plasmoid
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
Window {
id: root
flags: Qt.FramelessWindowHint
color: 'transparent'
onVisibleChanged: {
if (visible) {
opacityAnim.to = 1;
opacityAnim.restart();
}
}
onClosing: (close) => {
if (applicationItem.opacity !== 0) {
close.accepted = false;
opacityAnim.to = 0;
opacityAnim.restart();
}
}
signal requestConfigureMenu()
Kirigami.ApplicationItem {
id: applicationItem
anchors.fill: parent
opacity: 0
NumberAnimation on opacity {
id: opacityAnim
duration: Kirigami.Units.longDuration
easing.type: Easing.OutCubic
onFinished: {
if (applicationItem.opacity === 0) {
root.close();
}
}
}
scale: 0.7 + 0.3 * applicationItem.opacity
pageStack.globalToolBar.style: Kirigami.ApplicationHeaderStyle.ToolBar
pageStack.globalToolBar.showNavigationButtons: Kirigami.ApplicationHeaderStyle.NoNavigationButtons;
pageStack.initialPage: Kirigami.ScrollablePage {
id: page
opacity: applicationItem.opacity
titleDelegate: RowLayout {
QQC2.ToolButton {
Layout.leftMargin: -Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing
icon.name: "arrow-left"
onClicked: root.close()
}
Kirigami.Heading {
level: 1
text: page.title
}
}
title: i18n("Homescreen Settings")
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
FormCard.FormHeader {
title: i18n("Homescreen")
}
FormCard.FormCard {
FormCard.FormComboBoxDelegate {
id: wallpaperBlurCombobox
text: i18n("Wallpaper blur effect")
model: [
{"name": i18nc("Wallpaper blur effect", "None"), "value": 0},
{"name": i18nc("Wallpaper blur effect", "Simple"), "value": 1},
{"name": i18nc("Wallpaper blur effect", "Full"), "value": 2}
]
textRole: "name"
valueRole: "value"
Component.onCompleted: {
currentIndex = indexOfValue(Plasmoid.settings.wallpaperBlurEffect);
dialog.parent = root;
}
onCurrentValueChanged: Plasmoid.settings.wallpaperBlurEffect = currentValue
}
FormCard.FormDelegateSeparator { above: wallpaperBlurCombobox; below: doubleTapToSleepSwitch }
FormCard.FormSwitchDelegate {
id: doubleTapToSleepSwitch
text: i18n("Double tap to lock device")
checked: Plasmoid.settings.doubleTapToLock
onCheckedChanged: {
if (checked != Plasmoid.settings.doubleTapToLock) {
Plasmoid.settings.doubleTapToLock = checked;
}
}
}
}
FormCard.FormCard {
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.bottomMargin: Kirigami.Units.gridUnit
FormCard.FormButtonDelegate {
id: containmentSettings
text: i18nc("@action:button", "Switch between homescreens and more wallpaper options")
icon.name: 'settings-configure'
onClicked: root.requestConfigureMenu()
}
}
}
}
}
}