forked from Shinonome/dots-hyprland
add anti flashbang
could be improve with smooth fading
This commit is contained in:
@@ -303,6 +303,9 @@ Singleton {
|
|||||||
property string to: "06:30" // Format: "HH:mm", 24-hour time
|
property string to: "06:30" // Format: "HH:mm", 24-hour time
|
||||||
property int colorTemperature: 5000
|
property int colorTemperature: 5000
|
||||||
}
|
}
|
||||||
|
property JsonObject antiFlashbang: JsonObject {
|
||||||
|
property bool enable: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject lock: JsonObject {
|
property JsonObject lock: JsonObject {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Rectangle {
|
|||||||
property real targetY: root.height / 2 - root.backgroundHeight / 2
|
property real targetY: root.height / 2 - root.backgroundHeight / 2
|
||||||
y: root.show ? targetY : (targetY - root.backgroundAnimationMovementDistance)
|
y: root.show ? targetY : (targetY - root.backgroundAnimationMovementDistance)
|
||||||
implicitWidth: 350
|
implicitWidth: 350
|
||||||
implicitHeight: 0
|
implicitHeight: contentColumn.implicitHeight + dialogBackground.radius * 2
|
||||||
Behavior on implicitHeight {
|
Behavior on implicitHeight {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
id: dialogBackgroundHeightAnimation
|
id: dialogBackgroundHeightAnimation
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ WindowDialog {
|
|||||||
id: nightLightColumn
|
id: nightLightColumn
|
||||||
Layout.topMargin: -16
|
Layout.topMargin: -16
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
ConfigSwitch {
|
ConfigSwitch {
|
||||||
anchors {
|
anchors {
|
||||||
@@ -81,6 +80,39 @@ WindowDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowDialogSectionHeader {
|
||||||
|
text: Translation.tr("Anti-flashbang (experimental)")
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowDialogSeparator {
|
||||||
|
Layout.topMargin: -22
|
||||||
|
Layout.leftMargin: 0
|
||||||
|
Layout.rightMargin: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: antiFlashbangColumn
|
||||||
|
Layout.topMargin: -16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ConfigSwitch {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
iconSize: Appearance.font.pixelSize.larger
|
||||||
|
buttonIcon: "destruction"
|
||||||
|
text: Translation.tr("Enable")
|
||||||
|
checked: Config.options.light.antiFlashbang.enable
|
||||||
|
onCheckedChanged: {
|
||||||
|
Config.options.light.antiFlashbang.enable = checked;
|
||||||
|
}
|
||||||
|
StyledToolTip {
|
||||||
|
text: Translation.tr("Example use case: eroge on one workspace, dark Discord window on another")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WindowDialogSectionHeader {
|
WindowDialogSectionHeader {
|
||||||
text: Translation.tr("Brightness")
|
text: Translation.tr("Brightness")
|
||||||
}
|
}
|
||||||
@@ -95,7 +127,7 @@ WindowDialog {
|
|||||||
id: brightnessColumn
|
id: brightnessColumn
|
||||||
Layout.topMargin: -16
|
Layout.topMargin: -16
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
// Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
WindowDialogSlider {
|
WindowDialogSlider {
|
||||||
anchors {
|
anchors {
|
||||||
|
|||||||
@@ -79,10 +79,7 @@ AbstractQuickPanel {
|
|||||||
delegate: ButtonGroup {
|
delegate: ButtonGroup {
|
||||||
id: toggleRow
|
id: toggleRow
|
||||||
required property int index
|
required property int index
|
||||||
property var modelData: {
|
property var modelData: root.toggleRows[index]
|
||||||
print(JSON.stringify(root.toggleRows[index]))
|
|
||||||
return root.toggleRows[index]
|
|
||||||
}
|
|
||||||
property int startingIndex: {
|
property int startingIndex: {
|
||||||
const rows = root.toggleRows;
|
const rows = root.toggleRows;
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ pragma ComponentBehavior: Bound
|
|||||||
// From https://github.com/caelestia-dots/shell with modifications.
|
// From https://github.com/caelestia-dots/shell with modifications.
|
||||||
// License: GPLv3
|
// License: GPLv3
|
||||||
|
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.functions
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
@@ -85,6 +87,8 @@ Singleton {
|
|||||||
}
|
}
|
||||||
property int rawMaxBrightness: 100
|
property int rawMaxBrightness: 100
|
||||||
property real brightness
|
property real brightness
|
||||||
|
property real brightnessMultiplier: 1.0
|
||||||
|
property real multipliedBrightness: Math.max(0, Math.min(1, brightness * brightnessMultiplier))
|
||||||
property bool ready: false
|
property bool ready: false
|
||||||
|
|
||||||
onBrightnessChanged: {
|
onBrightnessChanged: {
|
||||||
@@ -120,7 +124,8 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function syncBrightness() {
|
function syncBrightness() {
|
||||||
const rounded = Math.round(monitor.brightness * monitor.rawMaxBrightness);
|
const brightnessValue = monitor.multipliedBrightness
|
||||||
|
const rounded = Math.round(brightnessValue * monitor.rawMaxBrightness);
|
||||||
setProc.command = isDdc ? ["ddcutil", "-b", busNum, "setvcp", "10", rounded] : ["brightnessctl", "--class", "backlight", "s", rounded, "--quiet"];
|
setProc.command = isDdc ? ["ddcutil", "-b", busNum, "setvcp", "10", rounded] : ["brightnessctl", "--class", "backlight", "s", rounded, "--quiet"];
|
||||||
setProc.startDetached();
|
setProc.startDetached();
|
||||||
}
|
}
|
||||||
@@ -131,6 +136,11 @@ Singleton {
|
|||||||
setTimer.restart();
|
setTimer.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setBrightnessMultiplier(value: real): void {
|
||||||
|
monitor.brightnessMultiplier = value;
|
||||||
|
setTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
@@ -146,6 +156,61 @@ Singleton {
|
|||||||
BrightnessMonitor {}
|
BrightnessMonitor {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Anti-flashbang
|
||||||
|
property string screenshotDir: "/tmp/quickshell/brightness/antiflashbang"
|
||||||
|
function brightnessMultiplierForLightness(x: real): real {
|
||||||
|
// 6.600135 + 216.360356 * e^(-0.0811129189x)
|
||||||
|
// Division by 100 is to normalize to [0, 1]
|
||||||
|
return (6.600135 + 216.360356 * Math.pow(Math.E, -0.0811129189 * x)) / 100.0;
|
||||||
|
}
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
Scope {
|
||||||
|
id: screenScope
|
||||||
|
required property var modelData
|
||||||
|
property string screenName: modelData.name
|
||||||
|
property string screenshotPath: `${root.screenshotDir}/screenshot-${screenName}.png`
|
||||||
|
Connections {
|
||||||
|
enabled: Config.options.light.antiFlashbang.enable
|
||||||
|
target: Hyprland
|
||||||
|
function onRawEvent(event) {
|
||||||
|
if (["workspacev2"].includes(event.name)) {
|
||||||
|
screenshotTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: screenshotTimer
|
||||||
|
interval: 700 // This is what I have for a Hyprland ws anim
|
||||||
|
onTriggered: {
|
||||||
|
screenshotProc.running = false;
|
||||||
|
screenshotProc.running = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: screenshotProc
|
||||||
|
command: ["bash", "-c",
|
||||||
|
`mkdir -p '${StringUtils.shellSingleQuoteEscape(root.screenshotDir)}'`
|
||||||
|
+ ` && grim -o '${StringUtils.shellSingleQuoteEscape(screenScope.screenName)}' '${StringUtils.shellSingleQuoteEscape(screenScope.screenshotPath)}'`
|
||||||
|
+ ` && magick '${StringUtils.shellSingleQuoteEscape(screenScope.screenshotPath)}' -colorspace Gray -format "%[fx:mean*100]" info:`
|
||||||
|
]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: lightnessCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
const lightness = lightnessCollector.text
|
||||||
|
const newMultiplier = root.brightnessMultiplierForLightness(parseFloat(lightness))
|
||||||
|
print(lightness, "->", newMultiplier)
|
||||||
|
Brightness.getMonitorForScreen(screenScope.modelData).setBrightnessMultiplier(newMultiplier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// External trigger points
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
target: "brightness"
|
target: "brightness"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user