commit 1e86958277bfb5d4cf6004caf6970884bf1a8c70 Author: Hermes Agent Date: Wed Sep 16 15:26:14 2026 +0200 Initial import: Black Screen Dim (Pygame + PyInstaller) Imported from matebook D:\BS (2026-03-11). Source only (no venv/build/dist). Added requirements.txt, .gitignore, README.md, IDEA.md. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..405b940 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Python +__pycache__/ +*.py[cod] +*.spec~ + +# Virtual env +venv/ +.venv/ + +# PyInstaller build artifacts +build/ +dist/ + +# OS +.DS_Store +Thumbs.db diff --git a/Black Screen Dim.spec b/Black Screen Dim.spec new file mode 100644 index 0000000..3cc3add --- /dev/null +++ b/Black Screen Dim.spec @@ -0,0 +1,39 @@ +# -*- mode: python ; coding: utf-8 -*- + + +a = Analysis( + ['black_screen_dim.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='Black Screen Dim', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=False, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon=['icon.ico'], +) diff --git a/IDEA.MD b/IDEA.MD new file mode 100644 index 0000000..f85cff5 --- /dev/null +++ b/IDEA.MD @@ -0,0 +1,22 @@ +# Black Screen Dim + +## Что это +Windows-приложение (Python + Pygame), которое при запуске: +- гасит яркость монитора до 0 через `screen-brightness-control`; +- показывает чёрный безрамочный полноэкранный экран (курсор скрыт); +- по ESC возвращает прежнюю яркость и курсор, корректно выходит. + +Собирается в `.exe` через PyInstaller (`Black Screen Dim.spec`), консоль отключена. + +## Источник +Скопировано с matebook (Windows) из `D:\BS` 2026-03-11. Исходники без `venv/build/dist`. + +## Цель доработки +См. план в переписке / README. Вектор: горячие клавиши, таймер авто-выхлопа, +несколько уровней затемнения (не только 0), трей-иконка, мультимонитор. + +## Стек +- Python 3.11 +- pygame (графика/окно) +- screen-brightness-control (яркость — только Windows) +- PyInstaller (сборка exe) diff --git a/README.md b/README.md new file mode 100644 index 0000000..12b9ca0 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Black Screen Dim + +Маленькая утилита для Windows: при запуске гасит экран до чёрного (яркость → 0), +показывает чёрный безрамочный полноэкран, скрывает курсор. По `ESC` — выход, +яркость и курсор возвращаются. + +## Запуск из исходников (Windows) +```bat +python -m venv venv +venv\Scripts\activate +pip install -r requirements.txt +python black_screen_dim.py +``` + +## Сборка в .exe +```bat +pip install pyinstaller +pyinstaller "Black Screen Dim.spec" +``` +Готовый exe — в `dist\Black Screen Dim\`. + +## Зависимости +- `pygame` — окно и отрисовка +- `screen-brightness-control` — управление яркостью (только Windows) + +> Управление яркостью работает только на Windows. На других ОС приложение +> просто покажет чёрный экран без изменения яркости. diff --git a/black_screen_dim.py b/black_screen_dim.py new file mode 100644 index 0000000..3d53bef --- /dev/null +++ b/black_screen_dim.py @@ -0,0 +1,90 @@ +import pygame +import sys +import os +import time +import screen_brightness_control as sbc + + +def get_current_brightness(): + try: + current = sbc.get_brightness() + except Exception: + return None + + if isinstance(current, list): + if not current: + return None + return current[0] + return current + + +def set_brightness_safe(value): + try: + sbc.set_brightness(int(value)) + return True + except Exception: + return False + + +def main(): + # --- яркость: читаем текущую и ставим минимум --- + original_brightness = get_current_brightness() + if original_brightness is not None: + set_brightness_safe(0) + + # --- чёрный экран --- + pygame.init() + + info = pygame.display.Info() + width, height = info.current_w, info.current_h + + os.environ["SDL_VIDEO_WINDOW_POS"] = "0,0" + screen = pygame.display.set_mode((width, height), pygame.NOFRAME) + pygame.display.set_caption("Black Screen Dim") + + try: + icon = pygame.image.load("icon.ico") + pygame.display.set_icon(icon) + except Exception: + pass + + pygame.mouse.set_visible(False) + + font = pygame.font.SysFont(None, 48) + hint_text = "ESC - exit" + text_surf = font.render(hint_text, True, (255, 255, 255)) + text_rect = text_surf.get_rect(center=(width // 2, height // 2)) + show_hint_until = time.time() + 1.0 # ~1 секунда + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: + running = False + + screen.fill((0, 0, 0)) + if time.time() < show_hint_until: + screen.blit(text_surf, text_rect) + + pygame.display.flip() + + # --- выходим: пытаемся вернуть яркость и курсор, без вылета --- + if original_brightness is not None: + try: + set_brightness_safe(original_brightness) + except Exception: + pass + + try: + pygame.mouse.set_visible(True) + except Exception: + pass + + pygame.quit() + sys.exit() + + +if __name__ == "__main__": + main() diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..3530b4b Binary files /dev/null and b/icon.ico differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..89fa711 Binary files /dev/null and b/icon.png differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..27bf289 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pygame>=2.5.0 +screen-brightness-control>=0.22.0