1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

desktop widgets: add grid/grid size hints

This commit is contained in:
bbedward
2025-12-19 14:04:37 -05:00
parent f2611e0de0
commit 908b4b58cd
15 changed files with 3508 additions and 2367 deletions

View File

@@ -447,6 +447,21 @@ Singleton {
property var systemMonitorDisplayPreferences: ["all"]
property var systemMonitorVariants: []
property var desktopWidgetPositions: ({})
property var desktopWidgetGridSettings: ({})
function getDesktopWidgetGridSetting(screenKey, property, defaultValue) {
const val = desktopWidgetGridSettings?.[screenKey]?.[property];
return val !== undefined ? val : defaultValue;
}
function setDesktopWidgetGridSetting(screenKey, property, value) {
const allSettings = JSON.parse(JSON.stringify(desktopWidgetGridSettings || {}));
if (!allSettings[screenKey])
allSettings[screenKey] = {};
allSettings[screenKey][property] = value;
desktopWidgetGridSettings = allSettings;
saveSettings();
}
function getDesktopWidgetPosition(pluginId, screenKey, property, defaultValue) {
const pos = desktopWidgetPositions?.[pluginId]?.[screenKey]?.[property];

View File

@@ -341,7 +341,8 @@ var SPEC = {
systemMonitorHeight: { def: 480 },
systemMonitorDisplayPreferences: { def: ["all"] },
systemMonitorVariants: { def: [] },
desktopWidgetPositions: { def: {} }
desktopWidgetPositions: { def: {} },
desktopWidgetGridSettings: { def: {} }
};
function getValidKeys() {

View File

@@ -1,9 +1,11 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Hyprland
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: root
@@ -86,6 +88,20 @@ Item {
property bool forceSquare: contentLoader.item?.forceSquare ?? false
property bool isInteracting: dragArea.pressed || resizeArea.pressed
property var _gridSettingsTrigger: SettingsData.desktopWidgetGridSettings
readonly property int gridSize: {
void _gridSettingsTrigger;
return SettingsData.getDesktopWidgetGridSetting(screenKey, "size", 40);
}
readonly property bool gridEnabled: {
void _gridSettingsTrigger;
return SettingsData.getDesktopWidgetGridSetting(screenKey, "enabled", false);
}
function snapToGrid(value) {
return Math.round(value / gridSize) * gridSize;
}
function updateVariantPositions(updates) {
const positions = JSON.parse(JSON.stringify(variantData?.positions || {}));
positions[screenKey] = Object.assign({}, positions[screenKey] || {}, updates);
@@ -141,7 +157,13 @@ Item {
WlrLayershell.namespace: "quickshell:desktop-widget:" + root.pluginId + (root.variantId ? ":" + root.variantId : "")
WlrLayershell.layer: WlrLayer.Bottom
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: (CompositorService.useHyprlandFocusGrab && root.isInteracting) ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: {
if (!root.isInteracting)
return WlrKeyboardFocus.None;
if (CompositorService.useHyprlandFocusGrab)
return WlrKeyboardFocus.OnDemand;
return WlrKeyboardFocus.Exclusive;
}
HyprlandFocusGrab {
active: CompositorService.isHyprland && root.isInteracting
@@ -238,8 +260,12 @@ Item {
if (!pressed)
return;
const currentPos = root.useGhostPreview ? Qt.point(mouse.x, mouse.y) : mapToGlobal(mouse.x, mouse.y);
const newX = Math.max(0, Math.min(startX + currentPos.x - startPos.x, root.screenWidth - root.widgetWidth));
const newY = Math.max(0, Math.min(startY + currentPos.y - startPos.y, root.screenHeight - root.widgetHeight));
let newX = Math.max(0, Math.min(startX + currentPos.x - startPos.x, root.screenWidth - root.widgetWidth));
let newY = Math.max(0, Math.min(startY + currentPos.y - startPos.y, root.screenHeight - root.widgetHeight));
if (root.gridEnabled) {
newX = Math.max(0, Math.min(root.snapToGrid(newX), root.screenWidth - root.widgetWidth));
newY = Math.max(0, Math.min(root.snapToGrid(newY), root.screenHeight - root.widgetHeight));
}
if (root.useGhostPreview) {
root.previewX = newX;
root.previewY = newY;
@@ -285,6 +311,10 @@ Item {
const currentPos = root.useGhostPreview ? Qt.point(mouse.x, mouse.y) : mapToGlobal(mouse.x, mouse.y);
let newW = Math.max(root.minWidth, Math.min(startWidth + currentPos.x - startPos.x, root.screenWidth - root.widgetX));
let newH = Math.max(root.minHeight, Math.min(startHeight + currentPos.y - startPos.y, root.screenHeight - root.widgetY));
if (root.gridEnabled) {
newW = Math.max(root.minWidth, root.snapToGrid(newW));
newH = Math.max(root.minHeight, root.snapToGrid(newH));
}
if (root.forceSquare) {
const size = Math.max(newW, newH);
newW = Math.min(size, root.screenWidth - root.widgetX);
@@ -330,6 +360,39 @@ Item {
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
Item {
id: gridOverlay
anchors.fill: parent
visible: root.gridEnabled
opacity: 0.3
Repeater {
model: Math.ceil(root.screenWidth / root.gridSize)
Rectangle {
required property int index
x: index * root.gridSize
y: 0
width: 1
height: root.screenHeight
color: Theme.primary
}
}
Repeater {
model: Math.ceil(root.screenHeight / root.gridSize)
Rectangle {
required property int index
x: 0
y: index * root.gridSize
width: root.screenWidth
height: 1
color: Theme.primary
}
}
}
Rectangle {
x: root.previewX
y: root.previewY
@@ -355,4 +418,177 @@ Item {
}
}
}
Loader {
active: root.isInteracting && root.gridEnabled && !root.useGhostPreview
sourceComponent: PanelWindow {
screen: root.screen
color: "transparent"
anchors {
left: true
right: true
top: true
bottom: true
}
mask: Region {}
WlrLayershell.namespace: "quickshell:desktop-widget-grid"
WlrLayershell.layer: WlrLayer.Background
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
Item {
anchors.fill: parent
opacity: 0.3
Repeater {
model: Math.ceil(root.screenWidth / root.gridSize)
Rectangle {
required property int index
x: index * root.gridSize
y: 0
width: 1
height: root.screenHeight
color: Theme.primary
}
}
Repeater {
model: Math.ceil(root.screenHeight / root.gridSize)
Rectangle {
required property int index
x: 0
y: index * root.gridSize
width: root.screenWidth
height: 1
color: Theme.primary
}
}
}
}
}
Loader {
active: root.isInteracting
sourceComponent: PanelWindow {
id: helperWindow
screen: root.screen
color: "transparent"
WlrLayershell.namespace: "quickshell:desktop-widget-helper"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.keyboardFocus: {
if (CompositorService.useHyprlandFocusGrab)
return WlrKeyboardFocus.OnDemand;
return WlrKeyboardFocus.Exclusive;
}
HyprlandFocusGrab {
active: CompositorService.isHyprland
windows: [helperWindow]
}
anchors {
bottom: true
left: true
right: true
}
implicitHeight: 60
Item {
anchors.fill: parent
focus: true
Keys.onPressed: event => {
switch (event.key) {
case Qt.Key_G:
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "enabled", !root.gridEnabled);
event.accepted = true;
break;
case Qt.Key_Z:
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "size", Math.max(10, root.gridSize - 10));
event.accepted = true;
break;
case Qt.Key_X:
SettingsData.setDesktopWidgetGridSetting(root.screenKey, "size", Math.min(200, root.gridSize + 10));
event.accepted = true;
break;
}
}
}
Rectangle {
id: helperContent
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacingL
width: helperRow.implicitWidth + Theme.spacingM * 2
height: 32
radius: Theme.cornerRadius
color: Theme.surface
Row {
id: helperRow
anchors.centerIn: parent
spacing: Theme.spacingM
height: parent.height
DankIcon {
name: "grid_on"
size: 16
color: root.gridEnabled ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: root.gridEnabled ? I18n.tr("Grid: ON", "Widget grid snap status") : I18n.tr("Grid: OFF", "Widget grid snap status")
font.pixelSize: Theme.fontSizeSmall
font.family: Theme.fontFamily
color: root.gridEnabled ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
width: 1
height: 16
color: Theme.outline
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: root.gridSize + "px"
font.pixelSize: Theme.fontSizeSmall
font.family: Theme.fontFamily
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
width: 1
height: 16
color: Theme.outline
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: I18n.tr("G: grid • Z/X: size", "Widget grid keyboard hints")
font.pixelSize: Theme.fontSizeSmall
font.family: Theme.fontFamily
font.italic: true
color: Theme.surfaceText
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
}
}

View File

@@ -548,7 +548,7 @@
{
"term": "Audio Codec Selection",
"context": "Audio Codec Selection",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:173",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:180",
"comment": ""
},
{
@@ -848,7 +848,7 @@
{
"term": "Battery",
"context": "Battery",
"reference": "Modules/Settings/WidgetsTabSection.qml:838, Modules/Settings/WidgetsTab.qml:168, Modules/ControlCenter/Models/WidgetModel.qml:161, Modules/ControlCenter/Widgets/BatteryPill.qml:19",
"reference": "Modules/Settings/WidgetsTabSection.qml:838, Modules/Settings/WidgetsTab.qml:168, Modules/ControlCenter/Models/WidgetModel.qml:161, Modules/ControlCenter/Widgets/BatteryPill.qml:17",
"comment": ""
},
{
@@ -884,7 +884,7 @@
{
"term": "Binds include added",
"context": "Binds include added",
"reference": "Services/KeybindsService.qml:217",
"reference": "Services/KeybindsService.qml:218",
"comment": ""
},
{
@@ -1118,7 +1118,7 @@
{
"term": "Capacity",
"context": "Capacity",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:171, Modules/DankBar/Popouts/BatteryPopout.qml:340, Modules/DankBar/Popouts/BatteryPopout.qml:498",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:169, Modules/DankBar/Popouts/BatteryPopout.qml:340, Modules/DankBar/Popouts/BatteryPopout.qml:498",
"comment": ""
},
{
@@ -1172,7 +1172,7 @@
{
"term": "Charging",
"context": "Charging",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:27",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:25",
"comment": ""
},
{
@@ -1196,7 +1196,7 @@
{
"term": "Choose a color",
"context": "Choose a color",
"reference": "Modules/ControlCenter/Widgets/ColorPickerPill.qml:18",
"reference": "Modules/ControlCenter/Widgets/ColorPickerPill.qml:14",
"comment": ""
},
{
@@ -1412,7 +1412,7 @@
{
"term": "Color Picker",
"context": "Color Picker",
"reference": "Modules/Settings/WidgetsTab.qml:231, Modules/ControlCenter/Models/WidgetModel.qml:179, Modules/ControlCenter/Widgets/ColorPickerPill.qml:17",
"reference": "Modules/Settings/WidgetsTab.qml:231, Modules/ControlCenter/Models/WidgetModel.qml:179, Modules/ControlCenter/Widgets/ColorPickerPill.qml:13",
"comment": ""
},
{
@@ -1760,7 +1760,7 @@
{
"term": "Current: %1",
"context": "Current: %1",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:189",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:194",
"comment": ""
},
{
@@ -2186,7 +2186,7 @@
{
"term": "Disk Usage",
"context": "Disk Usage",
"reference": "Modules/Settings/WidgetsTab.qml:116, Modules/ControlCenter/Models/WidgetModel.qml:169, Modules/ControlCenter/Widgets/DiskUsagePill.qml:37",
"reference": "Modules/Settings/WidgetsTab.qml:116, Modules/ControlCenter/Models/WidgetModel.qml:169, Modules/ControlCenter/Widgets/DiskUsagePill.qml:35",
"comment": ""
},
{
@@ -2666,7 +2666,7 @@
{
"term": "Failed to add binds include",
"context": "Failed to add binds include",
"reference": "Services/KeybindsService.qml:204",
"reference": "Services/KeybindsService.qml:205",
"comment": ""
},
{
@@ -2834,7 +2834,7 @@
{
"term": "Failed to remove keybind",
"context": "Failed to remove keybind",
"reference": "Services/KeybindsService.qml:181",
"reference": "Services/KeybindsService.qml:182",
"comment": ""
},
{
@@ -2864,7 +2864,7 @@
{
"term": "Failed to save keybind",
"context": "Failed to save keybind",
"reference": "Services/KeybindsService.qml:155",
"reference": "Services/KeybindsService.qml:156",
"comment": ""
},
{
@@ -2894,13 +2894,13 @@
{
"term": "Failed to set profile image",
"context": "Failed to set profile image",
"reference": "Services/PortalService.qml:150",
"reference": "Services/PortalService.qml:145",
"comment": ""
},
{
"term": "Failed to set profile image: %1",
"context": "Failed to set profile image: %1",
"reference": "Services/PortalService.qml:159",
"reference": "Services/PortalService.qml:154",
"comment": ""
},
{
@@ -3155,6 +3155,12 @@
"reference": "Widgets/DankIconPicker.qml:60",
"comment": ""
},
{
"term": "G: grid • Z/X: size",
"context": "Widget grid keyboard hints",
"reference": "Modules/Plugins/DesktopPluginWrapper.qml:582",
"comment": ""
},
{
"term": "GPU",
"context": "GPU",
@@ -3245,6 +3251,18 @@
"reference": "Modules/Settings/LauncherTab.qml:330",
"comment": ""
},
{
"term": "Grid: OFF",
"context": "Widget grid snap status",
"reference": "Modules/Plugins/DesktopPluginWrapper.qml:552",
"comment": ""
},
{
"term": "Grid: ON",
"context": "Widget grid snap status",
"reference": "Modules/Plugins/DesktopPluginWrapper.qml:552",
"comment": ""
},
{
"term": "Group by App",
"context": "Group by App",
@@ -3284,7 +3302,7 @@
{
"term": "Health",
"context": "Health",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:136, Modules/DankBar/Popouts/BatteryPopout.qml:305, Modules/DankBar/Popouts/BatteryPopout.qml:461",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:134, Modules/DankBar/Popouts/BatteryPopout.qml:305, Modules/DankBar/Popouts/BatteryPopout.qml:461",
"comment": ""
},
{
@@ -3788,7 +3806,7 @@
{
"term": "Loading codecs...",
"context": "Loading codecs...",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:189",
"reference": "Modules/ControlCenter/Details/BluetoothCodecSelector.qml:194",
"comment": ""
},
{
@@ -3926,7 +3944,7 @@
{
"term": "Management",
"context": "Management",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:84",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:82",
"comment": ""
},
{
@@ -4448,7 +4466,7 @@
{
"term": "No battery",
"context": "No battery",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:17",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:15",
"comment": ""
},
{
@@ -4478,13 +4496,13 @@
{
"term": "No disk data",
"context": "No disk data",
"reference": "Modules/ControlCenter/Widgets/DiskUsagePill.qml:40",
"reference": "Modules/ControlCenter/Widgets/DiskUsagePill.qml:38",
"comment": ""
},
{
"term": "No disk data available",
"context": "No disk data available",
"reference": "Modules/ControlCenter/Details/DiskUsageDetail.qml:64, Modules/ControlCenter/Widgets/DiskUsagePill.qml:50",
"reference": "Modules/ControlCenter/Details/DiskUsageDetail.qml:62, Modules/ControlCenter/Widgets/DiskUsagePill.qml:48",
"comment": ""
},
{
@@ -4586,7 +4604,7 @@
{
"term": "Not available",
"context": "Not available",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:24",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:22",
"comment": ""
},
{
@@ -4940,7 +4958,7 @@
{
"term": "Permission denied to set profile image.",
"context": "Permission denied to set profile image.",
"reference": "Services/PortalService.qml:155",
"reference": "Services/PortalService.qml:150",
"comment": ""
},
{
@@ -5018,7 +5036,7 @@
{
"term": "Plugged in",
"context": "Plugged in",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:30",
"reference": "Modules/ControlCenter/Widgets/BatteryPill.qml:28",
"comment": ""
},
{
@@ -5084,7 +5102,7 @@
{
"term": "Power",
"context": "Power",
"reference": "Modules/Settings/WidgetsTab.qml:245, Modules/ControlCenter/Details/BatteryDetail.qml:69",
"reference": "Modules/Settings/WidgetsTab.qml:245, Modules/ControlCenter/Details/BatteryDetail.qml:67",
"comment": ""
},
{
@@ -5132,13 +5150,13 @@
{
"term": "Power Profile Degradation",
"context": "Power Profile Degradation",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:242, Modules/DankBar/Popouts/BatteryPopout.qml:620",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:240, Modules/DankBar/Popouts/BatteryPopout.qml:620",
"comment": ""
},
{
"term": "Power profile management available",
"context": "Power profile management available",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:103",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:101",
"comment": ""
},
{
@@ -5276,13 +5294,13 @@
{
"term": "Profile Image Error",
"context": "Profile Image Error",
"reference": "Services/PortalService.qml:162",
"reference": "Services/PortalService.qml:157",
"comment": ""
},
{
"term": "Profile image is too large. Please use a smaller image.",
"context": "Profile image is too large. Please use a smaller image.",
"reference": "Services/PortalService.qml:153",
"reference": "Services/PortalService.qml:148",
"comment": ""
},
{
@@ -5876,7 +5894,7 @@
{
"term": "Selected image file not found.",
"context": "Selected image file not found.",
"reference": "Services/PortalService.qml:157",
"reference": "Services/PortalService.qml:152",
"comment": ""
},
{
@@ -6752,13 +6770,13 @@
{
"term": "Time remaining: %1",
"context": "Time remaining: %1",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:106",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:104",
"comment": ""
},
{
"term": "Time until full: %1",
"context": "Time until full: %1",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:106",
"reference": "Modules/ControlCenter/Details/BatteryDetail.qml:104",
"comment": ""
},
{
@@ -6950,7 +6968,7 @@
{
"term": "Unknown",
"context": "Unknown",
"reference": "Modules/Settings/PrinterTab.qml:1296, Modules/Settings/NetworkTab.qml:121, Modules/Settings/NetworkTab.qml:163, Modules/Settings/NetworkTab.qml:369, Modules/Settings/NetworkTab.qml:390, Modules/Settings/NetworkTab.qml:538, Modules/Settings/NetworkTab.qml:667, Modules/Settings/NetworkTab.qml:1071, Modules/ControlCenter/Details/BatteryDetail.qml:179, Modules/ControlCenter/Components/HeaderPane.qml:60",
"reference": "Modules/Settings/PrinterTab.qml:1296, Modules/Settings/NetworkTab.qml:121, Modules/Settings/NetworkTab.qml:163, Modules/Settings/NetworkTab.qml:369, Modules/Settings/NetworkTab.qml:390, Modules/Settings/NetworkTab.qml:538, Modules/Settings/NetworkTab.qml:667, Modules/Settings/NetworkTab.qml:1071, Modules/ControlCenter/Details/BatteryDetail.qml:177, Modules/ControlCenter/Components/HeaderPane.qml:60",
"comment": ""
},
{
@@ -7592,7 +7610,7 @@
{
"term": "dgop not available",
"context": "dgop not available",
"reference": "Modules/ControlCenter/Details/DiskUsageDetail.qml:64, Modules/ControlCenter/Widgets/DiskUsagePill.qml:47",
"reference": "Modules/ControlCenter/Details/DiskUsageDetail.qml:62, Modules/ControlCenter/Widgets/DiskUsagePill.qml:45",
"comment": ""
},
{
@@ -7604,7 +7622,7 @@
{
"term": "dms/binds.kdl is now included in config.kdl",
"context": "dms/binds.kdl is now included in config.kdl",
"reference": "Services/KeybindsService.qml:217",
"reference": "Services/KeybindsService.qml:218",
"comment": ""
},
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3681,6 +3681,13 @@
"reference": "",
"comment": ""
},
{
"term": "G: grid • Z/X: size",
"translation": "",
"context": "Widget grid keyboard hints",
"reference": "",
"comment": ""
},
{
"term": "GPU",
"translation": "",
@@ -3786,6 +3793,20 @@
"reference": "",
"comment": ""
},
{
"term": "Grid: OFF",
"translation": "",
"context": "Widget grid snap status",
"reference": "",
"comment": ""
},
{
"term": "Grid: ON",
"translation": "",
"context": "Widget grid snap status",
"reference": "",
"comment": ""
},
{
"term": "Group by App",
"translation": "",