feat: support focus mode

This commit is contained in:
hstyi
2025-07-14 09:36:45 +08:00
committed by hstyi
parent 675ad4608a
commit a8a1fea91b
10 changed files with 62 additions and 3 deletions

View File

@@ -1,11 +1,13 @@
package app.termora package app.termora
import app.termora.actions.TerminalFocusModeAction
import app.termora.database.DatabaseManager import app.termora.database.DatabaseManager
import app.termora.terminal.* import app.termora.terminal.*
import app.termora.terminal.panel.TerminalPanel import app.termora.terminal.panel.TerminalPanel
import app.termora.tlog.TerminalLoggerDataListener import app.termora.tlog.TerminalLoggerDataListener
import java.awt.Color import java.awt.Color
import javax.swing.UIManager import javax.swing.UIManager
import kotlin.reflect.cast
class TerminalFactory private constructor() : Disposable { class TerminalFactory private constructor() : Disposable {
private val terminals = mutableListOf<Terminal>() private val terminals = mutableListOf<Terminal>()
@@ -75,6 +77,8 @@ class TerminalFactory private constructor() : Disposable {
override fun <T : Any> getData(key: DataKey<T>, defaultValue: T): T { override fun <T : Any> getData(key: DataKey<T>, defaultValue: T): T {
if (key == TerminalPanel.SelectCopy) { if (key == TerminalPanel.SelectCopy) {
return config.selectCopy as T return config.selectCopy as T
} else if (key == TerminalPanel.FocusMode) {
return key.clazz.cast(TerminalFocusModeAction.getInstance().isSelected)
} }
return super.getData(key, defaultValue) return super.getData(key, defaultValue)
} }

View File

@@ -53,6 +53,7 @@ class ActionManager : org.jdesktop.swingx.action.ActionManager() {
addAction(TerminalClearScreenAction.CLEAR_SCREEN, TerminalClearScreenAction()) addAction(TerminalClearScreenAction.CLEAR_SCREEN, TerminalClearScreenAction())
addAction(OpenLocalTerminalAction.LOCAL_TERMINAL, OpenLocalTerminalAction()) addAction(OpenLocalTerminalAction.LOCAL_TERMINAL, OpenLocalTerminalAction())
addAction(TerminalSelectAllAction.SELECT_ALL, TerminalSelectAllAction()) addAction(TerminalSelectAllAction.SELECT_ALL, TerminalSelectAllAction())
addAction(TerminalFocusModeAction.FocusMode, TerminalFocusModeAction.getInstance())
addAction(TerminalZoomInAction.ZOOM_IN, TerminalZoomInAction()) addAction(TerminalZoomInAction.ZOOM_IN, TerminalZoomInAction())
addAction(TerminalZoomOutAction.ZOOM_OUT, TerminalZoomOutAction()) addAction(TerminalZoomOutAction.ZOOM_OUT, TerminalZoomOutAction())

View File

@@ -0,0 +1,37 @@
package app.termora.actions
import app.termora.ApplicationScope
import app.termora.EnableManager
import app.termora.I18n
import app.termora.Icons
import org.slf4j.LoggerFactory
class TerminalFocusModeAction private constructor() : AnAction(
I18n.getString("termora.actions.focus-mode"),
Icons.eye
) {
companion object {
const val FocusMode = "TerminalFocusMode"
private val log = LoggerFactory.getLogger(TerminalFocusModeAction::class.java)
fun getInstance(): TerminalFocusModeAction {
return ApplicationScope.forApplicationScope()
.getOrCreate(TerminalFocusModeAction::class) { TerminalFocusModeAction() }
}
}
init {
putValue(SHORT_DESCRIPTION, I18n.getString("termora.actions.focus-mode"))
putValue(ACTION_COMMAND_KEY, FocusMode)
setStateAction()
isSelected = enableManager.getFlag("Terminal.FocusMode", false)
}
private val enableManager get() = EnableManager.getInstance()
override fun actionPerformed(evt: AnActionEvent) {
enableManager.setFlag("Terminal.FocusMode", isSelected)
}
}

View File

@@ -5,6 +5,7 @@ import app.termora.I18n
import app.termora.Scope import app.termora.Scope
import app.termora.WindowScope import app.termora.WindowScope
import app.termora.actions.MultipleAction import app.termora.actions.MultipleAction
import app.termora.actions.TerminalFocusModeAction
import org.jdesktop.swingx.action.ActionManager import org.jdesktop.swingx.action.ActionManager
@@ -13,6 +14,7 @@ class QuickActionsFindEverywhereProvider(private val windowScope: WindowScope) :
Actions.KEY_MANAGER, Actions.KEY_MANAGER,
Actions.KEYWORD_HIGHLIGHT, Actions.KEYWORD_HIGHLIGHT,
MultipleAction.MULTIPLE, MultipleAction.MULTIPLE,
TerminalFocusModeAction.FocusMode,
) )
override fun find(pattern: String, scope: Scope): List<FindEverywhereResult> { override fun find(pattern: String, scope: Scope): List<FindEverywhereResult> {

View File

@@ -12,6 +12,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing import kotlinx.coroutines.swing.Swing
import java.awt.* import java.awt.*
import javax.swing.JComponent import javax.swing.JComponent
import javax.swing.UIManager
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@@ -263,9 +264,8 @@ class TerminalDisplay(
var j = 1 var j = 1
while (j <= cols) { while (j <= cols) {
val position = Position(row + 1, j) val position = Position(row + 1, j)
val caret = showCursor && j == cursorPosition.x + inputMethodData.offset val isCursorLine = i == cursorPosition.y + (maxVerticalScrollOffset - verticalScrollOffset)
&& i == cursorPosition.y + (maxVerticalScrollOffset - verticalScrollOffset) val caret = showCursor && j == cursorPosition.x + inputMethodData.offset && isCursorLine
val (text, style, length) = if (characters.hasNext()) characters.next() else triple val (text, style, length) = if (characters.hasNext()) characters.next() else triple
var textStyle = style var textStyle = style
val hasSelection = selectionModel.hasSelection(y = i + verticalScrollOffset, x = j) val hasSelection = selectionModel.hasSelection(y = i + verticalScrollOffset, x = j)
@@ -307,6 +307,16 @@ class TerminalDisplay(
length * averageCharWidth length * averageCharWidth
) )
// Focus Mode
if (terminalModel.getData(TerminalPanel.FocusMode, false)) {
if (terminalModel.isAlternateScreenBuffer().not()) {
if (isCursorLine.not()) {
background = colorPalette.getColor(TerminalColor.Basic.BACKGROUND)
foreground = UIManager.getColor("textInactiveText").rgb
}
}
}
// 如果没有颜色反转并且与渲染的背景色一致,那么无需渲染背景 // 如果没有颜色反转并且与渲染的背景色一致,那么无需渲染背景
if (textStyle.inverse || background != colorPalette.getColor(TerminalColor.Basic.BACKGROUND)) { if (textStyle.inverse || background != colorPalette.getColor(TerminalColor.Basic.BACKGROUND)) {
g.color = Color(background) g.color = Color(background)

View File

@@ -44,6 +44,7 @@ class TerminalPanel(val tab: TerminalTab?, val terminal: Terminal, private val w
val Finding = DataKey(Boolean::class) val Finding = DataKey(Boolean::class)
val Focused = DataKey(Boolean::class) val Focused = DataKey(Boolean::class)
val SelectCopy = DataKey(Boolean::class) val SelectCopy = DataKey(Boolean::class)
val FocusMode = DataKey(Boolean::class)
} }
private val properties get() = DatabaseManager.getInstance().properties private val properties get() = DatabaseManager.getInstance().properties

View File

@@ -392,6 +392,7 @@ termora.toolbar.customize-toolbar=Customize Toolbar...
# Actions # Actions
termora.actions.copy-from-terminal=Copy from Terminal termora.actions.copy-from-terminal=Copy from Terminal
termora.actions.focus-mode=Focus Mode
termora.actions.paste-to-terminal=Paste to Terminal termora.actions.paste-to-terminal=Paste to Terminal
termora.actions.select-all-in-terminal=Select All in Terminal termora.actions.select-all-in-terminal=Select All in Terminal
termora.actions.open-terminal-find=Open Terminal Find termora.actions.open-terminal-find=Open Terminal Find

View File

@@ -342,6 +342,7 @@ termora.toolbar.customize-toolbar=Настроить Панель Инструм
# Actions # Actions
termora.actions.copy-from-terminal=Копировать из Терминала termora.actions.copy-from-terminal=Копировать из Терминала
termora.actions.focus-mode=Режим фокусировки
termora.actions.paste-to-terminal=Вставить в Терминала termora.actions.paste-to-terminal=Вставить в Терминала
termora.actions.select-all-in-terminal=Выделить Все в Терминале termora.actions.select-all-in-terminal=Выделить Все в Терминале
termora.actions.open-terminal-find=Открыть Поиск Терминала termora.actions.open-terminal-find=Открыть Поиск Терминала

View File

@@ -396,6 +396,7 @@ termora.protocol.not-supported=不支持 {0} 协议,你可能需要安装插
# Actions # Actions
termora.actions.copy-from-terminal=从终端复制 termora.actions.copy-from-terminal=从终端复制
termora.actions.focus-mode=专注模式
termora.actions.paste-to-terminal=粘贴到终端 termora.actions.paste-to-terminal=粘贴到终端
termora.actions.select-all-in-terminal=在终端中全选 termora.actions.select-all-in-terminal=在终端中全选
termora.actions.open-terminal-find=打开终端查找 termora.actions.open-terminal-find=打开终端查找

View File

@@ -383,6 +383,7 @@ termora.protocol.not-supported=不支援 {0} 協議,你可能需要安裝插
# Actions # Actions
termora.actions.copy-from-terminal=從終端複製 termora.actions.copy-from-terminal=從終端複製
termora.actions.focus-mode=專注模式
termora.actions.paste-to-terminal=貼上到終端 termora.actions.paste-to-terminal=貼上到終端
termora.actions.select-all-in-terminal=在終端中全選 termora.actions.select-all-in-terminal=在終端中全選
termora.actions.open-terminal-find=開啟終端搜尋 termora.actions.open-terminal-find=開啟終端搜尋