2017-10-01

AppSummoner 〜Road to High Sierra 10.13 ready〜

なかなかまとまった時間がとれず遅々として進んでないのだけれども、このところMASに公開しているAppSumoner のHigh Sierra対応に時間の捻出も含め四苦八苦している。

現在公開しているものをHigh Sierraでいきなり確認すると実はこうなる



バックが黒く透過されているのは、デバッグモードだからなのだけど、Sierraの最後ではこんなことはなかった。描画済みのlayerがfillで更新されず、思い切り描き残っている。
これはこれでマウスポインタの軌跡が履歴で見れてUI/UXとして新たな可能性も感じるけど、客観的にアプリケーションとして見るとてんでいけてない。

最初は10.13のバグで、放っておけばそのうち直るのを期待していたのだけど、よくよくreleasenote見返したらまったくそうではないらしい。

で、releasenotesのこの辺をざっくり読んでわかったつもりで今日時点対応してみたのがこれ



よく見ると魔方陣のNSRect再描画でまだ対応途中なのだけど、ここまでreleasenotesの備忘録。

まずreleasenotesにはNSViewのbacking-layerで変更があったのだと書いてある。
その記述の先頭が↓

Stricter allocation of view-backing layers

macOS 10.13 is stricter in some cases about when it allocates view-backing layers for certain views. As before, if your view relies on having a layer (e.g. for the purpose of setting layer properties), it should receive [view wantsLayer:YES] and should probably also return YES from -wantsUpdateLayer.
"some cases"というのがどのケースなのかよくわからないが、どうやら僕のやり方はこのsome casesのひとつを引き当てたらしい。
でも、macOSのアニメーションはやりかたがたくさんありすぎて、どれがmain streamでどれがfringeなのかが明確に公言されてないところに、Stricterもない気はするけど。

ソフトウェアは否定しようと思えばいくらでも否定できるし、肯定しようと思えばいくらでも肯定できるのが数学と違うところ。
心を無にして...たしかにCALayerバリ使ってる。

まず、この記述によると、NSViewクラスインスタンスでwantsLayerにTrue立てろと。
これはSierra以前からもやっているし、少なくとも10.11時点でview.layer使うならこれやらないと使えなかったと記憶している。
ただし、今回は続きがあって、wantsUpdateLayerもTrueを立てろと。
で、NSViewのヘッダを見ると、wantsUpdateLayerは
    @available(OSX 10.8, *)
    open var wantsUpdateLayer: Bool { get }
とreadonlyなので、wantsLayerのように生成したインスタンスへ乱暴にtrueは放り込めない。
ObjCから脱却しきれないのは仕方ないのか、端から見てるとclangから脱却するためにうまいことswift取り込んだのに、やっぱりまだObjCが低水準レイヤに居座ってるんだと思いつつ、どうせdrawもoverrideしないといけないので、さくっとこうした。
class InvisibleView: NSView {
    override var wantsUpdateLayer: Bool { return true }...
やりたいことだけに注目すれば、objCではよく知られたsnippetsだけど、protocol extensionでできたりするのかな?
ぱっとやってみた感じ、NSViewのprotocolにこのIF持ってるやつがいなかったので、今回はすぐ諦めたけど。
メモリ空間シェアしちゃだめだよ、ちゃんとクラス立ててクリーンに動かせよという設計意図なのかもしれない。

ちなみに乗っ取ったScreen上の再描画はこれだけで、multiScreenのケースも含め蛇の張った跡みたいなやつは消えました。
問題は魔方陣の方で、ImageViewをpsdっぽくレイヤー重ね合わせで表現してるところ。
noteからすると、次項の"Ownership of view-backing layer properties"...ってもう答えが出てる気もするけど、とりあえず今日は時間切れ。

Cocoaの設計だとImageViewって、(できるけど)パーツごとの透過Image重ねるような使い方してほしくないんだよな...既存IFの建て付けと一般的にアルファブレンドの再描画コスト考えると。

やられて困ることはドキュメント読んだりやら、いちいち推論なんて立てなくても、はなからコードでできない設計にしてほしいとは思うが、Appleのアーキテクトではないので素直に逃げ道に従うか、別アプローチを考えよう。

今頃バタバタしてるのは、機材の関係でここ数年ベータ見てないのが悪いんだけど、ほんといつになったらHigh Serra readyと書いてMASに出せるのやら。

なお、CoolerCotrollerの方も、このあおりで一カ所起動パーツが参照でview渡してたところのCoreAnimationが中心座標ずれて回転してるのもわかっちゃいるのだけれども。主要機能をブロックする訳ではないから後回しにしてたり。
シリアルポートは9600でつながってたのでArduinoが反応してるのは確認した。

0 件のコメント :

コメントを投稿