diff --git a/core/internal/colorpicker/picker.go b/core/internal/colorpicker/picker.go index 7216a895..f2cdfda5 100644 --- a/core/internal/colorpicker/picker.go +++ b/core/internal/colorpicker/picker.go @@ -41,6 +41,7 @@ type LayerSurface struct { wlPool *client.ShmPool wlBuffer *client.Buffer configured bool + hidden bool } type Picker struct { @@ -503,7 +504,13 @@ func (p *Picker) captureForSurface(ls *LayerSurface) { } func (p *Picker) redrawSurface(ls *LayerSurface) { - renderBuf := ls.state.Redraw() + var renderBuf *ShmBuffer + if ls.hidden { + // When hidden, just show the screenshot without overlay + renderBuf = ls.state.RedrawScreenOnly() + } else { + renderBuf = ls.state.Redraw() + } if renderBuf == nil { return } @@ -571,6 +578,15 @@ func (p *Picker) redrawSurface(ls *LayerSurface) { ls.state.SwapBuffers() } +func (p *Picker) hideSurface(ls *LayerSurface) { + if ls == nil || ls.wlSurface == nil || ls.hidden { + return + } + ls.hidden = true + // Redraw without the crosshair overlay + p.redrawSurface(ls) +} + func (p *Picker) setupInput() { if p.seat == nil { return @@ -610,13 +626,22 @@ func (p *Picker) setupPointerHandlers() { if p.activeSurface == nil { return } + + // If surface was hidden, mark it as visible again + if p.activeSurface.hidden { + p.activeSurface.hidden = false + } + p.activeSurface.state.OnPointerMotion(e.SurfaceX, e.SurfaceY) p.redrawSurface(p.activeSurface) }) p.pointer.SetLeaveHandler(func(e client.PointerLeaveEvent) { - if p.activeSurface != nil && p.activeSurface.wlSurface.ID() == e.Surface.ID() { - p.activeSurface = nil + for _, ls := range p.surfaces { + if ls.wlSurface.ID() == e.Surface.ID() { + p.hideSurface(ls) + break + } } }) diff --git a/core/internal/colorpicker/state.go b/core/internal/colorpicker/state.go index fce7755d..90d4750c 100644 --- a/core/internal/colorpicker/state.go +++ b/core/internal/colorpicker/state.go @@ -274,6 +274,25 @@ func (s *SurfaceState) Redraw() *ShmBuffer { return dst } +// RedrawScreenOnly renders just the screenshot without any overlay (magnifier, preview). +// Used for when pointer leaves the surface. +func (s *SurfaceState) RedrawScreenOnly() *ShmBuffer { + s.mu.Lock() + defer s.mu.Unlock() + + if !s.readyForDisplay || s.screenBuf == nil { + return nil + } + + dst := s.renderBufs[s.front] + if dst == nil { + return nil + } + + copy(dst.data, s.screenBuf.data) + return dst +} + func (s *SurfaceState) PickColor() (Color, bool) { s.mu.Lock() defer s.mu.Unlock()