MacBookのRetinaディスプレイを縦2880pxにした壮観な眺め

以前の日記「Retinaよりも大切なもの」でも書いた「Retinaディスプレイを縦長に使う自由が欲しい」という欲求は、なんとOSX標準の機能で簡単に実現できてしまうのであった!

システム環境設定を起動(すでに起動している時は一旦終了してから)して、commandキーとoptionキーを押しながら、「ディスプレイ」をクリック。すると、いつもは見えない回転という設定が現れるのだ!

f:id:zariganitosh:20130307103004p:image:w450

  • MacBook Pro Retina15 OSX 10.8.2の環境において、「回転」の設定項目が表示された。
  • 初代 MacBook OSX10.6、2008late MacBook OSX10.6の環境では、いくら試しても「回転」の設定項目は表示されなかった...。
  • ハードウェアやOS環境によって「回転」できるマシン、できないマシンがあるのだと思う。

そのポップアップボタンをクリックすると、回転させる角度が表示される。回転させる方向は反時計回りだ。左サイドが上になるように回転させた方が電源・Thunderbolt・USB・ヘッドフォンが苦労なく活用できて便利そうと感じたので「90°」を選択。

f:id:zariganitosh:20130307103006p:image:w450

暫しのブルー画面を経過して、ディスプレイは左側をトップにしたポートレート(縦長)表示になるのだ!「元に戻す」か「確認」を問われているので「確認」を押そうと思ったが、マウスカーソルを動かすのが難しい...。画面はポートレート表示になったが、トラックパッドの反応は以前と変わらないのだ。上に動かすと右に移動し、左に動かすと上に移動する。混乱する...。

f:id:zariganitosh:20130307110000p:image:w450

そこで、キーボードからtabキーで「確認」を選択して、スペースキーで「確認」ボタンを押してみる。これで継続的に縦2880pxのポートレート環境になった。ワクワクしながらMacBookを本のように立てて、さっそく試してみた。ちなみに、トラックパッドの操作は混乱するが、マウスを接続すると問題なく操作できるのであった。
f:id:zariganitosh:20130307132553p:image:h450

縦2880pxの世界

  • ポートレート表示にすると、見た目の解像度を変更するRetina表示はできなくなる。
  • 常に、2880×1800の固定解像度で表示されるのだ。(Retina以前と同じ仕様)
  • ちなみに、180°回転させた上下逆のランドスケープ表示では、Retina表示が指定可能だった。
  • 自分の使用環境では、机の上にそのまま立てると、視線が遠い下側が見づらくなってしまった。
  • 12cmくらいの台の上に置くと、上端・下端までの視線の距離が等しくなり、見やすくなった。
  • 適当な台になるものを探してみたところ、amazonの箱の上に置くと、ちょうどいい感じだった。
  • ザリガニが見ていたのページは、サイドバー「合わせて読みたい」の位置まで一覧できる!
    (Webページを閲覧する時は、幅1800pxでは広すぎるので、幅1440pxにしている)

f:id:zariganitosh:20130307110007p:image:h720=1440×2880

f:id:zariganitosh:20130307110006p:image:h720=1440×2880

f:id:zariganitosh:20130307110005p:image:h720=1440×2880

f:id:zariganitosh:20130307110004p:image:h720=1440×2880

  • 嫁のはてブは、30記事すべてがスクロールなしで一覧表示されている。

f:id:zariganitosh:20130307110008p:image:h720=1440×2880

f:id:zariganitosh:20130307110003p:image:h720=1440×2880

  • GitHubソースコードは一気に150行前後表示される。スクロールなしで一覧できると、コードの流れも追いやすい!

f:id:zariganitosh:20130307110002p:image:h720=1440×2880

  • iPhotoの眺め。サムネールの表示枚数はそれほど変わらないけど、サイドバーのアルバム項目の一覧性に感動!

f:id:zariganitosh:20130307110001p:image:h720=1800×2880

縦2880pxのポートレート表示は素晴らしい一覧性能だ!Webページはスクロールして閲覧するという概念が変わってくる。そして、スクロールしないことの快適さを実感した。

ディスプレイの縦横を切り替えるAppleScript

  • 縦2880pxのポートレート表示は病み付きになる。
  • でも現状は外付キーボードがないので、入力する時は標準のランドスケープ表示に戻す。
  • その操作が面倒なので、90°と標準の回転を交互に切り替えるAppleScriptを作ってみた。
~/Library/Scripts/rotate_display.scpt
  • 以下のrotate_display.scptをQuicksilverに登録して、command-option-control-Rでディスプレイの縦横を瞬時に切り替えるのだ。


property angle : "90"
set mouse to load script file ((path to scripts folder as text) & "_mouse.scpt")
if application "System Preferences" is running then
tell application "System Preferences" to quit
delay 0.5
end if

tell application "System Preferences" to activate
tell application "System Events"
tell process "System Preferences"
set frontmost to true
tell window 1
set x to ((scroll area 1's button "ディスプレイ"'s position as list)'s item 1) + 40
set y to ((scroll area 1's button "ディスプレイ"'s position as list)'s item 2) + 16
end tell
end tell
end tell

mouse's modifire_left_click(x, y, 1, (mouse's command) + (mouse's option))
tell application "System Events"
tell process "System Preferences"
set frontmost to true
tell window 1
click tab group 1's radio button 1 -->タブ,1,missing value
if tab group 1's pop up button 1's value = "標準" then
click tab group 1's pop up button 1
keystroke angle & return
repeat 20 times
delay 0.5
if exists sheet 1 then exit repeat
end repeat
keystroke tab & space
else
click tab group 1's pop up button 1
keystroke "標準" & return
end if
end tell
end tell
end tell

tell application "System Preferences" to quit

~/Library/Scripts/_mouse.scpt


-------- CGEventType --------
property kCGEventNull : 0
property kCGEventLeftMouseDown : 1
property kCGEventLeftMouseUp : 2
property kCGEventRightMouseDown : 3
property kCGEventRightMouseUp : 4
property kCGEventMouseMoved : 5
property kCGEventLeftMouseDragged : 6
property kCGEventRightMouseDragged : 7
property kCGEventKeyDown : 10
property kCGEventKeyUp : 11
property kCGEventFlagsChanged : 12
property kCGEventScrollWheel : 22
property kCGEventTabletPointer : 23
property kCGEventTabletProximity : 24
property kCGEventOtherMouseDown : 25
property kCGEventOtherMouseUp : 26
property kCGEventOtherMouseDragged : 27
property kCGEventTapDisabledByTimeout : "0xFFFFFFFE"
property kCGEventTapDisabledByUserInput : "0xFFFFFFFF"
-------- CGEventType --------

-------- CGMouseButton --------
property kCGMouseButtonLeft : 0
property kCGMouseButtonRight : 1
property kCGMouseButtonCenter : 2
-------- CGMouseButton --------

-------- CGEventFlags --------
property kCGEventFlagMaskAlphaShift : 65536 --caps lock
property kCGEventFlagMaskShift : 131072
property kCGEventFlagMaskControl : 262144
property kCGEventFlagMaskAlternate : 524288 --option
property kCGEventFlagMaskCommand : 1048576
property kCGEventFlagMaskHelp : 4194304
property kCGEventFlagMaskSecondaryFn : 8388608 --fn
property kCGEventFlagMaskNumericPad : 2097152
property kCGEventFlagMaskNonCoalesced : 256
-------- CGEventFlags --------
-------- CGEventFlagsの短縮形 --------
property command : kCGEventFlagMaskCommand
property option : kCGEventFlagMaskAlternate
property shift : kCGEventFlagMaskShift
property control : kCGEventFlagMaskControl
property fn : kCGEventFlagMaskSecondaryFn
-------- CGEventFlagsの短縮形 --------

-------- CGEventField --------
property kCGMouseEventClickState : 1
-------- CGEventField --------

(* サンプルコード
CGEventPost(kCGEventLeftMouseDown, 27, 12, kCGMouseButtonLeft, option + shift, 1) --optionshiftを押しながら、アップルメニューでマウスボタンを押す
CGEventPost(kCGEventLeftMouseUp, 27, 12, kCGMouseButtonLeft, option + shift, 1) --optionshiftを押しながら、アップルメニューでマウスボタンを放す
*)
--RubyCocoaを利用して、AppleScriptから最もローレベルなマウスイベントを発行する
--(最もローレベルなマウスイベント=マウスボタンを押す、放す、移動するなど)
--引数:
--●CGEventType : kCGEventLeftMouseDown, kCGEventMouseMovedなど
--●x,y : マウスカーソルの座標
-- 例:27,12 数値による絶対座標指定
-- 例:"m+100","m-5" mを含めた相対座標指定(mは現在のカーソル位置のx座標・y座標に変換される)
--●CGMouseButton : 押されたマウスボタンの番号
-- 下記のCGEventTypeの時だけ有効になる。下記以外の場合は無視される。
-- kCGEventOtherMouseDown, kCGEventOtherMouseDragged, kCGEventOtherMouseUp
--●click_count : クリック回数(MouseDown時に指定した回数が有効になる)
--●CGEventFlags : 修飾キーの状態
-- 例:option + shift optionキーとshiftキーを押しながらマウスを操作する扱いになる
on CGEventPost(CGEventType, x, y, CGMouseButton, click_count, CGEventFlags)
set ruby_cocoa to "require 'osx/cocoa' loc=OSX::CGEventGetLocation(OSX::CGEventCreate(nil)) x=eval('" & x & "'.sub(/m/,loc.x.to_s)) y=eval('" & y & "'.sub(/m/,loc.y.to_s)) point=OSX::CGPointMake(x,y) event=OSX::CGEventCreateMouseEvent(nil, " & CGEventType & ", point, " & CGMouseButton & ") OSX::CGEventSetIntegerValueField(event, " & kCGMouseEventClickState & ", " & click_count & ") OSX::CGEventSetFlags(event, " & CGEventFlags & ") OSX::CGEventPost(0,event)"
do shell script "/usr/bin/ruby -e " & quoted form of ruby_cocoa
end CGEventPost

(* サンプルコード
mouse_move(26, 12) --マウスカーソルをアップルメニューへ移動する
*)
--マウスカーソルを移動する
on mouse_move(x, y)
CGEventPost(kCGEventMouseMoved, x, y, kCGMouseButtonLeft, 0, 0)
end mouse_move

(* サンプルコード
left_click(26, 12) --アップルメニューをクリック
left_click("m", "m") --現在のカーソル位置をクリック
left_click("m+" & 100, "m") --現在のカーソル位置から右に100px移動した位置をクリック
*)
--左クリックする
on left_click(x, y)
modifire_left_click(x, y, 1, 0)
end left_click

--右クリックする
on right_click(x, y)
modifire_right_click(x, y, 1, 0)
end right_click

(* サンプルコード
center_click("m", "m",) --現在のカーソル位置で中央クリック
*)
--中央クリックする
on center_click(x, y)
modifire_other_click(x, y, 1, 0, kCGMouseButtonCenter)
end center_click

(* サンプルコード
left_drag(28, 13, 44, 150) --アップルメニューをクリックして、最近使った項目までドラッグして離す
*)
--左ボタンを押しながらドラッグして離す
on left_drag(x1, y1, x2, y2)
modifire_left_drag(x1, y1, x2, y2, 0)
end left_drag

(* サンプルコード
modifire_left_click(26, 12, 1, option + shift) --optionshiftを押しながら、アップルメニューをクリック
modifire_left_click("m", "m", 2, 0) --現在のカーソル位置で左ダブルクリック
modifire_left_click("m", "m", 3, 0) --現在のカーソル位置で左トリプルクリック
*)
--修飾キーを押しながら、左ボタンをクリック・ダブルクリック等する
on modifire_left_click(x, y, click_count, modifire_key)
CGEventPost(kCGEventLeftMouseDown, x, y, kCGMouseButtonLeft, click_count, modifire_key)
delay 0.5
CGEventPost(kCGEventLeftMouseUp, "m", "m", kCGMouseButtonLeft, click_count, modifire_key)
end modifire_left_click

--修飾キーを押しながら、右ボタンをクリック・ダブルクリック等する
on modifire_right_click(x, y, click_count, modifire_key)
CGEventPost(kCGEventRightMouseDown, x, y, kCGMouseButtonRight, click_count, modifire_key)
delay 0.5
CGEventPost(kCGEventRightMouseUp, "m", "m", kCGMouseButtonRight, click_count, modifire_key)
end modifire_right_click

(* サンプルコード
modifire_other_click("m", "m", 1, 0, 0) --mightyマウスの左クリック
modifire_other_click("m", "m", 1, 0, 1) --mightyマウスの右クリック
modifire_other_click("m", "m", 1, 0, 2) --mightyマウスの中央クリック
modifire_other_click("m", "m", 1, 0, 3) --mightyマウスのサイドクリック
*)
--修飾キーを押しながら、マウスのボタン番号を指定してクリック・ダブルクリック等する
on modifire_other_click(x, y, click_count, modifire_key, CGMouseButton)
CGEventPost(kCGEventOtherMouseDown, x, y, CGMouseButton, click_count, modifire_key)
delay 0.5
CGEventPost(kCGEventOtherMouseUp, "m", "m", CGMouseButton, click_count, modifire_key)
end modifire_other_click

(* サンプルコード
modifire_left_drag(28, 13, 35, 38, option) --アップルメニューをクリックして、システム情報...までドラッグして離す
*)
--修飾キーを押しながら、左ボタンを押しながらドラッグして離す
on modifire_left_drag(x1, y1, x2, y2, modifire_key)
CGEventPost(kCGEventLeftMouseDown, x1, y1, kCGMouseButtonLeft, 0, modifire_key)
CGEventPost(kCGEventLeftMouseDragged, x2, y2, kCGMouseButtonLeft, 0, modifire_key)
CGEventPost(kCGEventLeftMouseUp, x2, y2, kCGMouseButtonLeft, 0, modifire_key)
end modifire_left_drag

(* サンプルコード
mouse_location() --結果:{x:28, y:14} *)
--マウスカーソルの座標(左上原点)を返す
on mouse_location()
set ruby_cocoa to "require 'osx/cocoa' pt=OSX::CGEventGetLocation(OSX::CGEventCreate(nil)) puts pt.x, pt.y"
set pt to do shell script "/usr/bin/ruby -e " & quoted form of ruby_cocoa
{x:pt's paragraph 1 as number, y:pt's paragraph 2 as number}
end mouse_location

ディスプレイまでの距離

  • 実際にMacBookを立ててみて気付いた。立てた時の方が、目からディスプレイまでの距離が近づく。台の上に置くと、さらに近づく。
  • Retinaが効かない縦2880pxのポートレート表示はかなり文字が小さくなるのだけど、距離が近づくおかげで十分実用的に使えそうな気がする。


本格的にポートレート表示で使ってみたい衝動に駆られた。
外付けのBluetoothキーボードとトラックパッドが欲しい!


fb-rotateコマンド

  • fb-rotate -i で内蔵ディスプレイIDを取得して、そのディスプレイIDに対して角度を指定してあげればOK。
$ fb-rotate -i
#  Display_ID  Resolution  ____Display_Bounds____  Rotation
0   0x4280380  1920x1200      0     0  1920  1200      0    [main][internal]
Mouse Cursor Position:  (  1857 ,   411 )

$ fb-rotate -d 0x4280380 -r 90

$ fb-rotate -d 0x4280380 -r 0


if internal_display_angle() = "0" then
internal_display_rotate(90) else
internal_display_rotate(0) end if


on internal_display_angle() do shell script "/usr/local/bin/fb-rotate -i|awk '/\\[internal\\]/{print $8}'"
end internal_display_angle

on internal_display_rotate(n) do shell script "ID=`/usr/local/bin/fb-rotate -i|awk '/\\[internal\\]/{print $2}'`;/usr/local/bin/fb-rotate -d $ID -r " & n
end internal_display_rotate