Feature (Overlay): MangoHud Fps Limiter widget

This commit is contained in:
reakjra
2025-11-06 14:23:13 +01:00
parent ad9f25c346
commit 60144ca3de
7 changed files with 123 additions and 1 deletions
@@ -93,6 +93,12 @@ Singleton {
property real x: 55
property real y: 188
}
property JsonObject fpsLimiter: JsonObject {
property bool pinned: false
property bool clickthrough: false
property real x: 100
property real y: 100
}
}
property JsonObject timer: JsonObject {
@@ -25,7 +25,7 @@ Scope {
exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "quickshell:overlay"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
WlrLayershell.keyboardFocus: GlobalStates.overlayOpen ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
visible: true
color: "transparent"
@@ -43,6 +43,16 @@ Scope {
right: true
}
HyprlandFocusGrab {
id: grab
windows: [overlayWindow]
active: GlobalStates.overlayOpen
onCleared: () => {
if (!active)
GlobalStates.overlayOpen = false;
}
}
OverlayContent {
id: overlayContent
anchors.fill: parent
@@ -12,6 +12,7 @@ import qs.modules.overlay.crosshair
Item {
id: root
focus: true
readonly property bool usePasswordChars: !PolkitService.flow?.responseVisible ?? true
Keys.onPressed: (event) => { // Esc to close
@@ -7,6 +7,7 @@ Singleton {
readonly property list<var> availableWidgets: [
{ identifier: "crosshair", materialSymbol: "point_scan" },
{ identifier: "fpsLimiter", materialSymbol: "speed" },
{ identifier: "volumeMixer", materialSymbol: "volume_up" }
]
@@ -8,6 +8,7 @@ import Quickshell
import Quickshell.Bluetooth
import qs.modules.overlay.crosshair
import qs.modules.overlay.volumeMixer
import qs.modules.overlay.fpsLimiter
DelegateChooser {
id: root
@@ -15,4 +16,5 @@ DelegateChooser {
DelegateChoice { roleValue: "crosshair"; Crosshair {} }
DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} }
DelegateChoice { roleValue: "fpsLimiter"; FpsLimiter {} }
}
@@ -0,0 +1,10 @@
import QtQuick
import Quickshell
import qs.modules.common
import qs.modules.overlay
StyledOverlayWidget {
id: root
title: "FPS Limiter"
contentItem: FpsLimiterContent {}
}
@@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import qs.modules.common
import qs.modules.common.widgets
Rectangle {
id: root
color: Appearance.m3colors.m3surfaceContainer
property real padding: 20
implicitWidth: contentColumn.implicitWidth + padding * 2
implicitHeight: contentColumn.implicitHeight + padding * 2
function applyLimit() {
var fpsValue = parseInt(fpsField.text);
if (isNaN(fpsValue) || fpsValue < 0) {
return;
}
var cfgPaths = [
"~/.config/MangoHud/MangoHud.conf",
]; // MangoHud config files
var updateCommands = cfgPaths.map(path => {
return "if grep -q '^fps_limit=' " + path + "; " +
"then sed -i 's/^fps_limit=.*/fps_limit=" + fpsValue + "/' " + path + "; " +
"else echo 'fps_limit=" + fpsValue + "' >> " + path + "; fi";
}).join("; ");
var cmd = updateCommands + "; pkill -SIGUSR2 mangohud";
fpsSetter.command = ["bash", "-c", cmd];
fpsSetter.startDetached();
// Clear the field after applying
fpsField.text = "";
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Escape) {
fpsField.text = "";
event.accepted = true;
}
}
ColumnLayout {
id: contentColumn
anchors.centerIn: parent
spacing: 15
RowLayout {
Layout.fillWidth: true
spacing: 10
ToolbarTextField {
id: fpsField
Layout.fillWidth: true
Layout.preferredWidth: 200
placeholderText: qsTr("Set FPS limit (e.g. 80)")
inputMethodHints: Qt.ImhDigitsOnly
focus: true
Keys.onReturnPressed: {
root.applyLimit();
event.accepted = true;
}
}
RippleButton {
id: applyButton
implicitWidth: 36
implicitHeight: 36
buttonRadius: Appearance.rounding.full
onClicked: {
root.applyLimit();
}
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
font.pixelSize: Appearance.font.pixelSize.title
text: "keyboard_return"
}
}
}
Process {
id: fpsSetter
}
}
}