Skip to content

Add QT_ACCESSIBILITY=1 toggle for Qt6 accessibility support#53

Merged
keyang556 merged 2 commits intomainfrom
claude/friendly-leakey
Apr 13, 2026
Merged

Add QT_ACCESSIBILITY=1 toggle for Qt6 accessibility support#53
keyang556 merged 2 commits intomainfrom
claude/friendly-leakey

Conversation

@keyang556
Copy link
Copy Markdown
Owner

@keyang556 keyang556 commented Apr 13, 2026

Summary

Adds a persistent user environment variable toggle for QT_ACCESSIBILITY=1 to improve Qt6 accessibility support in LINE Desktop. The setting is stored in the Windows registry (HKCU\Environment) and persists across reboots.

Features

  • Menu item: NVDA Tools > LINE Desktop > 切換 Qt 無障礙環境變數
  • Status reporting: NVDA+Shift+V now includes Qt accessibility status
  • Works offline: Toggle can be set even when LINE is not running
  • Auto-broadcast: Changes are broadcast via WM_SETTINGCHANGE to notify running processes

Implementation

  • Reads/writes HKCU\Environment\QT_ACCESSIBILITY via Windows registry
  • Includes helper functions in both line.py and globalPlugins/lineDesktopHelper.py
  • User is informed that LINE needs to be restarted for changes to take effect
  • AppModule logs Qt accessibility status at startup

Testing

  • Modified files pass Python syntax validation
  • No breaking changes to existing functionality

🤖 Generated with Claude Code

Greptile Summary

此 PR 新增了 QT_ACCESSIBILITY=1 使用者環境變數的切換功能,以改善 LINE Desktop 在 Qt6 下的輔助功能支援。實作方式為直接讀寫 Windows 登錄機碼 HKCU\\Environment,並透過 WM_SETTINGCHANGE 廣播通知所有執行中的程序,設定在重開機後持續有效。

主要變更:

  • line.py:新增 _isQtAccessibleSet / _setQtAccessible 輔助函式、script_toggleQtAccessible 腳本,並在 script_reportLineInfo(NVDA+Shift+V)的狀態報告中加入 Qt 無障礙狀態
  • lineDesktopHelper.py:新增對應的選單項目(「切換 Qt 無障礙環境變數」)及事件處理邏輯,LINE 未執行時仍可直接操作;輔助函式與 line.py 重複(註解中已坦承)

發現的問題:

  • script_toggleQtAccessibleline.py 中缺少 @script 裝飾器與 gesture 宣告,導致 PR 說明所列的 NVDA+Shift+A 鍵盤快捷鍵實際上不會被 NVDA 綁定,無法透過鍵盤觸發此功能。

Confidence Score: 3/5

PR 存在一個明確的功能缺失:@script 裝飾器遺漏使鍵盤快捷鍵完全無法運作,需在合併前修正。

核心功能(選單項目切換)可正常運作,登錄機碼讀寫邏輯無明顯錯誤,但 PR 說明宣稱的 NVDA+Shift+A 快捷鍵因缺少 @script 裝飾器而完全失效,屬於功能性缺失,需在合併前補上裝飾器。加上先前評論中尚未修正的問題(CreateKeyEx、靜默例外、重複程式碼),整體還需多一輪修正。

addon/appModules/line.pyscript_toggleQtAccessible 缺少 @script 裝飾器與 gesture 宣告。

Important Files Changed

Filename Overview
addon/appModules/line.py 新增 Qt 無障礙環境變數的讀寫輔助函式與 script_toggleQtAccessible,但後者缺少 @script 裝飾器,導致 PR 說明中宣稱的 NVDA+Shift+A 快捷鍵無法運作。
addon/globalPlugins/lineDesktopHelper.py 新增 Qt 無障礙選單項目與事件處理函式,當 LINE 執行中時委派至 AppModule,未執行時直接操作登錄機碼,邏輯正確;_isQtAccessibleSet 的最終 except 未記錄日誌(已於先前評論中提及)。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[使用者觸發切換] --> B{觸發來源}
    B -->|選單項目| C[GlobalPlugin._onToggleQtAccessible]
    B -->|鍵盤快捷鍵| D[❌ @script 裝飾器缺失\nNVDA+Shift+A 無效]
    C --> E[wx.CallAfter → _doToggleQtAccessible]
    E --> F{LINE 是否執行中?}
    F -->|是| G[委派至 AppModule.script_toggleQtAccessible]
    F -->|否| H[直接呼叫 GlobalPlugin._isQtAccessibleSet / _setQtAccessible]
    G --> I[_isQtAccessibleSet → HKCU\\Environment]
    G --> J[_setQtAccessible → winreg.OpenKey / SetValueEx / DeleteValue]
    H --> I
    H --> J
    J --> K[SendMessageTimeoutW WM_SETTINGCHANGE 廣播]
    K --> L[ui.message 通知使用者]
Loading

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
This is a comment left during a code review.
Path: addon/appModules/line.py
Line: 6087-6099

Comment:
**缺少 `@script` 裝飾器,快捷鍵無法運作**

`script_toggleQtAccessible` 雖然遵循 NVDA 的 `script_*` 命名慣例,但完全缺少 `@script` 裝飾器與 `gesture` 宣告。如此一來,NVDA 不會將任何鍵盤手勢綁定到此函式,使用者無論按下 `NVDA+Shift+A` 或其他任何組合鍵,都不會有任何反應。

PR 說明明確列出「**Keyboard shortcut: NVDA+Shift+A to toggle the setting**」,但搜尋整個程式碼庫確認此手勢並未被宣告於任何地方。

對照同一檔案內其他腳本(如 `script_reportLineInfo`),正確的寫法應為:

```suggestion
	@script(
		# Translators: Description of a script to toggle Qt accessibility env var
		description=_("切換 Qt 無障礙環境變數"),
		gesture="kb:NVDA+shift+a",
		category="LINE Desktop",
	)
	def script_toggleQtAccessible(self, gesture):
		"""Toggle QT_ACCESSIBILITY=1 user environment variable."""
		currentlySet = _isQtAccessibleSet()
		if currentlySet:
			if _setQtAccessible(False):
				ui.message(_("已移除 QT_ACCESSIBILITY 環境變數,重啟 LINE 後生效"))
			else:
				ui.message(_("移除 QT_ACCESSIBILITY 環境變數失敗"))
		else:
			if _setQtAccessible(True):
				ui.message(_("已設定 QT_ACCESSIBILITY=1,重啟 LINE 後生效"))
			else:
				ui.message(_("設定 QT_ACCESSIBILITY 環境變數失敗"))
```

補上裝飾器後,也建議在選單項目標籤中加入快捷鍵提示(`+ "\tNVDA+Shift+A"`),與其他選單項目保持一致。

How can I resolve this? If you propose a fix, please make it concise.

Reviews (3): Last reviewed commit: "Remove NVDA+Shift+A shortcut from Qt acc..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Provide a persistent user environment variable toggle (HKCU\Environment)
so LINE inherits QT_ACCESSIBILITY=1 on next launch. Accessible via
NVDA+Shift+A shortcut and the NVDA Tools > LINE Desktop menu. The
version info shortcut (NVDA+Shift+V) now also reports Qt accessibility
status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines +29 to +40
def _isQtAccessibleSet():
"""Check if QT_ACCESSIBILITY=1 is set in user environment variables."""
try:
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_READ
) as key:
value, _ = winreg.QueryValueEx(key, _QT_ACCESSIBILITY_ENV_NAME)
return str(value) == "1"
except FileNotFoundError:
return False
except Exception:
return False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 未記錄非預期例外

lineDesktopHelper.py_isQtAccessibleSet 在最後的 except Exception 中靜默忽略所有非 FileNotFoundError 的例外,沒有任何日誌紀錄,使除錯更加困難。相較之下,line.py 的同名函式有記錄 debugWarning

建議對齊兩個實作的行為:

Suggested change
def _isQtAccessibleSet():
"""Check if QT_ACCESSIBILITY=1 is set in user environment variables."""
try:
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_READ
) as key:
value, _ = winreg.QueryValueEx(key, _QT_ACCESSIBILITY_ENV_NAME)
return str(value) == "1"
except FileNotFoundError:
return False
except Exception:
return False
except Exception:
log.debugWarning("Failed to read QT_ACCESSIBILITY from registry", exc_info=True)
return False
Prompt To Fix With AI
This is a comment left during a code review.
Path: addon/globalPlugins/lineDesktopHelper.py
Line: 29-40

Comment:
**未記錄非預期例外**

`lineDesktopHelper.py``_isQtAccessibleSet` 在最後的 `except Exception` 中靜默忽略所有非 `FileNotFoundError` 的例外,沒有任何日誌紀錄,使除錯更加困難。相較之下,`line.py` 的同名函式有記錄 `debugWarning`。

建議對齊兩個實作的行為:

```suggestion
	except Exception:
		log.debugWarning("Failed to read QT_ACCESSIBILITY from registry", exc_info=True)
		return False
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Comment on lines +18 to +65
# ---------------------------------------------------------------------------
# Qt accessibility environment variable helpers (duplicated from line.py
# so the global plugin can toggle the setting even when LINE is not running)
# ---------------------------------------------------------------------------

_QT_ACCESSIBILITY_ENV_NAME = "QT_ACCESSIBILITY"
_HWND_BROADCAST = 0xFFFF
_WM_SETTINGCHANGE = 0x001A
_SMTO_ABORTIFHUNG = 0x0002


def _isQtAccessibleSet():
"""Check if QT_ACCESSIBILITY=1 is set in user environment variables."""
try:
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "Environment", 0, winreg.KEY_READ
) as key:
value, _ = winreg.QueryValueEx(key, _QT_ACCESSIBILITY_ENV_NAME)
return str(value) == "1"
except FileNotFoundError:
return False
except Exception:
return False


def _setQtAccessible(enable=True):
"""Set or remove QT_ACCESSIBILITY in user environment variables."""
try:
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "Environment", 0,
winreg.KEY_SET_VALUE | winreg.KEY_READ
) as key:
if enable:
winreg.SetValueEx(
key, _QT_ACCESSIBILITY_ENV_NAME, 0,
winreg.REG_SZ, "1"
)
else:
try:
winreg.DeleteValue(key, _QT_ACCESSIBILITY_ENV_NAME)
except FileNotFoundError:
pass
ctypes.windll.user32.SendMessageTimeoutW(
_HWND_BROADCAST, _WM_SETTINGCHANGE, 0,
"Environment", _SMTO_ABORTIFHUNG, 5000, None
)
return True
except Exception:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 輔助函式重複定義

_isQtAccessibleSet_setQtAccessible 及所有常數(_QT_ACCESSIBILITY_ENV_NAME_HWND_BROADCAST 等)都與 line.py 中的定義完全相同,程式碼注釋也坦承是「duplicated from line.py」。這造成維護負擔:若日後需修改邏輯(例如改用 CreateKeyEx 處理 key 不存在的邊緣案例),必須同步更新兩個地方。

建議將共用邏輯提取至 addon/appModules/_qtAccessibility.py(或 addon/lib/qtAccessibility.py),讓兩個模組都能 import 相同的實作,同時保留 GlobalPlugin 在 LINE 未執行時仍可作業的能力。

Prompt To Fix With AI
This is a comment left during a code review.
Path: addon/globalPlugins/lineDesktopHelper.py
Line: 18-65

Comment:
**輔助函式重複定義**

`_isQtAccessibleSet``_setQtAccessible` 及所有常數(`_QT_ACCESSIBILITY_ENV_NAME``_HWND_BROADCAST` 等)都與 `line.py` 中的定義完全相同,程式碼注釋也坦承是「duplicated from line.py」。這造成維護負擔:若日後需修改邏輯(例如改用 `CreateKeyEx` 處理 key 不存在的邊緣案例),必須同步更新兩個地方。

建議將共用邏輯提取至 `addon/appModules/_qtAccessibility.py`(或 `addon/lib/qtAccessibility.py`),讓兩個模組都能 import 相同的實作,同時保留 GlobalPlugin 在 LINE 未執行時仍可作業的能力。

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Comment on lines +119 to +134
Broadcasts WM_SETTINGCHANGE so new processes pick up the change.
Returns True on success, False on failure.
"""
try:
with winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "Environment", 0,
winreg.KEY_SET_VALUE | winreg.KEY_READ
) as key:
if enable:
winreg.SetValueEx(
key, _QT_ACCESSIBILITY_ENV_NAME, 0,
winreg.REG_SZ, "1"
)
log.info("QT_ACCESSIBILITY=1 set in user environment")
else:
try:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 HKCU\Environment 不存在時操作會靜默失敗

_setQtAccessible 使用 winreg.OpenKey 開啟已存在的機碼。若 HKCU\Environment 不存在(例如極度精簡的 Windows 環境或 Wine),函式會進入 except Exception 並回傳 False,使用者只會看到錯誤訊息,而不知道原因是 key 不存在。

建議改用 winreg.CreateKeyEx,它在 key 已存在時等同 OpenKey,在不存在時則自動建立:

with winreg.CreateKeyEx(
    winreg.HKEY_CURRENT_USER, "Environment", 0,
    winreg.KEY_SET_VALUE | winreg.KEY_READ
) as key:

這樣可同時處理 key 不存在與已存在的情況。此修改在 line.pylineDesktopHelper.py 兩處的 _setQtAccessible 都應套用。

Prompt To Fix With AI
This is a comment left during a code review.
Path: addon/appModules/line.py
Line: 119-134

Comment:
**`HKCU\Environment` 不存在時操作會靜默失敗**

`_setQtAccessible` 使用 `winreg.OpenKey` 開啟已存在的機碼。若 `HKCU\Environment` 不存在(例如極度精簡的 Windows 環境或 Wine),函式會進入 `except Exception` 並回傳 `False`,使用者只會看到錯誤訊息,而不知道原因是 key 不存在。

建議改用 `winreg.CreateKeyEx`,它在 key 已存在時等同 `OpenKey`,在不存在時則自動建立:

```python
with winreg.CreateKeyEx(
    winreg.HKEY_CURRENT_USER, "Environment", 0,
    winreg.KEY_SET_VALUE | winreg.KEY_READ
) as key:
```

這樣可同時處理 key 不存在與已存在的情況。此修改在 `line.py``lineDesktopHelper.py` 兩處的 `_setQtAccessible` 都應套用。

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Keep the feature accessible only via the NVDA Tools > LINE Desktop menu
to avoid conflicting with existing keyboard shortcuts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@keyang556
Copy link
Copy Markdown
Owner Author

@greptileai nvda+shift+a快速鍵需要移除,只保留工具切換,避免快速鍵衝突

Comment on lines +6087 to +6099
def script_toggleQtAccessible(self, gesture):
"""Toggle QT_ACCESSIBILITY=1 user environment variable."""
currentlySet = _isQtAccessibleSet()
if currentlySet:
if _setQtAccessible(False):
ui.message(_("已移除 QT_ACCESSIBILITY 環境變數,重啟 LINE 後生效"))
else:
ui.message(_("移除 QT_ACCESSIBILITY 環境變數失敗"))
else:
if _setQtAccessible(True):
ui.message(_("已設定 QT_ACCESSIBILITY=1,重啟 LINE 後生效"))
else:
ui.message(_("設定 QT_ACCESSIBILITY 環境變數失敗"))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 缺少 @script 裝飾器,快捷鍵無法運作

script_toggleQtAccessible 雖然遵循 NVDA 的 script_* 命名慣例,但完全缺少 @script 裝飾器與 gesture 宣告。如此一來,NVDA 不會將任何鍵盤手勢綁定到此函式,使用者無論按下 NVDA+Shift+A 或其他任何組合鍵,都不會有任何反應。

PR 說明明確列出「Keyboard shortcut: NVDA+Shift+A to toggle the setting」,但搜尋整個程式碼庫確認此手勢並未被宣告於任何地方。

對照同一檔案內其他腳本(如 script_reportLineInfo),正確的寫法應為:

Suggested change
def script_toggleQtAccessible(self, gesture):
"""Toggle QT_ACCESSIBILITY=1 user environment variable."""
currentlySet = _isQtAccessibleSet()
if currentlySet:
if _setQtAccessible(False):
ui.message(_("已移除 QT_ACCESSIBILITY 環境變數,重啟 LINE 後生效"))
else:
ui.message(_("移除 QT_ACCESSIBILITY 環境變數失敗"))
else:
if _setQtAccessible(True):
ui.message(_("已設定 QT_ACCESSIBILITY=1,重啟 LINE 後生效"))
else:
ui.message(_("設定 QT_ACCESSIBILITY 環境變數失敗"))
@script(
# Translators: Description of a script to toggle Qt accessibility env var
description=_("切換 Qt 無障礙環境變數"),
gesture="kb:NVDA+shift+a",
category="LINE Desktop",
)
def script_toggleQtAccessible(self, gesture):
"""Toggle QT_ACCESSIBILITY=1 user environment variable."""
currentlySet = _isQtAccessibleSet()
if currentlySet:
if _setQtAccessible(False):
ui.message(_("已移除 QT_ACCESSIBILITY 環境變數,重啟 LINE 後生效"))
else:
ui.message(_("移除 QT_ACCESSIBILITY 環境變數失敗"))
else:
if _setQtAccessible(True):
ui.message(_("已設定 QT_ACCESSIBILITY=1,重啟 LINE 後生效"))
else:
ui.message(_("設定 QT_ACCESSIBILITY 環境變數失敗"))

補上裝飾器後,也建議在選單項目標籤中加入快捷鍵提示(+ "\tNVDA+Shift+A"),與其他選單項目保持一致。

Prompt To Fix With AI
This is a comment left during a code review.
Path: addon/appModules/line.py
Line: 6087-6099

Comment:
**缺少 `@script` 裝飾器,快捷鍵無法運作**

`script_toggleQtAccessible` 雖然遵循 NVDA 的 `script_*` 命名慣例,但完全缺少 `@script` 裝飾器與 `gesture` 宣告。如此一來,NVDA 不會將任何鍵盤手勢綁定到此函式,使用者無論按下 `NVDA+Shift+A` 或其他任何組合鍵,都不會有任何反應。

PR 說明明確列出「**Keyboard shortcut: NVDA+Shift+A to toggle the setting**」,但搜尋整個程式碼庫確認此手勢並未被宣告於任何地方。

對照同一檔案內其他腳本(如 `script_reportLineInfo`),正確的寫法應為:

```suggestion
	@script(
		# Translators: Description of a script to toggle Qt accessibility env var
		description=_("切換 Qt 無障礙環境變數"),
		gesture="kb:NVDA+shift+a",
		category="LINE Desktop",
	)
	def script_toggleQtAccessible(self, gesture):
		"""Toggle QT_ACCESSIBILITY=1 user environment variable."""
		currentlySet = _isQtAccessibleSet()
		if currentlySet:
			if _setQtAccessible(False):
				ui.message(_("已移除 QT_ACCESSIBILITY 環境變數,重啟 LINE 後生效"))
			else:
				ui.message(_("移除 QT_ACCESSIBILITY 環境變數失敗"))
		else:
			if _setQtAccessible(True):
				ui.message(_("已設定 QT_ACCESSIBILITY=1,重啟 LINE 後生效"))
			else:
				ui.message(_("設定 QT_ACCESSIBILITY 環境變數失敗"))
```

補上裝飾器後,也建議在選單項目標籤中加入快捷鍵提示(`+ "\tNVDA+Shift+A"`),與其他選單項目保持一致。

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

@keyang556
Copy link
Copy Markdown
Owner Author

這個應該不需要快速鍵,很少人常常改這個

@keyang556 keyang556 merged commit 8e50ba4 into main Apr 13, 2026
2 of 3 checks passed
@keyang556 keyang556 deleted the claude/friendly-leakey branch April 15, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant