Commits

Commits on April 28, 2026

  1. Drop CanJoinAllSpaces; log focus and hide/unhide calls
    Overlays were leaking onto every macOS space simultaneously due to
    CanJoinAllSpaces, which presents as 'border stuck on the previous
    workspace' when the user navigates between tarmac workspaces. Removing
    that flag confines each overlay to the space where it was created.
    
    Add diagnostic logging in update_focus / hide / unhide so a workspace-
    switch trace can be read with RUST_LOG=ers=debug.
    mfwolffe committed
  2. Fix border thickness; orderOut before close in Drop
    CAShapeLayer strokes are centered on the path, so to render a visible
    border_width-thick ring inside the layer bounds we want
    line_width = border_width and path inset = border_width/2 (not the
    doubled values I had — those produced 2x-thick borders user reported).
    mfwolffe committed
  3. Replace SLS overlays with NSWindow + sharingType=.none
    BorderMap now stores nswindow_overlay::OverlayWindow per target. The
    event-processing loop moves from a background thread to a CFRunLoopTimer
    on the main thread, since AppKit calls (NSWindow, CALayer) must originate
    from the main thread.
    
    Verified empirically: screencapture -l <ers_wid> returns 'could not
    create image from window' for all 5 overlays — Tahoe's screencaptureui
    honors NSWindow.sharingType where it ignores SLS sharing-state for
    SLS-only windows. Full-screen screencapture cleanly captures app
    contents without the borders blocking them.
    mfwolffe committed
  4. mfwolffe committed
  5. Research: SLS-side screenshot exclusion attempts on Tahoe
    Empirically disproved approaches for excluding ers overlays from
    Tahoe's cmd+shift+4 + space picker. All of these apply *correctly*
    to the overlay window — they just don't influence the picker.
    
    Verified via post-create probes:
    - SLSNewWindowWithOpaqueShapeAndContext baking tag bits (1<<1)|(1<<9)
      at creation succeeds; readback shows tags=0x202.
    - SLSSetWindowSharingState(0) succeeds; SLSGetWindowSharingState
      reads back state=0.
    - CGWindowListCopyWindowInfo for the overlay reports
      kCGWindowSharingState=0 (the SLS-side state propagates through to
      the CG window list, which SCWindow filters on).
    - kCGWindowIsOnscreen is absent from the dictionary entry (CG
      doesn't know the on-screen state of an SLS-only window without
      an NSWindow wrapper).
    
    Despite all of the above, the screenshot picker still hit-tests onto
    the overlay and captures the border. This means Tahoe's picker uses
    a query path that bypasses standard CGWindowSharingState and tag-bit
    filtering for SLS-only windows.
    
    Approaches still untested but likely dead-ends without docs:
    SLSSetWindowType, SLSSetWindowFiltering, SLSSetWindowSubLevel.
    
    Probe helper probe_cg_window_info added for ongoing investigation.
    Branch is for research; main remains the working EventShape build.
    mfwolffe committed
  6. Revert tag-based exclusion; restore EventShape click-through
    Setting any SLS window tags (bit 1 or bits 1|9) post-creation breaks
    border visibility on Tahoe in our recreate-overlay-on-move lifecycle:
    borders flicker on and disappear during the rapid sync_overlay churn
    that tiling produces. JankyBorders works with tags 1|9 because it
    creates each border window once and moves it via
    SLSTransactionMoveWindowWithGroup; ers releases and recreates the SLS
    window on every geometry change, and Tahoe's compositor handles the
    tagged-then-released window very differently.
    
    Restoring SLSSetWindowEventShape(empty) + SLSSetWindowEventMask(0) for
    click-through; screenshots will again include the overlay until the
    lifecycle is refactored to match JankyBorders'.
    mfwolffe committed
  7. Exclude overlays from screenshots via SLS tag bit 9
    Sets tag bits (1<<1) | (1<<9) on every overlay window: bit 1 is
    kCGSIgnoreForEvents (click-through), bit 9 hides the window from
    ScreenCaptureKit, the screenshot picker, and screen recordings.
    Mirrors JankyBorders' approach (.refs/JankyBorders/src/border.c:290
    and .refs/JankyBorders/src/misc/window.h:266).
    
    Tags are now set BEFORE SLWindowContextCreate / drawing, which is the
    critical difference from the prior tag-based attempt that poisoned
    SLSNewWindow on stack-cycle recreates. Removes the now-redundant
    SLSSetWindowEventShape/Mask, SLSSetWindowSharingState, and
    SLSSetWindowClientPerceivedType bindings.
    mfwolffe committed
  8. Revert SLSTransactionSetWindowBoundsPath donut: segfaults on Tahoe
    The guessed FFI signature for SLSTransactionSetWindowBoundsPath does
    not match Tahoe's actual ABI — calling it crashes ers with SIGSEGV
    during overlay creation, which leaves tarmac with no border renderer.
    Removing the donut path; capture-exclusion now relies solely on the
    SharingState/ClientPerceivedType advisories. Screenshots will once
    again include the overlay border, but borders themselves come back.
    mfwolffe committed

Commits on April 27, 2026

  1. Refresh overlay bounds on focus change before hide/unhide
    AX-driven window moves during stack cycles often don't emit SLS
    WINDOW_MOVE notifications, so the stored overlay frame can be stale
    when update_focus runs. Calling sync_overlay against the live
    SLSGetWindowBounds for both old and new focused windows before the
    hide/unhide pair keeps the active border on the right window during
    stack-next/prev navigation.
    mfwolffe committed
  2. Exclude overlays from screen capture via donut bounds path
    Replaces the overlay's bounds region with a CGPath containing an outer
    rect and an inner cutout. SLS evaluates the path with even-odd winding,
    so the interior is treated as outside the window: screenshots taken
    inside the bordered area capture the underlying app window instead of
    the overlay. Pairs with SharingState/ClientPerceivedType advisories for
    capture clients that honor them.
    mfwolffe committed
  3. Switch overlay click-through from SLSSetWindowTags to SLSSetWindowEventShape
    The kCGSIgnoreForEvents tag bit poisons the shared SLS connection's
    SLSNewWindow path during stack-cycle recreates, dropping border
    overlays on the inactive stack windows. An empty event shape achieves
    the same click-through without mutating tags.
    mfwolffe committed

Commits on April 7, 2026

  1. espadonne committed

Commits on April 6, 2026

  1. espadonne committed

Commits on March 30, 2026

Commits on March 23, 2026

  1. revert layer filters to layer!=0, use main_cid for cross-process queries
    - revert add_fresh/discover/list layer filters back to layer != 0
      (opening to 0-25 caused ers to border its own stale overlays)
    - keep get_front_window layer filter open for focus detection on
      floating windows at non-zero levels
    - use self.main_cid instead of overlay.cid for SLSGetWindowBounds
      in redraw() and reposition() to fix cross-process bounds queries
    espadonne committed