feat: support drag and drop to other windows (#145)

This commit is contained in:
hstyi
2025-02-06 09:51:45 +08:00
committed by GitHub
parent 4a513360e6
commit 8bd1b34f46
3 changed files with 79 additions and 13 deletions

View File

@@ -136,19 +136,18 @@ class MyTabbedPane : FlatTabbedPane() {
return
}
val tab = this.terminalTab
val terminalTabbedManager = terminalTabbedManager
if (tab != null && terminalTabbedManager != null) {
// 如果是手动取消
if (cancelled) {
terminalTabbedManager.addTerminalTab(tabIndex, tab)
} else if (lastVisitTabIndex > 0) {
terminalTabbedManager.addTerminalTab(lastVisitTabIndex, tab)
} else if (lastVisitTabIndex == 0) {
terminalTabbedManager.addTerminalTab(1, tab)
} else {
terminalTabbedManager.addTerminalTab(tab)
val c = getTopMostWindowUnderMouse()
if (c != owner && c is TermoraFrame) {
dragToAnotherWindow(c)
} else {
val tab = this.terminalTab
val terminalTabbedManager = terminalTabbedManager
if (tab != null && terminalTabbedManager != null) {
moveTab(
terminalTabbedManager,
tab,
lastVisitTabIndex
)
}
}
@@ -184,6 +183,71 @@ class MyTabbedPane : FlatTabbedPane() {
}
return false
}
private fun getTopMostWindowUnderMouse(): Window? {
val mouseLocation = MouseInfo.getPointerInfo().location
val owner = owner
if (owner.isVisible && owner.bounds.contains(mouseLocation)) {
return owner
}
val windows = Window.getWindows()
// 倒序遍历,最上层的窗口优先匹配
for (i in windows.indices.reversed()) {
val window = windows[i]
if (window !is TermoraFrame) {
continue
}
if (window.isVisible && window.bounds.contains(mouseLocation)) {
val topComponent = SwingUtilities.getDeepestComponentAt(
window,
mouseLocation.x - window.x, mouseLocation.y - window.y
)
if (topComponent != null) {
return SwingUtilities.getWindowAncestor(topComponent)
}
}
}
return null
}
private fun dragToAnotherWindow(frame: TermoraFrame) {
val tab = this.terminalTab ?: return
val tabbedManager = frame.getData(DataProviders.TerminalTabbed) ?: return
val tabbedPane = frame.getData(DataProviders.TabbedPane) ?: return
val location = Point(MouseInfo.getPointerInfo().location)
SwingUtilities.convertPointFromScreen(location, tabbedPane)
val index = tabbedPane.indexAtLocation(location.x, location.y)
moveTab(
tabbedManager,
tab,
index
)
if (frame.hasFocus()) {
return
}
SwingUtilities.invokeLater {
frame.requestFocus()
tabbedPane.selectedComponent?.requestFocusInWindow()
}
}
private fun moveTab(terminalTabbedManager: TerminalTabbedManager, tab: TerminalTab, lastVisitTabIndex: Int) {
// 如果是手动取消
if (cancelled) {
terminalTabbedManager.addTerminalTab(tabIndex, tab)
} else if (lastVisitTabIndex > 0) {
terminalTabbedManager.addTerminalTab(lastVisitTabIndex, tab)
} else if (lastVisitTabIndex == 0) {
terminalTabbedManager.addTerminalTab(1, tab)
} else {
terminalTabbedManager.addTerminalTab(tab)
}
}
}

View File

@@ -116,6 +116,7 @@ class TermoraFrame : JFrame(), DataProvider {
Disposer.register(windowScope, terminalTabbed)
add(terminalTabbed)
dataProviderSupport.addData(DataProviders.TabbedPane, tabbedPane)
dataProviderSupport.addData(DataProviders.TermoraFrame, this)
dataProviderSupport.addData(DataProviders.WindowScope, windowScope)
}

View File

@@ -7,6 +7,7 @@ object DataProviders {
val Terminal = DataKey(app.termora.terminal.Terminal::class)
val PtyConnector = DataKey(app.termora.terminal.PtyConnector::class)
val TabbedPane = DataKey(app.termora.MyTabbedPane::class)
val TerminalTabbed = DataKey(app.termora.TerminalTabbed::class)
val TerminalTab = DataKey(app.termora.TerminalTab::class)
val TerminalTabbedManager = DataKey(app.termora.TerminalTabbedManager::class)