Skip to content

Commit 4d8393b

Browse files
authored
fix runtime shutdown crash and Scintilla clipping (#59)
* fix Scintilla scroll view clipping * upgrade Lynxtron toolchain to 0.0.10
1 parent 9013a2a commit 4d8393b

11 files changed

Lines changed: 452 additions & 160 deletions

File tree

.changeset/quiet-runtimes-rest.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"lynxtron-go": patch
3+
"@lynxtron-examples/cli": patch
4+
---
5+
6+
Upgrade the Lynxtron runtime and companion toolchain to 0.0.10 to avoid shutdown task-runner teardown crashes, keep generated workspaces on the same runtime, and contain native Scintilla scroll views during split resizing.

lynxtron-go/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@
6767
"@lynx-js/rspeedy": "catalog:",
6868
"@lynx-js/type-config": "catalog:",
6969
"@lynx-js/types": "catalog:",
70-
"app-builder-lib": "26.8.1",
71-
"dmg-builder": "26.8.1",
70+
"app-builder-lib": "26.13.0",
71+
"dmg-builder": "26.13.0",
72+
"electron-builder-squirrel-windows": "26.13.0",
7273
"@rsbuild/plugin-type-check": "1.6.0",
7374
"@rspack/cli": "catalog:",
7475
"@rspack/core": "catalog:",

lynxtron-go/repros/cover-view-input-paste/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"start": "npm run build && lynxtron ./dist/desktop"
99
},
1010
"dependencies": {
11-
"@lynx-js/lynxtron": "0.0.8",
11+
"@lynx-js/lynxtron": "0.0.10",
1212
"@lynx-js/react": "0.123.1"
1313
},
1414
"devDependencies": {

lynxtron-go/scintilla-extension/module/scintilla_view.mm

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ - (NSRect)adjustScroll:(NSRect)proposedVisibleRect {
4747
@end
4848

4949
@interface LynxtronScintillaView : ScintillaView
50+
@property(nonatomic, strong) NSView* scrollerCornerFillView;
5051
- (void)syncBounceBackgroundWithStyleDefault;
52+
- (void)updateScrollerCornerFillFrame;
5153
@end
5254

5355
@implementation LynxtronScintillaView
@@ -56,6 +58,30 @@ + (Class)contentViewClass {
5658
return [LynxtronSCIContentView class];
5759
}
5860

61+
- (void)layout {
62+
[super layout];
63+
[self updateScrollerCornerFillFrame];
64+
}
65+
66+
- (void)updateScrollerCornerFillFrame {
67+
NSScroller* horizontalScroller = self.scrollView.horizontalScroller;
68+
NSScroller* verticalScroller = self.scrollView.verticalScroller;
69+
const BOOL visible = self.scrollView.hasHorizontalScroller &&
70+
self.scrollView.hasVerticalScroller &&
71+
horizontalScroller != nil &&
72+
verticalScroller != nil;
73+
self.scrollerCornerFillView.hidden = !visible;
74+
if (!visible) return;
75+
76+
// NSScrollView leaves this rectangle uncovered when both legacy scrollers
77+
// are present. Pin our fill view to the same bottom-right intersection.
78+
self.scrollerCornerFillView.frame = NSMakeRect(
79+
NSMinX(verticalScroller.frame),
80+
NSMinY(horizontalScroller.frame),
81+
NSWidth(verticalScroller.frame),
82+
NSHeight(horizontalScroller.frame));
83+
}
84+
5985
- (void)syncBounceBackgroundWithStyleDefault {
6086
// Scintilla paints the document itself, but elastic overscroll exposes
6187
// AppKit's scroll/clip view background. Derive that native background
@@ -70,6 +96,20 @@ - (void)syncBounceBackgroundWithStyleDefault {
7096
self.scrollView.backgroundColor = backgroundColor;
7197
self.scrollView.contentView.drawsBackground = YES;
7298
self.scrollView.contentView.backgroundColor = backgroundColor;
99+
100+
// AppKit leaves a separate rectangle where the horizontal and vertical
101+
// legacy scrollers meet. Its default fill stays white in a dark editor.
102+
if (self.scrollerCornerFillView == nil) {
103+
self.scrollerCornerFillView = [[NSView alloc] initWithFrame:NSZeroRect];
104+
self.scrollerCornerFillView.autoresizingMask =
105+
NSViewMinXMargin | NSViewMaxYMargin;
106+
[self.scrollView addSubview:self.scrollerCornerFillView];
107+
}
108+
if (self.scrollerCornerFillView != nil) {
109+
self.scrollerCornerFillView.wantsLayer = YES;
110+
self.scrollerCornerFillView.layer.backgroundColor = backgroundColor.CGColor;
111+
[self updateScrollerCornerFillFrame];
112+
}
73113
}
74114

75115
@end
@@ -98,6 +138,14 @@ - (instancetype)initWithFrame:(NSRect)frameRect owner:(extension::ScintillaView*
98138
_owner = owner;
99139
_scintillaView = [[LynxtronScintillaView alloc] initWithFrame:self.bounds];
100140
[_scintillaView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
141+
// During a live mosaic resize AppKit can leave the scroll view's
142+
// private content-background view one legacy-scroller (17pt) larger
143+
// than the scroll view itself. NSView does not clip subviews by
144+
// default, so that private background otherwise paints across the
145+
// neighbouring pane's toolbar. Keep every AppKit-owned scroll-view
146+
// child contained by the editor's native bounds.
147+
_scintillaView.scrollView.wantsLayer = YES;
148+
_scintillaView.scrollView.layer.masksToBounds = YES;
101149
_scintillaView.delegate = self; // receive SCN_MODIFIED etc.
102150
[self addSubview:_scintillaView];
103151
}

lynxtron-go/src/main/desktop/package.runtime.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"dependencies": {
77
"@isaacs/fs-minipass": "^4.0.0",
88
"@lynx-js/react": "0.123.1",
9-
"@lynx-js/lynxtron": "0.0.8",
9+
"@lynx-js/lynxtron": "0.0.10",
1010
"@lynx-js/types": "4.1.0",
11-
"@lynxtron-examples/cli": "0.0.5",
11+
"@lynxtron-examples/cli": "0.0.6",
1212
"@types/node": "22.20.0",
1313
"@types/prop-types": "15.7.15",
1414
"@types/react": "18.3.31",

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
},
1717
"devDependencies": {
1818
"@changesets/cli": "^2.27.0",
19-
"app-builder-lib": "26.8.1",
20-
"dmg-builder": "26.8.1",
19+
"app-builder-lib": "26.13.0",
20+
"dmg-builder": "26.13.0",
21+
"electron-builder-squirrel-windows": "26.13.0",
2122
"verdaccio": "6.3.2"
2223
},
2324
"engines": {

packages/cli/src/workspace/manager.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import * as path from 'path';
66
// `catalog:` resolve to the versions they were built against. `latest` is used
77
// where the showcase does not care about pinning (config is unversioned surface).
88
const CATALOG_VERSIONS: Record<string, string> = {
9-
'@lynx-js/lynxtron': '0.0.8',
10-
'@lynx-js/lynxtron-builder': '0.0.8',
11-
'@lynx-js/lynxtron-dev-plugins': '0.0.8',
12-
'@lynx-js/lynx-library-headers': '0.0.8',
9+
'@lynx-js/lynxtron': '0.0.10',
10+
'@lynx-js/lynxtron-builder': '0.0.10',
11+
'@lynx-js/lynxtron-dev-plugins': '0.0.10',
12+
'@lynx-js/lynx-library-headers': '0.0.10',
13+
'@lynx-js/lynxtron-rebuild': '0.0.10',
1314
'@lynx-js/config-rsbuild-plugin': '0.2.0',
1415
'@lynx-js/react': '0.123.1',
1516
'@lynx-js/react-rsbuild-plugin': '^0.18.1',
@@ -34,8 +35,9 @@ const ROOT_DEPENDENCIES: Record<string, string> = {
3435
// hoist them, so unless the workspace root depends on them itself the patch
3536
// step errors and the whole install — and therefore every fetched showcase —
3637
// fails. The source monorepo carries them at its root for the same reason.
37-
'app-builder-lib': '26.8.1',
38-
'dmg-builder': '26.8.1',
38+
'app-builder-lib': '26.13.0',
39+
'dmg-builder': '26.13.0',
40+
'electron-builder-squirrel-windows': '26.13.0',
3941
};
4042

4143
/**

0 commit comments

Comments
 (0)