Skip to content

Commit 0d35cf3

Browse files
authored
Merge pull request #214 from stuffbucket/scrollbar-config
Fix scrollbar occlusion of taskbar in desktop environments
2 parents ccaf748 + 91ace1e commit 0d35cf3

4 files changed

Lines changed: 70 additions & 3 deletions

File tree

example/gui-linux/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
gui-linux
2+
virtualization

example/linux/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
linux
2+
virtualization

example/macOS/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
macOS
2+
virtualization

virtualization_view.m

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ @implementation AppDelegate {
179179
NSTimer *_scrollTimer;
180180
NSPoint _scrollDelta;
181181
id _mouseMovedMonitor;
182+
id _scrollWheelMonitor;
182183
}
183184

184185
- (instancetype)initWithVirtualMachine:(VZVirtualMachine *)virtualMachine
@@ -225,6 +226,10 @@ - (void)dealloc
225226
[NSEvent removeMonitor:_mouseMovedMonitor];
226227
_mouseMovedMonitor = nil;
227228
}
229+
if (_scrollWheelMonitor) {
230+
[NSEvent removeMonitor:_scrollWheelMonitor];
231+
_scrollWheelMonitor = nil;
232+
}
228233
[self stopScrollTimer];
229234
if (_virtualMachine) {
230235
[_virtualMachine removeObserver:self forKeyPath:@"state"];
@@ -416,6 +421,13 @@ - (void)setupGraphicWindow
416421
return event;
417422
}];
418423

424+
// Add scroll wheel event monitor for zoom functionality
425+
_scrollWheelMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel
426+
handler:^NSEvent *(NSEvent *event) {
427+
[self handleScrollWheel:event];
428+
return event;
429+
}];
430+
419431
// Create scroll view for the virtual machine view
420432
NSScrollView *scrollView = [self createScrollViewForVirtualMachineView:_virtualMachineView];
421433
[_window setContentView:scrollView];
@@ -638,6 +650,7 @@ - (void)showErrorAlertWithMessage:(NSString *)message error:(NSError *)error
638650
- (void)toggleZoomMode:(id)sender
639651
{
640652
_isZoomEnabled = !_isZoomEnabled;
653+
NSScrollView *scrollView = (NSScrollView *)_window.contentView;
641654

642655
// Reset zoom when zoom mode is disabled.
643656
if (!_isZoomEnabled) {
@@ -646,15 +659,29 @@ - (void)toggleZoomMode:(id)sender
646659
[context setDuration:0.3];
647660
[[_window.contentView animator] setMagnification:1.0];
648661
}
649-
completionHandler:nil];
662+
completionHandler:^{
663+
// Hide scrollers when zoom is disabled
664+
if ([scrollView isKindOfClass:[NSScrollView class]]) {
665+
scrollView.hasVerticalScroller = NO;
666+
scrollView.hasHorizontalScroller = NO;
667+
}
668+
}];
669+
} else {
670+
// Show scrollers when zoom is enabled (they'll auto-hide when not needed)
671+
if ([scrollView isKindOfClass:[NSScrollView class]]) {
672+
scrollView.hasVerticalScroller = YES;
673+
scrollView.hasHorizontalScroller = YES;
674+
scrollView.autohidesScrollers = YES;
675+
}
650676
}
651677
}
652678

653679
- (NSScrollView *)createScrollViewForVirtualMachineView:(VZVirtualMachineView *)view
654680
{
655681
NSScrollView *scrollView = [[[NSScrollView alloc] initWithFrame:_window.contentView.bounds] autorelease];
656-
scrollView.hasVerticalScroller = YES;
657-
scrollView.hasHorizontalScroller = YES;
682+
scrollView.hasVerticalScroller = NO;
683+
scrollView.hasHorizontalScroller = NO;
684+
scrollView.autohidesScrollers = YES;
658685
scrollView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
659686
scrollView.documentView = view;
660687

@@ -697,6 +724,40 @@ - (void)handleMagnification:(NSMagnificationGestureRecognizer *)recognizer
697724
[scrollView setMagnification:newMagnification centeredAtPoint:centeredPoint];
698725
}
699726

727+
// Handles scroll wheel events for zooming when Command or Option key is held.
728+
// This provides zoom functionality for mice and non-trackpad devices.
729+
- (void)handleScrollWheel:(NSEvent *)event
730+
{
731+
if (!_isZoomEnabled) {
732+
return;
733+
}
734+
735+
// Only zoom if Command or Option key is held
736+
if (!(event.modifierFlags & NSEventModifierFlagCommand) &&
737+
!(event.modifierFlags & NSEventModifierFlagOption)) {
738+
return;
739+
}
740+
741+
NSScrollView *scrollView = (NSScrollView *)_window.contentView;
742+
if (![scrollView isKindOfClass:[NSScrollView class]]) {
743+
return;
744+
}
745+
746+
// Calculate zoom delta (scrolling up = zoom in, down = zoom out)
747+
CGFloat zoomDelta = event.scrollingDeltaY * 0.01; // Scale factor for smooth zooming
748+
CGFloat currentMagnification = scrollView.magnification;
749+
CGFloat newMagnification = currentMagnification + zoomDelta;
750+
751+
// Clamp to min/max magnification
752+
newMagnification = MIN(scrollView.maxMagnification, MAX(scrollView.minMagnification, newMagnification));
753+
754+
// Get mouse location for centered zooming
755+
NSPoint mouseLocation = [_window.contentView convertPoint:event.locationInWindow fromView:nil];
756+
NSPoint centeredPoint = [scrollView.contentView convertPoint:mouseLocation fromView:_window.contentView];
757+
758+
[scrollView setMagnification:newMagnification centeredAtPoint:centeredPoint];
759+
}
760+
700761
// When the mouse approaches the window's edges, this handler adjusts the scroll position
701762
// to provide a smooth panning experience without requiring manual scroll input.
702763
- (void)handleMouseMovement:(NSEvent *)event

0 commit comments

Comments
 (0)