Skip to content

Commit

Permalink
Fixed a conflict between overlapping tracking areas, fixed #289 (#298)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikekazakov committed Jun 10, 2024
1 parent 31a69cf commit 6f461d1
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2015-2020 Michael Kazakov. Subject to GNU General Public License version 3.
// Copyright (C) 2015-2024 Michael Kazakov. Subject to GNU General Public License version 3.
#include "MainWindowFilePanelState+OverlappedTerminalSupport.h"
#include <Utility/NativeFSManager.h>
#include <VFS/Native.h>
Expand Down Expand Up @@ -136,16 +136,16 @@ - (void)onOverlappedTerminalShellCWDChanged
- (void)onOverlappedTerminalLongTaskStarted
{
if( self.overlappedTerminalVisible && !self.isPanelsSplitViewHidden ) {
[self hidePanelsSplitView];
m_OverlappedTerminal->did_hide_panels_for_long_task = true;
[self hidePanelsSplitView];
}
}

- (void)onOverlappedTerminalLongTaskFinished
{
if( self.isPanelsSplitViewHidden && m_OverlappedTerminal->did_hide_panels_for_long_task ) {
[self showPanelsSplitView];
m_OverlappedTerminal->did_hide_panels_for_long_task = false;
[self showPanelsSplitView];
}
}

Expand Down Expand Up @@ -175,6 +175,15 @@ - (void)updateOverlappedTerminalVisibility
else {
m_OverlappedTerminal->terminal.hidden = false;
}

if( m_OverlappedTerminal->did_hide_panels_for_long_task ) {
m_OverlappedTerminal->terminal.termScrollView.nonOverlappedHeight =
m_OverlappedTerminal->terminal.termScrollView.bounds.size.height;
}
else {
const double gap = [m_OverlappedTerminal->terminal bottomGapForLines:m_OverlappedTerminal->bottom_gap];
m_OverlappedTerminal->terminal.termScrollView.nonOverlappedHeight = gap;
}
}

- (bool)overlappedTerminalVisible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ - (void)updateBottomConstraint
if( m_OverlappedTerminal->terminal == nullptr )
return;

auto gap = [m_OverlappedTerminal->terminal bottomGapForLines:m_OverlappedTerminal->bottom_gap];
const double gap = [m_OverlappedTerminal->terminal bottomGapForLines:m_OverlappedTerminal->bottom_gap];
m_MainSplitViewBottomConstraint.constant = -gap;

[self updateOverlappedTerminalVisibility];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (C) 2015-2018 Michael Kazakov. Subject to GNU General Public License version 3.
// Copyright (C) 2015-2024 Michael Kazakov. Subject to GNU General Public License version 3.
#pragma once

#include <Term/ShellTask.h>
#include <Term/View.h>
#include <Term/ScrollView.h>

@interface FilePanelOverlappedTerminal : NSView

Expand All @@ -20,6 +21,7 @@

@property(nonatomic, readonly) nc::term::ShellTask::TaskState state;
@property(nonatomic, readonly) NCTermView *termView;
@property(nonatomic, readonly) NCTermScrollView *termScrollView;

/**
* tries to understand if Bash shell has something entered awaiting for Enter hit.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2015-2023 Michael Kazakov. Subject to GNU General Public License version 3.
// Copyright (C) 2015-2024 Michael Kazakov. Subject to GNU General Public License version 3.
#include <Base/CommonPaths.h>
#include <Term/ShellTask.h>
#include <Term/Screen.h>
Expand Down Expand Up @@ -57,6 +57,7 @@ - (id)initWithFrame:(NSRect)frameRect
settings:TerminalSettings()];
m_TermScrollView.translatesAutoresizingMaskIntoConstraints = false;
m_TermScrollView.view.reportsSizeByOccupiedContent = true;
m_TermScrollView.overlapped = true;
[self addSubview:m_TermScrollView];
[self addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"|-(==0)-[m_TermScrollView]-(==0)-|"
Expand Down Expand Up @@ -230,6 +231,11 @@ - (NCTermView *)termView
return m_TermScrollView.view;
}

- (NCTermScrollView *)termScrollView
{
return m_TermScrollView;
}

- (void)runShell:(const std::string &)_initial_wd
{
if( !_initial_wd.empty() )
Expand Down
4 changes: 3 additions & 1 deletion Source/Term/include/Term/ScrollView.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2015-2020 Michael Kazakov. Subject to GNU General Public License version 3.
// Copyright (C) 2015-2024 Michael Kazakov. Subject to GNU General Public License version 3.
#pragma once

#include <functional>
Expand All @@ -19,5 +19,7 @@ class Settings;
@property(nonatomic, readonly) NSEdgeInsets viewInsets;
@property(nonatomic, readwrite) NSCursor *customCursor;
@property(nonatomic, readwrite) std::function<void(int sx, int sy)> onScreenResized;
@property(nonatomic, readwrite) bool overlapped;
@property(nonatomic, readwrite) double nonOverlappedHeight;

@end
142 changes: 87 additions & 55 deletions Source/Term/source/ScrollView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ @implementation NCTermScrollView {
std::shared_ptr<nc::term::Settings> m_Settings;
std::function<void(int sx, int sy)> m_OnScreenResized;
int m_SettingsNotificationTicket;
bool m_MouseInsideNonOverlappedArea;
bool m_Overlapped;
double m_NonOverlappedHeight;
NSTrackingArea *m_TrackingArea;
}

@synthesize view = m_View;
Expand All @@ -31,7 +33,8 @@ - (id)initWithFrame:(NSRect)frameRect attachToTop:(bool)top settings:(std::share
assert(settings);
self = [super initWithFrame:frameRect];
if( self ) {
m_MouseInsideNonOverlappedArea = false;
m_Overlapped = false;
m_NonOverlappedHeight = 0.;
self.customCursor = NSCursor.IBeamCursor;

auto rc = self.contentView.bounds;
Expand Down Expand Up @@ -74,13 +77,7 @@ - (id)initWithFrame:(NSRect)frameRect attachToTop:(bool)top settings:(std::share
[strong_self onSettingsChanged];
});

const auto tracking_flags = NSTrackingActiveInKeyWindow | NSTrackingMouseMoved |
NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect;
const auto tracking = [[NSTrackingArea alloc] initWithRect:NSRect()
options:tracking_flags
owner:self
userInfo:nil];
[self addTrackingArea:tracking];
[self updateTrackingAreas];
}
return self;
}
Expand All @@ -95,56 +92,27 @@ - (void)dealloc
[NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)mouseMoved:(NSEvent *)event
- (void)cursorUpdate:(NSEvent *) [[maybe_unused]] _event
{
const auto hit_view = [self.window.contentView hitTest:event.locationInWindow];
const auto inside = static_cast<bool>([hit_view isDescendantOf:self]);
if( inside ) {
if( m_MouseInsideNonOverlappedArea == false ) {
m_MouseInsideNonOverlappedArea = true;
[self mouseEnteredNonOverlappedArea];
}
}
else {
if( m_MouseInsideNonOverlappedArea == true ) {
m_MouseInsideNonOverlappedArea = false;
[self mouseExitedNonOverlappedArea];
}
if( !m_TrackingArea ) {
[super cursorUpdate:_event];
return;
}
}

- (void)mouseEntered:(NSEvent *)event
{
[self mouseMoved:event];
}

- (void)mouseExited:(NSEvent *) [[maybe_unused]] _event
{
if( m_MouseInsideNonOverlappedArea == true ) {
m_MouseInsideNonOverlappedArea = false;
[self mouseExitedNonOverlappedArea];
if( m_Overlapped ) {
const NSPoint global_mouse_location = NSEvent.mouseLocation;
const NSPoint window_mouse_location = [self.view.window convertPointFromScreen:global_mouse_location];
const NSPoint local_mouse_location = [self convertPoint:window_mouse_location fromView:nil];
const NSRect tracking_rect = m_TrackingArea.rect;
if( NSPointInRect(local_mouse_location, tracking_rect) ) {
[self.customCursor set];
}
else {
[super cursorUpdate:_event];
}
}
}

- (void)cursorUpdate:(NSEvent *) [[maybe_unused]] _event
{
}

- (void)mouseEnteredNonOverlappedArea
{
[self.customCursor push];
}

- (void)mouseExitedNonOverlappedArea
{
[self.customCursor pop];
}

- (void)viewDidMoveToWindow
{
if( self.window == nil && m_MouseInsideNonOverlappedArea ) {
m_MouseInsideNonOverlappedArea = false;
[self mouseExitedNonOverlappedArea];
else {
[self.customCursor set];
}
}

Expand Down Expand Up @@ -236,4 +204,68 @@ - (void)mouseDown:(NSEvent *)_event
[m_View mouseDown:_event];
}

- (bool)overlapped
{
return m_Overlapped;
}

- (void)setOverlapped:(bool)_overlapped
{
if( m_Overlapped == _overlapped ) {
return;
}
m_Overlapped = _overlapped;
if( m_TrackingArea ) {
[self removeTrackingArea:m_TrackingArea];
m_TrackingArea = nil;
}
[self updateTrackingAreas];
}

- (double)nonOverlappedHeight
{
return m_NonOverlappedHeight;
}

- (void)setNonOverlappedHeight:(double)_height
{
if( m_NonOverlappedHeight == _height ) {
return;
}

m_NonOverlappedHeight = _height;
[self updateTrackingAreas];
}

- (void)updateTrackingAreas
{
[super updateTrackingAreas];

if( m_Overlapped ) {
if( m_TrackingArea ) {
[self removeTrackingArea:m_TrackingArea];
m_TrackingArea = nil;
}

if( m_NonOverlappedHeight > 0. ) {
const NSTrackingAreaOptions tracking_flags = NSTrackingActiveInKeyWindow | NSTrackingCursorUpdate;
const NSRect rc = NSMakeRect(
0., self.bounds.size.height - m_NonOverlappedHeight, self.bounds.size.width, m_NonOverlappedHeight);
m_TrackingArea = [[NSTrackingArea alloc] initWithRect:rc options:tracking_flags owner:self userInfo:nil];
[self addTrackingArea:m_TrackingArea];
}
}
else {
if( m_TrackingArea == nil ) {
const NSTrackingAreaOptions tracking_flags =
NSTrackingActiveInKeyWindow | NSTrackingCursorUpdate | NSTrackingInVisibleRect;
m_TrackingArea = [[NSTrackingArea alloc] initWithRect:NSRect {}
options:tracking_flags
owner:self
userInfo:nil];
[self addTrackingArea:m_TrackingArea];
}
}
}

@end

0 comments on commit 6f461d1

Please sign in to comment.