iTerm2透明化:非活动窗口的透明背景

55

原生的 MacOS 终端 可以设置无效和有效窗格的透明度。iTerm2 可以设置有效窗格的透明度,但我找不到无效窗格的设置,或许是没有这个选项? 我知道 iTerm2 可以使无效分割窗格变暗,但我想要的是透明度。

感谢帮助。


有一个调光量条,您可以调整不活动的分割窗格。这是您要找的吗? - yash
@yash 它确切地在哪里? - user5563206
2
它在“首选项”->“外观”->“调暗”下。我为您提供了一个截图链接https://ibb.co/dohF6S。 - yash
4个回答

94

这篇博客中找到了答案,但为了保存起见,在此重复一遍。

  1. 打开iTerm2的首选项,使用菜单或 +,
  2. 从菜单栏中选择配置文件
  3. 选择窗口标签
  4. 拖动透明度滑块以满足您的需要 iTerm2透明度控制

16
这会影响所有窗口,包括活动窗口。OP 希望仅更改非活动窗口的透明度。 - Todoroki
3
对我没用...我正在更改透明度,但iterm2窗口仍然不透明...有什么想法吗? - MrT77
2
这并没有回答问题。OP想要的是Mac终端的行为:使非活动窗口透明。据我所知,这是不可能的,但@bjfletcher的答案更接近。 - jcollum
同时,在设置新机器时也无法正常工作。我在某个地方读到,你需要按下cmd+B,然后它就可以工作了!(我记不得在旧机器上是否需要这样做了) - pHiL

17

偏好设置 → 外观 → 调暗 → 调暗程度

enter image description here


1
相似的替代,但并不完全相同。它应用了暗化效果(类似于灰色薄膜),而不是点击时不透明的效果和非活动时透明的效果。 - riddle_me_this

4

更新:我将这两个脚本上传到GitHub,并附上了一个漂亮的演示GIF :)

同时进行了一些重构和错误修复。请查看仓库以获取最新的脚本。

Demo toggling the transparency of two iTerm2 windows


每个先前的答案都有一个拼图的一部分。其中一个更改透明度,但是静态的; 另一个在窗口处于非活动状态时会变暗,而不是改变透明度。
要获得所需的行为(根据窗口焦点更改透明度),您需要使用iTerm2的Python API编写脚本,并将其保存为AutoLaunch脚本:
#!/usr/bin/env python3.7

import iterm2

# Store window change event reason objects in more convenient variables
window_selected = [iterm2.FocusUpdateWindowChanged.Reason.TERMINAL_WINDOW_BECAME_KEY]


async def update_tab_transparency(connection, tab, reason):
    # Apply to any and all sessions in tab
    for session in tab.sessions:
        profile = await session.async_get_profile()
        change = iterm2.LocalWriteOnlyProfile()

        # For window change events bringing a window into focus,
        # change transparency to zero
        if reason in window_selected:
            change.set_transparency(0)

        # For window change events taking a window out of focus,
        # make sure transparency matches the original profile
        else:
            # But, only need to do anything if the profile has been changed
            # from the original
            if profile.original_guid:
                original = await iterm2.Profile.async_get(
                    connection, [profile.original_guid]
                )
                change.set_transparency(original[0].transparency)

        await session.async_set_profile_properties(change)


async def main(connection):
    app = await iterm2.async_get_app(connection)

    # Initialize for first window
    window = app.current_window
    if window and window.current_tab:
        tab = window.current_tab
        reason = window_selected[0]
        await update_tab_transparency(connection, tab, reason)

    async with iterm2.FocusMonitor(connection) as mon:
        while True:
            # Block until a tab or window change
            update = await mon.async_get_next_update()

            # When switching to a new tab, treat as selecting a window
            if update.selected_tab_changed:
                tab = app.get_tab_by_id(update.selected_tab_changed.tab_id)
                reason = window_selected[0]

            # For window change events, use the provided event reason
            elif update.window_changed:
                window = app.get_window_by_id(update.window_changed.window_id)
                tab = window.current_tab
                reason = update.window_changed.event

            # For other focus change events, do nothing
            else:
                continue

            if tab:
                await update_tab_transparency(connection, tab, reason)


iterm2.run_forever(main)

请参阅iTerm文档,了解有关使用Python脚本的详细信息。
您想要在配置文件上设置所需的透明度,并选中“新窗口的设置”中的“使用透明度”框。这听起来有些反直觉,但是通过API似乎无法切换“使用透明度”设置,因此脚本在创建时会快速将窗口切换为不透明状态。
至少在我的机器上,当首次选择窗口时,窗口会短暂闪烁,但我不确定是否有什么办法可以解决这个问题。
注意:目前(11.6,Big Sur)的macOS处理窗口与此相反——它让活动窗口透明(至少某些部分),并使非活动窗口不透明(并带有淡化效果)。尝试在Safari中打开一个新标签页。这是有意义的!透明度创造了一种深度感。看到活动窗口后面有窗口强调它在它们前面。
要获得这种行为,请使用以下脚本。这个变体既简单,又似乎运行更平稳(没有闪烁)。如果你将模糊度调到最大,透明度约为25,则效果最佳。
#!/usr/bin/env python3.7

import iterm2

# Store window change event reason objects in more convenient variables
window_selected = [iterm2.FocusUpdateWindowChanged.Reason.TERMINAL_WINDOW_BECAME_KEY]


async def update_tab_transparency(connection, tab, reason):
    # Apply to any and all sessions in tab
    for session in tab.sessions:
        profile = await session.async_get_profile()
        change = iterm2.LocalWriteOnlyProfile()

        # For window change events bringing a window into focus,
        # make sure transparency matches the original profile
        if reason in window_selected:
            # But, only need to do anything if the profile has been changed
            # from the original
            if profile.original_guid:
                original = await iterm2.Profile.async_get(
                    connection, [profile.original_guid]
                )
                change.set_transparency(original[0].transparency)

        # For window change events taking a window out of focus,
        # change transparency to zero
        else:
            change.set_transparency(0)

        await session.async_set_profile_properties(change)


async def main(connection):
    app = await iterm2.async_get_app(connection)

    async with iterm2.FocusMonitor(connection) as mon:
        while True:
            # Block until a window change
            update = await mon.async_get_next_update()
            if update.window_changed:
                window = app.get_window_by_id(update.window_changed.window_id)
                tab = window.current_tab

                if tab:
                    reason = update.window_changed.event
                    await update_tab_transparency(connection, tab, reason)


iterm2.run_forever(main)

Derrik:只是想让你知道,我已经运行了你的第二个脚本几天了,它非常好。 - Enda Farrell
太好了听到这个消息!如果您有任何建议/修复,请分享给我。我注意到有时当我关闭选项卡时,会收到脚本崩溃的通知,但似乎不会影响其他选项卡的运行时行为,所以我没有深入研究它。 - Derrik Petrin
1
好的更新:我修复了那个错误(实际上有两个),进行了一些重构,并将它们全部上传到了Github :) - Derrik Petrin

0
我为任何需要更改活动窗格和所有非活动窗格/会话的透明度的人创建了一个脚本,而不仅仅是整个窗口。它适用于多个窗口和分割窗格。这是GitHub repo
个人上我在全屏模式下使用它与分割窗格-这样我可以通过非活动窗格轻松查看参考资料,同时保持活动窗格可读性。
如果您有任何问题或建议,请随时提出,并希望这对您有所帮助! :)
编辑:这是上述存储库中脚本的代码。如果不需要,可以使用settings.json删除代码-否则,您可以在iTerm2 Scripts文件夹(/Users/{username}/Library/Application Support/iTerm2/Scripts)中创建一个settings.json文件。
{
    "pane_transparency": {
        "active": 0.2,
        "inactive": 0.8,
        "blur": false,
        "blur_radius": 0
    }
}

如果你不想要模糊效果,也可以将其移除(需要对每个窗格、选项卡和窗口应用)。
如上所述,你可以阅读关于如何在iTerm2的官方文档中设置脚本的内容。应该将脚本作为守护进程运行(从./AutoLaunch文件夹中)。
#!/usr/bin/env python3.7

import iterm2
import json
import os

# Global settings
SETTINGS_FILE = os.path.join(os.path.dirname(__file__), '../settings.json')

# Default pane transparency settings (overridden by settings.json)
DEFAULT_TRANSPARENCY_ACTIVE = 0.25
DEFAULT_TRANSPARENCY_INACTIVE = 0.75
DEFAULT_BLUR = False
DEFAULT_BLUR_RADUIUS = 0

async def load_settings():
    """Load settings from the settings.json file."""

    with open(SETTINGS_FILE) as f:
        settings = json.load(f)

    pane_transparency = settings.get("pane_transparency", {})

    transparancy_active = pane_transparency.get("active", DEFAULT_TRANSPARENCY_ACTIVE)
    transparancy_active = transparancy_active if (0 <= transparancy_active <= 1) else DEFAULT_TRANSPARENCY_ACTIVE

    transparency_inactive = pane_transparency.get("inactive", DEFAULT_TRANSPARENCY_INACTIVE)
    transparency_inactive = transparency_inactive if (0 <= transparency_inactive <= 1) else DEFAULT_TRANSPARENCY_INACTIVE

    blur = pane_transparency.get("blur", DEFAULT_BLUR)
    blur = blur if blur == True or False else DEFAULT_BLUR

    blur_radius = pane_transparency.get("blur_radius", DEFAULT_BLUR_RADUIUS)
    blur_radius = blur_radius if (isinstance(blur_radius, int) and 0 <= blur_radius <= 30) else DEFAULT_BLUR_RADUIUS

    return transparancy_active, transparency_inactive, blur, blur_radius

async def transparancy_update(
        app,
        active_session,
        transparency_active,
        transparency_inactive,
        blur,
        blur_radius):
    """Updating the transparency for the active and all inactive panes."""

    inactive_change = iterm2.LocalWriteOnlyProfile()
    inactive_change.set_transparency(transparency_inactive)

    active_change = iterm2.LocalWriteOnlyProfile()
    active_change.set_transparency(transparency_active)
    active_change.set_blur(blur)
    active_change.set_blur_radius(blur_radius)

    # Updates all inactive panes
    await transparancy_update_inactive(app, active_session, inactive_change)

    # Updates the the active pane
    await active_session.async_set_profile_properties(active_change)

async def transparancy_update_inactive(app, active_session, inactive_change):
    """Updating the transparency for all inactive panes."""

    # Looping over all inactive panes and changing transparency
    for window in app.terminal_windows:
            for tab in window.tabs:
                for session in tab.all_sessions:
                    if session != active_session:
                        await session.async_set_profile_properties(inactive_change)

async def main(connection):
    """Pane transparency main method"""

    app = await iterm2.async_get_app(connection)

    transparency_active, transparency_inactive, blur, blur_radius = await load_settings()

    async with iterm2.FocusMonitor(connection) as mon:
        active_session = app.current_terminal_window.current_tab.current_session
        while True:
            update = await mon.async_get_next_update()

            if update.active_session_changed:
                active_session = app.get_session_by_id(update.active_session_changed.session_id)

            if update.active_session_changed or update.selected_tab_changed:
                await transparancy_update(
                    app,
                    active_session,
                    transparency_active,
                    transparency_inactive,
                    blur,
                    blur_radius)

iterm2.run_forever(main)

1
虽然此链接可能回答了问题,但最好在这里包含答案的关键部分,并提供链接供参考。仅有链接的答案可能会因为链接页面的更改而失效。- 来自审核 - soundflix
用代码库中相关的代码更新了帖子。 - BlackZoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接