homescreens/folio: Port to plugin architecture

This commit is contained in:
Devin Lin 2023-03-05 09:39:03 -08:00
parent e05d368913
commit 97d549c34c
23 changed files with 154 additions and 86 deletions

View file

@ -62,15 +62,16 @@ MouseArea { // use mousearea to ensure clicks don't go behind
}
}
Connections {
target: NanoShell.StartupNotifier
enabled: NanoShell.StartupNotifier.isValid
function onActivationStarted(appId, iconName) {
icon.source = iconName
background.state = "open";
}
}
// TODO
// Connections {
// target: NanoShell.StartupNotifier
// enabled: NanoShell.StartupNotifier.isValid
//
// function onActivationStarted(appId, iconName) {
// icon.source = iconName
// background.state = "open";
// }
// }
property alias state: background.state
property alias icon: icon.source

View file

@ -3,8 +3,6 @@
set(homescreen_SRCS
homescreen.cpp
desktopmodel.cpp
applicationlistmodel.cpp
)
add_library(plasma_containment_phone_homescreen MODULE ${homescreen_SRCS})
@ -27,3 +25,5 @@ target_link_libraries(plasma_containment_phone_homescreen
install(TARGETS plasma_containment_phone_homescreen DESTINATION ${KDE_INSTALL_PLUGINDIR}/plasma/applets)
plasma_install_package(package org.kde.plasma.mobile.homescreen.folio)
add_subdirectory(plugin)

View file

@ -14,20 +14,6 @@ HomeScreen::HomeScreen(QObject *parent, const KPluginMetaData &data, const QVari
: Plasma::Containment{parent, data, args}
{
setHasConfigurationInterface(true);
ApplicationListModel *applicationListModel = new ApplicationListModel{this};
DesktopModel *desktopModel = new DesktopModel{this, this};
qmlRegisterSingletonType<ApplicationListModel>("org.kde.phone.homescreen.default",
1,
0,
"ApplicationListModel",
[applicationListModel](QQmlEngine *, QJSEngine *) -> QObject * {
return applicationListModel;
});
qmlRegisterSingletonType<DesktopModel>("org.kde.phone.homescreen.default", 1, 0, "DesktopModel", [desktopModel](QQmlEngine *, QJSEngine *) -> QObject * {
return desktopModel;
});
connect(KWindowSystem::self(), &KWindowSystem::showingDesktopChanged, this, &HomeScreen::showingDesktopChanged);
}

View file

@ -7,9 +7,6 @@
#include <Plasma/Containment>
#include <QSortFilterProxyModel>
#include <applicationlistmodel.h>
#include <desktopmodel.h>
class HomeScreen : public Plasma::Containment
{
Q_OBJECT

View file

@ -17,12 +17,13 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
import "private" as Private
ContainmentLayoutManager.ItemContainer {
id: delegate
required property Folio.DesktopModel desktopModel
enabled: homeScreenState.currentView === HomeScreenState.PageView || homeScreenState.currentSwipeState === HomeScreenState.SwipingAppDrawerVisibility
@ -52,9 +53,9 @@ ContainmentLayoutManager.ItemContainer {
}
if (!MobileShellState.Shell.taskSwitcherVisible) {
HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
desktopModel.setMinimizedDelegate(index, delegate);
} else {
HomeScreenLib.DesktopModel.unsetMinimizedDelegate(index, delegate);
desktopModel.unsetMinimizedDelegate(index, delegate);
}
}
@ -65,7 +66,7 @@ ContainmentLayoutManager.ItemContainer {
delegate.launch(delegate.x + (PlasmaCore.Units.smallSpacing * 2), delegate.y + (PlasmaCore.Units.smallSpacing * 2), icon.source, modelData.applicationName);
}
HomeScreenLib.DesktopModel.setMinimizedDelegate(index, delegate);
desktopModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(modelData.applicationStorageId);
}
@ -197,6 +198,7 @@ ContainmentLayoutManager.ItemContainer {
//TODO: in loader?
Private.DelegateRemoveButton {
id: removeButton
desktopModel: delegate.desktopModel
}
}

View file

@ -21,7 +21,7 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
Item {
id: root
@ -54,6 +54,8 @@ Item {
homeScreenState.goToPageIndex(0);
homeScreenState.resetSwipeState();
}
property var desktopModel: Folio.DesktopModel {}
// the parent of the homescreen is a flickable that captures all flicks
FlickContainer {
@ -96,6 +98,7 @@ Item {
HomeScreenContents {
id: contents
desktopModel: root.desktopModel
homeScreenState: root.homeScreenState
height: pages.height
@ -110,7 +113,7 @@ Item {
appletsLayout: contents.appletsLayout
visible: favoriteStrip.flow.children.length > 0 || contents.launcherDragManager.active || contents.containsDrag
opacity: contents.launcherDragManager.active && HomeScreenLib.DesktopModel.favoriteCount >= HomeScreenLib.DesktopModel.maxFavoriteCount ? 0.3 : 1
opacity: contents.launcherDragManager.active && root.desktopModel.favoriteCount >= root.desktopModel.maxFavoriteCount ? 0.3 : 1
TapHandler {
target: favoriteStrip

View file

@ -17,7 +17,7 @@ import org.kde.draganddrop 2.0 as DragDrop
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
import "private" as Private
@ -25,7 +25,10 @@ DragDrop.DropArea {
id: dropArea
required property var homeScreenState
required property Folio.DesktopModel desktopModel
property var applicationListModel: Folio.ApplicationListModel
property alias launcherDelegate: launcherRepeater.delegate
property alias launcherModel: launcherRepeater.model
property alias launcherRepeater: launcherRepeater
@ -52,9 +55,7 @@ DragDrop.DropArea {
}
property bool inAppletEditMode: false
property var applicationListModel: HomeScreenLib.ApplicationListModel
property var desktopModel: HomeScreenLib.DesktopModel
Connections {
target: plasmoid
@ -119,7 +120,7 @@ DragDrop.DropArea {
}
let pos = Math.min(desktopModel.count, Math.floor(posInFavorites.x/favoriteStrip.cellWidth))
desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Favorites)
desktopModel.addFavorite(storageId, pos, Folio.ApplicationListModel.Favorites)
let item = launcherRepeater.itemAt(pos);
if (item) {
@ -134,7 +135,7 @@ DragDrop.DropArea {
}
let pos = desktopModel.count;
desktopModel.addFavorite(storageId, pos, HomeScreenLib.ApplicationListModel.Desktop)
desktopModel.addFavorite(storageId, pos, Folio.ApplicationListModel.Desktop)
let item = launcherRepeater.itemAt(pos);
event.accept(event.proposedAction);
@ -222,6 +223,7 @@ DragDrop.DropArea {
}
LauncherRepeater {
id: launcherRepeater
desktopModel: dropArea.desktopModel
homeScreenState: dropArea.homeScreenState
cellWidth: appletsLayout.cellWidth
cellHeight: appletsLayout.cellHeight

View file

@ -9,7 +9,7 @@ import QtQuick 2.4
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
Item {
id: root
@ -19,7 +19,7 @@ Item {
property ContainmentLayoutManager.ItemContainer currentlyDraggedDelegate
property bool active
property var desktopModel: HomeScreenLib.DesktopModel
required property Folio.DesktopModel desktopModel
readonly property Item spacer: Item {
width: favoriteStrip.cellWidth
@ -45,7 +45,7 @@ Item {
newRow = Math.floor((pos.x + dragCenterX) / delegate.width);
showSpacer(delegate, dragCenterX, dragCenterY);
HomeScreenLib.DesktopModel.moveItem(delegate.modelData.index, newRow);
desktopModel.moveItem(delegate.modelData.index, newRow);
// Put it on desktop
} else {
@ -162,8 +162,8 @@ Item {
if (!item.modelData) {
return appletsLayout;
} else if (favoriteStrip.contains(Qt.point(0,favoriteStrip.frame.mapFromItem(item, dragCenterX, dragCenterY).y))
&& (item.modelData.applicationLocation == HomeScreenLib.DesktopModel.Favorites
|| HomeScreenLib.DesktopModel.favoriteCount < HomeScreenLib.DesktopModel.maxFavoriteCount)) {
&& (item.modelData.applicationLocation == Folio.DesktopModel.Favorites
|| desktopModel.favoriteCount < desktopModel.maxFavoriteCount)) {
return favoriteStrip;
} else {
return appletsLayout;
@ -269,7 +269,7 @@ Item {
if (container == appletsLayout) {
if (item.modelData) {
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.Desktop);
desktopModel.setLocation(item.modelData.index, Folio.DesktopModel.Desktop);
}
var pos = appletsLayout.mapFromItem(item, 0, 0);
item.parent = appletsLayout;
@ -280,9 +280,9 @@ Item {
return;
} else if (container == favoriteStrip) {
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.Favorites);
desktopModel.setLocation(item.modelData.index, Folio.DesktopModel.Favorites);
} else {
HomeScreenLib.DesktopModel.setLocation(item.modelData.index, HomeScreenLib.DesktopModel.None);
desktopModel.setLocation(item.modelData.index, Folio.DesktopModel.None);
}
var child = nearestChild(item, dragCenterX, dragCenterY, container);

View file

@ -17,15 +17,15 @@ import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutM
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
import org.kde.kirigami 2.14 as Kirigami
Repeater {
id: launcherRepeater
model: HomeScreenLib.DesktopModel
required property var homeScreenState
required property Folio.DesktopModel desktopModel
property ContainmentLayoutManager.AppletsLayout appletsLayout
property FavoriteStrip favoriteStrip
property int cellWidth
@ -37,6 +37,7 @@ Repeater {
delegate: HomeDelegate {
id: delegate
desktopModel: launcherRepeater.desktopModel
homeScreenState: launcherRepeater.homeScreenState
width: launcherRepeater.cellWidth
@ -53,15 +54,15 @@ Repeater {
reservedSpaceForLabel: metrics.height
property Item parentFromLocation: {
switch (model.applicationLocation) {
case HomeScreenLib.DesktopModel.Favorites:
case Folio.DesktopModel.Favorites:
return favoriteStrip.flow;
case HomeScreenLib.DesktopModel.Desktop:
case Folio.DesktopModel.Desktop:
default:
return appletsLayout;
}
}
Component.onCompleted: {
if (model.applicationLocation === HomeScreenLib.DesktopModel.Desktop) {
if (model.applicationLocation === Folio.DesktopModel.Desktop) {
appletsLayout.restoreItem(delegate);
}
}
@ -117,10 +118,10 @@ Repeater {
onParentFromLocationChanged: {
if (!launcherDragManager.active && parent != parentFromLocation) {
parent = parentFromLocation;
if (model.applicationLocation === HomeScreenLib.DesktopModel.Favorites) {
if (model.applicationLocation === Folio.DesktopModel.Favorites) {
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[index]);
} else if (model.applicationLocation === HomeScreenLib.DesktopModel.None) {
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - HomeScreenLib.DesktopModel.favoriteCount)]);
} else if (model.applicationLocation === Folio.DesktopModel.None) {
MobileShell.ShellUtil.stackItemBefore(delegate, parentFromLocation.children[Math.max(0, index - desktopModel.favoriteCount)]);
}
}
}

View file

@ -18,7 +18,7 @@ import org.kde.kirigami 2.10 as Kirigami
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
import "../private"
@ -48,7 +48,7 @@ AbstractAppDrawer {
cacheBuffer: Math.max(0, rows * cellHeight)
model: HomeScreenLib.ApplicationListModel
model: Folio.ApplicationListModel
delegate: DrawerGridDelegate {
id: delegate
@ -78,7 +78,7 @@ AbstractAppDrawer {
Math.min(delegate.iconItem.width, delegate.iconItem.height));
}
HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
Folio.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(storageId);
root.launched();
}

View file

@ -17,7 +17,7 @@ import org.kde.kirigami 2.10 as Kirigami
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
import "../private"
@ -34,7 +34,7 @@ AbstractAppDrawer {
property int delegateHeight: PlasmaCore.Units.gridUnit * 3
model: HomeScreenLib.ApplicationListModel
model: Folio.ApplicationListModel
delegate: DrawerListDelegate {
id: delegate
@ -64,7 +64,7 @@ AbstractAppDrawer {
Math.min(delegate.iconItem.width, delegate.iconItem.height));
}
HomeScreenLib.ApplicationListModel.setMinimizedDelegate(index, delegate);
Folio.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(storageId);
root.launched();
}

View file

@ -15,7 +15,7 @@ import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
MobileShell.HomeScreen {
id: root
@ -34,9 +34,6 @@ MobileShell.HomeScreen {
property bool componentComplete: false
Component.onCompleted: {
HomeScreenLib.ApplicationListModel.load();
HomeScreenLib.DesktopModel.load();
// ensure the gestures work immediately on load
forceActiveFocus();
}
@ -124,7 +121,7 @@ MobileShell.HomeScreen {
// listen to app launch errors
Connections {
target: HomeScreenLib.ApplicationListModel
target: Folio.ApplicationListModel
function onLaunchError(msg) {
MobileShellState.Shell.closeAppLaunchAnimation()
}

View file

@ -16,10 +16,13 @@ import org.kde.kquickcontrolsaddons 2.0
import org.kde.plasma.private.containmentlayoutmanager 1.0 as ContainmentLayoutManager
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.phone.homescreen.default 1.0 as HomeScreenLib
import org.kde.private.plasma.mobile.homescreen.folio 1.0 as Folio
PC3.RoundButton {
id: removeButton
required property Folio.DesktopModel desktopModel
anchors {
right: parent.right
top: parent.top
@ -35,6 +38,7 @@ PC3.RoundButton {
removeButtonScaleAnim.to = 1;
removeButtonAnim.running = true;
}
function hide() {
if (!visible) {
return;
@ -43,6 +47,7 @@ PC3.RoundButton {
removeButtonScaleAnim.to = 0;
removeButtonAnim.running = true;
}
SequentialAnimation {
id: delegateDestructionAnim
NumberAnimation {
@ -56,7 +61,7 @@ PC3.RoundButton {
ScriptAction {
script: {
appletsLayout.releaseSpace(delegate);
HomeScreenLib.DesktopModel.removeFavorite(index);
desktopModel.removeFavorite(index);
}
}
}

View file

@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
set(folioplugin_SRCS
folioplugin.cpp
applicationlistmodel.cpp
desktopmodel.cpp
)
install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/private/plasma/mobile/homescreen/halcyon)
add_library(folioplugin SHARED ${folioplugin_SRCS})
target_link_libraries(folioplugin
Qt::Gui
Qt::Qml
Qt::Quick
KF6::Plasma
KF6::I18n
KF6::Service
KF6::KIOGui
KF6::Notifications
KF6::WaylandClient
KF6::WindowSystem)
set_property(TARGET folioplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/private/plasma/mobile/homescreen/folio)
install(TARGETS folioplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/private/plasma/mobile/homescreen/folio)

View file

@ -40,6 +40,8 @@ ApplicationListModel::ApplicationListModel(QObject *parent)
registry->setup();
connection->roundtrip();
load();
}
ApplicationListModel::~ApplicationListModel() = default;

View file

@ -58,8 +58,6 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
Q_INVOKABLE virtual void load();
Q_INVOKABLE void setMinimizedDelegate(int row, QQuickItem *delegate);
Q_INVOKABLE void unsetMinimizedDelegate(int row, QQuickItem *delegate);
@ -71,6 +69,8 @@ Q_SIGNALS:
void launchError(const QString &msg);
protected:
virtual void load();
QList<ApplicationData> m_applicationList;
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;

View file

@ -19,7 +19,7 @@
const int MAX_FAVORITES = 5;
DesktopModel::DesktopModel(QObject *parent, Plasma::Applet *applet)
: ApplicationListModel(parent)
: ApplicationListModel(parent) // constructor calls load()
, m_applet{applet}
{
}

View file

@ -33,7 +33,6 @@ public:
QString uniqueToStorageId(const QString &uniqueId) const;
void loadSettings();
Q_INVOKABLE void load() override;
int count();
int favoriteCount();
@ -50,6 +49,8 @@ Q_SIGNALS:
void favoriteCountChanged();
private:
void load() override;
QStringList m_appOrder;
QStringList m_favorites;
QSet<QString> m_desktopItems;

View file

@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "folioplugin.h"
#include "applicationlistmodel.h"
#include "desktopmodel.h"
void HalcyonPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.private.plasma.mobile.homescreen.halcyon"));
ApplicationListModel *applicationListModel = new ApplicationListModel{this};
qmlRegisterSingletonType<ApplicationListModel>(uri, 1, 0, "ApplicationListModel", [applicationListModel](QQmlEngine *, QJSEngine *) -> QObject * {
return applicationListModel;
});
qmlRegisterType<DesktopModel>(uri, 1, 0, "DesktopModel");
}

View file

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
class HalcyonPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri) override;
};

View file

@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
module org.kde.private.plasma.mobile.homescreen.folio
plugin folioplugin

View file

@ -26,5 +26,5 @@ target_link_libraries(halcyonplugin
KF6::WaylandClient
KF6::WindowSystem)
set_property(TARGET halcyonplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/plasma/mm)
set_property(TARGET halcyonplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/private/mobile/homescreen/halcyon)
install(TARGETS halcyonplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/private/mobile/homescreen/halcyon)

View file

@ -16,13 +16,16 @@ for (var j = 0; j < desktopsArray.length; j++) {
}
}
// keep this list in sync with shell/contents/updates/panelsfix.js
var panel = new Panel("org.kde.plasma.mobile.panel");
panel.location = "top";
panel.addWidget("org.kde.plasma.notifications");
panel.height = 1.25 * gridUnit; // HACK: supposed to be gridUnit + smallSpacing, but it doesn't seem to give the correct number
var bottomPanel = new Panel("org.kde.desktopcontainment")
bottomPanel.location = "bottom";
bottomPanel.height = 2 * gridUnit;
// var panel = new Panel("org.kde.plasma.mobile.panel");
// panel.location = "top";
// panel.addWidget("org.kde.plasma.notifications");
// panel.height = 1.25 * gridUnit; // HACK: supposed to be gridUnit + smallSpacing, but it doesn't seem to give the correct number
//
// console.log('script');
//
// var bottomPanel = new Panel("org.kde.plasma.mobile.taskpanel")
// bottomPanel.location = "bottom";
// bottomPanel.height = 2 * gridUnit;
//
// console.log('script');