1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-08 22:48:28 -04:00

screenshot: initial support for scroll capture mode

fixes #2871
port 1.5

(cherry picked from commit f8fe16738e)
This commit is contained in:
bbedward
2026-07-17 13:31:23 -04:00
committed by dms-ci[bot]
parent 63ffd7caec
commit 4ff93bf46e
13 changed files with 1866 additions and 72 deletions
+27 -8
View File
@@ -95,6 +95,9 @@ type RegionSelector struct {
showCapturedCursor bool
shiftHeld bool
phase selectorPhase
scroll *scrollSession
running bool
cancelled bool
result Region
@@ -167,11 +170,15 @@ func (r *RegionSelector) Run() (*CaptureResult, bool, error) {
r.running = true
for r.running {
if err := r.ctx.Dispatch(); err != nil {
if err := r.dispatchOrTick(); err != nil {
return nil, false, fmt.Errorf("dispatch: %w", err)
}
}
if r.scroll != nil && r.scroll.abortErr != nil {
return nil, false, r.scroll.abortErr
}
if r.cancelled || r.capturedBuffer == nil {
return nil, r.cancelled, nil
}
@@ -186,6 +193,10 @@ func (r *RegionSelector) Run() (*CaptureResult, bool, error) {
scale = s
}
}
if r.scroll != nil {
yInverted = false
format = uint32(r.scroll.format)
}
return &CaptureResult{
Buffer: r.capturedBuffer,
@@ -696,7 +707,9 @@ func (r *RegionSelector) initRenderBuffer(os *OutputSurface) {
}
slot.pool = pool
wlBuf, err := pool.CreateBuffer(0, int32(buf.Width), int32(buf.Height), int32(buf.Stride), os.screenFormat)
// niri latches surface opacity from the first buffer's format
// (observed), so slots are ARGB from the start with A=255 when opaque
wlBuf, err := pool.CreateBuffer(0, int32(buf.Width), int32(buf.Height), int32(buf.Stride), alphaFormat(os.screenFormat))
if err != nil {
log.Error("create render slot wl_buffer failed", "err", err)
pool.Destroy()
@@ -738,8 +751,9 @@ func (r *RegionSelector) applyPreSelection(os *OutputSurface) {
x1 := float64(r.preSelect.X-os.output.x) * scaleX
y1 := float64(r.preSelect.Y-os.output.y) * scaleY
x2 := float64(r.preSelect.X-os.output.x+r.preSelect.Width) * scaleX
y2 := float64(r.preSelect.Y-os.output.y+r.preSelect.Height) * scaleY
// selection edges are inclusive; the exclusive width edge is one device px past it
x2 := float64(r.preSelect.X-os.output.x+r.preSelect.Width)*scaleX - scaleX
y2 := float64(r.preSelect.Y-os.output.y+r.preSelect.Height)*scaleY - scaleY
r.selection.hasSelection = true
r.selection.dragging = false
@@ -769,10 +783,13 @@ func (r *RegionSelector) redrawSurface(os *OutputSurface) {
return
}
slot.shm.CopyFrom(srcBuf)
// Draw overlay (dimming + selection) into this slot
r.drawOverlay(os, slot.shm)
switch r.phase {
case phaseScroll:
r.drawScrollOverlay(os, slot.shm)
default:
slot.shm.CopyFrom(srcBuf)
r.drawOverlay(os, slot.shm)
}
if os.viewport != nil {
_ = os.wlSurface.SetBufferScale(1)
@@ -808,6 +825,8 @@ func (r *RegionSelector) cleanup() {
r.cursorBuffer.Close()
}
r.cleanupScroll()
for _, os := range r.surfaces {
for _, slot := range os.slots {
if slot == nil {