1
0
mirror of https://github.com/chylex/IntelliJ-Pin-Undocked-Tool-Windows.git synced 2025-05-07 04:34:02 +02:00

Add click listener that allows focus changes when clicking a button

This commit is contained in:
chylex 2023-05-19 08:45:48 +02:00
parent 7ec831c0c3
commit 64e5f63304
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
3 changed files with 45 additions and 9 deletions
src/main/kotlin/com/chylex/intellij/pinundockedtoolwindows/patch

View File

@ -0,0 +1,25 @@
package com.chylex.intellij.pinundockedtoolwindows.patch
import com.intellij.openapi.actionSystem.AnActionHolder
import com.intellij.openapi.application.ApplicationManager
import java.awt.AWTEvent
import java.awt.event.AWTEventListener
import java.awt.event.MouseEvent
import javax.swing.AbstractButton
object AwtClickListener : AWTEventListener {
var wasPressingButton = false
private set
override fun eventDispatched(event: AWTEvent?) {
if (event !is MouseEvent || event.id != MouseEvent.MOUSE_RELEASED) {
return
}
val source = event.source
if (source is AbstractButton || source is AnActionHolder) {
wasPressingButton = true
ApplicationManager.getApplication().invokeLater { wasPressingButton = false }
}
}
}

View File

@ -22,6 +22,10 @@ class PatchedAwtFocusListener(internal val original: AWTEventListener) : AWTEven
}
private fun shouldIgnoreFocusLostEvent(currentlyFocused: Component?): Boolean {
if (AwtClickListener.wasPressingButton) {
return false
}
val project = IdeFocusManager.getGlobalInstance().lastFocusedFrame?.project ?: return false
if (project.isDisposed || project.isDefault) {
return false

View File

@ -5,25 +5,34 @@ import java.awt.Toolkit
import java.awt.event.AWTEventListenerProxy
object ToolWindowPatcher {
private const val EVENT_MASK = AWTEvent.FOCUS_EVENT_MASK or AWTEvent.WINDOW_FOCUS_EVENT_MASK
private data class ActivePatch(val focusListener: PatchedAwtFocusListener, val focusEventMask: Long) {
fun apply() = with(Toolkit.getDefaultToolkit()) {
removeAWTEventListener(focusListener.original)
addAWTEventListener(focusListener, focusEventMask)
addAWTEventListener(AwtClickListener, AWTEvent.MOUSE_EVENT_MASK)
}
fun revert() = with(Toolkit.getDefaultToolkit()) {
removeAWTEventListener(AwtClickListener)
removeAWTEventListener(focusListener)
addAWTEventListener(focusListener.original, focusEventMask)
}
}
private var activePatch: ActivePatch? = null
private data class ActivePatch(val listener: PatchedAwtFocusListener, val eventMask: Long)
fun apply() {
if (activePatch != null) {
return
}
val toolkit = Toolkit.getDefaultToolkit()
for (listenerProxy in toolkit.getAWTEventListeners(EVENT_MASK)) {
for (listenerProxy in toolkit.getAWTEventListeners(AWTEvent.FOCUS_EVENT_MASK or AWTEvent.WINDOW_FOCUS_EVENT_MASK)) {
if (listenerProxy is AWTEventListenerProxy) {
val listener = listenerProxy.listener
if (listener.javaClass.name == "com.intellij.openapi.wm.impl.ToolWindowManagerImpl\$ToolWindowManagerAppLevelHelper\$MyListener") {
val patch = ActivePatch(PatchedAwtFocusListener(listener), listenerProxy.eventMask)
toolkit.removeAWTEventListener(listener)
toolkit.addAWTEventListener(patch.listener, patch.eventMask)
patch.apply()
activePatch = patch
return
}
@ -34,9 +43,7 @@ object ToolWindowPatcher {
fun revert() {
val patch = activePatch
if (patch != null) {
val toolkit = Toolkit.getDefaultToolkit()
toolkit.removeAWTEventListener(patch.listener)
toolkit.addAWTEventListener(patch.listener.original, patch.eventMask)
patch.revert()
activePatch = null
}
}