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 return
} }
val tab = this.terminalTab val c = getTopMostWindowUnderMouse()
val terminalTabbedManager = terminalTabbedManager if (c != owner && c is TermoraFrame) {
dragToAnotherWindow(c)
if (tab != null && terminalTabbedManager != null) { } else {
// 如果是手动取消 val tab = this.terminalTab
if (cancelled) { val terminalTabbedManager = terminalTabbedManager
terminalTabbedManager.addTerminalTab(tabIndex, tab) if (tab != null && terminalTabbedManager != null) {
} else if (lastVisitTabIndex > 0) { moveTab(
terminalTabbedManager.addTerminalTab(lastVisitTabIndex, tab) terminalTabbedManager,
} else if (lastVisitTabIndex == 0) { tab,
terminalTabbedManager.addTerminalTab(1, tab) lastVisitTabIndex
} else { )
terminalTabbedManager.addTerminalTab(tab)
} }
} }
@@ -184,6 +183,71 @@ class MyTabbedPane : FlatTabbedPane() {
} }
return false 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) Disposer.register(windowScope, terminalTabbed)
add(terminalTabbed) add(terminalTabbed)
dataProviderSupport.addData(DataProviders.TabbedPane, tabbedPane)
dataProviderSupport.addData(DataProviders.TermoraFrame, this) dataProviderSupport.addData(DataProviders.TermoraFrame, this)
dataProviderSupport.addData(DataProviders.WindowScope, windowScope) dataProviderSupport.addData(DataProviders.WindowScope, windowScope)
} }

View File

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