mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-21 10:44:01 -04:00
feat(screenshot): add flag to control HUD scale and visibility (#3398)
* feat(screenshot): add --hud flag to control HUD scale and visibility * fix(screenshot): clamp HUD scale to 1-4 and clarify flag description
This commit is contained in:
@@ -35,6 +35,7 @@ var (
|
||||
ssJSON bool
|
||||
ssGeometry bool
|
||||
ssAllowMulti bool
|
||||
ssHUD string
|
||||
)
|
||||
|
||||
type screenshotMetadata struct {
|
||||
@@ -181,6 +182,7 @@ func init() {
|
||||
screenshotCmd.PersistentFlags().BoolVar(&ssJSON, "json", false, "Print capture metadata as JSON")
|
||||
screenshotCmd.PersistentFlags().BoolVarP(&ssGeometry, "geometry", "g", false, "Print selected region geometry (X,Y WxH) to stdout without capturing an image")
|
||||
screenshotCmd.PersistentFlags().BoolVar(&ssAllowMulti, "allow-multiple", false, "Open a selector even when another one is already open")
|
||||
screenshotCmd.PersistentFlags().StringVar(&ssHUD, "hud", "auto", "HUD overlay scale in region selector (auto, off/0, or integer scale 1-4)")
|
||||
|
||||
ssScrollCmd.Flags().IntVar(&ssScrollInterval, "interval", 45, "Capture interval in milliseconds (30-1000)")
|
||||
|
||||
@@ -212,6 +214,7 @@ func getScreenshotConfig(mode screenshot.Mode) screenshot.Config {
|
||||
config.Stdout = ssStdout
|
||||
config.Geometry = ssGeometry
|
||||
config.AllowMultiple = ssAllowMulti
|
||||
config.HUD = ssHUD
|
||||
|
||||
if ssGeometry {
|
||||
config.Clipboard = false
|
||||
|
||||
@@ -973,11 +973,12 @@ func (r *RegionSelector) renderSurface(os *OutputSurface) {
|
||||
case !slot.cacheValid(srcBuf, r.selection.dragging, r.showCapturedCursor, r.phase, handles, shift):
|
||||
slot.shm.CopyFrom(srcBuf)
|
||||
r.dimBackground(slot.shm)
|
||||
scale := 1
|
||||
effectiveScale := 1.0
|
||||
if os.output != nil {
|
||||
scale = scaleFactor(os.output.effectiveScale())
|
||||
effectiveScale = os.output.effectiveScale()
|
||||
}
|
||||
r.drawHUD(slot.shm.Data(), slot.shm.Stride, slot.shm.Width, slot.shm.Height, os.screenFormat, scale)
|
||||
hudScale := r.hudScale(effectiveScale)
|
||||
r.drawHUD(slot.shm.Data(), slot.shm.Stride, slot.shm.Width, slot.shm.Height, os.screenFormat, hudScale)
|
||||
slot.backgroundInitialized = true
|
||||
slot.backgroundSource = srcBuf
|
||||
slot.backgroundDragging = r.selection.dragging
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -630,6 +632,32 @@ func (r *RegionSelector) drawScrollBar(data []byte, stride, bufW, bufH int, form
|
||||
style.TextR, style.TextG, style.TextB, format)
|
||||
}
|
||||
|
||||
const (
|
||||
minHUDScale = 1
|
||||
maxHUDScale = 4
|
||||
)
|
||||
|
||||
func (r *RegionSelector) hudScale(effectiveScale float64) int {
|
||||
hudOpt := "auto"
|
||||
if r.screenshoter != nil && r.screenshoter.config.HUD != "" {
|
||||
hudOpt = strings.ToLower(strings.TrimSpace(r.screenshoter.config.HUD))
|
||||
}
|
||||
switch hudOpt {
|
||||
case "off", "none", "false", "0":
|
||||
return 0
|
||||
case "", "auto":
|
||||
return min(scaleFactor(effectiveScale), maxHUDScale)
|
||||
default:
|
||||
if val, err := strconv.ParseFloat(hudOpt, 64); err == nil {
|
||||
if val <= 0 {
|
||||
return 0
|
||||
}
|
||||
return min(max(scaleFactor(val), minHUDScale), maxHUDScale)
|
||||
}
|
||||
return min(scaleFactor(effectiveScale), maxHUDScale)
|
||||
}
|
||||
}
|
||||
|
||||
type hudItem struct {
|
||||
key, desc string
|
||||
}
|
||||
@@ -657,6 +685,9 @@ func (r *RegionSelector) hudItems() []hudItem {
|
||||
}
|
||||
|
||||
func (r *RegionSelector) hudDimensions(bufW, bufH, scale int) (hudX, hudY, hudW, hudH int) {
|
||||
if scale <= 0 {
|
||||
return 0, 0, 0, 0
|
||||
}
|
||||
scale = scaleFactor(float64(scale))
|
||||
charH := fontCharH * scale
|
||||
padding, itemSpacing := 12*scale, 24*scale
|
||||
@@ -680,7 +711,7 @@ func (r *RegionSelector) hudDimensions(bufW, bufH, scale int) (hudX, hudY, hudW,
|
||||
}
|
||||
|
||||
func (r *RegionSelector) drawHUD(data []byte, stride, bufW, bufH int, format uint32, scale int) {
|
||||
if r.selection.dragging {
|
||||
if r.selection.dragging || scale <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +238,12 @@ func TestHUDDimensionsContainText(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
// When scale <= 0, hudDimensions should return zero
|
||||
hx, hy, hw, hh := r.hudDimensions(bufW, bufH, 0)
|
||||
if hx != 0 || hy != 0 || hw != 0 || hh != 0 {
|
||||
t.Fatalf("expected 0 dimensions for scale 0, got %d, %d, %d, %d", hx, hy, hw, hh)
|
||||
}
|
||||
|
||||
for _, scale := range []int{1, 2} {
|
||||
hudX, hudY, hudW, hudH := r.hudDimensions(bufW, bufH, scale)
|
||||
data := make([]byte, bufH*stride)
|
||||
@@ -260,6 +266,47 @@ func TestHUDDimensionsContainText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHUDScale(t *testing.T) {
|
||||
tests := []struct {
|
||||
hudOpt string
|
||||
effectiveScale float64
|
||||
expectedScale int
|
||||
}{
|
||||
{"auto", 1.0, 1},
|
||||
{"auto", 1.8, 2},
|
||||
{"auto", 2.4, 2},
|
||||
{"", 1.0, 1},
|
||||
{"", 2.0, 2},
|
||||
{"off", 1.0, 0},
|
||||
{"OFF", 2.0, 0},
|
||||
{"none", 1.5, 0},
|
||||
{"false", 1.0, 0},
|
||||
{"0", 2.0, 0},
|
||||
{"0.0", 1.0, 0},
|
||||
{"-1", 1.0, 0},
|
||||
{"1", 1.0, 1},
|
||||
{"1.5", 1.0, 2},
|
||||
{"2", 1.0, 2},
|
||||
{"3", 1.0, 3},
|
||||
{"4", 1.0, 4},
|
||||
{"1000", 1.0, 4},
|
||||
{"0.2", 1.0, 1},
|
||||
{"invalid", 1.7, 2},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
r := &RegionSelector{
|
||||
screenshoter: &Screenshoter{
|
||||
config: Config{HUD: tc.hudOpt},
|
||||
},
|
||||
}
|
||||
got := r.hudScale(tc.effectiveScale)
|
||||
if got != tc.expectedScale {
|
||||
t.Errorf("hudScale(%q, %v) = %d, expected %d", tc.hudOpt, tc.effectiveScale, got, tc.expectedScale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlayDeltaHandlesClampedMonitorEdge(t *testing.T) {
|
||||
prev := &overlay{
|
||||
interior: dirtyRect{100, 100, 1920, 1080},
|
||||
|
||||
@@ -73,6 +73,7 @@ type Config struct {
|
||||
Geometry bool
|
||||
AllowMultiple bool
|
||||
IntervalMs int
|
||||
HUD string
|
||||
// SelectorHook runs as the interactive selector starts (true) and ends (false).
|
||||
SelectorHook func(begin bool)
|
||||
}
|
||||
@@ -90,5 +91,6 @@ func DefaultConfig() Config {
|
||||
Clipboard: true,
|
||||
SaveFile: true,
|
||||
Notify: true,
|
||||
HUD: "auto",
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user