◉ Pulse
truth0530 avatar
#55 today ▼ 12

truth0530/lidguard

Swift Other

macOS 잠자기 방지 앱 — 뚜껑 닫아도/열어둘 때만 깨어 있기 (pmset · caffeinate)

Created Jul 29, 2026
Stars
7
Today
+1
Forks
0
Quality
90/100
Momentum
18

README

Fetched from GitHub on Oct 30, 2026, 11:07 PM UTC · README.md

View original on GitHub

Third-party content — Open Source Pulse is not the owner of this repository.

This README belongs to truth0530/lidguard and its contributors. We fetch it directly from the project’s public GitHub repository and display it for reference only. All text, code, images and trademarks remain the property of their respective authors. See the repository for its license terms. Copyright / takedown policy.

잠자기 방지 (lidguard) 1.5.4

뚜껑 닫힘/열림 유지 시간을 따로 두고, 시간이 끝나면 실제로 잠자기로 돌아갑니다.

동작

  • 뚜껑을 닫아도 켜 두기: 시작 즉시 pmset disablesleep 1. 뚜껑이 아직 열려 있어도 켭니다. Apple Silicon은 뚜껑을 닫는 순간 Clamshell Sleep이라, 닫힌 뒤에 켜면 이미 늦습니다. 끝나면 덮개가 닫혀 있으면 sleepnow. 관리자 권한이 필요해 같은 실행 파일의 감시 모드(lidguard --watchdog)가 root로 따로 돌며 시간을 지킵니다.
  • 뚜껑이 열렸을 때만 켜 두기: 앱 안에서 PreventUserIdleSystemSleep 요청(caffeinate -i와 같은 효과)을 잡습니다. 별도 프로그램이나 관리자 암호가 필요 없고, 앱이 꺼지면 macOS가 즉시 풀어 줍니다. 뚜껑을 닫으면 평소처럼 잠들고, 다시 열면 남은 시간 동안 이어집니다. 끔이면 화면·시스템 잠자기를 막지 않습니다.
  • 닫힘 유지가 켜져 있는 동안은 화면 자동꺼짐도 막힙니다. 창을 닫거나 종료하면 워치독이 disablesleep을 되돌립니다.
  • 앱을 강제 종료하거나 앱이 죽어도, 워치독이 앱이 사라진 것을 보고 약 1분 안에 잠자기를 되돌립니다.
  • 전원 연결 시만 (창 맨 위 오른쪽 체크박스): 배터리로 바뀌면 잠시 멈추고 잠자기를 macOS에 돌려줍니다. 뚜껑이 닫힌 채 어댑터를 뽑으면 바로 잠듭니다. 남은 시간 안에 다시 꽂으면 이어서 켜집니다. 두 모드 모두에 적용됩니다.
  • 뚜껑을 닫아도 켜 두기의 마지막 버튼은 체크하면 무한, 풀면 **6시간**입니다. 버튼 개수는 그대로입니다. 전원에 연결돼 있는 동안은 모니터 없이도 뚜껑을 닫고 계속 돌고, 어댑터를 뽑으면 잠듭니다. 감시 모드도 --closed-unlimited를 --ac-only 없이는 받지 않습니다.
  • macOS 과열 상태가 serious 이상이면 남은 시간과 관계없이 바로 해제합니다.
  • 배터리로 돌 때 잔량이 5% 이하가 되면 두 모드 모두 바로 해제하고, 뚜껑이 닫혀 있으면 잠듭니다. disablesleep이 켜져 있으면 macOS의 저전력 잠자기까지 막힐 수 있어서 둔 안전장치입니다. 충전 중에는 적용하지 않습니다.
  • 해제되면 창에 이유와 시각이 남습니다: 직접 해제, 시간 종료, 과열, 배터리 5% 이하.

설치와 업데이트

Releases에서 lidguard-macOS-arm64.zip을 받아 압축을 풀고 잠자기방지.app을 응용 프로그램 폴더로 옮깁니다. 처음 열 때 확인되지 않은 개발자 경고가 뜨면 Finder에서 앱을 우클릭해 열기를 누릅니다.

1.5.0부터 앱이 하루에 한 번 GitHub Releases를 확인하고, 새 버전이 있으면 업데이트할지 묻습니다. 메뉴의 업데이트 확인…으로 바로 확인할 수도 있습니다.

  • 잠자기 방지가 켜져 있는 동안에는 업데이트하지 않고, 해제된 뒤에 묻습니다.
  • 내려받은 압축 파일의 SHA-256이 릴리스의 .sha256 파일과 맞고, 번들 ID와 버전이 같고, codesign --verify를 통과해야 설치합니다.
  • 기존 앱은 교체가 끝날 때까지 백업해 두고, 복사에 실패하면 되돌립니다.
  • 다운로드 폴더에서 바로 실행 중이면(App Translocation) 응용 프로그램 폴더로 옮기라고 안내합니다.

1.1.0에서 남은 결함

  1. 워치독을 osascript+nohup으로 띄워, 관리자 스크립트가 끝나면 워치독이 같이 죽었다. 1시간 설정이 disablesleep 1만 남긴 채 끝나지 않았다.
  2. GUI NSTimer가 마감을 처리하려다 덮개 닫힌 동안 암호 창을 띄우거나, 세대 번호만 올리고 워치독을 꺼 disablesleep이 남았다.
  3. 닫힘 모드가 덮개를 연 뒤에도 disablesleep을 유지해 화면이 꺼지지 않았다.

1.2.0

  • 워치독은 python double-fork로 분리해 osascript와 수명을 끊는다.
  • 마감·덮개 상태 전환은 워치독만 처리한다. GUI 타이머는 표시용.
  • 창을 닫거나 종료하면 워치독 정지 파일을 쓰고, 남은 disablesleep만 관리자 권한으로 되돌린다.

1.4.0

  • 닫힘 유지를 덮개가 열린 동안에도 disablesleep으로 건다. 1.2.0이 화면 자동꺼짐을 지키려다 뚜껑 닫힘 잠을 막지 못했다.
  • 시작 스크립트가 워치독보다 먼저 disablesleep 1을 건다. 워치독이 안 뜨면 즉시 되돌린다.

1.5.0

  • 강제 종료 대비: 워치독을 --require-gui로 띄워, 앱이 사라지면 약 1분 안에 되돌린다.
  • 워치독이 되돌린 이유를 /tmp/lidguard_last_revert에 남기고, 창에 "해제됨 · 시간이 끝나 잠자기로 돌아갔습니다" 같은 상태를 보여준다. 해제 버튼을 누른 뒤에는 SleepDisabled가 실제로 0인지 다시 확인한다.
  • 닫힘 유지 중에는 "타이머가 끝나거나 과열되면 잠자기로 돌아갑니다." 안내를 보여준다.
  • GitHub Releases 기반 자동 업데이트.

1.5.1 가볍게

  • 화면 갱신(1초)에서 셸을 띄우던 확인을 모두 네이티브로 바꿨다. 뚜껑 상태와 SleepDisabled는 IOKit IOPMrootDomain에서, 프로세스 생존은 kill(pid, 0)(EPERM은 살아 있음)로 읽는다. 1초마다 실행하던 외부 프로그램 약 10개가 0개가 됐고, 뚜껑 상태 한 번 읽기가 약 19ms에서 약 17µs로 줄었다.
  • 창이 가려지거나 최소화되면 그리기와 레이아웃을 건너뛴다. 타이머에 여유(tolerance)를 줘 macOS가 깨우기를 묶을 수 있게 했다.
  • 열림 모드는 caffeinate와 감시 프로세스 대신 앱 안 IOPM 요청 하나로 끝난다.
  • 감시 스크립트(bash)와 daemonize.py(python)를 없애고, 같은 실행 파일의 Swift 감시 모드로 옮겼다. POSIX_SPAWN_SETSID로 관리자 셸과 수명을 끊는다. pmset은 켤 때 한 번, 끌 때 한 번만 실행하고, 과열은 ProcessInfo.thermalState로 판단한다. 2초 간격이라 해제가 빨라졌고, SIGTERM을 받아도 잠자기를 되돌린다. 같은 조건(10초, 1초 간격)에서 CPU 시간 0.47초→0.04초, pmset 실행 22회→2회.
  • 강제 종료 감지는 앱 이름(pgrep) 대신 앱 PID로 한다.
  • 전원 연결 중일 때만 옵션: 감시 모드 --ac-only, 전원 상태는 IOPSGetProvidingPowerSourceType(약 80µs)로 읽는다.
  • 업데이트 확인은 임시(ephemeral) 네트워크 세션을 쓰고 끝나면 닫는다. 빌드는 -dead_strip과 strip -x.

1.5.2

  • 배터리 5% 이하(배터리 사용 중)면 두 모드 모두 해제. 잔량은 IOPSGetPowerSourceDescription의 InternalBattery에서 읽는다. 감시 모드는 battery-low 이유를 남긴다.
  • 전원 연결 중일 때만 체크박스를 창 오른쪽 위로 옮기고, 켜면 닫힘 모드에 무한(감시 모드 --closed-unlimited, --ac-only 필수)을 추가했다.

1.5.3

  • 레이아웃 정리: 두 모드 제목은 왼쪽에 고정하고, 전원 연결 시만은 그보다 한 단계 위 별도 줄에 오른쪽 정렬로 두었다. 동작 중에는 비활성으로만 바뀌어 레이아웃이 움직이지 않는다.

  • 뚜껑 닫힘의 마지막 버튼은 체크박스에 따라 무한 ↔ 6시간으로 이름만 바뀐다(7개 유지).

  • 안내 문구를 줄였다. 대기 화면 "화면 자동꺼짐도 함께 막힙니다", 배터리 일시정지 "배터리 사용 중 · 전원을 연결하면 다시 켜집니다".

  • 상태 줄 자리를 항상 한 줄 비워 둬, 메시지가 나타나거나 사라질 때 창 높이가 출렁이지 않는다.

  • 상태 한 줄: 창 맨 아래에 전원/배터리 %, 발열(macOS 과열 단계), CPU %, 메모리 여유 %(커널 kern.memorystatus_level, 색은 macOS 메모리 압력)를 보여 준다. 배터리·발열·메모리는 macOS가 변화를 알려 줄 때만 갱신하고, CPU는 창이 보일 때만 1초마다 한 번 읽는다. 주의가 필요하면 그 항목만 주황·빨강으로 바뀐다.

  • 항목을 클릭하면 배터리는 시스템 설정의 배터리 화면, 나머지는 활성 상태 보기를 연다. 프로세스 목록·그래프·기록은 이 앱이 들고 있지 않는다.

1.5.4

  • 메모리를 메모리 여유 32%처럼 숫자로 표시하고, 상태 한 줄을 창 맨 아래로 옮겼다.

개발

bash scripts/build.sh
bash tests/test_watchdog.sh   # 가짜 pmset·뚜껑·과열·전원으로 감시 모드 23가지 시나리오
bash tests/test_native.sh     # 실제 Mac에서 IOKit·kill·IOPM 요청·호출 비용 확인
bash scripts/release.sh [노트파일]   # Info.plist 버전으로 v태그 릴리스, zip + sha256 업로드
Rendered by GitHub from the repository’s README. Scroll to read the full file.
First trending

Jul 30, 2026

first spotted on the list

Best rank

#45

highest position reached

Appearances

2

times on the trending list

Quality score

90

out of 100

Momentum

18

trend strength indicator

Star velocity

0.08

stars per day since creation

Activity — last 60 days

daily counts, collected every 6 hours
  • Stars
  • Forks
  • Merged PRs
  • Issues
  • Closed issues

Collecting activity data since launch — check back in a few days.

Star history

total stars per snapshot
5678truth0530/lidguard · Jul 30, 2 AM UTC: 6 starstruth0530/lidguard · Jul 30, 8 AM UTC: 7 stars2:39 AM5:36 AM8:32 AM

Rank history

position on trending · lower is better
#1#44#46#48#50#52#54#56Jul 30, 2 AM UTC: rank #45Jul 30, 8 AM UTC: rank #552:39 AM5:36 AM8:32 AM

3D card for your website

Live HTML card with a glass surface and pointer tilt. Paste the iframe on any website.

<iframe src="https://www.notionpulse.cc/embed/truth0530/lidguard" width="420" height="240" style="border:0;max-width:100%;background:transparent" loading="lazy" title="truth0530/lidguard — trending on Open Source Pulse"></iframe>

Stars badge

Show current stars in your README or profile. Auto-updates every 6 hours.

truth0530/lidguard stars badge
Markdown
[![truth0530/lidguard](https://www.notionpulse.cc/api/badge/truth0530/lidguard.svg)](https://www.notionpulse.cc/repo/truth0530/lidguard)
HTML
<a href="https://www.notionpulse.cc/repo/truth0530/lidguard"><img src="https://www.notionpulse.cc/api/badge/truth0530/lidguard.svg" alt="truth0530/lidguard stars badge" /></a>

Repository of the Day

#45 Repository of the Day

Repository of the Week

#45 Repository of the Week

Repository of the Month

#45 Repository of the Month