[object Object]

← back to Ticket System

ticketbar: add one-click Compact/Full toggle button (parity with dotbar)

27c33873291b037c65841e5bfd3be3e162ee97dc · 2026-09-23 09:44:22 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017VyZZwbLBMfoBmdLGuxBuD

Files touched

Diff

commit 27c33873291b037c65841e5bfd3be3e162ee97dc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 23 09:44:22 2026 -0700

    ticketbar: add one-click Compact/Full toggle button (parity with dotbar)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_017VyZZwbLBMfoBmdLGuxBuD
---
 desktop-bar/TicketBar.swift | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/desktop-bar/TicketBar.swift b/desktop-bar/TicketBar.swift
index 102d02e8..ce43b672 100644
--- a/desktop-bar/TicketBar.swift
+++ b/desktop-bar/TicketBar.swift
@@ -83,6 +83,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
   private var themeButton: NSButton!
   private var posButton: NSButton!
   private var dotsButton: NSButton!
+  private var sizeButton: NSButton!
   private var sniperButton: NSButton!
   private var hamburger: NSButton!
   private var isNight = true
@@ -192,6 +193,12 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
     dotsButton.bezelStyle = .inline
     dotsButton.isBordered = false
     dotsButton.toolTip = "Terminal dots"
+    // One-click Compact/Full toggle (Steve 2026-09-23) — parity with desktop-dotbar. Snaps the bar's
+    // cross-axis size between its compact min and the user's last full size (persisted in defaults).
+    sizeButton = NSButton(title: isCompactSize() ? "⤢ Expand" : "⤡ Compact", target: self, action: #selector(toggleCompactSize))
+    sizeButton.bezelStyle = .inline
+    sizeButton.isBordered = false
+    sizeButton.toolTip = "Toggle a compact bar vs full size"
     cpuLabel.font = .monospacedDigitSystemFont(ofSize: 12, weight: .medium)
     cpuLabel.lineBreakMode = .byTruncatingTail
     cpuLabel.alignment = .center
@@ -208,7 +215,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
     sniperButton.layer?.borderWidth = 1
     sniperButton.toolTip = "Toggle the background CPU/RAM priority sniper"
     sniperButton.setContentHuggingPriority(.required, for: .horizontal)
-    stack = NSStackView(views: tiles + [cpuLabel, healthLabel, sniperButton, open, themeButton, posButton, dotsButton])
+    stack = NSStackView(views: tiles + [cpuLabel, healthLabel, sniperButton, open, themeButton, posButton, dotsButton, sizeButton])
     stack.orientation = .horizontal
     stack.spacing = 6
     stack.alignment = .centerY
@@ -218,6 +225,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
     themeButton.setContentHuggingPriority(.required, for: .horizontal)
     posButton.setContentHuggingPriority(.required, for: .horizontal)
     dotsButton.setContentHuggingPriority(.required, for: .horizontal)
+    sizeButton.setContentHuggingPriority(.required, for: .horizontal)
 
     // Center the tile group in the bar. Collapsed hamburger (off-mode) lives in the
     // top-left corner and is shown only when barPosition == "off". In off mode the
@@ -310,6 +318,37 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
     applyPosition()
   }
 
+  // One-click Compact/Full toggle (Steve 2026-09-23). Snaps the bar's cross-axis size between its
+  // compact min and the user's last full size (remembered per-axis), reusing the same defaults keys
+  // that the grip drag + Bar Bigger/Smaller menu write. Additive — those controls are untouched.
+  private func isCompactSize() -> Bool {
+    if barPosition == "left" || barPosition == "right" { return vBarWidth() <= 200 }
+    if barPosition == "top" { return topBarHeight() <= 34 }
+    return false
+  }
+  @objc private func toggleCompactSize() {
+    if barPosition == "left" || barPosition == "right" {
+      let cur = vBarWidth()
+      if cur > 200 {                                   // full -> compact (remember where we were)
+        UserDefaults.standard.set(Double(cur), forKey: "ticketBarFullVWidth")
+        UserDefaults.standard.set(180.0, forKey: "ticketBarVWidth")
+      } else {                                         // compact -> full (restore last, else 300)
+        let full = (UserDefaults.standard.object(forKey: "ticketBarFullVWidth") as? Double) ?? 300
+        UserDefaults.standard.set(min(700, max(201, full)), forKey: "ticketBarVWidth")
+      }
+    } else if barPosition == "top" {
+      let cur = topBarHeight()
+      if cur > 34 {
+        UserDefaults.standard.set(Double(cur), forKey: "ticketBarFullHeight")
+        UserDefaults.standard.set(28.0, forKey: "ticketBarHeight")
+      } else {
+        let full = (UserDefaults.standard.object(forKey: "ticketBarFullHeight") as? Double) ?? 48
+        UserDefaults.standard.set(min(300, max(35, full)), forKey: "ticketBarHeight")
+      }
+    }
+    applyPosition()
+  }
+
   // Dock the bar top (horizontal), left/right (vertical), or collapse to a ☰ hamburger.
   private func applyPosition() {
     guard let screen = panel.screen ?? NSScreen.main ?? NSScreen.screens.first else { return }
@@ -355,6 +394,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
       panel.setFrame(NSRect(x: v.minX, y: v.maxY - barHeight - offset, width: v.width, height: barHeight), display: true)
     }
     posButton.title = ["top": "▔", "left": "▏", "right": "▕"][barPosition] ?? "▔"
+    sizeButton?.title = isCompactSize() ? "⤢ Expand" : "⤡ Compact"
     positionGrip()
     panel.orderFrontRegardless()
   }

← 0c0dc768 Add PARKED tile to desktop ticket bar, mirroring the board's  ·  back to Ticket System  ·  board: per-row status dropdown to reassign status incl. bloc 0774932e →