You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift脚本修改macOS滚动条可见性时触发输入源设置重置问题求助

问题:修改macOS滚动条可见性的Swift脚本意外重置输入源设置

我编写了一段Swift脚本用于调整macOS滚动条的可见性,代码如下:

import Foundation

func getSelectedValue() -> String {
  if CommandLine.argc < 2 {
    print("No arguments passed. Please pass one of the following values: \"Always\", \"Automatic\", \"WhenScrolling\".")
    exit(1)
  }

  let args = CommandLine.arguments
  let value = args[1]

  if value != "Always" && value != "Automatic" && value != "WhenScrolling" {
    return "Automatic"
  }

  return value
}

func setScrollBars(_ value: String) {
  let domain = "AppleShowScrollBars"

  UserDefaults.standard.setPersistentDomain(
    [domain: Optional(value) as Any],
    forName: UserDefaults.globalDomain
  )

  let notifyEvent = Notification.Name("AppleShowScrollBarsSettingChanged")
  DistributedNotificationCenter.default().post(name: notifyEvent, object: nil)
}

let value = getSelectedValue()
setScrollBars(value)

使用示例:

./set-scroll-bars Always

但运行脚本时,输入源设置会被重置为默认状态(原本添加的输入法消失,只剩系统默认选项),可脚本里完全没有处理输入源的代码,求解决办法。


问题原因

问题出在setPersistentDomain(_:forName:)方法的用法上:这个方法会完全替换指定域(这里是全局域UserDefaults.globalDomain)的所有持久化设置,而不是仅更新你指定的AppleShowScrollBars键。调用它时,系统会清除全局域中除了你传入的键值对之外的所有设置,这就导致输入源这类依赖全局域存储的配置被意外重置。

修复方案

不要使用setPersistentDomain,改用set(_:forKey:)单独更新目标设置键,再显式同步到磁盘,最后发送通知即可。修改后的代码如下:

import Foundation

func getSelectedValue() -> String {
    if CommandLine.argc < 2 {
        print("No arguments passed. Please pass one of the following values: \"Always\", \"Automatic\", \"WhenScrolling\".")
        exit(1)
    }

    let args = CommandLine.arguments
    let value = args[1]

    if value != "Always" && value != "Automatic" && value != "WhenScrolling" {
        return "Automatic"
    }

    return value
}

func setScrollBars(_ value: String) {
    let domainKey = "AppleShowScrollBars"
    
    // 仅更新指定键,不影响其他全局设置
    UserDefaults.standard.set(value, forKey: domainKey)
    // 显式同步设置到磁盘
    UserDefaults.standard.synchronize()

    let notifyEvent = Notification.Name("AppleShowScrollBarsSettingChanged")
    DistributedNotificationCenter.default().post(name: notifyEvent, object: nil)
}

let value = getSelectedValue()
setScrollBars(value)

说明

set(_:forKey:)只会修改你指定的键值对,不会触动全局域中的其他设置,这样就能避免输入源被意外重置的问题。测试修改后的脚本,既能正常调整滚动条可见性,也能保留原有的输入源配置。

内容的提问来源于stack exchange,提问作者danulqua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 21:45:09