以下の内容はhttps://www.bioerrorlog.work/entry/disable-clamshell-macより取得しました。


M2 MacBookを閉じたらスリープさせる方法/クラムシェルモードを無効化する方法

M2 MacBookでクラムシェルモードを無効化する方法のメモです。

はじめに

MacBookを外部ディスプレイ(+電源)に繋いだまま蓋を閉じると、スリープモードにはならず、外部ディスプレイが起動したまま作業が続行可能になるクラムシェルモードに入ります。

このクラムシェルモードを無効化したかったのですが、調べてみるとどうやらmacOSの機能としては提供されていないようです。(Intel Macの頃は設定コマンドがあった模様)

このクラムシェルモードを無効化する方法、つまりM2 MacBookを閉じたら外部ディスプレイに繋いでいてもスリープさせる簡単な方法を見つけたのでまとめます。

# 作業環境
M2 MacBook Air
macOS Sonoma 14.7.3

The English translation of this post is here.

クラムシェルモードを無効化する方法

noclamshell を使う

noclamshellというオープンソースの小さなスクリプトを使うことで、クラムシェルモードを無効化することができます。

github.com

このnoclamshellは、外部ツールという程の複雑なものではなく、たった20行ほどのミニマムなスクリプトです。

ターミナルを起動して下記のコマンドを実行することで、noclamshellをインストールできます:

brew install pirj/noclamshell/noclamshell
brew services start noclamshell

無事このコマンドが実行できれば完了です。 MacBookを閉じるとクラムシェルモードの代わりにスリープモードに入るようになります (私の場合閉じてから1秒ほどでスリープに入ります)。

私が求めていた挙動が実現できました。 簡単ですね。

補足: noclamshell の仕組みを理解する

このnoclamshellは20行の小さなスクリプトです。 どんな処理を行なっているのか見てみましょう。

#!/usr/bin/env bash

LID_CLOSED=$(ioreg -r -k AppleClamshellState | grep AppleClamshellState | grep Yes)
if [ "$LID_CLOSED" ]; then
  EXTERNAL_DISPLAY_CONNECTED=$(pmset -g powerstate | grep AppleDisplay | grep USEABLE)
  if [ "$EXTERNAL_DISPLAY_CONNECTED" ]; then
    AWAKE=$(pmset -g powerstate | grep IODisplayWrangler | grep USEABLE)
    if [ "$AWAKE" ]; then
      pmset sleepnow
    fi
  fi

  NUM_DEVICE_PROXY=$(pmset -g powerstate | grep -c DCPDPDeviceProxy)
  NUM_SERVICE_PROXY=$(pmset -g powerstate | grep -c DCPDPServiceProxy)
  ARM_AWAKE=$(( 0 < NUM_DEVICE_PROXY && NUM_DEVICE_PROXY < 4 ||
        0 < NUM_SERVICE_PROXY && NUM_SERVICE_PROXY < 4 ))
  if [ "$ARM_AWAKE" ]; then
    pmset sleepnow
  fi
fi

全体としては、PCの蓋が閉じている、かつシステムが起動状態であればスリープさせる、という処理を、Intel MacとApple Silicon Macともに行なっています。

各処理を個別に見てみましょう。

LID_CLOSED=$(ioreg -r -k AppleClamshellState | grep AppleClamshellState | grep Yes)
if [ "$LID_CLOSED" ]; then

まずここでPCの蓋が閉じているかを検知します。 もしPCの蓋が閉じていれば後続の処理に進み、もし空いていれば何もしません。

その後は、Intel Mac用とApple Silicon Mac用で別々の処理が用意されています。

Intel Mac用の処理はこちら:

  EXTERNAL_DISPLAY_CONNECTED=$(pmset -g powerstate | grep AppleDisplay | grep USEABLE)
  if [ "$EXTERNAL_DISPLAY_CONNECTED" ]; then
    AWAKE=$(pmset -g powerstate | grep IODisplayWrangler | grep USEABLE)
    if [ "$AWAKE" ]; then
      pmset sleepnow
    fi
  fi

外部ディスプレイが接続されている、かつシステムが起動状態であればスリープさせる、というシンプルな処理を行なっています。

一方、Apple Silicon Mac用の処理はこちら:

  NUM_DEVICE_PROXY=$(pmset -g powerstate | grep -c DCPDPDeviceProxy)
  NUM_SERVICE_PROXY=$(pmset -g powerstate | grep -c DCPDPServiceProxy)
  ARM_AWAKE=$(( 0 < NUM_DEVICE_PROXY && NUM_DEVICE_PROXY < 4 ||
        0 < NUM_SERVICE_PROXY && NUM_SERVICE_PROXY < 4 ))
  if [ "$ARM_AWAKE" ]; then
    pmset sleepnow
  fi

デバイスプロキシとサービスプロキシの数値をベースに、システムが起動状態かどうかを判定しています。 起動状態であればスリープに入れます。

この判定方法については議論がissueに残っていますので、気になる方はそちらをご覧ください。


あとはこのスクリプトを、下記のインストールコマンドでインストール&バックグラウンドプロセスとして起動して使います。

brew install pirj/noclamshell/noclamshell # スクリプトをダウンロード
brew services start noclamshell # バックグラウンドプロセスとして起動

補足: noclamshell をアンインストールする

noclamshellをアンインストールしたいときは、ターミナルで下記コマンドを実行してください。

brew services stop noclamshell
brew uninstall pirj/noclamshell/noclamshell

設定されていたバックグラウンドプロセスが停止し、noclamshellがアンインストールされます。

おわりに

以上、MacBookで蓋を閉じたらスリープさせる方法/クラムシェルモードを無効化する方法を整理しました。

大袈裟な外部ツールを入れることなく、簡単なスクリプトを利用することで実現できたのでよかったです。

どなたかの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

参考




以上の内容はhttps://www.bioerrorlog.work/entry/disable-clamshell-macより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14