windowplugin: Extract out windowutil from mobileshell to separate plugin

This allows us in the future to use mobileshell without having the WindowUtil singleton loaded (which does a bunch of wayland calls that aren't necessary for most applications).
This commit is contained in:
Devin Lin 2023-03-14 23:29:46 -07:00
parent 0a640e9331
commit 0775c56153
23 changed files with 149 additions and 57 deletions

View file

@ -5,3 +5,4 @@
add_subdirectory(mmplugin)
add_subdirectory(mobileshell)
add_subdirectory(mobileshellstate)
add_subdirectory(windowplugin)

View file

@ -8,7 +8,6 @@ set(mobileshellplugin_SRCS
mobileshellplugin.cpp
mobileshellsettings.cpp
shellutil.cpp
windowutil.cpp
components/direction.cpp
quicksettings/quicksetting.cpp
quicksettings/paginatemodel.cpp

View file

@ -22,7 +22,6 @@
#include "mobileshellsettings.h"
#include "shellutil.h"
#include "windowutil.h"
QUrl resolvePath(std::string str)
{
@ -46,9 +45,6 @@ void MobileShellPlugin::registerTypes(const char *uri)
qmlRegisterType<PaginateModel>(uri, 1, 0, "PaginateModel");
qmlRegisterType<SavedQuickSettings>(uri, 1, 0, "SavedQuickSettings");
qmlRegisterType<SavedQuickSettingsModel>(uri, 1, 0, "SavedQuickSettingsModel");
qmlRegisterSingletonType<WindowUtil>(uri, 1, 0, "WindowUtil", [](QQmlEngine *, QJSEngine *) -> QObject * {
return WindowUtil::instance();
});
// components
qmlRegisterType<Direction>(uri, 1, 0, "Direction");
@ -68,6 +64,7 @@ void MobileShellPlugin::registerTypes(const char *uri)
qmlRegisterType(resolvePath("actiondrawer/ActionDrawerWindow.qml"), uri, 1, 0, "ActionDrawerWindow");
// /components
qmlRegisterSingletonType(resolvePath("components/AppLaunch.qml"), uri, 1, 0, "AppLaunch");
qmlRegisterType(resolvePath("components/BaseItem.qml"), uri, 1, 0, "BaseItem");
qmlRegisterType(resolvePath("components/ExtendedAbstractButton.qml"), uri, 1, 0, "ExtendedAbstractButton");
qmlRegisterType(resolvePath("components/Flickable.qml"), uri, 1, 0, "Flickable");

View file

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
import QtQuick
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
pragma Singleton
QtObject {
/**
* Activates an application by storage id if it is already running, or launch the application.
*/
function launchOrActivateApp(storageId) {
const launched = WindowPlugin.WindowUtil.activateWindowByStorageId(storageId);
if (!launched) {
MobileShell.ShellUtil.launchApp(storageId);
}
}
}

View file

@ -1,9 +1,9 @@
/*
* SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2021 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
/**
* Applies both the min and max functions to a value.
*/
function applyMinMaxRange(min, max, num) {
return Math.min(max, Math.max(min, num));
}

View file

@ -3,15 +3,16 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick
import QtQuick.Window
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.plasmoid 2.0
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasmoid
import org.kde.taskmanager as TaskManager
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.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
/**
* The base homescreen component, implementing features that simplify
@ -77,14 +78,14 @@ Item {
target: MobileShellState.HomeScreenControls
function onOpenHomeScreen() {
if (!MobileShell.WindowUtil.allWindowsMinimized) {
if (!WindowPlugin.WindowUtil.allWindowsMinimized) {
itemContainer.zoomIn();
}
MobileShellState.HomeScreenControls.resetHomeScreenPosition();
MobileShell.WindowUtil.unsetAllMinimizedGeometries(root);
MobileShell.WindowUtil.minimizeAll();
WindowPlugin.WindowUtil.unsetAllMinimizedGeometries(root);
WindowPlugin.WindowUtil.minimizeAll();
root.homeTriggered();
}
@ -202,7 +203,7 @@ Item {
function evaluateAnimChange() {
// only animate if homescreen is visible
if (!visibleMaximizedWindowsModel.isWindowMaximized || MobileShell.WindowUtil.activeWindowIsShell) {
if (!visibleMaximizedWindowsModel.isWindowMaximized || WindowPlugin.WindowUtil.activeWindowIsShell) {
itemContainer.zoomIn();
} else {
itemContainer.zoomOut();
@ -210,7 +211,7 @@ Item {
}
Connections {
target: MobileShell.WindowUtil
target: WindowPlugin.WindowUtil
function onActiveWindowIsShellChanged() {
itemContainer.evaluateAnimChange();
}

View file

@ -25,10 +25,4 @@ PlasmaComponents.Label {
text: Qt.formatTime(source.data.Local.DateTime, is24HourTime ? "h:mm" : "h:mm ap")
color: PlasmaCore.ColorScope.textColor
verticalAlignment: Qt.AlignVCenter
TapHandler {
onTapped: {
MobileShell.ShellUtil.launchApp("org.kde.kclock.desktop");
}
}
}

View file

@ -75,7 +75,7 @@ Item {
implicitWidth: playerItem.implicitWidth
onClicked: {
MobileShell.ShellUtil.launchApp(modelData.desktopEntry + ".desktop");
Components.AppLaunch.launchOrActivateApp(modelData.desktopEntry + ".desktop");
MobileShellState.Shell.closeActionDrawer();
}

View file

@ -20,6 +20,7 @@
<file>qml/actiondrawer/LandscapeContentContainer.qml</file>
<file>qml/actiondrawer/PortraitContentContainer.qml</file>
<file>qml/components/AppLaunch.qml</file>
<file>qml/components/BaseItem.qml</file>
<file>qml/components/ExtendedAbstractButton.qml</file>
<file>qml/components/Flickable.qml</file>

View file

@ -8,7 +8,6 @@
#include "shellutil.h"
#include "mobileshellsettings.h"
#include "windowutil.h"
#include <KConfigGroup>
#include <KFileUtils>
@ -81,15 +80,6 @@ bool ShellUtil::isSystem24HourFormat()
void ShellUtil::launchApp(const QString &storageId)
{
// try to activate a running window first
auto windows = WindowUtil::instance()->windowsFromStorageId(storageId);
if (!windows.empty()) {
windows[0]->requestActivate();
return;
}
// now try launching the window
KService::Ptr service = KService::serviceByStorageId(storageId);
if (!service) {
qWarning() << "Could not find" << storageId;

View file

@ -52,7 +52,7 @@ public:
Q_INVOKABLE void executeCommand(const QString &command);
/**
* Launch an application by name. Sets the internal "launched app" state.
* Launch an application by name.
*
* @param storageId The storage id of the application to launch.
*/

View file

@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
add_library(windowplugin)
target_sources(windowplugin PRIVATE
windowplugin.cpp
windowutil.cpp
)
target_link_libraries(windowplugin
Qt::Qml
Qt::DBus
Qt::Gui
Qt::Quick
KF6::WaylandClient
KF6::Service
KF6::ConfigWidgets
)
set_property(TARGET windowplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/plasma/private/mobileshell/windowplugin)
file(COPY qmldir DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/plasma/private/mobileshell/windowplugin)
install(TARGETS windowplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobileshell/windowplugin)
install(FILES qmldir ${qml_SRC} DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/plasma/private/mobileshell/windowplugin)

View file

@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2021-2022 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
module org.kde.plasma.private.mobileshell.windowplugin
plugin windowplugin

View file

@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "windowplugin.h"
#include "windowutil.h"
#include <QQmlContext>
#include <QQuickItem>
void WindowPlugin::registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.plasma.private.mobileshell.windowplugin"));
qmlRegisterSingletonType<WindowUtil>(uri, 1, 0, "WindowUtil", [](QQmlEngine *, QJSEngine *) -> QObject * {
return WindowUtil::instance();
});
}

View file

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

View file

@ -137,6 +137,18 @@ bool WindowUtil::hasCloseableActiveWindow() const
return m_activeWindow && m_activeWindow->isCloseable() /*&& !m_activeWindow->isMinimized()*/;
}
bool WindowUtil::activateWindowByStorageId(const QString &storageId)
{
auto windows = windowsFromStorageId(storageId);
if (!windows.empty()) {
windows[0]->requestActivate();
return true;
}
return false;
}
void WindowUtil::closeActiveWindow()
{
if (m_activeWindow) {

View file

@ -72,6 +72,14 @@ public:
*/
QList<KWayland::Client::PlasmaWindow *> windowsFromStorageId(const QString &storageId) const;
/**
* Activates the first window by its associated storage id.
*
* @param storageId the window's storage id
* @returns whether a window was activated
*/
Q_INVOKABLE bool activateWindowByStorageId(const QString &storageId);
/**
* Close the current active window.
*/

View file

@ -63,7 +63,7 @@ ContainmentLayoutManager.ItemContainer {
}
desktopModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(modelData.applicationStorageId);
MobileShell.AppLaunch.launchOrActivateApp(modelData.applicationStorageId);
}
readonly property bool applicationRunning: model.applicationRunning

View file

@ -79,7 +79,7 @@ AbstractAppDrawer {
}
Folio.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(storageId);
MobileShell.AppLaunch.launchOrActivateApp(storageId);
root.launched();
}
}

View file

@ -65,7 +65,7 @@ AbstractAppDrawer {
}
Folio.ApplicationListModel.setMinimizedDelegate(index, delegate);
MobileShell.ShellUtil.launchApp(storageId);
MobileShell.AppLaunch.launchOrActivateApp(storageId);
root.launched();
}
}

View file

@ -88,7 +88,7 @@ Item {
}
application.setMinimizedDelegate(delegate);
MobileShell.ShellUtil.launchApp(application.storageId);
MobileShell.AppLaunch.launchOrActivateApp(application.storageId);
}
Loader {

View file

@ -100,7 +100,7 @@ MobileShell.GridView {
}
application.setMinimizedDelegate(delegate);
MobileShell.ShellUtil.launchApp(application.storageId);
MobileShell.AppLaunch.launchOrActivateApp(application.storageId);
}
}

View file

@ -1,17 +1,18 @@
// SPDX-FileCopyrightText: 2021-2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
import QtQuick 2.4
import QtQuick.Layouts 1.1
import QtQuick.Window 2.15
import QtQuick
import QtQuick.Layouts
import QtQuick.Window
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout 1.0 as Keyboards
import org.kde.plasma.plasmoid
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout as Keyboards
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
import org.kde.plasma.private.mobileshell.state 1.0 as MobileShellState
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.taskmanager as TaskManager
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
MobileShell.NavigationPanel {
id: root
@ -77,7 +78,7 @@ MobileShell.NavigationPanel {
onTriggered: {
MobileShellState.HomeScreenControls.openHomeScreen();
MobileShell.WindowUtil.allWindowsMinimizedChanged();
WindowPlugin.WindowUtil.allWindowsMinimizedChanged();
}
}
@ -85,7 +86,7 @@ MobileShell.NavigationPanel {
rightAction: MobileShell.NavigationPanelAction {
id: closeAppAction
enabled: Keyboards.KWinVirtualKeyboard.visible || MobileShell.WindowUtil.hasCloseableActiveWindow
enabled: Keyboards.KWinVirtualKeyboard.visible || WindowPlugin.WindowUtil.hasCloseableActiveWindow
iconSource: Keyboards.KWinVirtualKeyboard.visible ? "go-down-symbolic" : "mobile-close-app"
// mobile-close-app (from plasma-frameworks) seems to have less margins than icons from breeze-icons
iconSizeFactor: Keyboards.KWinVirtualKeyboard.visible ? 1 : 0.75
@ -94,7 +95,7 @@ MobileShell.NavigationPanel {
if (Keyboards.KWinVirtualKeyboard.active) {
// close keyboard if it is open
Keyboards.KWinVirtualKeyboard.active = false;
} else if (MobileShell.WindowUtil.hasCloseableActiveWindow) {
} else if (WindowPlugin.WindowUtil.hasCloseableActiveWindow) {
// if task switcher is closed, but there is an active window
if (tasksModel.activeTask !== 0) {
tasksModel.requestClose(tasksModel.activeTask);