Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions winrandr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"set_auto",
"set_brightness",
"set_gamma",
"set_night_mode",
"set_noprimary",
"set_off",
"set_position",
Expand All @@ -42,6 +43,7 @@
set_auto,
set_brightness,
set_gamma,
set_night_mode,
set_noprimary,
set_off,
set_position,
Expand Down
2 changes: 2 additions & 0 deletions winrandr/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"get_display_props",
"list_displays",
"list_providers",
"set_night_mode",
"set_position_relative",
]

Expand All @@ -15,6 +16,7 @@
identify_display,
set_brightness,
set_gamma,
set_night_mode,
)
from winrandr.features.layout import ( # noqa: F401
set_noprimary,
Expand Down
7 changes: 6 additions & 1 deletion winrandr/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
_handle_identify,
_handle_listmodes,
_handle_mode,
_handle_night_mode,
_handle_off,
_handle_pos,
_handle_preferred,
Expand Down Expand Up @@ -164,6 +165,8 @@ def _handle_global_ops(args: Namespace) -> None:
args.output = short
if args.brightness is not None:
_handle_brightness(args, t.name)
if args.night_mode is not None:
_handle_night_mode(args, t.name)
if args.gamma is not None:
_handle_gamma(args, t.name)

Expand All @@ -186,6 +189,8 @@ def _dispatch_display_ops(args: Namespace, device_name: str) -> None: # noqa: C
_handle_off(args, device_name)
if args.brightness is not None:
_handle_brightness(args, device_name)
if args.night_mode is not None:
_handle_night_mode(args, device_name)
if args.reflect:
_handle_reflect(args, device_name)
if args.gamma:
Expand Down Expand Up @@ -235,7 +240,7 @@ def main() -> None: # noqa: C901 # 调度型函数,分支复杂度本质
return

# 全局操作:亮度/伽马可不带 --output,应用到所有已连接显示器
_global_only_attrs = frozenset({"brightness", "gamma"})
_global_only_attrs = frozenset({"brightness", "gamma", "night_mode"})
if not args.output:
mod_attrs = {a for a in _MOD_OP_ATTRS if getattr(args, a, None)}
if mod_attrs and mod_attrs.issubset(_global_only_attrs):
Expand Down
1 change: 1 addition & 0 deletions winrandr/cli/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def _sort_key(n: str) -> tuple[int, int | str]:
"preferred",
"off",
"brightness",
"night_mode",
"reflect",
"gamma",
"left_of",
Expand Down
17 changes: 17 additions & 0 deletions winrandr/cli/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
set_auto,
set_brightness,
set_gamma,
set_night_mode,
set_off,
set_position,
set_position_relative,
Expand Down Expand Up @@ -123,6 +124,22 @@ def _handle_brightness(args: Namespace, dn: str) -> None:
_msg(args, f"已将 {args.output} 亮度设为 {args.brightness}")


def _handle_night_mode(args: Namespace, dn: str) -> None:
val = args.night_mode
if val in ("light", "medium", "heavy"):
strength = {"light": 0.2, "medium": 0.5, "heavy": 0.8}[val]
else:
try:
strength = float(val)
except (ValueError, TypeError):
_fail("--night-mode 参数无效", ["使用 light(20%)/medium(50%)/heavy(80%) 或数值 0.0-1.0"])
if not 0.0 <= strength <= 1.0:
_fail("夜间模式强度必须在 0.0-1.0 之间")
if not args.dry_run and not set_night_mode(dn, strength):
_fail("设置夜间模式失败", ["某些驱动或远程桌面环境不支持伽马校正", "使用 --verbose 查看详细日志"])
_msg(args, f"已将 {args.output} 的蓝光强度减弱 {int(strength * 100)}%")


def _handle_reflect(args: Namespace, dn: str) -> None:
if args.reflect in ("x", "y"):
_fail(f"单轴镜像翻转(-{args.reflect})在 Windows 上无标准 API 支持")
Expand Down
5 changes: 5 additions & 0 deletions winrandr/cli/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ def build_parser() -> argparse.ArgumentParser:

g_img = p.add_argument_group("图像调节")
g_img.add_argument("--brightness", type=float, help="亮度值(0.1-2.0,1.0 为正常)")
g_img.add_argument(
"--night-mode",
metavar="light|medium|heavy|0.0-1.0",
help="夜间模式:减少蓝光(预设 light/medium/heavy 或数值)",
)
g_img.add_argument("--gamma", metavar="R:G:B", help="伽马校正(如 1.0:0.9:0.8)")
g_img.add_argument("--reflect", choices=["normal", "x", "y", "xy"], help="镜像翻转(仅 xy 支持)")
g_img.add_argument("-x", action="store_true", help=argparse.SUPPRESS)
Expand Down
19 changes: 19 additions & 0 deletions winrandr/features/gamma.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ def _modify(ramp: c_uint16) -> None:
return ok


def set_night_mode(device_name: str, strength: float) -> bool:
"""通过衰减蓝光设置夜间模式。

strength: 0.0-1.0,0 为无变化,1 为完全移除蓝光。
"""
if not 0.0 <= strength <= 1.0:
logger.error("夜间模式强度必须在 0.0-1.0 之间: %g", strength)
return False

def _modify(ramp: c_uint16) -> None:
for i in range(512, 768):
ramp[i] = max(0, min(65535, int(ramp[i] * (1.0 - strength))))

ok = _apply_gamma(device_name, _modify)
if ok:
logger.debug("设置 %s 夜间模式强度为 %.2f", device_name, strength)
return ok


def identify_display(device_name: str, duration: float = 2.0) -> bool:
"""通过闪烁屏幕帮助识别指定显示器(闪 3 次后恢复原状)。"""
try:
Expand Down
Loading