Advertisement
Gigsoll

KDE blure in main.qml

Feb 16th, 2023
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
QML 11.79 KB | Source Code | 0 0
  1. /*
  2.     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
  3.     SPDX-FileCopyrightText: 2022 Marco Martin <mart@kde.org>
  4.     SPDX-FileCopyrightText: 2022 ivan tkachenko <me@ratijas.tk>
  5.  
  6.     SPDX-License-Identifier: GPL-2.0-or-later
  7. */
  8.  
  9. import QtQuick 2.15
  10. import QtQuick.Layouts 1.15
  11. import QtQuick.Window 2.15
  12. import QtGraphicalEffects 1.15
  13. import org.kde.kwin 3.0 as KWinComponents
  14. import org.kde.kwin.private.effects 1.0
  15. import org.kde.plasma.core 2.0 as PlasmaCore
  16. import org.kde.plasma.components 3.0 as PC3
  17.  
  18. Rectangle {
  19.     id: container
  20.  
  21.     KWinComponents.DesktopBackgroundItem {
  22.         activity: KWinComponents.Workspace.currentActivity
  23.         desktop: KWinComponents.Workspace.currentVirtualDesktop
  24.         outputName: targetScreen.name
  25.         anchors.fill: parent
  26.         layer.enabled: true
  27.         layer.effect: FastBlur {
  28.             id: blur
  29.             source: backgroundItem
  30.             anchors.fill: backgroundItem
  31.             radius: 64
  32.         }
  33.     }
  34.  
  35.  
  36.     required property QtObject effect
  37.     required property QtObject targetScreen
  38.  
  39.     property bool animationEnabled: false
  40.     property bool organized: false
  41.  
  42.     /** Shared Drag&Drop store to keep track of DND state across desktops. */
  43.     property var dndManagerStore: ({})
  44.  
  45.     color: "black"
  46.  
  47.     function start() {
  48.         animationEnabled = true;
  49.         organized = true;
  50.     }
  51.  
  52.     function stop() {
  53.         organized = false;
  54.     }
  55.  
  56.     function switchTo(desktopId) {
  57.         KWinComponents.Workspace.currentDesktop = desktopId;
  58.         effect.deactivate(effect.animationDuration);
  59.     }
  60.  
  61.     function selectNext(direction) {
  62.         let currentIndex = 0
  63.         for (let i = 0; i < gridRepeater.count; i++) {
  64.             if (gridRepeater.itemAt(i).focus) {
  65.                 currentIndex = i;
  66.                 break;
  67.             }
  68.         }
  69.         let x = currentIndex % grid.columns;
  70.         let y = Math.floor(currentIndex / grid.columns);
  71.  
  72.         // the direction we move in is the opposite of the window to select
  73.         // i.e pressing left should select the rightmost window on the desktop
  74.         // to the left
  75.         let invertedDirection;
  76.         switch(direction) {
  77.             case WindowHeap.Direction.Up:
  78.                 y--;
  79.                 invertedDirection = WindowHeap.Direction.Down;
  80.                 break;
  81.             case WindowHeap.Direction.Down:
  82.                 y++
  83.                 invertedDirection = WindowHeap.Direction.Up;
  84.                 break;
  85.             case WindowHeap.Direction.Left:
  86.                 x--;
  87.                 invertedDirection = WindowHeap.Direction.Right;
  88.                 break;
  89.             case WindowHeap.Direction.Right:
  90.                 x++;
  91.                 invertedDirection = WindowHeap.Direction.Left;
  92.                 break;
  93.         }
  94.  
  95.         if (x < 0 || x >= grid.columns) {
  96.             return false;
  97.         }
  98.         if (y < 0 || y >= grid.rows) {
  99.             return false;
  100.         }
  101.         let newIndex = y * grid.columns + x;
  102.  
  103.         gridRepeater.itemAt(newIndex).focus = true;
  104.         gridRepeater.itemAt(newIndex).selectLastItem(invertedDirection);
  105.         return true;
  106.     }
  107.  
  108.     Keys.onPressed: {
  109.         if (event.key === Qt.Key_Escape) {
  110.             effect.deactivate(effect.animationDuration);
  111.         } else if (event.key === Qt.Key_Plus || event.key === Qt.Key_Equal) {
  112.             addButton.clicked();
  113.         } else if (event.key === Qt.Key_Minus) {
  114.             removeButton.clicked();
  115.         } else if (event.key >= Qt.Key_F1 && event.key <= Qt.Key_F12) {
  116.             const desktopId = (event.key - Qt.Key_F1) + 1;
  117.             switchTo(desktopId);
  118.         } else if (event.key >= Qt.Key_0 && event.key <= Qt.Key_9) {
  119.             const desktopId = event.key === Qt.Key_0 ? 10 : (event.key - Qt.Key_0);
  120.             switchTo(desktopId);
  121.         } else if (event.key === Qt.Key_Up) {
  122.             event.accepted = selectNext(WindowHeap.Direction.Up);
  123.             if (!event.accepted) {
  124.                 let view = effect.getView(Qt.TopEdge)
  125.                 if (view) {
  126.                     effect.activateView(view)
  127.                 }
  128.             }
  129.         } else if (event.key === Qt.Key_Down) {
  130.             event.accepted = selectNext(WindowHeap.Direction.Down);
  131.             if (!event.accepted) {
  132.                 let view = effect.getView(Qt.BottomEdge)
  133.                 if (view) {
  134.                     effect.activateView(view)
  135.                 }
  136.             }
  137.         } else if (event.key === Qt.Key_Left) {
  138.             event.accepted = selectNext(WindowHeap.Direction.Left);
  139.             if (!event.accepted) {
  140.                 let view = effect.getView(Qt.LeftEdge)
  141.                 if (view) {
  142.                     effect.activateView(view)
  143.                 }
  144.             }
  145.         } else if (event.key === Qt.Key_Right) {
  146.             event.accepted = selectNext(WindowHeap.Direction.Right);
  147.             if (!event.accepted) {
  148.                 let view = effect.getView(Qt.RightEdge)
  149.                 if (view) {
  150.                     effect.activateView(view)
  151.                 }
  152.             }
  153.         } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Space) {
  154.             for (let i = 0; i < gridRepeater.count; i++) {
  155.                 if (gridRepeater.itemAt(i).focus) {
  156.                     switchTo(gridRepeater.itemAt(i).desktop.x11DesktopNumber)
  157.                     break;
  158.                 }
  159.             }
  160.         }
  161.     }
  162.     Keys.priority: Keys.AfterItem
  163.  
  164.     KWinComponents.VirtualDesktopModel {
  165.         id: desktopModel
  166.     }
  167.     KWinComponents.ClientModel {
  168.         id: stackModel
  169.     }
  170.  
  171.     // A grid, not a gridlayout as a gridlayout positions its elements too late
  172.     Grid {
  173.         id: grid
  174.  
  175.         property Item currentItem
  176.         readonly property real targetScale: Math.min(parent.width / width, parent.height / height)
  177.         property real panelOpacity: 1
  178.  
  179.         Behavior on x {
  180.             enabled: !container.effect.gestureInProgress
  181.             NumberAnimation {
  182.                 duration: container.effect.animationDuration
  183.                 easing.type: Easing.OutCubic
  184.             }
  185.         }
  186.         Behavior on y {
  187.             enabled: !container.effect.gestureInProgress
  188.             NumberAnimation {
  189.                 duration: container.effect.animationDuration
  190.                 easing.type: Easing.OutCubic
  191.             }
  192.         }
  193.         Behavior on scale {
  194.             enabled: !container.effect.gestureInProgress
  195.             NumberAnimation {
  196.                 duration: container.effect.animationDuration
  197.                 easing.type: Easing.OutCubic
  198.             }
  199.         }
  200.         Behavior on panelOpacity {
  201.             enabled: !container.effect.gestureInProgress
  202.             NumberAnimation {
  203.                 duration: container.effect.animationDuration
  204.                 easing.type: Easing.OutCubic
  205.             }
  206.         }
  207.  
  208.         width: (parent.width + columnSpacing) * columns - columnSpacing
  209.         height: (parent.height + rowSpacing) * rows - rowSpacing
  210.         rowSpacing: PlasmaCore.Units.gridUnit
  211.         columnSpacing: PlasmaCore.Units.gridUnit
  212.         rows: container.effect.gridRows
  213.         columns: container.effect.gridColumns
  214.         transformOrigin: Item.TopLeft
  215.  
  216.         states: [
  217.             State {
  218.                 when: container.effect.gestureInProgress
  219.                 PropertyChanges {
  220.                     target: grid
  221.                     x: Math.max(0, container.width / 2 - (grid.width * grid.targetScale) / 2) * container.effect.partialActivationFactor - grid.currentItem.x * (1 - container.effect.partialActivationFactor)
  222.                     y: Math.max(0, container.height / 2 - (grid.height * grid.targetScale) / 2) * container.effect.partialActivationFactor - grid.currentItem.y * (1 - container.effect.partialActivationFactor)
  223.                     scale: 1 - (1 - grid.targetScale) * container.effect.partialActivationFactor
  224.                     panelOpacity: 1 - container.effect.partialActivationFactor
  225.                 }
  226.                 PropertyChanges {
  227.                     target: buttonsLayout
  228.                     opacity: container.effect.partialActivationFactor
  229.                 }
  230.             },
  231.             State {
  232.                 when: container.organized
  233.                 PropertyChanges {
  234.                     target: grid
  235.                     x: Math.max(0, container.width / 2 - (grid.width * grid.targetScale) / 2)
  236.                     y: Math.max(0, container.height / 2 - (grid.height * grid.targetScale) / 2)
  237.                     scale: grid.targetScale
  238.                     panelOpacity: 0
  239.                 }
  240.                 PropertyChanges {
  241.                     target: buttonsLayout
  242.                     opacity: 1
  243.                 }
  244.             },
  245.             State {
  246.                 when: !container.organized
  247.                 PropertyChanges {
  248.                     target: grid
  249.                     x: -grid.currentItem.x
  250.                     y: -grid.currentItem.y
  251.                     scale: 1
  252.                     panelOpacity: 1
  253.                 }
  254.                 PropertyChanges {
  255.                     target: buttonsLayout
  256.                     opacity: 0
  257.                 }
  258.             }
  259.         ]
  260.         Repeater {
  261.             id: gridRepeater
  262.             model: desktopModel
  263.             DesktopView {
  264.                 id: thumbnail
  265.  
  266.                 panelOpacity: grid.panelOpacity
  267.                 readonly property bool current: KWinComponents.Workspace.currentVirtualDesktop === desktop
  268.                 z: dragActive ? 1 : 0
  269.                 onCurrentChanged: {
  270.                     if (current) {
  271.                         grid.currentItem = thumbnail;
  272.                     }
  273.                 }
  274.                 Component.onCompleted: {
  275.                     if (current) {
  276.                         grid.currentItem = thumbnail;
  277.                     }
  278.                 }
  279.                 width: container.width
  280.                 height: container.height
  281.  
  282.                 clientModel: stackModel
  283.                 dndManagerStore: container.dndManagerStore
  284.                 Rectangle {
  285.                     anchors.fill: parent
  286.                     color: "transparent"
  287.                     border {
  288.                         color: PlasmaCore.Theme.highlightColor
  289.                         width: 1 / grid.scale
  290.                     }
  291.                     visible: parent.activeFocus
  292.                 }
  293.                 TapHandler {
  294.                     acceptedButtons: Qt.LeftButton
  295.                     onTapped: {
  296.                         KWinComponents.Workspace.currentVirtualDesktop = thumbnail.desktop;
  297.                         container.effect.deactivate(container.effect.animationDuration);
  298.                     }
  299.                 }
  300.             }
  301.         }
  302.     }
  303.  
  304.     RowLayout {
  305.         id: buttonsLayout
  306.         anchors {
  307.             right: parent.right
  308.             bottom: parent.bottom
  309.             margins: PlasmaCore.Units.smallSpacing
  310.         }
  311.         spacing: PlasmaCore.Units.smallSpacing
  312.         visible: container.effect.showAddRemove
  313.         PC3.Button {
  314.             id: addButton
  315.             icon.name: "list-add"
  316.             onClicked: container.effect.addDesktop()
  317.         }
  318.         PC3.Button {
  319.             id: removeButton
  320.             icon.name: "list-remove"
  321.             onClicked: container.effect.removeDesktop()
  322.         }
  323.         Behavior on opacity {
  324.             enabled: !container.effect.gestureInProgress
  325.             NumberAnimation {
  326.                 duration: container.effect.animationDuration
  327.                 easing.type: Easing.OutCubic
  328.             }
  329.         }
  330.     }
  331.     TapHandler {
  332.         acceptedButtons: Qt.LeftButton
  333.         onTapped: {
  334.             container.effect.deactivate(container.effect.animationDuration);
  335.         }
  336.     }
  337.  
  338.     Component.onCompleted: start()
  339. }
  340.  
Tags: kde
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement