@atom-js-org/runtime 0.5.1-alpha.0 → 0.5.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/bridge-script.cjs +62 -0
- package/src/bridge-server.cjs +5 -0
- package/src/browser-window.cjs +11 -0
- package/src/runtime/macos-native-host.m +24 -0
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/src/bridge-script.cjs
CHANGED
|
@@ -39,6 +39,68 @@ function generateBridgeScript({ websocketUrl, preloadCode = '' }) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function normalizeAppRegion(value) {
|
|
43
|
+
const normalized = String(value || '').trim().toLowerCase();
|
|
44
|
+
return normalized === 'drag' || normalized === 'no-drag' ? normalized : '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function appRegionForElement(element) {
|
|
48
|
+
if (!(element instanceof Element)) return '';
|
|
49
|
+
if (element.hasAttribute('data-atom-no-drag')) return 'no-drag';
|
|
50
|
+
if (element.hasAttribute('data-atom-drag-region')) return 'drag';
|
|
51
|
+
|
|
52
|
+
const attribute = normalizeAppRegion(
|
|
53
|
+
element.getAttribute('data-atom-app-region') || element.getAttribute('data-app-region')
|
|
54
|
+
);
|
|
55
|
+
if (attribute) return attribute;
|
|
56
|
+
|
|
57
|
+
const inline = normalizeAppRegion(
|
|
58
|
+
element.style && (
|
|
59
|
+
element.style.getPropertyValue('-webkit-app-region') ||
|
|
60
|
+
element.style.getPropertyValue('app-region')
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
if (inline) return inline;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const computed = getComputedStyle(element);
|
|
67
|
+
return normalizeAppRegion(
|
|
68
|
+
computed.getPropertyValue('-webkit-app-region') ||
|
|
69
|
+
computed.getPropertyValue('app-region')
|
|
70
|
+
);
|
|
71
|
+
} catch {
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isInteractiveDragTarget(element) {
|
|
77
|
+
return element instanceof Element && Boolean(element.closest(
|
|
78
|
+
'button, input, textarea, select, option, a[href], [contenteditable=""], [contenteditable="true"], [role="button"]'
|
|
79
|
+
));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function shouldStartWindowDrag(event) {
|
|
83
|
+
if (event.button !== 0 || event.defaultPrevented) return false;
|
|
84
|
+
const path = typeof event.composedPath === 'function' ? event.composedPath() : [event.target];
|
|
85
|
+
let draggable = false;
|
|
86
|
+
|
|
87
|
+
for (const entry of path) {
|
|
88
|
+
if (!(entry instanceof Element)) continue;
|
|
89
|
+
const region = appRegionForElement(entry);
|
|
90
|
+
if (region === 'no-drag') return false;
|
|
91
|
+
if (region === 'drag') draggable = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!draggable || isInteractiveDragTarget(event.target)) return false;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
document.addEventListener('mousedown', (event) => {
|
|
99
|
+
if (!shouldStartWindowDrag(event)) return;
|
|
100
|
+
event.preventDefault();
|
|
101
|
+
sendNow({ type: 'system', command: 'start-window-drag' });
|
|
102
|
+
}, true);
|
|
103
|
+
|
|
42
104
|
function makeEvent(channel) {
|
|
43
105
|
return Object.freeze({
|
|
44
106
|
channel,
|
package/src/bridge-server.cjs
CHANGED
|
@@ -163,6 +163,11 @@ class BridgeServer {
|
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
if (message.type === 'system') {
|
|
167
|
+
if (message.command === 'start-window-drag') win._startNativeDrag();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
166
171
|
if (message.type === 'send') {
|
|
167
172
|
const event = createIpcEvent(win);
|
|
168
173
|
ipcMain.emit(message.channel, event, ...(Array.isArray(message.args) ? message.args : []));
|
package/src/browser-window.cjs
CHANGED
|
@@ -219,6 +219,11 @@ class BrowserWindow extends EventEmitter {
|
|
|
219
219
|
return false;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
_startNativeDrag() {
|
|
223
|
+
if (this._destroyed) return false;
|
|
224
|
+
return this._sendHostCommand({ command: 'start-drag' });
|
|
225
|
+
}
|
|
226
|
+
|
|
222
227
|
_markRendererReady(details) {
|
|
223
228
|
this._notifyDidFinishLoad(details && details.href ? details.href : this._currentUrl, 'bridge');
|
|
224
229
|
}
|
|
@@ -334,6 +339,12 @@ class BrowserWindow extends EventEmitter {
|
|
|
334
339
|
}
|
|
335
340
|
}
|
|
336
341
|
|
|
342
|
+
startDrag() {
|
|
343
|
+
if (!this._startNativeDrag()) {
|
|
344
|
+
console.warn('[AtomJS] Native window dragging is not supported by the current platform host.');
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
337
348
|
blur() {}
|
|
338
349
|
|
|
339
350
|
close() {
|
|
@@ -140,6 +140,7 @@ static void AtomJSConfigureApplicationIdentity(NSApplication *application) {
|
|
|
140
140
|
@property(nonatomic, assign) BOOL modal;
|
|
141
141
|
- (instancetype)initWithWindowId:(NSNumber *)windowId config:(NSDictionary *)config;
|
|
142
142
|
- (void)navigate:(NSString *)urlString;
|
|
143
|
+
- (void)beginWindowDrag;
|
|
143
144
|
@end
|
|
144
145
|
|
|
145
146
|
@implementation AtomJSWindowController
|
|
@@ -175,6 +176,8 @@ static void AtomJSConfigureApplicationIdentity(NSApplication *application) {
|
|
|
175
176
|
defer:NO];
|
|
176
177
|
_window.releasedWhenClosed = NO;
|
|
177
178
|
_window.delegate = self;
|
|
179
|
+
_window.movable = YES;
|
|
180
|
+
_window.movableByWindowBackground = NO;
|
|
178
181
|
_window.title = AtomJSString(config[@"title"], atomAppName);
|
|
179
182
|
_window.backgroundColor = AtomJSColor(config[@"backgroundColor"]);
|
|
180
183
|
_window.tabbingMode = NSWindowTabbingModeDisallowed;
|
|
@@ -270,6 +273,25 @@ static void AtomJSConfigureApplicationIdentity(NSApplication *application) {
|
|
|
270
273
|
return self;
|
|
271
274
|
}
|
|
272
275
|
|
|
276
|
+
- (void)beginWindowDrag {
|
|
277
|
+
if (!self.window || ([NSEvent pressedMouseButtons] & 1) == 0) return;
|
|
278
|
+
|
|
279
|
+
NSPoint screenLocation = [NSEvent mouseLocation];
|
|
280
|
+
NSPoint windowLocation = [self.window convertPointFromScreen:screenLocation];
|
|
281
|
+
NSEvent *mouseDown = [NSEvent
|
|
282
|
+
mouseEventWithType:NSEventTypeLeftMouseDown
|
|
283
|
+
location:windowLocation
|
|
284
|
+
modifierFlags:0
|
|
285
|
+
timestamp:[[NSProcessInfo processInfo] systemUptime]
|
|
286
|
+
windowNumber:self.window.windowNumber
|
|
287
|
+
context:nil
|
|
288
|
+
eventNumber:0
|
|
289
|
+
clickCount:1
|
|
290
|
+
pressure:1.0];
|
|
291
|
+
|
|
292
|
+
if (mouseDown) [self.window performWindowDragWithEvent:mouseDown];
|
|
293
|
+
}
|
|
294
|
+
|
|
273
295
|
- (void)navigate:(NSString *)urlString {
|
|
274
296
|
NSURL *url = [NSURL URLWithString:urlString ?: @"about:blank"];
|
|
275
297
|
if (!url) {
|
|
@@ -561,6 +583,8 @@ static void AtomJSHandleMessage(NSDictionary *message) {
|
|
|
561
583
|
[controller.window makeKeyAndOrderFront:nil];
|
|
562
584
|
[controller.window orderFrontRegardless];
|
|
563
585
|
[NSApp activateIgnoringOtherApps:YES];
|
|
586
|
+
} else if ([command isEqualToString:@"start-drag"]) {
|
|
587
|
+
[controller beginWindowDrag];
|
|
564
588
|
} else if ([command isEqualToString:@"close"] || [command isEqualToString:@"destroy"]) {
|
|
565
589
|
[controller.window close];
|
|
566
590
|
} else if ([command isEqualToString:@"set-title"]) {
|