2017/04/09

WPFのPer-Monitor DPIサポート(その4)

完結編。


Windows 10 Creators Updateがリリースされましたが、Windows 8.1から3年経過して、なぜか分かりませんがMicrosoftがようやくデスクトップアプリのPer-Monitor DPI対応に力を入れてきています。今更WinFormsまで対応してくるとは予想外でした。
新APIの追加など色々ありますが、WPFの場合は特別なことをしていない限り、関係するのはマニフェストへのPerMonitorV2の追加だけです。
これでWPFでも、例のNon-client areaのスケーリングが自動的にかかるようになります(Creators Update上では。なお、この例はAnniversary Updateより前の対応は自前でやる前提のもの)。

これによって、WPFのPer-Monitor DPI対応はひとまず完成ということで、何か特別なことをしない限りマニフェストに書くだけです。まあUIを作っていると、その何か特別なことが往々にして必要になりますが。

2017/03/06

環境光センサーとSurface

現在のタブレットには環境光センサーが付いていて、ディスプレイの明るさを自動調整できるのが普通ですが、実際どういうものかについて。

1. 環境光センサーによる調整

環境光センサー(Ambient Light Sensor)による調整とは、周辺の環境光を感知してディスプレイの明るさを自動調整するものですが、細かくいうと、ディスプレイの設定可能な明るさの範囲内(0~100%で表される。なお、0%は調整可能な下限ということであって、明るさが0ということではない)で、設定された元の明るさからより明るい方に(または暗い方に)寄せて変更します。

この変更幅は明るさの値によって違い、0%と100%では0、すなわち元のままです。その間で、これらの両端から離れるにつれ変更幅は大きくなります。

以下はこれを模式的に示したもので、横軸が元の値、縦軸が調整後の値です。赤線は調整なしの場合で、元の値と調整後の値は同じなので傾き45度の直線になります。対して青線は調整あり(環境光は一定)の場合で、0%から離れるにつれ赤線との差が大きくなっていき、中間を超えて100%に近づくと差が小さくなっていきます。途中で100%に達して、後は水平にそのままということにはなりません。
この調整の計算式はACPI規格で決まっていて、環境光センサーの値、ユーザーが設定した値、ディスプレイに応じてベンダーが用意した値を元に計算が行われます。
この調整後の値を繋いだ線は、環境光が強くなるほど、より上に膨らむ形になります。つまり、0%から出発後に一気に上昇し,ある程度の高さに達すると、後はなだらかに100%に繋がる形になります。

これは結果的に、操作するユーザーの側からすると、値が小さいときは操作量以上に大きく値が変化する一方、一旦大きくなると操作量の割に値が変化しなくなることを意味します。これはユーザーの操作と結果が比例しないということで、UI的には望ましくないです。

2. Windows 10のアクションセンター

Windows 10 Anniversary Updateのアクションセンターでは、ディスプレイの明るさをボタンで変更できるようになっています。

環境光による調整なしの場合は、以下の5段階で、単純に100を4で割った25%刻みになっています。
  1. 0%
  2. 25%
  3. 50%
  4. 75%
  5. 100%
一方、環境光による調整ありの場合は、数字は出ませんが、実際に設定される値は以下のとおりです(これに環境光による調整が加わる)。
  1. 最も暗い: 0%
  2. 暗い: 40%
  3. おすすめ: 50%
  4. 明るい: 60%
  5. 最も明るい: 100%
調整なしの場合と違うのは、2.と4.が「おすすめ」の50%から10%の差になっていることです。これは、環境光センサーによって基本的に「いい感じ」に調整されることを前提として、そこからの微調整を想定しているのだと思います。

この方法の問題点は、容易に想像されるように、
  • そもそも50%が万人に合う値とは限らない。明るさの感じ方には個人差が大きいし、同じ人間でも状況によって好ましい明るさは違う。
  • 環境光による調整がある場合(かつ環境光が十分明るい場合)、上で見たように、50%±10%程度ではさほど変化しないので、調整の役に立たない。
ということです。Microsoftの開発者は環境光センサーに任せておけばいいだろうと、実地に詰めて考えなかったのかなという気がします。ディスプレイの明るさって、個人によって微妙な調整を必要とする、割とデリケートな問題なんですよね。

そのせいか、Creators Updateではアクションセンターに明るさの設定用のスライダーが入るらしいです。それも一つの手っ取り早い解決ではありますが、もう少し工夫する余地はありそうな気がします。

3. Surface Pro 4の場合

さて、Surface Pro 4では実際にどう調整されるかを計測してみたのが以下です。
一見して分かるとおり、50%の部分だけ値を決めて、後は直線で結んだだけです。これには自分も意表を突かれましたが、SurfaceのベンダーとしてのMicrosoftが用意した設定がこうだということです。「おすすめ」の50%で使われる想定なのかもしれませんが、それにしてもざっくりしてます。

一応それぞれの環境を説明すると、
  • 437lux: 昼に日差しの入った室内、明るいオフィス内
  • 207lux: 夜に照明を点けた住宅内
  • 43lux: 薄暗い室内
  • 8lux: 暗い室内
といったところです。大体45luxのときに調整がない場合と同じになりそうなので、普通に照明がある環境では常に明るくする方に調整が入ることが分かります。

計測時には、自分のディスプレイの光が環境光センサーになるべく入らないよう遮蔽しましたが、ディスプレイが明るくなるとどうしても2~3lux上がってしまうので、その程度の変動を含んでいます。使用したコードは以下に置きました。
4. UIとして

UIとして見ると、現在の操作方法には問題があります。
  • 実際の調整後の値が設定時に分からない。
  • 明るさによって操作量に対する調整後の値の変化量が違う。
このため、その時点の環境光下で適当に「いい感じ」に設定して、環境が変わっても自動調整でたまたま「いい感じ」になればそれでよし、ならなければまた設定し直す、の繰り返しという非効率なことになっています。

これを解決するには、最終的にはユーザーの嗜好を学習して調整のデータに加えるAI的なアプローチが必要な気がしますが,差しあたっては調整後の値も表示するようにして見通しをよくするのがいいかもしれません。