Commit 48a0fc37 authored by Jan Blackquill's avatar Jan Blackquill 🌈 Committed by Nate Graham
Browse files

applets/windowlist: rewrite

This rewrites the Window List applet, in order to
have simpler code, as well as having a more useful
design that tells the user what app is in focus.

BUG: 387582
BUG: 405087
parent 19b9d8f8
Pipeline #158892 passed with stage
in 2 minutes and 27 seconds
/*
* SPDX-FileCopyrightText: 2022 Carson Black <uhhadd@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.10
import QtQuick.Layouts 1.10
import QtQuick.Controls 2.10
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 3.0 as PC3
import org.kde.kirigami 2.12 as Kirigami
AbstractButton {
id: controlRoot
hoverEnabled: true
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.SecondaryControl
Kirigami.MnemonicData.label: controlRoot.text
leftPadding: rest.margins.left
rightPadding: rest.margins.right
// needed since icon property can't hold QIcon, which the tasks manager gives us
property alias iconSource: iconItem.source
background: Item {
id: background
PlasmaCore.FrameSvgItem {
id: rest
anchors.fill: parent
visible: !controlRoot.down && !controlRoot.hovered
imagePath: "widgets/menubaritem"
prefix: "normal"
}
PlasmaCore.FrameSvgItem {
id: hover
anchors.fill: parent
visible: !controlRoot.down && controlRoot.hovered
imagePath: "widgets/menubaritem"
prefix: "hover"
}
PlasmaCore.FrameSvgItem {
id: down
anchors.fill: parent
visible: controlRoot.down
imagePath: "widgets/menubaritem"
prefix: "pressed"
}
}
contentItem: RowLayout {
PlasmaCore.IconItem {
id: iconItem
visible: source !== ""
implicitWidth: PlasmaCore.Units.roundToIconSize(label.implicitHeight)
implicitHeight: PlasmaCore.Units.roundToIconSize(label.implicitHeight)
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
}
PC3.Label {
id: label
visible: plasmoid.formFactor === PlasmaCore.Types.Horizontal
text: controlRoot.Kirigami.MnemonicData.richTextLabel
verticalAlignment: Text.AlignVCenter
Layout.fillHeight: true
}
}
}
/*
SPDX-FileCopyrightText: 2016 Eike Hein <hein@kde.org>
SPDX-FileCopyrightText: 2022 Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick 2.15
import QtQuick.Layouts 1.10
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.extras 2.0 as PlasmaExtras
import org.kde.plasma.components 2.0 as PC2
import org.kde.plasma.components 3.0 as PC3
import org.kde.kirigami 2.12 as Kirigami
import org.kde.taskmanager 0.1 as TaskManager
import org.kde.kwindowsystem 1.0 as KWindowSystem
Item {
Plasmoid.constraintHints: PlasmaCore.Types.CanFillArea
Plasmoid.compactRepresentation: windowListButton
Plasmoid.fullRepresentation: windowListView
Plasmoid.switchWidth: PlasmaCore.Units.gridUnit * 8
Plasmoid.switchHeight: PlasmaCore.Units.gridUnit * 6
FocusScope {
id: root
Layout.minimumWidth: PlasmaCore.Units.gridUnit * 12
Layout.minimumHeight: PlasmaCore.Units.gridUnit * 12
Plasmoid.switchWidth: PlasmaCore.Units.gridUnit * 11
Plasmoid.switchHeight: PlasmaCore.Units.gridUnit * 11
Plasmoid.toolTipSubText: i18n("Show list of opened windows")
property int itemHeight: Math.ceil((Math.max(theme.mSize(theme.defaultFont).height, PlasmaCore.Units.iconSizes.small)
+ Math.max(highlightItemSvg.margins.top + highlightItemSvg.margins.bottom,
listItemSvg.margins.top + listItemSvg.margins.bottom)) / 2) * 2
TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortVirtualDesktop
groupMode: TaskManager.TasksModel.GroupDisabled
}
TaskManager.VirtualDesktopInfo {
id: virtualDesktopInfo
}
KWindowSystem.KWindowSystem {
id: windowSystem
}
PlasmaCore.FrameSvgItem {
id : highlightItemSvg
visible: false
imagePath: "widgets/viewitem"
prefix: "hover"
}
PlasmaCore.FrameSvgItem {
id : listItemSvg
visible: false
imagePath: "widgets/viewitem"
prefix: "normal"
}
Connections {
target: plasmoid
function onExpandedChanged(expanded) {
if (!expanded) {
windowListView.currentIndex = 0;
}
}
}
PlasmaExtras.ScrollArea {
anchors.fill: parent
focus: true
onFocusChanged: {
if (!focus) {
windowListView.currentIndex = -1;
}
}
Component {
id: windowListView
ListView {
id: windowListView
property bool overflowing: (visibleArea.heightRatio < 1.0)
property var pinTopItem: null
property var pinBottomItem: null
focus: true
model: tasksModel
boundsBehavior: Flickable.StopAtBounds
snapMode: ListView.SnapToItem
spacing: 0
keyNavigationWraps: true
highlight: PlasmaExtras.Highlight {}
highlightMoveDuration: 0
onOverflowingChanged: {
if (!overflowing) {
pinTopItem = null;
pinBottomItem = null;
}
}
onContentYChanged: {
pinTopItem = contentItem.childAt(0, contentY);
pinBottomItem = contentItem.childAt(0, contentY + windowPin.height);
}
section.property: virtualDesktopInfo.numberOfDesktops ? "VirtualDesktop" : undefined
section.criteria: ViewSection.FullString
section.delegate: PlasmaComponents.Label {
height: root.itemHeight
width: root.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
textFormat: Text.PlainText
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: {
if (section > 0) {
return virtualDesktopInfo.desktopNames[section - 1];
}
return i18n("On all desktops");
}
clip: true
Layout.preferredWidth: PlasmaCore.Units.gridUnit * 10
Layout.preferredHeight: PlasmaCore.Units.gridUnit * 12
model: TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortVirtualDesktop
groupMode: TaskManager.TasksModel.GroupDisabled
}
delegate: Kirigami.BasicListItem {
id: del
onClicked: tasksModel.requestActivate(tasksModel.makeModelIndex(model.index))
delegate: MouseArea {
id: item
height: root.itemHeight
width: windowListView.overflowing ? ListView.view.width - PlasmaCore.Units.smallSpacing : ListView.view.width
property bool underPin: (item == windowListView.pinTopItem || item == windowListView.pinBottomItem)
Accessible.role: Accessible.MenuItem
Accessible.name: label.text
hoverEnabled: true
onClicked: tasksModel.requestActivate(tasksModel.makeModelIndex(index))
onContainsMouseChanged: {
if (containsMouse) {
windowListView.focus = true;
windowListView.currentIndex = index;
}
}
Row {
anchors.left: parent.left
anchors.leftMargin: highlightItemSvg.margins.left
anchors.right: parent.right
anchors.rightMargin: highlightItemSvg.margins.right
height: parent.height
spacing: PlasmaCore.Units.smallSpacing * 2
LayoutMirroring.enabled: (Qt.application.layoutDirection == Qt.RightToLeft)
leading: Item {
width: iconItem.width
PlasmaCore.IconItem {
id: icon
anchors.verticalCenter: parent.verticalCenter
width: visible ? PlasmaCore.Units.iconSizes.small : 0
height: width
usesPlasmaTheme: false
id: iconItem
source: model.decoration
}
PlasmaComponents.Label {
id: label
visible: source !== ""
width: (parent.width - icon.width - parent.spacing - (underPin ? root.width - windowPin.x : 0))
height: parent.height
verticalAlignment: Text.AlignVCenter
textFormat: Text.PlainText
wrapMode: Text.NoWrap
elide: Text.ElideRight
text: model.display
}
}
Keys.onTabPressed: windowPin.focus = true
Keys.onBacktabPressed: windowPin.focus = true
Keys.onPressed: {
if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
event.accepted = true;
tasksModel.requestActivate(tasksModel.makeModelIndex(index))
anchors.top: parent.top
anchors.verticalCenter: parent.verticalCenter
if (!windowPin.checked) {
plasmoid.expanded = false;
}
implicitWidth: PlasmaCore.Units.roundToIconSize(parent.height)
implicitHeight: PlasmaCore.Units.roundToIconSize(parent.height)
}
}
text: model.display
}
}
}
PlasmaComponents.ToolButton {
id: windowPin
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: windowListView.overflowing ? PlasmaCore.Units.gridUnit : 0
width: Math.round(PlasmaCore.Units.gridUnit * 1.25)
height: width
iconSource: "window-pin"
visible: plasmoid.compactRepresentationItem && plasmoid.compactRepresentationItem.visible
checkable: true
onCheckedChanged: plasmoid.hideOnWindowDeactivate = !checked
Keys.onTabPressed: {
if (windowListView.count) {
windowListView.currentIndex = 0;
windowListView.forceActiveFocus();
Component {
id: windowListButton
MenuButton {
Layout.minimumWidth: implicitWidth
Layout.maximumWidth: implicitWidth
Layout.fillHeight: plasmoid.formFactor === PlasmaCore.Types.Horizontal
Layout.fillWidth: plasmoid.formFactor === PlasmaCore.Types.Vertical
onClicked: tasksMenu.open()
down: pressed || tasksMenu.status === PC2.DialogStatus.Open
text: if (tasksModel.activeTask.valid) {
return tasksModel.data(tasksModel.activeTask, TaskManager.AbstractTasksModel.AppName) ||
tasksModel.data(tasksModel.activeTask, 0 /* display name, window title if app name not present */)
} else return i18n("Plasma Desktop")
iconSource: if (tasksModel.activeTask.valid) {
return tasksModel.data(tasksModel.activeTask, 1 /* decorationrole */)
} else return ""
TaskManager.TasksModel {
id: tasksModel
sortMode: TaskManager.TasksModel.SortVirtualDesktop
groupMode: TaskManager.TasksModel.GroupDisabled
}
}
Keys.onBacktabPressed: cascadeButton.focus = true
Keys.onUpPressed: {
if (windowListView.count) {
windowListView.currentIndex = (windowListView.count - 1);
windowListView.forceActiveFocus();
}
}
PC2.ModelContextMenu {
id: tasksMenu
Keys.onDownPressed: {
if (windowListView.count) {
windowListView.currentIndex = 0;
windowListView.forceActiveFocus();
}
}
Keys.onLeftPressed: {
if (windowListView.count) {
windowListView.currentIndex = 0;
windowListView.forceActiveFocus();
}
}
Keys.onRightPressed: {
if (windowListView.count) {
windowListView.currentIndex = 0;
windowListView.forceActiveFocus();
model: tasksModel
onClicked: (model) =>
tasksModel.requestActivate(tasksModel.makeModelIndex(model.index))
}
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment