tmytのらくがき

個人の日記レベルです

Surface Duoを買いました

使い始めてもう2週間くらいになるのだけれども、Surface Duoを買いました。

工事設計認証も通っているのですぐに日本ででるだろう。と思って待っていたのだけれども、一向にアメリカ以外の展開が発表されないので意を決して輸入に至りました*1

受け取り&開封

受け取り

本当はFedExのひとがうちまで配達に来てくれる…予定だったのだけども、せっかくなので関西空港での受け取りに挑戦。 FedExの営業所へ電話をして空港で受け取れないか?と尋ねたところ、ちょうど通関の許可が出たころでギリギリ間に合ったみたいでした。

用意ができたとの連絡を受けいざ空港へ…国際貨物と書かれたレーンを間違えないように進みます。

f:id:tmyt:20201019042751p:plain

一般人が使うのは一時立ち入りレーンなので一番右側の車線。

f:id:tmyt:20201019042903p:plain

しばらく行くと検問があって、右側2レーンぐらいが一時立ち入り向け。左側レーンは許可車両なので間違えないように進む。

f:id:tmyt:20201019043016p:plain

関係者以外立ち入り禁止とか書かれていてちょっとドキドキする。

f:id:tmyt:20201019043128p:plain

順番が回ってくると、検問のおじさんに、何しに来たの。と聞かれるので「FedExに荷物を取りに来た」と伝えると、一時立ち入りに必要な書類の記入をしてね。と紙を渡されるので書く。 一緒に、免許証を身分証として提出。退出予定時刻を伝えると、立ち入り許可証を受け取ってついに制限エリアの中へ!

FedExへ行くには国際郵便局前の信号を右折。僕は間違えて制限エリアの中をさまよいました。

国際郵便局前の信号を右折したらひたすら直進。突き当りを右折するとFedExの入り口と駐車場があるので、車をとめて荷物を受け取ります。 荷物受け取りに来たよ、と伝えると内線でここにかけて。といわれるので、内線で電話をしてトラッキング番号を伝えると奥から持ってきてくれます。

最後に、立ち入り許可証にハンコを押してもらって逆のルートで帰ればおしまい。

開封

BigAppleBuddy という、BestBuyとかで代わりに買ってきてくれるサービスを使ったのでそこのお手紙付き。

f:id:tmyt:20201019044140p:plain

本体、バンパー、ドキュメント類、充電器とケーブルが入ってました。SIMピンはドキュメント類の中に入ってました。

f:id:tmyt:20201019044745p:plain

Powered by Android

f:id:tmyt:20201019044322p:plain

楽天MobileのSIMを入れていたからか、言語設定の選択肢に日本語が出てきたのが印象的でした。

f:id:tmyt:20201019044426p:plain

セットアップ中も完全に日本語。

f:id:tmyt:20201019044455p:plain

早く日本でも普通に買えるようになってほしいね…

ちなみに、ちゃんと技適表示あります。

f:id:tmyt:20201019045157p:plain

設定その他

楽天MobileのAPNは自動設定されないので手動で設定。rakuten.jp と書いてあとは適当に設定。普通につながりました。 VoLTEはIMSを設定しても有効にならないみたい。4G LTE拡張モードのチェックが表示されないので使えなさそう。

そのほかの設定はあんまりやることもなくいつも通り普通のAndroidでした。

うちに届く2日前にミヤビックスからSurface Duo向けのOverlayほにゃららがタイミングよく販売スタートしたので、注文しておきました。 液晶はOverlay 9H Brilliant、背面はOverlay 9H Plusを貼っています。外側さらさらでとてもよい…

感想

サイズ感

2、3日使ってみたタイミングで折りたたんだ状態での手に持ったサイズ感が昔持ったことある気がする……ということになり、記憶をたどったところ2013年に発売された、Xperia Z Ultraとサイズ感が同じだ…ということに気付きました。

f:id:tmyt:20201019050433p:plain

Surface Duoのほうが少し幅広。縦は短い。数値で比較するとこう。

機種 サイズ
Surface Duo 145.2mm (H) x 93.3mm (W) x 9.9mm (T)
Xperia Z Ultra 179mm (H) × 92mm (W) x 6.5mm (T)

おんなじやんけ…案外サイズ感って覚えてるもんなんやな…と思った瞬間でした。Xperia Z Ultraの後継機が長年発売されないことに悲しんでいたところでのこれは個人的にうれしいポイントでした。

重さ

データ上は250gって書いてました。それがいいかどうかはさておき。

見開き状態で片手で持ってると微妙に重いかもしれない?いやそうでもないかも?そもそも昨今の情勢で電車に乗らなくなってしまったのであまり立って使うこともなく…… ただ、閉じた状態で片手で持っているとちょっと重いかな。という気持ちになります。たぶん気持ちの問題です。キー入力するときは両手で持つのであまり気になりません。

そんなぐらいの重さ感。

画面

スペックシートにはAMOLEDと書いてます。ちなみにLGのパネルだそうです。Kernelソース*2にそう書いてました。たぶんあってると思います。 まぁまぁ高いだけあって左右の色味もわりとちゃんと調整されているような雰囲気。あまり詳しいことはわかりません。

片面だと3:4、両面だと3:2ということになっているので35mm版の写真がぴったりやんけ!!壁紙設定したろ!!って設定したら微妙に合わないんです。 なぜかというと、片面だと1800x1350、両面だと2700x1800というサイズの画面ということになってるので、両面だと3:2ということになってます。だいたいどこのメディアとかもそう書いてます。スペックにもそう書いてるのであってます。

ただこれは、正確ではなく内部的にはヒンジ部分を非表示の84px幅の画面として扱ってます。いわゆる縦長のノッチです。なので、壁紙に必要なサイズは 2784x1800 です。これは3.09:2になるので微妙に3:2より横長なんですよね。豆知識です。

電子書籍

もっともおすすめの使い方は電子書籍リーダーです。コミックを読むために存在していると思っています。SurfaceブランドにはSurface Bookという製品がありますが、Surface DuoのほうがさらにBookだな思いました*3

f:id:tmyt:20201019063210p:plain

試したアプリが偏っていますが結果を書き残しておきます。リクエストあったら何かの方法で伝えてください。

  • Kindle: 見開きで読めるすばらしい。ただし文字の本はヒンジで文字が隠れるのでダメ。
  • サイコミ: 見開きにならない。2画面にするとデバイスとしては横向きになってしまう。
  • ジャンププラス: 表紙とかの片面ページが中央揃えになってヒンジと被る。見開きOK。

そのほか

  • カメラはとりあえず写ります。最近の複数レンズ構成の高級スマートフォンと比べると大してきれいではないと思います。結局iPhoneがカメラとしては優秀だと思います。たぶん。
  • 背面に移るときのダブルタップはわりと時々失敗します。2回目やるとだいたい成功するのでそんなに気にしてません。
  • 折りたたんで片側モードの時にスクショを撮影するとなにもない反対側までを含めた大きい画像が保存されます。ちょっとおもしろい。微妙に不便なのでアプリ作りました f:id:tmyt:20201019052441p:plain
  • 空きディスプレイ(ホーム画面が表示されている状態を空いていると定義する)は自動で積極的に利用される。
    • 新しいタスク*4を起動すると空きディスプレイは積極的に埋められます。
  • プリインストールのMicrosoft Launcher以外の利用は考えない方がよさそう
    • Surface Duoの内部APIまでしっかり組み込まれているのがこれしかない
  • プリインストールのMicrosoft SwiftKey keybaord以外の利用は考えない方がよさそう
    • Launcherにおなじ。Gboardとかはキーボードを使ってない側のアクティビティもキーボードが開いているみたいなサイズになるので怪しい。
  • 見開き状態で懐中電灯を誤ってONにしてしまうと、強力な目つぶしを受けてしまうので十分注意すること。
  • バッテリーはけっこうもちます*5
  • 当初Facebook Messengerの挙動があやしかったのは10月のアップデートで修正されました。
  • いちおう3年はアップデートの面倒を見てくれるそうです。

あと気づいたら書き足します。

おしまい

18万といわれるといやーさすがにたけーわ…となるのはわかります。正直僕も高いと思います。さすがにありえんと思います。ただ、買ってよかったか。というと、これは買ってよかったなぁ。という電話になりました。

*1:ちなみに日本円で約18万円だそうです。恐ろしい…

*2:厳密にはGPLで公開されているKernelコードに含まれているdevice tree

*3:ちなみに表示されているのは。ふらいんぐうぃっち(1)です。 https://www.amazon.co.jp/dp/B00HUIL6M6/

*4:Intent.FLAG_NEW_TASK

*5:使用頻度にもよるけど1.5日ぐらい持つかもしれない

BottomSheetDialogFragmentの角を丸くする

backgroundつけても反映されないのでshapeApperanceOverlayを設定するのがいいらしい。

<style name="MyBottomSheetDialogTheme" parent="@style/ThemeOverlay.MaterialComponents.DayNight.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/MyModalStyle</item>
</style>
<style name="MyModalStyle" parent="Widget.MaterialComponents.BottomSheet.Modal">
    <item name="shapeAppearanceOverlay">@style/BottomSheet.CornerRadius</item>
</style>
<style name="BottomSheet.CornerRadius" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">2dp</item>
</style>

VSCTをローカライズする

Visual Studio拡張でボタンとか追加する時はVSCTというXMLで配置先とか、ラベルとかを定義して、それがコンパイラでバイナリになって、リソースに押し込まれます。 で、それをローカライズするにはどうすればいいか、というとdocs.com のここに書いています。

docs.microsoft.com

この通りにいくらやってもうまくいかなくて、うまくいくcsprojができたので書き残しておきます。

AssemblyInfo.cs を編集

csprojを編集する前にまずAssemblyInfo.csにひとつ追加。これでフォールバックロケールの検索先が変わるそうです。

// これを追加する。この場合は en-us がデフォルト言語。それ以外をデフォルトにしたいときは、そのロケール文字列を指定するとOK
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]

これを書いておかないと、デフォルトのフォールバックリソースにVSCTのコンパイル結果が含まれていないので、フォールバックリソースが使われたVisual StudioでVSCTが読み込まれません。

VSCTをローカライズする

VSCTのXMLローカライズ済み文字列定義を参照するみたいな賢いことはできないので、全ロケール分コピーします。

例えば、Menus.vsctというファイルがある状態で、en-USとja-JPに対応したい場合はMenus.en-US.vsct、Menus.ja-JP.vsct をコピーして作ります。それぞれ中身はよさげにローカライズします。

f:id:tmyt:20200908063511p:plain

コピー元のMenus.vsctは消しても消さなくても大丈夫。もし、カスタムツールに"VsctGenerator"を指定している場合は残してもいいし、使ってない場合は削除でOK。 カスタムツールを使っている場合でも、ビルドアクションは"なし"にしてOK。

Resxをローカライズする

Resxもローカライズします。しないとうまく動きません。Resxのローカライズはいつもと同じ感じで、Strings.resxをStrings.en-US.resxとStrings.ja-JP.resxにコピーしてそれぞれローカライズみたいな感じでOK*1

ただし、フォールバック言語(ここではen-US)も個別言語としてつくらないとだめ。ここでフォールバック言語用のresxは消してはいけない。消すと動かない。

f:id:tmyt:20200908063645p:plain

この時、Resxがプロジェクトにひとつもない場合は空で大丈夫なので追加しておく。追加しておかないとうまく動かない

csprojを調整する

ここでcsprojをアンロードして右クリック→編集する。そして、こんな感じにする。

<!-- vsct -->
<ItemGroup>
  <!-- PackageGuidsとかを自動生成するのであればこれが必要 -->
  <None Include="ExpandAllPackage.vsct">
    <Generator>VsctGenerator</Generator>
    <LastGenOutput>ExpandAllPackage1.cs</LastGenOutput>
  </None>
  <!-- 各言語版をコピーして作る -->
  <VSCTCompile Include="ExpandAllPackage.ja-JP.vsct">
    <!-- ResourceNameはすべての言語でMenus.ctmenuにする -->
    <ResourceName>Menus.ctmenu</ResourceName>
  </VSCTCompile>
  <!-- ほかの言語と同じ。対応する言語分編集する。 -->
  <VSCTCompile Include="ExpandAllPackage.en-US.vsct">
    <ResourceName>Menus.ctmenu</ResourceName>
  </VSCTCompile>
</ItemGroup>
<ItemGroup>
  <Content Include="Resources\ExpandAll.png" />
</ItemGroup>
<!-- resx -->
<ItemGroup>
  <!-- 必須。ないとvsctがロードされない。リソースをコードから参照するときもこのリソースからバインディングが生成されるので消してはだめ -->
  <EmbeddedResource Include="Resources\Strings.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>Strings.Designer.cs</LastGenOutput>
    <!-- なんか適当に設定する。resxをresourcesに書き換えたものでOK。 -->
    <LogicalName>Strings.resources</LogicalName>
    <!-- ここには MergeWithCTOを書かない。書くとビルドできない。 -->
  </EmbeddedResource>
  <!-- 普通にローカライズするときと同じ。全言語作る。 -->
  <EmbeddedResource Include="Resources\Strings.en-US.resx">
    <!-- これをつけるとVSCTのコンパイル結果がこのresxとマージされる。ローカライズ済みリソースですべて必須。 -->
    <MergeWithCTO>true</MergeWithCTO>
    <!-- おなじ。resxをresourcesに書き換えたものでOK -->
    <LogicalName>Strings.en-US.resources</LogicalName>
  </EmbeddedResource>
  <!-- ほかの言語と同じ。対応する言語分編集する。 -->
  <EmbeddedResource Include="Resources\Strings.ja-JP.resx">
    <MergeWithCTO>true</MergeWithCTO>
    <LogicalName>Strings.ja-JP.resources</LogicalName>
  </EmbeddedResource>
</ItemGroup>

MergeWithCTOとLogicalNameは、resxの組のいずれかでOK。*2

編集したら、保存してプロジェクトを再読み込みする。あとはビルドすればおそらく複数言語に対応したVisual Studio拡張が出来上がっているはず。

ちなみに、VSCTが不要な場合はResxだけなのでこんな面倒なことをしなくてもローカライズできます*3

Visual Studioの言語を切り替えると、正しくローカライズされているように見える。

f:id:tmyt:20200908064008p:plain

*1:docs.comには、Strings.resxをStrings.en-US.resxにリネームするって書いてるけどここがたぶん間違い。

*2:たとえば、Strings.resxとBitmaps.resxがある場合は、Strings.resx(ja-JP, en-US)か、Bitmaps.resx(ja-JP, en-US)のいずれかでOK。ここではResxが1グループしかないので、こういうcsprojになっている。

*3:AssemblyInfo.csの編集もいらないしcsprojの編集もいらないし、ロケールのついてないresxがフォールバック先として読み込みもできる。

Visual Studioのソリューションエクスプローラのフィルタ機能を拡張する

tl;dr

  • ソリューションエクスプローラの表示を、Gitの中身を比較して変更があったファイルでフィルタする拡張を作った
  • フィルタする拡張機能は、HierarchyTreeFilterProvider を実装してVisual Studio側に公開するといい感じで動くらしい
  • フィルタ機能をソリューションエクスプローラに統合するときは、<Parent guid="guidSHLMainMenu" id="IDG_VS_TOOLBAR_PROJWIN_FILTERS" /> にするといい

Gitの状態でソリューションエクスプローラをフィルタしたい

Visual Studioの標準状態にはGitのunstagedなファイルのみ表示するフィルタはあって、これを使いたいからできればコミットしたくない。みたいな話を聞いた。 f:id:tmyt:20200908023344p:plain

普通にコミットして、git diff --stats origin/master 的なコマンドをSource Treeとかで実行したら十分なのでは?っていう話をしたら、それVSのフィルタ機能に統合してほしい。って言われたので作ってみたよ。

ソリューションエクスプローラのフィルタ機能を拡張する

まず、ソリューションエクスプローラのフィルタ機能を実現するにはHierarchyTreeFilterProviderというクラスを実装すればいい。 大まかにはdocs.com に書いてるのを読めばだいたい動く。

docs.microsoft.com

まず、HierarchyTreeFilterProviderを実装して、SolutionTreeFilterProvider属性を付けて、protectedで定義されているHierarchyTreeFilterを実装すればOK。

HierarchyTreeFilterProviderはフィルタの実装をnewするためのファクトリクラスで、フィルタとしての実体はHierarchyTreeFilterVisual Studioがフィルタを実行したい気分になると、HierarchyTreeFilter.GetIncludedItemsAsyncが呼び出されるので、このメソッドのなかにフィルタロジックを書いていけばOK。

次に、フィルタを呼び出すボタンをVSCTファイルに書く。基本的にはボタンをツールバーに追加する時と同じで、親として設定するグループを適切に設定する。適切というのは、

<Parent guid="guidSHLMainMenu" id="IDG_VS_TOOLBAR_PROJWIN_FILTERS" />

こう書く。このIDG_VS_TOOLBAR_PROJWIN_FILTERSはどこから出てきたのはは気にしてはいけない。こう書け。と先のdocs.comにも書いてあるのでこう書く。気にしてはいけない。

Gitの状態にアクセスする

LibGit2Sharpを使ってアクセスした。Visual Studioが開いているソリューションは DTE.Solution.FullNameプロパティにアクセスすると得られるので、ここからディレクトリを上方向にたどった最寄りの.git をソリューションが参照すべきGitリポジトリとした。

このパスを、LibGit2Sharpで開いて、Diff.Compare<TreeChanges>を呼び出す。差分がある(Add, Delete, Modifiedなど)ファイルのみを返すのでこの一覧をソリューションエクスプローラに表示すべきファイルとして使った。 この一覧ができてしまえばあとは、_hierarchyCollectionProvider.GetFilteredHierarchyItemsAsync を呼び出して、コールバックにフィルタすべきかどうかを判定する項目が入っているので、CanonicalNameに含まれているパスをチェックすればOK。

LibGit2SharpをVS拡張から使う

LibGit2Sharpはlibgit2のC#バインディングで実行にはネイティブ実装が必要。で、本来はNuGetから自動でインストールされてbinに出力されるけれども、VSIXの場合はVSIXに明示的に含めるようにしないとだめ。なのでcsprojを編集して次を書き足しておく。

<ItemGroup>
  <PackageReference Include="LibGit2Sharp.NativeBinaries" GeneratePathProperty="true">
    <Version>2.0.306</Version>
  </PackageReference>
  <Content Include="$(PkgLibGit2Sharp_NativeBinaries)\runtimes\win-x64\native\git2-106a5f2.dll">
    <Link>lib\win32\x64\git2-106a5f2.dll</Link>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <IncludeInVSIX>true</IncludeInVSIX>
  </Content>
  <Content Include="$(PkgLibGit2Sharp_NativeBinaries)\runtimes\win-x64\native\git2-106a5f2.pdb">
    <Link>lib\win32\x64\git2-106a5f2.pdb</Link>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <IncludeInVSIX>true</IncludeInVSIX>
  </Content>
  <Content Include="$(PkgLibGit2Sharp_NativeBinaries)\runtimes\win-x86\native\git2-106a5f2.dll">
    <Link>lib\win32\x86\git2-106a5f2.dll</Link>
    <IncludeInVSIX>true</IncludeInVSIX>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
  <Content Include="$(PkgLibGit2Sharp_NativeBinaries)\runtimes\win-x86\native\git2-106a5f2.pdb">
    <Link>lib\win32\x86\git2-106a5f2.pdb</Link>
    <IncludeInVSIX>true</IncludeInVSIX>
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </Content>
  <Content Include="Resources\SolutionFilter.png" />
</ItemGroup>

これで、NuGetからLibGit2Sharp.NativeBinariesがインストールされて、x86, x64 Windows向けバイナリがVSIXに含まれるようになる。

ベースブランチを選択する

どこかをDiffの基準点にする必要がある。今回は、WPFの非表示のWindowとContextMenuを動的に生成して、ボタンを押したときにポップアップメニューが表示されるようにした。

f:id:tmyt:20200908025438p:plain

ソリューションエクスプローラのこのツールバーにボタンを追加する方法は探しても見つからないけれども、VSCTの親設定にこう書けば追加できる。

<Parent guid="guidSharedMenuGroup" id="IDG_VS_PROJ_TOOLBAR2" />

これをどうやって探すかはdocs.comに詳しくはないけど書いてある。

docs.microsoft.com

SharedCmdPlace.vsctこのファイルに定義されているのが定義済みのコマンドバーなどなどの場所で、このファイルはこのあたりに入っていた。 C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VSSDK\VisualStudioIntegration\Common\Inc

この中から、ソリューションエクスプローラツールバーを探すと、IDG_VS_PROJ_TOOLBAR2がみつかる。

おしまい

成果物はGitHubVisual Studio Marketplaceに公開してあります。ローカライズもうまくいかなくてだいぶ悩んだけどそれはまた別の機会に…

github.com

marketplace.visualstudio.com

wslのpathにある実行ファイルをwindowsから実行できるやつを作った

WSLって歴史的経緯で今も bash.exe で起動ができるけど、 bash.exe で起動したときは chsh で設定されたシェルではなく常にbashが起動してしまう。たぶん内部的に /usr/bin/bash を実行してるんだとおもう*1

wsl を呼べば chsh で設定されたシェルが起動はするのだけどせっかくなので zsh.exe を起動するとデフォルトのWSL環境でzshが実行されるようなやつを作ってみました。

github.com

やっていることはarg[0]からファイル名を取り出して拡張子を除去、引数部分は無加工のまま受け取ってそれらをくっつけてWSLプロセスを起動。 実行ファイルの名前を変えると*2起動するWSLプロセスが変わる仕組みです。busyboxみたいな挙動ですね。

せっかくなのでWSLでプロセスを起動したりすることについて残しておきます。

WSL内でのプロセスの実行

WSL内でプロセスを実行するには大昔は非公開APIをCOM経由で呼ばないといけなかったのだけど、いまではちゃんと公開APIが用意されているのでそれを呼ぶだけ。

プロセスの実行方法は2種類用意されていて

  • 標準入出力をパイプで渡してhProcessを返すパターン
  • 現在実行中のプロセスの標準入出力を使ってプロセスが終了するまでAPIが返ってこないパターン

コンソールを持たないプロセスの場合とかは前者、コンソールでWSLプロセスが終了するまで制御を返さなくていいなら後者でいいと思う。

今回の場合は単純にWSL内でプロセスが実行できて終了すれば自分自身も終了するので後者。

docs.microsoft.com

このAPIに、実行したいディストリビューションの名前、実行したいパスなどを指定するだけでWSLでプロセスが実行できるとても簡単。

ひとつ問題があって、ドキュメントには wslapi.lib をリンクせよ。と書いているのだけどこれがSDKになぜか含まれていない。なぜ含まれていないのかは謎だけど、実際なぜか含まれていない。 しかたないので、wslapi.dll をダイナミックリンクして使いましょう。

デフォルトディストリビューションの解決

ドキュメントを見てもデフォルト設定のディストリビューションがどれなのかを取得することはどうやらできなさそうです。これはレジストリを見ると解決できます。

WSLに関する設定は HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss 配下に収まっています。ここの、DefaultDistributionに書き込まれている名前でサブキーをたどると そこにデフォルト設定になっているディストリビューションの情報が埋まっています。

WslLaunch*ディストリビューションの名前を必要としているので、サブキーから DistributionName の値を読むことでデフォルト値が解決できます。

おしまい

こんな感じでWSLのプロセスがWindows側から起動できるそうです。

zshが起動したいためだけに作ったけれども、python.exeとかgrep.exeとか用意したらなかなか楽しくなってきた。

*1:調べてないです

*2:実行ファイルをコピーしてリネームとか、ハードリンクするといいと思います。シンボリックリンクだとExplorerがリンク先の実行ファイルを起動してしまってうまく動かない。

UWPでタスクバーのアイコンをLight/Darkで切り替える

tl;dr

  • 通常は theme-light
  • シェル用のリソース(altform-unplatedなやつ)はaltform-lightunplated

Lightテーマのシェル向けのリソース定義

Windows 10 1903でタスクバーとかがLightテーマにできるようになったのにあわせて、UWPのリソースもライトテーマ向けのアイコンを含められるようになっています。

そもそもタスクバーとかで利用されるアイコンは altform-unplated だったけれどもLightテーマだと真っ白けでなにもわからんくなってしまうのでどうにかしたというやつ。

docs.microsoft.com

ライトテーマ固有のアセットを提供する シェルライトテーマ用に調整されたリソースを提供するアプリでは、新しい代替フォームリソース修飾子である altform-lightunplatedを使用できます。 この修飾子は、既存の altform-プレートなし修飾子を反映します。

機械翻訳されて若干あやしめだけど、ファイル名の altform-unplatedaltform-lightunplated に変更することでLightテーマ用のリソースとして扱えます。

ただ、最近は白一色/黒一色アイコンやめる風潮なので近いうちにいらなくなるかもしれない。

WSL2のVHDを移動する

TL;DR

  • export/importすれば移動できます
CMD> wsl --export Debian debian.tar
CMD> wsl --unregister Debian
CMD> wsl --import Debian D:\wsl\Debian\ debian.tar
  • import後のデフォルトアカウントがrootになる
    • ファイル名を指定して実行でコマンドを実行した
debian config --default-user {your_name}

WSL2のVHDを移動したい

WSL2はWSL1と違ってext4フォーマットのrootfsをVHD形式でWindows側に保持してます。いろいろ使ってると案外大きくなっていって気が付いたら40GBも使ってました。

デフォルトでは %LocalAppData\Packages\{package_name} の中にVHDが作成されてまぁまぁ邪魔なのでほかのディスクへ移動できないかぐぐったらGitHubにその通りのIssueがあったので同じことをやります。 IssueはUbuntuですが、手元はWSL2はDebianで使ってるのでSnippetはDebianに変わっています。

github.com

まず移動。

> wsl --export Debian debian.tar
> wsl --unregister Debian
> wsl --import Debian D:\wsl\Debian\ debian.tar

export時点で40GBのtarが一時的にできて、unregisterでVHDが削除、その後importで40GBのtarから40GBのVHDが目的の場所にできてました。

export/import後に起動してみるとデフォルトアカウントがrootになっていたのでこれを修正。 デフォルトアカウントを変更するには debian config --default-user {your_name} を実行したらいいらしい。

コマンドプロンプトからだとなぜか動かなかったので、ファイル名を指定して実行からコマンドを実行してデフォルトユーザを変更。

うまくいきました。