Make top visual space for surface drag handles

This commit is contained in:
Martin Emde
2026-01-11 09:50:51 -08:00
committed by Mitchell Hashimoto
parent dcbc765dc0
commit 47577c7623
2 changed files with 20 additions and 26 deletions

View File

@@ -1,41 +1,30 @@
import AppKit
import SwiftUI
extension Ghostty {
/// A grab handle overlay at the top of the surface for dragging the window.
/// Only appears when hovering in the top region of the surface.
struct SurfaceGrabHandle: View {
private let handleHeight: CGFloat = 10
let surfaceView: SurfaceView
@State private var isHovering: Bool = false
@State private var isDragging: Bool = false
var body: some View {
VStack(spacing: 0) {
Rectangle()
.fill(Color.primary.opacity(isHovering || isDragging ? 0.15 : 0))
.frame(height: handleHeight)
.overlay(alignment: .center) {
if isHovering || isDragging {
Image(systemName: "ellipsis")
.font(.system(size: 14, weight: .semibold))
.foregroundColor(.primary.opacity(0.5))
}
}
.contentShape(Rectangle())
.overlay {
SurfaceDragSource(
surfaceView: surfaceView,
isDragging: $isDragging,
isHovering: $isHovering
)
}
ZStack {
SurfaceDragSource(
surfaceView: surfaceView,
isDragging: $isDragging,
isHovering: $isHovering
)
.frame(width: 80, height: 12)
.contentShape(Rectangle())
Spacer()
Image(systemName: "ellipsis")
.font(.system(size: 10, weight: .semibold))
.foregroundColor(.primary.opacity(isHovering ? 0.8 : 0.3))
.offset(y: -2)
.allowsHitTesting(false)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
}
}

View File

@@ -427,9 +427,14 @@ const DerivedConfig = struct {
}
fn scaledPadding(self: *const DerivedConfig, x_dpi: f32, y_dpi: f32) rendererpkg.Padding {
// Add 6pt header height for macOS overlay elements (tight fit around ellipsis)
const header_height_pt: f32 = 6.0;
const header_height_px: u32 = @intFromFloat(@floor(header_height_pt * y_dpi / 72));
const padding_top: u32 = padding_top: {
const padding_top: f32 = @floatFromInt(self.window_padding_top);
break :padding_top @intFromFloat(@floor(padding_top * y_dpi / 72));
const scaled_padding: u32 = @intFromFloat(@floor(padding_top * y_dpi / 72));
break :padding_top scaled_padding + header_height_px;
};
const padding_bottom: u32 = padding_bottom: {
const padding_bottom: f32 = @floatFromInt(self.window_padding_bottom);