アルファサード株式会社 代表取締役 野田 純生のブログ


(Xojo) Retinaディスプレイ対応、OS X Mavericks 判別


公開日 : 2014-01-07 21:20:04


Retina Displayのサポートについては、そのものズバリのブログエントリがあり、最新版にはサンプルディレクトリにサンプルもある(Example Projects/Platform-Specific/OS X/RetinaDisplay/RetinaDisplay.Xojo_binary_project)。こいつを動かせばそのまま動くのだけども、新規に作成したプロジェクトにソースをコピペしてもなぜか動かなかったので、共有しておく。

Retinaディスプレイへの対応方法

(元エントリにあるように)要するに、Info.plistに以下を追加して、Declare Function BackingScaleFactor をコールする。

<key>NSHighResolutionCapable</key>
<true/>

引数はWindowPtrなので、このコードはWindowのメソッドとしておく(もしくは呼び出す際にWindowを指定してやる必要がある)。要はマルチスクリーンのケースがあるので、Windowから判定するということなのだろう。

  #If TargetCocoa Then
    Try
      Soft Declare Function BackingScaleFactor Lib "AppKit" Selector "backingScaleFactor" (target As WindowPtr) As Double
      Return BackingScaleFactor(Self)
    Catch e As ObjCException
      Return 1
    End Try
  #Else
    Return 1
  #Endif

問題はこれをビルド時に追加するためのコードの場所で、これは、「挿入」→「Build Step」→「新しいIDEスクリプト実行手順」を作成して、そこに書くことになる。

  Dim appName As String = CurrentBuildAppName
  appName = ReplaceAll(appName, " ", "\ ") // Escape spaces for the command line
  
  Dim appPath As String = CurrentBuildLocation + "/" + appName + ".app"
  
  Dim command As String
  command = "/usr/bin/defaults write " + appPath + "/Contents/Info ""NSHighResolutionCapable"" YES"
  Call DoShellCommand(command)

Info.plistにXMLを直接書くのではなく、defaultsコマンドを使ってシェル経由で設定を追加している(この仕組みを使うと先に紹介したPerlスクリプトにUIを被せるような用途の際にPerlスクリプトやモジュールを自動的にパッケージに含められて便利)。

ところが、単にこれを書いただけでは正しく実行されない。ビルド設定のOS Xの「Build」の下にDragして配置することではじめて正しく動作します(こういうのがね、日本語マニュアルが無いってのが無駄な労力につながるってんだ)。

XojoのプロジェクトをRetinaDisplay対応させる

Mavericks(OS X10.9)の判別と、ついでにRetinaディスプレイの判別も初期化時に行う方法

ついでに、OS X10.9(Mavericks)の判別が必要になったので、これを行う方法と、マルチスクリーンを考慮しなければ初期化時にRetinaディスプレイ判別もできちゃわないだろうか、ということで、以下(どちらかといえばこっちが本題)。問答無用で、コードをそのまま貼っておく。AppのOpenイベントに書く。

OSのバージョン判定は素直に sw_vers -productVersion をシェルで叩く。その後、screencaptureコマンドを叩くのだけど、Retinaディスプレイだと生成されたキャプチャのピクセルが縦横ともに常に2倍になる。Mavericksかどうかでコマンドのパラメタが違うのは、Mavericks以前では screencapture の-R(ピクセル指定)が有効でないためです。

  #If TargetMacOS Then
    Dim IsMavericks, IsRetina As Boolean
    Dim sh As New Shell
    Dim GetOSVer As String = "sw_vers -productVersion"
    sh.Execute(GetOSVer)
    Dim Res As String = sh.ReadAll
    Dim vNum As Double = Val(Res)
    If vNum >= 10.9 Then
      IsMavericks = True
    End If
    Dim Temp,TestFile As FolderItem
    Temp = SpecialFolder.Temporary.Child( "com.alfasado.test.work" )
    if Temp.Exists = False Then
      Temp.CreateAsFolder
    End If
    Dim OrigWidth As Integer
    Dim CreateCapture As String
    If IsMavericks = True Then
      OrigWidth = 1
      CreateCapture = "cd " + Temp.ShellPath + "; screencapture -R 1,1,1,1" 
    Else
      OrigWidth = Screen(0).Width
      CreateCapture = "cd " + Temp.ShellPath + "; screencapture -x 1,1,1,1" 
    End If
    sh.Execute(CreateCapture)
    TestFile = Temp.Child( "1,1,1,1" )
    If TestFile.Exists Then
      Dim P As Picture
      P = Picture.Open(TestFile)
      If OrigWidth = P.Width Then
        IsRetina = False
      ElseIf OrigWidth * 2 = P.Width Then
        IsRetina = True
      End If
      TestFile.Delete
    End If
    Temp.Delete
    If IsRetina Then
      MsgBox "Retina"
    Else
      MsgBox "Not Retina"
    End If
    If IsMavericks Then
      MsgBox "Mavericks"
    Else
      MsgBox "Not Mavericks"
    End If
  #Endif

以前に本格的にREALBasic使ってたのってOS9の時代だったので。OS Xにすっかり変わっていることでシェルが活用できることが結構大きいな、と。何でもかんでもDeclareってのがパターンだったけど、Tarminal遣いの人にも色々と活用できる。こういう点ではUnix万歳、だね(screencaptureコマンドの仕様が将来変わるかもってのはあるけど、て、まぁあるだろな。互換性だけちゃんとしてくれれば動かなくなることはなかろう)。

関連

カテゴリ


このブログを書いている人
野田純生の写真
野田 純生 (のだ すみお)

大阪府出身。ウェブアクセシビリティエバンジェリスト。 アルファサード株式会社の創業者であり、現役のプログラマ。経営理念は「テクノロジーによって顧客とパートナーに寄り添い、ウェブを良くする」。 プロフィール詳細へ