mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-20 02:04:01 -04:00
wheel: use WheelInput horizontal helper, make default action cycle
window on WS pill
This commit is contained in:
+1
-1
Submodule dank-qml-common updated: df82b1265c...212ac8cc7d
Generated
+3
-3
@@ -3,11 +3,11 @@
|
||||
"dank-qml-common": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1791492221,
|
||||
"narHash": "sha256-RzuPqnlzsoAIXpyPDaAV9yPO4Tj39PfZ4JRftDpa4UQ=",
|
||||
"lastModified": 1791563938,
|
||||
"narHash": "sha256-Pg9M+qGfLKqKih7thzP4QLuKsi9jauSIEiQy8T6+EoY=",
|
||||
"owner": "AvengeMedia",
|
||||
"repo": "dank-qml-common",
|
||||
"rev": "df82b1265c085f615d7403e6b3320e234221fd3b",
|
||||
"rev": "212ac8cc7d83e1b5d10ae63535abfab0b1903624",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -23,7 +23,7 @@ Singleton {
|
||||
id: root
|
||||
readonly property var log: Log.scoped("SettingsData")
|
||||
|
||||
readonly property int settingsConfigVersion: 39
|
||||
readonly property int settingsConfigVersion: 40
|
||||
|
||||
readonly property bool isGreeterMode: Quickshell.env("DMS_RUN_GREETER") === "1" || Quickshell.env("DMS_RUN_GREETER") === "true"
|
||||
|
||||
|
||||
@@ -1553,7 +1553,7 @@ var LOCAL_SPEC = {
|
||||
maximizeDetection: true,
|
||||
useOverlayLayer: false,
|
||||
scrollEnabled: true,
|
||||
scrollXBehavior: "column",
|
||||
scrollXBehavior: "focusWindow",
|
||||
scrollYBehavior: "workspace",
|
||||
middleClickAction: "none",
|
||||
rightClickAction: "none",
|
||||
|
||||
@@ -206,7 +206,8 @@ function toJson(root, setKeys) {
|
||||
value = withoutInstancePositions(value);
|
||||
if (k === "builtInPluginSettings")
|
||||
value = withoutSessionBackedPluginState(value);
|
||||
if (!setKeys.has(k) && Util.isDefault(value, SPEC[k].def)) continue;
|
||||
if (!setKeys.has(k) && Util.isDefault(value, SPEC[k].def))
|
||||
continue;
|
||||
out[k] = value;
|
||||
}
|
||||
out.configVersion = root.settingsConfigVersion;
|
||||
@@ -722,9 +723,26 @@ function migrateToVersion(obj, targetVersion) {
|
||||
settings.configVersion = 39;
|
||||
}
|
||||
|
||||
if (currentVersion < 40 && targetVersion >= 40) {
|
||||
migrateScrollColumnBehavior(settings);
|
||||
settings.configVersion = 40;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
// v40: the niri-only "column" scroll behavior became the compositor-neutral "focusWindow"
|
||||
function migrateScrollColumnBehavior(settings) {
|
||||
for (const bar of Array.isArray(settings.barConfigs) ? settings.barConfigs : []) {
|
||||
if (!bar || typeof bar !== "object")
|
||||
continue;
|
||||
for (const key of ["scrollXBehavior", "scrollYBehavior"]) {
|
||||
if (bar[key] === "column")
|
||||
bar[key] = "focusWindow";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// v39: the per-island toggle folded into the global reduceMotion; any bar that had it on turns the global one on
|
||||
function migrateIslandReducedMotion(settings) {
|
||||
for (const bar of Array.isArray(settings.barConfigs) ? settings.barConfigs : []) {
|
||||
|
||||
@@ -9,7 +9,7 @@ MouseArea {
|
||||
id: root
|
||||
|
||||
property bool scrollEnabled: true
|
||||
property string xBehavior: "column"
|
||||
property string xBehavior: "focusWindow"
|
||||
property string yBehavior: "workspace"
|
||||
property string screenName: ""
|
||||
property var barConfig: null
|
||||
@@ -18,6 +18,8 @@ MouseArea {
|
||||
property real mouseAccumulatorX: 0
|
||||
property real mouseAccumulatorY: 0
|
||||
property bool actionInProgress: false
|
||||
property bool gestureActive: false
|
||||
property bool gestureHorizontal: false
|
||||
|
||||
signal workspaceSwitchRequested(int direction)
|
||||
|
||||
@@ -34,14 +36,8 @@ MouseArea {
|
||||
case "workspace":
|
||||
workspaceSwitchRequested(direction);
|
||||
return true;
|
||||
case "column":
|
||||
if (!CompositorService.isNiri)
|
||||
return false;
|
||||
if (direction > 0)
|
||||
NiriService.moveColumnRight(screenName);
|
||||
else
|
||||
NiriService.moveColumnLeft(screenName);
|
||||
return true;
|
||||
case "focusWindow":
|
||||
return CompositorService.stepWindowFocus(screenName, direction);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -88,22 +84,34 @@ MouseArea {
|
||||
mouseAccumulatorY = 0;
|
||||
}
|
||||
|
||||
function horizontalGesture(wheel, isTouchpad) {
|
||||
if (!isTouchpad)
|
||||
return WheelInput.isHorizontal(wheel);
|
||||
if (!gestureActive || wheel.phase === Qt.ScrollBegin)
|
||||
gestureHorizontal = WheelInput.isHorizontal(wheel);
|
||||
gestureActive = true;
|
||||
return gestureHorizontal;
|
||||
}
|
||||
|
||||
function processWheel(wheel) {
|
||||
wheel.accepted = false;
|
||||
if (wheel.phase === Qt.ScrollEnd)
|
||||
gestureActive = false;
|
||||
if (!scrollEnabled || actionInProgress)
|
||||
return;
|
||||
|
||||
const deltaY = wheel.angleDelta.y;
|
||||
const deltaX = wheel.angleDelta.x;
|
||||
const delta = WheelInput.dominantDelta(wheel.angleDelta);
|
||||
if (delta === 0)
|
||||
return;
|
||||
const isTouchpad = WheelInput.isTouchpad(wheel);
|
||||
|
||||
if (CompositorService.isNiri && xBehavior !== "none" && Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
accumulateX(isTouchpad, deltaX, xBehavior);
|
||||
if (horizontalGesture(wheel, isTouchpad)) {
|
||||
if (xBehavior !== "none")
|
||||
accumulateX(isTouchpad, delta, xBehavior);
|
||||
return;
|
||||
}
|
||||
if (yBehavior === "none")
|
||||
return;
|
||||
accumulateY(isTouchpad, deltaY, yBehavior);
|
||||
accumulateY(isTouchpad, delta, yBehavior);
|
||||
}
|
||||
|
||||
onWheel: wheel => processWheel(wheel)
|
||||
|
||||
@@ -1162,7 +1162,7 @@ Item {
|
||||
propagateComposedEvents: true
|
||||
z: -1
|
||||
scrollEnabled: barWindow.barConfig?.scrollEnabled ?? true
|
||||
xBehavior: barWindow.barConfig?.scrollXBehavior ?? "column"
|
||||
xBehavior: barWindow.barConfig?.scrollXBehavior ?? "focusWindow"
|
||||
yBehavior: barWindow.barConfig?.scrollYBehavior ?? "workspace"
|
||||
screenName: barWindow.screenName
|
||||
barConfig: barWindow.barConfig
|
||||
|
||||
@@ -294,13 +294,12 @@ DCard {
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoverEnabled: true
|
||||
onWheel: wheel => {
|
||||
const horizontal = wheel.angleDelta.x !== 0 || wheel.pixelDelta.x !== 0 || (wheel.modifiers & Qt.ShiftModifier);
|
||||
if (!horizontal || !root.scrollable) {
|
||||
if (!WheelInput.isHorizontal(wheel) || !root.scrollable) {
|
||||
wheel.accepted = false;
|
||||
return;
|
||||
}
|
||||
const pixels = WheelInput.isTouchpad(wheel) ? wheel.pixelDelta.x || wheel.pixelDelta.y : 0;
|
||||
const steps = (wheel.angleDelta.x || wheel.angleDelta.y) / 120;
|
||||
const pixels = WheelInput.isTouchpad(wheel) ? WheelInput.dominantDelta(wheel.pixelDelta) : 0;
|
||||
const steps = WheelInput.dominantDelta(wheel.angleDelta) / 120;
|
||||
root.scrollTo(timeline.contentX - (pixels || steps * timeline.mouseWheelSpeed));
|
||||
wheel.accepted = true;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import qs.Modules.Plugins
|
||||
import qs.Services
|
||||
import qs.DCommon.Widgets
|
||||
import qs.Widgets
|
||||
import "../../../DCommon/Common/WheelInput.js" as WheelInput
|
||||
|
||||
BasePill {
|
||||
id: root
|
||||
@@ -230,7 +231,7 @@ BasePill {
|
||||
}
|
||||
|
||||
onWheel: wheel => {
|
||||
if (Math.abs(wheel.angleDelta.x) > Math.abs(wheel.angleDelta.y))
|
||||
if (WheelInput.isHorizontal(wheel))
|
||||
return;
|
||||
wheel.accepted = true;
|
||||
workspaces.handleWheel(wheel);
|
||||
|
||||
@@ -5,6 +5,7 @@ import qs.Common
|
||||
import qs.Services
|
||||
import qs.DCommon.Widgets
|
||||
import qs.Modules.DDash
|
||||
import "../../../DCommon/Common/WheelInput.js" as WheelInput
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@@ -60,12 +61,11 @@ Item {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: wheel => {
|
||||
const horizontal = wheel.angleDelta.x !== 0 || (wheel.modifiers & Qt.ShiftModifier);
|
||||
if (!horizontal || root.maxStart === 0) {
|
||||
if (!WheelInput.isHorizontal(wheel) || root.maxStart === 0) {
|
||||
wheel.accepted = false;
|
||||
return;
|
||||
}
|
||||
const delta = wheel.angleDelta.x || wheel.angleDelta.y;
|
||||
const delta = WheelInput.dominantDelta(wheel.angleDelta);
|
||||
const step = delta > 0 ? -1 : 1;
|
||||
const next = root.start + step;
|
||||
if (delta !== 0 && next >= 0 && next <= root.maxStart)
|
||||
|
||||
@@ -458,11 +458,12 @@ Item {
|
||||
}
|
||||
|
||||
SettingsToggleCard {
|
||||
id: scrollCard
|
||||
iconName: "mouse"
|
||||
settingKey: "barScrollWheel"
|
||||
resetStore: bar
|
||||
resetKeys: ["scrollEnabled"]
|
||||
tags: ["scroll", "wheel", "workspace", "column", "axis"]
|
||||
tags: ["scroll", "wheel", "workspace", "focus", "window", "axis"]
|
||||
title: I18n.tr("Scroll wheel")
|
||||
visible: (bar.selectedBarConfig?.enabled ?? false) && !bar.selectedBarIsIsland
|
||||
checked: bar.selectedBarConfig?.scrollEnabled ?? true
|
||||
@@ -470,43 +471,23 @@ Item {
|
||||
scrollEnabled: checked
|
||||
})
|
||||
|
||||
readonly property var behaviors: CompositorService.canStepWindowFocus ? ["none", "workspace", "focusWindow"] : ["none", "workspace"]
|
||||
readonly property var behaviorLabels: CompositorService.canStepWindowFocus ? [I18n.tr("None"), I18n.tr("Workspace"), I18n.tr("Focus window")] : [I18n.tr("None"), I18n.tr("Workspace")]
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Y axis")
|
||||
resetStore: bar
|
||||
resetKeys: ["scrollYBehavior"]
|
||||
model: CompositorService.isNiri ? [I18n.tr("None"), I18n.tr("Workspace"), I18n.tr("Column", "noun, bar scroll behavior option, niri window column")] : [I18n.tr("None"), I18n.tr("Workspace")]
|
||||
model: scrollCard.behaviorLabels
|
||||
buttonPadding: Theme.spacingS
|
||||
minButtonWidth: 44
|
||||
textSize: Theme.fontSizeSmall
|
||||
currentIndex: {
|
||||
switch (bar.selectedBarConfig?.scrollYBehavior || "workspace") {
|
||||
case "none":
|
||||
return 0;
|
||||
case "workspace":
|
||||
return 1;
|
||||
case "column":
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
currentIndex: Math.max(0, scrollCard.behaviors.indexOf(bar.selectedBarConfig?.scrollYBehavior || "workspace"))
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let behavior = "workspace";
|
||||
switch (index) {
|
||||
case 0:
|
||||
behavior = "none";
|
||||
break;
|
||||
case 1:
|
||||
behavior = "workspace";
|
||||
break;
|
||||
case 2:
|
||||
behavior = "column";
|
||||
break;
|
||||
}
|
||||
SettingsData.updateBarConfig(bar.selectedBarId, {
|
||||
scrollYBehavior: behavior
|
||||
scrollYBehavior: scrollCard.behaviors[index]
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -515,40 +496,16 @@ Item {
|
||||
text: I18n.tr("X axis")
|
||||
resetStore: bar
|
||||
resetKeys: ["scrollXBehavior"]
|
||||
visible: CompositorService.isNiri
|
||||
model: [I18n.tr("None"), I18n.tr("Workspace"), I18n.tr("Column")]
|
||||
model: scrollCard.behaviorLabels
|
||||
buttonPadding: Theme.spacingS
|
||||
minButtonWidth: 44
|
||||
textSize: Theme.fontSizeSmall
|
||||
currentIndex: {
|
||||
switch (bar.selectedBarConfig?.scrollXBehavior || "column") {
|
||||
case "none":
|
||||
return 0;
|
||||
case "workspace":
|
||||
return 1;
|
||||
case "column":
|
||||
return 2;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
currentIndex: Math.max(0, scrollCard.behaviors.indexOf(bar.selectedBarConfig?.scrollXBehavior || "focusWindow"))
|
||||
onSelectionChanged: (index, selected) => {
|
||||
if (!selected)
|
||||
return;
|
||||
let behavior = "column";
|
||||
switch (index) {
|
||||
case 0:
|
||||
behavior = "none";
|
||||
break;
|
||||
case 1:
|
||||
behavior = "workspace";
|
||||
break;
|
||||
case 2:
|
||||
behavior = "column";
|
||||
break;
|
||||
}
|
||||
SettingsData.updateBarConfig(bar.selectedBarId, {
|
||||
scrollXBehavior: behavior
|
||||
scrollXBehavior: scrollCard.behaviors[index]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,13 +208,13 @@ Scope {
|
||||
}
|
||||
|
||||
if (event.key === Qt.Key_Left) {
|
||||
NiriService.moveColumnLeft();
|
||||
NiriService.focusColumnLeft();
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key === Qt.Key_Right) {
|
||||
NiriService.moveColumnRight();
|
||||
NiriService.focusColumnRight();
|
||||
event.accepted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2126,6 +2126,35 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
readonly property bool canStepWindowFocus: compositor === "niri" || compositor === "hyprland" || compositor === "mango"
|
||||
|
||||
function stepWindowFocus(screenName, direction) {
|
||||
switch (compositor) {
|
||||
case "niri":
|
||||
if (direction > 0)
|
||||
NiriService.focusColumnRight(screenName);
|
||||
else
|
||||
NiriService.focusColumnLeft(screenName);
|
||||
return true;
|
||||
case "hyprland":
|
||||
if (screenName && screenName !== Hyprland.focusedMonitor?.name)
|
||||
HyprlandService.focusMonitor(screenName);
|
||||
HyprlandService.cycleWindow(direction > 0);
|
||||
return true;
|
||||
case "mango":
|
||||
{
|
||||
const command = direction > 0 ? "focusstack,next" : "focusstack,prev";
|
||||
if (screenName)
|
||||
MangoService.dispatchOnOutput(screenName, command);
|
||||
else
|
||||
MangoService.dispatch(command);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function focusWindow(windowId) {
|
||||
switch (compositor) {
|
||||
case "aqueous":
|
||||
|
||||
@@ -10,7 +10,7 @@ import "../Common/ConfigIncludeResolve.js" as ConfigIncludeResolve
|
||||
import qs.Services
|
||||
import "../Common/OutputModel.js" as OutputModel
|
||||
import "../Common/BlurStrength.js" as BlurStrength
|
||||
import "../Common/WorkspaceModel.js" as WorkspaceModel
|
||||
import "../Common/WorkspaceModel.js" as WorkspaceModel // qmllint disable unused-imports
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
@@ -549,6 +549,7 @@ hl.config({
|
||||
${sections.join("\n")}
|
||||
})
|
||||
`;
|
||||
|
||||
if (layoutXrayEnabled) {
|
||||
content += `
|
||||
hl.layer_rule({
|
||||
@@ -969,6 +970,14 @@ hl.layer_rule({
|
||||
Hyprland.dispatch(`hl.dsp.window.move({ workspace = ${luaValue(workspace)}, window = ${luaString(selector)}, follow = ${follow ? "true" : "false"} })`);
|
||||
}
|
||||
|
||||
function cycleWindow(forward) {
|
||||
if (!luaConfigActive) {
|
||||
Hyprland.dispatch(forward ? "cyclenext" : "cyclenext prev");
|
||||
return;
|
||||
}
|
||||
Hyprland.dispatch(`hl.dsp.window.cycle_next({ next = ${forward ? "true" : "false"} })`);
|
||||
}
|
||||
|
||||
function focusMonitor(monitor) {
|
||||
if (!luaConfigActive) {
|
||||
Hyprland.dispatch(`focusmonitor ${monitor}`);
|
||||
|
||||
@@ -836,7 +836,7 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function moveColumnLeft(outputName) {
|
||||
function focusColumnLeft(outputName) {
|
||||
if (outputName && outputName !== currentOutput)
|
||||
focusMonitor(outputName);
|
||||
return send({
|
||||
@@ -846,7 +846,7 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function moveColumnRight(outputName) {
|
||||
function focusColumnRight(outputName) {
|
||||
if (outputName && outputName !== currentOutput)
|
||||
focusMonitor(outputName);
|
||||
return send({
|
||||
|
||||
@@ -4161,7 +4161,7 @@
|
||||
"keywords": [
|
||||
"axis",
|
||||
"bar",
|
||||
"column",
|
||||
"focus",
|
||||
"general",
|
||||
"panel",
|
||||
"scroll",
|
||||
@@ -4169,6 +4169,7 @@
|
||||
"taskbar",
|
||||
"topbar",
|
||||
"wheel",
|
||||
"window",
|
||||
"workspace"
|
||||
],
|
||||
"parentLabel": "Bar",
|
||||
|
||||
Reference in New Issue
Block a user