diff --git a/app/src/layout/Tab.ts b/app/src/layout/Tab.ts index 1435f093d..2fa7fc32d 100644 --- a/app/src/layout/Tab.ts +++ b/app/src/layout/Tab.ts @@ -9,6 +9,10 @@ import {unicode2Emoji} from "../emoji"; import {fetchPost} from "../util/fetch"; import {showTooltip} from "../dialog/tooltip"; import {isTouchDevice} from "../util/functions"; +/// #if !BROWSER +import {getCurrentWindow} from "@electron/remote"; +import {openNewWindow} from "../window/openNewWindow"; +/// #endif import {layoutToJSON} from "./util"; export class Tab { @@ -93,6 +97,17 @@ export class Tab { item.remove(); }); } + /// #if !BROWSER + // 拖拽到屏幕外 + setTimeout(() => { + if (!this.headElement.style.maxWidth) { + const windowBounds = getCurrentWindow().getBounds(); + if (event.clientX < 0 || event.clientY < 0 || event.clientX > windowBounds.width || event.clientY > windowBounds.height) { + openNewWindow(this) + } + } + }, Constants.TIMEOUT_BLOCKLOAD) // 等待主进程发送关闭消息 + /// #endif window.siyuan.dragElement = undefined; if (event.dataTransfer.dropEffect === "none") { // 按 esc 取消的时候应该还原在 dragover 时交换的 tab diff --git a/app/src/menus/tab.ts b/app/src/menus/tab.ts index 3504f166d..e89ba266e 100644 --- a/app/src/menus/tab.ts +++ b/app/src/menus/tab.ts @@ -1,13 +1,11 @@ import {Tab} from "../layout/Tab"; import {MenuItem} from "./Menu"; import {Editor} from "../editor"; -import {copyTab, layoutToJSON} from "../layout/util"; +import {copyTab} from "../layout/util"; /// #if !BROWSER -import {BrowserWindow} from "@electron/remote"; -import * as path from "path"; +import {openNewWindow} from "../window/openNewWindow"; /// #endif import {copySubMenu} from "./commonMenuItem"; -import {Constants} from "../constants"; const closeMenu = (tab: Tab) => { const allTabs: Tab[] = []; @@ -208,25 +206,7 @@ export const initTabMenu = (tab: Tab) => { label: window.siyuan.languages.tabToWindow, icon: "iconMove", click: () => { - const win = new BrowserWindow({ - show: true, - trafficLightPosition: {x: 8, y: 13}, - width: 1032, - height: 650, - frame: "darwin" === window.siyuan.config.system.os, - icon: path.join(window.siyuan.config.system.appDir, "stage", "icon-large.png"), - titleBarStyle: "hidden", - webPreferences: { - contextIsolation: false, - nodeIntegration: true, - webviewTag: true, - webSecurity: false, - }, - }); - const json = {}; - layoutToJSON(tab, json); - win.loadURL(`${window.location.protocol}//${window.location.host}/stage/build/app/window.html?v=${Constants.SIYUAN_VERSION}&json=${JSON.stringify(json)}`); - tab.parent.removeTab(tab.id); + openNewWindow(tab); } }).element); /// #endif diff --git a/app/src/window/openNewWindow.ts b/app/src/window/openNewWindow.ts new file mode 100644 index 000000000..424438daf --- /dev/null +++ b/app/src/window/openNewWindow.ts @@ -0,0 +1,29 @@ +import {layoutToJSON} from "../layout/util"; +/// #if !BROWSER +import {BrowserWindow} from "@electron/remote"; +import * as path from "path"; +/// #endif +import {Constants} from "../constants"; +import {Tab} from "../layout/Tab"; + +export const openNewWindow = (tab: Tab) => { + const win = new BrowserWindow({ + show: true, + trafficLightPosition: {x: 8, y: 13}, + width: 1032, + height: 650, + frame: "darwin" === window.siyuan.config.system.os, + icon: path.join(window.siyuan.config.system.appDir, "stage", "icon-large.png"), + titleBarStyle: "hidden", + webPreferences: { + contextIsolation: false, + nodeIntegration: true, + webviewTag: true, + webSecurity: false, + }, + }); + const json = {}; + layoutToJSON(tab, json); + win.loadURL(`${window.location.protocol}//${window.location.host}/stage/build/app/window.html?v=${Constants.SIYUAN_VERSION}&json=${JSON.stringify(json)}`); + tab.parent.removeTab(tab.id); +}