From 06329297c6b6cb6063a7ed2b4d51fd3cab27a75e Mon Sep 17 00:00:00 2001 From: Uri Herrera Date: Thu, 24 Oct 2024 03:01:50 -0600 Subject: [PATCH] update pkg --- debian/changelog | 6 + kwin/CMakeLists.txt | 1 + kwin/KZones/contents/config/Shadow.qml | 18 + kwin/KZones/contents/config/main.xml | 117 +++ .../contents/ui/components/Indicator.qml | 48 ++ kwin/KZones/contents/ui/components/Shadow.qml | 18 + kwin/KZones/contents/ui/config.ui | 579 ++++++++++++++ .../contents/ui/config/configGeneral.qml | 23 + kwin/KZones/contents/ui/config_ui.py | 311 ++++++++ kwin/KZones/contents/ui/main.qml | 714 ++++++++++++++++++ kwin/KZones/contents/ui/menu.js | 28 + kwin/KZones/contents/ui/ui_config.py | 558 ++++++++++++++ kwin/KZones/metadata.desktop | 21 + 13 files changed, 2442 insertions(+) create mode 100644 kwin/KZones/contents/config/Shadow.qml create mode 100644 kwin/KZones/contents/config/main.xml create mode 100644 kwin/KZones/contents/ui/components/Indicator.qml create mode 100644 kwin/KZones/contents/ui/components/Shadow.qml create mode 100644 kwin/KZones/contents/ui/config.ui create mode 100644 kwin/KZones/contents/ui/config/configGeneral.qml create mode 100644 kwin/KZones/contents/ui/config_ui.py create mode 100644 kwin/KZones/contents/ui/main.qml create mode 100644 kwin/KZones/contents/ui/menu.js create mode 100644 kwin/KZones/contents/ui/ui_config.py create mode 100644 kwin/KZones/metadata.desktop diff --git a/debian/changelog b/debian/changelog index ec05d6e..dec9300 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +nx-plasma-look-and-feel (2.3.2) nitrux; urgency=medium + + * Add KZones KWin script. + + -- Uri Herrera Mon, 15 Jul 2024 16:15:00 -0500 + nx-plasma-look-and-feel (2.3.1) nitrux; urgency=medium * Add icon for vpn connection and ethernet and vpn connections. diff --git a/kwin/CMakeLists.txt b/kwin/CMakeLists.txt index 7e1b94e..0ce148a 100644 --- a/kwin/CMakeLists.txt +++ b/kwin/CMakeLists.txt @@ -1,2 +1,3 @@ install(DIRECTORY polonium DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kwin/scripts) install(DIRECTORY macsimize DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kwin/scripts) +install(DIRECTORY KZones DESTINATION ${CMAKE_INSTALL_PREFIX}/share/kwin/scripts) diff --git a/kwin/KZones/contents/config/Shadow.qml b/kwin/KZones/contents/config/Shadow.qml new file mode 100644 index 0000000..7bae352 --- /dev/null +++ b/kwin/KZones/contents/config/Shadow.qml @@ -0,0 +1,18 @@ +import QtQuick 2.15 +import QtGraphicalEffects 1.0 + +DropShadow { + property Item target : null + anchors.fill: target + visible: target.visible + opacity: target.opacity + scale: target.scale + cached: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 32 + samples: (radius*2)+1 + color: color_indicator_shadow + smooth: true + source: target +} \ No newline at end of file diff --git a/kwin/KZones/contents/config/main.xml b/kwin/KZones/contents/config/main.xml new file mode 100644 index 0000000..6704886 --- /dev/null +++ b/kwin/KZones/contents/config/main.xml @@ -0,0 +1,117 @@ + + + + + + + + true + + + + 1 + + + + true + + + + 0 + + + + 0 + + + + true + + + + + + + [ + { + "name": "Priority Grid", + "padding": 0, + "zones": [ + { + "x": 0, + "y": 0, + "height": 100, + "width": 25 + }, + { + "x": 25, + "y": 0, + "height": 100, + "width": 50 + }, + { + "x": 75, + "y": 0, + "height": 100, + "width": 25 + } + ] + }, + { + "name": "Quadrant Grid", + "zones": [ + { + "x": 0, + "y": 0, + "height": 50, + "width": 50 + }, + { + "x": 0, + "y": 50, + "height": 50, + "width": 50 + }, + { + "x": 50, + "y": 50, + "height": 50, + "width": 50 + }, + { + "x": 50, + "y": 0, + "height": 50, + "width": 50 + } + ] + } +] + + + + + + + 0 + + + + + + + + + + 100 + + + + false + + + + diff --git a/kwin/KZones/contents/ui/components/Indicator.qml b/kwin/KZones/contents/ui/components/Indicator.qml new file mode 100644 index 0000000..d8333a2 --- /dev/null +++ b/kwin/KZones/contents/ui/components/Indicator.qml @@ -0,0 +1,48 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.15 +import org.kde.kirigami 2.15 as Kirigami + +Rectangle { + id: indicator + property int activeZone: 0 + property bool hovering: false + property var zones: [] + width: parent.width + height: parent.height + color: "transparent" + opacity: 1 + + Repeater { + id: indicators + model: zones + + Item { + id: zone + x: ((modelData.x / 100) * (indicator.width)) + y: ((modelData.y / 100) * (indicator.height)) + width: ((modelData.width / 100) * (indicator.width)) + height: ((modelData.height / 100) * (indicator.height)) + + Rectangle { + property int padding: 2 + anchors.fill: parent + anchors.margins: padding + Kirigami.Theme.colorSet: Kirigami.Theme.View + Kirigami.Theme.inherit: false + color: (activeZone == index) ? Kirigami.Theme.hoverColor : Kirigami.ColorUtils.tintWithAlpha( Kirigami.Theme.backgroundColor, Qt.rgba(1,1,1), 0.1) + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.2) + border.width: 1 + radius: 5 + + Behavior on color { + ColorAnimation { + duration: 150 + } + } + } + + } + + } + +} \ No newline at end of file diff --git a/kwin/KZones/contents/ui/components/Shadow.qml b/kwin/KZones/contents/ui/components/Shadow.qml new file mode 100644 index 0000000..da5f22d --- /dev/null +++ b/kwin/KZones/contents/ui/components/Shadow.qml @@ -0,0 +1,18 @@ +import QtQuick 2.15 +import QtGraphicalEffects 1.0 + +DropShadow { + property Item target : null + anchors.fill: target + visible: target.visible + opacity: target.opacity + scale: target.scale + cached: true + horizontalOffset: 0 + verticalOffset: 0 + radius: 32 + samples: (radius*2)+1 + color: '#69000000' + smooth: true + source: target +} \ No newline at end of file diff --git a/kwin/KZones/contents/ui/config.ui b/kwin/KZones/contents/ui/config.ui new file mode 100644 index 0000000..16db707 --- /dev/null +++ b/kwin/KZones/contents/ui/config.ui @@ -0,0 +1,579 @@ + + + KWin::KZonesConfigForm + + + + 0 + 0 + 550 + 650 + + + + + + + 0 + + + + + ../../../../../../../../.designer/backup../../../../../../../../.designer/backup + + + General + + + + + + Enable Zone Selector + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + The zone selector is a small widget that appears when you drag a window to the top of the screen. It allows you to snap the window to a zone regardless of the current layout. + + + true + + + + + + + + + + 0 + 0 + + + + Close + + + 0 + + + + Close + + + + + Medium + + + + + Far + + + + + + + + Trigger distance + + + + + + + + + + + + Enable Zone Overlay + + + true + + + true + + + + + + The zone overlay is a fullscreen overlay that appears when you move a window. It shows all zones from the current layout and the window will snap to the zone you drop it on. + + + true + + + + + + + + + Highlight zone when + + + + + + + + 0 + 0 + + + + + My cursor is above the zone indicator + + + + + My cursor is anywhere in the zone + + + + + + + + Show overlay when + + + + + + + + 0 + 0 + + + + + I start moving a window + + + + + I press the toggle overlay shortcut + + + + + + + + + + + + + Snapping Behaviour + + + + 15 + + + + + + 0 + 0 + + + + Remember and restore window geometries + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + verticalSpacer_3 + groupBox_general + kcfg_enableZoneSelector + kcfg_enableZoneOverlay + + + + + ../../../../../../../../.designer/backup../../../../../../../../.designer/backup + + + Layouts + + + + + + Layouts + + + + + + [ + { + "name": "Priority Grid", + "padding": 0, + "zones": [ + { + "x": 0, + "y": 0, + "height": 100, + "width": 25 + }, + { + "x": 25, + "y": 0, + "height": 100, + "width": 50 + }, + { + "x": 75, + "y": 0, + "height": 100, + "width": 25 + } + ] + }, + { + "name": "Quadrant Grid", + "zones": [ + { + "x": 0, + "y": 0, + "height": 50, + "width": 50 + }, + { + "x": 0, + "y": 50, + "height": 50, + "width": 50 + }, + { + "x": 50, + "y": 50, + "height": 50, + "width": 50 + }, + { + "x": 50, + "y": 0, + "height": 50, + "width": 50 + } + ] + } +] + + + + + + + + + + + + ../../../../../../../../.designer/backup../../../../../../../../.designer/backup + + + Filters + + + + + + Filtering + + + + + + + 0 + 0 + + + + Choose a filter mode and enter the window classes you wish to include or exclude, seperated by a new line. + + + true + + + + + + + + + Mode + + + + + + + + 0 + 0 + + + + + Include + + + + + Exclude + + + + + + + + Filter + + + + + + + Enter window classes you wish to include/exclude (seperated by a new line) + + + + + + + + + + + + + + ../../../../../.designer/backup../../../../../.designer/backup + + + Shortcuts + + + + + + + + Shortcuts + + + + + + <html><head/><body><p>To set up shortcuts for this script</p><p>Go to System Settings / Shortcuts and search for &quot;KZones&quot;</p></body></html> + + + Qt::AlignCenter + + + + + + + + + + + + + + ../../../../../../../../.designer/backup../../../../../../../../.designer/backup + + + Advanced + + + + + + + + Performance + + + false + + + + + + + + Speed of which the zone checking is done + + + Polling rate + + + + + + + + 0 + 0 + + + + Speed of which the zone checking is done + + + ms + + + 10 + + + 1000 + + + 10 + + + 100 + + + + + + + + + + + + Debug + + + + + + + 0 + 0 + + + + Enable debug mode + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + https://github.com/gerritdevriese/kzones + + + <a href="https://github.com/gerritdevriese/kzones">Github page</a> + + + 8 + + + true + + + + + + + + 50 + false + false + false + false + + + + + + + Please reload the script after making changes to apply them + + + false + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 8 + + + + + + + + + + diff --git a/kwin/KZones/contents/ui/config/configGeneral.qml b/kwin/KZones/contents/ui/config/configGeneral.qml new file mode 100644 index 0000000..5339507 --- /dev/null +++ b/kwin/KZones/contents/ui/config/configGeneral.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.5 +import org.kde.kirigami 2.4 as Kirigami + +import "../lib" + +Item { + id: configGeneral + width: childrenRect.width + height: childrenRect.height + + property alias cfg_icon: configIcon.value + + Kirigami.FormLayout { + anchors.left: parent.left + anchors.right: parent.right + + ConfigIcon { + id: configIcon + Kirigami.FormData.label: i18nd("plasma_applet_org.kde.plasma.kickoff", "Icon:") + } + } +} diff --git a/kwin/KZones/contents/ui/config_ui.py b/kwin/KZones/contents/ui/config_ui.py new file mode 100644 index 0000000..abcde3d --- /dev/null +++ b/kwin/KZones/contents/ui/config_ui.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '/home/user/Documents/Git/kzones/contents/ui/config.ui' +# +# Created by: PyQt5 UI code generator 5.15.9 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_KWin::KZonesConfigForm(object): + def setupUi(self, KWin::KZonesConfigForm): + KWin::KZonesConfigForm.setObjectName("KWin::KZonesConfigForm") + KWin::KZonesConfigForm.resize(600, 600) + self.verticalLayout = QtWidgets.QVBoxLayout(KWin::KZonesConfigForm) + self.verticalLayout.setObjectName("verticalLayout") + self.tabWidget = QtWidgets.QTabWidget(KWin::KZonesConfigForm) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.North) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded) + self.tabWidget.setIconSize(QtCore.QSize(16, 16)) + self.tabWidget.setElideMode(QtCore.Qt.ElideNone) + self.tabWidget.setDocumentMode(False) + self.tabWidget.setTabsClosable(False) + self.tabWidget.setTabBarAutoHide(False) + self.tabWidget.setObjectName("tabWidget") + self.tab_general = QtWidgets.QWidget() + self.tab_general.setObjectName("tab_general") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.tab_general) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.groupBox_2 = QtWidgets.QGroupBox(self.tab_general) + self.groupBox_2.setObjectName("groupBox_2") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_2) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.kcfg_enableZoneIndicators = QtWidgets.QCheckBox(self.groupBox_2) + self.kcfg_enableZoneIndicators.setChecked(True) + self.kcfg_enableZoneIndicators.setObjectName("kcfg_enableZoneIndicators") + self.verticalLayout_3.addWidget(self.kcfg_enableZoneIndicators) + self.widget = QtWidgets.QWidget(self.groupBox_2) + self.widget.setObjectName("widget") + self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.widget) + self.verticalLayout_10.setContentsMargins(20, 0, 0, 6) + self.verticalLayout_10.setObjectName("verticalLayout_10") + self.kcfg_indicatorIsTarget = QtWidgets.QRadioButton(self.widget) + self.kcfg_indicatorIsTarget.setChecked(True) + self.kcfg_indicatorIsTarget.setObjectName("kcfg_indicatorIsTarget") + self.verticalLayout_10.addWidget(self.kcfg_indicatorIsTarget) + self.kcfg_zoneIsTarget = QtWidgets.QRadioButton(self.widget) + self.kcfg_zoneIsTarget.setObjectName("kcfg_zoneIsTarget") + self.verticalLayout_10.addWidget(self.kcfg_zoneIsTarget) + self.verticalLayout_3.addWidget(self.widget) + self.kcfg_enableZoneSelector = QtWidgets.QCheckBox(self.groupBox_2) + self.kcfg_enableZoneSelector.setChecked(True) + self.kcfg_enableZoneSelector.setObjectName("kcfg_enableZoneSelector") + self.verticalLayout_3.addWidget(self.kcfg_enableZoneSelector) + self.verticalLayout_4.addWidget(self.groupBox_2) + self.groupBox_general = QtWidgets.QGroupBox(self.tab_general) + self.groupBox_general.setObjectName("groupBox_general") + self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.groupBox_general) + self.verticalLayout_11.setObjectName("verticalLayout_11") + self.kcfg_rememberWindowGeometries = QtWidgets.QCheckBox(self.groupBox_general) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_rememberWindowGeometries.sizePolicy().hasHeightForWidth()) + self.kcfg_rememberWindowGeometries.setSizePolicy(sizePolicy) + self.kcfg_rememberWindowGeometries.setChecked(True) + self.kcfg_rememberWindowGeometries.setObjectName("kcfg_rememberWindowGeometries") + self.verticalLayout_11.addWidget(self.kcfg_rememberWindowGeometries) + self.kcfg_invertedMode = QtWidgets.QCheckBox(self.groupBox_general) + self.kcfg_invertedMode.setObjectName("kcfg_invertedMode") + self.verticalLayout_11.addWidget(self.kcfg_invertedMode) + self.verticalLayout_4.addWidget(self.groupBox_general) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_4.addItem(spacerItem) + self.groupBox_2.raise_() + self.groupBox_general.raise_() + icon = QtGui.QIcon.fromTheme("systemsettings") + self.tabWidget.addTab(self.tab_general, icon, "") + self.tab_layouts = QtWidgets.QWidget() + self.tab_layouts.setObjectName("tab_layouts") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_layouts) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.groupBox = QtWidgets.QGroupBox(self.tab_layouts) + self.groupBox.setObjectName("groupBox") + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.groupBox) + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.kcfg_layoutsJson = QtWidgets.QPlainTextEdit(self.groupBox) + self.kcfg_layoutsJson.setObjectName("kcfg_layoutsJson") + self.verticalLayout_6.addWidget(self.kcfg_layoutsJson) + self.verticalLayout_2.addWidget(self.groupBox) + icon = QtGui.QIcon.fromTheme("preferences-desktop-virtual") + self.tabWidget.addTab(self.tab_layouts, icon, "") + self.tab_filters = QtWidgets.QWidget() + self.tab_filters.setObjectName("tab_filters") + self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab_filters) + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.groupBox_3 = QtWidgets.QGroupBox(self.tab_filters) + self.groupBox_3.setObjectName("groupBox_3") + self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.groupBox_3) + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.label_2 = QtWidgets.QLabel(self.groupBox_3) + self.label_2.setObjectName("label_2") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_2) + self.kcfg_filterMode = QtWidgets.QComboBox(self.groupBox_3) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_filterMode.sizePolicy().hasHeightForWidth()) + self.kcfg_filterMode.setSizePolicy(sizePolicy) + self.kcfg_filterMode.setObjectName("kcfg_filterMode") + self.kcfg_filterMode.addItem("") + self.kcfg_filterMode.addItem("") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_filterMode) + self.label_18 = QtWidgets.QLabel(self.groupBox_3) + self.label_18.setObjectName("label_18") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_18) + self.kcfg_filterList = QtWidgets.QPlainTextEdit(self.groupBox_3) + self.kcfg_filterList.setObjectName("kcfg_filterList") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcfg_filterList) + self.verticalLayout_8.addLayout(self.formLayout) + self.verticalLayout_7.addWidget(self.groupBox_3) + icon = QtGui.QIcon.fromTheme("preferences-desktop-filter") + self.tabWidget.addTab(self.tab_filters, icon, "") + self.tab_shortcuts = QtWidgets.QWidget() + self.tab_shortcuts.setObjectName("tab_shortcuts") + self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.tab_shortcuts) + self.verticalLayout_9.setObjectName("verticalLayout_9") + self.verticalLayout_5 = QtWidgets.QVBoxLayout() + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.groupBox_4 = QtWidgets.QGroupBox(self.tab_shortcuts) + self.groupBox_4.setObjectName("groupBox_4") + self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.groupBox_4) + self.verticalLayout_12.setObjectName("verticalLayout_12") + self.label_23 = QtWidgets.QLabel(self.groupBox_4) + self.label_23.setAlignment(QtCore.Qt.AlignCenter) + self.label_23.setObjectName("label_23") + self.verticalLayout_12.addWidget(self.label_23) + self.verticalLayout_5.addWidget(self.groupBox_4) + self.verticalLayout_9.addLayout(self.verticalLayout_5) + icon = QtGui.QIcon.fromTheme("configure-shortcuts") + self.tabWidget.addTab(self.tab_shortcuts, icon, "") + self.tab_advanced = QtWidgets.QWidget() + self.tab_advanced.setObjectName("tab_advanced") + self.verticalLayout_91 = QtWidgets.QVBoxLayout(self.tab_advanced) + self.verticalLayout_91.setObjectName("verticalLayout_91") + self.verticalLayout_51 = QtWidgets.QVBoxLayout() + self.verticalLayout_51.setObjectName("verticalLayout_51") + self.groupBox_7 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_7.setFlat(False) + self.groupBox_7.setObjectName("groupBox_7") + self.verticalLayout_16 = QtWidgets.QVBoxLayout(self.groupBox_7) + self.verticalLayout_16.setObjectName("verticalLayout_16") + self.formLayout_3 = QtWidgets.QFormLayout() + self.formLayout_3.setObjectName("formLayout_3") + self.label_4 = QtWidgets.QLabel(self.groupBox_7) + self.label_4.setObjectName("label_4") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_4) + self.kcfg_pollingRate = QtWidgets.QSpinBox(self.groupBox_7) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_pollingRate.sizePolicy().hasHeightForWidth()) + self.kcfg_pollingRate.setSizePolicy(sizePolicy) + self.kcfg_pollingRate.setMinimum(10) + self.kcfg_pollingRate.setMaximum(1000) + self.kcfg_pollingRate.setSingleStep(10) + self.kcfg_pollingRate.setProperty("value", 100) + self.kcfg_pollingRate.setObjectName("kcfg_pollingRate") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_pollingRate) + self.verticalLayout_16.addLayout(self.formLayout_3) + self.verticalLayout_51.addWidget(self.groupBox_7) + self.groupBox_8 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_8.setObjectName("groupBox_8") + self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.groupBox_8) + self.verticalLayout_17.setObjectName("verticalLayout_17") + self.kcfg_enableDebugMode = QtWidgets.QCheckBox(self.groupBox_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_enableDebugMode.sizePolicy().hasHeightForWidth()) + self.kcfg_enableDebugMode.setSizePolicy(sizePolicy) + self.kcfg_enableDebugMode.setObjectName("kcfg_enableDebugMode") + self.verticalLayout_17.addWidget(self.kcfg_enableDebugMode) + self.verticalLayout_51.addWidget(self.groupBox_8) + self.verticalLayout_91.addLayout(self.verticalLayout_51) + spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_91.addItem(spacerItem1) + icon = QtGui.QIcon.fromTheme("applications-development") + self.tabWidget.addTab(self.tab_advanced, icon, "") + self.verticalLayout.addWidget(self.tabWidget) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.label_25 = QtWidgets.QLabel(KWin::KZonesConfigForm) + self.label_25.setOpenExternalLinks(True) + self.label_25.setObjectName("label_25") + self.horizontalLayout.addWidget(self.label_25) + self.label_13 = QtWidgets.QLabel(KWin::KZonesConfigForm) + font = QtGui.QFont() + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setStrikeOut(False) + self.label_13.setFont(font) + self.label_13.setToolTip("") + self.label_13.setScaledContents(False) + self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_13.setObjectName("label_13") + self.horizontalLayout.addWidget(self.label_13) + self.verticalLayout.addLayout(self.horizontalLayout) + + self.retranslateUi(KWin::KZonesConfigForm) + self.tabWidget.setCurrentIndex(0) + self.kcfg_enableZoneIndicators.toggled['bool'].connect(self.widget.setEnabled) # type: ignore + QtCore.QMetaObject.connectSlotsByName(KWin::KZonesConfigForm) + + def retranslateUi(self, KWin::KZonesConfigForm): + _translate = QtCore.QCoreApplication.translate + self.groupBox_2.setTitle(_translate("KWin::KZonesConfigForm", "Overlay")) + self.kcfg_enableZoneIndicators.setText(_translate("KWin::KZonesConfigForm", "Show zones when I start moving a window")) + self.kcfg_indicatorIsTarget.setText(_translate("KWin::KZonesConfigForm", "Highlight zone when hovering over the indicator")) + self.kcfg_zoneIsTarget.setText(_translate("KWin::KZonesConfigForm", "Highlight zone when the cursor is anywhere in the zone")) + self.kcfg_enableZoneSelector.setText(_translate("KWin::KZonesConfigForm", "Show zone selector when I drag a window to the top of the screen")) + self.groupBox_general.setTitle(_translate("KWin::KZonesConfigForm", "Behaviour")) + self.kcfg_rememberWindowGeometries.setText(_translate("KWin::KZonesConfigForm", "Remember and restore window geometries")) + self.kcfg_invertedMode.setToolTip(_translate("KWin::KZonesConfigForm", "When enabled, moving windows will not trigger the osd. Instead you\'ll have to use the \"Toggle OSD\" shortcut to show the osd.")) + self.kcfg_invertedMode.setText(_translate("KWin::KZonesConfigForm", "Require shortcut to show overlay")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_general), _translate("KWin::KZonesConfigForm", "General")) + self.groupBox.setTitle(_translate("KWin::KZonesConfigForm", "Layouts")) + self.kcfg_layoutsJson.setPlainText(_translate("KWin::KZonesConfigForm", "[\n" +" {\n" +" \"name\": \"Priority Grid\",\n" +" \"padding\": 0,\n" +" \"zones\": [\n" +" {\n" +" \"x\": 0,\n" +" \"y\": 0,\n" +" \"height\": 100,\n" +" \"width\": 25\n" +" },\n" +" {\n" +" \"x\": 25,\n" +" \"y\": 0,\n" +" \"height\": 100,\n" +" \"width\": 50\n" +" },\n" +" {\n" +" \"x\": 75,\n" +" \"y\": 0,\n" +" \"height\": 100,\n" +" \"width\": 25\n" +" }\n" +" ]\n" +" },\n" +" {\n" +" \"name\": \"Quadrant Grid\",\n" +" \"zones\": [\n" +" {\n" +" \"x\": 0,\n" +" \"y\": 0,\n" +" \"height\": 50,\n" +" \"width\": 50\n" +" },\n" +" {\n" +" \"x\": 0,\n" +" \"y\": 50,\n" +" \"height\": 50,\n" +" \"width\": 50\n" +" },\n" +" {\n" +" \"x\": 50,\n" +" \"y\": 50,\n" +" \"height\": 50,\n" +" \"width\": 50\n" +" },\n" +" {\n" +" \"x\": 50,\n" +" \"y\": 0,\n" +" \"height\": 50,\n" +" \"width\": 50\n" +" }\n" +" ]\n" +" }\n" +"]")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_layouts), _translate("KWin::KZonesConfigForm", "Layouts")) + self.groupBox_3.setTitle(_translate("KWin::KZonesConfigForm", "Filtering")) + self.label_2.setText(_translate("KWin::KZonesConfigForm", "Mode")) + self.kcfg_filterMode.setItemText(0, _translate("KWin::KZonesConfigForm", "Include")) + self.kcfg_filterMode.setItemText(1, _translate("KWin::KZonesConfigForm", "Exclude")) + self.label_18.setText(_translate("KWin::KZonesConfigForm", "Filter")) + self.kcfg_filterList.setToolTip(_translate("KWin::KZonesConfigForm", "Enter window classes you wish to include/exclude (seperated by a new line)")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_filters), _translate("KWin::KZonesConfigForm", "Filters")) + self.groupBox_4.setTitle(_translate("KWin::KZonesConfigForm", "Shortcuts")) + self.label_23.setText(_translate("KWin::KZonesConfigForm", "

To set up shortcuts for this script

Go to System Settings / Shortcuts and search for "KZones"

")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_shortcuts), _translate("KWin::KZonesConfigForm", "Shortcuts")) + self.groupBox_7.setTitle(_translate("KWin::KZonesConfigForm", "Performance")) + self.label_4.setToolTip(_translate("KWin::KZonesConfigForm", "Speed of which the zone checking is done")) + self.label_4.setText(_translate("KWin::KZonesConfigForm", "Polling rate")) + self.kcfg_pollingRate.setToolTip(_translate("KWin::KZonesConfigForm", "Speed of which the zone checking is done")) + self.kcfg_pollingRate.setSuffix(_translate("KWin::KZonesConfigForm", " ms")) + self.groupBox_8.setTitle(_translate("KWin::KZonesConfigForm", "Debug")) + self.kcfg_enableDebugMode.setText(_translate("KWin::KZonesConfigForm", "Enable debug mode")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_advanced), _translate("KWin::KZonesConfigForm", "Advanced")) + self.label_25.setToolTip(_translate("KWin::KZonesConfigForm", "https://github.com/gerritdevriese/kzones")) + self.label_25.setText(_translate("KWin::KZonesConfigForm", "Github page")) + self.label_13.setText(_translate("KWin::KZonesConfigForm", "Please reload the script after making changes to apply them")) diff --git a/kwin/KZones/contents/ui/main.qml b/kwin/KZones/contents/ui/main.qml new file mode 100644 index 0000000..31bb5ab --- /dev/null +++ b/kwin/KZones/contents/ui/main.qml @@ -0,0 +1,714 @@ +import QtGraphicalEffects 1.0 +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.2 +import org.kde.kirigami 2.15 as Kirigami +import org.kde.kwin 2.0 +import org.kde.plasma.components 3.0 as PlasmaComponents +import org.kde.plasma.core 2.0 as PlasmaCore + +import "components" as Components + +PlasmaCore.Dialog { + + // api documentation + // https://api.kde.org/frameworks/plasma-framework/html/classPlasmaQuick_1_1Dialog.html + // https://api.kde.org/frameworks/plasma-framework/html/classPlasma_1_1Types.html + // https://develop.kde.org/docs/getting-started/kirigami/style-colors/ + + id: mainDialog + + // properties + property bool shown: false + property bool moving: false + property bool moved: false + property bool resizing: false + property var clientArea: {} + property var cachedClientArea: {} + property var displaySize: {} + property int currentLayout: 0 + property int highlightedZone: -1 + property int activeScreen: 0 + property var config: {} + property bool showZoneOverlay: config.zoneOverlayShowWhen == 0 + + location: PlasmaCore.Types.Floating + type: PlasmaCore.Dialog.OnScreenDisplay + backgroundHints: PlasmaCore.Types.NoBackground + flags: Qt.X11BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint + Kirigami.Theme.colorSet: Kirigami.Theme.View + visible: false + outputOnly: true + opacity: 1 + width: displaySize.width + height: displaySize.height + + function loadConfig() { + + // load values from configuration + config = { + enableZoneSelector: KWin.readConfig("enableZoneSelector", true), // enable zone selector + zoneSelectorTriggerDistance: KWin.readConfig("zoneSelectorTriggerDistance", 1), // distance from the top of the screen to trigger the zone selector + enableZoneOverlay: KWin.readConfig("enableZoneOverlay", true), // enable zone overlay + zoneOverlayShowWhen: KWin.readConfig("zoneOverlayShowWhen", 0), // show zone overlay when + zoneOverlayHighlightTarget: KWin.readConfig("zoneOverlayHighlightTarget", 0), // highlight target zone + rememberWindowGeometries: KWin.readConfig("rememberWindowGeometries", true), // remember window geometries before snapping to a zone, and restore them when the window is removed from their zone + layouts: JSON.parse(KWin.readConfig("layoutsJson", '[{"name":"Priority Grid","padding":0,"zones":[{"x":0,"y":0,"height":100,"width":25},{"x":25,"y":0,"height":100,"width":50},{"x":75,"y":0,"height":100,"width":25}]},{"name":"Quadrant Grid","zones":[{"x":0,"y":0,"height":50,"width":50},{"x":0,"y":50,"height":50,"width":50},{"x":50,"y":50,"height":50,"width":50},{"x":50,"y":0,"height":50,"width":50}]}]')), // layouts + filterMode: KWin.readConfig("filterMode", 0), // filter mode + filterList: KWin.readConfig("filterList", ""), // filter list + pollingRate: KWin.readConfig("pollingRate", 100), // polling rate in milliseconds + enableDebugMode: KWin.readConfig("enableDebugMode", false), // enable debug mode + } + + log("Config loaded: " + JSON.stringify(config)) + } + + function log(message) { + if (!config.enableDebugMode) return + console.log("KZones: " + message) + } + + function show() { + // show OSD + mainDialog.shown = true + mainDialog.visible = true + + refreshClientArea() + } + + function hide() { + // hide OSD + mainDialog.shown = false + mainDialog.visible = false + + zoneSelectorBackground.expanded = false + zoneSelectorBackground.near = false + highlightedZone = -1 + + showZoneOverlay = config.zoneOverlayShowWhen == 0 + } + + function refreshClientArea() { + activeScreen = workspace.activeScreen + clientArea = workspace.clientArea(KWin.FullScreenArea, activeScreen, workspace.currentDesktop) + displaySize = workspace.displaySize + } + + function isPointInside(x, y, geometry) { + return x >= geometry.x && x <= geometry.x + geometry.width && y >= geometry.y && y <= geometry.y + geometry.height + } + + function isHovering(item) { + let itemGlobal = item.mapToGlobal(Qt.point(0, 0)) + return isPointInside(workspace.cursorPos.x, workspace.cursorPos.y, {x: itemGlobal.x, y: itemGlobal.y, width: item.width * item.scale, height: item.height * item.scale}) + } + + function rectOverlapArea(component1, component2) { + let x1 = component1.x + let y1 = component1.y + let x2 = component1.x + component1.width + let y2 = component1.y + component1.height + let x3 = component2.x + let y3 = component2.y + let x4 = component2.x + component2.width + let y4 = component2.y + component2.height + let xOverlap = Math.max(0, Math.min(x2, x4) - Math.max(x1, x3)) + let yOverlap = Math.max(0, Math.min(y2, y4) - Math.max(y1, y3)) + return xOverlap * yOverlap + } + + function matchZone(client) { + client.zone = -1 + // get all zones in the current layout + let zones = config.layouts[currentLayout].zones + // loop through zones and compare with the geometries of the client + for (let i = 0; i < zones.length; i++) { + let zone = zones[i] + let zonePadding = config.layouts[currentLayout].padding || 0 + let zoneX = ((zone.x / 100) * (clientArea.width - zonePadding)) + zonePadding + let zoneY = ((zone.y / 100) * (clientArea.height - zonePadding)) + zonePadding + let zoneWidth = ((zone.width / 100) * (clientArea.width - zonePadding)) - zonePadding + let zoneHeight = ((zone.height / 100) * (clientArea.height - zonePadding)) - zonePadding + if (client.geometry.x == zoneX && client.geometry.y == zoneY && client.geometry.width == zoneWidth && client.geometry.height == zoneHeight) { + // zone found, set it and exit the loop + client.zone = i + client.zone = currentLayout + break + } + } + } + + function getWindowsInZone(zone, layout) { + let windows = [] + for (let i = 0; i < workspace.clientList().length; i++) { + let client = workspace.clientList()[i] + if (client.zone === zone && + client.layout === layout && + client.desktop === workspace.currentDesktop && + client.activity === workspace.currentActivity && + client.screen === workspace.activeClient.screen && + client.normalWindow) { + windows.push(client) + } + } + return windows + } + + function switchWindowInZone(zone, layout, reverse) { + + let clientsInZone = getWindowsInZone(zone, layout) + + if (reverse) { clientsInZone.reverse() } + + // cycle through clients in zone + if (clientsInZone.length > 0) { + let index = clientsInZone.indexOf(workspace.activeClient) + if (index === -1) { + workspace.activeClient = clientsInZone[0] + } else { + workspace.activeClient = clientsInZone[(index + 1) % clientsInZone.length] + } + } + } + + function moveClientToZone(client, zone) { + + // block abnormal windows from being moved (like plasmashell, docks, etc...) + if (!client.normalWindow) return + + log("Moving client " + client.resourceClass.toString() + " to zone " + zone) + + clientArea = workspace.clientArea(KWin.FullScreenArea, client.screen, workspace.currentDesktop) + saveWindowGeometries(client, zone) + + // move client to zone + if (zone != -1) { + let zoneItem = repeaterZones.itemAt(zone) + let itemGlobal = zoneItem.mapToGlobal(Qt.point(0, 0)) + let newGeometry = Qt.rect(Math.round(itemGlobal.x), Math.round(itemGlobal.y), Math.round(zoneItem.width), Math.round(zoneItem.height)) + log("Moving client " + client.resourceClass.toString() + " to zone " + zone + " with geometry " + JSON.stringify(newGeometry)) + client.geometry = newGeometry + } + } + + function saveWindowGeometries(client, zone) { + + log("Saving geometry for client " + client.resourceClass.toString()) + + // save current geometry + if (config.rememberWindowGeometries) { + let geometry = { + "x": client.geometry.x, + "y": client.geometry.y, + "width": client.geometry.width, + "height": client.geometry.height + } + if (zone != -1) { + if (client.zone == -1) { + client.oldGeometry = geometry + } + } + } + + // save zone + client.zone = zone + client.layout = currentLayout + client.desktop = workspace.currentDesktop + client.activity = workspace.currentActivity + } + + Component.onCompleted: { + + // register window + KWin.registerWindow(mainDialog) + + // refresh client area + refreshClientArea() + + // shortcut: cycle through layouts + bindShortcut("Cycle layouts", "Ctrl+Alt+D", function() { + //cycle through layouts + currentLayout = (currentLayout + 1) % config.layouts.length + highlightedZone = -1 + osdCmd.exec(config.layouts[currentLayout].name) + }) + + // shortcut: move to zone (1-9) + for (let i = 0; i < 9; i++) { + bindShortcut(`Move active window to zone ${i+1}`, `Ctrl+Alt+Num+${i+1}`, function() { + moveClientToZone(workspace.activeClient, i) + }) + } + + // shortcut: move to next zone + bindShortcut("Move active window to next zone", "Ctrl+Alt+Right", function() { + const client = workspace.activeClient + // TODO: if client.zone = -1 check if client is in a zone by geometry + const zonesLength = config.layouts[currentLayout].zones.length + moveClientToZone(client, (client.zone + 1) % zonesLength) + }) + + // shortcut: move to previous zone + bindShortcut("Move active window to previous zone", "Ctrl+Alt+Left", function() { + const client = workspace.activeClient + // TODO: if client.zone = -1 check if client is in a zone by geometry + const zonesLength = config.layouts[currentLayout].zones.length + moveClientToZone(client, (client.zone - 1 + zonesLength) % zonesLength) + }) + + // shortcut: toggle osd + bindShortcut("Toggle zone overlay", "Ctrl+Alt+C", function() { + if (!config.enableZoneOverlay) osdCmd.exec("Zone overlay is disabled") + else if (moving) showZoneOverlay = !showZoneOverlay + else osdCmd.exec("The overlay can only be shown while moving a window") + }) + + // shortcut: switch to next window in current zone + bindShortcut("Switch to next window in current zone", "Ctrl+Alt+Up", function() { + let zone = workspace.activeClient.zone + let layout = workspace.activeClient.layout + switchWindowInZone(zone, layout) + }) + + // shortcut: switch to previous window in current zone + bindShortcut("Switch to previous window in current zone", "Ctrl+Alt+Down", function() { + let zone = workspace.activeClient.zone + let layout = workspace.activeClient.layout + switchWindowInZone(zone, layout, true) + }) + + mainDialog.loadConfig() + + // match all clients to zones + for (var i = 0; i < workspace.clientList().length; i++) { + matchZone(workspace.clientList()[i]) + } + } + + function bindShortcut(title, sequence, callback) { + KWin.registerShortcut(`KZones: ${title}`, `KZones: ${title}`, sequence, callback) + } + + Item { + id: mainItem + + anchors.fill: parent + + // main polling timer + Timer { + id: timer + + triggeredOnStart: true + interval: config.pollingRate + running: shown && moving + repeat: true + + onTriggered: { + + refreshClientArea() + + let hoveringZone = -1 + + if (config.enableZoneOverlay && showZoneOverlay && !zoneSelectorBackground.expanded) { + + repeaterZones.model.forEach((zone, zoneIndex) => { + if (isHovering(repeaterZones.itemAt(zoneIndex).children[config.zoneOverlayHighlightTarget])) { + hoveringZone = zoneIndex + } + }) + + } + + if (config.enableZoneSelector) { + if (!zoneSelectorBackground.animating && zoneSelectorBackground.expanded) { + + repeaterLayouts.model.forEach((layout, layoutIndex) => { + let layoutItem = repeaterLayouts.itemAt(layoutIndex) + + layout.zones.forEach((zone, zoneIndex) => { + let zoneItem = layoutItem.children[zoneIndex] + if(isHovering(zoneItem)) { + hoveringZone = zoneIndex + currentLayout = layoutIndex + } + }) + + }) + + } + // set zoneSelectorBackground expansion state + zoneSelectorBackground.expanded = isHovering(zoneSelectorBackground) && (workspace.cursorPos.y - clientArea.y) >= 0; + // set zoneSelectorBackground near state + let triggerDistance = config.zoneSelectorTriggerDistance * 50 + 25 + zoneSelectorBackground.near = (workspace.cursorPos.y - clientArea.y) < zoneSelectorBackground.y + zoneSelectorBackground.height + triggerDistance; + } + + // if hovering zone changed from the last frame + if (hoveringZone != highlightedZone) { + log("Highlighting zone " + hoveringZone + " in layout " + currentLayout) + highlightedZone = hoveringZone + } + + } + } + + // osd qdbus + PlasmaCore.DataSource { + + id: osdCmd + + engine: "executable" + + connectedSources: [] + onNewData: { + disconnectSource(sourceName); + } + function exec(text, icon) { + connectSource(`qdbus org.kde.plasmashell /org/kde/osdService showText "${icon}" "${text}"`); + } + } + + Item { + x: clientArea.x + y: clientArea.y + width: clientArea.width + height: clientArea.height + clip: true + + // debug osd + Rectangle { + id: debugOsd + + visible: config.enableDebugMode + anchors.left: parent.left + anchors.leftMargin: 20 + anchors.top: parent.top + anchors.topMargin: 20 + z: 100 + width: debugOsdText.paintedWidth + debugOsdText.padding * 2 + height: debugOsdText.paintedHeight + debugOsdText.padding * 2 + radius: 5 + color: Kirigami.Theme.backgroundColor + + Text { + id: debugOsdText + + anchors.fill: parent + padding: 15 + color: Kirigami.Theme.textColor + text: { + if (config.enableDebugMode) { + let t = "" + t += `Active: ${workspace.activeClient.caption}\n` + t += `Window class: ${workspace.activeClient.resourceClass.toString()}\n` + t += `X: ${workspace.activeClient.geometry.x}, Y: ${workspace.activeClient.geometry.y}, Width: ${workspace.activeClient.geometry.width}, Height: ${workspace.activeClient.geometry.height}\n` + t += `Previous Zone: ${workspace.activeClient.zone}\n` + t += `Highlighted Zone: ${highlightedZone}\n` + t += `Layout: ${currentLayout}\n` + t += `Polling Rate: ${config.pollingRate}ms\n` + t += `Moving: ${moving}\n` + t += `Resizing: ${resizing}\n` + t += `Old Geometry: ${JSON.stringify(workspace.activeClient.oldGeometry)}\n` + t += `Active Screen: ${activeScreen}\n` + return t + } else { + return "" + } + } + font.pixelSize: 14 + font.family: "Hack" + } + } + + // zones + Repeater { + id: repeaterZones + + model: config.layouts[currentLayout].zones + + // zone + Item { + id: zone + + property int zoneIndex: index + property int zonePadding: config.layouts[currentLayout].padding || 0 + + x: ((modelData.x / 100) * (clientArea.width - zonePadding)) + zonePadding + y: ((modelData.y / 100) * (clientArea.height - zonePadding)) + zonePadding + implicitWidth: ((modelData.width / 100) * (clientArea.width - zonePadding)) - zonePadding + implicitHeight: ((modelData.height / 100) * (clientArea.height - zonePadding)) - zonePadding + + // zone indicator + Rectangle { + id: zoneIndicator + + width: 160 + height: 100 + color: Kirigami.ColorUtils.tintWithAlpha( Kirigami.Theme.backgroundColor, Qt.rgba(0,0,0), 0.1) + radius: 10 + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.2) + border.width: 1 + anchors.centerIn: parent + opacity: !showZoneOverlay ? 0 : (zoneSelectorBackground.expanded) ? 0 : (highlightedZone == zoneIndex ? 0.6 : 1) + scale: highlightedZone == zoneIndex ? 1.1 : 1 + visible: config.enableZoneOverlay + + Behavior on scale { + NumberAnimation { + duration: zoneSelectorBackground.expanded ? 0 : 150 + } + } + + Behavior on opacity { + NumberAnimation { + duration: 150 + } + } + + Components.Indicator { + zones: config.layouts[currentLayout].zones + activeZone: index + anchors.centerIn: parent + width: parent.width - 20 + height: parent.height - 20 + hovering: (highlightedZone == zoneIndex) + } + + } + + // zone background + Rectangle { + id: zoneBackground + + anchors.fill: parent + color: (highlightedZone == zoneIndex) ? Qt.rgba(Kirigami.Theme.hoverColor.r, Kirigami.Theme.hoverColor.g, Kirigami.Theme.hoverColor.b, 0.1) : "transparent" + border.color: (highlightedZone == zoneIndex) ? Kirigami.Theme.hoverColor : "transparent" + border.width: 3 + radius: 8 + } + + // indicator shadow + Components.Shadow { + target: zoneIndicator + visible: zoneIndicator.visible + } + + } + + } + + // zone selector + Item { + id: zoneSelectorBackground + + property bool expanded: false + property bool near: false + property bool animating: false + + visible: false + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: expanded ? 0 : (near ? -height + 30 : -height) + + Behavior on anchors.topMargin { + NumberAnimation { + duration: 150 + onRunningChanged: { + if (!running) zoneSelectorBackground.visible = true + zoneSelectorBackground.animating = running + } + } + } + + width: zoneSelector.width + 30 + height: zoneSelector.height + 40 + + Rectangle { + id: zoneSelector + + width: row.implicitWidth + row.spacing * 2 + height: row.implicitHeight + row.spacing * 2 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 15 + color: Kirigami.ColorUtils.tintWithAlpha( Kirigami.Theme.backgroundColor, Qt.rgba(0,0,0), 0.1) + radius: 10 + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.2) + border.width: 1 + + RowLayout { + id: row + + spacing: 15 + anchors.fill: parent + anchors.margins: spacing + + Repeater { + id: repeaterLayouts + + model: config.layouts + + Components.Indicator{ + zones: modelData.zones + activeZone: (currentLayout == index) ? highlightedZone : -1 + width: 160 - 30 + height: 100 - 30 + hovering: (currentLayout == index) + } + } + } + + } + + Components.Shadow { + target: zoneSelector + visible: true + } + + } + + } + + + // workspace connection + Connections { + target: workspace + + function onClientAdded(client) { + // check if new window spawns in a zone + if (client.zone == undefined || client.zone == -1) { + matchZone(client) + } + } + + function onClientFullScreenSet(client, fullscreen, user) { + if (!client) return; + log("Client fullscreen: " + client.resourceClass.toString() + " (fullscreen " + fullscreen + ")"); + mainDialog.hide(); + } + + // unused, but may be useful in the future + // function onClientActivated(client) { + // if (client) { + // console.log("KZones: Client activated: " + client.resourceClass.toString() + " (zone " + client.zone + ")"); + // } + // } + // function onVirtualScreenSizeChanged(){ } + } + + // options connection + Connections { + //! not working at the moment + target: options + + function onConfigChanged() { + log("Config changed") + mainDialog.loadConfig() + } + } + + // activeClient connection + Connections { + target: workspace.activeClient + + // start moving + function onClientStartUserMovedResized(client) { + if (client.resizeable && client.normalWindow) { + if (client.move && checkFilter(client)) { + + cachedClientArea = clientArea + moving = true + moved = false + resizing = false + log("Move start " + client.resourceClass.toString()) + mainDialog.show() + } + if (client.resize) { + moving = false + moved = false + resizing = true + // client resizing + } + } + } + + // is moving + function onClientStepUserMovedResized(client, r) { + + if (client.resizeable) { + if (moving && checkFilter(client)) { + moved = true + if (config.rememberWindowGeometries && client.zone != -1) { + if (client.oldGeometry) { + let geometry = client.oldGeometry + let zone = config.layouts[client.layout].zones[client.zone] + let zoneCenterX = (zone.x + zone.width / 2) / 100 * cachedClientArea.width + cachedClientArea.x + let zoneX = ((zone.x / 100) * cachedClientArea.width + cachedClientArea.x) + let newGeometry = Qt.rect(Math.round((r.x - zoneX) + (zoneCenterX - geometry.width / 2)), Math.round(r.y), Math.round(geometry.width), Math.round(geometry.height)) + client.geometry = newGeometry + } + } + } + if (resizing) { + // client resizing + } + } + } + + // stop moving + function onClientFinishUserMovedResized(client) { + if (moving) { + log("Move end " + client.resourceClass.toString()) + if (moved) { + if (shown) { + moveClientToZone(client, highlightedZone) + } else { + saveWindowGeometries(client, -1) + } + } + hide() + } + if (resizing) { + // client resizing + } + moving = false + moved = false + resizing = false + } + + // check filter + function checkFilter(client) { + + let filter = config.filterList.split(/\r?\n/) + + if (config.filterList.length > 0) { + if (config.filterMode == 0) { // include + return filter.includes(client.resourceClass.toString()) + } + if (config.filterMode == 1) { // exclude + return !filter.includes(client.resourceClass.toString()) + } + } + return true + } + } + + // reusable timer + Timer { + id: delay + + function setTimeout(callback, timeout) { + delay.interval = timeout + delay.repeat = false + delay.triggered.connect(callback) + delay.triggered.connect(function release () { + delay.triggered.disconnect(callback) + delay.triggered.disconnect(release) + }) + delay.start() + } + } + + } + +} diff --git a/kwin/KZones/contents/ui/menu.js b/kwin/KZones/contents/ui/menu.js new file mode 100644 index 0000000..07a1d8c --- /dev/null +++ b/kwin/KZones/contents/ui/menu.js @@ -0,0 +1,28 @@ + + +function test() { + return "check"; +} + +function init() { + KWin.registerUserActionsMenu(function(client){ + return { + text: "Maximize to New Desktop", + items: [ + { + text: "Enabled", + checkable: true, + checked: state.enabled, + triggered: function() { + state.enabled = !state.enabled; + if (state.enabled) { + + } else { + + } + } + }, + ] + }; + }); +} \ No newline at end of file diff --git a/kwin/KZones/contents/ui/ui_config.py b/kwin/KZones/contents/ui/ui_config.py new file mode 100644 index 0000000..1160f7e --- /dev/null +++ b/kwin/KZones/contents/ui/ui_config.py @@ -0,0 +1,558 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '/home/user/Documents/Git/kzones/contents/ui/config.ui' +# +# Created by: PyQt5 UI code generator 5.15.7 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_KWin::KZonesConfigForm(object): + def setupUi(self, KWin::KZonesConfigForm): + KWin::KZonesConfigForm.setObjectName("KWin::KZonesConfigForm") + KWin::KZonesConfigForm.resize(700, 635) + KWin::KZonesConfigForm.setMinimumSize(QtCore.QSize(700, 600)) + self.verticalLayout = QtWidgets.QVBoxLayout(KWin::KZonesConfigForm) + self.verticalLayout.setObjectName("verticalLayout") + self.tabWidget = QtWidgets.QTabWidget(KWin::KZonesConfigForm) + self.tabWidget.setTabPosition(QtWidgets.QTabWidget.North) + self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded) + self.tabWidget.setIconSize(QtCore.QSize(16, 16)) + self.tabWidget.setElideMode(QtCore.Qt.ElideNone) + self.tabWidget.setDocumentMode(False) + self.tabWidget.setTabsClosable(False) + self.tabWidget.setTabBarAutoHide(False) + self.tabWidget.setObjectName("tabWidget") + self.tab_behaviour = QtWidgets.QWidget() + self.tab_behaviour.setObjectName("tab_behaviour") + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.tab_behaviour) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.groupBox_general = QtWidgets.QGroupBox(self.tab_behaviour) + self.groupBox_general.setObjectName("groupBox_general") + self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.groupBox_general) + self.verticalLayout_11.setObjectName("verticalLayout_11") + self.kcfg_rememberWindowGeometries = QtWidgets.QCheckBox(self.groupBox_general) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_rememberWindowGeometries.sizePolicy().hasHeightForWidth()) + self.kcfg_rememberWindowGeometries.setSizePolicy(sizePolicy) + self.kcfg_rememberWindowGeometries.setChecked(True) + self.kcfg_rememberWindowGeometries.setObjectName("kcfg_rememberWindowGeometries") + self.verticalLayout_11.addWidget(self.kcfg_rememberWindowGeometries) + self.kcfg_alwaysShowLayoutName = QtWidgets.QCheckBox(self.groupBox_general) + self.kcfg_alwaysShowLayoutName.setObjectName("kcfg_alwaysShowLayoutName") + self.verticalLayout_11.addWidget(self.kcfg_alwaysShowLayoutName) + self.verticalLayout_4.addWidget(self.groupBox_general) + self.groupBox_target = QtWidgets.QGroupBox(self.tab_behaviour) + self.groupBox_target.setObjectName("groupBox_target") + self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.groupBox_target) + self.verticalLayout_14.setObjectName("verticalLayout_14") + self.formLayout_6 = QtWidgets.QFormLayout() + self.formLayout_6.setObjectName("formLayout_6") + self.kcfg_zoneTarget = QtWidgets.QComboBox(self.groupBox_target) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_zoneTarget.sizePolicy().hasHeightForWidth()) + self.kcfg_zoneTarget.setSizePolicy(sizePolicy) + self.kcfg_zoneTarget.setObjectName("kcfg_zoneTarget") + self.kcfg_zoneTarget.addItem("") + self.kcfg_zoneTarget.addItem("") + self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_zoneTarget) + self.label_5 = QtWidgets.QLabel(self.groupBox_target) + self.label_5.setToolTip("") + self.label_5.setObjectName("label_5") + self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_5) + self.kcfg_targetMethod = QtWidgets.QComboBox(self.groupBox_target) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_targetMethod.sizePolicy().hasHeightForWidth()) + self.kcfg_targetMethod.setSizePolicy(sizePolicy) + self.kcfg_targetMethod.setFrame(True) + self.kcfg_targetMethod.setObjectName("kcfg_targetMethod") + self.kcfg_targetMethod.addItem("") + self.kcfg_targetMethod.addItem("") + self.kcfg_targetMethod.addItem("") + self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcfg_targetMethod) + self.label_14 = QtWidgets.QLabel(self.groupBox_target) + self.label_14.setToolTip("") + self.label_14.setObjectName("label_14") + self.formLayout_6.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_14) + self.kcfg_handleSize = QtWidgets.QSpinBox(self.groupBox_target) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_handleSize.sizePolicy().hasHeightForWidth()) + self.kcfg_handleSize.setSizePolicy(sizePolicy) + self.kcfg_handleSize.setSuffix("") + self.kcfg_handleSize.setMaximum(2147483647) + self.kcfg_handleSize.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType) + self.kcfg_handleSize.setProperty("value", 100) + self.kcfg_handleSize.setObjectName("kcfg_handleSize") + self.formLayout_6.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.kcfg_handleSize) + self.kcfg_handleUnitPercent = QtWidgets.QRadioButton(self.groupBox_target) + self.kcfg_handleUnitPercent.setChecked(True) + self.kcfg_handleUnitPercent.setObjectName("kcfg_handleUnitPercent") + self.formLayout_6.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.kcfg_handleUnitPercent) + self.kcfg_handleUnitPixels = QtWidgets.QRadioButton(self.groupBox_target) + self.kcfg_handleUnitPixels.setObjectName("kcfg_handleUnitPixels") + self.formLayout_6.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.kcfg_handleUnitPixels) + self.label_20 = QtWidgets.QLabel(self.groupBox_target) + self.label_20.setObjectName("label_20") + self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_20) + self.verticalLayout_14.addLayout(self.formLayout_6) + self.verticalLayout_4.addWidget(self.groupBox_target) + self.kcfg_modifierEnabled = QtWidgets.QGroupBox(self.tab_behaviour) + self.kcfg_modifierEnabled.setFlat(False) + self.kcfg_modifierEnabled.setCheckable(True) + self.kcfg_modifierEnabled.setChecked(False) + self.kcfg_modifierEnabled.setObjectName("kcfg_modifierEnabled") + self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.kcfg_modifierEnabled) + self.verticalLayout_12.setObjectName("verticalLayout_12") + self.kcfg_invertedMode = QtWidgets.QCheckBox(self.kcfg_modifierEnabled) + self.kcfg_invertedMode.setObjectName("kcfg_invertedMode") + self.verticalLayout_12.addWidget(self.kcfg_invertedMode) + self.formLayout_4 = QtWidgets.QFormLayout() + self.formLayout_4.setObjectName("formLayout_4") + self.label_27 = QtWidgets.QLabel(self.kcfg_modifierEnabled) + self.label_27.setObjectName("label_27") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_27) + self.kcfg_modifierKey = QtWidgets.QComboBox(self.kcfg_modifierEnabled) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_modifierKey.sizePolicy().hasHeightForWidth()) + self.kcfg_modifierKey.setSizePolicy(sizePolicy) + self.kcfg_modifierKey.setMinimumSize(QtCore.QSize(100, 0)) + self.kcfg_modifierKey.setObjectName("kcfg_modifierKey") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.kcfg_modifierKey.addItem("") + self.formLayout_4.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_modifierKey) + self.verticalLayout_12.addLayout(self.formLayout_4) + self.verticalLayout_4.addWidget(self.kcfg_modifierEnabled) + self.kcfg_npmbEnabled = QtWidgets.QGroupBox(self.tab_behaviour) + self.kcfg_npmbEnabled.setCheckable(True) + self.kcfg_npmbEnabled.setChecked(False) + self.kcfg_npmbEnabled.setObjectName("kcfg_npmbEnabled") + self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.kcfg_npmbEnabled) + self.verticalLayout_13.setObjectName("verticalLayout_13") + self.kcfg_npmbToggle = QtWidgets.QRadioButton(self.kcfg_npmbEnabled) + self.kcfg_npmbToggle.setChecked(True) + self.kcfg_npmbToggle.setObjectName("kcfg_npmbToggle") + self.verticalLayout_13.addWidget(self.kcfg_npmbToggle) + self.kcfg_npmbCycle = QtWidgets.QRadioButton(self.kcfg_npmbEnabled) + self.kcfg_npmbCycle.setObjectName("kcfg_npmbCycle") + self.verticalLayout_13.addWidget(self.kcfg_npmbCycle) + self.verticalLayout_4.addWidget(self.kcfg_npmbEnabled) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_4.addItem(spacerItem) + self.kcfg_modifierEnabled.raise_() + self.kcfg_npmbEnabled.raise_() + self.groupBox_general.raise_() + self.groupBox_target.raise_() + icon = QtGui.QIcon.fromTheme("systemsettings") + self.tabWidget.addTab(self.tab_behaviour, icon, "") + self.tab_layouts = QtWidgets.QWidget() + self.tab_layouts.setObjectName("tab_layouts") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab_layouts) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.label_3 = QtWidgets.QLabel(self.tab_layouts) + font = QtGui.QFont() + font.setPointSize(12) + self.label_3.setFont(font) + self.label_3.setObjectName("label_3") + self.verticalLayout_2.addWidget(self.label_3) + self.kcfg_layoutsJson = QtWidgets.QPlainTextEdit(self.tab_layouts) + self.kcfg_layoutsJson.setObjectName("kcfg_layoutsJson") + self.verticalLayout_2.addWidget(self.kcfg_layoutsJson) + icon = QtGui.QIcon.fromTheme("preferences-desktop-virtual") + self.tabWidget.addTab(self.tab_layouts, icon, "") + self.tab_appearance = QtWidgets.QWidget() + self.tab_appearance.setObjectName("tab_appearance") + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.tab_appearance) + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.groupBox = QtWidgets.QGroupBox(self.tab_appearance) + self.groupBox.setTitle("") + self.groupBox.setObjectName("groupBox") + self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.groupBox) + self.verticalLayout_8.setObjectName("verticalLayout_8") + self.label_22 = QtWidgets.QLabel(self.groupBox) + font = QtGui.QFont() + font.setPointSize(11) + self.label_22.setFont(font) + self.label_22.setObjectName("label_22") + self.verticalLayout_8.addWidget(self.label_22) + self.formLayout_2 = QtWidgets.QFormLayout() + self.formLayout_2.setObjectName("formLayout_2") + self.label_21 = QtWidgets.QLabel(self.groupBox) + self.label_21.setObjectName("label_21") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_21) + self.kcfg_osdTimeout = QtWidgets.QSpinBox(self.groupBox) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_osdTimeout.sizePolicy().hasHeightForWidth()) + self.kcfg_osdTimeout.setSizePolicy(sizePolicy) + self.kcfg_osdTimeout.setMinimum(500) + self.kcfg_osdTimeout.setMaximum(10000) + self.kcfg_osdTimeout.setProperty("value", 1000) + self.kcfg_osdTimeout.setObjectName("kcfg_osdTimeout") + self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcfg_osdTimeout) + self.label_24 = QtWidgets.QLabel(self.groupBox) + self.label_24.setObjectName("label_24") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_24) + self.kcfg_fadeDuration = QtWidgets.QSpinBox(self.groupBox) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_fadeDuration.sizePolicy().hasHeightForWidth()) + self.kcfg_fadeDuration.setSizePolicy(sizePolicy) + self.kcfg_fadeDuration.setMaximum(2000) + self.kcfg_fadeDuration.setProperty("value", 100) + self.kcfg_fadeDuration.setObjectName("kcfg_fadeDuration") + self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_fadeDuration) + self.verticalLayout_8.addLayout(self.formLayout_2) + self.verticalLayout_6.addWidget(self.groupBox) + self.groupBox_2 = QtWidgets.QGroupBox(self.tab_appearance) + self.groupBox_2.setTitle("") + self.groupBox_2.setObjectName("groupBox_2") + self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.groupBox_2) + self.verticalLayout_10.setObjectName("verticalLayout_10") + self.label_17 = QtWidgets.QLabel(self.groupBox_2) + font = QtGui.QFont() + font.setPointSize(11) + self.label_17.setFont(font) + self.label_17.setObjectName("label_17") + self.verticalLayout_10.addWidget(self.label_17) + self.verticalLayout_3 = QtWidgets.QVBoxLayout() + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.formLayout_8 = QtWidgets.QFormLayout() + self.formLayout_8.setObjectName("formLayout_8") + self.label_7 = QtWidgets.QLabel(self.groupBox_2) + self.label_7.setObjectName("label_7") + self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_7) + self.kcolorbutton = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton.sizePolicy().hasHeightForWidth()) + self.kcolorbutton.setSizePolicy(sizePolicy) + self.kcolorbutton.setText("") + self.kcolorbutton.setAlphaChannelEnabled(True) + self.kcolorbutton.setObjectName("kcolorbutton") + self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton) + self.label_10 = QtWidgets.QLabel(self.groupBox_2) + self.label_10.setObjectName("label_10") + self.formLayout_8.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_10) + self.kcolorbutton_4 = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton_4.sizePolicy().hasHeightForWidth()) + self.kcolorbutton_4.setSizePolicy(sizePolicy) + self.kcolorbutton_4.setAlphaChannelEnabled(True) + self.kcolorbutton_4.setObjectName("kcolorbutton_4") + self.formLayout_8.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton_4) + self.horizontalLayout_2.addLayout(self.formLayout_8) + self.formLayout_12 = QtWidgets.QFormLayout() + self.formLayout_12.setObjectName("formLayout_12") + self.label_8 = QtWidgets.QLabel(self.groupBox_2) + self.label_8.setObjectName("label_8") + self.formLayout_12.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_8) + self.kcolorbutton_2 = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton_2.sizePolicy().hasHeightForWidth()) + self.kcolorbutton_2.setSizePolicy(sizePolicy) + self.kcolorbutton_2.setAlphaChannelEnabled(True) + self.kcolorbutton_2.setObjectName("kcolorbutton_2") + self.formLayout_12.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton_2) + self.label_11 = QtWidgets.QLabel(self.groupBox_2) + self.label_11.setObjectName("label_11") + self.formLayout_12.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_11) + self.kcolorbutton_5 = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton_5.sizePolicy().hasHeightForWidth()) + self.kcolorbutton_5.setSizePolicy(sizePolicy) + self.kcolorbutton_5.setAlphaChannelEnabled(True) + self.kcolorbutton_5.setObjectName("kcolorbutton_5") + self.formLayout_12.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton_5) + self.horizontalLayout_2.addLayout(self.formLayout_12) + self.formLayout_11 = QtWidgets.QFormLayout() + self.formLayout_11.setObjectName("formLayout_11") + self.label_9 = QtWidgets.QLabel(self.groupBox_2) + self.label_9.setObjectName("label_9") + self.formLayout_11.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_9) + self.kcolorbutton_3 = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton_3.sizePolicy().hasHeightForWidth()) + self.kcolorbutton_3.setSizePolicy(sizePolicy) + self.kcolorbutton_3.setAlphaChannelEnabled(True) + self.kcolorbutton_3.setObjectName("kcolorbutton_3") + self.formLayout_11.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton_3) + self.label_12 = QtWidgets.QLabel(self.groupBox_2) + self.label_12.setObjectName("label_12") + self.formLayout_11.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_12) + self.kcolorbutton_6 = KColorButton(self.groupBox_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcolorbutton_6.sizePolicy().hasHeightForWidth()) + self.kcolorbutton_6.setSizePolicy(sizePolicy) + self.kcolorbutton_6.setAlphaChannelEnabled(True) + self.kcolorbutton_6.setObjectName("kcolorbutton_6") + self.formLayout_11.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcolorbutton_6) + self.horizontalLayout_2.addLayout(self.formLayout_11) + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout_2.addItem(spacerItem1) + self.verticalLayout_3.addLayout(self.horizontalLayout_2) + self.verticalLayout_10.addLayout(self.verticalLayout_3) + self.verticalLayout_6.addWidget(self.groupBox_2) + self.groupBox_3 = QtWidgets.QGroupBox(self.tab_appearance) + self.groupBox_3.setTitle("") + self.groupBox_3.setObjectName("groupBox_3") + self.verticalLayout_15 = QtWidgets.QVBoxLayout(self.groupBox_3) + self.verticalLayout_15.setObjectName("verticalLayout_15") + self.label_26 = QtWidgets.QLabel(self.groupBox_3) + font = QtGui.QFont() + font.setPointSize(11) + self.label_26.setFont(font) + self.label_26.setObjectName("label_26") + self.verticalLayout_15.addWidget(self.label_26) + self.kcfg_alternateIndicatorStyle = QtWidgets.QCheckBox(self.groupBox_3) + self.kcfg_alternateIndicatorStyle.setObjectName("kcfg_alternateIndicatorStyle") + self.verticalLayout_15.addWidget(self.kcfg_alternateIndicatorStyle) + self.verticalLayout_6.addWidget(self.groupBox_3) + spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_6.addItem(spacerItem2) + icon = QtGui.QIcon.fromTheme("preferences-desktop-theme") + self.tabWidget.addTab(self.tab_appearance, icon, "") + self.tab_filters = QtWidgets.QWidget() + self.tab_filters.setObjectName("tab_filters") + self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.tab_filters) + self.verticalLayout_7.setObjectName("verticalLayout_7") + self.label_19 = QtWidgets.QLabel(self.tab_filters) + font = QtGui.QFont() + font.setPointSize(11) + self.label_19.setFont(font) + self.label_19.setObjectName("label_19") + self.verticalLayout_7.addWidget(self.label_19) + self.formLayout = QtWidgets.QFormLayout() + self.formLayout.setObjectName("formLayout") + self.label_2 = QtWidgets.QLabel(self.tab_filters) + self.label_2.setObjectName("label_2") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_2) + self.kcfg_filterMode = QtWidgets.QComboBox(self.tab_filters) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_filterMode.sizePolicy().hasHeightForWidth()) + self.kcfg_filterMode.setSizePolicy(sizePolicy) + self.kcfg_filterMode.setObjectName("kcfg_filterMode") + self.kcfg_filterMode.addItem("") + self.kcfg_filterMode.addItem("") + self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_filterMode) + self.label_18 = QtWidgets.QLabel(self.tab_filters) + self.label_18.setObjectName("label_18") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_18) + self.kcfg_filterList = QtWidgets.QPlainTextEdit(self.tab_filters) + self.kcfg_filterList.setObjectName("kcfg_filterList") + self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.kcfg_filterList) + self.verticalLayout_7.addLayout(self.formLayout) + icon = QtGui.QIcon.fromTheme("preferences-desktop-filter") + self.tabWidget.addTab(self.tab_filters, icon, "") + self.tab_shortcuts = QtWidgets.QWidget() + self.tab_shortcuts.setObjectName("tab_shortcuts") + self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.tab_shortcuts) + self.verticalLayout_9.setObjectName("verticalLayout_9") + self.verticalLayout_5 = QtWidgets.QVBoxLayout() + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.label_23 = QtWidgets.QLabel(self.tab_shortcuts) + self.label_23.setAlignment(QtCore.Qt.AlignCenter) + self.label_23.setObjectName("label_23") + self.verticalLayout_5.addWidget(self.label_23) + self.verticalLayout_9.addLayout(self.verticalLayout_5) + icon = QtGui.QIcon.fromTheme("configure-shortcuts") + self.tabWidget.addTab(self.tab_shortcuts, icon, "") + self.tab_advanced = QtWidgets.QWidget() + self.tab_advanced.setObjectName("tab_advanced") + self.verticalLayout_91 = QtWidgets.QVBoxLayout(self.tab_advanced) + self.verticalLayout_91.setObjectName("verticalLayout_91") + self.verticalLayout_51 = QtWidgets.QVBoxLayout() + self.verticalLayout_51.setObjectName("verticalLayout_51") + self.groupBox_7 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_7.setTitle("") + self.groupBox_7.setObjectName("groupBox_7") + self.verticalLayout_16 = QtWidgets.QVBoxLayout(self.groupBox_7) + self.verticalLayout_16.setObjectName("verticalLayout_16") + self.label_15 = QtWidgets.QLabel(self.groupBox_7) + font = QtGui.QFont() + font.setPointSize(11) + self.label_15.setFont(font) + self.label_15.setObjectName("label_15") + self.verticalLayout_16.addWidget(self.label_15) + self.formLayout_3 = QtWidgets.QFormLayout() + self.formLayout_3.setObjectName("formLayout_3") + self.label_4 = QtWidgets.QLabel(self.groupBox_7) + self.label_4.setObjectName("label_4") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_4) + self.kcfg_pollingRate = QtWidgets.QSpinBox(self.groupBox_7) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_pollingRate.sizePolicy().hasHeightForWidth()) + self.kcfg_pollingRate.setSizePolicy(sizePolicy) + self.kcfg_pollingRate.setMinimum(10) + self.kcfg_pollingRate.setMaximum(1000) + self.kcfg_pollingRate.setSingleStep(10) + self.kcfg_pollingRate.setProperty("value", 100) + self.kcfg_pollingRate.setObjectName("kcfg_pollingRate") + self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.kcfg_pollingRate) + self.verticalLayout_16.addLayout(self.formLayout_3) + self.verticalLayout_51.addWidget(self.groupBox_7) + self.groupBox_8 = QtWidgets.QGroupBox(self.tab_advanced) + self.groupBox_8.setTitle("") + self.groupBox_8.setObjectName("groupBox_8") + self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.groupBox_8) + self.verticalLayout_17.setObjectName("verticalLayout_17") + self.label_16 = QtWidgets.QLabel(self.groupBox_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth()) + self.label_16.setSizePolicy(sizePolicy) + font = QtGui.QFont() + font.setPointSize(11) + self.label_16.setFont(font) + self.label_16.setObjectName("label_16") + self.verticalLayout_17.addWidget(self.label_16) + self.kcfg_enableDebugMode = QtWidgets.QCheckBox(self.groupBox_8) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.kcfg_enableDebugMode.sizePolicy().hasHeightForWidth()) + self.kcfg_enableDebugMode.setSizePolicy(sizePolicy) + self.kcfg_enableDebugMode.setObjectName("kcfg_enableDebugMode") + self.verticalLayout_17.addWidget(self.kcfg_enableDebugMode) + self.verticalLayout_51.addWidget(self.groupBox_8) + self.verticalLayout_91.addLayout(self.verticalLayout_51) + spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.verticalLayout_91.addItem(spacerItem3) + icon = QtGui.QIcon.fromTheme("applications-development") + self.tabWidget.addTab(self.tab_advanced, icon, "") + self.verticalLayout.addWidget(self.tabWidget) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.label_25 = QtWidgets.QLabel(KWin::KZonesConfigForm) + self.label_25.setOpenExternalLinks(True) + self.label_25.setObjectName("label_25") + self.horizontalLayout.addWidget(self.label_25) + self.label_13 = QtWidgets.QLabel(KWin::KZonesConfigForm) + font = QtGui.QFont() + font.setBold(False) + font.setItalic(False) + font.setUnderline(False) + font.setWeight(50) + font.setStrikeOut(False) + self.label_13.setFont(font) + self.label_13.setToolTip("") + self.label_13.setScaledContents(False) + self.label_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_13.setObjectName("label_13") + self.horizontalLayout.addWidget(self.label_13) + self.verticalLayout.addLayout(self.horizontalLayout) + + self.retranslateUi(KWin::KZonesConfigForm) + self.tabWidget.setCurrentIndex(0) + self.kcfg_modifierKey.setCurrentIndex(5) + QtCore.QMetaObject.connectSlotsByName(KWin::KZonesConfigForm) + + def retranslateUi(self, KWin::KZonesConfigForm): + _translate = QtCore.QCoreApplication.translate + self.groupBox_general.setTitle(_translate("KWin::KZonesConfigForm", "General")) + self.kcfg_rememberWindowGeometries.setText(_translate("KWin::KZonesConfigForm", "Remember and restore window geometries")) + self.kcfg_alwaysShowLayoutName.setText(_translate("KWin::KZonesConfigForm", "Always show layout name")) + self.groupBox_target.setTitle(_translate("KWin::KZonesConfigForm", "Zone determination")) + self.kcfg_zoneTarget.setToolTip(_translate("KWin::KZonesConfigForm", "The part of the zone you need to hover over to highlight it")) + self.kcfg_zoneTarget.setItemText(0, _translate("KWin::KZonesConfigForm", "Indicator")) + self.kcfg_zoneTarget.setItemText(1, _translate("KWin::KZonesConfigForm", "Zone")) + self.label_5.setText(_translate("KWin::KZonesConfigForm", "Method")) + self.kcfg_targetMethod.setToolTip(_translate("KWin::KZonesConfigForm", "Method to determine in which zone the window is located")) + self.kcfg_targetMethod.setItemText(0, _translate("KWin::KZonesConfigForm", "Titlebar")) + self.kcfg_targetMethod.setItemText(1, _translate("KWin::KZonesConfigForm", "Window")) + self.kcfg_targetMethod.setItemText(2, _translate("KWin::KZonesConfigForm", "Cursor")) + self.label_14.setText(_translate("KWin::KZonesConfigForm", "Size")) + self.kcfg_handleSize.setToolTip(_translate("KWin::KZonesConfigForm", "Set the size of the handle, only applicable when target method is Titlebar or Window")) + self.kcfg_handleUnitPercent.setText(_translate("KWin::KZonesConfigForm", "Percent")) + self.kcfg_handleUnitPixels.setText(_translate("KWin::KZonesConfigForm", "Pixels")) + self.label_20.setText(_translate("KWin::KZonesConfigForm", "Target")) + self.kcfg_modifierEnabled.setTitle(_translate("KWin::KZonesConfigForm", "Modifier key (X11)")) + self.kcfg_invertedMode.setText(_translate("KWin::KZonesConfigForm", "Hold modifier key to activate zones while dragging")) + self.label_27.setText(_translate("KWin::KZonesConfigForm", "Modifier key")) + self.kcfg_modifierKey.setItemText(0, _translate("KWin::KZonesConfigForm", "Alt")) + self.kcfg_modifierKey.setItemText(1, _translate("KWin::KZonesConfigForm", "AltGr")) + self.kcfg_modifierKey.setItemText(2, _translate("KWin::KZonesConfigForm", "Ctrl")) + self.kcfg_modifierKey.setItemText(3, _translate("KWin::KZonesConfigForm", "Hyper")) + self.kcfg_modifierKey.setItemText(4, _translate("KWin::KZonesConfigForm", "Meta")) + self.kcfg_modifierKey.setItemText(5, _translate("KWin::KZonesConfigForm", "Shift")) + self.kcfg_modifierKey.setItemText(6, _translate("KWin::KZonesConfigForm", "Super")) + self.kcfg_npmbEnabled.setTitle(_translate("KWin::KZonesConfigForm", "Non-primary mouse button (X11)")) + self.kcfg_npmbToggle.setText(_translate("KWin::KZonesConfigForm", "Toggles zone activation")) + self.kcfg_npmbCycle.setText(_translate("KWin::KZonesConfigForm", "Cycles between layouts")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_behaviour), _translate("KWin::KZonesConfigForm", "Behaviour")) + self.label_3.setText(_translate("KWin::KZonesConfigForm", "JSON")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_layouts), _translate("KWin::KZonesConfigForm", "Layouts")) + self.label_22.setText(_translate("KWin::KZonesConfigForm", "Animations")) + self.label_21.setText(_translate("KWin::KZonesConfigForm", "OSD timeout")) + self.kcfg_osdTimeout.setSuffix(_translate("KWin::KZonesConfigForm", " ms")) + self.label_24.setText(_translate("KWin::KZonesConfigForm", "Fade duration")) + self.kcfg_fadeDuration.setSuffix(_translate("KWin::KZonesConfigForm", " ms")) + self.label_17.setText(_translate("KWin::KZonesConfigForm", "Colors")) + self.label_7.setText(_translate("KWin::KZonesConfigForm", "Background")) + self.label_10.setText(_translate("KWin::KZonesConfigForm", "Font")) + self.label_8.setText(_translate("KWin::KZonesConfigForm", "Handle")) + self.label_11.setText(_translate("KWin::KZonesConfigForm", "Target")) + self.label_9.setText(_translate("KWin::KZonesConfigForm", "Zone")) + self.label_12.setText(_translate("KWin::KZonesConfigForm", "Center")) + self.label_26.setText(_translate("KWin::KZonesConfigForm", "Style")) + self.kcfg_alternateIndicatorStyle.setText(_translate("KWin::KZonesConfigForm", "Alternate indicator style")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_appearance), _translate("KWin::KZonesConfigForm", "Appearance")) + self.label_19.setText(_translate("KWin::KZonesConfigForm", "Filtering")) + self.label_2.setText(_translate("KWin::KZonesConfigForm", "Mode")) + self.kcfg_filterMode.setItemText(0, _translate("KWin::KZonesConfigForm", "Include")) + self.kcfg_filterMode.setItemText(1, _translate("KWin::KZonesConfigForm", "Exclude")) + self.label_18.setText(_translate("KWin::KZonesConfigForm", "Filter")) + self.kcfg_filterList.setToolTip(_translate("KWin::KZonesConfigForm", "Enter window classes you wish to include/exclude (seperated by a new line)")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_filters), _translate("KWin::KZonesConfigForm", "Filters")) + self.label_23.setText(_translate("KWin::KZonesConfigForm", "

To set up shortcuts for this script

Go to System Settings / Shortcuts and search for "KZones"

")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_shortcuts), _translate("KWin::KZonesConfigForm", "Shortcuts")) + self.label_15.setText(_translate("KWin::KZonesConfigForm", "Performance")) + self.label_4.setToolTip(_translate("KWin::KZonesConfigForm", "Speed of which the zone checking is done")) + self.label_4.setText(_translate("KWin::KZonesConfigForm", "Polling rate")) + self.kcfg_pollingRate.setToolTip(_translate("KWin::KZonesConfigForm", "Speed of which the zone checking is done")) + self.kcfg_pollingRate.setSuffix(_translate("KWin::KZonesConfigForm", " ms")) + self.label_16.setText(_translate("KWin::KZonesConfigForm", "Debug")) + self.kcfg_enableDebugMode.setText(_translate("KWin::KZonesConfigForm", "Enable debug mode")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_advanced), _translate("KWin::KZonesConfigForm", "Advanced")) + self.label_25.setToolTip(_translate("KWin::KZonesConfigForm", "https://github.com/gerritdevriese/kzones")) + self.label_25.setText(_translate("KWin::KZonesConfigForm", "Github page")) + self.label_13.setText(_translate("KWin::KZonesConfigForm", "Please reload the script after making changes to apply them")) +from kcolorbutton import KColorButton diff --git a/kwin/KZones/metadata.desktop b/kwin/KZones/metadata.desktop new file mode 100644 index 0000000..9491899 --- /dev/null +++ b/kwin/KZones/metadata.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Name=KZones +Comment=Utility for snapping windows into zones + +Icon=preferences-desktop-virtual +Type=Service + +X-Plasma-API=declarativescript +X-Plasma-MainScript=ui/main.qml + +X-KDE-ServiceTypes=KWin/Script +X-KDE-ConfigModule=kwin/effects/configs/kcm_kwin4_genericscripted + +X-KDE-PluginInfo-Author=gerritdevriese +X-KDE-PluginInfo-Name=kzones +X-KDE-PluginInfo-Version=0.6 +X-KDE-PluginInfo-Website=https://kde.org +X-KDE-PluginInfo-Category=Utilities +X-KDE-PluginInfo-License=GPL-3.0+ +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-PluginInfo-Website=https://github.com/gerritdevriese/kzones \ No newline at end of file