← back to Ticket System
Ticket desktop bar: drag-to-resize the bar edge with a visible grip handle
03487e804c10984a518a88cb085ecaec55556084 · 2026-09-03 11:48:20 -0700 · Steve Abrams
The bar is now resizable by DRAGGING its edge (the menu-only resize wasn't
discoverable — 'won't let me adjust'):
- Left dock: drag the RIGHT edge; Right dock: drag the LEFT edge (width 180–700).
- Top bar: drag the BOTTOM edge (height 28–300).
- A blue grip handle marks the draggable edge; the whole edge is a 12px grab zone.
Edge-drag is checked before slide/reorder so grabbing the edge always resizes.
Verified live via cliclick: left dock 300→481px.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M desktop-bar/TicketBar.swift
Diff
commit 03487e804c10984a518a88cb085ecaec55556084
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 3 11:48:20 2026 -0700
Ticket desktop bar: drag-to-resize the bar edge with a visible grip handle
The bar is now resizable by DRAGGING its edge (the menu-only resize wasn't
discoverable — 'won't let me adjust'):
- Left dock: drag the RIGHT edge; Right dock: drag the LEFT edge (width 180–700).
- Top bar: drag the BOTTOM edge (height 28–300).
- A blue grip handle marks the draggable edge; the whole edge is a 12px grab zone.
Edge-drag is checked before slide/reorder so grabbing the edge always resizes.
Verified live via cliclick: left dock 300→481px.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
desktop-bar/TicketBar.swift | 57 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/desktop-bar/TicketBar.swift b/desktop-bar/TicketBar.swift
index 553e7d39..100d0263 100644
--- a/desktop-bar/TicketBar.swift
+++ b/desktop-bar/TicketBar.swift
@@ -99,6 +99,10 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
private var dragStartPanelY: CGFloat?
private var barSlid = false
private var didDrag = false
+ private var resizing = false
+ private var resizeStartMouse = CGPoint.zero
+ private var resizeStartSize: CGFloat = 0
+ private var gripView: NSView!
func applicationDidFinishLaunching(_ notification: Notification) {
NSApp.setActivationPolicy(.accessory)
@@ -198,6 +202,13 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
hamburger.centerXAnchor.constraint(equalTo: container.centerXAnchor),
hamburger.centerYAnchor.constraint(equalTo: container.centerYAnchor)
])
+ // Visible resize grip at the draggable edge (positioned per-dock in applyPosition).
+ gripView = NSView(frame: .zero)
+ gripView.wantsLayer = true
+ gripView.layer?.backgroundColor = NSColor(calibratedRed: 0.30, green: 0.60, blue: 1.0, alpha: 0.9).cgColor
+ gripView.layer?.cornerRadius = 2
+ gripView.toolTip = "Drag to resize the bar"
+ container.addSubview(gripView)
panel.contentView = container
installDragMonitor()
applyTheme()
@@ -205,6 +216,27 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
panel.orderFrontRegardless()
}
+ // The draggable resize edge for the current dock, in window (bottom-left) coords.
+ private func inResizeZone(_ loc: CGPoint) -> Bool {
+ let f = panel.frame
+ switch barPosition {
+ case "left": return loc.x >= f.width - 12
+ case "right": return loc.x <= 12
+ case "top": return loc.y <= 9
+ default: return false
+ }
+ }
+ private func positionGrip() {
+ guard gripView != nil else { return }
+ let f = panel.frame
+ switch barPosition {
+ case "left": gripView.isHidden = false; gripView.frame = NSRect(x: f.width - 6, y: f.height/2 - 60, width: 5, height: 120)
+ case "right": gripView.isHidden = false; gripView.frame = NSRect(x: 1, y: f.height/2 - 60, width: 5, height: 120)
+ case "top": gripView.isHidden = false; gripView.frame = NSRect(x: f.width/2 - 60, y: 1, width: 120, height: 4)
+ default: gripView.isHidden = true
+ }
+ }
+
private static let positionOrder = ["top", "left", "right", "off"]
@objc private func cyclePosition() {
let i = (BarController.positionOrder.firstIndex(of: barPosition) ?? 0) + 1
@@ -243,6 +275,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
stack.removeFromSuperview()
}
hamburger.isHidden = false
+ gripView?.isHidden = true
let w: CGFloat = 46, h: CGFloat = 32
panel.setFrame(NSRect(x: v.minX + 8, y: v.maxY - h, width: w, height: h), display: true)
panel.orderFrontRegardless()
@@ -277,6 +310,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] ?? "▔"
+ positionGrip()
panel.orderFrontRegardless()
}
@@ -318,6 +352,12 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
case .leftMouseDown:
self.didDrag = false
self.barSlid = false
+ // Grab the resize edge? (right edge of left dock, left edge of right dock, bottom of top bar)
+ self.resizing = self.inResizeZone(event.locationInWindow)
+ if self.resizing {
+ self.resizeStartMouse = NSEvent.mouseLocation
+ self.resizeStartSize = (self.barPosition == "top") ? self.topBarHeight() : self.vBarWidth()
+ }
self.draggingKey = self.tiles.first(where: {
$0.bounds.contains($0.convert(event.locationInWindow, from: nil))
})?.key
@@ -325,6 +365,22 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
self.dragStartMouseY = NSEvent.mouseLocation.y // global screen Y
self.dragStartPanelY = self.panel.frame.origin.y
case .leftMouseDragged:
+ // Edge-drag RESIZE takes priority over slide/reorder.
+ if self.resizing {
+ self.didDrag = true
+ let m = NSEvent.mouseLocation
+ switch self.barPosition {
+ case "left":
+ UserDefaults.standard.set(Double(min(700, max(180, self.resizeStartSize + (m.x - self.resizeStartMouse.x)))), forKey: "ticketBarVWidth")
+ case "right":
+ UserDefaults.standard.set(Double(min(700, max(180, self.resizeStartSize + (self.resizeStartMouse.x - m.x)))), forKey: "ticketBarVWidth")
+ case "top":
+ UserDefaults.standard.set(Double(min(300, max(28, self.resizeStartSize + (self.resizeStartMouse.y - m.y)))), forKey: "ticketBarHeight")
+ default: break
+ }
+ self.applyPosition()
+ return event
+ }
let dy = NSEvent.mouseLocation.y - (self.dragStartMouseY ?? NSEvent.mouseLocation.y)
let dx = event.locationInWindow.x - (self.dragStartX ?? event.locationInWindow.x)
// Vertical drag → SLIDE the whole bar up/down (Top mode only). Horizontal drag on a tile → reorder.
@@ -338,6 +394,7 @@ private final class BarController: NSObject, NSApplicationDelegate, NSWindowDele
}
case .leftMouseUp:
if self.barSlid { self.persistBarOffset() }
+ self.resizing = false
self.draggingKey = nil
self.dragStartX = nil
self.dragStartMouseY = nil
← 737fe045 record TK-11188 bounded monitoring proof
·
back to Ticket System
·
desktop-bar: add ◉ terminal-dots dropdown (multi-select + fo 02eb728b →