diff --git a/pkg/driver/vz/scrollbar_fix_darwin.go b/pkg/driver/vz/scrollbar_fix_darwin.go new file mode 100644 index 00000000000..6b4e0f92f50 --- /dev/null +++ b/pkg/driver/vz/scrollbar_fix_darwin.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright The Lima Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:build darwin + +// This file includes scrollbar_fix_darwin.m via cgo. +// See that file for documentation on why this patch is needed. + +package vz + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Cocoa -lobjc +#include "scrollbar_fix_darwin.m" +*/ +import "C" diff --git a/pkg/driver/vz/scrollbar_fix_darwin.m b/pkg/driver/vz/scrollbar_fix_darwin.m new file mode 100644 index 00000000000..e84cb563b3e --- /dev/null +++ b/pkg/driver/vz/scrollbar_fix_darwin.m @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright The Lima Authors +// SPDX-License-Identifier: Apache-2.0 + +// scrollbar_fix_darwin.m - Runtime patch to disable scrollbars on VZ display window +// +// The Code-Hex/vz library wraps VZVirtualMachineView in an NSScrollView with +// scrollbars hardcoded to YES (for their zoom feature). This causes ~16px of +// the VM display to be cut off by scrollbar gutters. +// +// This file uses Objective-C method swizzling to intercept NSScrollView's +// setDocumentView: method and disable scrollbars when the document view is +// a VZVirtualMachineView. +// +// This is a temporary workaround until Code-Hex/vz adds a configuration option +// to disable scrollbars. See: https://github.com/Code-Hex/vz/issues/XXX + +#import +#import + +// Store original implementation pointer +static IMP original_setDocumentView = NULL; + +// Patched implementation that disables scrollbars for VZ views +static void patched_setDocumentView(id self, SEL _cmd, NSView *view) { + // Call original implementation first + ((void (*)(id, SEL, NSView *))original_setDocumentView)(self, _cmd, view); + + // If the document view is a VZVirtualMachineView, disable scrollbars + // The scrollbars cause the VM display to be cut off by ~16px + if (view != nil && [view isKindOfClass:NSClassFromString(@"VZVirtualMachineView")]) { + [(NSScrollView *)self setHasVerticalScroller:NO]; + [(NSScrollView *)self setHasHorizontalScroller:NO]; + } +} + +// Constructor attribute ensures this runs before main() +// This patches NSScrollView before Code-Hex/vz creates any windows +__attribute__((constructor)) +static void patchNSScrollViewForVZ(void) { + Method m = class_getInstanceMethod([NSScrollView class], @selector(setDocumentView:)); + if (m != NULL) { + original_setDocumentView = method_setImplementation(m, (IMP)patched_setDocumentView); + } +}