Chế độ Closed-Lid trên macOS, không cần kext

Đúng vậy — chế độ Closed-Lid trên Mac hoạt động mà không cần kernel extension. Đó là công tắc pmset disablesleep đã được Apple tài liệu hóa, chính là cơ chế đứng sau lệnh sudo pmset -a disablesleep 1 trong Terminal, chỉ khác là nó được giữ tự động thay vì bạn phải tự quản lý bằng tay. Bài này đi vào chi tiết: công tắc đó thực sự làm gì, caffeinate và chế độ clamshell màn hình ngoài của chính Apple đã cho bạn được gì miễn phí, chuyện gì có thể sai nếu bạn tự bật công tắc đó, và LidRun giữ nó như thế nào mà không để Mac bị kẹt thức mãi.
Vì sao đóng nắp máy lại khiến Mac ngủ ngay từ đầu
Đóng nắp MacBook mà không cắm gì khác vào, macOS sẽ ngủ chỉ trong vài giây. Đó là clamshell sleep — một cơ chế khác hẳn so với idle sleep thông thường. Cách chính thức Apple hỗ trợ để né việc này là chế độ clamshell màn hình ngoài: cắm một màn hình rời, giữ nguồn AC, và Mac sẽ chạy với nắp đóng vô thời hạn mà không cần bất kỳ phần mềm bên thứ ba nào — vì vẫn còn một màn hình để macOS tiếp tục điều khiển, nên việc đóng nắp không còn quan trọng nữa.
Không có màn hình ngoài, không công cụ giữ máy thức phổ biến nào chạm được vào ranh giới đó theo cách thông thường. caffeinate, Amphetamine, KeepingYouAwake, Lungo và Caffeine đều hoạt động bằng cách giữ một IOKit power assertion — IOPMAssertionCreateWithName, API chính thức cho việc "đừng idle-sleep". Điều đó là thật, và nó thực sự hiệu quả trong việc giữ màn hình hoặc toàn bộ Mac thức khi nắp đang mở. Nhưng một assertion chỉ chặn được idle sleep. Đóng nắp lại kích hoạt clamshell sleep ở tầng thấp hơn mà không assertion nào chặn được, bất kể app nào đang giữ nó — đó là ranh giới ở cấp hệ điều hành, không phải lỗ hổng của riêng công cụ nào.
Công tắc công khai, có tài liệu duy nhất thực sự thay đổi được hành vi đóng nắp khi không có màn hình gắn ngoài là pmset disablesleep — một cài đặt quản lý nguồn ở cấp hệ thống, có sẵn ngay trong macOS.
Các lựa chọn miễn phí: chế độ clamshell của Apple, caffeinate, và pmset
Nếu bạn có sẵn một màn hình rời, hãy dùng nó. Cắm vào, giữ nguồn điện, rồi đóng nắp lại — đó chính là cách setup closed-lid thật sự, được Apple hỗ trợ: không cần phần mềm phụ, không cần mật khẩu admin, không có gì phải nhớ tắt lại. Đây là câu trả lời đúng cho một setup bàn làm việc cố định.


Không có màn hình rời? caffeinate là công cụ dòng lệnh có sẵn của Apple (man caffeinate). caffeinate -i chặn idle sleep, caffeinate -d chặn luôn cả display sleep, còn caffeinate -s giữ toàn bộ hệ thống thức khi đang cắm nguồn AC, miễn là tiến trình đó còn chạy. Nó thực sự hữu ích cho một script không nên bị idle-sleep — nhưng nó thừa hưởng đúng điểm mù clamshell-sleep giống mọi công cụ dựa trên assertion: đóng nắp mà không có màn hình gắn ngoài thì Mac vẫn ngủ bên dưới nó như thường.
Công tắc thực sự có tác dụng khi đóng nắp, không cần màn hình, chính là công tắc mà các app closed-lid tự động hóa: sudo pmset -a disablesleep 1 trong Terminal, kiểm tra bất cứ lúc nào bằng pmset -g | grep SleepDisabled, tắt lại bằng sudo pmset -a disablesleep 0. Nó đã có tài liệu, miễn phí, và sẵn có ngay trên Mac của bạn.
Hướng dẫn liên quanBáo thức trên Mac có kêu khi đóng nắp máy không?Điểm cần lưu ý: đây là cài đặt toàn cục, và nó không tự tắt
disablesleep không bị giới hạn trong phiên Terminal hay script của bạn — đó là một cờ (flag) tồn tại dai dẳng ở cấp hệ thống. Đặt nó thành 1 thì nó vẫn giữ nguyên là 1 dù bạn thoát app, đóng cửa sổ Terminal, hay phiên SSH đã kết thúc. Quên đặt lại, Mac sẽ thực sự không thể ngủ được cho đến khi có gì đó reset nó: bạn chạy lại lệnh, hoặc khởi động lại máy.
Đó chính là rủi ro thật mà mọi người nhắc đến khi thận trọng với các công cụ closed-lid — một chiếc laptop không thể ngủ được về mặt vật lý, nhét trong túi, không có gì theo dõi nhiệt độ hay tình trạng pin. Bản thân pmset không hề biết nhiệt độ SoC là bao nhiêu hay còn bao nhiêu pin. Nó chỉ giữ nguyên cài đặt cho đến khi được bảo làm khác đi.
Đó cũng chính là kiểu lỗi mà một lớp an toàn chống crash được tạo ra để bắt lại — vì một script hay app đặt cờ này rồi crash, bị force-quit, hoặc mất kết nối SSH đều để lại đúng cái cài đặt bị kẹt đó.
Cách chạy an toàn hơn nếu bạn tự làm bằng tay
Nếu bạn quen dùng Terminal và không muốn cài thêm app nào, hãy coi việc ghép cặp bật/tắt là điều không thể thương lượng. Đặt disablesleep thành 1 ngay trước khi chạy job, và đặt disablesleep 0 tương ứng trong một trap on EXIT ở đầu script để nó vẫn kích hoạt kể cả khi job chết giữa chừng.


Kiểm tra trạng thái trước khi tin tưởng nó — pmset -g | grep SleepDisabled hiện giá trị hiện tại chỉ trong một dòng. Đáng để chạy trước khi bạn đóng nắp, và chạy lại lần nữa khi bạn mở nắp ra.
Các quy tắc vật lý áp dụng bất kể công cụ nào đã bật công tắc: một bề mặt cứng, phẳng, thông thoáng, không bao giờ đặt trên giường hay nhét trong túi kín, và cắm nguồn điện cho bất cứ việc gì dài hơn một job ngắn. Nắp đóng lại làm hạn chế luồng khí trên mặt bàn phím, bất kể thứ gì đang giữ nó đóng.
LidRun nằm ở đâu trong chuyện này: vẫn công tắc đó, chỉ là được giữ tự động
Chế độ Closed-Lid của LidRun chính xác là công tắc pmset disablesleep đó — không kernel extension, không driver DriverKit giả lập màn hình. Điều khác biệt nằm ở lớp bọc quanh nó. LidRun ghép mỗi lần bật với một lần tắt tương ứng khi dừng, khi thoát, và lại một lần nữa khi mở lại app, nên cài đặt này không phụ thuộc vào việc bạn có nhớ hay không.


Với trường hợp crash mà bản thân pmset không thể tự lo được, LidRun ghi một file trạng thái "armed" nhỏ kèm heartbeat trong khi chế độ Closed-Lid đang hoạt động. Nếu app crash hoặc bị kill, lần khởi chạy tiếp theo sẽ thấy file đó vẫn ở trạng thái armed, nhận ra phiên trước chưa được dọn dẹp, và tự động reset disablesleep về 0 — đó là CrashGuard. Tuy nhiên nó chỉ kích hoạt vào lần khởi chạy kế tiếp: một phiên đã crash mà không ai mở lại LidRun sẽ để cài đặt đó bật mãi cho đến khi bạn mở lại, hoặc cho đến khi khởi động lại máy — cùng giới hạn mà lệnh thủ công gặp phải.
Xác thực admin là điều không thể tránh khỏi — thay đổi disablesleep cần quyền quản trị, giống hệt như khi làm từ Terminal. LidRun yêu cầu bạn phê duyệt một privileged helper một lần duy nhất trong lúc thiết lập; sau đó, chế độ Closed-Lid bật/tắt mà không cần nhập lại mật khẩu. Bỏ qua bước đó thì nó sẽ quay về hỏi mật khẩu admin mỗi lần dùng. Dù theo cách nào, không có gì chạy mà không có sự đồng ý rõ ràng của bạn.
Về mặt nhiệt độ, LidRun coi SoC là ở trạng thái nguy cấp khi đọc được 100°C trở lên, hoặc khi CPU bị throttle xuống còn 30% hiệu năng bình thường trở xuống — cái nào xảy ra trước. Nếu trạng thái nguy cấp đó kéo dài khoảng hai phút và bạn đã rời đi (không có thao tác gì trong năm phút) hoặc nắp máy đang đóng vật lý, LidRun sẽ leo thang từ việc thả assertion sang đẩy Mac vào giấc ngủ hẳn. Nếu bạn đang có mặt và nắp máy đang mở, máy sẽ không bao giờ bị ép ngủ chỉ vì lý do nhiệt — rào chắn đó tồn tại để một phiên làm việc đang diễn ra không bị giật mất khỏi tay bạn. Về pin cũng có một ngưỡng sàn tương ứng: ngưỡng pin nguy cấp mặc định là 5% và không thể đặt thấp hơn 4%, nên cái sàn an toàn đó không phải thứ bạn có thể vô tình tắt đi.
LidRun cũng kiểm tra xem bạn đã ở trong setup clamshell của chính Apple hay chưa — một màn hình ngoài, không phải màn hình tích hợp, đang thực sự điều khiển desktop — và coi đó là lý do chính đáng để thức lúc đóng nắp mà không cần bật công tắc riêng của nó chút nào. Và vì chế độ Closed-Lid cần thay đổi pmset ở cấp admin đó, nó không an toàn với sandbox của Mac App Store; thay vào đó LidRun phát hành dưới dạng DMG tải trực tiếp đã được notarize, nghĩa là vẫn được Apple quét, chỉ là không phân phối qua Store.
Triết lý đằng sau tất cả những điều này: agent còn chạy thì máy còn thức; agent xong việc hoặc không còn an toàn thì thả ra và để Mac ngủ. Chế độ Closed-Lid là tính năng Pro — gói miễn phí đi kèm một số lượng phiên closed-lid giới hạn để dùng thử, trước khi cần mở khóa Pro một lần.
So sánh với Amphetamine, KeepingYouAwake, Lungo và Caffeine
Đây đều là những app thanh menu bar chắc chắn, làm tốt — và với đúng công việc của chúng: giữ idle sleep hay display sleep, theo lịch, theo từng app, hoặc theo trigger, chúng làm việc đó tốt. Nếu điều bạn cần chỉ là "đừng làm tối màn hình lúc đang gọi video" hay "đừng idle-sleep khi tôi đang đọc", thì bất kỳ app nào trong số đó cũng là lựa chọn ổn, nhẹ hơn LidRun.
Điều mà không app nào trong số đó thay đổi được là ranh giới assertion-với-clamshell đã nói ở trên: một IOPMAssertion, dù được cấu hình thế nào, cũng không sống sót qua việc đóng nắp khi không có màn hình ngoài. Một vài công cụ trong số này có tài liệu riêng về tùy chọn closed-lid của họ, tách biệt khỏi assertion — đáng để đọc kỹ xem mỗi công cụ triển khai nó ra sao trước khi tin tưởng giao cho nó một job thật với nắp đóng, giống như bài này đã nói rõ phiên bản của LidRun là pmset disablesleep, không phải kext.
Khác biệt của LidRun không nằm ở công tắc — mà ở chỗ chế độ Closed-Lid là điều duy nhất nó làm với một lớp an toàn thật sự bọc quanh (bật/tắt ghép cặp, khôi phục sau crash, tự dừng theo nhiệt độ và pin), thay vì một danh sách tính năng giữ máy thức chung chung có gắn thêm tùy chọn closed-lid vào.
Những đánh đổi thẳng thắn trước khi bạn tin tưởng giao việc thật cho bất kỳ cách nào ở trên
Không công tắc phần mềm nào thay đổi được vật lý — pmset disablesleep, phiên bản của LidRun, hay một lệnh Terminal gõ tay đều có tác động y hệt nhau lên luồng khí: không gì cả. Nắp đóng làm hạn chế luồng khí trên mặt bàn phím, nên một job nặng chạy sau nắp đóng sẽ nóng hơn cùng job đó chạy với nắp mở. LidRun hiện cảnh báo nhiệt trước khi bạn bật chế độ này, để bạn chủ động chấp nhận đánh đổi đó, và bộ điều tiết nhiệt của nó theo dõi áp lực nhiệt tăng lên và có thể tự dừng phiên làm việc — điều đó giúp giảm rủi ro, chứ không làm cho nhiệt biến mất.
Vị trí đặt máy vẫn quan trọng hơn bất kỳ cài đặt nào: một bề mặt cứng, phẳng, thông thoáng, không bao giờ đặt trên giường hay nhét trong túi kín, và cắm nguồn điện cho bất cứ job closed-lid nào dài hơn một chút, để pin không bị hao thêm dưới áp lực nhiệt.
Và nếu điều bạn thực sự cần chỉ là giữ màn hình sáng — chứ không phải đóng nắp lại rồi đi mất — thì bạn không cần chế độ Closed-Lid chút nào. Một assertion giữ máy thức đơn thuần đã đủ làm việc đó, và bỏ qua hoàn toàn bước phê duyệt admin/helper. Hãy để dành chế độ Closed-Lid cho lúc bạn thực sự muốn đóng nắp lại.
LidRun giữ công việc của bạn chạy tiếp khi đóng nắp, với cơ chế bảo vệ pin và nhiệt tích hợp sẵn.
Đã có LidRun? Đọc hướng dẫn thiết lập →
Mới biết đến LidRun? Xem bảng giá →
Câu hỏi thường gặp
Không. Đó là công tắc pmset disablesleep đã có tài liệu — không kext, không trình giả lập màn hình DriverKit. Đó là cùng một công tắc có sẵn từ Terminal qua sudo pmset -a disablesleep 1, chỉ khác là được ghép cặp và đối soát tự động thay vì để bạn tự quản lý.
File heartbeat của CrashGuard sẽ bắt được điều đó: lần tới khi LidRun khởi chạy, nó sẽ thấy cài đặt vẫn đang ở trạng thái armed từ một phiên chưa được dọn dẹp, và reset disablesleep về 0. Tuy nhiên điều này chỉ xảy ra khi khởi chạy lại — nếu bạn không bao giờ mở lại app, hoặc không khởi động lại máy, Mac sẽ vẫn không thể ngủ được cho đến khi bạn làm vậy, cùng giới hạn mà một lệnh pmset gõ tay gặp phải.
Thay đổi pmset disablesleep thực sự cần quyền quản trị — đó là quy tắc của macOS, không phải lựa chọn của LidRun. LidRun yêu cầu bạn phê duyệt một privileged helper một lần; sau đó, chế độ Closed-Lid bật/tắt mà không cần nhập lại mật khẩu. Bỏ qua bước đó thì nó sẽ quay về hỏi mật khẩu mỗi lần.
Chế độ Closed-Lid cần thay đổi pmset disablesleep, mà điều này không an toàn với sandbox — sandbox của App Store sẽ không cho phép. Thay vào đó, LidRun phát hành dưới dạng DMG trực tiếp đã được notarize: vẫn được Apple quét, chỉ là không phân phối qua Store.
Được. caffeinate -s và pmset -a disablesleep 1 đều miễn phí, có sẵn trong macOS, và có tài liệu đầy đủ. caffeinate không thể chặn được clamshell sleep nếu không có màn hình ngoài; lệnh pmset thô thì làm được, nhưng đó là một cài đặt toàn cục tồn tại dai dẳng, không có khôi phục sau crash, không nhận biết nhiệt độ hay pin, nên việc ghép cặp bật với tắt hoàn toàn là trách nhiệm của bạn.
Thường là không cần. Cắm màn hình ngoài và giữ nguồn AC, chế độ clamshell của chính macOS đã giữ Mac chạy với nắp đóng mà không cần bất kỳ công tắc bên thứ ba nào. Chế độ Closed-Lid trong LidRun tồn tại cho trường hợp còn lại — không có màn hình ngoài, nắp đóng, nhưng vẫn muốn công việc tiếp tục chạy.
Đó là các tiện ích giữ máy thức đa dụng, xây dựng quanh IOKit power assertion — giỏi trong việc chặn idle hoặc display sleep theo lịch hay theo trigger. Chế độ Closed-Lid của LidRun là một phiên bản hẹp hơn, được bọc an toàn, cụ thể cho công tắc pmset disablesleep: bật/tắt ghép cặp, khôi phục sau crash, và tự dừng theo nhiệt độ và pin được xây dựng xung quanh nó, thay vì một danh sách tính năng giữ máy thức có gắn thêm closed-lid vào.