mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
Feature (Overlay): MangoHud Fps Limiter widget (#2388)
This commit is contained in:
@@ -107,6 +107,12 @@ Singleton {
|
||||
property real y: 280
|
||||
property int tabIndex: 0
|
||||
}
|
||||
property JsonObject fpsLimiter: JsonObject {
|
||||
property bool pinned: false
|
||||
property bool clickthrough: false
|
||||
property real x: 1576
|
||||
property real y: 630
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject timer: JsonObject {
|
||||
|
||||
@@ -18,5 +18,6 @@ ToolbarButton {
|
||||
iconSize: 22
|
||||
text: iconBtn.text
|
||||
color: iconBtn.colText
|
||||
animateChange: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,30 @@ Scope {
|
||||
right: true
|
||||
}
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: grab
|
||||
windows: [overlayWindow]
|
||||
active: false
|
||||
onCleared: () => {
|
||||
if (!active) GlobalStates.overlayOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onOverlayOpenChanged() {
|
||||
delayedGrabTimer.restart();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: delayedGrabTimer
|
||||
interval: Appearance.animation.elementMoveFast.duration
|
||||
onTriggered: {
|
||||
grab.active = GlobalStates.overlayOpen;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -9,6 +9,7 @@ Singleton {
|
||||
{ identifier: "recorder", materialSymbol: "screen_record" },
|
||||
{ identifier: "volumeMixer", materialSymbol: "volume_up" },
|
||||
{ identifier: "crosshair", materialSymbol: "point_scan" },
|
||||
{ identifier: "fpsLimiter", materialSymbol: "animation" },
|
||||
{ identifier: "resources", materialSymbol: "browse_activity" }
|
||||
]
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import qs.modules.overlay.crosshair
|
||||
import qs.modules.overlay.volumeMixer
|
||||
import qs.modules.overlay.fpsLimiter
|
||||
import qs.modules.overlay.recorder
|
||||
import qs.modules.overlay.resources
|
||||
|
||||
@@ -17,6 +18,7 @@ DelegateChooser {
|
||||
|
||||
DelegateChoice { roleValue: "crosshair"; Crosshair {} }
|
||||
DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} }
|
||||
DelegateChoice { roleValue: "fpsLimiter"; FpsLimiter {} }
|
||||
DelegateChoice { roleValue: "recorder"; Recorder {} }
|
||||
DelegateChoice { roleValue: "resources"; Resources {} }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
import qs.modules.overlay
|
||||
|
||||
StyledOverlayWidget {
|
||||
id: root
|
||||
title: "MangoHud FPS"
|
||||
contentItem: FpsLimiterContent {
|
||||
radius: root.contentRadius
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import qs.services
|
||||
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
|
||||
|
||||
enum State { Normal, Success, Error }
|
||||
|
||||
anchors.fill: parent
|
||||
property real padding: 16
|
||||
property var currentState: FpsLimiterContent.State.Normal
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
implicitWidth: content.implicitWidth + (padding * 2)
|
||||
implicitHeight: content.implicitHeight + (padding * 2)
|
||||
|
||||
Timer {
|
||||
id: iconResetTimer
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
root.currentState = FpsLimiterContent.State.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
function applyLimit() {
|
||||
var fpsValue = parseInt(fpsField.text);
|
||||
if (isNaN(fpsValue) || fpsValue < 0) {
|
||||
root.currentState = FpsLimiterContent.State.Error;
|
||||
iconResetTimer.restart();
|
||||
fpsField.text = "";
|
||||
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();
|
||||
|
||||
root.currentState = FpsLimiterContent.State.Success;
|
||||
iconResetTimer.restart();
|
||||
|
||||
// Clear the field after applying
|
||||
fpsField.text = "";
|
||||
}
|
||||
|
||||
Process {
|
||||
id: fpsSetter
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
anchors.centerIn: parent
|
||||
spacing: 4
|
||||
|
||||
ToolbarTextField {
|
||||
id: fpsField
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 200
|
||||
placeholderText: root.currentState === FpsLimiterContent.State.Error ? Translation.tr("Enter a valid number") : Translation.tr("Set FPS limit")
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
focus: true
|
||||
|
||||
onAccepted: {
|
||||
root.applyLimit();
|
||||
}
|
||||
}
|
||||
|
||||
IconToolbarButton {
|
||||
id: applyButton
|
||||
text: switch (root.currentState) {
|
||||
case FpsLimiterContent.State.Error: return "close";
|
||||
case FpsLimiterContent.State.Success: return "check";
|
||||
case FpsLimiterContent.State.Normal:
|
||||
default: return "save";
|
||||
}
|
||||
enabled: root.currentState === FpsLimiterContent.State.Normal && fpsField.text.length > 0
|
||||
onClicked: {
|
||||
root.applyLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user