dsh-desktop-windows 0.2.0 → 0.2.2
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/package.json +1 -1
- package/src/main.js +43 -15
- package/src/screenshot-preload.js +2 -0
- package/src/screenshot.html +4 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-desktop-windows",
|
|
3
3
|
"productName": "DeepSeek Harness Desktop",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"description": "DeepSeek Harness 桌面版(Windows)· Electron desktop shell for DeepSeek Harness (dsh web) — 双击即用,无需终端 / double-click to run the harness in a standalone window",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"license": "MIT",
|
package/src/main.js
CHANGED
|
@@ -410,12 +410,20 @@ function openShotWindow() {
|
|
|
410
410
|
shotWindow.focus()
|
|
411
411
|
return
|
|
412
412
|
}
|
|
413
|
+
// 用显示器精确尺寸铺满屏幕(不用 fullscreen,Windows 上更可靠)
|
|
414
|
+
const display = screen.getPrimaryDisplay()
|
|
415
|
+
const bounds = display.bounds
|
|
413
416
|
shotWindow = new BrowserWindow({
|
|
414
|
-
|
|
417
|
+
x: bounds.x,
|
|
418
|
+
y: bounds.y,
|
|
419
|
+
width: bounds.width,
|
|
420
|
+
height: bounds.height,
|
|
415
421
|
frame: false,
|
|
416
422
|
resizable: false,
|
|
423
|
+
movable: false,
|
|
417
424
|
alwaysOnTop: true,
|
|
418
425
|
skipTaskbar: true,
|
|
426
|
+
show: false, // 截图加载完成后再显示,避免黑屏闪烁
|
|
419
427
|
webPreferences: {
|
|
420
428
|
contextIsolation: true,
|
|
421
429
|
nodeIntegration: false,
|
|
@@ -424,11 +432,8 @@ function openShotWindow() {
|
|
|
424
432
|
},
|
|
425
433
|
})
|
|
426
434
|
shotWindow.setAlwaysOnTop(true, 'screen-saver')
|
|
435
|
+
shotWindow.setBounds(bounds) // 再次确保铺满
|
|
427
436
|
shotWindow.loadFile(path.join(__dirname, 'screenshot.html'))
|
|
428
|
-
shotWindow.once('ready-to-show', () => {
|
|
429
|
-
shotWindow.show()
|
|
430
|
-
shotWindow.focus()
|
|
431
|
-
})
|
|
432
437
|
shotWindow.webContents.once('did-finish-load', () => {
|
|
433
438
|
if (pendingShot && !shotWindow.isDestroyed()) {
|
|
434
439
|
shotWindow.webContents.send('screenshot:data', pendingShot.toDataURL())
|
|
@@ -439,6 +444,14 @@ function openShotWindow() {
|
|
|
439
444
|
})
|
|
440
445
|
}
|
|
441
446
|
|
|
447
|
+
// 截图在选区窗口内加载完成 → 再显示窗口(避免黑屏"小窗口")
|
|
448
|
+
function onShotLoaded() {
|
|
449
|
+
if (shotWindow && !shotWindow.isDestroyed()) {
|
|
450
|
+
shotWindow.show()
|
|
451
|
+
shotWindow.focus()
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
442
455
|
/** 选区确认:裁剪 → 剪贴板 → 恢复主窗口并粘贴。 */
|
|
443
456
|
function onShotDone(rect) {
|
|
444
457
|
const image = pendingShot
|
|
@@ -455,18 +468,32 @@ function onShotDone(rect) {
|
|
|
455
468
|
}
|
|
456
469
|
if (r.width <= 0 || r.height <= 0) return
|
|
457
470
|
const cropped = image.crop(r)
|
|
471
|
+
// 保存一份临时文件(验证/诊断用)
|
|
472
|
+
try {
|
|
473
|
+
fs.writeFileSync(path.join(os.tmpdir(), 'dsh-screenshot.png'), cropped.toPNG())
|
|
474
|
+
} catch { /* 非致命 */ }
|
|
458
475
|
clipboard.writeImage(cropped)
|
|
476
|
+
// 等主窗口就绪后尝试自动粘贴;若聚焦失败则提示手动 Ctrl+V
|
|
459
477
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
|
|
478
|
+
setTimeout(async () => {
|
|
479
|
+
let focused = false
|
|
480
|
+
try {
|
|
481
|
+
focused = await mainWindow.webContents.executeJavaScript(
|
|
482
|
+
`(() => { const el = document.querySelector('textarea, [contenteditable="true"]'); if (el) { el.focus(); return true } return false })()`
|
|
483
|
+
)
|
|
484
|
+
} catch {
|
|
485
|
+
focused = false
|
|
486
|
+
}
|
|
487
|
+
if (focused) {
|
|
488
|
+
mainWindow.webContents.paste()
|
|
489
|
+
} else {
|
|
490
|
+
dialog.showMessageBox(mainWindow, {
|
|
491
|
+
type: 'info',
|
|
492
|
+
message: '截图已复制到剪贴板,请在聊天输入框按 Ctrl+V 粘贴',
|
|
493
|
+
buttons: ['好'],
|
|
494
|
+
})
|
|
495
|
+
}
|
|
496
|
+
}, 400)
|
|
470
497
|
}
|
|
471
498
|
}
|
|
472
499
|
|
|
@@ -669,6 +696,7 @@ if (!gotLock) {
|
|
|
669
696
|
// 选区截图结果
|
|
670
697
|
ipcMain.on('screenshot:done', (_e, rect) => onShotDone(rect))
|
|
671
698
|
ipcMain.on('screenshot:cancel', () => onShotCancel())
|
|
699
|
+
ipcMain.on('screenshot:loaded', () => onShotLoaded())
|
|
672
700
|
if (external) log('reusing external dsh service on port ' + port)
|
|
673
701
|
})
|
|
674
702
|
|
package/src/screenshot.html
CHANGED
|
@@ -58,8 +58,11 @@
|
|
|
58
58
|
|
|
59
59
|
// 接收主进程传来的截图 dataURL
|
|
60
60
|
window.__screenshot.onData((dataUrl) => {
|
|
61
|
+
bg.onload = () => {
|
|
62
|
+
window.__screenshot.loaded()
|
|
63
|
+
setTimeout(() => (hint.style.opacity = '0.9'), 100)
|
|
64
|
+
}
|
|
61
65
|
bg.src = dataUrl
|
|
62
|
-
setTimeout(() => (hint.style.opacity = '0.9'), 100)
|
|
63
66
|
})
|
|
64
67
|
|
|
65
68
|
const updateMask = () => {
|