mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23:09 +00:00
Add task strip and Overview to navigation panel
In convergence mode, show a running-app icon strip in the navigation panel using the existing TaskManager.TasksModel. Each icon activates its window on click, with an indicator dot for the active window. Replace the mobile task switcher button with a KWin Overview trigger: add triggerOverview() to TaskPanel (D-Bus call to kglobalaccel), swap the button icon to view-grid-symbolic, and enable the Overview effect in the envmanager KWin config when convergence mode is active. Wire convergenceMode and taskModel properties from NavigationPanelComponent through to NavigationPanel so the task strip populates from the existing TasksModel instance.
This commit is contained in:
parent
60163ee15e
commit
5dfae0c45c
5 changed files with 112 additions and 5 deletions
|
|
@ -9,6 +9,7 @@ import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Window
|
import QtQuick.Window
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
|
import QtQuick.Controls as Controls
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
import org.kde.kirigami as Kirigami
|
||||||
import org.kde.taskmanager 0.1 as TaskManager
|
import org.kde.taskmanager 0.1 as TaskManager
|
||||||
|
|
@ -34,6 +35,10 @@ Item {
|
||||||
|
|
||||||
property bool isVertical: false
|
property bool isVertical: false
|
||||||
|
|
||||||
|
// Convergence mode: show running-app task strip
|
||||||
|
property bool convergenceMode: false
|
||||||
|
property var taskModel: null
|
||||||
|
|
||||||
// drop shadow for icons
|
// drop shadow for icons
|
||||||
MultiEffect {
|
MultiEffect {
|
||||||
anchors.fill: icons
|
anchors.fill: icons
|
||||||
|
|
@ -133,6 +138,63 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Running-app task strip for convergence (desktop) mode
|
||||||
|
ListView {
|
||||||
|
id: taskStrip
|
||||||
|
visible: root.convergenceMode && root.taskModel !== null && root.taskModel.count > 0
|
||||||
|
orientation: root.isVertical ? ListView.Vertical : ListView.Horizontal
|
||||||
|
spacing: Kirigami.Units.smallSpacing
|
||||||
|
clip: true
|
||||||
|
interactive: contentWidth > width
|
||||||
|
model: root.taskModel
|
||||||
|
|
||||||
|
delegate: NavigationPanelButton {
|
||||||
|
id: taskDelegate
|
||||||
|
required property int index
|
||||||
|
required property var model
|
||||||
|
width: taskStrip.orientation === ListView.Horizontal ? height : taskStrip.width
|
||||||
|
height: taskStrip.orientation === ListView.Horizontal ? taskStrip.height : taskStrip.width
|
||||||
|
|
||||||
|
Kirigami.Theme.colorSet: root.foregroundColorGroup
|
||||||
|
Kirigami.Theme.inherit: false
|
||||||
|
iconSource: taskDelegate.model.decoration
|
||||||
|
enabled: true
|
||||||
|
shrinkSize: 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.taskModel.requestActivate(root.taskModel.makeModelIndex(taskDelegate.index));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right-click context menu
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onClicked: taskContextMenu.popup()
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.Menu {
|
||||||
|
id: taskContextMenu
|
||||||
|
Controls.MenuItem {
|
||||||
|
text: i18n("Close")
|
||||||
|
icon.name: "window-close"
|
||||||
|
onTriggered: root.taskModel.requestClose(root.taskModel.makeModelIndex(taskDelegate.index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active-window indicator dot
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottomMargin: Kirigami.Units.smallSpacing / 2
|
||||||
|
width: Kirigami.Units.smallSpacing * 2
|
||||||
|
height: width
|
||||||
|
radius: width / 2
|
||||||
|
color: Kirigami.Theme.highlightColor
|
||||||
|
visible: taskDelegate.model.IsActive === true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
|
|
@ -200,6 +262,21 @@ Item {
|
||||||
height: Kirigami.Units.gridUnit * 2
|
height: Kirigami.Units.gridUnit * 2
|
||||||
width: icons.width
|
width: icons.width
|
||||||
}
|
}
|
||||||
|
// Task strip: vertical layout — positioned between leftCornerButton (bottom) and leftButton (above middle)
|
||||||
|
AnchorChanges {
|
||||||
|
target: taskStrip
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottom: leftButton.top
|
||||||
|
top: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: taskStrip
|
||||||
|
width: parent.width
|
||||||
|
// Fill space between leftCorner (bottom) and the nav button group
|
||||||
|
height: taskStrip.visible ? (leftButton.y - leftCornerButton.y - leftCornerButton.height - Kirigami.Units.smallSpacing * 2) : 0
|
||||||
|
}
|
||||||
}, State {
|
}, State {
|
||||||
name: "horizontal"
|
name: "horizontal"
|
||||||
when: !root.isVertical
|
when: !root.isVertical
|
||||||
|
|
@ -264,6 +341,19 @@ Item {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: Kirigami.Units.gridUnit * 2
|
width: Kirigami.Units.gridUnit * 2
|
||||||
}
|
}
|
||||||
|
// Task strip: horizontal layout — positioned between leftCornerButton (left) and leftButton (near center)
|
||||||
|
AnchorChanges {
|
||||||
|
target: taskStrip
|
||||||
|
anchors {
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
left: leftCornerButton.right
|
||||||
|
right: leftButton.left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: taskStrip
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ MobileShell.NavigationPanel {
|
||||||
foregroundColorGroup: forcedComplementary ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
|
foregroundColorGroup: forcedComplementary ? Kirigami.Theme.Complementary : Kirigami.Theme.Window
|
||||||
shadow: forcedComplementary
|
shadow: forcedComplementary
|
||||||
|
|
||||||
|
// Convergence mode: expose running-app task strip
|
||||||
|
convergenceMode: ShellSettings.Settings.convergenceModeEnabled
|
||||||
|
taskModel: tasksModel
|
||||||
|
|
||||||
MobileShellState.PanelSettingsDBusClient {
|
MobileShellState.PanelSettingsDBusClient {
|
||||||
id: panelSettings
|
id: panelSettings
|
||||||
screenName: Screen.name
|
screenName: Screen.name
|
||||||
|
|
@ -68,16 +72,20 @@ MobileShell.NavigationPanel {
|
||||||
// ~~~~
|
// ~~~~
|
||||||
// navigation panel actions
|
// navigation panel actions
|
||||||
|
|
||||||
// toggle task switcher button
|
// toggle task switcher button (KWin Overview in convergence mode, mobile task switcher otherwise)
|
||||||
leftAction: MobileShell.NavigationPanelAction {
|
leftAction: MobileShell.NavigationPanelAction {
|
||||||
id: taskSwitcherAction
|
id: taskSwitcherAction
|
||||||
|
|
||||||
enabled: true
|
enabled: true
|
||||||
iconSource: "mobile-task-switcher"
|
iconSource: ShellSettings.Settings.convergenceModeEnabled ? "view-grid-symbolic" : "mobile-task-switcher"
|
||||||
shrinkSize: 4
|
shrinkSize: ShellSettings.Settings.convergenceModeEnabled ? 0 : 4
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
Plasmoid.triggerTaskSwitcher();
|
if (ShellSettings.Settings.convergenceModeEnabled) {
|
||||||
|
Plasmoid.triggerOverview();
|
||||||
|
} else {
|
||||||
|
Plasmoid.triggerTaskSwitcher();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,11 @@ void TaskPanel::triggerTaskSwitcher() const
|
||||||
QDBusConnection::sessionBus().send(message);
|
QDBusConnection::sessionBus().send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskPanel::triggerOverview() const
|
||||||
|
{
|
||||||
|
QDBusMessage message = QDBusMessage::createMethodCall("org.kde.kglobalaccel", "/component/kwin", "org.kde.kglobalaccel.Component", "invokeShortcut");
|
||||||
|
message.setArguments({QStringLiteral("Overview")});
|
||||||
|
QDBusConnection::sessionBus().send(message);
|
||||||
|
}
|
||||||
|
|
||||||
#include "taskpanel.moc"
|
#include "taskpanel.moc"
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@ class TaskPanel : public Plasma::Containment
|
||||||
public:
|
public:
|
||||||
TaskPanel(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
TaskPanel(QObject *parent, const KPluginMetaData &data, const QVariantList &args);
|
||||||
Q_INVOKABLE void triggerTaskSwitcher() const;
|
Q_INVOKABLE void triggerTaskSwitcher() const;
|
||||||
|
Q_INVOKABLE void triggerOverview() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ QMap<QString, QMap<QString, QVariant>> getKwinrcSettings(KSharedConfig::Ptr m_mo
|
||||||
{"blurEnabled", false}, // disable blur for performance reasons, we could reconsider in the future for more powerful devices
|
{"blurEnabled", false}, // disable blur for performance reasons, we could reconsider in the future for more powerful devices
|
||||||
{"convergentwindowsEnabled", true}, // enable our convergent window plugin
|
{"convergentwindowsEnabled", true}, // enable our convergent window plugin
|
||||||
{"mobiletaskswitcherEnabled", true}, // ensure the mobile task switcher plugin is enabled
|
{"mobiletaskswitcherEnabled", true}, // ensure the mobile task switcher plugin is enabled
|
||||||
|
{"overviewEnabled", convergenceModeEnabled}, // enable KWin Overview effect in convergence mode for desktop-style task switching
|
||||||
{"screenedgeEnabled", false} // disable the blue highlighting of screen edge effects. TODO would be nice if we could only deactivate it on
|
{"screenedgeEnabled", false} // disable the blue highlighting of screen edge effects. TODO would be nice if we could only deactivate it on
|
||||||
// touchscreen gestures and not mouse as well
|
// touchscreen gestures and not mouse as well
|
||||||
}},
|
}},
|
||||||
|
|
@ -76,7 +77,7 @@ QMap<QString, QMap<QString, QVariant>> getKwinrcSettings(KSharedConfig::Ptr m_mo
|
||||||
|
|
||||||
// Have a separate list here because we need to trigger DBus calls to load/unload each effect/script.
|
// Have a separate list here because we need to trigger DBus calls to load/unload each effect/script.
|
||||||
// Make sure that the effect/script is added to the kwinrc "Plugins" section above!
|
// Make sure that the effect/script is added to the kwinrc "Plugins" section above!
|
||||||
const QList<QString> KWIN_EFFECTS = {"blur", "mobiletaskswitcher", "screenedge"};
|
const QList<QString> KWIN_EFFECTS = {"blur", "mobiletaskswitcher", "overview", "screenedge"};
|
||||||
const QList<QString> KWIN_SCRIPTS = {"convergentwindows"};
|
const QList<QString> KWIN_SCRIPTS = {"convergentwindows"};
|
||||||
|
|
||||||
// .config/plasma-mobile/ksmserver - immutable settings:
|
// .config/plasma-mobile/ksmserver - immutable settings:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue