Commit cbef8e66 authored by Noah Davis's avatar Noah Davis 🌵 Committed by Nate Graham
Browse files

Move plasmoid specific properties out of singleton

BUG: 443131
parent b00d93e3
......@@ -7,23 +7,26 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
pragma Singleton
pragma Singleton // NOTE: Singletons are shared between all instances of a plasmoid
import QtQuick 2.15
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 2.0 as PC2 // for Menu + MenuItem
import "code/tools.js" as Tools
Item {
id: root
property var actionList: menu.visualParent ? menu.visualParent.actionList : null
// Workaround for `plasmoid` context property not working in singletons
readonly property var plasmoid: KickoffSingleton.plasmoid
// Workaround for `plasmoid` context property not working in singletons.
// Only one action menu can be open at a time, so this should be safe to use.
property Plasmoid plasmoid: null
// Not a QQC1 Menu. It's actually a custom QObject that uses a QMenu.
readonly property PC2.Menu menu: PC2.Menu {
id: menu
visualParent: root.parent
visualParent: null
placement: PlasmaCore.Types.BottomPosedLeftAlignedPopup
}
......
......@@ -16,7 +16,7 @@ BasePage {
sideBarComponent: KickoffListView {
id: sideBar
focus: true // needed for Loaders
model: KickoffSingleton.rootModel
model: plasmoid.rootItem.rootModel
delegate: KickoffItemDelegate {
id: itemDelegate
extendHoverMargins: true
......@@ -32,7 +32,7 @@ BasePage {
readonly property Component preferredAppsViewComponent: plasmoid.configuration.applicationsDisplay == 0 ? applicationsGridViewComponent : applicationsListViewComponent
// NOTE: The 0 index modelForRow isn't supposed to be used. That's just how it works.
property int appsModelRow: 1
readonly property Kicker.AppsModel appsModel: KickoffSingleton.rootModel.modelForRow(appsModelRow)
readonly property Kicker.AppsModel appsModel: plasmoid.rootItem.rootModel.modelForRow(appsModelRow)
focus: true
initialItem: preferredFavoritesViewComponent
......@@ -43,7 +43,7 @@ BasePage {
objectName: "favoritesListView"
mainContentView: true
focus: true
model: KickoffSingleton.rootModel.favoritesModel
model: plasmoid.rootItem.rootModel.favoritesModel
}
}
......@@ -53,7 +53,7 @@ BasePage {
id: favoritesGridView
objectName: "favoritesGridView"
focus: true
model: KickoffSingleton.rootModel.favoritesModel
model: plasmoid.rootItem.rootModel.favoritesModel
}
}
......@@ -115,7 +115,7 @@ BasePage {
target: plasmoid
function onExpandedChanged() {
if(!plasmoid.expanded) {
KickoffSingleton.contentArea.currentItem.forceActiveFocus()
plasmoid.rootItem.contentArea.currentItem.forceActiveFocus()
}
}
}
......@@ -124,14 +124,14 @@ BasePage {
// StackView.status and visible. This way the bindings are reset when
// NormalPage is Activated again.
Binding {
target: KickoffSingleton
target: plasmoid.rootItem
property: "sideBar"
value: root.sideBarItem
when: root.T.StackView.status === T.StackView.Active && root.visible
restoreMode: Binding.RestoreBinding
}
Binding {
target: KickoffSingleton
target: plasmoid.rootItem
property: "contentArea"
value: root.contentAreaItem.currentItem // NOT just root.contentAreaItem
when: root.T.StackView.status === T.StackView.Active && root.visible
......
......@@ -59,8 +59,8 @@ FocusScope {
// backtab is implicitly set by the last button in Header.qml
KeyNavigation.tab: root.contentAreaItem
KeyNavigation.right: contentAreaLoader
Keys.onUpPressed: KickoffSingleton.header.nextItemInFocusChain().forceActiveFocus(Qt.BacktabFocusReason)
Keys.onDownPressed: KickoffSingleton.footer.tabBar.forceActiveFocus(Qt.TabFocusReason)
Keys.onUpPressed: plasmoid.rootItem.header.nextItemInFocusChain().forceActiveFocus(Qt.BacktabFocusReason)
Keys.onDownPressed: plasmoid.rootItem.footer.tabBar.forceActiveFocus(Qt.TabFocusReason)
}
}
PlasmaCore.SvgItem {
......@@ -86,9 +86,9 @@ FocusScope {
}
KeyNavigation.backtab: root.sideBarItem
// Tab should go to the start of the footer focus chain
KeyNavigation.tab: KickoffSingleton.footer.nextItemInFocusChain()
KeyNavigation.tab: plasmoid.rootItem.footer.nextItemInFocusChain()
KeyNavigation.left: sideBarLoader
Keys.onUpPressed: KickoffSingleton.searchField.forceActiveFocus(Qt.BacktabFocusReason)
Keys.onDownPressed: KickoffSingleton.footer.leaveButtons.nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
Keys.onUpPressed: plasmoid.rootItem.searchField.forceActiveFocus(Qt.BacktabFocusReason)
Keys.onDownPressed: plasmoid.rootItem.footer.leaveButtons.nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
}
}
......@@ -34,8 +34,8 @@ PlasmaExtras.PlasmoidHeading {
contentHeight: leaveButtons.implicitHeight
// We use an increased vertical padding to improve touch usability
leftPadding: KickoffSingleton.leftPadding
rightPadding: KickoffSingleton.rightPadding
leftPadding: plasmoid.rootItem.backgroundMetrics.leftPadding
rightPadding: plasmoid.rootItem.backgroundMetrics.rightPadding
topPadding: PlasmaCore.Units.smallSpacing*2
bottomPadding: PlasmaCore.Units.smallSpacing*2
......@@ -44,7 +44,7 @@ PlasmaExtras.PlasmoidHeading {
topInset: 0
bottomInset: 0
spacing: KickoffSingleton.spacing
spacing: plasmoid.rootItem.backgroundMetrics.spacing
position: PC3.ToolBar.Footer
PC3.TabBar {
......@@ -107,7 +107,7 @@ PlasmaExtras.PlasmoidHeading {
icon.height: PlasmaCore.Units.iconSizes.smallMedium
icon.name: "applications-other"
text: i18n("Applications")
KeyNavigation.backtab: KickoffSingleton.contentArea ? KickoffSingleton.contentArea : null
KeyNavigation.backtab: plasmoid.rootItem.contentArea ? plasmoid.rootItem.contentArea : null
}
PC3.TabButton {
id: placesTab
......@@ -161,7 +161,7 @@ PlasmaExtras.PlasmoidHeading {
leaveButtons.nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
}
}
Keys.onUpPressed: KickoffSingleton.sideBar.forceActiveFocus(Qt.BacktabFocusReason)
Keys.onUpPressed: plasmoid.rootItem.sideBar.forceActiveFocus(Qt.BacktabFocusReason)
}
LeaveButtons {
......@@ -172,7 +172,7 @@ PlasmaExtras.PlasmoidHeading {
bottom: parent.bottom
leftMargin: root.spacing
}
Keys.onUpPressed: KickoffSingleton.contentArea.forceActiveFocus(Qt.BacktabFocusReason)
Keys.onUpPressed: plasmoid.rootItem.contentArea.forceActiveFocus(Qt.BacktabFocusReason)
}
Behavior on height {
......
......@@ -19,10 +19,11 @@ import org.kde.plasma.private.kicker 0.1 as Kicker
EmptyPage {
id: root
leftPadding: -KickoffSingleton.leftPadding
rightPadding: -KickoffSingleton.rightPadding
// plasmoid.rootItem is Kickoff.qml
leftPadding: -plasmoid.rootItem.backgroundMetrics.leftPadding
rightPadding: -plasmoid.rootItem.backgroundMetrics.rightPadding
topPadding: 0
bottomPadding: -KickoffSingleton.bottomPadding
bottomPadding: -plasmoid.rootItem.backgroundMetrics.bottomPadding
Layout.minimumWidth: implicitWidth
Layout.minimumHeight: implicitHeight
......@@ -55,7 +56,7 @@ EmptyPage {
id: header
preferredNameAndIconWidth: normalPage.preferredSideBarWidth
Binding {
target: KickoffSingleton
target: plasmoid.rootItem
property: "header"
value: header
restoreMode: Binding.RestoreBinding
......@@ -82,7 +83,7 @@ EmptyPage {
implicitHeight: normalPage.implicitHeight
// Forces the function be re-run every time runnerModel.count changes.
// This is absolutely necessary to make the search view work reliably.
model: runnerModel.count ? KickoffSingleton.runnerModel.modelForRow(0) : null
model: plasmoid.rootItem.runnerModel.count ? plasmoid.rootItem.runnerModel.modelForRow(0) : null
delegate: KickoffItemDelegate {
extendHoverMargins: true
width: view.availableWidth
......@@ -92,8 +93,8 @@ EmptyPage {
// always focus the first item in the header focus chain
KeyNavigation.tab: root.header.nextItemInFocusChain()
T.StackView.onActivated: {
KickoffSingleton.sideBar = null
KickoffSingleton.contentArea = searchView
plasmoid.rootItem.sideBar = null
plasmoid.rootItem.contentArea = searchView
}
}
}
......@@ -101,7 +102,7 @@ EmptyPage {
Keys.priority: Keys.AfterItem
// This is here rather than root because events are implicitly forwarded
// to parent items. Don't want to send multiple events to searchField.
Keys.forwardTo: KickoffSingleton.searchField
Keys.forwardTo: plasmoid.rootItem.searchField
Connections {
target: root.header
......@@ -116,70 +117,4 @@ EmptyPage {
}
}
}
Kicker.RootModel {
id: rootModel
autoPopulate: false
appletInterface: plasmoid
flat: true // have categories, but no subcategories
sorted: plasmoid.configuration.alphaSort
showSeparators: false
showTopLevelItems: true
showAllApps: true
showAllAppsCategorized: false
showRecentApps: false
showRecentDocs: false
showRecentContacts: false
showPowerSession: false
showFavoritesPlaceholder: true
Component.onCompleted: {
favoritesModel.initForClient("org.kde.plasma.kickoff.favorites.instance-" + plasmoid.id)
if (!plasmoid.configuration.favoritesPortedToKAstats) {
favoritesModel.portOldFavorites(plasmoid.configuration.favorites);
plasmoid.configuration.favoritesPortedToKAstats = true;
}
rootModel.refresh();
KickoffSingleton.rootModel = Qt.binding(() => { return rootModel })
}
}
Kicker.RunnerModel {
id: runnerModel
query: KickoffSingleton.searchField.text
appletInterface: plasmoid
mergeResults: true
favoritesModel: rootModel.favoritesModel
Component.onCompleted: KickoffSingleton.runnerModel = Qt.binding(() => { return runnerModel })
}
Kicker.ComputerModel {
id: computerModel
appletInterface: plasmoid
favoritesModel: rootModel.favoritesModel
systemApplications: plasmoid.configuration.systemApplications
Component.onCompleted: {
//systemApplications = plasmoid.configuration.systemApplications;
KickoffSingleton.computerModel = Qt.binding(() => { return computerModel })
}
}
Kicker.RecentUsageModel {
id: recentUsageModel
favoritesModel: rootModel.favoritesModel
Component.onCompleted: KickoffSingleton.recentUsageModel = Qt.binding(() => { return recentUsageModel })
}
Kicker.RecentUsageModel {
id: frequentUsageModel
favoritesModel: rootModel.favoritesModel
ordering: 1 // Popular / Frequently Used
Component.onCompleted: KickoffSingleton.frequentUsageModel = Qt.binding(() => { return frequentUsageModel })
}
}
......@@ -33,8 +33,8 @@ PlasmaExtras.PlasmoidHeading {
topPadding: Math.round((background.margins.top - background.inset.top) / 2.0)
bottomPadding: background.margins.bottom + Math.round((background.margins.bottom - background.inset.bottom) / 2.0)
leftInset: -KickoffSingleton.leftPadding
rightInset: -KickoffSingleton.rightPadding
leftInset: -plasmoid.rootItem.backgroundMetrics.leftPadding
rightInset: -plasmoid.rootItem.backgroundMetrics.rightPadding
topInset: -background.margins.top
bottomInset: 0
......@@ -42,7 +42,7 @@ PlasmaExtras.PlasmoidHeading {
id: kuser
}
spacing: KickoffSingleton.spacing
spacing: plasmoid.rootItem.backgroundMetrics.spacing
RowLayout {
id: nameAndIcon
......@@ -93,10 +93,10 @@ PlasmaExtras.PlasmoidHeading {
Keys.onRightPressed: if (!LayoutMirroring.enabled) {
searchField.forceActiveFocus(Qt.TabFocusReason)
}
Keys.onDownPressed: if (KickoffSingleton.sideBar) {
KickoffSingleton.sideBar.forceActiveFocus(Qt.TabFocusReason)
Keys.onDownPressed: if (plasmoid.rootItem.sideBar) {
plasmoid.rootItem.sideBar.forceActiveFocus(Qt.TabFocusReason)
} else {
KickoffSingleton.contentArea.forceActiveFocus(Qt.TabFocusReason)
plasmoid.rootItem.contentArea.forceActiveFocus(Qt.TabFocusReason)
}
onClicked: KQuickAddons.KCMShell.openSystemSettings("kcm_users")
......@@ -160,13 +160,13 @@ PlasmaExtras.PlasmoidHeading {
left: nameAndIcon.right
right: parent.right
}
Keys.onDownPressed: KickoffSingleton.contentArea.forceActiveFocus(Qt.TabFocusReason)
Keys.onDownPressed: plasmoid.rootItem.contentArea.forceActiveFocus(Qt.TabFocusReason)
PC3.TextField {
id: searchField
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
Layout.fillWidth: true
Layout.leftMargin: KickoffSingleton.leftPadding
Layout.leftMargin: plasmoid.rootItem.backgroundMetrics.leftPadding
focus: true
placeholderText: i18n("Search…")
clearButtonShown: true
......@@ -174,7 +174,7 @@ PlasmaExtras.PlasmoidHeading {
Accessible.searchEdit: true
inputMethodHints: Qt.ImhNoPredictiveText
Binding {
target: KickoffSingleton
target: plasmoid.rootItem
property: "searchField"
value: searchField
}
......@@ -197,11 +197,11 @@ PlasmaExtras.PlasmoidHeading {
searchField.forceActiveFocus(Qt.ShortcutFocusReason)
}
onAccepted: {
KickoffSingleton.contentArea.currentItem.action.triggered()
KickoffSingleton.contentArea.currentItem.forceActiveFocus(Qt.ShortcutFocusReason)
plasmoid.rootItem.contentArea.currentItem.action.triggered()
plasmoid.rootItem.contentArea.currentItem.forceActiveFocus(Qt.ShortcutFocusReason)
}
Keys.priority: Keys.AfterItem
Keys.forwardTo: KickoffSingleton.contentArea.view
Keys.forwardTo: plasmoid.rootItem.contentArea.view
Keys.onLeftPressed: if (activeFocus) {
if (LayoutMirroring.enabled) {
nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
......@@ -256,8 +256,8 @@ PlasmaExtras.PlasmoidHeading {
value: !plasmoid.configuration.pin
}
KeyNavigation.backtab: configureButton
KeyNavigation.tab: if (KickoffSingleton.sideBar) {
return KickoffSingleton.sideBar
KeyNavigation.tab: if (plasmoid.rootItem.sideBar) {
return plasmoid.rootItem.sideBar
} else {
return nextItemInFocusChain()
}
......
......@@ -20,6 +20,102 @@ import org.kde.plasma.private.kicker 0.1 as Kicker
Item {
id: kickoff
// The properties are defined here instead of the singleton because each
// instance of Kickoff requires different instances of these properties
property bool inPanel: plasmoid.location === PlasmaCore.Types.TopEdge
|| plasmoid.location === PlasmaCore.Types.RightEdge
|| plasmoid.location === PlasmaCore.Types.BottomEdge
|| plasmoid.location === PlasmaCore.Types.LeftEdge
property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
//BEGIN Models
property Kicker.RootModel rootModel: Kicker.RootModel {
autoPopulate: false
appletInterface: plasmoid
flat: true // have categories, but no subcategories
sorted: plasmoid.configuration.alphaSort
showSeparators: false
showTopLevelItems: true
showAllApps: true
showAllAppsCategorized: false
showRecentApps: false
showRecentDocs: false
showRecentContacts: false
showPowerSession: false
showFavoritesPlaceholder: true
Component.onCompleted: {
favoritesModel.initForClient("org.kde.plasma.kickoff.favorites.instance-" + plasmoid.id)
if (!plasmoid.configuration.favoritesPortedToKAstats) {
if (favoritesModel.count < 1) {
favoritesModel.portOldFavorites(plasmoid.configuration.favorites);
}
plasmoid.configuration.favoritesPortedToKAstats = true;
}
refresh();
}
}
property Kicker.RunnerModel runnerModel: Kicker.RunnerModel {
query: kickoff.searchField ? kickoff.searchField.text : ""
appletInterface: plasmoid
mergeResults: true
favoritesModel: rootModel.favoritesModel
}
property Kicker.ComputerModel computerModel: Kicker.ComputerModel {
appletInterface: plasmoid
favoritesModel: rootModel.favoritesModel
systemApplications: plasmoid.configuration.systemApplications
Component.onCompleted: {
//systemApplications = plasmoid.configuration.systemApplications;
}
}
property Kicker.RecentUsageModel recentUsageModel: Kicker.RecentUsageModel {
favoritesModel: rootModel.favoritesModel
}
property Kicker.RecentUsageModel frequentUsageModel: Kicker.RecentUsageModel {
favoritesModel: rootModel.favoritesModel
ordering: 1 // Popular / Frequently Used
}
//END
//BEGIN UI elements
// Set in FullRepresentation.qml
property Item header: null
// Set in Header.qml
property PC3.TextField searchField: null
// Set in FullRepresentation.qml, ApplicationPage.qml, PlacesPage.qml
property Item sideBar: null // is null when searching
property Item contentArea: null // is searchView when searching
// Set in NormalPage.qml
property Item footer: null
//END
//BEGIN Metrics
readonly property PlasmaCore.FrameSvgItem backgroundMetrics: PlasmaCore.FrameSvgItem {
// Inset defaults to a negative value when not set by margin hints
readonly property real leftPadding: margins.left - Math.max(inset.left, 0)
readonly property real rightPadding: margins.right - Math.max(inset.right, 0)
readonly property real topPadding: margins.top - Math.max(inset.top, 0)
readonly property real bottomPadding: margins.bottom - Math.max(inset.bottom, 0)
readonly property real spacing: leftPadding
visible: false
imagePath: plasmoid.formFactor === PlasmaCore.Types.Planar ? "widgets/background" : "dialogs/background"
}
//END
Plasmoid.switchWidth: plasmoid.fullRepresentationItem ? plasmoid.fullRepresentationItem.Layout.minimumWidth : -1
Plasmoid.switchHeight: plasmoid.fullRepresentationItem ? plasmoid.fullRepresentationItem.Layout.minimumHeight : -1
......@@ -36,11 +132,11 @@ Item {
implicitHeight: PlasmaCore.Units.iconSizeHints.panel
Layout.minimumWidth: {
if (!KickoffSingleton.inPanel) {
if (!kickoff.inPanel) {
return PlasmaCore.Units.iconSizes.small
}
if (KickoffSingleton.vertical) {
if (kickoff.vertical) {
return -1;
} else {
return Math.min(PlasmaCore.Units.iconSizeHints.panel, parent.height) * buttonIcon.aspectRatio;
......@@ -48,11 +144,11 @@ Item {
}
Layout.minimumHeight: {
if (!KickoffSingleton.inPanel) {
if (!kickoff.inPanel) {
return PlasmaCore.Units.iconSizes.small
}
if (KickoffSingleton.vertical) {
if (kickoff.vertical) {
return Math.min(PlasmaCore.Units.iconSizeHints.panel, parent.width) * buttonIcon.aspectRatio;
} else {
return -1;
......@@ -60,11 +156,11 @@ Item {
}
Layout.maximumWidth: {
if (!KickoffSingleton.inPanel) {
if (!kickoff.inPanel) {
return -1;
}
if (KickoffSingleton.vertical) {
if (kickoff.vertical) {
return PlasmaCore.Units.iconSizeHints.panel;
} else {
return Math.min(PlasmaCore.Units.iconSizeHints.panel, parent.height) * buttonIcon.aspectRatio;
......@@ -72,11 +168,11 @@ Item {
}
Layout.maximumHeight: {
if (!KickoffSingleton.inPanel) {
if (!kickoff.inPanel) {
return -1;
}
if (KickoffSingleton.vertical) {
if (kickoff.vertical) {
return Math.min(PlasmaCore.Units.iconSizeHints.panel, parent.width) * buttonIcon.aspectRatio;
} else {
return PlasmaCore.Units.iconSizeHints.panel;
......@@ -105,7 +201,7 @@ Item {
PlasmaCore.IconItem {
id: buttonIcon
readonly property double aspectRatio: (KickoffSingleton.vertical ? implicitHeight / implicitWidth
readonly property double aspectRatio: (kickoff.vertical ? implicitHeight / implicitWidth
: implicitWidth / implicitHeight)
anchors.fill: parent
......@@ -120,30 +216,6 @@ Item {
id: processRunner;
}
// Workaround for `plasmoid` context property not working in singletons
// and `Plasmoid` not giving access to the plasmoid either.
Binding {
target: KickoffSingleton
property: "plasmoid"
value: plasmoid
restoreMode: Binding.RestoreBindingOrValue
}
Binding {
target: KickoffSingleton
property: "inPanel"
value: plasmoid.location === PlasmaCore.Types.TopEdge
|| plasmoid.location === PlasmaCore.Types.RightEdge
|| plasmoid.location === PlasmaCore.Types.BottomEdge
|| plasmoid.location === PlasmaCore.Types.LeftEdge
restoreMode: Binding.RestoreBindingOrValue
}
Binding {
target: KickoffSingleton
property: "vertical"
value: plasmoid.formFactor === PlasmaCore.Types.Vertical
restoreMode: Binding.RestoreBindingOrValue
}
function action_menuedit() {
processRunner.runMenuEditor();
}
......
......@@ -71,6 +71,7 @@ T.ItemDelegate {
}
root.actionList = allActions
}
ActionMenu.plasmoid = plasmoid
ActionMenu.menu.visualParent = root
if (x !== undefined && y !== undefined) {
ActionMenu.menu.open(x, y)
......
......@@ -2,7 +2,7 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
pragma Singleton
pragma Singleton // NOTE: Singletons are shared between all instances of a plasmoid
import QtQml.Models 2.15
import QtQuick 2.15
......@@ -17,19 +17,8 @@ import org.kde.plasma.private.kicker 0.1 as Kicker
Item {
id: root
visible: false
// Workaround for `plasmoid` context property not working in singletons
property var plasmoid: null
//BEGIN Models and Data Sources
// These are set in FullRepresentation.qml because the `plasmoid` context property
// doesn't work here and using `Plasmoid` from org.kde.plasma.plasmoid doesn't work either.
// Even the `plasmoid` property defined above doesn't quite work,
// but it works better than nothing for things like `plasmoid.expanded`
property Kicker.RootModel rootModel