mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
navigationpanel: Add ability to toggle between gesture only and shown navigation panel modes
Addresses: https://invent.kde.org/plasma/plasma-phone-components/-/issues/140
This commit is contained in:
parent
6d6b38ac46
commit
8f9f722ca7
27 changed files with 690 additions and 151 deletions
|
|
@ -69,6 +69,7 @@ add_subdirectory(bin)
|
||||||
add_subdirectory(containments)
|
add_subdirectory(containments)
|
||||||
add_subdirectory(components)
|
add_subdirectory(components)
|
||||||
add_subdirectory(quicksettings)
|
add_subdirectory(quicksettings)
|
||||||
|
add_subdirectory(kcms)
|
||||||
|
|
||||||
find_program(PlasmaOpenSettings plasma-open-settings)
|
find_program(PlasmaOpenSettings plasma-open-settings)
|
||||||
set_package_properties(PlasmaOpenSettings PROPERTIES
|
set_package_properties(PlasmaOpenSettings PROPERTIES
|
||||||
|
|
|
||||||
21
LICENSES/MIT.txt
Normal file
21
LICENSES/MIT.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) [year] [fullname]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -33,8 +33,8 @@ Item {
|
||||||
|
|
||||||
appDrawerFlickable: appDrawer.flickable
|
appDrawerFlickable: appDrawer.flickable
|
||||||
|
|
||||||
availableScreenHeight: height - (MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0)
|
availableScreenHeight: height - MobileShell.Shell.bottomMargin
|
||||||
availableScreenWidth: width - (MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth)
|
availableScreenWidth: width - MobileShell.Shell.leftMargin - MobileShell.Shell.rightMargin
|
||||||
|
|
||||||
appDrawerBottomOffset: favoriteStrip.height
|
appDrawerBottomOffset: favoriteStrip.height
|
||||||
}
|
}
|
||||||
|
|
@ -73,9 +73,10 @@ Item {
|
||||||
|
|
||||||
// account for panels
|
// account for panels
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: MobileShell.TopPanelControls.panelHeight
|
anchors.topMargin: MobileShell.Shell.topMargin
|
||||||
anchors.rightMargin: MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth
|
anchors.bottomMargin: MobileShell.Shell.bottomMargin
|
||||||
anchors.bottomMargin: MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0
|
anchors.leftMargin: MobileShell.Shell.leftMargin
|
||||||
|
anchors.rightMargin: MobileShell.Shell.rightMargin
|
||||||
|
|
||||||
// animation when app drawer is being shown
|
// animation when app drawer is being shown
|
||||||
opacity: root.appDrawer ? 1 - root.appDrawer.openFactor : 1
|
opacity: root.appDrawer ? 1 - root.appDrawer.openFactor : 1
|
||||||
|
|
@ -129,9 +130,10 @@ Item {
|
||||||
homeScreenState: root.homeScreenState
|
homeScreenState: root.homeScreenState
|
||||||
|
|
||||||
// account for panels
|
// account for panels
|
||||||
topPadding: MobileShell.TopPanelControls.panelHeight
|
topPadding: MobileShell.Shell.topMargin
|
||||||
rightPadding: MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth
|
bottomPadding: MobileShell.Shell.bottomMargin
|
||||||
bottomPadding: MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0
|
leftPadding: MobileShell.Shell.leftMargin
|
||||||
|
rightPadding: MobileShell.Shell.rightMargin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ set(mobileshellplugin_SRCS
|
||||||
mobileshellplugin.cpp
|
mobileshellplugin.cpp
|
||||||
shellutil.cpp
|
shellutil.cpp
|
||||||
quicksettingsmodel.cpp
|
quicksettingsmodel.cpp
|
||||||
|
mobileshellsettings.cpp
|
||||||
vkbdinterface.cpp
|
vkbdinterface.cpp
|
||||||
displaysmodel.cpp
|
displaysmodel.cpp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
|
|
||||||
#include "displaysmodel.h"
|
#include "displaysmodel.h"
|
||||||
|
#include "mobileshellsettings.h"
|
||||||
#include "notifications/notificationfilemenu.h"
|
#include "notifications/notificationfilemenu.h"
|
||||||
#include "notifications/notificationthumbnailer.h"
|
#include "notifications/notificationthumbnailer.h"
|
||||||
#include "quicksettingsmodel.h"
|
#include "quicksettingsmodel.h"
|
||||||
|
|
@ -25,6 +26,10 @@ void MobileShellPlugin::registerTypes(const char *uri)
|
||||||
return ShellUtil::instance();
|
return ShellUtil::instance();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
qmlRegisterSingletonType<MobileShellSettings>(uri, 1, 0, "MobileShellSettings", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||||
|
return MobileShellSettings::self();
|
||||||
|
});
|
||||||
|
|
||||||
qmlRegisterType<QuickSetting>(uri, 1, 0, "QuickSetting");
|
qmlRegisterType<QuickSetting>(uri, 1, 0, "QuickSetting");
|
||||||
qmlRegisterType<QuickSettingsModel>(uri, 1, 0, "QuickSettingsModel");
|
qmlRegisterType<QuickSettingsModel>(uri, 1, 0, "QuickSettingsModel");
|
||||||
|
|
||||||
|
|
|
||||||
35
components/mobileshell/mobileshellsettings.cpp
Normal file
35
components/mobileshell/mobileshellsettings.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mobileshellsettings.h"
|
||||||
|
|
||||||
|
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
|
||||||
|
const QString GENERAL_CONFIG_GROUP = QStringLiteral("General");
|
||||||
|
|
||||||
|
MobileShellSettings *MobileShellSettings::self()
|
||||||
|
{
|
||||||
|
static MobileShellSettings *singleton = new MobileShellSettings();
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
MobileShellSettings::MobileShellSettings(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
m_config = KSharedConfig::openConfig(CONFIG_FILE, KConfig::SimpleConfig);
|
||||||
|
m_configWatcher = KConfigWatcher::create(m_config);
|
||||||
|
|
||||||
|
connect(m_configWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) -> void {
|
||||||
|
if (group.name() == GENERAL_CONFIG_GROUP) {
|
||||||
|
Q_EMIT navigationPanelEnabledChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MobileShellSettings::navigationPanelEnabled() const
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
return group.readEntry("navigationPanelEnabled", true);
|
||||||
|
}
|
||||||
32
components/mobileshell/mobileshellsettings.h
Normal file
32
components/mobileshell/mobileshellsettings.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KConfigWatcher>
|
||||||
|
#include <KSharedConfig>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class MobileShellSettings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool navigationPanelEnabled READ navigationPanelEnabled NOTIFY navigationPanelEnabledChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MobileShellSettings *self();
|
||||||
|
|
||||||
|
MobileShellSettings(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool navigationPanelEnabled() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void navigationPanelEnabledChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
KConfigWatcher::Ptr m_configWatcher;
|
||||||
|
KSharedConfig::Ptr m_config;
|
||||||
|
};
|
||||||
49
components/mobileshell/qml/Shell.qml
Normal file
49
components/mobileshell/qml/Shell.qml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Window 2.15
|
||||||
|
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to the homescreen plasmoid containment within the shell.
|
||||||
|
*/
|
||||||
|
QtObject {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top margin from the screen edge where application windows would display.
|
||||||
|
*/
|
||||||
|
readonly property real topMargin: TopPanelControls.panelHeight
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bottom margin from the screen edge where application windows would display.
|
||||||
|
*/
|
||||||
|
readonly property real bottomMargin: TaskPanelControls.isPortrait ? TaskPanelControls.panelHeight : 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Left margin from the screen edge where application windows would display.
|
||||||
|
*/
|
||||||
|
readonly property real leftMargin: 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Right margin from the screen edge where application windows would display.
|
||||||
|
*/
|
||||||
|
readonly property real rightMargin: !TaskPanelControls.isPortrait ? TaskPanelControls.panelWidth : 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Orientation of the mobile device.
|
||||||
|
*/
|
||||||
|
readonly property int orientation: TaskPanelControls.isPortrait ? Shell.Portrait : Shell.Landscape
|
||||||
|
|
||||||
|
enum Orientation {
|
||||||
|
Landscape,
|
||||||
|
Portrait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ pragma Singleton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to the taskpanel plasmoid containment within the shell.
|
* Provides access to the taskpanel plasmoid containment within the shell.
|
||||||
|
* Properties are updated by the taskpanel containment.
|
||||||
*/
|
*/
|
||||||
QtObject {
|
QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
|
||||||
|
* SPDX-FileCopyrightText: 2022 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.2
|
||||||
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
|
import org.kde.taskmanager 0.1 as TaskManager
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.kquickcontrolsaddons 2.0
|
||||||
|
|
||||||
|
import org.kde.plasma.private.nanoshell 2.0 as NanoShell
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var taskSwitcher
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
drag.filterChildren: true
|
||||||
|
|
||||||
|
// drag gesture
|
||||||
|
property int oldMouseY: 0
|
||||||
|
property int startMouseY: 0
|
||||||
|
property int oldMouseX: 0
|
||||||
|
property int startMouseX: 0
|
||||||
|
property bool opening: false
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
startMouseX = oldMouseX = mouse.y;
|
||||||
|
startMouseY = oldMouseY = mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
if (!opening && Math.abs(startMouseY - oldMouseY) < root.height) {
|
||||||
|
oldMouseY = mouse.y;
|
||||||
|
return;
|
||||||
|
} else if (mouseArea.pressed) {
|
||||||
|
opening = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.taskSwitcher.visible) {
|
||||||
|
// update task switcher drag
|
||||||
|
let offsetY = (mouse.y - oldMouseY) * 0.5; // we want to make the gesture take a longer swipe than it being pixel perfect
|
||||||
|
let offsetX = (mouse.x - oldMouseX) * 0.7; // we want to make the gesture not too hard to swipe, but not too easy
|
||||||
|
taskSwitcher.taskSwitcherState.yPosition = Math.max(0, taskSwitcher.taskSwitcherState.yPosition - offsetY);
|
||||||
|
taskSwitcher.taskSwitcherState.xPosition -= offsetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root.taskSwitcher.visible && Math.abs(startMouseY - mouse.y) > PlasmaCore.Units.gridUnit && taskSwitcher.tasksCount) {
|
||||||
|
// start task switcher gesture
|
||||||
|
root.taskSwitcher.show(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
oldMouseY = mouse.y;
|
||||||
|
oldMouseX = mouse.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (taskSwitcher.taskSwitcherState.currentlyBeingOpened) {
|
||||||
|
taskSwitcher.taskSwitcherState.updateState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -20,6 +20,7 @@ import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool shadow: false
|
||||||
property color backgroundColor
|
property color backgroundColor
|
||||||
property var foregroundColorGroup
|
property var foregroundColorGroup
|
||||||
|
|
||||||
|
|
@ -32,7 +33,7 @@ Item {
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
anchors.fill: mouseArea
|
anchors.fill: mouseArea
|
||||||
visible: !showingApp
|
visible: shadow
|
||||||
cached: true
|
cached: true
|
||||||
horizontalOffset: 0
|
horizontalOffset: 0
|
||||||
verticalOffset: 1
|
verticalOffset: 1
|
||||||
|
|
@ -166,7 +167,7 @@ Item {
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "landscape"
|
name: "landscape"
|
||||||
when: Screen.width > Screen.height
|
when: root.width < root.height
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: icons
|
target: icons
|
||||||
buttonLength: icons.height * 0.8 / 3
|
buttonLength: icons.height * 0.8 / 3
|
||||||
|
|
@ -204,7 +205,7 @@ Item {
|
||||||
}
|
}
|
||||||
}, State {
|
}, State {
|
||||||
name: "portrait"
|
name: "portrait"
|
||||||
when: Screen.width <= Screen.height
|
when: root.width >= root.height
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: icons
|
target: icons
|
||||||
buttonLength: icons.width * 0.8 / 3
|
buttonLength: icons.width * 0.8 / 3
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ singleton VolumeProvider 1.0 dataproviders/VolumeProvider.qml
|
||||||
singleton WifiProvider 1.0 dataproviders/WifiProvider.qml
|
singleton WifiProvider 1.0 dataproviders/WifiProvider.qml
|
||||||
|
|
||||||
# /navigationpanel
|
# /navigationpanel
|
||||||
|
NavigationGestureArea 1.0 navigationpanel/NavigationGestureArea.qml
|
||||||
NavigationPanel 1.0 navigationpanel/NavigationPanel.qml
|
NavigationPanel 1.0 navigationpanel/NavigationPanel.qml
|
||||||
NavigationPanelAction 1.0 navigationpanel/NavigationPanelAction.qml
|
NavigationPanelAction 1.0 navigationpanel/NavigationPanelAction.qml
|
||||||
|
|
||||||
|
|
@ -40,5 +41,6 @@ NotificationsModelType 1.0 widgets/notifications/NotificationsModelType.qml
|
||||||
|
|
||||||
# /
|
# /
|
||||||
singleton HomeScreenControls 1.0 HomeScreenControls.qml
|
singleton HomeScreenControls 1.0 HomeScreenControls.qml
|
||||||
|
singleton Shell 1.0 Shell.qml
|
||||||
singleton TaskPanelControls 1.0 TaskPanelControls.qml
|
singleton TaskPanelControls 1.0 TaskPanelControls.qml
|
||||||
singleton TopPanelControls 1.0 TopPanelControls.qml
|
singleton TopPanelControls 1.0 TopPanelControls.qml
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@ Item {
|
||||||
|
|
||||||
// account for system header and footer offset (center the preview image)
|
// account for system header and footer offset (center the preview image)
|
||||||
y: {
|
y: {
|
||||||
let headerHeight = MobileShell.TopPanelControls.panelHeight;
|
let headerHeight = MobileShell.Shell.topMargin;
|
||||||
let footerHeight = MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0;
|
let footerHeight = MobileShell.Shell.bottomMargin;
|
||||||
let diff = headerHeight - footerHeight;
|
let diff = headerHeight - footerHeight;
|
||||||
|
|
||||||
let baseY = (taskSwitcher.height / 2) - (height / 2) - (taskSwitcherState.taskHeaderHeight / 2)
|
let baseY = (taskSwitcher.height / 2) - (height / 2) - (taskSwitcherState.taskHeaderHeight / 2)
|
||||||
|
|
|
||||||
|
|
@ -166,9 +166,10 @@ Item {
|
||||||
|
|
||||||
// provide shell margins
|
// provide shell margins
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.rightMargin: MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth
|
anchors.leftMargin: MobileShell.Shell.leftMargin
|
||||||
anchors.bottomMargin: MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0
|
anchors.rightMargin: MobileShell.Shell.rightMargin
|
||||||
anchors.topMargin: MobileShell.TopPanelControls.panelHeight
|
anchors.bottomMargin: MobileShell.Shell.bottomMargin
|
||||||
|
anchors.topMargin: MobileShell.Shell.topMargin
|
||||||
|
|
||||||
FlickContainer {
|
FlickContainer {
|
||||||
id: flickable
|
id: flickable
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ QtObject {
|
||||||
// ~~ measurement constants ~~
|
// ~~ measurement constants ~~
|
||||||
|
|
||||||
// dimensions of a real window on the screen
|
// dimensions of a real window on the screen
|
||||||
readonly property real windowHeight: taskSwitcher.height - (MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0) - MobileShell.TopPanelControls.panelHeight
|
readonly property real windowHeight: taskSwitcher.height - MobileShell.Shell.topMargin - MobileShell.Shell.bottomMargin
|
||||||
readonly property real windowWidth: taskSwitcher.width - (MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth)
|
readonly property real windowWidth: taskSwitcher.width - MobileShell.Shell.leftMargin - MobileShell.Shell.rightMargin
|
||||||
|
|
||||||
// dimensions of the task previews
|
// dimensions of the task previews
|
||||||
readonly property real previewHeight: windowHeight * scalingFactor
|
readonly property real previewHeight: windowHeight * scalingFactor
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,10 @@ Item {
|
||||||
id: flickable
|
id: flickable
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: MobileShell.TopPanelControls.panelHeight
|
anchors.topMargin: MobileShell.Shell.topMargin
|
||||||
anchors.bottomMargin: MobileShell.TaskPanelControls.isPortrait ? MobileShell.TaskPanelControls.panelHeight : 0
|
anchors.bottomMargin: MobileShell.Shell.bottomMargin
|
||||||
anchors.rightMargin: MobileShell.TaskPanelControls.isPortrait ? 0 : MobileShell.TaskPanelControls.panelWidth
|
anchors.leftMargin: MobileShell.Shell.leftMargin
|
||||||
|
anchors.rightMargin: MobileShell.Shell.rightMargin
|
||||||
|
|
||||||
contentHeight: flickable.height + root.closedContentY + 999999
|
contentHeight: flickable.height + root.closedContentY + 999999
|
||||||
contentY: root.closedContentY
|
contentY: root.closedContentY
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021-2022 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 org.kde.plasma.plasmoid 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
import org.kde.plasma.private.mobileshell 1.0 as MobileShell
|
||||||
|
|
||||||
|
MobileShell.NavigationPanel {
|
||||||
|
id: root
|
||||||
|
property bool appIsShown: !plasmoid.nativeInterface.allMinimized
|
||||||
|
|
||||||
|
// background is:
|
||||||
|
// - opaque if an app is shown
|
||||||
|
// - translucent if the task switcher is open
|
||||||
|
// - transparent if on the homescreen
|
||||||
|
backgroundColor: {
|
||||||
|
if (root.taskSwitcher.visible) {
|
||||||
|
return Qt.rgba(0, 0, 0, 0.1);
|
||||||
|
} else {
|
||||||
|
return appIsShown ? PlasmaCore.ColorScope.backgroundColor : "transparent";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foregroundColorGroup: (!root.taskSwitcher.visible && appIsShown) ? PlasmaCore.Theme.NormalColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
||||||
|
shadow: !appIsShown
|
||||||
|
|
||||||
|
// do not enable drag gesture when task switcher is already open
|
||||||
|
// also don't disable drag gesture mid-drag
|
||||||
|
dragGestureEnabled: !root.taskSwitcher.visible || root.taskSwitcher.taskSwitcherState.currentlyBeingOpened
|
||||||
|
|
||||||
|
// ~~~~
|
||||||
|
// navigation panel actions
|
||||||
|
|
||||||
|
// toggle task switcher button
|
||||||
|
leftAction: MobileShell.NavigationPanelAction {
|
||||||
|
id: taskSwitcherAction
|
||||||
|
|
||||||
|
enabled: (root.taskSwitcher.tasksCount > 0) || root.taskSwitcher.visible
|
||||||
|
iconSource: "mobile-task-switcher"
|
||||||
|
iconSizeFactor: 0.75
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
plasmoid.nativeInterface.showDesktop = false;
|
||||||
|
|
||||||
|
if (!root.taskSwitcher.visible) {
|
||||||
|
root.taskSwitcher.show(true);
|
||||||
|
} else {
|
||||||
|
// when task switcher is open
|
||||||
|
if (root.taskSwitcher.taskSwitcherState.wasInActiveTask) {
|
||||||
|
// restore active window
|
||||||
|
root.taskSwitcher.activateWindow(taskSwitcher.taskSwitcherState.currentTaskIndex);
|
||||||
|
} else {
|
||||||
|
root.taskSwitcher.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// home button
|
||||||
|
middleAction: MobileShell.NavigationPanelAction {
|
||||||
|
id: homeAction
|
||||||
|
|
||||||
|
enabled: true
|
||||||
|
iconSource: "start-here-kde"
|
||||||
|
iconSizeFactor: 1
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
MobileShell.HomeScreenControls.openHomeScreen();
|
||||||
|
plasmoid.nativeInterface.allMinimizedChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close app/keyboard button
|
||||||
|
rightAction: MobileShell.NavigationPanelAction {
|
||||||
|
id: closeAppAction
|
||||||
|
|
||||||
|
enabled: MobileShell.KWinVirtualKeyboard.visible || root.taskSwitcher.visible || plasmoid.nativeInterface.hasCloseableActiveWindow
|
||||||
|
iconSource: MobileShell.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: MobileShell.KWinVirtualKeyboard.visible ? 1 : 0.75
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
if (MobileShell.KWinVirtualKeyboard.active) {
|
||||||
|
// close keyboard if it is open
|
||||||
|
MobileShell.KWinVirtualKeyboard.active = false;
|
||||||
|
} else if (taskSwitcher.visible) {
|
||||||
|
// if task switcher is open, close the current window shown
|
||||||
|
let indexToClose = root.taskSwitcher.tasksModel.index(root.taskSwitcher.currentTaskIndex, 0);
|
||||||
|
root.taskSwitcher.tasksModel.requestClose(indexToClose);
|
||||||
|
|
||||||
|
} else if (plasmoid.nativeInterface.hasCloseableActiveWindow) {
|
||||||
|
// if task switcher is closed, but there is an active window
|
||||||
|
if (root.taskSwitcher.tasksModel.activeTask !== 0) {
|
||||||
|
root.taskSwitcher.tasksModel.requestClose(root.taskSwitcher.tasksModel.activeTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.15
|
||||||
import QtGraphicalEffects 1.12
|
import QtGraphicalEffects 1.12
|
||||||
|
|
||||||
import org.kde.taskmanager 0.1 as TaskManager
|
import org.kde.taskmanager 0.1 as TaskManager
|
||||||
|
|
@ -21,17 +21,32 @@ import org.kde.plasma.phone.taskpanel 1.0 as TaskPanel
|
||||||
|
|
||||||
PlasmaCore.ColorScope {
|
PlasmaCore.ColorScope {
|
||||||
id: root
|
id: root
|
||||||
colorGroup: showingApp ? PlasmaCore.Theme.HeaderColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
width: 360
|
||||||
|
|
||||||
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
|
// contrasting colour
|
||||||
|
colorGroup: !plasmoid.nativeInterface.allMinimized ? PlasmaCore.Theme.HeaderColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
||||||
|
|
||||||
readonly property color backgroundColor: PlasmaCore.ColorScope.backgroundColor
|
readonly property color backgroundColor: PlasmaCore.ColorScope.backgroundColor
|
||||||
readonly property bool showingApp: !plasmoid.nativeInterface.allMinimized
|
|
||||||
|
|
||||||
readonly property bool hasTasks: tasksModel.count > 0
|
|
||||||
|
|
||||||
property var taskSwitcher: MobileShell.HomeScreenControls.taskSwitcher
|
|
||||||
|
|
||||||
|
Plasmoid.backgroundHints: PlasmaCore.Types.NoBackground
|
||||||
|
|
||||||
|
// toggle visibility of navigation bar (show, or use gestures only)
|
||||||
|
Binding {
|
||||||
|
target: plasmoid.Window.window // assumed to be plasma-workspace "PanelView" component
|
||||||
|
property: "visibilityMode"
|
||||||
|
// 0 - VisibilityMode.NormalPanel
|
||||||
|
// 3 - VisibilityMode.WindowsGoBelow
|
||||||
|
value: MobileShell.MobileShellSettings.navigationPanelEnabled ? 0 : 3
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: plasmoid.Window.window // assumed to be plasma-workspace "PanelView" component
|
||||||
|
property: "thickness"
|
||||||
|
// height of panel:
|
||||||
|
// - if navigation panel is enabled: PlasmaCore.Units.gridUnit * 2
|
||||||
|
// - if gestures only is enabled: 8 (just large enough for touch swipe to register, without blocking app content)
|
||||||
|
value: MobileShell.MobileShellSettings.navigationPanelEnabled ? PlasmaCore.Units.gridUnit * 2 : 8
|
||||||
|
}
|
||||||
|
|
||||||
//BEGIN API implementation
|
//BEGIN API implementation
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
|
|
@ -42,160 +57,69 @@ PlasmaCore.ColorScope {
|
||||||
Binding {
|
Binding {
|
||||||
target: MobileShell.TaskPanelControls
|
target: MobileShell.TaskPanelControls
|
||||||
property: "panelHeight"
|
property: "panelHeight"
|
||||||
value: root.height
|
value: MobileShell.MobileShellSettings.navigationPanelEnabled ? root.height : 0
|
||||||
}
|
}
|
||||||
Binding {
|
Binding {
|
||||||
target: MobileShell.TaskPanelControls
|
target: MobileShell.TaskPanelControls
|
||||||
property: "panelWidth"
|
property: "panelWidth"
|
||||||
value: root.width
|
value: MobileShell.MobileShellSettings.navigationPanelEnabled ? root.width : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//END API implementation
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: plasmoid.nativeInterface
|
target: plasmoid.nativeInterface
|
||||||
function onAllMinimizedChanged() {
|
function onAllMinimizedChanged() {
|
||||||
MobileShell.HomeScreenControls.homeScreenVisible = plasmoid.nativeInterface.allMinimized
|
MobileShell.HomeScreenControls.homeScreenVisible = plasmoid.nativeInterface.allMinimized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager.TasksModel {
|
//END API implementation
|
||||||
id: tasksModel
|
|
||||||
groupMode: TaskManager.TasksModel.GroupDisabled
|
|
||||||
|
|
||||||
screenGeometry: plasmoid.screenGeometry
|
|
||||||
sortMode: TaskManager.TasksModel.SortAlpha
|
|
||||||
|
|
||||||
virtualDesktop: virtualDesktopInfo.currentDesktop
|
|
||||||
activity: activityInfo.currentActivity
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskManager.VirtualDesktopInfo {
|
|
||||||
id: virtualDesktopInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskManager.ActivityInfo {
|
|
||||||
id: activityInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
Window.onWindowChanged: {
|
Window.onWindowChanged: {
|
||||||
if (!Window.window)
|
if (!Window.window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// ensure that Plasma sets the correct offset
|
||||||
Window.window.offset = Qt.binding(() => {
|
Window.window.offset = Qt.binding(() => {
|
||||||
return plasmoid.formFactor === PlasmaCore.Types.Vertical ? MobileShell.TopPanelControls.panelHeight : 0
|
return (plasmoid.formFactor === PlasmaCore.Types.Vertical) ? MobileShell.TopPanelControls.panelHeight : MobileShell.TopPanelControls.panelWidth
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// navigation panel actions
|
// bottom navigation panel component
|
||||||
MobileShell.NavigationPanelAction {
|
Component {
|
||||||
id: taskSwitcherAction
|
id: navigationPanel
|
||||||
|
NavigationPanelComponent {
|
||||||
enabled: hasTasks || taskSwitcher.visible
|
taskSwitcher: MobileShell.HomeScreenControls.taskSwitcher
|
||||||
iconSource: "mobile-task-switcher"
|
|
||||||
iconSizeFactor: 0.75
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
plasmoid.nativeInterface.showDesktop = false;
|
|
||||||
|
|
||||||
if (!taskSwitcher.visible) {
|
|
||||||
taskSwitcher.show(true);
|
|
||||||
} else {
|
|
||||||
// when task switcher is open
|
|
||||||
if (taskSwitcher.taskSwitcherState.wasInActiveTask) {
|
|
||||||
// restore active window
|
|
||||||
taskSwitcher.activateWindow(taskSwitcher.taskSwitcherState.currentTaskIndex);
|
|
||||||
} else {
|
|
||||||
taskSwitcher.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileShell.NavigationPanelAction {
|
// bottom navigation gesture area component
|
||||||
id: homeAction
|
Component {
|
||||||
|
id: navigationGesture
|
||||||
enabled: true
|
MobileShell.NavigationGestureArea {
|
||||||
iconSource: "start-here-kde"
|
taskSwitcher: MobileShell.HomeScreenControls.taskSwitcher
|
||||||
iconSizeFactor: 1
|
|
||||||
onTriggered: {
|
|
||||||
MobileShell.HomeScreenControls.openHomeScreen();
|
|
||||||
plasmoid.nativeInterface.allMinimizedChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileShell.NavigationPanelAction {
|
// load appropriate system navigation component
|
||||||
id: closeAppAction
|
Loader {
|
||||||
|
id: navigationLoader
|
||||||
enabled: MobileShell.KWinVirtualKeyboard.visible || taskSwitcher.visible || plasmoid.nativeInterface.hasCloseableActiveWindow
|
|
||||||
// mobile-close-app (from plasma-frameworks) seems to have less margins than icons from breeze-icons
|
|
||||||
iconSizeFactor: MobileShell.KWinVirtualKeyboard.visible ? 1 : 0.75
|
|
||||||
iconSource: MobileShell.KWinVirtualKeyboard.visible ? "go-down-symbolic" : "mobile-close-app"
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (MobileShell.KWinVirtualKeyboard.active) {
|
|
||||||
// close keyboard if it is open
|
|
||||||
MobileShell.KWinVirtualKeyboard.active = false;
|
|
||||||
} else if (taskSwitcher.visible) {
|
|
||||||
|
|
||||||
// if task switcher is open, close the current window shown
|
|
||||||
taskSwitcher.tasksModel.requestClose(taskSwitcher.tasksModel.index(taskSwitcher.currentTaskIndex, 0));
|
|
||||||
|
|
||||||
} else if (plasmoid.nativeInterface.hasCloseableActiveWindow) {
|
|
||||||
|
|
||||||
// if task switcher is closed, but there is an active window
|
|
||||||
var index = taskSwitcher.tasksModel.activeTask;
|
|
||||||
if (index) {
|
|
||||||
taskSwitcher.tasksModel.requestClose(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// bottom navigation panel
|
|
||||||
MobileShell.NavigationPanel {
|
|
||||||
id: panel
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
taskSwitcher: root.taskSwitcher
|
sourceComponent: MobileShell.MobileShellSettings.navigationPanelEnabled ? navigationPanel : navigationGesture
|
||||||
|
|
||||||
backgroundColor: {
|
|
||||||
if (taskSwitcher.visible) {
|
|
||||||
return Qt.rgba(0, 0, 0, 0.1);
|
|
||||||
} else {
|
|
||||||
return root.showingApp ? root.backgroundColor : "transparent";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foregroundColorGroup: (!taskSwitcher.visible && root.showingApp) ? PlasmaCore.Theme.NormalColorGroup : PlasmaCore.Theme.ComplementaryColorGroup
|
|
||||||
|
|
||||||
// do not enable drag gesture when task switcher is already open
|
|
||||||
// also don't disable drag gesture mid-drag
|
|
||||||
dragGestureEnabled: !taskSwitcher.visible || taskSwitcher.taskSwitcherState.currentlyBeingOpened
|
|
||||||
|
|
||||||
leftAction: taskSwitcherAction
|
|
||||||
middleAction: homeAction
|
|
||||||
rightAction: closeAppAction
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// landscape vs. portrait orientation of panel
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "landscape"
|
name: "landscape"
|
||||||
when: Screen.width > Screen.height
|
when: MobileShell.Shell.orientation === MobileShell.Shell.Landscape
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: plasmoid.nativeInterface
|
target: plasmoid.nativeInterface
|
||||||
location: PlasmaCore.Types.RightEdge
|
// only show on right edge if gestures are not enabled
|
||||||
}
|
location: MobileShell.MobileShellSettings.navigationPanelEnabled ? PlasmaCore.Types.RightEdge : PlasmaCore.Types.BottomEdge
|
||||||
PropertyChanges {
|
|
||||||
target: plasmoid
|
|
||||||
width: PlasmaCore.Units.gridUnit
|
|
||||||
height: PlasmaCore.Units.gridUnit
|
|
||||||
}
|
}
|
||||||
}, State {
|
}, State {
|
||||||
name: "portrait"
|
name: "portrait"
|
||||||
when: Screen.width <= Screen.height
|
when: MobileShell.Shell.orientation === MobileShell.Shell.Portrait
|
||||||
PropertyChanges {
|
|
||||||
target: plasmoid
|
|
||||||
height: PlasmaCore.Units.gridUnit
|
|
||||||
}
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: plasmoid.nativeInterface
|
target: plasmoid.nativeInterface
|
||||||
location: PlasmaCore.Types.BottomEdge
|
location: PlasmaCore.Types.BottomEdge
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ void TaskPanel::initWayland()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_showingDesktop = showing;
|
m_showingDesktop = showing;
|
||||||
emit showingDesktopChanged(m_showingDesktop);
|
Q_EMIT showingDesktopChanged(m_showingDesktop);
|
||||||
});
|
});
|
||||||
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged, m_activeTimer, qOverload<>(&QTimer::start));
|
connect(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::activeWindowChanged, m_activeTimer, qOverload<>(&QTimer::start));
|
||||||
|
|
||||||
|
|
@ -115,10 +115,17 @@ void TaskPanel::setPanel(QWindow *panel)
|
||||||
}
|
}
|
||||||
m_panel = panel;
|
m_panel = panel;
|
||||||
connect(m_panel, &QWindow::visibilityChanged, this, &TaskPanel::updatePanelVisibility, Qt::QueuedConnection);
|
connect(m_panel, &QWindow::visibilityChanged, this, &TaskPanel::updatePanelVisibility, Qt::QueuedConnection);
|
||||||
emit panelChanged();
|
Q_EMIT panelChanged();
|
||||||
updatePanelVisibility();
|
updatePanelVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskPanel::setPanelHeight(qreal height)
|
||||||
|
{
|
||||||
|
if (m_panel) {
|
||||||
|
m_panel->setHeight(height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TaskPanel::updatePanelVisibility()
|
void TaskPanel::updatePanelVisibility()
|
||||||
{
|
{
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
|
|
@ -163,10 +170,10 @@ void TaskPanel::updateActiveWindow()
|
||||||
}
|
}
|
||||||
if (newAllMinimized != m_allMinimized) {
|
if (newAllMinimized != m_allMinimized) {
|
||||||
m_allMinimized = newAllMinimized;
|
m_allMinimized = newAllMinimized;
|
||||||
emit allMinimizedChanged();
|
Q_EMIT allMinimizedChanged();
|
||||||
}
|
}
|
||||||
// TODO: connect to closeableChanged, not needed right now as KWin doesn't provide this changeable
|
// TODO: connect to closeableChanged, not needed right now as KWin doesn't provide this changeable
|
||||||
emit hasCloseableActiveWindowChanged();
|
Q_EMIT hasCloseableActiveWindowChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TaskPanel::hasCloseableActiveWindow() const
|
bool TaskPanel::hasCloseableActiveWindow() const
|
||||||
|
|
@ -181,7 +188,7 @@ void TaskPanel::forgetActiveWindow()
|
||||||
disconnect(m_activeWindow.data(), &KWayland::Client::PlasmaWindow::unmapped, this, &TaskPanel::forgetActiveWindow);
|
disconnect(m_activeWindow.data(), &KWayland::Client::PlasmaWindow::unmapped, this, &TaskPanel::forgetActiveWindow);
|
||||||
}
|
}
|
||||||
m_activeWindow.clear();
|
m_activeWindow.clear();
|
||||||
emit hasCloseableActiveWindowChanged();
|
Q_EMIT hasCloseableActiveWindowChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskPanel::closeActiveWindow()
|
void TaskPanel::closeActiveWindow()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ public:
|
||||||
QWindow *panel();
|
QWindow *panel();
|
||||||
void setPanel(QWindow *panel);
|
void setPanel(QWindow *panel);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setPanelHeight(qreal height);
|
||||||
|
|
||||||
Q_INVOKABLE void closeActiveWindow();
|
Q_INVOKABLE void closeActiveWindow();
|
||||||
|
|
||||||
bool isShowingDesktop() const
|
bool isShowingDesktop() const
|
||||||
|
|
|
||||||
4
kcms/CMakeLists.txt
Normal file
4
kcms/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
add_subdirectory(mobileshell)
|
||||||
88
kcms/mobileshell/.clang-format
Normal file
88
kcms/mobileshell/.clang-format
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
---
|
||||||
|
# SPDX-FileCopyrightText: 2019 Christoph Cullmann <cullmann@kde.org>
|
||||||
|
# SPDX-FileCopyrightText: 2019 Gernot Gebhard <gebhard@absint.com>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
# This file got automatically created by ECM, do not edit
|
||||||
|
# See https://clang.llvm.org/docs/ClangFormatStyleOptions.html for the config options
|
||||||
|
# and https://community.kde.org/Policies/Frameworks_Coding_Style#Clang-format_automatic_code_formatting
|
||||||
|
# for clang-format tips & tricks
|
||||||
|
---
|
||||||
|
Language: JavaScript
|
||||||
|
DisableFormat: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Style for C++
|
||||||
|
Language: Cpp
|
||||||
|
|
||||||
|
# base is WebKit coding style: https://webkit.org/code-style-guidelines/
|
||||||
|
# below are only things set that diverge from this style!
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
|
||||||
|
# enforce C++11 (e.g. for std::vector<std::vector<lala>>
|
||||||
|
Standard: Cpp11
|
||||||
|
|
||||||
|
# 4 spaces indent
|
||||||
|
TabWidth: 4
|
||||||
|
|
||||||
|
# 2 * 80 wide lines
|
||||||
|
ColumnLimit: 160
|
||||||
|
|
||||||
|
# sort includes inside line separated groups
|
||||||
|
SortIncludes: true
|
||||||
|
|
||||||
|
# break before braces on function, namespace and class definitions.
|
||||||
|
BreakBeforeBraces: Linux
|
||||||
|
|
||||||
|
# CrlInstruction *a;
|
||||||
|
PointerAlignment: Right
|
||||||
|
|
||||||
|
# horizontally aligns arguments after an open bracket.
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
|
||||||
|
# don't move all parameters to new line
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
|
||||||
|
# no single line functions
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
|
||||||
|
# always break before you encounter multi line strings
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
|
||||||
|
# don't move arguments to own lines if they are not all on the same
|
||||||
|
BinPackArguments: false
|
||||||
|
|
||||||
|
# don't move parameters to own lines if they are not all on the same
|
||||||
|
BinPackParameters: false
|
||||||
|
|
||||||
|
# In case we have an if statement with multiple lines the operator should be at the beginning of the line
|
||||||
|
# but we do not want to break assignments
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
|
||||||
|
# format C++11 braced lists like function calls
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
|
||||||
|
# do not put a space before C++11 braced lists
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
|
||||||
|
# remove empty lines
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
|
||||||
|
# no namespace indentation to keep indent level low
|
||||||
|
NamespaceIndentation: None
|
||||||
|
|
||||||
|
# we use template< without space.
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
|
||||||
|
# Always break after template declaration
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
|
||||||
|
# macros for which the opening brace stays attached.
|
||||||
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE , wl_resource_for_each, wl_resource_for_each_safe ]
|
||||||
|
|
||||||
|
# keep lambda formatting multi-line if not empty
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
|
||||||
|
# We do not want clang-format to put all arguments on a new line
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
50
kcms/mobileshell/CMakeLists.txt
Normal file
50
kcms/mobileshell/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
|
project(mobileshellkcm)
|
||||||
|
|
||||||
|
set(QT_MIN_VERSION "5.15.0")
|
||||||
|
set(KF5_MIN_VERSION "5.86.0")
|
||||||
|
|
||||||
|
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
|
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||||
|
|
||||||
|
include(KDEInstallDirs)
|
||||||
|
include(KDECMakeSettings)
|
||||||
|
include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
|
||||||
|
|
||||||
|
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
||||||
|
Quick
|
||||||
|
Svg
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
|
||||||
|
I18n
|
||||||
|
KCMUtils
|
||||||
|
Declarative
|
||||||
|
Config
|
||||||
|
)
|
||||||
|
|
||||||
|
set(mobileshellsettings_SRCS
|
||||||
|
kcm.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(kcm_mobileshell MODULE ${mobileshellsettings_SRCS})
|
||||||
|
|
||||||
|
target_link_libraries(kcm_mobileshell
|
||||||
|
Qt5::Core
|
||||||
|
KF5::CoreAddons
|
||||||
|
KF5::KCMUtils
|
||||||
|
KF5::I18n
|
||||||
|
KF5::QuickAddons
|
||||||
|
)
|
||||||
|
|
||||||
|
kcoreaddons_desktop_to_json(kcm_mobileshell "package/metadata.desktop")
|
||||||
|
|
||||||
|
install(TARGETS kcm_mobileshell DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms)
|
||||||
|
install(FILES package/metadata.desktop RENAME kcm_mobileshell.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) # Install the desktop file
|
||||||
|
|
||||||
|
|
||||||
|
kpackage_install_package(package kcm_mobileshell kcms) # Install our QML kpackage.
|
||||||
35
kcms/mobileshell/kcm.cpp
Normal file
35
kcms/mobileshell/kcm.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kcm.h"
|
||||||
|
|
||||||
|
#include <KPluginFactory>
|
||||||
|
|
||||||
|
K_PLUGIN_CLASS_WITH_JSON(KCMMobileShell, "metadata.json")
|
||||||
|
|
||||||
|
const QString CONFIG_FILE = QStringLiteral("plasmamobilerc");
|
||||||
|
const QString GENERAL_CONFIG_GROUP = QStringLiteral("General");
|
||||||
|
|
||||||
|
KCMMobileShell::KCMMobileShell(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
|
||||||
|
: KQuickAddons::ManagedConfigModule(parent, data, args)
|
||||||
|
, m_config{KSharedConfig::openConfig("plasmamobilerc", KConfig::SimpleConfig)}
|
||||||
|
{
|
||||||
|
setButtons(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KCMMobileShell::navigationPanelEnabled() const
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
return group.readEntry("navigationPanelEnabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCMMobileShell::setNavigationPanelEnabled(bool navigationPanelEnabled)
|
||||||
|
{
|
||||||
|
auto group = KConfigGroup{m_config, GENERAL_CONFIG_GROUP};
|
||||||
|
group.writeEntry("navigationPanelEnabled", navigationPanelEnabled, KConfigGroup::Notify);
|
||||||
|
m_config->sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "kcm.moc"
|
||||||
29
kcms/mobileshell/kcm.h
Normal file
29
kcms/mobileshell/kcm.h
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KQuickAddons/ManagedConfigModule>
|
||||||
|
#include <KSharedConfig>
|
||||||
|
|
||||||
|
class KCMMobileShell : public KQuickAddons::ManagedConfigModule
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool navigationPanelEnabled READ navigationPanelEnabled WRITE setNavigationPanelEnabled NOTIFY navigationPanelEnabledChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
KCMMobileShell(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
||||||
|
virtual ~KCMMobileShell() override = default;
|
||||||
|
|
||||||
|
bool navigationPanelEnabled() const;
|
||||||
|
void setNavigationPanelEnabled(bool navigationPanelEnabled);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void navigationPanelEnabledChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
KSharedConfig::Ptr m_config;
|
||||||
|
};
|
||||||
43
kcms/mobileshell/package/contents/ui/main.qml
Normal file
43
kcms/mobileshell/package/contents/ui/main.qml
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import QtQuick.Controls 2.15 as QQC2
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
import org.kde.kcm 1.3 as KCM
|
||||||
|
|
||||||
|
KCM.SimpleKCM {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: i18n("Shell")
|
||||||
|
|
||||||
|
leftPadding: Kirigami.Units.largeSpacing
|
||||||
|
rightPadding: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
|
Kirigami.FormLayout {
|
||||||
|
id: form
|
||||||
|
wideMode: false
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Kirigami.FormData.label: i18n("Navigation Panel")
|
||||||
|
Kirigami.FormData.isSection: true
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.CheckBox {
|
||||||
|
Kirigami.FormData.label: i18n("Remove panel (only use gestures):")
|
||||||
|
Layout.maximumWidth: form.width
|
||||||
|
text: checked ? i18n("On") : i18n("Off")
|
||||||
|
checked: !kcm.navigationPanelEnabled
|
||||||
|
onCheckStateChanged: {
|
||||||
|
if (checked != !kcm.navigationPanelEnabled) {
|
||||||
|
kcm.navigationPanelEnabled = !checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
kcms/mobileshell/package/metadata.desktop
Normal file
25
kcms/mobileshell/package/metadata.desktop
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Shell
|
||||||
|
Comment=Configure the system shell
|
||||||
|
Encoding=UTF-8
|
||||||
|
Type=Service
|
||||||
|
Icon=preferences-desktop-plasma
|
||||||
|
X-KDE-Library=kcm_mobileshell
|
||||||
|
X-KDE-ServiceTypes=KCModule
|
||||||
|
X-KDE-FormFactors=desktop,handset,tablet,mediacenter
|
||||||
|
X-Plasma-MainScript=ui/main.qml
|
||||||
|
X-KDE-System-Settings-Parent-Category=personalization
|
||||||
|
X-KDE-PluginInfo-Author=Devin Lin
|
||||||
|
X-KDE-PluginInfo-Email=espidev@gmail.com
|
||||||
|
X-KDE-PluginInfo-Name=kcm_cellular_network
|
||||||
|
X-KDE-PluginInfo-Version=0.1
|
||||||
|
X-KDE-PluginInfo-Website=https://plasma-mobile.org/
|
||||||
|
X-KDE-PluginInfo-Category=System Information
|
||||||
|
X-KDE-PluginInfo-License=GPL
|
||||||
|
X-KDE-PluginInfo-EnabledByDefault=true
|
||||||
|
X-KDE-Keywords=system,shell,panel
|
||||||
|
X-KDE-ParentApp=kcontrol
|
||||||
|
X-KDE-PluginInfo-Name=kcm_mobileshell
|
||||||
Loading…
Reference in a new issue