NyaRuRuが地球にいたころ https://nyaruru.hatenablog.com/ Mon, 12 Nov 2018 01:43:47 +0900 http://blogs.law.harvard.edu/tech/rss Hatena::Blog Android 9.0 に追加した API https://nyaruru.hatenablog.com/entry/2018/11/12/014347 <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Faosp-mirror%2Fplatform_frameworks_base%2Fcommit%2F386f50e04f6e93894a38951cf9e946e9fa952af8" title="Add IMS#BACK_DISPOSITION_ADJUST_NOTHING · aosp-mirror/platform_frameworks_base@386f50e" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/aosp-mirror/platform_frameworks_base/commit/386f50e04f6e93894a38951cf9e946e9fa952af8">github.com</a></cite> <iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Faosp-mirror%2Fplatform_frameworks_base%2Fcommit%2Ffbc2f7acd581eca7180a3d916936fb4e758279e1" title="Unhide InputMethodService#requestShowSelf() · aosp-mirror/platform_frameworks_base@fbc2f7a" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/aosp-mirror/platform_frameworks_base/commit/fbc2f7acd581eca7180a3d916936fb4e758279e1">github.com</a></cite></p> <ul> <li><a href="https://developer.android.com/reference/android/inputmethodservice/InputMethodService.html#BACK_DISPOSITION_ADJUST_NOTHING"><code>InputMethodService#BACK_DISPOSITION_ADJUST_NOTHING</code></a></li> <li><a href="https://developer.android.com/reference/android/inputmethodservice/InputMethodService.html#requestShowSelf%28int%29"><code>InputMethodService#requestShowSelf(int)</code></a></li> </ul> Mon, 12 Nov 2018 01:43:47 +0900 hatenablog://entry/10257846132668276634 Android 8.1 に追加した API https://nyaruru.hatenablog.com/entry/2017/12/10/173407 <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Faosp-mirror%2Fplatform_frameworks_base%2Fcommit%2F262dadf8708b5ecc80bccee14adf587f2fb2e4d5" title="New haptic feedback constants · aosp-mirror/platform_frameworks_base@262dadf" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/aosp-mirror/platform_frameworks_base/commit/262dadf8708b5ecc80bccee14adf587f2fb2e4d5">github.com</a></cite></p> <ul> <li><a href="https://developer.android.com/reference/android/view/HapticFeedbackConstants.html#KEYBOARD_PRESS"><code>HapticFeedbackConstants#KEYBOARD_PRESS</code></a></li> <li><a href="https://developer.android.com/reference/android/view/HapticFeedbackConstants.html#KEYBOARD_RELEASE"><code>HapticFeedbackConstants#KEYBOARD_RELEASE</code></a></li> <li><a href="https://developer.android.com/reference/android/view/HapticFeedbackConstants.html#TEXT_HANDLE_MOVE"><code>HapticFeedbackConstants#TEXT_HANDLE_MOVE</code></a></li> <li><a href="https://developer.android.com/reference/android/view/HapticFeedbackConstants.html#VIRTUAL_KEY_RELEASE"><code>HapticFeedbackConstants#VIRTUAL_KEY_RELEASE</code></a></li> </ul> Sun, 10 Dec 2017 17:34:07 +0900 hatenablog://entry/8599973812325324716 Android 8.0 Oreo に追加した API https://nyaruru.hatenablog.com/entry/2017/08/25/131644 <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F5959af13d069e77ff2b2ac729225e7d248b83a79" title="Introduce EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING · android/platform_frameworks_base@5959af1" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/5959af13d069e77ff2b2ac729225e7d248b83a79">github.com</a></cite></p> <ul> <li><a href="https://developer.android.com/reference/android/view/inputmethod/EditorInfo.html#IME_FLAG_NO_PERSONALIZED_LEARNING"><code>EditorInfo#IME_FLAG_NO_PERSONALIZED_LEARNING</code></a></li> </ul> Fri, 25 Aug 2017 13:16:44 +0900 hatenablog://entry/8599973812291809685 2015 年やったこと - Mozc 編 https://nyaruru.hatenablog.com/entry/2017/01/03/153842 <p>1 年遅れぐらいになりますが,OSS Mozc 関係で 2015 年にやったことのまとめです.</p> <p>空き時間を利用したプロダクトチーム外からのコミットということで,新規機能に関しては引き続き何も行っていません.前年と同じく OSS プロジェクトとしての環境整備と技術的負債の解消に注力した年でした.</p> <p>以下が主な活動内容です.</p> <ul> <li>Google Code (Subversion) から GitHub (git) への移行を完了 <ul> <li>過去のコミット履歴を可能な限り維持</li> <li>ドキュメントを Markdown で書き直す</li> <li><a href="https://travis-ci.org">Travis CI</a> および <a href="https://www.appveyor.com">AppVeyor</a> を利用し,サポートしている全プラットフォームについて CI (Continuous Integration) を実現 <ul> <li>Android</li> <li>Linux desktop</li> <li>NaCl</li> <li>Windows</li> <li>macOS</li> </ul> </li> </ul> </li> <li>コードの簡略化 <ul> <li>プロダクションに使われなかった実験的コードの削除</li> <li>サポートを終了した古い OS 向けコードの削除</li> <li>積極的にコンパイラをアップグレードし,C++ 11 のライブラリでコードを書き換え <ul> <li>Windows 環境は Visual C++ 2010 から 2013 を経て 2015 へ <ul> <li>インストーラの <a href="https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/">Universal CRT 対応</a></li> </ul> </li> <li>非 Windows 環境は <code>GCC</code> から <code>Clang</code> / <code>libc++</code> に移行</li> <li><code>base/hash_tables.h</code> を <code>std::unordered_map</code> / <code>std::unordered_set</code> に置き換え</li> <li><code>mozc::scoped_ptr&lt;T&gt;</code> を <code>std::unique_ptr&lt;T&gt;</code> に置き換え</li> </ul> </li> </ul> </li> <li>Windows 10 向けの緊急性の高い問題の修正</li> </ul> <h1>コミット単位でみる作業まとめ</h1> <h2>Windows XP 向けコードの削除</h2> <ul> <li><a href="https://github.com/google/mozc/commit/b782c5af17f7fe17f4024098959e20c99381bf14">Demove dead code that is never used in Windows Vista or later &middot; google/mozc@b782c5a &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/6182d5ebadbe4d4a86f8d5ede61243f1afb58a57">Implicitly link to SlimReaderWriterLock APIs &middot; google/mozc@6182d5e &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/f470414b26d0e0f13f2ec865e0f3a1d2046a5398">Implicitly link to input.dll on Windows. &middot; google/mozc@f470414 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/e373cda80e31a4b36475bf550383c9c3ecc05597">Require Windows Vista SP2 or later &middot; google/mozc@e373cda &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/d2e723933c34506dc6e524eab63e07e2ad9931a6">Initialize NONCLIENTMETRICSW structure to be compatible with Windows &hellip; &middot; google/mozc@d2e7239 &middot; GitHub</a></li> </ul> <p>以前は最低サポート環境が Windows XP であったため,Windows Vista 以降に追加された API は <code>GetProcAddress</code> で動的にリンクするというスタイルで統一されていました.Windows XP 廃止後も同様のコードは動くことは動くのですが,コードが不必要に長くなるだけでなく,<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd744765.aspx">Loader Lock</a> に代表されるような同期的モジュール解決の問題すらも不必要に呼び込んでしまいます.そこで,Windows Vista 以降に追加された API に関しても可能な限り暗黙的なリンク (Implicit Linking) に変更したのが主な変更内容です.</p> <p>少し冒険してみた点としては,DLL の Import Library が提供されない <code>input.dll</code> についても,ビルドルールを工夫して暗黙的にリンクするようにしてみたということでしょうか.基本的には <a href="http://apostata.web.fc2.com/dlllib/">DLL から「正しい」LIB ファイルを作るには</a> と同じことを行っています.</p> <h2>Android 版の不要なコードの削除</h2> <ul> <li><a href="https://github.com/google/mozc/commit/7d03922bee88c316a18cfb962ef8d40869cb1653">Rely on pthread to implement reader-writer lock for Android &middot; google/mozc@7d03922 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/46440f371dda6a16e3e69b2be6df2fe6391c5464">Remove a workaround for sysconf w/ _SC_PHYS_PAGES &middot; google/mozc@46440f3 &middot; GitHub</a></li> </ul> <p>サポートバージョンを上げたことにより不要になったコードを削除しました.</p> <h2>Visual C++ 2013 への移行</h2> <ul> <li><a href="https://github.com/google/mozc/commit/14232384b28fb477132391881c3ea1d833d5645e">Require Visual C++ 2013 to build Mozc for Windows &middot; google/mozc@1423238 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/091dc3bafa1645432dd9b8ba1ba0f77645d39c1a">Remove a workaround code for Visual C++ 2010 (KB813540) &middot; google/mozc@091dc3b &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/2cc1a0553421295277e8fc12e2636dcf8ef07f39">Enforce NOMINMAX macro everywhere in Mozc. &middot; google/mozc@2cc1a05 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/812d5b8be99631b4f630fdf31e6111b6f015f3d8">Use VersionHelpers.h to simplify SystemUtil &middot; google/mozc@812d5b8 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/c8fdbc96ba7bb1dafd747a95b63d3ca65de85465">Use predefined constants when possible &middot; google/mozc@c8fdbc9 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/fd0f5b347d35fe287f4cc9be49f650c87f82ba03">Use constants defined in the latest Windows SDK. &middot; google/mozc@fd0f5b3 &middot; GitHub</a></li> </ul> <p>Mozc の Windows 向けビルドは,2015 年始めの時点では依然として Visual C++ 2010 を使用しており,これが C++ 11 移行の大きな障害となっていました.これをまずは Visual C++ 2013 段階までアップグレードするという試みです.これに付随して,Windows Kit (Windows SDK) 8.1 に追加されたライブラリや定数を使ったコードの簡略化も行いました.</p> <p>この過程で遂に実現できたもののひとつに,<code>NOMINMAX</code> マクロをプロジェクト全体に適用することに成功した,というものがあります.そうです,<code>&lt;windows.h&gt;</code> を include するだけで,<code>min</code>/<code>max</code> というプリプロセッサマクロが定義されてしまうという問題が,commit <a href="https://github.com/google/mozc/commit/2cc1a0553421295277e8fc12e2636dcf8ef07f39">2cc1a055</a> によってついに過去のものとなったのでした.</p> <h2>Visual C++ 2015 への移行準備</h2> <ul> <li><a href="https://github.com/google/mozc/commit/d76bf787c778b09d645606e9c006c2b2fc401f88">Pull google/googletest@82b11b8cfcca464c2ac74b623d04e74452e74f32 &middot; google/mozc@d76bf78 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/f149187227946274b5f410f9a7182c2f49c2cf15">Import a subset of WTL 9.1.5321. &middot; google/mozc@f149187 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/d17c374faf99ffa32dd31a76c16100133d0c9812">Pull google/protobuf@b152d7feb9c0a739d7f227eb840858133a4111ef &middot; google/mozc@d17c374 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/0670fac88239964cde51de3c3a366d6afa6d92c9">Pull google/protobuf@d4569d1f5ede96238dbb87b0ecc1fdcfbd399f62 &middot; google/mozc@0670fac &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/9b97b61a11c66c63f85e4d1221ba617db375a261">Support building Mozc with Visual C++ 2015 &middot; google/mozc@9b97b61 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/22b5334892bf2a3b38a51bd41caad9b2b18366a5">Use Visual C++ 2015 merge modules as needed &middot; google/mozc@22b5334 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/07c50e3d3cff7f12476d51d9b362531efade960c">Support Visual C++ 2015 in post-build actions &middot; google/mozc@07c50e3 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/c43fd81e9e28a6eff27c4c0c625912106532674d">Pull google/protobuf@1a59a715dc5fa584340197aac0811ba3de9850b5 &middot; google/mozc@c43fd81 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/c43fd81e9e28a6eff27c4c0c625912106532674d">Pull google/protobuf@1a59a715dc5fa584340197aac0811ba3de9850b5 &middot; google/mozc@c43fd81 &middot; GitHub</a></li> </ul> <p>2015 年の年末にかけて,さらに Visual C++ 2013 から Visual C++ 2015 への移行の下準備を行いました.移行の完成は 2016 年を待つことになりますが,2015 年の段階である程度の下準備 (<code>Google Test</code> や <code>Protocol Buffers</code> のアップデート等) を完了することができました.</p> <h2>C++ 11 対応</h2> <ul> <li><a href="https://github.com/google/mozc/commit/bf596928946a4b8a64e08863d4f3d1eb65964447">Switch from stlport to libcxx in Android build &middot; google/mozc@bf59692 &middot; GitHub</a> * <a href="https://github.com/google/mozc/commit/6895df10f02dafb86150da8a3cc65f051f70e054">Remove legacy base/hash_tables.h in favor of C++11 &middot; google/mozc@6895df1 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/987b0e9166585f3420661d3f0025b96e2a420e43">Make error message from DISALLOW_COPY_AND_ASSIGN and DISALLOW_IMPLICI&hellip; &middot; google/mozc@987b0e9 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/7df47a1d53651e3a914b41d858f92920fda23513">Require Clang to build Linux host binaries &middot; google/mozc@7df47a1 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/4cff93c7a81c7f156b82a5293b8a636861de831e">Use Clang 3.4 to build host binaries &middot; google/mozc@4cff93c &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/aff84de21a81be7f7e0201aa1426a00f4396f740">Enable C++11 features in gtest. &middot; google/mozc@aff84de &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/d56d5db9353d89e7010ac03a9add9220f0f221c6">Deprecate scoped_ptr part 1. &middot; google/mozc@d56d5db &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/b3330bb9043f689faaab5af653e0feba9ed5cf4f">Deprecate scoped_ptr part 2. &middot; google/mozc@b3330bb &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/1ed31197ff736715ce51f0f852625e7fee2d2632">Deprecate scoped_ptr part 3. &middot; google/mozc@1ed3119 &middot; GitHub</a></li> </ul> <p>Visual C++ 2013 への移行でいよいよ C++ 11 対応の目途がたったことから,まずは全プラットフォームで C++ 11 が前提とできるようにビルドルールの変更等と行いました.この過程で <code>STLPort</code> を利用した Android ビルドを非サポートとしたり,非 Windows 環境のデフォルトコンパイラを Clang に統一したりといった変更も行っており,全体としてはビルドルールの簡略化に貢献できたものを考えています.</p> <p>その後,実際に C++ 11 の新しいライブラリを用いて以下のような置き換えを行いました.技術的に難しいところはないものの,単純に多数のファイルを変更する必要があるため,時間に余裕があるときでないとなかなか難しい作業です.</p> <ul> <li><code>base/hash_tables.h</code> を <code>std::unordered_map</code> / <code>std::unordered_set</code> に置き換え</li> <li><code>mozc::scoped_ptr&lt;T&gt;</code> を <code>std::unique_ptr&lt;T&gt;</code> に置き換え</li> </ul> <h2>実験的コードの削除</h2> <p><a href="https://github.com/google/mozc/commit/51b1f78853aa7cb12ffb69032a473b6497c779c5">Remove unused code from mozc_tool &middot; google/mozc@51b1f78 &middot; GitHub</a></p> <p>もしかしたら将来使うかも,と導入したものの,結局プロダクションで使われなかったコードの削除も行いました.例えば上記コミットで削除されているコードは,1,000 行以上もありながら Windows 専用かつプロダクションでは一度も使われていないという正真正銘デッドコードです.</p> <h2>ibus-mozc 廃止に向けた下準備</h2> <ul> <li><a href="https://github.com/google/mozc/commit/0796f5143400e2beb3d18156ae426f8ce06b0c0d">Enable undo-commit iff IBUS_CAP_SURROUNDING_TEXT is set. &middot; google/mozc@0796f51 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/9fbcdd5e27cf26ff16d72bd2d92f269334912ede">Stop working around a limitation in GTK IM-module. &middot; google/mozc@9fbcdd5 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/7a129e6590297380dccd8b997cbbd821f54403a2">Remove dead code from mozc_server. &middot; google/mozc@7a129e6 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/b71fe3d0b8eee0a0d7c5717b252f91e6a329fbd6">Enable &#39;ibus_mozc_test&#39;. &middot; google/mozc@b71fe3d &middot; GitHub</a></li> </ul> <p>予定されていた <code>ibus-mozc</code> の<a href="https://github.com/google/mozc/issues/287">廃止</a>は結局 2015 年中に行われませんでしたが,そのための下準備としていくつか <code>ibus-mozc</code> 関連のコードのクリーンアップを行っています.</p> <p>一番入れたかった変更は commit <a href="https://github.com/google/mozc/commit/7a129e6590297380dccd8b997cbbd821f54403a2">7a129e65</a> で,<code>mozc_server</code> 中にある <code>ibus-mozc</code> 専用コードを今のうちに削除しておくというものです.このコードは,<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd318634.aspx">IMR_QUERYCHARPOSITION </a> や <a href="https://developer.apple.com/reference/appkit/nstextinputclient/1438240-firstrect">NSTextInputClient firstRect</a> と同様の機能をなんとか Gtk+ IM Module 上に実現しようとしたものの名残で,クライアントコードはなるべく簡潔にするという Mozc の設計思想に基づき <code>mozc_server</code> 側にエミュレーションコードが実装されました.しかしながら,<a href="https://github.com/google/mozc/issues/243">Mozc Issue #243</a> で議論されているように本質的に解決できないコーナーケースが存在すること,および <code>ibus-mozc</code> 以外では使用されていないこと,という 2 点の理由から,<code>ibus-mozc</code> 廃止前に完全に削除しておきたかったのでした.</p> <h2>GitHub への移行と Continuous Integration (CI) の整備</h2> <p>Google Code の<a href="https://opensource.googleblog.com/2015/03/farewell-to-google-code.html">サービスを終了</a>にともない,OSS Mozc についても GitHub への移行を行うこととなりました.当時は私自身あまり git に慣れていなかったこともあり,Subversion から git への移行をあれこれ試行錯誤するのにずいぶんと時間を使ったように思います.</p> <p>とはいえ移行が済んだあとは GitHub のエコシステムに感心するばかりでした.特に CI については最終的にサポートしている全プラットフォームについて自動ビルドをセットアップすることができ,マルチプラットフォーム対応に価値を置いているプロジェクトとしては本当に助かっています.</p> <h3>Travis CI のセットアップ</h3> <ul> <li><a href="https://github.com/google/mozc/commit/7e20f88b830bfdb4f446167151b3c09b1fc36d3b">Enable continuous build for OS X with Travis-CI. &middot; google/mozc@7e20f88 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/0e0e5c21207b61f0b0b96c1b017ee040df08d84f">Enable Linux desktop build on Travis-CI. &middot; google/mozc@0e0e5c2 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/6215113da0c0bb80c001ed9e85a7db61ce94d07d">Enable NaCl build on Travis-CI. &middot; google/mozc@6215113 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/0f5e8a06672f6591ef541a17789e77940bef309b">Enable Android build on Travis-CI. &middot; google/mozc@0f5e8a0 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/c557fcd8daa9fa9eb5f95fc9d0f7bde7731afcd1">Enable unittest for Linux and OSX on Travis-CI. &middot; google/mozc@c557fcd &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/b207fa61abb286c6dcefab7f3180ade551e44af1">Remove unnecessary &#39;-r&#39; option from &#39;ln&#39; command. &middot; google/mozc@b207fa6 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/446b53be16be2b58ebe41e254834bdb928df9ad4">Reduce the test concurrency. &middot; google/mozc@446b53b &middot; GitHub</a></li> </ul> <h3>AppVeyor のセットアップ</h3> <ul> <li><a href="https://github.com/google/mozc/commit/6acd05e645db74e30a619859ec7c73e685cd22b9">Enable continuous build for Window with AppVeyor. &middot; google/mozc@6acd05e &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/f806322a173da72a7a6ecc8a83c9a1ccd574a662">Build all targets on AppVeyor. &middot; google/mozc@f806322 &middot; GitHub</a></li> </ul> <h3>gclient から git submodule への移行</h3> <ul> <li><a href="https://github.com/google/mozc/commit/57aa5c320f9f41fe198cc27d872b7f6d4f25d413">Follow repository migration of GYP from gyp.googlecode.com to chromiu&hellip; &middot; google/mozc@57aa5c3 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/be8d070c447727fa4f91fdd66c70fbf1c8004816">Use the official zlib repository rather than Chromium&#39;s mirror &middot; google/mozc@be8d070 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/d2b01f77cc97ea9ee9255c6ef081c06bd99f419e">Import a subset of WTL 9.0 into third_party/wtl/. &middot; google/mozc@d2b01f7 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/8a53a39251a853c3b78fab0849cb53800c9899d0">Update repository URLs of third party libraries. &middot; google/mozc@8a53a39 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/0f4b21b0ad19922afcdb282814feec53f32cbc1e">Use system-installed jsr305.jar for Android build. &middot; google/mozc@0f4b21b &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/03c3155de88f2a1c0c639da712a6f9bb88d5714a">Build Zinnia from source by default. &middot; google/mozc@03c3155 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/276fa5c362e68771b840dd5925317e310d6d75ff">Replace gclient/DEPS with git sub-modules. &middot; google/mozc@276fa5c &middot; GitHub</a></li> </ul> <h2>Windows 10 対応</h2> <ul> <li><a href="https://github.com/google/mozc/commit/0989ef207351294fa5b6810b7cf59c790bbbfd3c">Update status icon even for Windows Store Apps. &middot; google/mozc@0989ef2 &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/a2c1d40e5244e10c5afe808b92daf205cec76fdf">Introduce a workaround for sandboxed applications. &middot; google/mozc@a2c1d40 &middot; GitHub</a></li> </ul> <p>Windows 10 で状況が変わった点についてもいくつか緊急的な修正を行いました.</p> <ul> <li>言語バーが Store App でも使われるようになったことへの対処</li> <li>サンドボックス下で実行されるアプリケーションから <code>mozc_server</code> プロセスを起動できないという制約が Windows 8.1 時代よりも目立つようになったため,いくつかの対症療法的な変更</li> </ul> <h2>不安定なテストの改善</h2> <ul> <li><a href="https://github.com/google/mozc/commit/68ae78f5a9a00adaf958cb4439abebb0980ccb27">Make NamedEventTest deterministic. &middot; google/mozc@68ae78f &middot; GitHub</a></li> <li><a href="https://github.com/google/mozc/commit/d9d63a11f1fd46913049e93b0acfb7fbd241114c">Try to fix flaky session_handler_scenario_test. &middot; google/mozc@d9d63a1 &middot; GitHub</a></li> </ul> <p>Travis CI 上で不安定だったテストについて安定化を試みました.</p> <h2>透明度付き PNG ファイルを PBGRA32 形式の Bitmap ファイルの変換するツールを作成</h2> <ul> <li><a href="https://github.com/google/mozc/commit/73a8154b79b0b8db6cf8e11d6f1e750709c17518">Add a tool to convert PNG file to PBGRA32 BMP &middot; google/mozc@73a8154 &middot; GitHub</a></li> </ul> <p>ちょうど 2015 年,<a href="https://googleblog.blogspot.com/2015/09/google-update.html">会社のロゴが更新</a>され,候補ウィンドウに表示される画像も変更する必要ができました.</p> <p>Windows 版の <code>mozc_renderer</code> は,会社ロゴの表示に GDI の <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183351.aspx">AlphaBlend API</a> を利用しています.問題はこの API はいわゆる<a href="https://blogs.msdn.microsoft.com/ito/2010/07/10/423/">乗算済みアルファ</a> フォーマット (正確には PBGRA32 形式) を期待していることです.デザイナーさんから渡された PNG ファイルを PBGRA32 に変更する必要があったですが,適当なツールがみつからなかったので急遽作ったのがこちらのコードでした.</p> <h1>雑感</h1> <p>以前から興味のあった GitHub 上での作業や CI について一通り体験することができたのは非常に有意義でした.また,<code>git filter-branch</code> や <code>git rebase</code> を使ったコミット履歴の編集を学ぶ上でも良い機会でした.</p> <p>一方,前年に引き続きメンテナンス作業に注力して実感したのは,ソフトウェアのメンテナンスというのは本当にコストがかかるというというものでした.OSS Mozc に関して言うと,以下の作業だけで年間 100 時間は軽くかかっています.</p> <ul> <li>コンパイラのバージョンを上げる</li> <li>依存するライブラリのバージョンを上げる</li> <li>丁寧にリリースノートを書く</li> <li>ドキュメントを最新の状態に維持する</li> <li>Issure Tracker に報告された問題に丁寧に答える</li> </ul> <p>自分の場合これらの作業に有給休暇 10 日分以上を消費していることになるわけで,今後も同程度の貢献が継続可能かというと大変に疑問です.各種 Linux ディストリビューションで OSS Mozc が採用されるのはありがたい一方,最大の不安は期待値が高くなりすぎることです.将来のメンテナンスも含めて,あくまで無保証で提供されているという点を今一度思い出していただければという次第.</p> <h1>過去の関連エントリ</h1> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2015/02/11/183043">2014 &#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2014/01/02/120515">2013&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/03/31/172627">2012&#x5E74;&#x4ED6;&#x306B;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/01/01/134011">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul> Tue, 03 Jan 2017 15:38:42 +0900 hatenablog://entry/10328749687203188443 Android 7.1 に追加した API https://nyaruru.hatenablog.com/entry/2016/12/07/152341 <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F152944f4909c47917473293b258d266435c6ab35" title="Add InputConnection#insertContent(). · android/platform_frameworks_base@152944f" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/152944f4909c47917473293b258d266435c6ab35">github.com</a></cite> <iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2Fadebb52588b098a1af678d4e33a234ef1ce783b2" title="API Rename: IC#inputContent to IC#commitContent. · android/platform_frameworks_base@adebb52" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/adebb52588b098a1af678d4e33a234ef1ce783b2">github.com</a></cite> <iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F25e0813e6eb6315b1016db805fa9b791b4ae5cc2" title="Add InputMethodService#exposeContent() · android/platform_frameworks_base@25e0813" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/25e0813e6eb6315b1016db805fa9b791b4ae5cc2">github.com</a></cite> <iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F45700fa135e83ed44e4b69ca60cf12960a5898d7" title="Use a flag to grant a temporary URI permission. · android/platform_frameworks_base@45700fa" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/45700fa135e83ed44e4b69ca60cf12960a5898d7">github.com</a></cite></p> <ul> <li><code>BaseInputConnection#commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle)</code></li> <li><code>EditorInfo#contentMimeTypes</code></li> <li><code>InputConnection#INPUT_CONTENT_GRANT_READ_URI_PERMISSION</code></li> <li><code>InputConnection#commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle)</code></li> <li><code>InputConnectionWrapper#commitContent(android.view.inputmethod.InputContentInfo, int, android.os.Bundle)</code></li> <li><code>InputContentInfo#InputContentInfo(android.net.Uri, android.content.ClipDescription)</code></li> <li><code>InputContentInfo#InputContentInfo(android.net.Uri, android.content.ClipDescription, android.net.Uri)</code></li> <li><code>InputContentInfo#describeContents()</code></li> <li><code>InputContentInfo#getContentUri()</code></li> <li><code>InputContentInfo#getDescription()</code></li> <li><code>InputContentInfo#getLinkUri()</code></li> <li><code>InputContentInfo#writeToParcel(android.os.Parcel, int)</code></li> <li><code>InputContentInfo#CREATOR</code></li> </ul> Wed, 07 Dec 2016 15:23:41 +0900 hatenablog://entry/10328749687197792235 Android 7.0 Nougat に追加した API https://nyaruru.hatenablog.com/entry/2016/08/24/143247 <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F24df931e9e8c708fc605cd8e76a3ffd9ce5f6c77" title="Unhide View#dispatch{Start,Finish}TemporaryDetach() · android/platform_frameworks_base@24df931" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/24df931e9e8c708fc605cd8e76a3ffd9ce5f6c77">github.com</a></cite></p> <ul> <li><code>View#dispatchFinishTemporaryDetach()</code></li> <li><code>View#dispatchStartTemporaryDetach()</code></li> <li><code>View#isTemporarilyDetached()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F9f9afe526d1f8ad17c628fc9e1e839725ffe913e" title="Add IC#closeConnection(). · android/platform_frameworks_base@9f9afe5" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/9f9afe526d1f8ad17c628fc9e1e839725ffe913e">github.com</a></cite></p> <ul> <li><code>InputConnection#closeConnection()</code></li> <li><code>InputConnectionWrapper#closeConnection()</code></li> <li><code>BaseInputConnection#closeConnection()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F612cce92ad96eda1146c3abd2afa7aaa4d4f2b3f" title="Introduce InputConnection#getHandler(). · android/platform_frameworks_base@612cce9" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/612cce92ad96eda1146c3abd2afa7aaa4d4f2b3f">github.com</a></cite></p> <ul> <li><code>InputConnection#getHandler()</code></li> <li><code>InputConnectionWrapper#getHandler()</code></li> <li><code>BaseInputConnection#getHandler()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2Fd8701bfed0a7f9e00604011bc760af59464a0da1" title="Add ACTION_KEYBOARD_LAYOUT_SETTINGS. · android/platform_frameworks_base@d8701bf" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/d8701bfed0a7f9e00604011bc760af59464a0da1">github.com</a></cite></p> <ul> <li><code>Settings#ACTION_KEYBOARD_LAYOUT_SETTINGS</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2Fd469f2122edf7662dbe8c9c39269064c0265b520" title="Clarify the purpose of EditorInfo#hintLocales. · android/platform_frameworks_base@d469f21" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/d469f2122edf7662dbe8c9c39269064c0265b520">github.com</a></cite></p> <ul> <li><code>TextView#getImeHintLocales()</code></li> <li><code>TextView#setImeHintLocales()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2Fc38b51953921c17181fbe334cdaa95f188bfdb14" title="Replace Locale with LocaleList in LocaleSpan. · android/platform_frameworks_base@c38b519" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/c38b51953921c17181fbe334cdaa95f188bfdb14">github.com</a></cite></p> <ul> <li><code>LocaleSpan#LocaleSpan(LocaleList)</code></li> <li><code>LocaleSpan#getLocales()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F60fbc8e3bbe55e8be655418cc8111354e17f6ea7" title="Introduce SuggestionSpan#getLocaleObject(). · android/platform_frameworks_base@60fbc8e" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/60fbc8e3bbe55e8be655418cc8111354e17f6ea7">github.com</a></cite></p> <ul> <li><code>SuggestionSpan#getLocaleObject()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2Fc89e22a6ff227089fde26daea186346029d1b32c" title="Introdude IC#deleteSurroundingTextInCodePoints(). · android/platform_frameworks_base@c89e22a" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/c89e22a6ff227089fde26daea186346029d1b32c">github.com</a></cite></p> <ul> <li><code>InputConnection#deleteSurroundingTextInCodePoints(int, int)</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F2afe2aa15f7cd98e372d222fa5c21bede865e5b9" title="Add a new API IMM#dispatchKeyEventFromInputMethod(). · android/platform_frameworks_base@2afe2aa" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/2afe2aa15f7cd98e372d222fa5c21bede865e5b9">github.com</a></cite></p> <ul> <li><code>InputMethodManager#dispatchKeyEventFromInputMethod(View, KeyEvent)</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F868d19b93b1e20c802a001c7304f8bcac5fe5114" title="Use BCP-47 LanguageTag in IME/Spell-Checker. · android/platform_frameworks_base@868d19b" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/868d19b93b1e20c802a001c7304f8bcac5fe5114">github.com</a></cite></p> <ul> <li><code>InputMethodSubtype#getLanguageTag()</code></li> <li><code>InputMethodSubtype.InputMethodSubtypeBuilder#setLanguageTag(String)</code></li> <li><code>SpellCheckerSubtype#getLanguageTag()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F8d6eeb01df72891acd3aa75e64aa1595a41cc96e" title="Introduce EditorInfo#locales. · android/platform_frameworks_base@8d6eeb0" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/8d6eeb01df72891acd3aa75e64aa1595a41cc96e">github.com</a></cite></p> <ul> <li><code>EditorInfo#locales()</code></li> </ul> <hr /> <p><iframe src="//hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fandroid%2Fplatform_frameworks_base%2Fcommit%2F789d8fdbd9509e567cc3669c59e9e2dac2b57270" title="Make LocaleList Parcelable. · android/platform_frameworks_base@789d8fd" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;"></iframe><cite class="hatena-citation"><a href="https://github.com/android/platform_frameworks_base/commit/789d8fdbd9509e567cc3669c59e9e2dac2b57270">github.com</a></cite></p> <ul> <li><code>LocaleList#describeContents()</code></li> <li><code>LocaleList#writeToParcel(Parcel, int)</code></li> <li><code>LocaleList#CREATOR</code></li> </ul> Wed, 24 Aug 2016 14:32:47 +0900 hatenablog://entry/10328749687180609471 Windows 10 Insider Preview Build 14332 実験ノート: ブラウザと IME のプライベートモード連携 https://nyaruru.hatenablog.com/entry/2016/05/02/112650 <p><a href="https://blogs.msdn.microsoft.com/jpwin/2016/04/22/14328/">Windows 10 Preview &#x30D3;&#x30EB;&#x30C9; 14328 &#x3067;&#x304A;&#x8A66;&#x3057;&#x3044;&#x305F;&#x3060;&#x3051;&#x308B;&#x65E5;&#x672C;&#x8A9E; IME &#x306E;&#x5909;&#x66F4;&#x70B9;&#x306B;&#x3064;&#x3044;&#x3066; &ndash; Windows &amp; Devices &#x958B;&#x767A;&#x7D71;&#x62EC;&#x90E8;</a></p> <blockquote><p>入力履歴の管理が便利になりました。人に見られたくない履歴が候補リストに表示されて困った経験はありませんか?<br/> プライベートモード(仮称)を使えば、その間に蓄積された入力履歴はモードの終了時には削除され、その後意図しない場面で表示されてしまうことを防ぐことができます。<br/> プライベートモード(仮称)はIME のアイコンをクリックして表示されるメニューから「プライベートモード」を選択することでオン・オフすることができます。Edge や Internet Explorer で InPrivate ブラウズ機能をお使いの場合は、本機能が自動的に オン・オフ されます。<br/> プライベートモード(仮称)で蓄積された入力履歴はプライベートモードの間だけ有効となり、モードの終了時には削除されます。それまでにプライベートモード以外で蓄積されていた入力履歴のデータには影響ありません。</p></blockquote> <p>ブラウザと IME のプライベートモード連携は,自分にとっても時間があったらやれたらいいなぁと思っていた機能だったこともあって,週末を利用して少し調べてみました,がどうも時間切れっぽいのでメモだけでも残しておきます.想定読者はブラウザ開発者,IME 開発者,および IME API 開発者という感じですが,正直に言えば自分用のメモです.</p> <p>この機能,名前に (仮称) が付いているようにまだまだフィードバックしだいで色々変わりうる段階と思われます.というわけでまだちょっと調べたりないのですが,実験したい人向けにメモでも残しておく次第です.</p> <h2>疑問点</h2> <ol> <li>そもそも Internet Explorer / Edge と MS-IME はどのようなプロトコルでこの動作を行っているのか?</li> <li>サードパーティ製のブラウザと MS-IME の組み合わせで同じことができるか?</li> <li>Internet Explorer / Edge とサードパーティー製の IME で同じことができるか?</li> </ol> <h2>今回の調査結果</h2> <h3>そもそも Internet Explorer / Edge と MS-IME はどのようなプロトコルでこの動作を行っているのか?</h3> <p>時間内に絞り込み切れませんでした.無念……</p> <h3>サードパーティ製のブラウザと MS-IME の組み合わせで同じことができるか?</h3> <p>上の結果が確定しなかったため確たる結論に至れず.残念……</p> <h3>Internet Explorer / Edge とサードパーティー製の IME で同じことができるか?</h3> <p>公開 API のみで,InPrivate モードの検出が可能であることまでは確認.少なくとも見かけ上は可能.</p> <h2>調べたこと</h2> <ul> <li><code>ITfTextInputProcessorEx::ActivateEx</code> に指定される <code>flags</code> は,InPrivate かどうかで変化するか?</li> <li><code>ITfThreadMgr::GetGlobalCompartment</code> → <code>ITfCompartmentMgr::EnumCompartments</code> の結果は InPrivate かどうかで変化するか?</li> <li><code>ITfThreadMgr::QueryInterface</code> → <code>ITfCompartmentMgr::EnumCompartments</code> の結果は InPrivate かどうかで変化するか?</li> <li><code>ITfDocumentMgr::QueryInterface</code> → <code>ITfCompartmentMgr::EnumCompartments</code> の結果は InPrivate かどうかで変化するか?</li> <li><code>ITfContext::QueryInterface</code> → <code>ITfCompartmentMgr::EnumCompartments</code> の結果は InPrivate かどうかで変化するか?</li> <li><code>ITfContext::EnumProperties</code> で列挙される <code>ITfProperty</code> に対応しそうなものはあるか?</li> <li>Edge の設定する <code>InputScope</code> は InPrivate かどうかで変化するか?</li> <li><code>InputScope</code> の一種 <code>IS_PRIVATE</code> (<code>== 61</code>) で MS-IME は動作を変化させるか?</li> <li><a href="https://blogs.windows.com/buildingapps/2016/04/28/windows-10-anniversary-sdk-preview-build-14332-released/">Windows 10 Anniversary SDK Preview Build 14332</a> の API ヘッダの差分および InPrivate と付いた API に関連しそうなものはあるか?</li> </ul> <h2>得られた知見</h2> <ul> <li>Build 14332 時点で,正式な InPrivate 連携 API が Text Services Framework (TSF) に存在するかどうかは疑わしい.InputScope を含め,TSF の API で観測可能な範囲内に InPrivate モードの有効無効を示唆するものは一切見つけられなかった.</li> <li>Build 14332 時点で,<code>InputScope</code> の一種 <code>IS_PRIVATE</code> によって MS-IME をプライベートモードにすることはできなかった.</li> <li>Internet Explorer であれば,<code>ieframe.dll</code> のエクスポート関数 <a href="https://msdn.microsoft.com/en-us/library/dd464662.aspx"><code>IEIsInPrivateBrowsing</code></a> が依然として利用可能.ただしこの API は Edge のプロセスには読み込まれない.</li> <li>Windows 10 SDK では,<code>ProcessInPrivateInfo</code> という列挙値が <code>processthreadsapi.h</code> に追加されている (少なくとも 10.0.10586.0 SDK の時点で既に存在する).</li> </ul> <pre class="code" data-lang="" data-unlink>typedef enum _PROCESS_INFORMATION_CLASS { ProcessMemoryPriority, ProcessMemoryExhaustionInfo, ProcessAppMemoryInfo, ProcessInPrivateInfo, ProcessInformationClassMax } PROCESS_INFORMATION_CLASS;</pre> <p>Build 14332 時点で,以下のコードは Internet Explorer および Edge 共に InPrivate モードのみ true を返す.</p> <pre class="code" data-lang="" data-unlink>bool is_process_in_private() { BYTE value = 0; if (!::GetProcessInformation(GetCurrentProcess(), ProcessInPrivateInfo, &amp;value, sizeof(value)) { return false; } return value != 0; }</pre> <h2>フィードバックアイディア</h2> <p>ちょっと裏付け不足でまだ未登録なのですが,概ね以下の点についてもうちょい調べてみないとなーと思っております.</p> <ul> <li>プライベートモード連携に関しては,TSF の公開 API 内で完結させ,サードパーティー製ブラウザおよびサードパーティー製 IME との相互運用性に配慮して欲しい.ファーストパーティ製ブラウザおよびファーストパーティ製 IME の間のみで使われるプライベートプロトコルは好ましくない.</li> <li>ProcessInPrivateInfo は,現状取得のみが可能なように見える.これに該当する特殊プロセスの作成に非公開 API が必要なのであれば,ファーストパーティ製ブラウザのみがそれを使用可能という状況は好ましくない.</li> </ul> <h2>関連事例</h2> <h3>(同一プロセスで動く IME で使うことを前提とした) Accessibility API を利用したプライベートモード検出</h3> <p>書くいう自分も,2013 年末ごろには MSAA を使ってプライベートモードの検出ができるかどうか実験したりしていました,がチームを移ったあとのごたごたで結局プロダクションでは使われてなかったりします.その辺のコードがいまもここに.</p> <p><a href="https://github.com/google/mozc/blob/4a370c6ea6f003be99e7837713a939a68b75aeae/src/win32/base/browser_info.cc#L108-L154"><code>mozc/src/win32/base/browser_info.cc</code> <code>BrowserInfo::IsInIncognitoMode</code></a></p> <p><code>sufix</code> は typo ですすみません.あとで直します……</p> <h3>Chromium Bug 311180: Chrome OS: Incognito window is not really incognito for IME users</h3> <p><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=311180">Issue 311180 - chromium - Chrome OS: Incognito window is not really incognito for IME users - Monorail</a></p> <p>Chromium OS での同様の機能リクエスト.長いこと放置されていて辛い感じです.</p> <h3>Chromium Bug 601951: Android keyboard suggestions leak information typed in incognito window</h3> <p><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=601951">Issue 601951 - chromium - Android keyboard suggestions leak information typed in incognito window - Monorail</a></p> <p>Android 版 Chromium での同様の機能リクエスト.</p> <p>この件については SwiftKey のサポートページにも以下のように書かれていたり.</p> <p><a href="https://support.swiftkey.com/hc/en-us/articles/202437682-Can-I-turn-off-learning-in-incognito-mode-with-SwiftKey-Keyboard-for-Android-">Can I turn off learning in incognito mode with SwiftKey Keyboard for Android? &ndash; SwiftKey Support</a></p> <blockquote><p>Unfortunately, the keyboard actually does not know that you are in this special mode in the Chrome app because that is not something Google passes on to other apps.</p></blockquote> <h2>改定履歴</h2> <ul> <li>2016-05-02: <code>ProcessInPrivateInfo</code> の追加時期について表現を変更.少なくとも 10.0.10586.0 SDK の時点で存在する.</li> </ul> Mon, 02 May 2016 11:26:50 +0900 hatenablog://entry/6653812171393980241 My OSS Wish List https://nyaruru.hatenablog.com/entry/2015/09/14/052102 <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150914/20150914052437.png" alt="f:id:NyaRuRu:20150914052437p:plain" title="f:id:NyaRuRu:20150914052437p:plain" class="hatena-fotolife" itemprop="image"></span></p> <p>業務外にパッチを書いたりしている OSS プロジェクト,だいぶやりたいことが溜まっているので,優先順位をつける意味でもまとめてみた. 業務と基本無関係なので,代わりにやっていただくのは大歓迎.なので以下は Wish List ということにしておきたい.</p> <h1>OSS Mozc 関係</h1> <h2>[Mozc] Windows 版向けのインストーラーをビルドできるようにする</h2> <p>2013 年に Windows 版のコードを概ねオープンソース化したときに,面倒で後回しにしたのがこの部分. プロダクト版の WiX スクリプトは実際<a href="https://github.com/google/mozc/blob/14232384b28fb477132391881c3ea1d833d5645e/src/win32/installer/installer_32bit.wxs">公開済み</a>ではあるのだけど,自動アップデート関係の設定等もここで行っているため OSS 版のインストーラにそのまま転用できなくなっている. 技術的な障害は何もなく,OSS 版向きでない処理を取り除くだけ,なんだけどずるずるとはや 2 年半ぐらい.</p> <p>やること.</p> <ul> <li>OSS Mozc 向けに,余計なものを取り除いた WiX スクリプトを書く</li> <li>ビルドに必要な WiX のインストール方法を決める.OSS Mozc のリポジトリにチェックインしてしまうか,<code>choco install wixtoolset</code> あたりを使う.</li> </ul> <h2>[Mozc] DirectWrite を使うと真っ白になる問題を再現させる</h2> <p><a href="http://nyaruru.hatenablog.com/entry/2015/02/11/183043">候補ウィンドウの DirectWrite で表示する</a>というコードを実装したのがだいぶ前の 2013 年 12 月ごろ.先日こいつが安定版に取り込まれ,それなりの数のユーザーにリリースされたところ,文字が全く表示されなくなるという問題が各所で起こることが判明.急遽該当コードを無効化するという事態に. 報告を読む限り Windows 7 環境限定っぽいのですが手元で再現できていないので詳しいことはよくわからず.</p> <p>やること.</p> <ul> <li>再現環境を入手する</li> <li>Mozc の実装に問題があるかどうかを調査する.問題があれば修正する.</li> <li>もし環境側の問題であれば,それを検出する方法があるか調査する.</li> <li>DirectWrite を用いた表示を無効化する設定を設定ダイアログに追加するべきか検討する.必要があればその実装.</li> </ul> <h2>[Mozc] ソースコードのチェックアウトプロセスから Subversion 依存を取り除く</h2> <p><a href="https://github.com/google/mozc/issues/299">Mozc Issue #299</a> 参照. 技術的な障害は何もなく,淡々と手を動かせば終わるはず.</p> <h2>[Mozc] 依存する外部リポジトリの管理を gclient から Git submodule に変更</h2> <p>Subversion 依存が取り除かれれば,あとは機械的に対応可能.</p> <h2>[Mozc] ibus-mozc の削除</h2> <p><a href="https://github.com/google/mozc/issues/287">Mozc Issue #287</a> 及び <a href="https://github.com/google/mozc/issues/194">Mozc Issue #194</a> 参照. これは割と自分の都合でお願いして削除することを決めてもらった話なので,早いところ何とかしたい.</p> <p>ibus-mozc に関しては主に 2 つの理由からサポートをやめたいと思っていた.ひとつはメンテナー不在という問題,もうひとつは互換性問題の多発による周辺プロジェクトの疲弊がある.</p> <p>メンテナー不在に関しては単純で,自分の空き時間の使い道としては優先順位が高くない,というのが理由である. 自分が OSS Mozc のメンテナンスを引き受け始めたころには,既に Chromium OS は IBus の使用をやめており,ibus-mozc を業務でメンテナンスする人間はいなかった. 自分の場合 OSS 関係のプロジェクトに関しては基本的に業務外時間で面倒を見ていて,そのため土日にできる範囲で作業するというスタンスを取っている. 日本語入力については,Windows と Android であれば日常的に使っているという意味もあってまだ興味が持てるものの,Linux Desktop 上で日本語入力することは基本的にない. そのため,既知のバグを概ね直しきったところで手を引くべきだと考えていた. <a href="https://github.com/google/mozc/issues/194">Mozc Issue #194</a> という Issue を立てメンテナーを社内外から募集してみたのが 2 年ほど前. 残念ながら特に引き取り手は現れなかったので,まだ作業する余裕があるうちにコードを削除してしまおうというのが現在の考えである. というものの実際ここ数ヶ月は時間がとれずに作業が進んでいなかったので,もう少し早く始めていれば良かったのかもしれない.</p> <p>互換性問題に関しては,複雑だ. IBus 1.4 あたりから,IBus の様々な処理が非同期プロセス間呼び出しとして実装されているのだけど,自分が普段使っているアプリケーションを中心にこれが何度も互換性問題を引き起こしている.</p> <ul> <li><a href="http://tools.android.com/knownissues/ibus">Android Studio &amp; ibus-daemon interactions</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=354495">Chromium Issue #354495: The last Korean character before space is inserted after a space in all input field</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=524084">Chromium Issue #524084: Linux keydown/keyup/keypress events are reordered</a></li> </ul> <p>自分の理解が正しければ,もともと Chromium OS でのパフォーマンスを稼ぐために寄せられたパッチ群がもとで ibus が非同期処理を多用し始めた,という歴史だったように思う.とすれば不幸としか言いようがない. とはいえ同僚が今もこの件で時間を消費していることを考えると,多くのユーザーには IBus 以外の実装に移って欲しいという気持ちもある.心境としては複雑ではあるのだけど.</p> <p>やること.</p> <ul> <li>社内リポジトリで変更済みの ibus-mozc 関係の更新を全て OSS 化</li> <li>ibus-mozc 関係のコードを全削除</li> <li>fcitx-mozc 等の代替ソフトウェアに足りない機能があれば,可能な範囲でそちらへの協力.</li> <li>IBus の非同期モードが問題を引き起こしている周辺プロジェクトへのできる限りの協力.</li> </ul> <h2>[Mozc] tsf-mozc の Windows 10 関係の互換性問題の調査</h2> <p>やること.</p> <ul> <li>Windows 10 環境を作る</li> <li>色々と言われている問題が再現するか調査.再現するなら直す.</li> </ul> <h2>[Mozc] Windows 環境での縦書きサポート</h2> <p>ずっと言われているのでどこかで時間を取って何とかしたい.候補ウィンドウ側に関してはハッカソンで一回動くところまで作ったことがあって,2 日もあればそこまではできることは確認済み. 問題は変換エンジン側で,縦書き時にカーソルキーの意味が変わるという動作をきちんとプロトコルレベルで定義する必要がある.</p> <p>やること.</p> <ul> <li>候補ウィンドウの縦書きを実装.テストも追加.</li> <li>縦書きと横書きでキーマップを入れ替えるためのプロトコルを定義する</li> </ul> <h2>[Mozc] Qt 5.x への移行</h2> <p>Mozc では依然として Qt 4.8.x 系を使っているのだけど,いくつかの理由から 5.x へのアップグレードを急ぐ必要がある.</p> <ul> <li>Qt 4.8.x では Windows の HiDPI 環境をサポートできない.これはだいぶ深刻.</li> <li>様々な Linux ディストリビューションが Qt 4.x のサポートを打ち切りたがっている.</li> </ul> <p>基本的には Qt のアップグレードでビルドが通らなくなるところをひたすら直していく以外にないのだけど,Qt にパッチを当てずに移行可能かはまだ未知数. また,ビルドが通っても特定ユーザー環境で問題が発生する可能性もあり,先は長い.</p> <h2>[Mozc] Linux および Android 向け Continuous Build / Test 環境の整備.</h2> <p>現在の OSS Mozc は,Windows と OS X に関してある程度の Continuous Build / Test 環境が有効化されているものの,Travis CI が長らく Linux 12.04 にとどまっているため Linux および Android に関しては有効化できていなかった. 最近 <a href="http://blog.travis-ci.com/2015-08-19-using-docker-on-travis-ci/">Travis CI が Docker をサポートを追加</a>したらしく,そろそろ何とかなりそうな気がしている.</p> <h2>[Mozc] その他溜まっている OSS Mozc の更新</h2> <p>Mozc の開発は現在も社内リポジトリが master. OSS リポジトリの更新タイミングは,基本的に誰かの手が空いているときであって,ここ 1 年半ぐらいは自分が土日及び休暇の空き時間を利用して行っている. で,ここのところ時間がとりにくかったのもあって,OSS 化すべき更新が 7 ヶ月分ぐらい溜まっている.</p> <p>やること.</p> <ul> <li>作業のさらなる自動化.</li> <li>ビルド確認の手間を減らすべく CI の拡充.</li> </ul> <p>gclient から git submodule に移行すれば,GitHub 界隈のエコシステムをもうちょっとうまいこと活用できるんではないかと期待.</p> <h1>GYP 関係</h1> <h2>[GYP] Revert された 540e4b1e665 の再有効化</h2> <p>これは完全に巻き込まれ案件なのだけど,個人的に気になっていて何とかしたい.以下時系列.</p> <ol> <li>いくつかのビルドツールで問題を起こすことから,GYP は同一ビルドターゲット内に (ディレクトリだけ異なる) 同名ファイルが存在することを許さない.一方,社内外からこの制限が不便だという声があがっていた.</li> <li>数年前,社内リポジトリにとりこまれたバージョンの GYP に,このファイル名チェックを回避するオプションを追加するローカルパッチが提案され,メンテナンスを担当していた自分はうかつにもこれを受け入れてしまう.以後,アップデートのたびにパッチを当てなおす必要がうまれメンテナンスコストが増大.</li> <li>自分が中心となって,GYP upstream に同等のオプションを実装 <a href="https://codereview.chromium.org/670063006/">GYP r1947</a>.</li> <li>上記機能が実装された GYP を社内にインポート.いくつかのプロジェクトがそのオプションを有効にする.</li> <li>とある Chromium 開発者,この制限を完全に取り除くパッチを提案.受け入れられる.<a href="https://codereview.chromium.org/670063006/">GYP r1993</a>.</li> <li>上記機能が実装された GYP を社内にインポート.不要になったオプションは削除される.</li> <li>GYP r1993 が,Chromium のビルドで警告を引き起こすことが分かり revert される.<a href="https://codereview.chromium.org/1151963003/">GYP c0cf1f22eb</a></li> </ol> <p>というわけで,最新の GYP をそのまま社内にインポートすると,いくつかのプロジェクトでビルドが壊れることが分かっている.何とかしたい. この問題,自分の理解では OS X の libtools の制限によるもので,XCode では技巧的な方法で回避済み.同じことを GYP の Ninja ジェネレータでも実装すれば済む話,なんだけど時間が取れずまだ何もできていない.</p> <p>が,こうやって書いてみると,自分的には最新の GYP がインポートできれば十分なので,もう一回社内の該当プロジェクトにオプション追加すれば良いだけのような気もしてきた……</p> <p>やること.</p> <ul> <li>自分で直すまたは代わりにやってくれる人をみつける.</li> </ul> <h1>Chromium 関係</h1> <h2>[Chromium] Web MIDI の実装に Windows 10 の新 MIDI API が使えるか調査</h2> <p><a href="https://code.google.com/p/chromium/issues/detail?id=512433">Chromium Issue #512433</a> 参照. Windows 10 には <a href="http://www.sonicstate.com/news/2015/07/21/why-microsofts-windows-10-audio-and-midi-apis-are-a-big-deal/">MIDI API が追加されていて</a>,Windows 版 Chromium の Web MIDI がもっと使いやすくなる可能性がある.</p> <p>やること.</p> <ul> <li>自分でやるまたは代わりにやってくれる人をみつける.</li> <li>自分でやる場合,まずは Windows 10 環境を作る.</li> </ul> <h2>[Chromium] その他 Chromium の Web MIDI サポートで担当者募集中バグの修正</h2> <p>2015 年 9 月 13 日現在 24 個の<a href="https://code.google.com/p/chromium/issues/list?can=2&amp;q=label%3ACr-Blink-WebMIDI+status%3Aavailable">担当者募集中バグ</a>がある. しかしこれはちょっと分量的につらいかも.</p> <p>やること.</p> <ul> <li>自分でやるまたは代わりにやってくれる人をみつける.</li> <li>MIDI の meetup 等で協力者を募る.</li> </ul> <h2>[Chromium] Android Lollipop で追加された新 IME API のサポート</h2> <p><a href="https://code.google.com/p/chromium/issues/detail?id=424866">Chromium Issue #424866</a> 参照. 去年 Android Lollipop に追加した <a href="https://developer.android.com/reference/android/view/inputmethod/CursorAnchorInfo.html">CursorAnchorInfo API</a>,Chromium でまだサポートされていないのでなんとかしたい. 実はパッチまでは既にあるのだけど,Chromium 特有のレビューコスト・パフォーマンスに関する敷居の高さに阻まれ中断中. これはひょっとしたら業務時間中にやりきる口実を見つけられる可能性もゼロではないのだけど,その時間を Android 本体に使ったほうがどう考えても合理的なので早いところ担当してくれる Chromium 関係者を見つけるべきだと思っている.</p> <p>やること.</p> <ul> <li>代わりにやってくれる人をみつける.あるいは気合を入れて自分でやりきる.</li> </ul> <h1>Firefox 関係</h1> <h2>[Firefox] Android Lollipop で追加された新 IME API のサポート</h2> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094729">Mozilla Issue #1094729</a> 参照. 去年 Android Lollipop に追加した <a href="https://developer.android.com/reference/android/view/inputmethod/CursorAnchorInfo.html">CursorAnchorInfo API</a>,Firefox でまだサポートされていないのでサポートされて欲しい. 新 IME API が自社製品でしか使われないというシナリオは避けたい.心の底から.それが Microsoft ウォッチャーとして Text Services Framework から得た教訓なのですな.</p> <p>やること.</p> <ul> <li>あの手この手で実装してもらう.あるいは気合を入れて自分で実装してパッチを取り込んでもらう.</li> <li>新 API の解説を書く.</li> <li><a href="http://stackoverflow.com/questions/4142887/how-the-input-method-can-request-updatecursor-event">How the input method can request 'updateCursor' event? - Stack Overflow</a> に付いている回答に補足する形で,各種ブラウザの実装状況についてコメントする.</li> </ul> Mon, 14 Sep 2015 05:21:02 +0900 hatenablog://entry/6653458415121287587 Docker 上に IPython Notebook 実行環境を作って DeepDream を動かす https://nyaruru.hatenablog.com/entry/2015/07/05/092107 <p>DeepDream を動かしてみようと思ったら 9 割ぐらい IPython Notebook と必要なライブラリの環境整備だったのでそのまとめ.</p> <ul> <li>作業日 <ul> <li>2015 年 7 月 4 日</li> </ul> </li> <li>作業前の筆者の状況及びそこから導かれる想定読者 <ul> <li>IPython Notebook を使ったことがない.環境構築もしたことがない. <ul> <li>Mathematica は使ったことがあるかもしれない.</li> </ul> </li> <li>docker コマンドが動く Linux Desktop 環境を,実機,または VM 内 (Windows にインストールした VMWare 等) にもっている.</li> <li>Deep Neural Network と呼ばれる技術について,特に知らないし,特に自分で手を動かして何かしたこもなく,業務でも当面使う予定はない.</li> <li>インターネットからの数 GB 程度のデータダウンロードが可能である.</li> </ul> </li> <li>目標 <ul> <li>docker コマンドが動く環境ならどこでも DeepDream のチュートリアルを実行できるようになる.</li> </ul> </li> <li>目標ではない <ul> <li>Deep Neural Network と呼ばれる技術について,何らかの知見を得る.</li> </ul> </li> </ul> <h2>Deep Neural Network 素人であるところの筆者が理解できた範囲の話の背景</h2> <p>6 月中旬ごろ,不思議な画像を生み出す画像処理アルゴリズムが Google Brain Project に所属する研究者たちによって公表されました.</p> <ul> <li><a href="http://googleresearch.blogspot.com/2015/06/inceptionism-going-deeper-into-neural.html">Inceptionism: Going Deeper into Neural Networks</a></li> </ul> <p>Inceptionism の背景ですが,たとえば 10 段から 30 段にもなるニューラルネットワークが存在したとき,各段の振る舞いが実際に何をやっているのかは自明な話ではありません.この疑問に対する実験の 1 つとして,特定の段のニューロンの特性を使って入力画像を強調してみたらどうなるか,というのがどうも Inceptionism の意義というか立ち位置のようです.</p> <p>実際,ランダムノイズ画像に上記強調処理を行った結果何やら物体めいたものが見えてきたというのが,ブログの前半で述べられていることです.</p> <blockquote><p>So here’s one surprise: neural networks that were trained to discriminate between different kinds of images have quite a bit of the information needed to generate images too.</p></blockquote> <p>さて,異なる画像を識別するように訓練されたニューラルネットワークは,画像を生成するために必要な情報をある程度持っているのであれば,これを使って面白画像が生成できないかというのが後半パートです.</p> <p>Inceptionism ブログ記事では,実際の画像強調処理の具体的なアルゴリズムは記述されていませんでしたが,7月1日になって,<a href="http://ipython.org/notebook.html">IPython Notebook</a> というインタラクティブな Python 実行環境を使ってチュートリアル的に行う方法が<a href="http://googleresearch.blogspot.com/2015/07/deepdream-code-example-for-visualizing.html">公開されました</a>. この GitHub リポジトリの名前が <a href="https://github.com/google/deepdream">DeepDream</a> です.</p> <p>ちなみに DeepDream として新たに公開されたのは,数十行程度の反復処理アルゴリズムだけで,Inceptionism ブログ記事の画像を再現するために公開が必要だった本当にこの反復処理アルゴリズムだけであったことが分かります. DeepDream では,<a href="https://github.com/BVLC/caffe/blob/master/models/bvlc_googlenet/readme.md">GoogLeNet</a> という訓練済みニューラルネットワークを用いており,このデータは 2014 年 12 月に公開済みでした.</p> <p>さて問題は,普段この種の処理と無縁な生活をしている人間にとって,まずこの IPython Notebook の実行環境を (DeepDream に必要なライブラリを揃えつつ) 整えるのが大変面倒だ,ということです. というわけで Docker の出番です.</p> <h2>なぜ Docker を使うのか</h2> <p>まず最初になぜ Docker を選んだのかについて書いておきます.筆者の気づいた範囲で,DeepDream の実行環境を整えるにあたって面倒なのは次のような点です:</p> <ul> <li><a href="http://caffe.berkeleyvision.org"><code>Caffe</code></a> というライブラリを正しくインストール・設定する必要がある <ul> <li><a href="https://github.com/BVLC/caffe/blob/master/models/bvlc_googlenet/readme.md"><code>GoogLeNet</code></a> のデータセットが含まれていなければならない</li> <li>特定 GPU / ドライバへの依存を避けるために,Caffe は CPU 処理モードになっていて欲しい</li> </ul> </li> <li><code>pip</code> コマンドで複数の Python ライブラリをインストールする必要がある</li> <li>IPython Notebook はブラウザをフロントエンドに使用するため,実行環境にはブラウザがインストールされている必要がある</li> </ul> <p>これらの処理を,普段使用している Linux Desktop 環境を汚さず,かつ (なるべく) 再現可能な形で,Linux ディストリビューション間の非互換性に煩わされることなく行いたいというのが Docker を使用する目的です. Docker を用いることで,仮に IPython Notebook 実行環境を予期せず壊してしまっても,すぐに最初からやり直すことが可能です. また,いったんコンテナイメージを作ってしまえば,ホスト環境が変わってもすぐに同じ実験を行うことが可能です.</p> <p>ほんと,Docker みたいなのが自分の学生時代にも欲しかったものです……</p> <h2>(Docker) ホスト Linux </h2> <p>以下では Ubuntu 14.04.1 64-bit 版を想定していますが,必要な環境は Docker コンテナ内に用意するため,ホスト環境に要求するのは以下の 2 点です.</p> <ul> <li>Docker が動く</li> <li>(表示用のブラウザを X11 経由でホスト画面に表示するため) GUI ログイン可能である</li> </ul> <p>Docker のセットアップについては詳しく述べませんので,<a href="https://docs.docker.com/installation/">Supported installation - Docker</a> から辿ってインストールしてみてください.</p> <p>なお,以下では sudo なしで docker コマンドが実行可能なように設定されていることを前提に書かれています.その設定を望まない場合は各自 sudo を付けて読み替えてください.</p> <h2>Docker コンテナのダウンロードとインストール</h2> <p>必要なコンテナは DockerHub にアップロード済みです.</p> <pre class="code" data-lang="" data-unlink>docker pull nyaruru/deepdream-ipython-notebook</pre> <p>セキュリティが気になる人・自分で再現を試みたい人は,<a href="https://registry.hub.docker.com/u/nyaruru/deepdream-ipython-notebook/dockerfile/"><code>deepdream-ipython-notebook/dockerfile/</code></a> で Dockerfile を確認することができます.</p> <p>何か問題・改善点がありましたら GitHub 上の<a href="https://github.com/NyaRuRu/deepdream-ipython-notebook"><code>NyaRuRu/deepdream-ipython-notebook</code></a> までお知らせください. また,今回は <a href="https://github.com/visionai/clouddream"><code>github.com/visionai/clouddream</code></a> をベースイメージに使わせていただいており,Caffe のセットアップ等大部分の処理はそちらで行われています.</p> <h2>Docker コンテナの実行</h2> <p>まず,コンテナ内からホストへの X11 接続を許可しておきます.</p> <pre class="code" data-lang="" data-unlink>xhost +local:</pre> <p>DeepDream を一通り実行するだけであれば,以下のように <code>docker</code> コマンドを実行するだけで十分です.</p> <pre class="code" data-lang="" data-unlink>docker run -i -t --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro nyaruru/deepdream-ipython-notebook</pre> <p>上手くいけば,コンテナ内で Firefox が起動され,そのウィンドウがホスト GUI 環境に表示されるはずです. 終了するには,ターミナル上で Ctrl-C を実行すれば OK です.</p> <p>docker コンテナ起動時に <code>--rm</code> オプションを付けていることに注意してください.この結果,コンテナ終了時に作業内容は全て失われますが,もう一度実行しなおすことで確実に動く状態からやり直すことが可能です.</p> <h2>DeepDream IPython Notebook チュートリアルの実行</h2> <p>Docker コンテナを起動すると,すでに IPython Notebook が起動しているはずです.DeepDream のディレクトリが表示されているはずですので,そこから <code>dream.ipynb</code> を選択します.</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150705/20150705091726.png" alt="f:id:NyaRuRu:20150705091726p:plain" title="f:id:NyaRuRu:20150705091726p:plain" class="hatena-fotolife" itemprop="image"></span></p> <p>IPython Notebook が表示されます.Mathematica 経験者であれば,あの Notebook みたいなもの,と思えばとっつきやすいかも.</p> <p>上の方に ▸ ボタンがありますので,それを押していくとチュートリアルの内容が上から順に実行されてきます.</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150705/20150705091711.png" alt="f:id:NyaRuRu:20150705091711p:plain" title="f:id:NyaRuRu:20150705091711p:plain" class="hatena-fotolife" itemprop="image"></span></p> <p>以下の箇所を実行することで,チュートリアルのサンプル設定での DeepDream が画像を強調処理していく様子をリアルタイムに見ていくことができます.</p> <pre class="code" data-lang="" data-unlink>_=deepdream(net, img)</pre> <p>デフォルトのパラメータは,関数定義に書いてあるとおり以下のようになります.</p> <ul> <li><code>ter_n=10</code></li> <li><code>octave_n=4</code></li> <li><code>octave_scale=1.4</code></li> <li><code>end='inception_4c/output'</code></li> </ul> <h2>さらに DeepDream を楽しむために</h2> <h3>パラメータを変える</h3> <p>こちらについても詳細についてはチュートリアルに書かれています.たとえば,</p> <pre class="code" data-lang="" data-unlink>net.blobs.keys()</pre> <p>を実行することでニューロン層のリストが表示されます.強調処理に使う層を <code>inception_3b/5x5_reduce</code> に変更してみるというのが</p> <pre class="code" data-lang="" data-unlink>_=deepdream(net, img, end=&#39;inception_3b/5x5_reduce&#39;)</pre> <p>の行っていることです.</p> <h3>ホスト環境のディレクトリを Docker コンテナ内に見せる</h3> <p>ここまで来ると,実際に色々な画像で実験してみたくなります. Docker のホストとコンテナでファイルをやり取りする方法はいくつかあるかと思いますが,ここでは <code>-v</code> オプションでホストの特定ディレクトリをコンテナ内に公開することにします.</p> <pre class="code" data-lang="" data-unlink>docker run -i -t --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix:ro -v $HOME/Pictures:/opt/pictures nyaruru/deepdream-ipython-notebook</pre> <p>これで,ホスト環境の <code>$HOME/Pictures</code> がコンテナ内の <code>/opt/pictures</code> と共有されます. たとえば <code>foobar.jpg</code> を $HOME/Pictures に置いたとします.IPython Notebook のデータを読み込んでいる次の行を探してください.</p> <pre class="code" data-lang="" data-unlink>img = np.float32(PIL.Image.open(&#39;sky1024px.jpg&#39;)) showarray(img)</pre> <p>これを,</p> <pre class="code" data-lang="" data-unlink>img = np.float32(PIL.Image.open(&#39;/opt/pictures/foobar.jpg&#39;)) showarray(img)</pre> <p>に書き換え,フォーカスを合わせた状態で実行 ▸ ボタンを押します. これで画像が読み込めれば成功です. あとは改めて deepdream を行っている行を実行します. 結果は,ブラウザの「画像に名前を付けて保存」で保存してもいいでしょうし,Python で</p> <pre class="code" data-lang="" data-unlink>frame=deepdream(net, img) PIL.Image.fromarray(np.uint8(frame)).save(&#34;/opt/pictures/foobare_result.jpb&#34;)</pre> <p>と書いても良いでしょう.</p> <h3>その他の実装</h3> <p><a href="https://github.com/jcjohnson/cnn-vis"><code>github.com/jcjohnson/cnn-vis</code></a> にて,独立実装による Inceptionism の再現実験が試みられています.こちらでは,MIT Places データセットに対して訓練された GoogLeNet のデータを用いることで,建物に反応する (と思われる) ニューロン層を使った実験も行われています.</p> <h2>Future Work</h2> <p>今回の Dockerfile はあくまで IPython Notebook チュートリアルの実行を目標としているので,DeepDream の処理を動画に対して行ったり,GPU を使って高速化したりはまた別リポジトリで行いたいと思っています.</p> <p>そのうえで,いくつか気になっている点としては,</p> <ul> <li>Caffe が CPU モードで動くのはいいんだけど,CPU 1 コアしか使っていない気がする.</li> <li>ホスト環境のファイル受け渡しが若干面倒なので何とかしたい.</li> <li>ベースにしている Docker イメージから引き継いだ特性として,コンテナ内のユーザーが root な のが若干気にいらない.出来れば root でブラウザを動かしたくない.</li> </ul> <p>あたりでしょうか.この辺はまた時間が取れたら見ていきたいところです,</p> <p>Docker とか Caffe とか普段触ることがないので,詳しい方ぜひおすすめテクニック等教えてください.</p> Sun, 05 Jul 2015 09:21:07 +0900 hatenablog://entry/8454420450100266796 2014 年やったこと - Mozc 編 https://nyaruru.hatenablog.com/entry/2015/02/11/183043 <p>いつもどおりコードが公開されている範囲で.</p> <div class="section"> <h3>実は 2013 年にやっていたこと</h3> <p>OSS Mozc のアップデートタイミングの関係上,<a href="http://nyaruru.hatenablog.com/entry/2014/01/02/120515">2013&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> に載っていなかった内容です.概ね 2013 年末休暇シーズンに余暇としてやっていました.</p> <div class="section"> <h4>Windows 版での候補ウィンドウのカラー絵文字対応</h4> <p>Mozc チームを離れる直前,休暇シーズンということもあって久しぶりに自分の書きたいコードでも書くかと言うことでやってみたのがこのカラー絵文字対応です.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150211/20150211174200.png" alt="f:id:NyaRuRu:20150211174200p:plain" title="f:id:NyaRuRu:20150211174200p:plain" class="hatena-fotolife" itemprop="image"></span><br /> 作業のほとんどは mozc_renderer (独立したプロセスとして動く,候補ウィンドウ表示用プロセス) 内の文字表示処理を DirectWrite に対応させることでした.カラー絵文字専用に追加したコードは数行です.<br /> <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にてリリース.<br /> 変更の大半は <a href="https://code.google.com/p/mozc/source/diff?spec=svn192&r=192&format=side&path=/trunk/src/renderer/win32/text_renderer.cc&old_path=/trunk/src/renderer/win32/text_renderer.cc&old=185">renderer/win32/text_renderer.cc</a> にまとまっています.</p> </div> <div class="section"> <h4>候補ウィンドウの DirectWrite 対応</h4> <p>思い起こせば 2009 年,Mozc の候補ウィンドウ表示を別プロセス化したころから DirectWrite を使うというアイディア自体はありました.緊急性と重要性の高いタスクは他にいくらでもあったことからこのアイディアは長らく放置されていたのですが,カラー絵文字表示の副産物として 4 年越しの実現となります.Windows 8 以前の OS でも,高 DPI 環境ではそれなりにメリットがあるかもしれません.<br /> <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にてリリース.</p> </div> <div class="section"> <h4>ITfFnReconversion::GetReconversion 対応</h4> <p>tsf-mozc が ITfFnReconversion::GetReconversion をサポートしていなかったので実装してみた,というものです.ITfFnReconversion::GetReconversion を使用する一部アプリケーション以外でユーザーの目に見える変化はありません.</p><p>一番わかりやすいのは Microsoft Word で,文字を選択したあと右クリックすると,コンテキストメニュー内に再変換候補が表示されるようになります.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150211/20150211163902.png" alt="f:id:NyaRuRu:20150211163902p:plain:h600" title="f:id:NyaRuRu:20150211163902p:plain:h600" class="hatena-fotolife" style="height:600px" itemprop="image"></span><br /> Mozc 内部のプロトコル的に再変換は対応済みだったので,あとは単純に実装するだけという内容でした.</p> </div> </div> <div class="section"> <h3>2014 年にやったこと</h3> <p>2013 年 12 月末をもって所属的には Mozc チームを離れたこともあり,休日・休暇に作業できる内容であることというのを特に重視していた 2014 年でした.そんなわけで注目してみたのが,OSS 版周りの自主オープンソース活動でした.OSS としてみた Mozc プロジェクトは,特に対外的な締め切りもなく,本当に時間的に余裕があるときだけ作業するのに適しています.また,OSS 化後のソースコードについては個人の PC 環境で作業できるので,喫茶店や旅行先でコードを見たり変更したりしながらあれこれ試せるのも嬉しいポイントでした.</p><p>OSS Mozc を選んだもうひとつの理由としては,最近モバイル OS 向けに OSS Mozc をベースにした IME を作っていただけるケースが増えていて,少し応援してみたくなったというのもあります.数字的にも合計数百万インストールという規模で,OSS としてはまずまずの成果.間接的にモバイル IME 開発の活発化に貢献できるのであれば,休日の使い方としてはまずまず Mobile First かなと思った次第.</p><p>さて,2014 年のテーマとして個人的に興味があったのは,社内リポジトリから OSS リポジトリへに変更を移動するとき,そのコミット粒度を小さくするのは可能か,というものでした.</p><p>これまで OSS Mozc といえば,いわゆる "code drop" 方式でリリースされていました.開発自体は社内のリポジトリで行い,しかるべきタイミングに (たいていはプロプライタリな製品として社外にリリースされたあと),開発されたソースコードを OSS として公開する,というものです.このとき問題になるのがコミットログで,OSS Mozc は様々な理由から変更は 1 つの SVN コミットにまとめられ,数千行から多いときは数万行の変更になることもありました.この巨大なコミットに含まれる変更点全てを把握するは開発者自身にとっても難しく,コミットログやリリースノートを書くときに苦労したのを憶えています.</p><p>そこで試してみることにしたのが,OSS 化して問題ない変更については,確認の上,個別のコミットとして OSS リポジトリに適宜反映させていくというものでした.作業自体は休日等の空き時間を利用して行っています.2014年5月24日から12月25日の間に,222 個のコミットを行いました (うち 81 コミットは 2014年12月6日から12月31日までの間,有給消化の年末休暇中に行っています).</p> <ul> <li><a href="https://code.google.com/p/mozc/source/list?start=470&num=265">2014&#x5E74;5&#x6708;24&#x65E5;&#x304B;&#x3089;12&#x6708;25&#x65E5;&#x306E;&#x9593;&#x306E;&#x30B3;&#x30DF;&#x30C3;&#x30C8;&#x4E00;&#x89A7;</a></li> </ul><p>残念ながら <a href="https://code.google.com/p/mozc/source/detail?r=467">r467</a> だけは従来通りの巨大コミットになってしまいましたが,これは Android 向け新機能が多数含まれるため分けきれなかったというのが理由です.それ以前の 218 個のコミットはコミットメッセージと変更が (概ね) 対応した通常のコミットに見えるようになっています.変更の粒度を下げたことで,最後の巨大コミットを待つことなく,27 個のバグを閉じることができました.</p><p>この作業,個人的に何が新鮮に感じたかというと,それがある種の &lt;コミット後レビュー&gt; だったことです (このあたりの話,<a href="http://steps.dodgson.org/b/2012/08/18/code-review-styles/">&#x30B3;&#x30FC;&#x30C9;&#x30EC;&#x30D3;&#x30E5;&#x30FC;&#x3044;&#x308D;&#x3044;&#x308D; - steps to phantasien</a> を先に読むことをおすすめ).会社に入って以来,&lt;コミット前レビュー&gt; は 6 年ぐらいやってきたものの,&lt;コミット後レビュー&gt; を継続的にやったのはこれが初めてでした.<br /> 感想 1.既にコミット済みのコードに対するレビューなので,気になるところを修正するとそれが別コミットになってしまう.<br /> 感想 2.ある程度の期間のコミットの差分をまとめて見たことで,無駄なコードが増えたのに気付きやすくなる.以下典型的なケース.</p> <ol> <li>ある問題に,A という方法で対処する</li> <li>A という方法では完全に問題が解決できないことが分かり B という方法に切り替える</li> </ol><p>複数のコミットが数日から数週間の間に加えられていたとき.あとで全体の差分を見てみると不要な変更が残ってしまっているケースを数件発見.これは確かに &lt;コミット前レビュー&gt; で見つけにくいパターンかも.</p><p>まあそんなわけで新鮮でもあった細切れ OSS 化作業ですが,休日の時間を結構吸い取られる作業であったのも確かで,今後どうするかはまだ決めていません.</p><p>一方,OSS 版リポジトリを活用し,実際にバグを直したり技術的負債を返済したりといったことも行っていました.以下は,そんな休日自主オープンソース活動についてです.</p> <div class="section"> <h4>TF_E_NOLAYOUT 問題</h4> <p>Mozilla Japan の中野さんから<a href="https://productforums.google.com/forum/#!topic/ime-ja/GmpJZHWpDCk">&#x5831;&#x544A;&#x3057;&#x3066;&#x3044;&#x305F;&#x3060;&#x3044;&#x305F;</a>問題です.調査の結果,以下のような OS 側の問題であることが分かりました.</p> <ol> <li>TSF で書かれた IME (TIP) が ITfContextView::GetTextExt() を呼び出す.</li> <li>TSF ランタイムがアプリケーションの実装する ITextStoreACP::GetTextExt() を呼び出す</li> <li>アプリケーションが ITextStoreACP::GetTextExt() に対して TS_E_NOLAYOUT を返す</li> <li>TSF ランタイムが戻り値を E_FAIL に書き換える</li> <li>TSF で書かれた IME (TIP) が ITfContextView::GetTextExt() の結果として E_FAIL を受け取る</li> </ol><p>開発元のサポートに相談したところ,ITfContextView::GetACPFromPoint() と ITfContextView:: GetRangeFromPoint() にはこの問題がないことが分かり,TS_E_NOLAYOUT が返されているかどうかの判定をこれらの API で行うという回避策をおすすめされました.その方針で tsf-mozc 側にて対処してみた,というのが一連の流れとなります.<br /> <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にてリリース.コード的には以下となります.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/win32/tip/tip_range_util.cc?r=192#231">https://code.google.com/p/mozc/source/browse/trunk/src/win32/tip/tip_range_util.cc?r=192#231</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink>HRESULT TipRangeUtil::GetTextExt(ITfContextView *context_view, TfEditCookie read_cookie, ITfRange *range, RECT *rect, <span class="synType">bool</span> *clipped) { BOOL clipped_result = FALSE; HRESULT hr = context_view-&gt;GetTextExt( read_cookie, range, rect, &amp;clipped_result); <span class="synStatement">if</span> (clipped != nullptr) { *clipped = (clipped_result != FALSE); } <span class="synComment">// Due to a bug of TSF subsystem, as of Windows 8.1 and prior,</span> <span class="synComment">// ITfContextView::GetTextExt never returns TF_E_NOLAYOUT even when an</span> <span class="synComment">// application returns TS_E_NOLAYOUT in ITextStoreACP::GetTextExt. Since this</span> <span class="synComment">// bug is specific to ITfContextView::GetTextExt, a possible workaround is</span> <span class="synComment">// to also see the returned value of ITfContextView::GetRangeFromPoint.</span> <span class="synComment">// If the attached application implements ITextStoreACP::GetACPFromPoint</span> <span class="synComment">// consistently with ITfContextView::GetTextExt,, we can suspect if E_FAIL</span> <span class="synComment">// returned from ITfContextView::GetTextExt comes from TF_E_NOLAYOUT.</span> <span class="synStatement">if</span> (hr == E_FAIL) { <span class="synComment">// Depending on the internal design of an application, the implementation of</span> <span class="synComment">// ITextStoreACP::GetACPFromPoint can easily be computationally expensive.</span> <span class="synComment">// This is why we should carefully choose parameters passed to</span> <span class="synComment">// ITfContextView::GetRangeFromPoint here.</span> <span class="synType">const</span> POINT dummy_point = { numeric_limits&lt;LONG&gt;::min(), numeric_limits&lt;LONG&gt;::min() }; CComPtr&lt;ITfRange&gt; dummy_range; <span class="synType">const</span> HRESULT next_hr = context_view-&gt;GetRangeFromPoint( read_cookie, &amp;dummy_point, <span class="synConstant">0</span>, &amp;dummy_range); <span class="synStatement">if</span> (next_hr == TF_E_NOLAYOUT) { hr = TF_E_NOLAYOUT; } } <span class="synStatement">return</span> hr; } </pre><p>ちなみにこの問題,現在ベータテスト中の Windows 10 では OS 側で無事修正されている模様です.<blockquote class="twitter-tweet" lang="HASH(0x8e363f8)"><p>Win10 + Nightly + Google日本語入力で試してみたところ、TSFの、ITextStoreACP::GetTextExt()で、TS_E_NOLAYOUTを返しても、TIPにE_FAILが返されてしまってたバグは修正されてるっぽい? <a href="https://twitter.com/hashtag/%E3%82%82%E3%81%9A%E3%81%A7%E3%81%B6?src=hash">#もずでぶ</a> <a href="https://twitter.com/NyaRuRu">@NyaRuRu</a></p>&mdash; なかのん DAYS&#39;&#39; (@d_toybox) <a href="https://twitter.com/d_toybox/status/517359169934856193">October 1, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> </p> </div> <div class="section"> <h4>TSF を有効にした Firefox がフォーカスを失ったとき候補ウィンドウが表示されたままになる</h4> <p>tsf-mozc と TSF-aware Firefox の組み合わせで,文字入力中に別アプリケーションにフォーカスを移すと,Mozc の候補ウィンドウが表示されたままになるという問題です.<br /> tsf-mozc 側で ITfThreadFocusSink::OnSetThreadFocus() と ITfThreadFocusSink::OnKillThreadFocus() を処理していなかったのが問題でした.<br /> <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にてリリース.</p> </div> <div class="section"> <h4>Issue 206: 特定ロケールの Windows 環境で prediction/dictionary_predictor.cc をビルドすると C2065 エラーで失敗する</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=206">https://code.google.com/p/mozc/issues/detail?id=206</a><br /> Mozcの C++ で書かれたソースコードは基本的に BOM なし UTF-8 で統一されているのですが,過去何度もVisual C++ が C2065 エラーでコンパイルに失敗するというトラブルに見舞われて来ました.そこで発明された対処法が,とりあえず non-ASCII 文字は "" で囲む,というものです.<br /> OSS Mozc の方に C2065 の報告が来たわけですが,今回も "" で囲って対処となりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にてリリース.</p> </div> <div class="section"> <h4>Issue 215: mozc::Encryptor 実装のポータブル化</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=215">https://code.google.com/p/mozc/issues/detail?id=215</a><br /> mozc::Encryptor というクラスの実装から,プラットフォーム別の処理を極力取り除いたというものです. <br /> Mozc は,確定履歴などいくつかのローカルファイルを保存時に AES256 CBC モードで暗号化します (<a href="https://code.google.com/p/mozc/wiki/DataEncryptionAndPasswordManagement">Design Doc</a> 参照)<br /> 当時この実装はプラットフォームごとに異なっていて, Mac 版, NaCl 版,および Linux デスクトップ版 Mozc では OpenSSL が,Windows 版では Win32 Crypto APIが,そしてAndroid 版では javax.crypto.Cipher クラスが使われていました.<br /> さて,話は 2014 年 2月22日にさかのぼります.当日 Mozilla Japan 東京オフィスで開かれていた FxOS コードリーディングミートアップ #4 にふらりと参加した筆者は,Mozc を Emscripten でビルドできないものかとあれこれ試し始めました.Mozc のビルドは概ね「近寄るべきではない程度に大変」の部類に属しますが,そうはいってもクロスコンパイルの必要な Android 対応と NaCl 対応は既にできているわけです.数時間もあれば最初の一歩ぐらいはなんとかなるだろうと軽い気持ちで始めたものの,結果的に最初の一歩すら踏み出せずに敗退することとなります.</p><p><blockquote class="twitter-tweet" lang="HASH(0x8e363f8)"><p>そもそもOSS MozcはNDK使ったAndroid向けネイティブビルドもNaCl SDK使ったpNaClビルドも対応済みなのに,どうしてこうなった状態.</p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/448467948575793152">March 25, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p><p>このとき最初の一歩として立ちふさがったのが,この OpenSSL 依存でした.以下に,当時私が参考にしようとしていた nacl-mozc の OpenSSL 依存部分を示します.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/base/base.gyp?r=185#508">https://code.google.com/p/mozc/source/browse/trunk/src/base/base.gyp?r=185#508</a></p> <pre class="code" data-lang="" data-unlink> [&#39;target_platform==&#34;NaCl&#34;&#39;, { &#39;targets&#39;: [ { &#39;target_name&#39;: &#39;pepper_file_system_mock&#39;, &#39;type&#39;: &#39;static_library&#39;, &#39;sources&#39;: [ &#39;pepper_file_system_mock.cc&#39;, ], &#39;dependencies&#39;: [ &#39;base.gyp:base&#39;, ], }, { &#39;target_name&#39;: &#39;openssl_crypto_aes&#39;, &#39;type&#39;: &#39;static_library&#39;, &#39;variables&#39;: { &#39;openssl_dir%&#39;: &#39;&lt;(DEPTH)/third_party/openssl/openssl&#39;, }, &#39;direct_dependent_settings&#39;: { &#39;defines&#39;: [ &#39;HAVE_OPENSSL=1&#39;, ], &#39;include_dirs&#39;: [ &#39;&lt;(gen_out_dir)/openssl/include&#39;, &#39;&lt;(openssl_dir)/include&#39;, ], }, &#39;cflags&#39;: [ # Suppresses warnings in third_party codes. &#39;-Wno-unused-value&#39;, ], &#39;include_dirs&#39;: [ &#39;&lt;(gen_out_dir)/openssl/include&#39;, &#39;&lt;(openssl_dir)&#39;, &#39;&lt;(openssl_dir)/crypto&#39;, &#39;&lt;(openssl_dir)/include&#39;, ], &#39;hard_dependency&#39;: 1, &#39;sources&#39;: [ # The following files are the minumum set for &#39;encryptor.cc&#39; &#39;&lt;(openssl_dir)/crypto/aes/aes_cbc.c&#39;, &#39;&lt;(openssl_dir)/crypto/aes/aes_core.c&#39;, &#39;&lt;(openssl_dir)/crypto/aes/aes_misc.c&#39;, &#39;&lt;(openssl_dir)/crypto/mem_clr.c&#39;, &#39;&lt;(openssl_dir)/crypto/modes/cbc128.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha1dgst.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha1_one.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha256.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha512.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha_dgst.c&#39;, &#39;&lt;(openssl_dir)/crypto/sha/sha_one.c&#39;, ], &#39;dependencies&#39;: [ &#39;openssl_config&#39;, ], &#39;export_dependent_settings&#39;: [ &#39;openssl_config&#39;, ], }, { &#39;target_name&#39;: &#39;openssl_config&#39;, &#39;type&#39;: &#39;none&#39;, &#39;actions&#39;: [ { &#39;action_name&#39;: &#39;openssl_config&#39;, &#39;inputs&#39;: [ &#39;openssl_config.sh&#39;, ], &#39;outputs&#39;: [ &#39;&lt;(gen_out_dir)/openssl/include/openssl/opensslconf.h&#39;, ], &#39;action&#39;: [ &#39;bash&#39;, &#39;openssl_config.sh&#39;, &#39;&lt;(gen_out_dir)&#39;, &#39;$(abspath ./)&#39;, ], }, ], }, ]}, ], ], }</pre><p>ここでやっているのは,OpenSSL のソースコードがダウンロード済みと仮定して,configure スクリプトを走らせ,ターゲットの toolchain でビルドする,というものです.asm.js 版 Mozc を作るにあたって,これとほぼ同様の作業を行う必要がありました.一方 Android 版も, JNI を使って javax.crypto.Cipher クラスの一部を C++ に公開するという,処理的にもビルド設定的にも非常に複雑な実装になっていることが分かりました.<br /> 実は Mozc がローカルにファイルを保存するときの暗号化処理は,"カジュアルな" 情報漏洩対策という何とも微妙な目的で導入されたという過去があります.デスクトップ版のみであった最初期は,この機能による複雑さの増加もまだ許容できたのかもしれませんが, Android 版や NaCl 版開発時に「がんばって移植すべき機能」のひとつになってしまったのは不幸でした.これらの環境では,システムの OpenSSL を単純に呼び出すといった方法が使えなかったため,ビルド時に OpenSSL 自体をビルドしたり,JNI コードを追加したりといった方法で対処されることとなりました.このがんばりは,予定されたスケジュールまでに製品をリリースするという点では有効でしたが,残ることになった複雑さはまさに技術的負債でした.<br /> さて,よくよく処理内容を調べてみると,SHA1 と AES256 CBC の計算で,きちんと認証を受けた OS 固有実装を利用しようとした結果,物事が複雑化しまっていることがわかります.しかしながら,もともと "カジュアルな" 情報漏洩対策でしかない暗号化処理で,FIPS 認定にこだわるというのも変な話です.だったら自前で SHA1 と AES256 CBC を実装してしまえば,大幅にビルドが単純になるだろう,と始めてみたのがこの Issue 215 となります.<br /> 基本実装は <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> に含まれていますが,この時点では旧実装も残されていました.その後,<a href="https://code.google.com/p/mozc/source/detail?r=208">r208</a>,<a href="https://code.google.com/p/mozc/source/detail?r=209">r209</a>,<a href="https://code.google.com/p/mozc/source/detail?r=497">r497</a> として旧実装は削除されています.<br /> 規格を読みながら有名アルゴリズムを実装するのは楽しい体験でした.計算結果の比較のために見ていた Chromium の SHA1 実装にバグを見つけるというおまけもありました (<a href="https://code.google.com/p/chromium/issues/detail?id=348333">Chromium Issue 348333</a>) .4 月に OpenSSL の Heartbleed が盛り上がったのも,面白い偶然の一致です.<br /> まとめると,以下のようなメリットがあったものと考えています.</p> <ul> <li>実行時に依存するライブラリが少なくなる</li> <li>ビルドが単純化される</li> <li>プラットフォーム共通コードが増える</li> <li>(OSS Mozc に GPL コードを組み合わせたい人にとっての),潜在的なライセンス非互換問題のリスクが減る</li> </ul> </div> <div class="section"> <h4>Issue 211: 2 段階ビルドを廃止</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=211">https://code.google.com/p/mozc/issues/detail?id=211</a><br /> 従来,たとえば Android 版 Mozc の APK をビルドするときには,以下のようにコマンドを 3 回実行する必要がありました.</p> <pre class="code" data-lang="" data-unlink>python build_mozc.py gyp --target_platform=Android python build_mozc.py build_tools -c Release python build_mozc.py build -c Debug_Android android/android.gyp:apk</pre><p>これが,以下のようにコマンド 2 回でビルドできるようになった,というものです.</p> <pre class="code" data-lang="" data-unlink>python build_mozc.py gyp --target_platform=Android python build_mozc.py build -c Debug android/android.gyp:apk</pre><p>Mozc のビルドが build_tools というコマンドと build の 2 段階に分けられたのは,実に 2010 年,Mozc を OSS 化するにあたってビルドシステムを GYP に移行するさなかのことでした.当初の動機は,時間のかかるバイナリ辞書圧縮処理を開発中何度も実行したくないという理由でした.状況が変わったのは,Android 版や NaCl 版の必要がでてきてからです.これらのプラットフォームはクロスコンパイルを必要とし,そのための基盤として 2 段階ビルドが「利用」されました.ビルドの複雑さは一時制御不能な規模までふくれあがり,一見正しく見える変更が,なぜか Android ビルドだけを壊すという問題が多発しました.記憶が確かなら 2011 年から 2012 年頃が最も酷かったように思います.<br /> このひどい状況は,2013 年末,Android 版ビルドが GYP の Android.mk ジェネレータから一般的な make ジェネレータに切り替えられることで大幅に改善され,今回 FxOS コードリーディングミートアップ #4 に参加したのを切っ掛けに取り払ってみた感じです.<br /> ちなみに 2010 年ごろ懸念されたビルド時間の問題も,今時のワークステーションで作業する分には概ね問題になりません.<br /> 基本実装は <a href="https://code.google.com/p/mozc/source/detail?spec=svn192&r=192">r192</a> にて.その後,<a href="https://code.google.com/p/mozc/source/detail?r=211">r211</a>および<a href="https://code.google.com/p/mozc/source/detail?r=214">r214</a>にて有効化されました.<br /> 2 段階ビルドに使用されたコードはその後 <a href="https://code.google.com/p/mozc/source/detail?r=371">r371</a> および <a href="https://code.google.com/p/mozc/source/detail?r=507">r507</a> として完全に削除されます.</p> </div> <div class="section"> <h4>Issue 224: enable_gtk_renderer=0 指定時にビルドが失敗する</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=224">https://code.google.com/p/mozc/issues/detail?id=224</a><br /> Linux 版 Mozc で, mozc_renderer を無効にした状態でビルドしようとするとコンパイルエラーになるという問題.単純なミスだったので即修正となりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=215">r215</a> にて修正.</p> </div> <div class="section"> <h4>Unicode 絵文字変換を NaCl 環境および Linux デスクトップ環境でもデフォルト有効化</h4> <p>今までは特定環境のみ Unicode 絵文字をデフォルト有効化というロジックだったのですが,コードがだいぶ複雑になってしまっていたので,逆に特定環境のみデフォルト無効化というロジックに変更しました.このときの簡略化の一環で, NaCl 環境および Linux デスクトップ環境でも Unicode 絵文字変換はデフォルト有効化となりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=229">r229</a>,<a href="https://code.google.com/p/mozc/source/detail?r=230">r230</a>,<a href="https://code.google.com/p/mozc/source/detail?r=231">r231</a> の 3 つのコミットにより有効化.</p> </div> <div class="section"> <h4>Issue 226: ibus-mozc の周辺文字列取得コードが正しく動作していなかった</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=226">https://code.google.com/p/mozc/issues/detail?id=226</a><br /> ibus-mozc の周辺文字列の取得コードにバグがあって,UTF-8 文字列のバイトオフセットを使って部分文字列を切り出すべきところに,間違って文字数を使って部分文字列を切り出していたというもの.結果的に,ibus-mozc で周辺文字列を考慮した変換が意図しない形で動作してしまっていました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=232">r232</a> および <a href="https://code.google.com/p/mozc/source/detail?r=233">r233</a> にて修正.</p> </div> <div class="section"> <h4>Issue 227: IBus 1.5 環境下で確定取り消しが動作しない</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=227">https://code.google.com/p/mozc/issues/detail?id=227</a><br /> <a href="https://code.google.com/p/mozc/issues/detail?id=201">Issue 201</a> 修正の副作用で,ibus-mozc を IBus 1.5 環境下で使用しているとき,確定取り消し (MS-IME キー設定で言うところの Ctrl+BS) が動作しなくなっていた,という問題の修正です. <br /> <a href="https://code.google.com/p/mozc/source/detail?r=234">r234</a> にて修正.</p> </div> <div class="section"> <h4>Issue 233: ibus-mozc 使用時,MozcTool に対応するテキストラベルが存在しない</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=233">https://code.google.com/p/mozc/issues/detail?id=233</a><br /> MozcTool に対応するテキストラベルが存在せず,空白のエントリが表示されるというものです. IBus 1.4 環境までは言語バー的な UI が標準で表示されていたため問題になりませんでしたが,IBus 1.5 環境で言語バー的な UI が廃止されたためこの問題が表面化する可能性が高くなりました.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150211/20150211174258.png" alt="f:id:NyaRuRu:20150211174258p:plain" title="f:id:NyaRuRu:20150211174258p:plain" class="hatena-fotolife" itemprop="image"></span><br /> ちょうど社内のワークステーションが Ubuntu 14.04 に切り替わるタイミングだったので,同僚から言われる前に IBus 1.5 関係のやり残しタスクの一環で直してみた感じです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=251">r251</a> にて修正.</p> </div> <div class="section"> <h4>Issue 236: Windows 8.1 update1 環境で Explorer がクラッシュすることがある</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=236">https://code.google.com/p/mozc/issues/detail?id=236</a><br /> 安定性の確認もかねて,家でときどき tsf-mozc を使っていたところ,Windows 8.1 update1 環境で Explorer がクラッシュする確実な手順を発見したので,デバッグ・対処してみたというものです.再現率 100% なので, Visual Studio で簡単にデバッグできるかと思いきや,windbg で WinRT の内部まで潜る必要があって大変でした.<a href="http://blogs.msdn.com/b/ntdebugging/archive/2014/01/13/debugging-a-windows-8-1-store-app-crash-dump.aspx">Ntdebugging Blog &#x306E;&#x8A18;&#x4E8B;</a>を見つけられなければデバッグは無理だったように思います.WinRT で言語共通の実行時例外がどのように実装されているか興味がある人には,この記事面白いかもしれません.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=230">r252</a> にて対処.</p> </div> <div class="section"> <h4>Issue 222: Linux デスクトップ, NaCl, および Android ビルドで Ninja を使用する</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=222">https://code.google.com/p/mozc/issues/detail?id=222</a><br /> <a href="http://nyaruru.hatenablog.com/entry/2013/03/31/172627">2012&#x5E74;&#x4ED6;&#x306B;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> で書いたように,2012 年末から Windows 版 Mozc は Ninja でビルドされるようになっていたのですが,これを Linux デスクトップ, NaCl, および Android ビルドでも使うようにしたというものです.<br /> やってみて分かったのですが,どうも GYP の Ninja ジェネレータとmake_global_settings という GYP の設定の組み合わせで Android 向けクロスビルドを行ったのは Mozc が最初らしく,結局自分で GYP 側も直す必要がありました.以下のようにせっせと GYP 側にパッチを送っていたりします.たまに役立つ GYP コミット権.</p> <ul> <li><a href="https://code.google.com/p/gyp/source/detail?r=1931">GYP r1931</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1934">GYP r1934</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1935">GYP r1935</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1937">GYP r1937</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1939">GYP r1939</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1940">GYP r1940</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1941">GYP r1941</a></li> <li><a href="https://code.google.com/p/gyp/source/detail?r=1942"> GYP r1942</a></li> </ul><p>Mozc 側では,<a href="https://code.google.com/p/mozc/source/detail?r=265">r265</a>, <a href="https://code.google.com/p/mozc/source/detail?r=266">r266</a>, <a href="https://code.google.com/p/mozc/source/detail?r=267">r267</a>, <a href="https://code.google.com/p/mozc/source/detail?r=268">r268</a> の 4 回に分けて有効化されました.</p> </div> <div class="section"> <h4>Issue 240: Linux デスクトップ, NaCl, および Android ビルド環境構築のための Dockerfile の提供開始</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=240">https://code.google.com/p/mozc/issues/detail?id=240</a> <br /> OSS Mozc の公式ビルド環境を Docker で定義してみよう,と Docker の勉強がてらやってみました.特に Android 版 Mozcのビルド環境を Docker 化できたおかげで,その後のビルドの検証がだいぶ楽になりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=271">r271</a> にて Ubuntu 12.04 ベースのコンテナを提供開始.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=330">r330</a> にて Ubuntu 14.04 ベースのコンテナの試験提供を開始しました.<br /> なお, <a href="https://code.google.com/p/mozc/source/detail?r=486">r486</a> で Ubuntu 12.04 ベースのコンテナは役目を終了し,以後は Ubuntu 14.04 に一本化しています.</p> </div> <div class="section"> <h4>Ninja の Console Pool 機能を有効化</h4> <p><a href="https://code.google.com/p/mozc/source/detail?r=314">https://code.google.com/p/mozc/source/detail?r=314</a><br /> Ninja 1.5 の新機能に Console Pool というのがあって,これが Mozc の Android ビルドのときに使えるかなと試してみたものです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=314">r314</a> にて有効化.</p> </div> <div class="section"> <h4>Issue 246: Linux, NaCl, および Android 環境で,'Set input mode to X' コマンドが直接入力モードで動作しない</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=246">https://code.google.com/p/mozc/issues/detail?id=246</a><br /> <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1119048">https://bugzilla.redhat.com/show_bug.cgi?id=1119048</a><br /> Red Hat Bugzilla で ibus-mozc 向けに報告されていた問題で,キーマップエディタで直接入力モード時に「ひらがなモードに切り替え」というコマンドを設定したとしても,実際には動作しないという問題です.<br /> Windows では問題なく動作するのですが,動作するプラットフォームが実はホワイトリスト方式になっていて,Windows 以外では意図的に受け付けないようになっていました.実際には Mac 以外で許可することに問題はないので,そのように対処した,というものです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=315">r315</a> にて修正.</p> </div> <div class="section"> <h4>Issue 244: Visual C++ 2013 対応</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=244">https://code.google.com/p/mozc/issues/detail?id=244</a><br /> OSS Mozc を Visual Studio 2013 でビルドできるようにしてみた,というものです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=311">r311</a> 以降で対応.<br /> ちなみにこの後 <a href="http://visualstudio.com/free">Visual Studio Community</a> がリリースされたおかげで,無償版の Visual Studio を利用して OSS Mozc Windows 版をビルドできるようになっています.<br /> なお, <a href="https://code.google.com/p/mozc/source/detail?r=509">r509</a> 以降では Visual Studio 2013 にサポートするコンパイラを一本化しています.</p> </div> <div class="section"> <h4>About ダイアログ上の Copyright 表記の更新</h4> <p>2014 年も半分以上過ぎているのに,About Dialog 上の Copyright 表記が 2013 年のままだったので直したというものです. <br /> <a href="https://code.google.com/p/mozc/source/detail?r=324">r324</a> にて修正.</p> </div> <div class="section"> <h4>アプリケーションマニフェストに Windows 10 対応宣言を追加</h4> <p>Windows 版の実行ファイル全てに,Windows 10 対応という GUID をセットするというものです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=344">r344</a> にて対処.</p> </div> <div class="section"> <h4>UserHistoryStorage の 2038 年問題</h4> <p>Mozc の入力履歴ファイル内で使用されるタイムスタンプが 2038 年以降不正な値になるという問題です.たまたまコードを眺めていて発見したので直してみました.修正自体はほぼ Protocol Buffers で定義されたデータ型の型を uint32 から uint64 に変更するだけといえます.Protocol Buffers の特徴として,この変更に関しては互換性と保存されるデータサイズ的に影響を及ぼさないと分かっていたため,割と気軽に直すことができました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=346">r346</a> にて対処.</p> </div> <div class="section"> <h4>SafeStrToDouble/SafeStrToFloat を Android 環境で再度有効化</h4> <p><a href="https://code.google.com/p/mozc/source/detail?r=370">https://code.google.com/p/mozc/source/detail?r=370</a><br /> 特定バージョンの Android NDK でビルドすると,strtod に 16 進数表記の文字列を渡したときの挙動に非互換の変更があったため,Android 環境で一部のテストを無効化されていたのですが,Android NDK r10c でこの問題が修正されたためテストを再度有効化したというものです.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=370">r370</a> にて対処.</p> </div> <div class="section"> <h4>Issue 249: Windows 8 以降の環境でスタート画面に統合された IME 候補表示が正しく動作しない</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=249">https://code.google.com/p/mozc/issues/detail?id=249</a><br /> これも家で tsf-mozc を使っていて発見した問題です.当時実験的に tsf-mozc でITfFnSearchCandidateProvider をサポートしていたのですが,どうも実装が不完全だったため逆に問題のある挙動になってしまっていたらしく,該当機能を無効化することで対処となりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=329">r329</a> にて修正.</p> </div> <div class="section"> <h4>Issue 248: Android 環境に物理キーボードを接続し,デッドキーを使用するとクラッシュする</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=248">https://code.google.com/p/mozc/issues/detail?id=248</a><br /> OSS Mozc の Issue Tracker に寄せられた報告です.Android 環境での Mozc のデッドキーイベントの扱いに問題があり,特定キーボードレイアウトで特定キーシーケンスを入力すると必ず Mozc がクラッシュしてしまっていました. <br /> <a href="https://code.google.com/p/mozc/source/detail?r=463">r463</a> にて修正.</p> </div> <div class="section"> <h4>Issue 255: ibus-mozc を XIM プロトコルで使用すると,フォーカスロスト時にプリエディットがクリアされない</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=255">https://code.google.com/p/mozc/issues/detail?id=255</a><br /> OSS Mozc の Issue Tracker に寄せられた報告です.元々は日本 IBM の人から SUSE Linux に報告が寄せられ,さらに openSUSE の Issue Tracker を経ての報告だそうです.<br /> ibus-mozc を XIM プロトコルで使用し,gedit 上でプリエディットが残っている状態で,別アプリケーションにフォーカスを移し,再度 gedit にフォーカスを戻すと,以前のプリエディットは既に確定されているのに,ibus-mozc は以前のプリエディットの内容が残ったままであるかのように振る舞う,という問題でした.<br /> 調べてみると Mozc 1.2.809.102 より前のバージョンではこのケースでも正しく動いていたものの, Chromium OS (当時はまだ IBus を使用していた)でのフォーカス周りのバグに対処すべくあれこれ変更するうちに現在の挙動になってしまったということが分かりました.<br /> <a href="https://code.google.com/p/mozc/source/detail?r=386">r386</a> にて修正.</p> </div> </div> <div class="section"> <h3>2015 年の話とか</h3> <p>今年は休日の空き時間があまり読めないので,分からないというのが正直なところです.少なくとも OSS 化作業については,Android 5.0 向けの OSS 化が一息ついたので,多少は時間が稼げたんではなかろうかと.</p><p>もし何かひとつ優先するすれば,今年こそ不要コードの削除に注力したいかなと.Windows XP 対応のために入れていたコードや,もうあまり意味の無さそうなパフォーマンスチューニング,古いコンパイラのために必要だったコードなどなど.書いた本人ならすぐに判断がつくものの,もし仮に誰かが引き継いでしまうと消していいかの判断がつかなくなりそうなものは今のうちに消してしまいたいと思う次第.</p><p>次点としては,Windows 版向けにずっとやりたかったことあれこれ,たとえば OSS 版のインストーラーを動くようにするとか per-monitor DPI-aware 対応とか.とはいえ,すべては今年の休日具合次第なんですけどね.あとどんなミートアップに参加するかも.</p> </div> <div class="section"> <h3>過去編</h3> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2014/01/02/120515">2013&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/03/31/172627">2012&#x5E74;&#x4ED6;&#x306B;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/01/01/134011">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul> </div> Wed, 11 Feb 2015 18:30:43 +0900 hatenablog://entry/8454420450083176968 2014 年やったこと - Chromium 編 https://nyaruru.hatenablog.com/entry/2015/01/04/210639 <p>Chromium 関係,コードはあまり書いていない一年でした.数字としてはコミット 17 回,コードレビュー 13 回となります.一方 Issue Tracker 上での活動はまあそれなりにで,Issue 登録 19 回,コメントを書き込んだり状態を変更したりといった Issue の数は 173 件となりました.</p> <div class="section"> <h3>自分でやったこと</h3> <div class="section"> <h4>Windows 版 Chromium の Aura 移行完了後不要になった IME 関連コードの削除</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=319122">Issue 319122 - chromium - Remove TSFEventRouter[Observer], InputMethodTSF, and related unused code. - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>2014 年 1 月から 2 月にかけて,Aura + Ash 移行に伴い不要になった IME 関連コードの削除をやっていました.既にチームを移っていたこともあり,最後の後片付けという感じです.書くだけ書いて後片付けを次の人に任せるのは気が引けたというのもありますし,Chromium に関わり始めた 2012 年ごろ,おっかなびっくり書いたやっつけコードを自らの手で消し去る良い機会だったというのもあります.</p> </div> <div class="section"> <h4>Windows 版 Chromium で HiDPI 有効化時に IME の候補ウィンドウの位置がずれる問題の修正</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=260529">Issue 260529 - chromium - IME UI is not placed at proper position when HiDPI is enabled - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150104/20150104153618.png" alt="f:id:NyaRuRu:20150104153618p:plain" title="f:id:NyaRuRu:20150104153618p:plain" class="hatena-fotolife" itemprop="image"></span><br /> 2013 年に自分が登録したバグですが,普段使っている Windows ノート PC がこの影響を受けていてあまりにも不便だったので,土日の空き時間を使って自分で直してみたものです.</p> </div> <div class="section"> <h4>Android 5.0 の新 IME API への対応 (未完)</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=424866">Issue 424866 - chromium - Support InputMethodManager#updateCursorAnchorInfo for Android 5.0 - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>後で改めて書くかと思いますが,2014 年のメインプロジェクトの仕事のひとつで Android 5.0 にいくつか IME API を追加,というのをやっておりました.追加した API は <a href="http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html#updateCursor(android.view.View, int, int, int, int)">InputMethodManager.html#updateCursor</a> API の置き換えを狙ったもので,変換中の文字列のスクリーン座標を IME に伝えられるようにするものです.さて,この種の新 API の宿命として,IME だけでなくテキスト入力 widget 側にも新 API 対応が必要になります.Android の標準 TextView を使っているアプリケーションであれば何もしなくてよいのですが,独自にテキスト描画を行っているアプリケーションではそうはいきません.Chromium も当然ながらこのカテゴリに属し,Android 5.0 の SDK を使用して割と面倒なコードを追加する必要がありました.この仕事,当初は Chromium Android 版チームの人に頼もうかと漠然と考えていたのですが,Android 5.0 の開発期間中にとりあえず動く検証用コードを書き上げてしまったこともあり,なし崩し的に自分で対応コードを追加することになったという感じです.<br /> とはいえコードレビューでのリクエストに色々応えていたらだいぶ規模が大きくなり,そのまま年末休暇シーズンに突入してしまったため,実現は 2015 年に持ち越しとなりました.</p> </div> </div> <div class="section"> <h3>Issue Tracker 上で情報提供しつつ直してもらったものからいくつか</h3> <div class="section"> <h4>base::SHA1HashBytes に 4 GB 以上のデータを渡すと誤ったハッシュ値を返す</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=348333">Issue 348333 - chromium - Security: base::SHA1HashBytes produces wrong SHA1 hash when |len| &gt;= 4GB - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>別件で SHA1 Hash の計算式を調べていたときに,参考に見てみた Chromium の内部関数に問題を見つけてしまったというものです.ざっと見てみた範囲では問題になるケースは見つけられませんでしたが,念のためセキュリティバグとして報告,修正してもらいました.</p> </div> <div class="section"> <h4>Chrome Remote Desktop (Chromoting) のウィンドウ上ではクライアント環境の IME は常にオフにすべき</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=401371">Issue 401371 - chromium - IME should never be enabled in Chromoting window - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>仕事で Chrome Remote Desktop (内部コードネーム Chromoting) を使うことが良くあるのですが,IME 関係で不満があったので変更を提案して対応してもらったというものです.<br /> Windows 環境から Linux 環境に Chrome Remote Desktop で接続するケースを考えてみます.このとき,Chrome Remote Desktop のウィンドウ上でクライアント側 (Windows 側) の IME を有効にすることができてしまっていました.しかし,確定した文字列は単に捨てられてしまうという状況でした.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20150427/20150427054704.png" alt="f:id:NyaRuRu:20150427054704p:plain" title="f:id:NyaRuRu:20150427054704p:plain" class="hatena-fotolife" itemprop="image"></span><br /> これは,特に機能として役立っていないだけではなく,パスワードを意図せず IME に学習させてしまうなど望ましくない動作でした.そこで,クライアント側の IME を完全にオフにするという提案をしてみた次第です.<br /> 以前 Pepper SDK の IME 周りを担当されていた kinaba@ さんの的確なアドバイスのおかげで,数日のうちに対応していただくことができました.</p> </div> <div class="section"> <h4>Time::EnableHighResolutionTimer(false) が無視されることがある</h4> <p><blockquote class="twitter-tweet" lang="HASH(0x851ad98)"><p><a href="http://t.co/JTur7YYQ3y">http://t.co/JTur7YYQ3y</a>&#10;これ,Chromiumのソースを読むと若干印象が違うんですよね.&#10;timeBeginPeriodは気を付けろ的な長いコメントは実際書いてあるし,バッテリー駆動時にはtimeBeginPeriod(1)呼ぶのを避けようとしてたり.</p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/489047353387528192">July 15, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="HASH(0x851ad98)"><p>かなり初期からそうなっていたはず.2009年1月のGoogle Chrome Out of Beta Partyにお呼ばれしたときにこのネタでLTした記憶が……&#10;<a href="http://t.co/8jPmv2kGHo">http://t.co/8jPmv2kGHo</a></p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/489048058408087552">July 15, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="HASH(0x851ad98)"><p>んで,まずいのは実はこの辺の挙動が継続的にテストされていないということかなぁと.実際,2009年1月当時LTしたときも,実は電源抜き差しイベントのモニタリングの実装が壊れていてなんかずっと電源つながっている状態と誤認されていました的な状態だったと.</p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/489049515152789506">July 15, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="HASH(0x851ad98)"><p>2013年にも,WM_POWERBROADCASTイベントのモニタリングが8ヶ月ぐらい壊れたままだったのに誰も気づかなかった事件とか.&#10;<a href="https://t.co/2je9isJfdJ">https://t.co/2je9isJfdJ</a></p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/489050309650423808">July 15, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="HASH(0x851ad98)"><p>教訓としては,継続的テストの実行環境の中に,バッテリーモード動作をテストするための環境をちゃんと作るのが重要,というあたりでしょうか.でないと,バッテリーモードで動作するとき特有の挙動がテストできないですよ,と.</p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/status/489053058060402689">July 15, 2014</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> 2014 年 7 月頃,ネットメディアを中心に Windows 版 Chrome の電力消費量が話題になったことがありました.報道に関して色々言いたいことはあったものの,実際うまく動作しないケースが存在することも知っていたので,念のため知っていることを Issue Tracker にコメントしておきました.実際には他にも色々問題があったらしく,しばらくしてまとめて修正していただきました.マルチスレッド絡みバグがたくさん見つかったそうです.</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=153139#c69">Issue 153139 - chromium - System clock rate: Chrome is not battery friendly on Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul> </div> <div class="section"> <h4>base::PowerMonitor::AddObserver と base::PowerMonitor::RemoveObserver が同じスレッドで呼ばれないことによる use-after-free</h4> <p>たまたま自分の目の前で Google Chrome Canary がクラッシュしたので,クラッシュダンプを頼りに Issue Tracker 上で原因究明に協力したものです.Issue としては以下のものになります.(Chromium ではクラッシュバグは原則セキュリティバグ扱いのため,特定アカウントでログインしていない限り以下のページは表示されません.面倒な仕組みですみません)</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=404767#c2">Chromium Issue 404767</a></li> </ul><p>仮想関数呼び出しで EXCEPTION_ACCESS_VIOLATION_EXEC という一見不可思議なクラッシュだったのですが,イベントリスナーとして使われている仮想関数だったことから use-after-free を疑って関連コードを読んでいくと,以下のようなコードを発見.これ,AddObserver と RemoveObserver が同じスレッドで呼ばれないと,RemoveObserver はサイレントに何もしないという実装だったという.<br /> <a href="http://src.chromium.org/viewvc/chrome/trunk/src/base/observer_list_threadsafe.h?revision=212281#l125">http://src.chromium.org/viewvc/chrome/trunk/src/base/observer_list_threadsafe.h?revision=212281#l125</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink> <span class="synComment">// Remove an observer from the list if it is in the list.</span> <span class="synComment">// If there are pending notifications in-transit to the observer, they will</span> <span class="synComment">// be aborted.</span> <span class="synComment">// If the observer to be removed is in the list, RemoveObserver MUST</span> <span class="synComment">// be called from the same thread which called AddObserver.</span> <span class="synType">void</span> RemoveObserver(ObserverType* obs) { </pre><p>「このせいじゃね?」とコメントしておいたところ,直前にコミットされていた <a href="https://codereview.chromium.org/482333003">Issue 482333003: Reland r290125: Close all active PeerConnections upon OS suspend - Code Review</a> がまさにこの問題を踏んでいたことを特定していただきました.これにコードレビューで気付けというのはちょっと無理ですかね.ライブラリの設計ミスとでも言うべきか.</p> </div> <div class="section"> <h4>Google Cloud Messaging クライアントの exponential backoff が約 7 日でオーバーフローする</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=373181">Issue 373181 - chromium - Chromium packet storm on port 5228 - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>利用者からバグ報告に担当者が割り当てられていなかったので,関係しそうな人々を CC しただけ仕事です.Chrome が特定条件で (Google のサーバーの?) port 5228 に大量のパケットを送信する,という問題.原因だけは気になっていたのでその後もやりとりをウォッチしていたのですが,exponential backoff の計算方法に問題があって,約 7 日送信失敗し続けると double の精度を超えてしまっていたというオチでした.</p> </div> <div class="section"> <h4>Windows 10 Technical Preview 上で動く Chromium の User Agent が "Windows NT 6.3" と返す</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=420629">Issue 420629 - chromium - User agent string reports &quot;Windows NT 6.3&quot; on Windows 10 Technical Preview - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>Windows 8.1 のときにもあった,GetVersionEx 嘘つき問題です.マニフェストファイルに GUID を追加すれば解決する話ではあるのですが,実際手を出してみたら大量の yak shaving に付き合わされたのが前回.今回は Issue として登録して直してもらいました.</p> </div> </div> <div class="section"> <h3>感想</h3> <p>何となくそうではないかと予想していましたが,Issue Tracker で人に作業を振ったりあれこれ意見を述べるだけってのはだいぶ楽ですねこれ.チームを移ったこともあり,基本的に休日や通勤中の空き時間でできる作業に専念していたのですが,これぐらいの作業なら空き時間との相談で続けてもいいかなというところです.<br /> 一方で Chromium のコードを書く人の負担が半端なく大きいという問題は未解決のままと言えます.かなり厳しいコードレビュー,法外に高いクロスプラットフォーム対応コスト,不安定なテスト,コミット後忘れた頃にやってくる regression とクラッシュの報告.実際に問題を修正してくれている人たちは何故そんな面倒な仕事をしてくれているのか,そこをうまくシステム化していかないとブラウザ開発というプロジェクト自体の持続可能性が危ういんではないかなと.Issue Tracker であれこれ意見を言うだけの人が 100 人いても,大変めんどくさいコード変更作業に立ち上がってくれる人が 1 人現れない限り問題は解決しないという構造をプロジェクト運営にどう反映させていくのか.思うことは色々あるのですが,この辺についてはまた改めて別のエントリで書いてみたいと思います.<br /> 2015 年ですが,Android 5.0 の新 IME API 対応はさっさと終わせないとですね.その先はあんまり考えていないです.まあなるようになる感じで.</p> </div> <div class="section"> <h3>過去のエントリ</h3> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2014/01/04/123238">2013&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Chromium &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/01/03/214030">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Chromium &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> </li> </ul> </div> <div class="section"> <h3>References</h3> <div class="section"> <h4>コミット一覧</h4> <ul> <li><a href="http://crrev.com/757233003">Do not provisionally send ImeCompositionRangeChanged message on Android</a></li> <li><a href="http://crrev.com/784503002">Revert &quot;Plumb composition character bounds from C++ to Java&quot;</a></li> <li><a href="http://crrev.com/755853004">Replace #updateCursor with #updateCursorAnchorInfo</a></li> <li><a href="http://crrev.com/679223002">Plumb composition character bounds from C++ to Java</a></li> <li><a href="http://crrev.com/671503005">Plumb composition character bounds for Android 5.0</a></li> <li><a href="http://crrev.com/227073002">Treats the returned value from ui::TextInputClient as DIP</a></li> <li><a href="http://crrev.com/182433002">Remove obsolete files and comment from skia/</a></li> <li><a href="http://crrev.com/166063002">Unify InputMethodIMM32 into InputMethodWin again</a></li> <li><a href="http://crrev.com/145283006">Remove ui::TextInputClient::GetAttachedWindow</a></li> <li><a href="http://crrev.com/158463003">Remove WM_DEADCHAR/WM_SYSDEADCHAR handler</a></li> <li><a href="http://crrev.com/141773009">Revert r151669 and r155589 as non-Aura Metro mode is gone</a></li> <li><a href="http://crrev.com/158483003">Logically revert r206996, which is no longer used in the era of Aura</a></li> <li><a href="http://crrev.com/158313002">Remove non-Aura stuff from InputMethodWin</a></li> <li><a href="http://crrev.com/143503004">Revert &quot;Revert 249234 &quot;Use MessagePumpDispatcher instead of MessageFilter&quot;&quot;</a></li> <li><a href="http://crrev.com/152033005">Use MessagePumpDispatcher instead of MessageFilter</a></li> <li><a href="http://crrev.com/137493006">Revert r156303 as non-Aura Metro mode is gone</a></li> </ul> </div> <div class="section"> <h4>レビューした CL 一覧</h4> <ul> <li><a href="http://crrev.com/826713002"> Show autofill popup after keyboard (if any) is shown.</a></li> <li><a href="http://crrev.com/700723004">Do not use vector&lt;scoped_ptr&lt;&gt;&gt;.</a></li> <li><a href="http://crrev.com/640143003">Fix DOM code for VKEY_LCONTROL and VKEY_RCONTROL</a></li> <li><a href="http://crrev.com/664843002">Web MIDI: distributes MIDIPort information asynchronously</a></li> <li><a href="http://crrev.com/645683002">Get IME&#39;s to work in Chrome OS mode on Windows 7.</a></li> <li><a href="http://crrev.com/382423003">The message length should be serialized as a 64-bit value.</a></li> <li><a href="http://crrev.com/269543028">Web MIDI: make input_ports_ and output_ports_ members private</a></li> <li><a href="http://crrev.com/264053002">Web MIDI: introduce pending client count limit to start sessions</a></li> <li><a href="http://crrev.com/261263002">Web MIDI: add an unit test to check MidiManager instantiation</a></li> <li><a href="http://crrev.com/187813008">Add PGO targets to Chrome.</a></li> <li><a href="http://crrev.com/194313003">Removed the unnecessary TODO</a></li> <li><a href="http://crrev.com/150283005">Revert 249234 &quot;Use MessagePumpDispatcher instead of MessageFilter&quot;</a></li> <li><a href="http://crrev.com/149073009">Remove InputMethodTSF, TSFEventRouter, TSFTextStore, TSFBridge</a></li> </ul> </div> <div class="section"> <h4>報告した Issue 一覧</h4> <ul> <li><a href="http://crbug.com/304691">Issue 304691: Support IMEs and keyboard input for --open-ash on Linux</a></li> <li><a href="http://crbug.com/326777">Issue 326777: Win/Ash: Ctrl+{Left, Right}Shift does not flip the text direction</a></li> <li><a href="http://crbug.com/334380">Issue 334380: IME is not available under Ash mode on Windows</a></li> <li><a href="http://crbug.com/343826">Issue 343826: Remove ui::TextInputClient::GetAttachedWindow </a></li> <li><a href="http://crbug.com/344209">Issue 344209: Unify ui::InputMethodIMM32 into ui::InputMethodWin</a></li> <li><a href="http://crbug.com/347363">Issue 347363: Revise obsolete comments that were written in the era of IBus</a></li> <li><a href="http://crbug.com/348333">Issue 348333: Security: base::SHA1HashBytes produces wrong SHA1 hash when |len| &gt;= 4GB</a></li> <li><a href="http://crbug.com/350649">Issue 350649: depot_tools.zip is obsolete and requires multiple self update</a></li> <li><a href="http://crbug.com/350656">Issue 350656: Design Documents? of Text Input is obsolete</a></li> <li><a href="http://crbug.com/350659">Issue 350659: Specify /Zc:strictStrings for release build</a></li> <li><a href="http://crbug.com/350660">Issue 350660: Remove unused IDS_OPTIONS_SETTINGS_LANGUAGES_* messages</a></li> <li><a href="http://crbug.com/360334">Issue 360334: Needs a spec of whether ui::TextInputClient uses DIP (Density Independent Pixel) or not</a></li> <li><a href="http://crbug.com/401371">Issue 401371: IME should never be enabled in Chromoting window </a></li> <li><a href="http://crbug.com/402239">Issue 402239: (restricted)</a></li> <li><a href="http://crbug.com/402244">Issue 402244: (restricted)</a></li> <li><a href="http://crbug.com/404132">Issue 404132: (restricted)</a></li> <li><a href="http://crbug.com/420629">Issue 420629: User agent string reports &quot;Windows NT 6.3&quot; on Windows 10 Technical Preview</a></li> <li><a href="http://crbug.com/424866">Issue 424866: Support InputMethodManager#updateCursorAnchorInfo for Android 5.0</a></li> <li><a href="http://crbug.com/427090">Issue 427090: Monitor the performance impact on real devices when CursorAnchorInfo is enabled</a></li> </ul> </div> <div class="section"> <h4>コメントした Issue 一覧</h4> <ul> <li><a href="http://crbug.com/1970">Issue 1970: ctrl+shift+t conflicts with Google Pinyin IME</a></li> <li><a href="http://crbug.com/65712">Issue 65712: Autofill eats keystrokes when SCIM is enabled</a></li> <li><a href="http://crbug.com/86460">Issue 86460: GoogleJapaneseInputMethod shows the candidate window inappropriate position</a></li> <li><a href="http://crbug.com/113805">Issue 113805: Chromium wrongly add text to clipboard while using input method with preedit under linux</a></li> <li><a href="http://crbug.com/125161">Issue 125161: Please do not use GtkIMContextSimple for password fields.</a></li> <li><a href="http://crbug.com/125888">Issue 125888: SSH extension doesn&#39;t permit use of IBUS input method (and maybe also other input methods, not tested)</a></li> <li><a href="http://crbug.com/128475">Issue 128475: Search setting incorrectly unfocus the input field cause text commit</a></li> <li><a href="http://crbug.com/135135">Issue 135135: Does not remove committed string with an IME on cancelling</a></li> <li><a href="http://crbug.com/139764">Issue 139764: Can&#39;t render double underline on composition</a></li> <li><a href="http://crbug.com/142823">Issue 142823: Some preedit text might be typed in to input box</a></li> <li><a href="http://crbug.com/168993">Issue 168993: Win/Ash: Cannot commit text via IME on Google Document</a></li> <li><a href="http://crbug.com/170186">Issue 170186: pdb size being exceeded in non-component=shared_library builds</a></li> <li><a href="http://crbug.com/174136">Issue 174136: Refactor pdb workaround</a></li> <li><a href="http://crbug.com/215520">Issue 215520: ibus-mozc: no way to delete input history</a></li> <li><a href="http://crbug.com/218382">Issue 218382: hterm: incorrect handling of utf-8 input</a></li> <li><a href="http://crbug.com/260529">Issue 260529: IME UI is not placed at proper position when HiDPI is enabled</a></li> <li><a href="http://crbug.com/264288">Issue 264288: Blue lowercase letter a displated in top left corner of menu icon on canary</a></li> <li><a href="http://crbug.com/265848">Issue 265848: pasting a data-uri into Metro address bar makes it completely invisible</a></li> <li><a href="http://crbug.com/266660">Issue 266660: (restricted)</a></li> <li><a href="http://crbug.com/268220">Issue 268220: (restricted)</a></li> <li><a href="http://crbug.com/271962">Issue 271962: Investigate correct focus event propagation path for NativeTextfieldViews and InputMethodTSF</a></li> </ul> <ul> <li><a href="http://crbug.com/272668">Issue 272668: Weird painting in the find bar (Win8 Metro)</a></li> <li><a href="http://crbug.com/273106">Issue 273106: Blue lowercase &#39;a&#39; badge on Chrome Canary menu icon, but no &quot;Open Ash Desktop&quot; menu item</a></li> <li><a href="http://crbug.com/276987">Issue 276987: Japanese Input does not respect keyboard layout</a></li> <li><a href="http://crbug.com/279097">Issue 279097: Web MIDI: implement MIDIConnectionEvent</a></li> <li><a href="http://crbug.com/293394">Issue 293394: Unable to reopen last closed tab because Google Pinyin always eats &#39;Ctrl+Shift+T&#39;</a></li> <li><a href="http://crbug.com/310698">Issue 310698: (restricted)</a></li> <li><a href="http://crbug.com/311448">Issue 311448: Images can not easily be deleted in contentEditable elements in Chrome for mobile</a></li> <li><a href="http://crbug.com/311488">Issue 311488: Migrating to Win SDK 8.1</a></li> <li><a href="http://crbug.com/313911">Issue 313911: Google search page tab title not read by JAWS</a></li> <li><a href="http://crbug.com/315010">Issue 315010: Regression: Omnibox suggestions flashing just before the &#39;Google Pinyin IME&#39; candidate window shows up (Win7)</a></li> <li><a href="http://crbug.com/317945">Issue 317945: Remove support for system V SHM in the sandbox</a></li> <li><a href="http://crbug.com/318484">Issue 318484: aura: omnibox popup history ignores system font foreground colour</a></li> <li><a href="http://crbug.com/319122">Issue 319122: Remove TSFEventRouter(Observer), InputMethodTSF, and related unused code.</a></li> <li><a href="http://crbug.com/321294">Issue 321294: Crash with Matrox Power Desk software (TripleHead2Go and DualHead2Go devices)</a></li> <li><a href="http://crbug.com/323376">Issue 323376: Cannot activate an IME in Omnibox (Aura)</a></li> <li><a href="http://crbug.com/326837">Issue 326837: (restricted)</a></li> <li><a href="http://crbug.com/330735">Issue 330735: Remove non-Aura Windows code</a></li> <li><a href="http://crbug.com/331419">Issue 331419: (restricted)</a></li> <li><a href="http://crbug.com/332729">Issue 332729: Regression - Other elements are clickable in presence of &quot;Confirm New App&quot; dialogue box.</a></li> <li><a href="http://crbug.com/333011">Issue 333011: Windows 8.1 Color Emoji on Segoe UI Emoji is not supported on Chrome</a></li> <li><a href="http://crbug.com/334600">Issue 334600: (restricted)</a></li> <li><a href="http://crbug.com/335386">Issue 335386: (restricted)</a></li> <li><a href="http://crbug.com/335471">Issue 335471: Don&#39;t show the input mode indicator when it&#39;s located in a weird position.</a></li> <li><a href="http://crbug.com/335912">Issue 335912: Chrome: Crash Report - Magic Signature: views::DesktopWindowTreeHostWin::HandleIMEM...</a></li> <li><a href="http://crbug.com/335972">Issue 335972: IME input mode should change dynamically as an IME becomes active/inactive</a></li> <li><a href="http://crbug.com/336740">Issue 336740: IME can&#39;t be enabled in FlashPlayer when Chrome settings for plug-ins is set to &quot;Click to play&quot;.</a></li> <li><a href="http://crbug.com/337927">Issue 337927: Google English keyboard inserts extra string</a></li> <li><a href="http://crbug.com/338357">Issue 338357: (restricted)</a></li> <li><a href="http://crbug.com/338644">Issue 338644: In some Win8 + Chrome32, unicode glyphs with 4-byte codes are not shown</a></li> <li><a href="http://crbug.com/340199">Issue 340199: X keyboard layout / input handling is wrong</a></li> <li><a href="http://crbug.com/340569">Issue 340569: Can&#39;t delete U+FF8A U+FF9E in the text area</a></li> <li><a href="http://crbug.com/340972">Issue 340972: Chrome crashes with an error message asking me if I want to restart Chrome</a></li> <li><a href="http://crbug.com/343622">Issue 343622: Can&#39;t activate Chinese/Japanese input method in Hangouts chatting window</a></li> <li><a href="http://crbug.com/343875">Issue 343875: Check failed: text_input_type_ != ui::TEXT_INPUT_TYPE_NONE in render_widget_host_view_aura.cc (2344)</a></li> <li><a href="http://crbug.com/344091">Issue 344091: Chrome_Win: Crash Report: &#39;views::corewm::InputMethodEventFilter::DispatchKeyEventPostIME&#39;</a></li> <li><a href="http://crbug.com/344410">Issue 344410: Web MIDI: midi_manager_alsa requires exclusive access to device</a></li> <li><a href="http://crbug.com/344773">Issue 344773: Omnibox suggestions overlaps candidate window on selecting Google Pinyin IME</a></li> <li><a href="http://crbug.com/345080">Issue 345080: IMEs are disabled on Hangout chat window after link navigation</a></li> <li><a href="http://crbug.com/347360">Issue 347360: &#39;ols.bat&quot;&#39; is not recognized as an internal or external command</a></li> <li><a href="http://crbug.com/348194">Issue 348194: Linux Aura : Tool tip background color is shown incorrectly</a></li> <li><a href="http://crbug.com/348437">Issue 348437: Linux Aura: Task manager should have native window dressing</a></li> <li><a href="http://crbug.com/348907">Issue 348907: The &#39;Chrome hangs when we select &#39;Google Pinyin&#39; and click on &#39;Load Unpacked extension&#39; on &#39;chrome://extensions&#39; page</a></li> <li><a href="http://crbug.com/348983">Issue 348983: Chrome: Crash Report - views::DesktopWindowTreeHostWin::HandleIMEMessage</a></li> <li><a href="http://crbug.com/349163">Issue 349163: Key modifier doesn&#39;t work when cursor is in text box with some IMEs</a></li> <li><a href="http://crbug.com/349576">Issue 349576: git runs out of memory cloning https://chromium.googlesource.com/chromium/reference_builds/chrome_win.git</a></li> <li><a href="http://crbug.com/349788">Issue 349788: Chrome crashes on startup when using Matrox software with dual monitors</a></li> <li><a href="http://crbug.com/349896">Issue 349896: (restricted)</a></li> <li><a href="http://crbug.com/350018">Issue 350018: Use some new flags to improve the VS build</a></li> <li><a href="http://crbug.com/350260">Issue 350260: (restricted)</a></li> <li><a href="http://crbug.com/350639">Issue 350639: Large PDB hack no longer required post VS2013 Update 2</a></li> <li><a href="http://crbug.com/350694">Issue 350694: &quot;fetch --nohooks chromium&quot; fails with an error because reference_build\\_gclient_chrome_win_xxxxxx is not found</a></li> <li><a href="http://crbug.com/351991">Issue 351991: Notifications from extension disables ibus-based input methods until refocus</a></li> <li><a href="http://crbug.com/352598">Issue 352598: The &#39;Choose Folder&#39; window opens behind the Feedback&#39; app when Google Pinyin is selected.</a></li> <li><a href="http://crbug.com/353914">Issue 353914: Can&#39;t delete unicode6 emoji of surrogate pair in Google Search of Chrome.</a></li> <li><a href="http://crbug.com/354495">Issue 354495: The last Korean character before space is inserted after a space in all input field</a></li> <li><a href="http://crbug.com/355122">Issue 355122: (restricted)</a></li> <li><a href="http://crbug.com/355995">Issue 355995: Can&#39;t delete certain Thai characters in text box on Chrome 33 Android</a></li> <li><a href="http://crbug.com/356467">Issue 356467: Sometimes, IME switching doesn&#39;t work properly</a></li> <li><a href="http://crbug.com/359843">Issue 359843: Directwrite causes tab crashes on some pages</a></li> <li><a href="http://crbug.com/359892">Issue 359892: (restricted)</a></li> <li><a href="http://crbug.com/360317">Issue 360317: Joining multiple same type devices to Windows PC, inputs method return only one entry.</a></li> <li><a href="http://crbug.com/360351">Issue 360351: Some websites (twitter/github) crash when DirectWrite is enabled</a></li> <li><a href="http://crbug.com/360388">Issue 360388: Ignores all keyboard input</a></li> <li><a href="http://crbug.com/362155">Issue 362155: Ugly fonts in address bar, tab title and sandwich menu</a></li> <li><a href="http://crbug.com/362698">Issue 362698: ozone: implement input method support on ChromeOS</a></li> <li><a href="http://crbug.com/363358">Issue 363358: Hangouts does not work on Google Chrome beta</a></li> <li><a href="http://crbug.com/363604">Issue 363604: Cannot type into Chromium</a></li> <li><a href="http://crbug.com/363921">Issue 363921: keyboard input is broken in a forked version of Chromium 34 shipped with Ubuntu 14.04</a></li> <li><a href="http://crbug.com/364571">Issue 364571: Chrome breaking devanagari input using IBUS input method.</a></li> <li><a href="http://crbug.com/364707">Issue 364707: selecting url from address bar no longer includes the scheme</a></li> <li><a href="http://crbug.com/365015">Issue 365015: Aura shows garbage font when Droid Sans enabled</a></li> <li><a href="http://crbug.com/365063">Issue 365063: Cannot type any text in any text field</a></li> <li><a href="http://crbug.com/365152">Issue 365152: Korean Character Input Problem</a></li> <li><a href="http://crbug.com/365208">Issue 365208: Japanese fonts shipping with Windows look bad in DirectWrite mode</a></li> <li><a href="http://crbug.com/366952">Issue 366952: HTML5 color picker isn&#39;t using a native window</a></li> <li><a href="http://crbug.com/367919">Issue 367919: (restricted)</a></li> <li><a href="http://crbug.com/368100">Issue 368100: Keydown fires extra event (key 229)</a></li> <li><a href="http://crbug.com/368218">Issue 368218: Task manager does not match with the browser window border color</a></li> <li><a href="http://crbug.com/368679">Issue 368679: Smilies in Google search textfield are not deleting when &quot;Delete key&quot; is pressed</a></li> <li><a href="http://crbug.com/369190">Issue 369190: Copying from the URL bar no longer includes http:// prefix</a></li> <li><a href="http://crbug.com/369229">Issue 369229: Titlebar mouse events are no longer passed to underlying window manager</a></li> <li><a href="http://crbug.com/369788">Issue 369788: Closing extension popup breaks chrome</a></li> <li><a href="http://crbug.com/369846">Issue 369846: Accept suggestion not working in console</a></li> <li><a href="http://crbug.com/370778">Issue 370778: Extension IME doesn&#39;t works fine</a></li> <li><a href="http://crbug.com/371478">Issue 371478: ozone/freon: make X11 optional for chromeos builds</a></li> <li><a href="http://crbug.com/371652">Issue 371652: IMEs cannot activate</a></li> <li><a href="http://crbug.com/372650">Issue 372650: IME stops working when switching focus between native input fields and &lt;INPUT type=&#39;text&#39;&gt; field</a></li> <li><a href="http://crbug.com/373174">Issue 373174: CJK IME disabled after inserting a hyperlink on Google Blogger</a></li> <li><a href="http://crbug.com/373181">Issue 373181: Chromium packet storm on port 5228</a></li> <li><a href="http://crbug.com/373712">Issue 373712: (restricted)</a></li> <li><a href="http://crbug.com/373756">Issue 373756: accessibility: accented/currency/emoji keys entered via on screen keyboard do not show (ee&#xFFE1;????????)</a></li> <li><a href="http://crbug.com/373934">Issue 373934: Not able to delete a letter followed by a space on Google search box</a></li> <li><a href="http://crbug.com/373946">Issue 373946: Keyboard stopped to work in Chromium</a></li> <li><a href="http://crbug.com/374077">Issue 374077: MacViews: Implement a ui::InputMethod for Mac</a></li> <li><a href="http://crbug.com/374882">Issue 374882: problem to install the new version on Ubuntu 10.04</a></li> <li><a href="http://crbug.com/374950">Issue 374950: AltGr moves curses to the left in input boxes (but not address bar).</a></li> <li><a href="http://crbug.com/375659">Issue 375659: Tooltip text isn&#39;t visible when using dark GTK theme + Aura</a></li> <li><a href="http://crbug.com/375670">Issue 375670: Deadkey (apostrophe) shows up after first hit</a></li> <li><a href="http://crbug.com/375684">Issue 375684: Problem with national characters</a></li> <li><a href="http://crbug.com/375758">Issue 375758: Chrome V.35 seems to no longer provide WM hints used by some window manegers like WindowMaker</a></li> <li><a href="http://crbug.com/375827">Issue 375827: Web MIDI api completely broken on linux</a></li> <li><a href="http://crbug.com/375866">Issue 375866: libappindicator support broken in Fedora 20</a></li> <li><a href="http://crbug.com/375909">Issue 375909: Chrome 35 on Ubuntu x64 does not pick up OpenJDK 1.7</a></li> <li><a href="http://crbug.com/376258">Issue 376258: Error typing accented letters</a></li> <li><a href="http://crbug.com/376346">Issue 376346: Weird text-rendering in Korean Italic case only on ubuntu.</a></li> <li><a href="http://crbug.com/376515">Issue 376515: Omnibox has dark background since Chrome 35 (Linux, KDE, Aura)</a></li> <li><a href="http://crbug.com/376616">Issue 376616: REGRESSION: Chromium raises even if click-to-raise is disabled on the current WM</a></li> <li><a href="http://crbug.com/377203">Issue 377203: Cursor moves back if Rigth Alt is pressed in text box</a></li> <li><a href="http://crbug.com/379931">Issue 379931: Japanese IME doesn&#39;t work at all</a></li> <li><a href="http://crbug.com/381597">Issue 381597: Chrome doesn&#39;t handle Linux X11 forward key event anymore (breaks our language&#39;s IME)</a></li> <li><a href="http://crbug.com/382201">Issue 382201: infolist_window grabs the focus which causes a weird effect on Japanese input</a></li> <li><a href="http://crbug.com/383009">Issue 383009: (restricted)</a></li> <li><a href="http://crbug.com/390190">Issue 390190: Microsoft Word / RichEdit specific keyboard shortcuts for international characters are no longer supported</a></li> <li><a href="http://crbug.com/391668">Issue 391668: (restricted)</a></li> <li><a href="http://crbug.com/392875">Issue 392875: Cannot input letter &quot;i&quot;</a></li> <li><a href="http://crbug.com/393691">Issue 393691: Cannot enter aA umlauts while </a></li> <li><a href="http://crbug.com/394416">Issue 394416: (restricted)</a></li> <li><a href="http://crbug.com/395019">Issue 395019: linux: XLookupString doesn&#39;t support some characters.</a></li> <li><a href="http://crbug.com/395470">Issue 395470: Cannot type the letters &quot;c&quot; and &quot;h&quot; in web pages</a></li> <li><a href="http://crbug.com/397143">Issue 397143: M36 Regression: Custom keyboard layouts extensions don&#39;t work on startup.</a></li> <li><a href="http://crbug.com/398799">Issue 398799: IME does not work 64-bit Chrome</a></li> <li><a href="http://crbug.com/398890">Issue 398890: Caret position randomness when using Google Japanese IME</a></li> <li><a href="http://crbug.com/399864">Issue 399864: a, o and u not working</a></li> <li><a href="http://crbug.com/400736">Issue 400736: Can&#39;t delete Emoji at google.com search box. </a></li> <li><a href="http://crbug.com/402307">Issue 402307: With Dvorak International, altgr falls back to qwerty instead of 3rd level</a></li> <li><a href="http://crbug.com/403347">Issue 403347: On Windows laptops with touch screens the virtual keyboard pops up incorrectly</a></li> <li><a href="http://crbug.com/404752">Issue 404752: (restricted)</a></li> <li><a href="http://crbug.com/404767">Issue 404767: (restricted)</a></li> <li><a href="http://crbug.com/406233">Issue 406233: Chrome crashed, no specific step to reproduce just I was running debug version of he chrome. and doing random operation.</a></li> <li><a href="http://crbug.com/407207">Issue 407207: Add a visual indicator for internal IME states</a></li> <li><a href="http://crbug.com/407233">Issue 407233: IME: Empty compositionend event fired after complete composition in Pinyin on Linux, signals cancellation</a></li> <li><a href="http://crbug.com/407256">Issue 407256: IME: Chrome does not fire any composition events for CJK spaces</a></li> <li><a href="http://crbug.com/408561">Issue 408561: cannot choose other layouts than US or Japanese with Japanese IME (like AZERTY etc.)</a></li> <li><a href="http://crbug.com/409016">Issue 409016: Memory leak in MidiManagerAlsa implementation</a></li> <li><a href="http://crbug.com/409709">Issue 409709: ideographs in Chinese and Japanese show as empty space in Linux in UI elements like tooltips, addressbar and Ctrl+F search entry</a></li> <li><a href="http://crbug.com/411747">Issue 411747: Chinese input method doen&#39;t work correctly sometimes, for unknown reason</a></li> <li><a href="http://crbug.com/411768">Issue 411768: Can&#39;t input non-default language</a></li> <li><a href="http://crbug.com/411788">Issue 411788: Notifications from extension disables the connection to ibus</a></li> <li><a href="http://crbug.com/414258">Issue 414258: Regression: &quot;Ctrl+tab&quot; keyboard shortcut doesn&#39;t work after reloading sad/crashed tab.</a></li> <li><a href="http://crbug.com/417152">Issue 417152: Regression:Touch selection quick menu appears on deleting url from chrome://settings/startup on touch device.</a></li> <li><a href="http://crbug.com/421645">Issue 421645: (restricted)</a></li> <li><a href="http://crbug.com/421980">Issue 421980: IME does not work in Chrome OS mode on Windows 7</a></li> <li><a href="http://crbug.com/422203">Issue 422203: (restricted)</a></li> <li><a href="http://crbug.com/422685">Issue 422685: Backspace submits composition string unexpectedly</a></li> <li><a href="http://crbug.com/424680">Issue 424680: Update and start using Android SDK 21</a></li> <li><a href="http://crbug.com/424902">Issue 424902: Web pages containing Java Applets not working well</a></li> <li><a href="http://crbug.com/427780">Issue 427780: Out-of-order &amp; slow key input on Linux/ChromeOS</a></li> <li><a href="http://crbug.com/428516">Issue 428516: new Korean IME: cannot enter a number and a punctuation after a standalone Hangul consonant or vowel</a></li> <li><a href="http://crbug.com/429957">Issue 429957: Korean input issue while deleting characters</a></li> <li><a href="http://crbug.com/430997">Issue 430997: Roll android aosp to lollipop</a></li> <li><a href="http://crbug.com/433715">Issue 433715: Chinese font selected while typing Japanese font in search box</a></li> <li><a href="http://crbug.com/437764">Issue 437764: ibus-based IMEs may not work with Google Chrome after rebooting the computer</a></li> </ul> </div> </div> Sun, 04 Jan 2015 21:06:39 +0900 hatenablog://entry/8454420450078969004 2013年やったこと - Firefox, LibreOffice, Gyp 編 https://nyaruru.hatenablog.com/entry/2014/01/05/123855 <p>2013年やったこと - Firefox, LibreOffice, Gyp 編.</p> <div class="section"> <h4>Firefox: TSF 無効時の HTML5 Forms のtype 指定と InputScope の対応作業</h4> <p><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=866736">866736 &ndash; InputScope support for IMM32 with CUAS</a><br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140105/20140105122321.png" alt="f:id:NyaRuRu:20140105122321p:plain" title="f:id:NyaRuRu:20140105122321p:plain" class="hatena-fotolife" itemprop="image"></span><br /> TSF モードの Firefox は InputScope に対応既なのですが,IMM32 モードでは特に何も考慮されていませんでした.実は SetInputScopes API を使えばレガシー IMM32 アプリでも InputScope に対応できるので,Firefox でもやってみた,という変更です.以下のように InputScope 周りを重点的に見ていた時期だったので,タイミングが良かったというのもありました.</p> <ul> <li>同様の方法で InputScope に対応するコードを Chromium 向けに書いていた</li> <li>同時期に Mozc の InputScope 対応を実装していた</li> </ul><p>ゴールデンウィークに Mozilla Japan の六本木オフィスで行われたハッカソンで書き上げたものです.パッチの送り方も一緒に教えてもらえたので大変助かりました. <br /> ビルドを壊しちゃったり コードに CRLF が混ざっていたりと,チェックイン後も色々ご迷惑をおかけすることに.中野さんをはじめフォローしていただいた Mozilla の皆様ありがとうございました.</p> </div> <div class="section"> <h4>LibreOffice: IMR_QUERYCHARPOSITION 対応</h4> <p><a href="https://bugs.freedesktop.org/show_bug.cgi?id=64298">Bug 64298 &ndash; Support IMR_QUERYCHARPOSITION for better integration with IMEs</a><br /> LibreOffice に IMR_QUERYCHARPOSITION サポートを追加して,各種 IME が適切な位置にサジェストウィンドウを表示できるようにするというパッチです.</p> <div class="section"> <h5>LibreOffice Writer 4.0 (修正前)</h5> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140105/20140105122333.png" alt="f:id:NyaRuRu:20140105122333p:plain" title="f:id:NyaRuRu:20140105122333p:plain" class="hatena-fotolife" itemprop="image"></span></p> </div> <div class="section"> <h5>LibreOffice Writer 4.1 (修正後)</h5> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140105/20140105122401.png" alt="f:id:NyaRuRu:20140105122401p:plain" title="f:id:NyaRuRu:20140105122401p:plain" class="hatena-fotolife" itemprop="image"></span><br /> この問題との付き合いは長く,Mozc リリース直後にOpenOffice.org でサジェストウィンドウの表示位置が変というレポートがたくさん来て以来となります.3 年半のときを経てやっと根本的に対処できました.</p> <ul> <li><a href="http://productforums.google.com/d/msg/ime-ja/VxhbDcajYtg/X1KbtGVcuX8J">&#x5909;&#x63DB;&#x5019;&#x88DC;&#x306E;&#x8868;&#x793A;&#x4F4D;&#x7F6E; &#x307B;&#x304B;</a></li> <li><a href="http://productforums.google.com/d/msg/ime-ja/vrTbqTw9nxY/EwEbIk-4FyIJ">OpenOffice.org &#x4F7F;&#x7528;&#x6642;&#x306B;</a></li> <li><a href="http://productforums.google.com/d/msg/ime-ja/6KFHospZcQ4/f-1aNAUR3C8J">openoffice&#x3067;&#x4F7F;&#x7528;&#x3057;&#x305F;&#x3068;&#x304D;&#x3001;&#x691C;&#x7D22;&#x7A93;&#x304C;&#x753B;&#x9762;&#x306E;&#x53F3;&#x4E0B;&#x306B;&#x6765;&#x308B;&#x305F;&#x3081;&#x8996;&#x7DDA;&#x306E;&#x79FB;&#x52D5;&#x304C;&#x5927;&#x304D;&#x3059;&#x304E;&#x307E;&#x3059;&#x3002;</a></li> <li><a href="http://productforums.google.com/d/msg/ime-ja/17bty5I91zM/tscPJvzIGaQJ">Open Office&#x3068;&#x306E;&#x63A5;&#x7D9A;&#x306B;&#x3064;&#x3044;&#x3066;</a></li> <li><a href="http://productforums.google.com/d/msg/ime-ja/__QeUBZNLGo/hjPQumsmfnsJ">OpenOffice Calc&#x3092;&#x5229;&#x7528;&#x3059;&#x308B;&#x969B;&#x3001;&#x5909;&#x63DB;&#x5019;&#x88DC;&#x306E;&#x30DD;&#x30C3;&#x30D7;&#x30A2;&#x30C3;&#x30D7;&#x8868;&#x793A;&#x304C;&#x753B;&#x9762;&#x53F3;&#x4E0B;&#x306B;&#x79FB;&#x52D5;&#x3057;&#x3066;&#x3057;&#x307E;&#x3046;</a></li> </ul><p>IMR_QUERYCHARPOSITION を (直接的または間接的に) 利用している全 IME で表示位置が改善されます.<br /> このパッチもたしかゴールデンウィークを利用して書いています.パッチの送り方からチェックイン後のビルド失敗の後始末まで LibreOffice チームのみなさんにたくさんフォローしていただきました.この場をお借りして改めてお礼申しあげます.</p> </div> </div> <div class="section"> <h4>Gyp Issue 385: ninja generator doesn't handle LinkTimeCodeGeneration/ProfileGuidedDatabase for PGO</h4> <p><a href="https://code.google.com/p/gyp/issues/detail?id=385">Issue 385 - gyp - ninja generator doesn&#39;t handle LinkTimeCodeGeneration/ProfileGuidedDatabase for PGO - Generate Your Projects - Google Project Hosting</a><br /> 年末休暇で暇つぶしに適当に見つけた Gyp のバグを直してみたというもの.特に困ってはいなかったのですが,たまには Gyp コミッターらしいことでもしておくかという感じ.<br /> Gyp の Ninja 向けジェネレータが PGO 設定の一部をサポートしていなかったので,対応してみました.実装自体は単に対応表を書くだけだったのですが,コードレビューで「実際に PGO ビルドするテストもあるといいね」という流れになってテストを書いてみたら予想を上回る大変さだったという.この体験がもとになって書いたのが次の記事です.</p> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2013/12/31/101413">&#x300C;&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x306E;&#x4E2D;&#x8EAB;&#x306B;&#x4F9D;&#x5B58;&#x3057;&#x3064;&#x3064;&#x305D;&#x306E;&#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x81EA;&#x4F53;&#x3092;&#x66F4;&#x65B0;&#x3059;&#x308B;&#x300D;&#x30B3;&#x30DE;&#x30F3;&#x30C9;&#x30E9;&#x30A4;&#x30F3;&#x30C4;&#x30FC;&#x30EB;&#x306F;&#x30D3;&#x30EB;&#x30C9;&#x30B7;&#x30B9;&#x30C6;&#x30E0;&#x3068;&#x76F8;&#x6027;&#x304C;&#x60AA;&#x3044; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul><p>Chromium で PGO が有効化される場合はもしかしたら意味があるかもしれません.もっとも,そのまえに Chromium のビルドシステムが Gyp から <a href="https://code.google.com/p/chromium/wiki/gn">GN (Generate Ninja)</a> に移行しちゃうかもしれませんが.</p> </div> <div class="section"> <h4>Gyp Issue 389: ninja generator is not aware of VCLinkerTool.GenerateManifest</h4> <p><a href="https://code.google.com/p/gyp/issues/detail?id=389">Issue 389 - gyp - ninja generator is not aware of VCLinkerTool.GenerateManifest - Generate Your Projects - Google Project Hosting</a><br /> 上の Gyp Issue 385 のテストを書くのにどうしても必要になった機能です.</p> </div> <div class="section"> <h3>感想</h3> <p>メインプロジェクトと関連があるところを攻めつつ,みんなが便利になる方向の改良にもっていけたように思います.</p> </div> <div class="section"> <h3>今年の話とか</h3> <p>今年も隙を見て OSS プロジェクトにパッチを投げていきたいです.</p> </div> Sun, 05 Jan 2014 12:38:55 +0900 hatenablog://entry/12921228815715823351 2013年やったこと - Chromium 編 https://nyaruru.hatenablog.com/entry/2014/01/04/123238 <p>2013年やったこと - Chromium 編,いつもどおりコードが公開されている範囲で.</p> <div class="section"> <h4>HTML5 Forms の type 指定と InputScope の対応作業</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=13768">Issue 13768 - chromium - InputScope support on Windows (a better IME integration) - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>HTML5 Forms の type 指定と Windows 環境での InputScope を連携させるという変更です.Windows 8 以降のオンスクリーンキーボードは InputScope でレイアウトを切り替えるため,IME を必要としない言語でも有効なのがポイントです.<br /> 変更自体はそれほど難しくなく,特にトラブルもないまま無事リリースされていきました.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140104/20140104120453.png" alt="f:id:NyaRuRu:20140104120453p:plain" title="f:id:NyaRuRu:20140104120453p:plain" class="hatena-fotolife" itemprop="image"></span><br /> メジャーブラウザの InputScope 対応状況については,以下の記事にまとめています. </p> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2013/07/07/210150">HTML5 Forms &#x306E; type &#x6307;&#x5B9A;&#x304C;&#x30C7;&#x30B9;&#x30AF;&#x30C8;&#x30C3;&#x30D7; IME&#x306B;&#x5F71;&#x97FF;&#x3059;&#x308B;&#x3068;&#x3044;&#x3046;&#x8A71; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul> </div> <div class="section"> <h4>Omnibox フォント問題</h4> <p>Omnibox のフォントサイズが微妙に変わった/特定文字が□になったから直すべし,という案件.</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=168480">Issue 168480 - chromium - omnibox uses strange multi-sized font rendering in Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=163135">Issue 163135 - chromium - Texts in Chrome showing different height - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=178695">Issue 178695 - chromium - Square boxes are displayed in Omnibox when Selected Chinese letter from candidate window - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140104/20140104120504.png" alt="f:id:NyaRuRu:20140104120504p:plain" title="f:id:NyaRuRu:20140104120504p:plain" class="hatena-fotolife" itemprop="image"></span><br /> なんでこのバグを担当する羽目になったかというと,Omnibox で使っていた RichEdit のバージョンを上げたのが私だったからです.なぜバージョンを上げる必要があったかというと,Immersive Mode で IME をサポートするためには TSF を使う必要があって,古い RichEdit は TSF をサポートしていなかったからです.欲しかったのは TSF の機能だけで,その他は前と同じように動いてほしかったのですが,そうはいかなかったようでした.<br /> 問題自体は i18n 対応でありふれたものです.様々な経験則を駆使しつつ複数フォントで文字をレンダリングしたいという需要があるのですが,それはそれでうまく動かないことがあるというもの.RichEdit ではいくつか制御フラグがあるものの (e.g., IMF_DUALFONT, IMF_AUTOFONT) あちらを立てればこちらが立たずで,直ったーと思ってリリースしてみると予想外の言語から「見た目が変わったー」「文字が□になるー」とバグが報告されるという.<br /> ちなみに後で分かったのですが,Aura という UI フレームワークへの移行することがだいぶ前に決まっていて,その過程で RichEdit は使われなくなるとことも決定事項だったのでした.実際,このとき書いたコードは 1 年と経たず使われなくなりました.</p> </div> <div class="section"> <h4>破損 msftedit.dll 問題</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=161034">Issue 161034 - chromium - Unable to type URL in the address bar, showing blank omnibox - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>これも同じく RichEdit のバージョンを上げたら壊れた問題です.RichEdit 4.1 は msftedit.dll という DLL で提供されているのですが,どうも世の中には msftedit.dll が破損している環境というのが一定数あるらしく,その場合は Omnibox が真っ黒になって何も文字が入力できなくなってしまうとのこと.ユーザーフォーラムに多数問い合わせが来て発覚.議論の末 LoadLibrary("msftedit.dll") が失敗したらダイアログを出してヘルプページに誘導する,ということになりました.ダイアログを表示するような UI 周りのコードを書くのは初めてだったのでだいぶ苦労したのを憶えています.がその後数か月のうちに RichEdit は使われなくなるわけで,このコードも今は使われていません.(たぶんもう消されてるはず)</p> </div> <div class="section"> <h3>用語整理</h3> <p>以後のトピックを理解する上で必要になる用語整理をここで軽く済ませておきます.</p> <div class="section"> <h5>Aura</h5> <ul> <li><a href="http://www.chromium.org/developers/design-documents/aura">Aura - The Chromium Projects</a></li> </ul><p>上の資料はだいぶ古くなっているのではないかと思いますがかといってあんまりいい資料もないかも.<br /> 一般的には「全てを GPU でレンダリングするための変更」という説明をされることが多い Aura ですが,何年もかけて移行していると関係者が増えすぎていて一言でいうのはもう無理なのではという印象もあります.<br /> Chrome OS はとっくの昔に Aura に移行していて,現在 Windows と Linux で移行の最終段階です.Windows については次の Chrome M-32 で安定板にも Aura が投入されそうではありますが正式にリリースはまだなのでご注意を.<br /> 基本的には Chrome OS / Linux / Windows で共有されるコードが増える方向のプロジェクトです.ウィンドウを抽象化し,UI イベントを抽象化し,IME 処理も抽象化し,レンダリング API も抽象化し,という流れ.イベント処理周りのコールスタックは数割深くなる印象.また,いわゆる抽象化の漏れによるバグの比率が増えます.<br /> 一方,UI イベントの型と描画 API がプラットフォーム間で統一されることから,新規プラットフォームへの移植時に必要なコード量は確実に少なくなります.WebView として Chromium を使いたい人は特にこの点を重視している模様.たとえば Intel の人たちが中心になって行っている Chromium 派生プロジェクト <a href="https://crosswalk-project.org/">Crosswalk</a> は Aura が前提だったりします.<br /> ちなみに,Aura は大規模にコードを入れ替えるため,ビルドオプションで有効無効を切り替えます.実行時スイッチで切り替えられず,安定性・互換性・パフォーマンスに関する影響は非常に大きいということで,リリースエンジニアリングの観点では非常に厄介なタイプの大規模変更です.</p> </div> <div class="section"> <h5>Ash (Aura Shell)</h5> <p>Aura のウィンドウモデルやイベントモデルの上に作られたウィンドウマネージャで,Chrome OS のために作られました.実際 Chrome OS では,はるか昔に投入済みです.<br /> 経緯は知りませんが Windows 8 以降の Immsersive Mode でも使われることになり,すでに開発版等ではリリースされています.Windows での実装は,ブラウザプロセス + レンダラプロセスで構成されている Chromium にさらに WinRT プロセスが追加されるという非常にトリッキーなマルチプロセス構成となっており,IME サポートもだいぶ面倒なことになりました.詳しくは後ほど.<br /> 後になって知ったのですが,Immsersive モードに Ash を投入するという構想自体はだいぶ前からあったようです.Windows 版での Ash モードで IME が動かないというバグ登録されたのは,2012 年12月7日のことでした.<br /> <a href="https://code.google.com/p/chromium/issues/detail?id=164964">Issue 164964 - chromium - Support basic functionality of IMEs in Chrome Metro ASH on Windows 8 - An open-source project to help move the web forward. - Google Project Hosting</a><br /> </p> </div> <div class="section"> <h5>Desktop Aura</h5> <p>ウィンドウマネージャは従来通り OS のものを使いつつ,独立した各ウィンドウの内側だけを Aura に置き換えるというもの.デスクトップモードの Windows と Linux で投入されます.現在の Chrome OS にこの動作形態はありません.<br /> IME に関していえばウィンドウマネージャは OS のものを使うという点がやっぱり罠で,Ash 環境では表面化しなかったタイミングバグやイベント順序バグが沢山表面化することとなりました.<br /> 先ほど述べたように,予定通りいけば次の Chrome M-32 安定板からWindows 版でも有効化される見込みとなっています.IME に限らず,アクセシビリティ系ツールとの互換性,パフォーマンス,GPU ドライバとの互換性等,あちこち大変みたいです.</p> </div> <div class="section"> <h5>Native Textfield Views</h5> <p>従来ネイティブウィンドウを使って実装していたテキストフィールドを自前の Window-less コントロールに置き換えようというものです.なお Web コンテンツ領域はもともと自前のテキストフィールドだったので,ここで置き換えられるのは Omnibox 等外側の部分のテキストフィールドのみなことに注意.<br /> Desktop Aura ではトップレベルウィンドウ以外はネイティブウィンドウを持たないので, Aura 移行のためには必須となります.Aura 移行が完了している Chrome OS 環境では当然のことながら置き換え済みです.<br /> Native Textfield Views の実装自体は Aura から独立していて,Windows 版 Aura 投入にあたっては以下のように段階的な移行が行われました.</p> <ol> <li>non-Aura + Native Textfield Views 無効</li> <li>non-Aura + Native Textfield Views 有効</li> <li>Aura + Native Textfield Views 有効</li> </ol><p>このいずれの構成でも IME は動作する必要があり,移行期には考慮すべきケースが増えてしまうので大変でした.<br /> Aura と異なり,起動時のフラグで有効無効を切り替えるという特徴があります.上の 1 と 2 は同じバイナリで提供することが可能です.</p> </div> <div class="section"> <h5>構成</h5> <p>一時的にテストされたものも含むと,IME に関しては以下の 7 パターンの構成を見ることになりました.</p> <ul> <li>IMM32 で動作する non-Aura モード (Windows XP, Vista, 7, 8, 8.1 のデスクトップモード) <ul> <li>Native Textfield Views 有効の場合</li> <li>Native Textfield Views 無効の場合</li> </ul></li> <li>TSFで動作する non-Aura モード (Windows 8, 8.1 の Immersive モード) <ul> <li>Native Textfield Views 有効の場合</li> <li>Native Textfield Views 無効の場合</li> </ul></li> <li>IMM32 で動作する Desktop-Aura モード (Windows XP, Vista, 7)</li> <li>TSF で動作する Desktop-Aura モード (Windows 8, 8.1) [のちに不要だったことが判明]</li> <li>TSFで動作する Ash モード (Windows 8, 8.1 の Immersive モード)</li> </ul><p>不運だったのは,この「TSF で動作する Desktop-Aura モード (Windows 8, 8.1)」が,非常に不安定だった割に,実際のところ全く不要だったとあとになって判明することです. 2013 年 4 月ごろ,将来の必要性を見越して Windows 向け Aura/Ash を担当しているチームから追加されたこのモードは,その後 5 か月にわたって安定化のためにエンジニアリングリソースを吸い込み続け,そして一度も安定板に投入されることなく削除されることになります.<br /> なお,移行が概ね完了した Chromium M-33 以降では,以下の 2 つの構成にまで簡略化されています.</p> <ul> <li>IMM32 で動作する Desktop-Aura モード (Windows XP, Vista, 7, 8, 8.1 のデスクトップモード)</li> <li>TSFで動作する Ash モード (Windows 8, 8.1 の Immersive モード)</li> </ul><p>というわけで用語説明終わりです.</p> </div> <div class="section"> <h4>Native Textfield Views が IMR_QUERYCHARPOSITION をサポートしない</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=236733">Issue 236733 - chromium - Native Textfield Views does not support IMR_QUERYCHARPOSITION - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=239629">Issue 239629 - chromium - IME candidate window is far away from text input field when input text in Chrome UI using IME - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>ゴールデンウィークの暇つぶしに軽い気持ちでパッチを投げたもの.Desktop Aura や Ash のリリースプランを当時の私は全く知らなくて,村の近くに出没したゴブリンでも退治する感じでパッチを投げてしまったのでした.ちなみにこの後どうなるかというと,</p> <ol> <li>Native Textfield Views 導入編 (ゴブリンの巣)</li> <li>Native Textfield Views + non-Aura完結編 (なんか最初の山場)</li> <li>Desktop Aura 編 (魔王城)</li> <li>Ash 編 (宇宙)</li> </ol><p>みたいな流れになります.<br /> この時直したバグは,Native Textfield Views が有効だとサジェストウィンドウ位置が揃わないというものでした.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140104/20140104120522.png" alt="f:id:NyaRuRu:20140104120522p:plain" title="f:id:NyaRuRu:20140104120522p:plain" class="hatena-fotolife" itemprop="image"></span></p><p>このパッチのせいで,Omnibox 上でカーソルが点滅しなくなるというバグを引き起こしてしまいあわてて直したりもしています.</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=238136">Issue 238136 - chromium - Omnibox cursor doesn&#39;t show or blink reliably - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul> </div> <div class="section"> <h4>Native Textfield Views で変換中の文節区切りが分からない</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=164516">Issue 164516 - chromium - Views Textfield: no segments are visible and no focus on the segments - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>ゴールデンウィークのゴブリン退治その 2.<br /> IME で入力中,文節区切りが分からないという問題の修正です.Chrome OS 版で発見されたまま直っていなかった問題ですが,さすがにこのまま Windows 版に出すのはまずかろうという気持ちで (特に担当だったわけではないのですが) 直してみました.</p> </div> <div class="section"> <h4>Native Textfield Views + non-Aura 環境での IME 対応</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=246534">Issue 246534 - chromium - Upgrade ui::InputMethod for non-Aura environment on Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>6 月ごろだった気もしますがやや記憶があいまい.<blockquote class="twitter-tweet" lang="HASH(0x92eff10)"><p>既に一月は復活IMEバグと戦い続けていた. &#10;「このバグで最後のはずだ」&#10;「ん,なんだこのコピペされたコードは」&#10;「聞いてないぞ」&#10;「Ben Goodgerのレビューでコミットされてたんだ」&#10;「なんてこった,ここはIMEバグの巣だ!」&#10;今,IMEの平和をかけた最後の戦いが始まる.</p>&mdash; NyaRuRu (@NyaRuRu) <a href="https://twitter.com/NyaRuRu/statuses/340474034930216960">May 31, 2013</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p><p>思っていたより事態が深刻だと気付き始めます.というのも,既に Aura への移行を済ませてしまっている Chrome OS と違い,Windows 版では Native Textfield Views と non-Aura という組み合わせでも IME を完璧に動作させる必要があります.もちろん最終的には Windows での Aura ビルドでも IME サポートを行う必要もあります.ともあれ,Native Textfield Viewsの投入は近そうだということで,何とか 7 月末に Native Textfield Views + non-Aura という環境で概ね問題なく動くところまでこぎつけました.<br /> コードだけでなく Design Doc もこのタイミングで書くことにもなりました.しかし既に Aura への移行を済ませた Chrome OS の IME 実装を大きく変えるわけにもいきません,必然的に Design Doc の大半は,既にコミットされているコードの説明に費やされました.</p> </div> <div class="section"> <h4>Desktop Aura 対応</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=287620">Issue 287620 - chromium - TextInputFocus is wrong for textfield on popup window - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=287624">Issue 287624 - chromium - TextInputFocus is wrong for textfield in webcontent area just after full-screen. - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=294943">Issue 294943 - chromium - Cannot turn on IME after cloging a popped up window - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=296505">Issue 296505 - chromium - Layout of on-screen keyboard is not aware of HTML5 input type - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=265461">Issue 265461 - chromium - Typing accented characters is bad using US International keyboard - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=319100">Issue 319100 - chromium - Holding enter upon navigation triggers web content form submission. - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>8 月から 9 月にかけて.Native Textfield Views がひと段落したと思ったのもつかの間,すぐにも Desktop Aura が Windows に投入されそうと知らされ再び戦場へ.<br /> ウィンドウのフォーカス処理を OS に任せるか Aura で行うかの違いは思った以上に大きく,Chrome OS では表面化しなかったイベント順序問題やタイミングバグが頻発します.<br /> さらに IMM32 と TSF という異なる実装を同時に安定化させる作業は困難を極めました.また,コードが共有される関係上,変更が Chrome OS での IME サポートを壊すリスクもあり,頻繁にマニュアルテストを行う必要がありました.特定の操作でのみ発生する use-after-free バグが頻発し,GC が恋しくなった時期でもあります.<br /> そして9 月中旬.ラスボスだと思っていたものがラスボスではなかったことを知ります.Immsersive モードで Ash を使用する予定であること,およびそれが WinRT プロセスとデスクトッププロセスが入り混じったものになることを初めて把握します.と同時に,4 月に Windows 版 Ash チームの人がデスクトップモードでも TSF を有効化したその意図をやっと理解したのでした.ここにきての伏線回収.結局それは Ash モードでの動作を見越して投機的に行われたものだったのでした.<br /> が,改めて実験してみると,TSF ランタイムに嫌な制約があって,ブラウザプロセスで TSF を有効にしても Ash モードでの IME サポートの役には立たないことが明らかに.伏線を回収してみたら事件の真相は単にコミュニケーション不足だったという.人類はなんど同じネタを繰り返さなければならないのでしょうか.<br /> 最終的には,デスクトップモードでの TSF サポートをやめたことで,IME に関する Desktop Aura の安定化が急激に進むのでした.</p> </div> <div class="section"> <h4>Ash での IME サポート</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=164964">Issue 164964 - chromium - Support basic functionality of IMEs in Chrome Metro ASH on Windows 8 - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=326774">Issue 326774 - chromium - Win/Ash: IME candidate window overlaps OmniBox suggest - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=328237">Issue 328237 - chromium - Win/Ash: IME&#39;s candidate window is not shown at the caret position - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>Windows 環境での Ash モードは非常に特殊な動きをします.Win32 的なキーボードフォーカスは WinRT プロセスが保持する一方,UI イベントの処理は全てデスクトップで動いているブラウザプロセスに転送するという動作をします (ウェブコンテンツはさらにレンダラプロセスでレンダリングされます).キーイベントに IME が絡まなければ,基本的にこれはうまく動作します.<br /> さて IME ですが,WinRT プロセス内で IME を動かすか,ブラウザプロセス内で IME を動かすかという選択肢が考えられます.しかし,いくつかの実験から分かったのは,TSF ランタイムはフォアグラウンドプロセスかどうかを監視していて,バックグラウンドプロセスで動く IME は決してフォーカスイベントを受け取らない,という事実でした.消去法的に,WinRT プロセス内に TSF ベースのテキストストアを構築し,IPC を通じてブラウザプロセス内の既存コードと連携させる以外道がないということになります.このことをちゃんと調べられたのが 2013 年 9 月,Ash モードでの IME サポートに関するバグが登録されて実に 10 か月が経過してのことでした.<br /> <a href="https://code.google.com/p/chromium/issues/detail?id=164964">Issue 164964 - chromium - Support basic functionality of IMEs in Chrome Metro ASH on Windows 8 - An open-source project to help move the web forward. - Google Project Hosting</a><br /> 動作する最低限のコードは 10 月中には完成させたのですが,Desktop Aura の安定化を優先させたこと,変更が大きなことから,実際にチェックイン作業を始められたのは 11 月下旬でした.残念ながら M-32 には間に合わず,M-32 ベースの Ash モードでは IME は動作しません.<br /> とはいえ遅れはしたものの,予定した変更の大半は無事 M-33 ブランチカット前にチェックインを終えることができました.M-34現在,Ashモードでニコニコ動画にコメント入力すら可能です.ニコニコ動画に IME で入力するときは,</p> <ol> <li>WinRT プロセス</li> <li>ブラウザプロセス</li> <li>レンダラプロセス</li> <li>プラグインコンテナプロセス</li> </ol><p>と 4 つのプロセスが非同期 IPC で連携しながら動作することになるのですが,その綱渡り具合を真に理解できる人がはたして世界に何人いるのかにも興味があるところ.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140104/20140104120535.png" alt="f:id:NyaRuRu:20140104120535p:plain" title="f:id:NyaRuRu:20140104120535p:plain" class="hatena-fotolife" itemprop="image"></span><br /> Ash モードの Flash 上で候補ウィンドウの位置が正しく設定されない問題は M-34 で直ります.</p> </div> </div> <div class="section"> <h3>IME に関係なく行きがかり上担当することになったもの</h3> <div class="section"> <h4>User Agent 文字列が正しい OS バージョンを示さない</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=259228">Issue 259228 - chromium - User agent string does not show the correct OS version on Windows 8.1 - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>Windows 8.1 で動く Chromium の User Agent 文字列が</p> <pre class="code" data-unlink>Mozilla/5.0 (Windows NT 6.2; WOW64)</pre><p>みたいになっていました.いわゆる GetVersion(Ex) API 問題.ブラウザの User Agent 文字列から OS のシェア推定とかやっているところには影響があったはず.<blockquote class="twitter-tweet" lang="ja"><p><a href="https://twitter.com/NyaRuRu">@NyaRuRu</a> FYI: <a href="http://t.co/Ary1YgDNhu">http://t.co/Ary1YgDNhu</a></p>&mdash; なかのん -Nakanon- (@d_toybox) <a href="https://twitter.com/d_toybox/statuses/355193054803660800">2013, 7月 11</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="ja"><p><a href="https://twitter.com/NyaRuRu">@NyaRuRu</a> あー、確かに、Win8.1でUA名、6.2のままですね。</p>&mdash; なかのん -Nakanon- (@d_toybox) <a href="https://twitter.com/d_toybox/statuses/355198407637344257">2013, 7月 11</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p><p>という感じの,のどかな会話から思いがけず発覚したのが印象的でした.Mozilla 側でも直後に修正されています.<br /> まあついでということで Chromium にはパッチを投げてみました.メジャーブラウザ の User Agent 文字列に影響する変更というのはなかなか貴重な体験でした.</p> </div> <div class="section"> <h4>全部の *.exe にアプリケーションマニフェストファイルを設定すべき</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=260692">Issue 260692 - chromium - All executables should embed application manifest - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>先ほどの GetVersion(Ex) API 問題を修正するために chrome.exe のマニフェストファイルをアップデートしたわけですが,コードレビューで「ユニットテストとプロダクションバイナリで動作が変わるのは良くないから,全部の *.exe に同じアプリケーションマニフェストを設定できないかな」的なコメントが付いたで急遽やることになった仕事です.<br /> Mozc で培った Gyp 誰得ノウハウをいかんなく発揮して華麗に解決! といけばよかったのですが,実際全部の *.exe にマニフェストファイルを埋め込んでみたら今度は「ユニットテストのビルドが 30 倍遅くなった!」と怒られます.えー</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=276953">Issue 276953 - chromium - unit_tests build regression by 30X - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>結局いくつかのユニットテストではマニフェストファイルを埋め込まず隣に置く方式になりました.<br /> 後日談としては,Gyp r1813 でマニフェストファイルの扱いが大幅に見直されたので,パフォーマンスを悪化させずにマニフェストを埋め込むことができるようになりそうです.</p> </div> <div class="section"> <h4>Web MIDI: Windows 対応</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=303599">Issue 303599 - chromium - Web MIDI: implement MIDIManager for Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=317355">Issue 317355 - chromium - Web MIDI: MIDIInput.cpp does not handle SysEx message properly - An open-source project to help move the web forward. - Google Project Hosting</a></li> <li><a href="https://code.google.com/p/chromium/issues/detail?id=329964">Issue 329964 - chromium - Web MIDI: receivedTime is incorrect on Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>社内 TechTalk で Toyoshima さんが Windows 版 Chromium 向け Web MIDI の実装者を募集していて,Mac 版が既に動いているならそれほど苦労せずに Windows 版も対応できるかなと思って手を上げました.<br /> 実際,10 月19日の Web Music ハッカソンにふらっと立ち寄って半日で単純な入出力までできたのですが,細かいところまで見てみると既にある共通部分のコードにも色々バグを見つけてしまい,基本部分からひとつずつバグを直していくことになりました.私にとっては Blink への初コミットが Web MIDI となります.<br /> Aura/Ash の IME 実装がほんとに大変な時期だったというのもあって,コードレビューの待ち時間等を利用して少しずつ直しながら,一か月半後ぐらいの12月4日にやっと有効化となりました.</p> </div> <div class="section"> <h4>Windows で電源イベントのオブザーバーが動いていなかった</h4> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=314477">Issue 314477 - chromium - PowerMonitor is not functional on Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul><p>Web MIDI 関連で調べているときにたまたま見つけてしまったバグです.Chromium の実装用のライブラリに,電源コードの抜き差しや,サスペンドへの移行・復帰時にコールバックを受けられる仕組みがあるのですが,これが数か月動いていませんでした.<br /> タイマ割り込み精度の変更とか GPU ウォッチドッグタイマの設定とかネットワークのコネクションキャッシュがこれらのイベントに依存しているみたいですが,誰も気づいていなかったみたいですね.</p> </div> </div> <div class="section"> <h3>その他社内コンサル業</h3> <div class="section"> <h4>W3C Working Draft: Input Method Editor API</h4> <p><a href="http://www.w3.org/TR/ime-api/">http://www.w3.org/TR/ime-api/</a><br /> W3C に提案中の Input Method Editor API について,社内で API 設計の議論をしたり,Chromium での実装に関してアドバイスをしたりしています.</p> </div> <div class="section"> <h4>chrome.input.ime</h4> <p><a href="http://developer.chrome.com/extensions/input_ime.html">http://developer.chrome.com/extensions/input_ime.html</a><br /> Chromium OS 専用の内部 API である,chrome.input.ime についてもたまに議論に参加したりしています.</p> </div> </div> <div class="section"> <h3>感想</h3> <p>色々思うところのある1年でした.</p> </div> <div class="section"> <h3>今年の話とか</h3> <p>2014 年 1 月から社内の (Chromium 以外の) 別プロジェクトに移ることにしました.Web MIDI 等,趣味として参加できそうな部分は引き続きコミットしていければと思いますが,締め切りのあるバグを担当するほどの余裕はたぶんないと思います.社内コンサル業と,IME 周りのクリティカルな部分のコードレビューに費やす時間ぐらいはまあなんとか捻出したいところ.</p> </div> <div class="section"> <h3>過去編</h3> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2013/01/03/214030">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Chromium &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul> </div> Sat, 04 Jan 2014 12:32:38 +0900 hatenablog://entry/12921228815715740078 2013年やったこと - Mozc 編 https://nyaruru.hatenablog.com/entry/2014/01/02/120515 <p>2013年やったこと - Mozc 編,いつもどおりコードが公開されている範囲で.</p> <div class="section"> <h4>Mozc IPC の Windows 64-bit 対応</h4> <p>Windows 環境で動く Mozc は名前付きパイプ使ってプロセス間通信を行うのですが,いわゆる "Squatting Attack" 対策として,GetNamedPipeServerProcessId API で接続先のプロセス ID を取得し,さらにそのプロセス ID から GetModuleFileNameExW API で実行ファイル名を取得して検証しています.が,この仕組みが今は動いていても将来的にうまく動かないことがあるかもという問題.<br /> このころ mozc_server や mozc_renderer を 64-bit で動かす実験を行っていて気付いたわけですが, 32-bit プロセスから 64-bit プロセスに対して GetModuleFileNameExW API を呼び出すと必ず失敗するようです.仕方ないので GetProcessImageFileNameW API を使うように変更して対処.これまで mozc_server と mozc_renderer は常に 32-bit プロセスだったので問題が表面化していなかったというわけでした.</p> </div> <div class="section"> <h4>TSF-Mozc 使用時に ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0) が動作しない</h4> <p>IMM32 の頃には,アプリケーション側から進行中のコンポジションをキャンセルするという API が存在しました.TSF になってそういう API はなくなったのですが,CUAS はなにかしらの方法でこの IMM32 API を エミュレートする必要があります.実際これは「コンポジションの範囲を空にする」という形で行われています.ということで TSF-Mozc でも対応する必要があるというわけでした.<br /> Excel が,インライン補完のためにこの機能に依存しているので割と重要だったりします.</p> </div> <div class="section"> <h4>TSF-Mozc で候補ウィンドウの候補をマウスで選択・決定できない問題の修正</h4> <p>経験上ほとんどの人はマウスで候補ウィンドウを選択しないのを知っていたので,TSF-Mozc ではマウス関係の処理を後回しにしていました.とはいえ,タッチイベントでも動作しないのはそろそろよろしくないというのもあって修正という感じです.</p> </div> <div class="section"> <h4>TSF-Mozc での InputScope のサポート</h4> <p>InputScope も登場後 10 年以上経っている仕組みで,いまさらという感もありますが,Windows 8 以降はだいぶ InputScopeへの移行が進んでいます.最近はブラウザの HTML Forms の種類が InputScope で通知されたり,Windows 8 以降でImmSetConversionStatus API が (デフォルト設定では) 実質廃止になったりで,IME 側も InputScope 対応が割と重要になってきています.というわけで TSF-Mozc でも対応してみました.<br /> アプリケーション開発者様におかれましても,Windows 8 以降,ImmSetConversionStatus API は大多数のユーザー環境で期待通り動作していない可能性が高いため,この機会に InputScope に移行してしまうのが良いのではないかと思います.詳細については下記資料等を参照してください.</p> <ul> <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh994466.aspx">Switch text input changed from per-thread to per-user (Windows)</a></li> <li><a href="http://www.grapecity.com/tools/support/technical/knowledge_detail.asp?id=35737">IME&#x30E2;&#x30FC;&#x30C9;&#x306E;&#x5207;&#x308A;&#x66FF;&#x3048;&#x3092;Windows 8&#x4EE5;&#x964D;&#x306E;&#x74B0;&#x5883;&#x3067;&#x884C;&#x3046;&#x65B9;&#x6CD5; - InputMan for Windows Forms 7.0J - &#x30CA;&#x30EC;&#x30C3;&#x30B8;&#x30D9;&#x30FC;&#x30B9;&#x306E;&#x8A73;&#x7D30; &#xFF5C; GrapeCity Developer Tools</a></li> </ul><p>さて,デスクトップ IME の文脈で気を付けるべき点として,アプリケーション側からのモード変更リクエストを永続的なものとして扱うか,一時的な変更リクエストとして扱うかという問題があります.たとえば次のような順序でテキストフィールドを移動していったとしましょう.</p> <ol> <li>通常のテキストフィールド</li> <li>パスワードフィールド</li> <li>通常のテキストフィールド</li> </ol><p>多くの場合,ステップ 1 で IME がオンの状態であれば,ステップ 3 でIME がオンの状態に復帰します.つまり,パスワードフィールドで IME が自動的にオフになるのは,永続的なモード変更ではなく一時的なモード変更というわけです.<br /> では次の場合はどうなるべきでしょうか?</p> <ol> <li>通常のテキストフィールド</li> <li>全角カタカナが期待されるテキストフィールド</li> <li>通常のテキストフィールド</li> </ol><p>ステップ 2 で IME の入力モードが「全角カタカナ」になるのはまあ良いとします.では,ステップ 3 に移動したときにも「全角カタカナ」のままであるべきでしょうか? それともステップ 1 のときのモードに復帰すべきでしょうか. <br /> TSF-Mozc に関しては,InputScope によるモード変更リクエストはその場限りの一時的なものであるという解釈を行いました.したがって,上記ステップ 3 ではステップ 1 のときのモードに復帰します.簡単に Design Doc を書いていますので詳細についてはそちらを参照してください.</p> <ul> <li><a href="https://code.google.com/p/mozc/wiki/InputScope">InputScope - mozc - DesignDoc - InputScope support - Mozc - Japanese Input Method for Chromium OS, Android, Windows, Mac and Linux - Google Project Hosting</a></li> </ul> </div> <div class="section"> <h4>Windows 版 Mozc での Mode Indicator のサポート</h4> <p>これ.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140102/20140102115121.png" alt="f:id:NyaRuRu:20140102115121p:plain" title="f:id:NyaRuRu:20140102115121p:plain" class="hatena-fotolife" itemprop="image"></span><br /> 位置形状とフォントサイズの決定以外のほぼ全てを担当しました.個人的にはカーソル直下よりもカーソルに対して左揃えの方が良いんではないかとか,ちょっと大きすぎるんではないかとか色々思うところはあるのですが,まあデザイナーさんがそう言っているわけで案件.個人的にはもうちょっと作りこみたかったのですが,別の仕事が忙しくてあんまり専念できなかったのが心残りです.<br /> InputScope で自動モード変更を行う以上,この種の視覚的フィードバックは必須ですね.というわけで InputScope 対応とセットで実装されました. </p> </div> <div class="section"> <h4>周辺文字列を利用した変換の (部分的) サポート</h4> <p>周辺文字列を利用した変換も十数年以上の歴史があるいまさら技術ではあります.前世紀の IMM32 時代から <a href="http://msdn.microsoft.com/en-us/library/dd318632.aspx">IMR_DOCUMENTFEED</a> メッセージをサポートしたアプリケーションでは周辺文字列を利用した変換は可能でした.<br /> さて,周辺文字列を利用した変換というのは実際のところあんまりコストパフォーマンスの良くないアプローチだと思っています.細切れ変換対策という意味では,変換エンジン側で前回コミットされた文字列を覚えておけばすむ話です.というわけで,今回注目したのは,IME をオフにして入力しがちな文字種,つまり半角英数です.<br /> たとえば「明日1日」という文章を入力するのに,</p> <ol> <li>「明日」を入力</li> <li>IME をオフにする</li> <li>「1」を入力</li> <li>IME をオンにする</li> <li>「日」を入力</li> </ol><p>という使い方をする人は一定いることが分かっています.以前の Mozc では,ステップ 4 実行時に内部ステートは「文頭」状態でした.というのも,IME がオフの状態で入力された内容はモニタリングしていないので,ステップ 5 で入力する内容がどういう文章に続くものなのか把握できません.今回救いたかったのはまさにこういうケースで,カーソル前にある文字種がアルファベットか数字かどうかだけを判定します.このあたりの詳細についても Design Doc を書いておきましたので詳細が気になる人はどうぞ.</p> <ul> <li><a href="https://code.google.com/p/mozc/wiki/SurroundingText">SurroundingText - mozc - DesignDoc - Surrounding Text support - Mozc - Japanese Input Method for Chromium OS, Android, Windows, Mac and Linux - Google Project Hosting</a></li> </ul><p>imm32-mozc と tsf-mozc,ibus-mozc および mozc_server の実装を担当しました.<br /> IMM32 版では IMR_DOCUMENTFEED を単純に使うだけですが,TSF では <a href="http://blogs.msdn.com/b/tsfaware/archive/2007/05/21/transitory-extensions.aspx">Transitory Extensions</a> という拡張的な仕組みも使っていて,メモ帳や Internet Explorer にも対応しています.軽く調べてみた限り,ATOK 2013 も MS-IME 2013 も Transitory Extensions までは使っていないようなので,ちょっとしたアピールポイントではないかと思っております.<br /> このとき書いたコードは別のオープンソースプロジェクトで使われたりもしているようです.</p> <ul> <li><a href="https://github.com/deton/tsf-vim">deton/tsf-vim &middot; GitHub</a></li> <li><a href="https://github.com/deton/tsf-tutcode">deton/tsf-tutcode &middot; GitHub</a></li> </ul> </div> <div class="section"> <h4>C++11 対応</h4> <p>最近社内コード規約的に C++11 が解禁されつつあるので Mozc でもいくつかコードのクリーンアップを行っています.具体的には,</p> <ul> <li>自前 scoped_ptr から std::unique_ptr への置き換え</li> <li>COMPILE_ASSERT マクロの static_assert への置き換え</li> <li>auto での書き換え</li> <li>NULL から nullptr への置き換え</li> </ul><p>あたりをちまちまやってます.<br /> 最近は Visual C++ の C++11 適応度合が上がってきていてだいぶ楽なのですが,意外に足を引っ張るのが Mac OS X だったり.というのも,libc++ の実行時ライブラリが標準で入るようになったのが Mac OS X 10.7 以降.未だに Snow Leopard をサポートしていたりすると C++11 の大部分の機能が使えないのでした.</p> </div> <div class="section"> <h4>UCS2 しかサポートできない内部関数の削除</h4> <p>Mozc コードベースに残っていた UCS2 専用関数をすべて削除しました.</p> </div> <div class="section"> <h4>TSF-Mozc でタッチに最適化されたオンスクリーンキーボードを表示するように</h4> <p>ITfFnGetPreferredTouchKeyboardLayout を実装するだけ,というわけでもなくて Windows のオンスクリーンキーボードは U+F003 と U+F004 に特別な意味を持たせたりしているのでその対応とか.詳しくは下記資料参照のこと.</p> <ul> <li><a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh967425.aspx#ime_for_touch_keyboard">Guidelines and checklist for IME development (Windows Store apps) (Windows)</a></li> </ul> </div> <div class="section"> <h4>可能なら LogicalToPhysicalPointForPerMonitorDPI API を使う</h4> <p>Mozc の候補ウィンドウや Mode Indicator は,入力中のプロセスとは別のプロセスで動いているので,DPI 仮想化にともなう座標変換が必要になることがあります.Windows 8.1 Preview で LogicalToPhysicalPoint API が動作しなくなっていたので,新しく追加された LogicalToPhysicalPointForPerMonitorDPI API が利用可能ならそちらを使う,といった修正を行っていました.Windows の DPI 周り,ほんと落ち着かないですね.<br /> 次の資料とかが詳しいです.<br /> <a href="http://go.microsoft.com/fwlink/?LinkID=307061">http://go.microsoft.com/fwlink/?LinkID=307061</a><br /> </p> </div> <div class="section"> <h4>アプリケーションマニフェストに Windows 8.1 対応宣言を追加</h4> <p>恒例行事.</p> </div> <div class="section"> <h4>ITfLangBarItemButton::GetIcon で返すモノクロフォントを実行時に描画</h4> <p>Accessibility (a11y) 案件.<br /> Windows 版の Mozc は,控えめに言っても Accessibility 関係の機能が全然足りていないのですが,珍しく対応している機能のひとつに言語バーのテキストアイコン色があります.Windows では,デスクトップテーマをハイコントラストモード(背景色黒・文字色緑) に変更すると,言語バーのテキストアイコンも緑色に切り替わります.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140102/20140102115125.png" alt="f:id:NyaRuRu:20140102115125p:plain" title="f:id:NyaRuRu:20140102115125p:plain" class="hatena-fotolife" itemprop="image"></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140102/20140102115128.png" alt="f:id:NyaRuRu:20140102115128p:plain" title="f:id:NyaRuRu:20140102115128p:plain" class="hatena-fotolife" itemprop="image"></span><br /> ではこれどうやって実装するかですが,大まかに方法は 2 つ.<br /> A. 実行時にアイコンを描画する.この場合,テーマカラーを実行時に取得できるので文字色は問題ない.テーマが変更されるたびにアイコンを再生成する必要がある.<br /> B. モノクロアイコンを事前に生成しておき,言語バーAPI に TF_LBI_STYLE_TEXTCOLORICON フラグを渡す.この場合,言語バー側で色変更を行ってくれる.<br /> Mozc はながらく B の方法を使っていました.が,最近になってビットマップハンドルのリークが発生しているという報告を受けて調べてみると驚きの事実が! ITfLangBarItemButton::GetIcon にモノクロアイコンを渡すと,言語バー内部でビットマップハンドルのリークが発生するようです.というわけで方向 A で書き直しました.<br /> この問題,原因の発見までがとにかく大変だったのが印象的でした.ハンドルリークが全然再現できず困っていたのですが,ユーザーの方からアップロードしていただいたスクリーンショットがクラシックテーマだったことが気になってテーマを変更してみたところやっと再現できた,というケースです.どういうやりとりが行われたか興味がある人は以下のスレッドをどうぞ.</p> <ul> <li><a href="http://productforums.google.com/d/msg/ime-ja/W1V7pKjUuB4/DtpudRLPpfQJ">Google &#x30B0;&#x30EB;&#x30FC;&#x30D7;</a></li> </ul><p>TF_LBI_STYLE_TEXTCOLORICON を使用している IME 作者様はご注意ください.</p> </div> <div class="section"> <h4>Adobe Sandbox をサポート</h4> <p><a href="https://twitter.com/corvussolis">@corvussolis</a> さんから Adobe Flash および Adobe Acrobat Reader で使われている Sandbox の動作について教えてもらって Mozc でも対応してみたという話.これでやっと Firefox でも「保護モード」オンのまま<a href="http://www.nicovideo.jp">&#x30CB;&#x30B3;&#x30CB;&#x30B3;&#x52D5;&#x753B;</a>にコメントを書けるようになりました.<br /> ご協力いただいた皆様に感謝.</p> </div> <div class="section"> <h4>Windows 8 以降で MS-IME からのユーザー辞書インポートが動かなくなっていたのを修正</h4> <p>詳細については <a href="https://code.google.com/p/mozc/source/diff?spec=svn184&r=178&format=side&path=/trunk/src/dictionary/user_dictionary_importer.cc&old_path=/trunk/src/dictionary/user_dictionary_importer.cc&old=163">diff</a> を参考にしてください.</p> </div> <div class="section"> <h4>Owner Rights SID を設定</h4> <p>Windows では,オブジェクト所有者に暗黙に WRITE_DAC および READ_CONTROL 権限が許可されるという仕様がありましたが,Vista 以降この挙動を拒否することが可能になりました.</p> <ul> <li><a href="http://technet.microsoft.com/en-us/library/dd125370.aspx">AD DS: Owner Rights</a></li> </ul><p>というわけで Mozc でも不要な権限を削除してみたという話.追加すると権限が減る系の SID ですね.</p> </div> <div class="section"> <h4>Windows 版 Mozc のビルド時に Cygwin が不要になった</h4> <p>Mozc のビルドは,もともと Cygwin に依存しないように作られていました.しかし,Mozcのビルドシステムを SCons から gyp に変更したときに,gyp に引っ張られる形で Cygwin 依存が生まれてしまいました.<br /> 外部コマンドの呼び出しに時に色々気を付ければ Cygwin は不要というのは分かっていたのですが,とりあえず重要度は低いので後回しのままとなってはや数年,いい加減直すかということでやっと依存関係を解消したという話です.Windows 版 OSS Mozc のチェックアウトサイズもだいぶ減ったはず.<br /> ちなみに Chromium も同様の問題があって,以下のようにビルド時の Cygwin 依存を取り除く努力が行われています (こっちも数年がかり).</p> <ul> <li><a href="https://code.google.com/p/chromium/issues/detail?id=123026">Issue 123026 - chromium - Remove cygwin as a build dependency on Windows - An open-source project to help move the web forward. - Google Project Hosting</a></li> </ul> </div> <div class="section"> <h3>以下 OSS Mozc 固有っぽいもの</h3> <div class="section"> <h4>Issue 42: get rid of absolute path in unix/ibus/gen_mozc_xml.py</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=41">https://code.google.com/p/mozc/issues/detail?id=41</a><br /> ibus-mozc のバイナリとアイコンファイルのインストール先はカスタマイズできるべきだという案件.3 年ぐらい放置されていのですが (すみません) リファクタリングの一環として対応.</p> </div> <div class="section"> <h4>Issue 180: Mozc and IBus does not respect xinerama at all</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=180">https://code.google.com/p/mozc/issues/detail?id=180</a><br /> マルチディスプレイ環境で mozc_renderer が画面境界の判定に失敗するというバグ.gdk_screen_get_monitor_at_point を使うことで解決.</p> </div> <div class="section"> <h4>Issue 182: mozc property titles are empty in gnome-shell</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=182">https://code.google.com/p/mozc/issues/detail?id=182</a><br /> Red Hat で ibus-mozc をメンテナンスされている Tagoh さんから転送されてきたバグの対応.Gnome-Shell はいくつかの IBus メタデータに依存しているのですが,ibus-mozc がそれらを設定していないという問題.具体的には,</p> <ul> <li>IBus 1.5 以降にのみ存在する symbol というプロパティをセットするようにする (これを行わないと現在の入力モードがアイコンとして表示されない)</li> <li>Gnome Shell は "InputMode" という名前のプロパティに現在のモード (全角カタカナとか直接入力とか) が設定されていることを期待しているので,プロパティ名を変更</li> </ul><p>という感じです.ちなみにこのあたりの Gnome-Shell の仕様はどこにもドキュメント化されていません.自分でソースを読んで調べる必要があります.結果的に以下のような見た目になりました.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20140102/20140102115130.png" alt="f:id:NyaRuRu:20140102115130p:plain" title="f:id:NyaRuRu:20140102115130p:plain" class="hatena-fotolife" itemprop="image"></span><br /> このパッチがあたっていないバージョンの Mozc (具体的には 1.6.1187.102 以前) では,入力中のモードは分かりませんし,入力モードを Gnome Shell から選択することもできません.</p> </div> <div class="section"> <h4>Issue 188: Add Session command for ConvertPrevPage and ConvertNextPage</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=188">https://code.google.com/p/mozc/issues/detail?id=188</a><br /> Fcitx の開発者から来た機能追加リクエスト.Fcitx の候補ウィンドウには次頁・前頁に相当するボタンが存在するのですが,その動作に対応するメッセージが Mozc のプロトコルに存在しなかったという問題.たまたま Windows 8 のソフトウェアキーボード対応で似たような需要があったので合わせて対応となりました.</p> </div> <div class="section"> <h4>Issue 189: use_libprotobuf=1 does not work in Mozc 1.10.1390.102</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=189">https://code.google.com/p/mozc/issues/detail?id=189</a><br /> Red Hat で ibus-mozc をメンテされている Tagoh さんから,システムにインストールされている libprotobuf を使用する場合のビルドが壊れているとの報告があったので粛々と修正.壊したのも私なのでマッチポンプ案件だったりします.</p> </div> <div class="section"> <h4>Issue 195: Candidate Popup is hidden by Cinnamon menu</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=195">https://code.google.com/p/mozc/issues/detail?id=195</a><br /> Linux で Cinnamon を使っていると,mozc_renderer がメニューの後ろ側に行ってしまうという問題.修正は 2 行で済んだんですが,環境のセットアップやら調査やらで結局 1 日ぐらいかかっているという.ちなみにこのケースでは日曜日が消えました.</p> </div> <div class="section"> <h4>Issue 198: 'build_mozc.py gyp' fails when gyp r1667 or higher is used</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=198">https://code.google.com/p/mozc/issues/detail?id=198</a><br /> Mozc 開発ではビルドに使用する gyp のリビジョンを固定しているのですが,OSS Mozc をビルドする人は推奨リビジョン以外の gyp と組み合わせている人もいるらしく,gyp 側の変更でビルドできなくなることがあります.<br /> 今回は,Mozc r171 以前と gyp の r1667 以降を組み合わせるとビルドに失敗するという問題でした.</p> </div> <div class="section"> <h4>Issue 199: ibus-mozc must be locked down on the Gnome Shell's locked screen</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=199">https://code.google.com/p/mozc/issues/detail?id=199</a><br /> <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4509">CVE-2013-4509</a> の ibus-mozc 側の対処を一通りやりました.<br /> 私も完全に背景を把握できているか怪しいのですが,概ね以下のような感じだと理解しております.</p> <ol> <li>2013年1月4日,Gnome 3 環境で IME をオンにしたままスクリーンをロックし, Gnome-Shell のスクリーンロック解除画面からパスワードを入力してロック解除しようとすると,パスワードフィールドで IME がオンのままになっているというバグが Red Hat の Jens Petersen さんから報告される.<a href="https://bugzilla.redhat.com/show_bug.cgi?id=891835">Red Hat Bug 891835</a></li> <li>2013年1月9日,Red Had の Ueno さんから,GTK の "input-purpose" と "input-hints" を,パスワードフィールドにセットすることで問題が回避したらよいのではという提案がなされる.<a href="https://bugzilla.gnome.org/show_bug.cgi?id=691392">Gnome Bug 691392</a></li> <li>2013年1月10日,Red Hat の Ueno さん,ibus-gtk2 にパッチをコミット (<a href="https://github.com/ibus/ibus/commit/927e9f58da9b4a9898403c8e339109e2ad2fa966">927e9f58</a>).この変更は IBus 1.5.3 としてリリースされる.変更は ibus-gtk2 に対するもので,IM Engine 側では何もする必要がない.具体的には,"input-purpose" が password であれば,使用している IM Engine に関わらず IM Engine が無効化される.</li> <li>2013年8月14日,Red Hat の Ueno さん,ibus-gtk にパッチをコミット (<a href="https://github.com/ibus/ibus/commit/3b3a7ceccbf75f36dee0df45589d79f7e96131f4">3b3a7cec</a>).この変更は IBus 1.5.4 としてリリースされる.この変更によりまたしても挙動が変わり,"input-purpose" が password のときの振る舞いは各 IM Engineの責任になる.具体的には,IM Engine が IBus 1.5.4 以降の環境で動作する場合のみ,このコミットで追加された ibus_engine_get_content_type 等の新しい API を使って IM Engine の動作を変更する必要がある.</li> <li>2013年9月21日,Red Hat の Fujiwara さんから <a href="https://groups.google.com/d/msg/ibus-devel/mvCHDO1BJUw/hSOCNHSDwPQJ">IBus 1.5.4 &#x306E;&#x30EA;&#x30EA;&#x30FC;&#x30B9;&#x304C;&#x30A2;&#x30CA;&#x30A6;&#x30F3;&#x30B9;&#x3055;&#x308C;&#x308B;</a>.この中で "Handle GTK+ input purose for gnome-shell password dialog and each engine need to implement it" として各 IM Engine 開発者向けにアナウンス.</li> <li>2013年9月21日,俺のターン! IBus 1.5.4 のリリースノートを受けて <a href="https://code.google.com/p/mozc/issues/detail?id=199">OSS Mozc Issue 199</a> をファイル.この時点では状況を完全に把握できていませんでした.</li> <li>2013年9月30日,俺のターン! やっと状況を把握.急いでOSS Mozc Issue 199 への<a href="https://code.google.com/p/mozc/issues/detail?id=199#c1">&#x30D1;&#x30C3;&#x30C1;&#x3092;&#x516C;&#x958B;</a>.帰宅後色々弄っていて事態の深刻さに気付き急いで書き上げた感じの奴です.翌日ほんと眠かったです.</li> <li>2013年10月1日,Red Hat の Mike FABIAN さんから,IBus 1.5.4 側の問題で "input-purpose" が正しく通知されないことがある問題が報告される.<a href="https://bugzilla.redhat.com/show_bug.cgi?id=1013948">Red Hat Bug 1013948</a> この問題はすぐに修正されるものの,対応する IBus の安定板リリースは行われておらず,各ディストリビューションでは独自にパッチを取り込んで IBus 1.5.4 として配布している.</li> <li>2013年10月25日,openSUSE のコミュニティメンバーの Takeyama さんから,<a href="https://bugzilla.novell.com/show_bug.cgi?id=847718">Novel Bug 847718</a> がファイルされる.</li> <li>2013年11月4日,Red Hat の Kurt Seifried さんにより今回の問題に CVE-2013-4509 が付与される.</li> </ol><p>この後 IBus を採用する各種ディストリビューションで色々対応が進んだようです.</p> </div> <div class="section"> <h4>Issue 201: making initial mode customizable for ibus-mozc</h4> <p><a href="https://code.google.com/p/mozc/issues/detail?id=201">https://code.google.com/p/mozc/issues/detail?id=201</a><br /> 1.5.2 のころまでの IBus は,各 IM Engine は「直接入力 (いわゆる IME オフ)」というステートを持たないことを前提に設計されていました.従って,ibus-mozc は起動直後にひらがなモードである必要があります.<br /> が,IBus 1.5.3 頃から,日本語 IME に関しては各 IM Engine 内部でオンオフ状態を切り替える方向に IBus 上流の人たちは心変わりしたようです.Red Hat の Fujiwara さんが ibus-anthy の挙動変更について下で説明されています.<br /> <a href="https://code.google.com/p/ibus/issues/detail?id=747#c31">https://code.google.com/p/ibus/issues/detail?id=747#c31</a><br /> この変更にともない,以前の使い勝手を再現するためには,ibus-mozc が起動直後に「直接入力 (いわゆる IME オフ)」になって欲しいという要望が来たのが OSS Mozc Issue 201 です.<br /> とはいえ Mozc は IBus 1.4 もまだ対応していますから,IBus のバージョンによらずデフォルトモードを変えてしまうと今度は IBus 1.4 ユーザーが困ることになります.また,デフォルトモードを選択する UI を追加しようにも,Mozc の設定画面は imm32-mozc, tsf-mozc, ibus-mozc, uim-mozc, fcitx-mozc, emacs-mozc, Mozc for IMKit で共有されているため,IBus 1.5.3 以降専用の項目を追加するのは躊躇するところです.<br /> とりあえず初期状態をオフにするパッチだけは公開しましたが,以後のリリースでどうするかは未定です.<br /> <a href="https://code.google.com/p/mozc/issues/detail?id=201#c8">https://code.google.com/p/mozc/issues/detail?id=201#c8</a><br /> ちなみに,初期値を変更するぐらい簡単だろうと思われる方もいらっしゃるかもしれません.が,実際は結構面倒です.事実,上のパッチを適用すると,mozc_server が予想外のクラッシュをした時のプレイバックの仕組みが壊れることが分かっています.初期値が変わっちゃったわけですね.</p> </div> <div class="section"> <h4>その他 OSS Mozc でメンテナンスしていたページ</h4> <ul> <li><a href="https://code.google.com/p/mozc/wiki/ReleaseHistory">https://code.google.com/p/mozc/wiki/ReleaseHistory</a></li> <li><a href="https://code.google.com/p/mozc/wiki/AboutMozc">https://code.google.com/p/mozc/wiki/AboutMozc</a></li> <li><a href="https://code.google.com/p/mozc/wiki/WindowsBuildInstructions">https://code.google.com/p/mozc/wiki/WindowsBuildInstructions</a></li> <li><a href="https://code.google.com/p/mozc/wiki/LinuxBuildInstructions">https://code.google.com/p/mozc/wiki/LinuxBuildInstructions</a></li> </ul> </div> <div class="section"> <h4>その他 OSS Mozc 関係でやったこと</h4> <p>2013年4月ぐらいに fcitx-mozc のマニュアルテストを行って 6 件ぐらいバグを見つけたところ,作者様にものすごい勢いで修正していただきました.</p> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2013/04/06/213423">Fcitx-mozc &#x3092;&#x8A66;&#x3057;&#x3066;&#x307F;&#x305F; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul><p>あと,fcitx-mozc の再変換には,ibus-mozc の再変換用に私が書いたコードが使われていたりするようです.</p> <ul> <li><a href="https://gitorious.org/fcitx/mozc/source/b56a93877c9bb1c529494830fa5b1e808923ce06:src/unix/fcitx/surrounding_text_util.h">src/unix/fcitx/surrounding_text_util.h in fcitx/mozc:master - Gitorious</a></li> <li><a href="https://gitorious.org/fcitx/mozc/source/b56a93877c9bb1c529494830fa5b1e808923ce06:src/unix/fcitx/surrounding_text_util.cc">src/unix/fcitx/surrounding_text_util.cc in fcitx/mozc:master - Gitorious</a></li> </ul> </div> </div> <div class="section"> <h3>今年の話とか</h3> <p>入社後なんだかんだでずっと Mozc に関わってきましたが,2014 年 1 月から社内の別プロジェクトに移ることにしました.オープンな場で何をやったか話すのはいつも通り書いたコードが公開されてからにしようかと思います.<br /> Windows 版 Mozc は 20% の枠内で今後も協力していきたいところですが,ibus-mozc のメンテナンスまでやる余裕はなさそうです.ibus-mozc の今後の開発・メンテナンスを引き継いでもいいという方がいらっしゃいましたら社内外問わずお知らせください.</p> <ul> <li><a href="https://code.google.com/p/mozc/issues/detail?id=194">Issue 194 - mozc - ibus-mozc is now in maintenance mode - Mozc - Japanese Input Method for Chromium OS, Android, Windows, Mac and Linux - Google Project Hosting</a></li> </ul> </div> <div class="section"> <h3>過去編</h3> <ul> <li><a href="http://nyaruru.hatenablog.com/entry/2013/03/31/172627">2012&#x5E74;&#x4ED6;&#x306B;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> <li><a href="http://nyaruru.hatenablog.com/entry/2013/01/01/134011">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a></li> </ul> </div> Thu, 02 Jan 2014 12:05:15 +0900 hatenablog://entry/12921228815715595286 「ファイルの中身に依存しつつそのファイル自体を更新する」コマンドラインツールはビルドシステムと相性が悪い https://nyaruru.hatenablog.com/entry/2013/12/31/101413 <p>関数型プログラミングのメリットについて語られることはあっても,「ファイルの中身に依存しつつそのファイル自体を更新する」コマンドラインツールがビルドシステムと相性が悪い,みたいな話をする人はあんまりいないようなので書いてみた.</p><p>Windows には signtool.exe というデジタル署名ツールがある.実行ファイル myapp.exeに署名したい場合は以下のようにする.</p> <pre class="code" data-unlink>signtool sign /a myapp.exe</pre><p>十分にシンプルなように見える.が,典型的なビルドシステムはこの処理がお気に召さない.試しに Chromium や node.js で使われているメタビルドシステムである Gyp で書いてみる.</p> <pre class="code" data-unlink>{ &#39;targets&#39;: [ { &#39;target_name&#39;: &#39;myapp&#39;, &#39;type&#39;: &#39;executable&#39;, &#39;sources&#39;: [ &#39;main.cc&#39;, ], }, { &#39;target_name&#39;: &#39;sign&#39;, &#39;type&#39;: &#39;none&#39;, &#39;dependencies&#39;: [ &#39;myapp&#39;, ], &#39;actions&#39;: [ { &#39;action_name&#39;: &#39;run_signtool&#39;, &#39;inputs&#39;: [ &#39;&lt;(PRODUCT_DIR)/myapp.exe&#39;, ], &#39;outputs&#39;: [ &#39;&lt;(PRODUCT_DIR)/myapp.exe&#39;, ], &#39;action&#39;: [&#39;signtool&#39;, &#39;sign&#39;, &#39;/a&#39;, &#39;&lt;(PRODUCT_DIR)/myapp.exe&#39;], &#39;msvs_cygwin_shell&#39;: 0, }, ], }, ], }</pre><p>この Gyp ファイルから生成された Ninja 用ビルドファイルは,以下のようにビルド時にエラーとなる.</p> <pre class="code" data-unlink>C:\work\dag&gt;ninja -C out/Default sign ninja: warning: multiple rules generate myapp.exe. builds involving this target will not be correct; continuing anyway ninja: Entering directory `out/Default&#39; ninja: error: dependency cycle: myapp.exe -&gt; myapp.exe</pre><p>myapp.exe をビルドするのに myapp.exe が必要なのはけしからん,とのこと.<br /> 私の場合,ラッパースクリプトを書いて署名前後でファイルパスの一部が変わるようにして回避することが多い.<br /> 例1. </p> <pre class="code" data-unlink>mysigntool --input=myapp.exe --output=myapp.signed.exe</pre><p>例2.</p> <pre class="code" data-unlink>mysigntool --input=unsigned/myapp.exe --output=signed/myapp.exe</pre><p>デジタル署名に限らず,mt.exe を利用したマニフェストファイルの埋め込み,rebase.exe を利用した事前バインド,Profile Guided Optimization (PGO) などで,うっかり入力ファイルと出力ファイルを同一パスにすると同様の問題に直面する.</p><p>なんでこんな話を書く気になったかというと,暇つぶしに Gyp にパッチを書いていて突然気付いたからである.<br /> <a href="https://codereview.chromium.org/82703007#msg3">https://codereview.chromium.org/82703007#msg3</a><br /> Directed Acyclic Graph (DAG; 無閉路有向グラフ) を事前に構築できることを前提としているシステムというのは,ビルドシステムにしろ MapReduce にしろ,案外日常的にお世話になっている.そういうシステムで「ちょっとした処理」を行うとして,なんだかうまく書けないなぁという処理,実はそれ入力と出力に循環があったりしませんか,というまあただそれだけの話.<br /> こうやって考えてみると,世間のビルドシステムというのはファイルシステムと割とべったりくっついているということに気付かされる.</p> <div class="section"> <h4>まとめ</h4> <p>入力パス名と出力パス名が同じになる操作は,一般的にビルドシステムと相性が悪い.典型的なビルドシステムでは,ファイルの内容ではなくパス名だけを用いて依存関係を記述する必要があることに注意.</p> </div> Tue, 31 Dec 2013 10:14:13 +0900 hatenablog://entry/12921228815715444987 DAG の廻らない冒険 Windows の IME を変換エンジンとして使う https://nyaruru.hatenablog.com/entry/2013/12/18/052616 <p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20131218/20131218051110.png" alt="f:id:NyaRuRu:20131218051110p:plain" title="f:id:NyaRuRu:20131218051110p:plain" class="hatena-fotolife" itemprop="image"></span><br /> プロセス分離型の IME の開発に携わった以上,一度は試してみたいと思っていた奴,の基礎実証実験っぽいのをやってみた.Windows向け IME を (とくに個人規模で) 作っている人にはもしかしたら役に立つかも.</p> <div class="section"> <h3>テーマ</h3> <p>メインテーマは,Windows で IME を実装するとして,バックグラウンドで別 IME を有効化し,その IME に対してクエリを投げ,返ってきた結果を利用するための技術的な枠組みについて.ここではプロセスモデル的に Windows で可能かどうかという点のみを考える.</p> </div> <div class="section"> <h3>大まかな流れ</h3> <p>今回試した手法では,Windows 8 で TSF に追加された <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh920951.aspx">ITfFnSearchCandidateProvider</a> という仕組みを活用する.このインターフェイスは,複雑なことはできない反面,1) 文字列を投げて文字列のリストが返ってくるというシンプルな仕組みである,2) ステートを持たず,IME でユーザーが入力中かどうかに関わらず自由に使える,という点で大変使いやすい.ただしすべての IME が実装しているわけではない.これについては後述.<br /> また,このインターフェイスには "Windows 8 <span data-unlink>[desktop apps only]</span>" と注釈がついている.ここで,プロセス分離型の IME 実装を前提とするのが生きてくる.プロセス分離型の実装では,好きにデスクトッププロセスと連携できるのでこれは特に問題にはならない.</p> </div> <div class="section"> <h3>具体的な流れ</h3> <p>以下の手順で,キーボードフォーカスを持たないバックグラウンドプロセス内で,ITfFnSearchCandidateProvider をサポートした IME を変換エンジンとして使用できる.</p> <ol> <li>バックグラウンドスレッドを作る</li> <li>スレッド内で COM を初期化する (STA 推奨)</li> <li>ITfInputProcessorProfileMgr.ActivateProfile を使用して,使用したい IME を有効化する.</li> <li>ITfThreadMgr2.ActivateEx を呼んで IME に初期化処理を行わせる.</li> <li>ITfThreadMgr2.GetFunctionProvider に,対象 IME の CLSID を渡して ITfFunctionProvider を取得</li> <li>GetFunctionProvider.GetFunction 経由で ITfFnSearchCandidateProvider を取得</li> <li>ITfFnSearchCandidateProvider.GetSearchCandidates で任意のクエリを行う</li> </ol> </div> <div class="section"> <h3>罠ポイント</h3> <p>上記手順の 3 が問題. Windows 8 以降はデスクトッププロセス間で IME 関係の設定を共有するようになったため,うかつに別 IME を選択すると他スレッド/他プロセスにも影響が及んでしまう.これについては, API を使って一時的にこの挙動に関する設定そのものを変更することで回避できそう.具体的には,SystemParametersInfo API に SPI_GETTHREADLOCALINPUTSETTINGS/ SETTHREADLOCALINPUTSETTINGS を指定して,以前の「スレッドごとに IME 関係の設定を保持」に変更する.変更は永続的である必要はなくて,IME を変更するごく短い間だけで十分なようだ.というわけで先ほどの手順をもう少し改良する.</p> <ol> <li>バックグラウンドスレッドを作る</li> <li>スレッド内で COM を初期化する (STA 推奨)</li> <li>「スレッドごとに IME 関係の設定を保持」が有効でなければ SETTHREADLOCALINPUTSETTINGS を使って有効にする</li> <li>ITfInputProcessorProfileMgr.ActivateProfile を使用して,使用したい IME を有効化する.</li> <li>ITfThreadMgr2.ActivateEx を呼んで IME に初期化処理を行わせる.</li> <li>ITfThreadMgr2.GetFunctionProvider に,対象 IME の CLSID を渡して ITfFunctionProvider を取得</li> <li>GetFunctionProvider.GetFunction 経由で ITfFnSearchCandidateProvider を取得</li> <li>「スレッドごとに IME 関係の設定を保持」を変更していれば,SETTHREADLOCALINPUTSETTINGS で元に戻す</li> <li>ITfFnSearchCandidateProvider.GetSearchCandidates で任意のクエリを行う</li> </ol><p>実際には「スレッドごとの IME 設定」を元に戻すのはもう少し手前でも問題ないかもしれない.<br /> また,ユーザーが「アプリウィンドウごとに異なる入力方式を設定する」を有効にしている場合,GETTHREADLOCALINPUTSETTINGS は TRUE を返す.この場合はスレッドごとに異なる IME を有効化できるため何もしなくてよい.</p> </div> <div class="section"> <h3>応用</h3> <p>上の罠ポイントさえ回避できれば,複数のバックグラウンドスレッドを用意し,それぞれに別 IME をロードして構わない.つまり,複数の IME に対して同時にクエリを行うことができる.</p> </div> <div class="section"> <h3>ITfFnSearchCandidateProvider をサポートしている IME はどれぐらいあるのか?</h3> <p>手元の Windows 8.1 環境でしらべたところ,MS-IME 日本語版と ATOK 2013 はサポートしている.Google 日本語入力 / OSS Mozc は1.12.1599.102 の時点で未サポート.以下,実験したい人のための GUID 一覧.</p> <pre class="code" data-unlink>{ name: &#34;MS-IME Japanese (Windows 8.1)&#34;, langid: 0x0411, clsid: &#34;03B5835F-F03C-411B-9CE2-AA23E1171E36&#34;, profile: &#34;A76C93D9-5523-4E90-AAFA-4DB112F9AC76&#34;, }, { name: &#34;ATOK 2013&#34;, langid: 0x0411, clsid: &#34;E7602D3E-204C-4662-B92F-78DF0DE5752D&#34;, profile: &#34;3C4DB511-189A-4168-B6EA-BFD0B4C85615&#34;, }, { name: &#34;Google Japanese Input&#34;, langid: 0x0411, clsid: &#34;D5A86FD5-5308-47EA-AD16-9C4EB160EC3C&#34;, profile &#34;773EB24E-CA1D-4B1B-B420-FA985BB0B80D&#34;, }, { name: &#34;OSS Mozc&#34;, langid: 0x0411, clsid: &#34;10A67BC8-22FA-4A59-90DC-2546652C56BF&#34;, profile: &#34;186F700C-71CF-43FE-A00E-AACB1D9E6D3D&#34;, }, { name: &#34;Corvus-skk&#34;, langid: 0x0411, clsid: &#34;EAEA0E29-AA1E-48ef-B2DF-46F4E24C6265&#34;, profile: &#34;956F14B3-5310-4cef-9651-26710EB72F3A&#34;, },</pre> </div> <div class="section"> <h3>まとめ</h3> <p>Windows 8.1 環境で ITfFnSearchCandidateProvider を利用すると,MS-IME 日本語版と ATOK 2013 を(同時に)フォールバックエンジンとして使う IME が作成可能.</p> </div> <div class="section"> <h3>速度とか所感</h3> <p>MS-IME Japanese は大体 10 msec 以内で返ってくるのでサジェストでも大丈夫かも.ATOK 2013 はクエリが返ってくるまで 100 msec 以上かかっていて,リアルタイムのサジェストに使うのはちょっときついかも.</p> </div> <div class="section"> <h3>サンプルコード</h3> <p>次のコードは,現在使用中の IME からのみ ITfFnSearchCandidateProvider を取得することで色々処理を簡略化したもの.起動後に何か入力すると,その入力を ITfFnSearchCandidateProvider.GetSearchCandidates に渡した結果が返ってくる.空行入力で終了.<br /> ビルドには要 NuGet.Package Manager から TSF.SearchCandidateProvider を追加.</p> <pre class="code" data-unlink>PM &gt; Install-Package TSF.SearchCandidateProvider</pre><pre class="code" data-unlink><span class="synStatement">using</span> System; <span class="synStatement">using</span> System.Linq; <span class="synStatement">using</span> TSF; <span class="synType">static</span> <span class="synType">class</span> Program { <span class="synType">static</span> <span class="synType">void</span> Main(<span class="synType">string</span>[] args) { <span class="synStatement">using</span> (var provider = SearchCandidateProvider.FromCurrentProfile().Result) { <span class="synStatement">if</span> (provider == <span class="synConstant">null</span>) { Console.WriteLine(<span class="synConstant">&quot;No provider found.&quot;</span>); <span class="synStatement">return</span>; } Console.WriteLine(<span class="synConstant">&quot;{0} is found&quot;</span>, provider.Profile.Name); <span class="synStatement">while</span> (<span class="synConstant">true</span>) { var line = Console.ReadLine(); <span class="synStatement">if</span> (<span class="synType">string</span>.IsNullOrEmpty(line)) { <span class="synStatement">return</span>; } var result = provider.GetSearchCandidates(line).Result; Console.WriteLine(<span class="synConstant">&quot;Elapsed time: {0} msec&quot;</span>, result.Elaplsed.TotalMilliseconds); result.Candidates.ToList().ForEach(s =&gt; Console.WriteLine(<span class="synConstant">&quot; &quot;</span> + s)); Console.WriteLine(); } } } } </pre><p>ビルドするのは面倒なのでビルド済みファイルが欲しいという人はこちら.<br /> <a href="http://d.hatena.ne.jp/NyaRuRu/files/SearchCandidateProviderSample.zip">http://d.hatena.ne.jp/NyaRuRu/files/SearchCandidateProviderSample.zip</a></p><p>TSF.SearchCandidateProvider のコードが見たい人はこちらから.<br /> <a href="https://github.com/NyaRuRu/TSF-SearchCandidateProvider">NyaRuRu/TSF-SearchCandidateProvider &middot; GitHub</a><br /> </p> </div> <div class="section"> <h3>類似研究</h3> <p><a href="http://hp.vector.co.jp/authors/VA050396/tech_01.html">&#x30A2;&#x30EC;&#x7528;&#x306E;&#x4F55;&#x304B;</a><br /> ITfFnReconversion を使う例.</p> </div> Wed, 18 Dec 2013 05:26:16 +0900 hatenablog://entry/12921228815714687968 HTML5 Forms の type 指定がデスクトップ IMEに影響するという話 https://nyaruru.hatenablog.com/entry/2013/07/07/210150 <p>最近やっていた仕事について,一通りリリースが終わって誰でも試せる段階になったので書いてみる.Web アプリ開発者の人や,IME 作成者の人には影響があるかも知れない.ただし Windows デスクトップを相手にしていなければ,ここで読むのをやめてもなんら問題はない.</p><p>最近 Chromium と Firefox にパッチを書いて,HTML5 Forms の type 指定が InputScope として TSF ベースの IME (いわゆる Text Input Processors; TIP) やソフトウェアキーボードに通知されるようにした.これは,基本的に Windows 8 上での Internet Explorer 10 の動作に合わせたものである.具体的には,以下の環境で,各種ブラウザが InputScope をサポートするようになった.</p> <ul> <li>Microsoft Internet Explorer 10以降 (ただし Windows 8以降)</li> <li>Google Chrome 26以降 (ただし Windows Vista以降)</li> <li>Mozilla Firefox 23以降 (ただし Windows Vista以降)</li> </ul><p>なぜこれが問題になるのか.それは,一部の InputScope が指定されたとき,(Windows Vista 以降の) MS-IME は自動的に自分自身をオフにするからだ.<br /> モダンなブラウザの実装では,HTML5 Forms input 要素の type 属性に,number, email, tel, time (Firefox 23+ の場合のみ), url のいずれかを指定したときこの「一部の InputScope」に該当する.結果として,対応する InputScope を受け取った MS-IME は自分自身のモードをオフに設定する.</p><p>ポイントは,これが IME 自身の判断によって行われるモード変更ということだ.この挙動についてブラウザベンダーを責めるのは難しい.ブラウザは単に対応する InputScope を IME に伝えているだけである.この点で,非標準の CSS に存在する <a href="https://developer.mozilla.org/ja/docs/Web/CSS/ime-mode">ime-mode</a> とは大きく異なる (ただし,type = password だけは以前からブラウザ自身が IME をオフにしている).</p><p>影響を受けないのは,</p> <ul> <li>TSF 非対応の IME を使っている場合</li> <li>InputScope を無視する IME を使っている場合 (たとえば ATOK 2013 とそれ以前)</li> <li>Windows XP で上記ブラウザを使っている場合</li> </ul><p>である.なお,各 InputScope に対する挙動は各 IME にゆだねられているため,今後のアップデートで振る舞いが変化する可能性もある.</p> <div class="section"> <h3>まとめ</h3> <p>InputScope に対応したデスクトップブラウザ</p> <ul> <li>Microsoft Internet Explorer 10以降 (ただし Windows 8以降)</li> <li>Google Chrome 26以降 (ただし Windows Vista以降)</li> <li>Mozilla Firefox 23以降 (ただし Windows Vista以降)</li> </ul><p>InputScope に対応した IME</p> <ul> <li>Microsoft IME (Windows Vista以降)</li> <li>Mozc / Google 日本語入力 1.11.x 以降 (TSF モードのみ)</li> </ul><p>HTML5 Forms の input 要素の type</p> <ul> <li>number </li> <li>email</li> <li>tel</li> <li>time (Firefox 23+ の場合のみ)</li> <li>url</li> </ul><p>の組み合わせで,(結果として) IME がオフになる.これは IME が自主的に行っているもので,ブラウザ側から IME のオフを設定しているわけではない.この動作に関して意見がある場合,基本的には IME ベンダーへどうぞということになる.</p> <div class="section"> <h4>謝辞</h4> <p>Mozilla Firefox への InputScope 対応パッチについて,Mozilla Japan の中野さんにレビュー等たいへんお世話になりました.この場をお借りしてお礼申し上げます.</p> <div class="section"> <h5>余談 0</h5> <p>各ブラウザでの Forms の type と InputScope の対応については Mozc のデザインドキュメントでまとめておいた.詳細についてはそちらを参考にしてほしい.<br /> <a href="https://code.google.com/p/mozc/wiki/InputScope#Scope">https://code.google.com/p/mozc/wiki/InputScope#Scope</a></p> </div> <div class="section"> <h5>余談 1</h5> <p>Windows 8 の Immersive モードで,MS-IME 2012 は入力モードをカーソル周辺に表示するようになった.今後,自動モード変更が受け入れられていくためには,このようなモード表示は必須と考えられる.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20130707/20130707205612.png" alt="f:id:NyaRuRu:20130707205612p:plain" title="f:id:NyaRuRu:20130707205612p:plain" class="hatena-fotolife" itemprop="image"></span></p> </div> <div class="section"> <h5>余談 2</h5> <p>InputScope に応じて,IME は変換に関する挙動を最適化することができる.たとえば,InputScope が「サーチ」のときに名詞中心のサジェストを行う,といった最適化が考えられる.実際すでに MS-IME 2012 は InputScope が「サーチ」のときに,挙動を変えている.</p> </div> <div class="section"> <h5>余談 3</h5> <p>現在 W3C で (主にデスクトップ向けの) IME API が議論されている.その流れの中で Microsoft から inputmode という追加の属性が提案されている.<br /> <a href="https://dvcs.w3.org/hg/ime-api/raw-file/tip/proposals/IMEProposal.html#inputmode-attribute">https://dvcs.w3.org/hg/ime-api/raw-file/tip/proposals/IMEProposal.html#inputmode-attribute</a><br /> この属性を使うと,ひらがなモードやカタカナモードといった,より日本人になじみが深い入力モードを指定できるようになる.InputScope にはこういったモードが既に存在するため,将来的には「半角カタカナモード」が期待される入力フィールド,といったものが HTML5 で実現可能になる可能性がある.興味がある人が議論に参加して欲しい.</p> </div> <div class="section"> <h5>余談 4</h5> <p>Tablet PC の時代に InputScope が設計され,10 年以上たってようやく HTML と InputScope が結びついたわけであるが,ブラウザでの InputScope への取り組み自体は以前から存在する.<br /> たとえば Google Summer of Code 2008 では,Mozilla に対して -moz-input-scope という拡張が試みられた.<br /> <a href="https://wiki.mozilla.org/Community:SummerOfCode08:TSF">https://wiki.mozilla.org/Community:SummerOfCode08:TSF</a></p> </div> <div class="section"> <h5>余談 5</h5> <p>Input 要素の type 指定だが,実際のところモバイル用途の方が需要は高い.理由として,ソフトウェアキーボードのレイアウトが Input 要素の typeによって変化すると便利であること,CJK以外の国でもソフトウェアキーボードが使用されること,が挙げられる.</p> </div> </div> </div> Sun, 07 Jul 2013 21:01:50 +0900 hatenablog://entry/11696248318755484379 Fcitx-mozc を試してみた https://nyaruru.hatenablog.com/entry/2013/04/06/213423 <p>(4/7 追記) fcitx-mozc の master branch では下記の問題は修正されたようです.Great!<br /> <hr><a href="http://blog.goo.ne.jp/ikunya/e/a5c2a00e25564c61d322c4c73b7a81da">Fcitx&#x306E;&#x30C6;&#x30B9;&#x30C8;&#x306E;&#x304A;&#x9858;&#x3044; - &#x3044;&#x304F;&#x3084;&#x306E;&#x65AC;&#x9244;&#x65E5;&#x8A18;</a> というのがあったので,軽く動作を見てみました.環境はこんな感じ.</p> <ul> <li>Ubuntu 13.04 Final Beta 64-bit</li> <li>VMWare 9.0.2</li> <li>Mozc / fcitx は 2013年4月6日午後8時(日本時間)の時点で,ppa:ikuya-fruitsbasket/fcitx に登録されていたバージョン</li> </ul><p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20130406/20130406212509.png" alt="f:id:NyaRuRu:20130406212509p:plain" title="f:id:NyaRuRu:20130406212509p:plain" class="hatena-fotolife" itemprop="image"></span><br /> 以下,ibus-mozc から後退する部分で気付いたものを列挙してみます.</p> <div class="section"> <h4>一部の Ctrl 付きのショートカットが動作しない</h4> <ol> <li>Open gedit</li> <li>Enable Mozc</li> <li>type "kyouha"</li> <li>hit Ctrl+H</li> </ol><p>Expected: "きょう"<br /> Actual: "きょうは"</p><p>Mozc (というか Windows の代表的な IME は),F7 キー,F8 キー,F9 キーの代わりにそれぞれ Ctrl+i,Ctrl+o,Ctrl+p という感じのショートカットが用意されています (QWERTY 配列では横に並んでいることに注目).また,IME での入力中は Ctrl+h によってバックスペース相当の動作をすることも可能です.これらが fcitx-mozc では使えないようです.ibus-mozc 1.6.1187.102 では動作するはずです.<br /> Mozc プロトコルでのモディファイアキーの扱いについては <a href="https://code.google.com/p/mozc/source/browse/trunk/src/session/commands.proto?r=131#137">commands.proto &#x3067;&#x89E3;&#x8AAC;&#x3055;&#x308C;&#x3066;</a> います.Windows 版 Mozc の <a href="https://code.google.com/p/mozc/source/browse/trunk/src/win32/base/keyevent_handler_test.cc">keyevent_handler_test.cc</a> にも大量にテストケースがあります.</p> </div> <div class="section"> <h4>ひらがな/カタカナキーが常にカタカナキーとして振る舞う</h4> <p>(On 109 Japanese keyboard)</p> <ol> <li>Open gedit</li> <li>Enable Mozc</li> <li>Type "a"</li> <li>Hit Shift+Hiragana/Katakana</li> <li>Type "i"</li> <li>Hit Hiragana/Katakana</li> <li>Type "u"</li> </ol><p>Expected: "あイう"<br /> Actual: "あイウ"</p><p>期待される実装方法については ibus-mozc の以下のコードあたりが参考になるかと.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/key_translator.cc?r=131#57">https://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/key_translator.cc?r=131#57</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink> {IBUS_Hiragana, mozc::commands::KeyEvent::KANA}, {IBUS_Hiragana_Katakana, mozc::commands::KeyEvent::KANA}, {IBUS_Katakana, mozc::commands::KeyEvent::KATAKANA}, </pre><p><a href="https://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/key_translator.cc?r=124#377">https://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/key_translator.cc?r=124#377</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink> <span class="synComment">// Due to historical reasons, many linux ditributions set Hiragana_Katakana</span> <span class="synComment">// key as Hiragana key (which is Katkana key with shift modifier). So, we</span> <span class="synComment">// translate Hiragana_Katanaka key as Hiragana key by mapping table, and</span> <span class="synComment">// Shift + Hiragana_Katakana key as Katakana key by functionally.</span> <span class="synComment">// </span><span class="synTodo">TODO</span><span class="synComment">(nona): Fix process modifier to handle right shift</span> <span class="synStatement">if</span> (IsHiraganaKatakanaKeyWithShift(keyval, keycode, modifiers)) { modifiers &amp;= ~IBUS_SHIFT_MASK; keyval = IBUS_Katakana; } </pre> </div> <div class="section"> <h4>一時的な英数モードからシフトキーで復帰しない</h4> <ol> <li>Unset "L_SHIFT" from "Extra key for trigger input method" in the Fcitx global config.</li> <li>Open gedit</li> <li>Enable Mozc</li> <li>Hit key as follows <ol> <li>Down Shift key</li> <li>Hit a key</li> <li>Up Shift key</li> <li>Hit i key</li> <li>Hit u key</li> <li>Down Shift key</li> <li>Up Shift key</li> <li>Hit a key</li> <li>Hit i key</li> <li>Hit u key</li> </ol></li> </ol><p>Expected: "Aiuあいう"<br /> Actual: "Aiuaiu"</p><p>MS-IME のローマ字モードには,Shift キーと共に入力を行うことで一時的に英数モードに入るという機能があるのですが、この入力状態はシフトキーを単独で押すことで解除できます。fcitx-mozc ではこの機能が働かないようです。ibus-mozc 1.6.1187.102 では動作するはずです.</p> </div> <div class="section"> <h4>ツールを起動する系のショートカットが動作しない</h4> <ol> <li>Open the config tool of Mozc</li> <li>Enter key customize mode</li> <li>Add an entry as "Precomposition/F2/Launch word register dialog"</li> <li>Open gedit</li> <li>Enable Mozc</li> <li>Hit F2</li> </ol><p>Expected: word register dialog is launched<br /> Actual: nothing happens</p><p>Mozc (というか Windows の代表的な IME )はショートカットキーで設定ダイアログを起動したり単語登録ダイアログを起動したりできるのですが,fcitx-mozc では機能していないようです.ibus-mozc 1.6.1187.102 では動作するはずです.</p> </div> <div class="section"> <h4>gedit で確定取り消しが動作しない</h4> <ol> <li>Open gedit</li> <li>Enable Mozc</li> <li>Type "kyouha"</li> <li>Hit enter to commit</li> <li>Hit Ctrl+BackSpace</li> </ol><p>Expected: commit action is canceled<br /> Actual: nothing happens</p><p>Mozc (というか Windows の代表的な IME )は直前の確定動作を取り消せるのですが,fcitx-mozc では機能していないようです.ibus-mozc 1.6.1187.102 では動作するはずです.</p> </div> <div class="section"> <h4>gedit で再変換が動作しない</h4> <p>(On 109 Japanese keyboard)</p> <ol> <li>Open gedit</li> <li>Type something</li> <li>Enable Mozc</li> <li>Select some text</li> <li>Hit Henkan key</li> </ol><p>Expected: The selected text is reconverted by Mozc<br /> Actual: nothing happens</p><p>Mozc (というか Windows の代表的な IME は)選択した単語を再変換できるのですが,fcitx-mozc では機能していないようです.ibus-mozc 1.6.1187.102 では動作するはずです.<br /> <hr>冒頭にも追記したとおり,ここに挙げた問題は全て master branch では修正済みのようです.良かった良かった.</p> </div> Sat, 06 Apr 2013 21:34:23 +0900 hatenablog://entry/6435988827676868920 2012年他にやったこと - Mozc 編 https://nyaruru.hatenablog.com/entry/2013/03/31/172627 <p><a href="https://code.google.com/p/mozc/wiki/ReleaseHistory#2013-03-28_1.10.1389.102">Mozc 1.10.1389.102</a> が公開されたということやっと書ける感じの <a href="http://nyaruru.hatenablog.com/entry/2013/01/01/134011">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> の続き.2012 年にやっていたことの今回公開分.</p> <div class="section"> <h3>Support IBus 1.5</h3> <p>Red Hat によって主導され,GNU/Linux 界隈で使われている Input Method Framework であるところの IBus が,メジャーアップデートにあたって設定ファイルの解釈を変えるという決定を下したところ,挙動の変化に気づいたユーザーが IME 側にバグを登録してくることになり,IME 側で設定ファイルを変更することで対処することになったという案件.<br /> 平常心平常心と自分に言い聞かせつつ淡々と対処.</p> <ul> <li><a href="https://code.google.com/p/mozc/issues/detail?id=159">https://code.google.com/p/mozc/issues/detail?id=159</a></li> <li><a href="https://code.google.com/p/mozc/issues/detail?id=160">https://code.google.com/p/mozc/issues/detail?id=160</a></li> <li><a href="https://code.google.com/p/mozc/issues/detail?id=161">https://code.google.com/p/mozc/issues/detail?id=161</a></li> </ul> </div> <div class="section"> <h3>Increase opaque buffer size for x32</h3> <p>Mozc が日本語入力を提供しているところの Chromium OS から,x32 でビルドすると static assert に引っかかったからバッファサイズ変更してねとやってきたバグ.こんな身近に x32 を検討中のプロジェクトがあったのかという驚きの気持ちで淡々と対処……したんだけど,その後色々あって Chromium OS の日本語入力は PNaCl でビルドした Mozc が使われることになったため,たぶんこの修正は無意味なはず……</p> <ul> <li><a href="https://code.google.com/p/mozc/issues/detail?id=177">https://code.google.com/p/mozc/issues/detail?id=177</a></li> </ul> <div class="section"> <h4>プロセス間通信の AppContainer 対応</h4> <p>Windows 8 で導入された AppContainer サンドボックス下で動作するストアアプリから Mozc を使うにはどうすればよいか考えて実装する,というお仕事.<br /> Mozc のように out-of-process 型の IME にとって,サンドボックスは天敵.実際 Windows 8 のベータテストの段階から色々実験を行っていて,AppContainer から外部プロセスへは単純に名前付きパイプで通信できないというのは分かっていた……んだけど同時にどうしようもなく過ぎていく日々.もちろん胃は痛い.マルチプロセス設計を見直すというのは,Mozc のコード規模では既に悪夢と言ってよく,ストアアプリ対応を諦めるという選択までもがかなりの現実味を持つという状況.ほんと胃が痛かった日々.<br /> 結局 <a href="http://nyaruru.hatenablog.com/entry/2012/10/08/185804">AppContainer &#x5C0E;&#x5165;&#x306B;&#x3088;&#x308B; Windows &#x958B;&#x767A;&#x3078;&#x306E;&#x5F71;&#x97FF; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> で紹介したように,名前付きパイプの DACL にエントリを追加すればよいという情報を発見しほっと胸をなで下ろしたのが 8 月頃.<br /> ちなみにこの手法,API の説明を読むに,out-of-process で動作するアクセシビリティ系常駐ソフトへの配慮から残された裏口のようにも読める.変化と互換性の間で綱渡りをする Microsoft らしい配慮がなければ,今でも没入型 UI で Mozc は動作しないままだったかもしれない.<br /> 今回公開されたコードでは,以下のうち "(A;;GA;;;AC)" を足している部分がそれ.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/base/win_sandbox.cc?r=131#247">https://code.google.com/p/mozc/source/browse/trunk/src/base/win_sandbox.cc?r=131#247</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink><span class="synStatement">case</span> WinSandbox::kSharablePipe: <span class="synComment">// Sharable Named Pipe:</span> <span class="synComment">// - Deny Remote Acccess</span> <span class="synComment">// - Allow general access to LocalSystem</span> <span class="synComment">// - Allow general access to Built-in Administorators</span> <span class="synComment">// - Allow general access to the current user</span> <span class="synComment">// - Allow general access to ALL APPLICATION PACKAGES</span> <span class="synComment">// - Allow read/write access to low integrity</span> ssdl += <span class="synConstant">L&quot;D:(D;;GA;;;NU)(A;;GA;;;SY)(A;;GA;;;BA)&quot;</span>; <span class="synStatement">if</span> (SystemUtil::IsWindows8OrLater()) { ssdl += <span class="synConstant">L&quot;(A;;GA;;;AC)&quot;</span>; } ssdl += allow_user; <span class="synStatement">if</span> (SystemUtil::IsVistaOrLater()) { ssdl += allow_rw_low_integrity; } <span class="synStatement">break</span>; </pre><p>Mozc を Windows 8 対応させるにあたって,最も重要だったのはこの一行だといっても過言ではない.</p> </div> <div class="section"> <h4>TSF 再対応</h4> <p>Windows 8 の没入型 UI では TSF ベースの IME (正確には Text Input Processor; TIP) 以外は使えないというのは割と知られた話.しかし実際の ところ迫害はこれにとどまらず,デスクトップモードでも IMM32 ベースの IME には次のような制限がある.</p> <ul> <li>言語バー API を使用して,通知領域にアイコンを表示できない</li> <li>言語設定から IME の設定画面を開けない</li> </ul><p>正直 Windows 8 では IMM32 ベースの IME は現実的とは言えないんじゃなかろうか.<br /> このような理由もあって,Mozc を TSF に再対応させるのは割と早いうちから決心していた.もっとも,プロセス間通信の問題の方がより頭が痛かったので TSF の問題は割と放置気味だった.<br /> プロセス間通信の問題が片付いて,Chromium の TSF 対応も一段落しところで,一人で淡々と TSF 対応を開始.それも無事 12 月中にすべてリリース.短期間に大量のコードレビューをこなしてくれた同僚に感謝.<br /> こうして,IMM32/TSF との関わりがまた増えた.</p> <ol> <li>学生時代に C# で TSF ベースの IME を途中まで作る</li> <li>学生時代に Windows Vista 向け TSF 対応記事を書いたり CEDEC で講演したり</li> <li>入社後,TSF で書かれていた初代 Mozc クライアントの開発を手伝う</li> <li>Windows XP 環境での CUAS に絶望し,IMM32 で Mozc クライアントをゼロから書き直す</li> <li>Chromium の TSF 対応を指揮</li> <li>Windows 8 向けに Mozc クライアントを TSF で書き直す (New!)</li> </ol><p>今回書き散らかしたコードはこのあたりに見ることができる.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/#src%2Fwin32%2Ftip">https://code.google.com/p/mozc/source/browse/trunk/src/#src%2Fwin32%2Ftip</a><br /> </p> </div> </div> <div class="section"> <h3>vcbuild から Ninja への移行</h3> <p>2012 年末,TSF 対応コードを一通りリリースし終わった後,同僚たちが休暇モードに入るのを横目に始めた年末ビルドパイプライン大掃除.<br /> Mozc の Windows ビルドは,<a href="https://code.google.com/p/gyp/">gyp</a> のおかげで柔軟性が高く,ターゲットとなる Visual C++ のバージョンを変更するのは容易である.実際手元の開発では Visual C++ 2012 + Visual Assist X で快適開発ということが割と簡単にできている.一方,ビルドサーバーはいまだに Visual C++ 2008 を使っていた.これに関して最近以下のような懸念点があった.</p> <ul> <li>Chromium がデフォルトコンパイラを Visual C++ 2008 から Visual C++ 2010 に移行した</li> <li>Visual C++ 2010 になると,nullptr や auto が使えるようになる</li> </ul><p>そんなわけで,Mozc のデフォルトコンパイラを Visual C++ 2008 から Visual C++ 2010 に変更しようと思い立つ.<br /> この変更で問題になるのは,従来コマンドラインからのビルドに使っていた vcbuild.exe が使えなくなり,.NET ベースの msbuild.exe に移行しなければならないことである.密閉型のビルドサーバーに .NET ベースの複雑な依存関係を持ち込むのはうれしくない.そこで,最近 Chromium でも併用されている <a href="http://martine.github.com/ninja/">ninja</a> を使ってみることにした.<br /> Ninja は,当時 Chromium チーム に在籍していた Evan Martin による make 代替ツールで,gyp や CMake のようなツールから自動生成されたビルド設定を読み込むことを前提に,とにかく高速に動作することを目指している.Ninja は Chromium 開発で多用されているだけでなく,最近は LLVM のような CMake 利用プロジェクトにもファンを広げているようだ.今回 vcbuild.exe ではなく Ninja を採用したもう一つの理由は,社内で勢いを持ちつつあるツールにはなるべく乗っかっておくという経験則もある.困ったときに聞きやすいし,自分の経験が同僚の役に立つこともある.<br /> もっとも,Chromium 付随プロジェクトにありがちな話として,Chromium が必要になった部分だけ実装され,他は未実装というのは今回も同じ.Mozc を gyp + Ninja + Visual C++ 2010 で快適にビルドするには,gyp の Ninja 向けジェネレータ側にいくつか追加実装を行う必要があった.12 月頃せっせとパッチをアップストリームしている姿を以下に見ることができる.</p> <ul> <li><a href="http://www.ohloh.net/p/gyp/contributors/1359664239828870">http://www.ohloh.net/p/gyp/contributors/1359664239828870</a></li> </ul><p>移行は無事予定していた期間で終わり,現在の Mozc のビルドサーバーは gyp + Ninja + Visual C++ 2010 で動いている.</p> </div> Sun, 31 Mar 2013 17:26:27 +0900 hatenablog://entry/6435988827676630003 その名は「新しい (Windows) UI の…」 https://nyaruru.hatenablog.com/entry/2013/03/20/010538 <div class="section"> <h3>発端</h3> <blockquote cite="http://www.forest.impress.co.jp/docs/serial/moritalk/20130319_592252.html"> <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%AF%A5%ED%A5%BD%A5%D5%A5%C8">マイクロソフト</a>社がIEの舵取りに迷っている。同社は先週、Windows 8の“Windows ストアアプリ”として動作する「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer%2010">Internet Explorer 10</a>」でFlashコンテンツを表示する際の方針を変更すると発表した。この方針転換が意味することを理解するためには、Windows 8が発売される前までさかのぼる必要がある。</p> <cite><a href="http://www.forest.impress.co.jp/docs/serial/moritalk/20130319_592252.html">&#x3010;&#xFF03;&#x30E2;&#x30EA;&#x30C8;&#x30FC;&#x30AF;&#x3011;&#x7B2C;50&#x8A71;&#xFF1A;IE&#x306E;&#x30B8;&#x30EC;&#x30F3;&#x30DE; - &#x7A93;&#x306E;&#x675C;</a></cite> </blockquote> <p>という記事を読んだのだけど,どうも用語の使い方が危なっかしい.枝葉の部分ならともかく記事の論点に直結する部分だけに余計に気になる.というわけでちょっとだけ書いてみたのが以下.</p> </div> <div class="section"> <h3>Windows 8 向けブラウザの 3 分類</h3> <p>Windows 8 でウェブブラウザというと,大きく 3 種類に分けられる.</p> <ol> <li>いわゆる Windows ストアアプリであって,標準ブラウ<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B6%A5%B3%A5%F3">ザコン</a>ポーネントを利用するもの</li> <li>いわゆるデスクトップアプリケーションとして動作するブラウザ</li> <li>Windows ストアアプリではないものの,Windows ストアアプリと同様の没入型 UI で動作するブラウザ</li> </ol><p>単独製品としての「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer%2010">Internet Explorer 10</a>」が該当するのは 2 と 3 である.この厳密な定義に従えば,元記事にあった,</p> <blockquote> <p>“Windows ストアアプリ”として動作する「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer%2010">Internet Explorer 10</a>」</p> </blockquote> <p>なるものは,実は存在しない.元記事に登場する <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Chrome">Google Chrome</a> も同様で,“Windows ストアアプリ”として動作する <a class="keyword" href="http://d.hatena.ne.jp/keyword/Google%20Chrome">Google Chrome</a> というものは存在しない.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Chrome">Chrome</a> もタイプ 2 とタイプ 3 で動作する.<br /> なぜこの区別が重要かというと,タイプ 3 のブラウザは,没入型 UI で動作するという点ではタイプ 1 に近いものの,開発者視点ではむしろタイプ 2 のデスクトップアプリケーションとしてのブラウザに近いからだ.タイプ 1 ブラウザと対照的な,タイプ 3 のブラウザの特徴を挙げてみよう.</p> <ul> <li>AppContainer <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A5%F3%A5%C9%A5%DC%A5%C3%A5%AF%A5%B9">サンドボックス</a>が強制されず,Integrity Level Medium で起動される</li> <li>WinRT に縛られず,デスクトップアプリケーションとほぼ同等の Win32 <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> にアクセスできる</li> <li>Windows ストアを経由せずにインストールできる</li> </ul><p>このように,タイプ 3 ブラウザは,実際にはデスクトップブラウザと同じ技術で作られている.プラグイン的な実行時ライブラリの使用や,<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a> コンパイルのような実行時コード生成についても特に技術的な制約はない.<br /> もう一点強調しておくと,Windows 8 で没入型 UI が導入されるにあたって,こんな動作モードが許されたのはブラウザだけである.この動作モードが許されるのはデフォルトブラウザに限定され,その他のブラウザには許されないというところからも,今回の措置が例外的なものであることが透けて見える.</p> </div> <div class="section"> <h3>参考資料</h3> <p>Windows 8 の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B5%A1%BC%A5%C9%A5%D1%A1%BC%A5%C6%A5%A3">サードパーティ</a>ー製ブラウザ事情については,Microsoft がブラウザ開発者向けに公開している <a href="http://go.microsoft.com/fwlink/?LinkID=243079">Developing a new experience enabled desktop browser</a> という資料に詳しい.なかでは,Windows 8 で動作するタイプ 3 のブラウザを開発する方法について解説されている.プロセス分離型ブラウザについても言及されているあたり個人的には好感度が高い.<br /> ちなみにこの資料で,タイプ 1, 2, 3 ブラウザはそれぞれ以下のように呼ばれている.</p> <ol> <li>Windows Store app</li> <li>Desktop browsers.</li> <li>New experience enabled desktop browser</li> </ol><p>3 については,"New experience enabled" のあたりに没入型 UI を,"desktop browser" のあたりに <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> 的な側面を感じるとよいのではなかろうか.</p> </div> <div class="section"> <h3>きみの名は……</h3> <p>さて,以上の話を理解してから見る次のツイートは味わい深い.<br /> <blockquote class="twitter-tweet" lang="ja"><p>Windows 8 の IE10 ですが、新しい UI の方をただの「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer">Internet Explorer</a>」、デスクトップから起動する方は「デスクトップ版 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer">Internet Explorer</a>」と呼びます。</p>&mdash; 日本<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%AF%A5%ED%A5%BD%A5%D5%A5%C8">マイクロソフト</a> IE Teamさん (@IE_Japan) <a href="https://twitter.com/IE_Japan/status/313511408195235840">2013年3月18日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="ja"><p>ただし前者はわかりづらいので、"新しい (Windows) UI の IE"、"Windows 8 スタイルの IE" と言うのが一応ルールになっています。</p>&mdash; 日本<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%DE%A5%A4%A5%AF%A5%ED%A5%BD%A5%D5%A5%C8">マイクロソフト</a> IE Teamさん (@IE_Japan) <a href="https://twitter.com/IE_Japan/status/313511871472881664">2013年3月18日</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> 背景事情が分かってしまえば簡単な話である.つまり,開発者向け資料で New experience enabled desktop browser と呼ばれる動作モードの IE が,ユーザー向けには "新しい (Windows) UI の IE"、"Windows 8 スタイルの IE" と紹介されているわけだ.まあ他に呼びようなかったのやもしれず.</p> </div> Wed, 20 Mar 2013 01:05:38 +0900 hatenablog://entry/6435988827676178502 Windows 8 Dell の個人向け商品で領収書をもらう方法 (または,まともなタッチ対応ディスプレイを経費で買う方法) https://nyaruru.hatenablog.com/entry/2013/03/09/192105 <div class="section"> <h3>まとめ</h3> <p>Dell の 10 点タッチ外付け 23 インチディスプレイ <a href="http://accessories.apj.dell.com/sna/productdetail.aspx?c=jp&amp;cs=jpdhs1&amp;l=ja&amp;sku=391-10045">S2340T</a> は,個人向けサイトにしか載っていないけど,経費購入に必要な領収書も<a href="https://jpapp1.jp.dell.com/dhs/Recipt.htm">&#x7528;&#x610F;&#x3057;&#x3066;&#x3082;&#x3089;&#x3048;&#x308B;</a>ので必要な人は迷わず買うと良いよ.</p> </div> <div class="section"> <h3>S2340T</h3> <p>Windows 8 に起因するタッチ対応案件は第一弾が一段落したころでしょうか.「<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> のときに済ませた」という人から,「まだ対応していない」,「テストすらしていない」,「積み残しタスクがある」,という方まで,色々いらっしゃることかと思います.<br /> そんななか,まだタッチ対応アプリケーションの開発体制を整えていなくて機材を探しているという場合におすすめなのが Dell の 23 インチディスプレイ <a href="http://accessories.apj.dell.com/sna/productdetail.aspx?c=jp&amp;cs=jpdhs1&amp;l=ja&amp;sku=391-10045">S2340T</a>.この製品,Full HD (1,920 x 1,080),10 点タッチに対応しつつ,59,980 円という Windows 8 前のタッチ対応外付けディスクプレイからは考えられない低価格で.半年前に発表されるやいなや注文が積み上がり,一時期は通常納期 + 14 週間というすさまじいバックオーダーが生じていました.それが最近は需給が釣り合ってきたらしく,ついに通常納期まで改善したようなのでおすすめしてみる次第であります.<hr>(参考) 製品紹介記事:<br /> <a href="http://ascii.jp/elem/000/000/749/749858/" class="http-screenshot" target="_blank"><img class="http-screenshot" src="http://screenshot.hatena.ne.jp/images/200x150/8/2/b/4/9/162466aaf885d301aa8bb817ba6dff20380.jpg" height="150px" width="200px" alt="screenshot" /></a> <a href="http://www.itmedia.co.jp/pcuser/articles/1211/19/news018.html" class="http-screenshot" target="_blank"><img class="http-screenshot" src="http://screenshot.hatena.ne.jp/images/200x150/9/7/e/5/9/f06af2ba8c72765617412cf1d90daf91002.jpg" height="150px" width="200px" alt="screenshot" /></a> <a href="http://pc.watch.impress.co.jp/docs/news/20121024_568145.html" class="http-screenshot" target="_blank"><img class="http-screenshot" src="http://screenshot.hatena.ne.jp/images/200x150/c/5/0/3/9/d57cfdf308024b2f68ebef65236c6c6e951.jpg" height="150px" width="200px" alt="screenshot" /></a><hr>さて,この製品を経費で買おう思ったあなたに一点アドバイス.S2340T は Dell の<a href="http://www.dell.com/jp/p/?c=jp&amp;l=ja&amp;s=dhs&amp;cs=jpdhs1&amp;~ck=mn">&#x500B;&#x4EBA;&#x5411;&#x3051;&#x30B5;&#x30A4;&#x30C8;</a> にのみ掲載されており,法人向けサイトには掲載されていません.これで困るのが領収書.通常の注文フローだと会社名・事業者名宛ての領収書が作れないっぽく見えるため,経費で買おう企んでいた人はそこで諦めてしまいかねません.私の場合,諦めきれなかったので Dell のサポートの人に聞いてみたのですが,実は個人向け製品でも領収書は作れるとのこと.</p> <blockquote cite="http://www.dell.com/Learn/jp/ja/jpdhs1/campaigns/purchase-faq?c=jp&amp;l=ja&amp;s=dhs&amp;cs=jpdhs1&amp;delphi"> <p>Q 領収書を発行可能ですか?<br /> A 領収書は、現金払いでのご注文の場合原則”お振込票の控え”等をもって代えさせて頂いております。現金以外のお支払方法ご利用の場合、お客様よりご希望のあった場合のみ発行しております。ご希望の場合はこちらのフォームよりご連絡いただけますようお願い申し上げます。<br /> ※個人のお客様で現金前払いのお客様には弊社にて入金確認後「入金確認書兼領収書」を郵送させていただいておりますのでそちらを領収書としてご利用いただけます。<br /> ※領収日は現金前振込の場合はご入金の確認がとれた日・クレジットカードの場合はカード会社より引き落としを承認された日になります。(領収日の変更は承ることが出来ません。)<br /> ※領収書のお届けは納品後となり、お時間がかかることもございます。また商品には同梱できませんので、予めご了承ください。 </p> <cite><a href="http://www.dell.com/Learn/jp/ja/jpdhs1/campaigns/purchase-faq?c=jp&amp;l=ja&amp;s=dhs&amp;cs=jpdhs1&amp;delphi:gr=true">&#x3088;&#x304F;&#x3042;&#x308B;&#x3054;&#x8CEA;&#x554F;</a></cite> </blockquote> <p>流れとしては,以下のようになるようです.<br /> 1. 個人向けページから購入する.<br /> 2. <a href="https://jpapp1.jp.dell.com/dhs/Recipt.htm">&#x9818;&#x53CE;&#x66F8;&#x767A;&#x884C;&#x30D5;&#x30A9;&#x30FC;&#x30E0;</a> から領収書を請求する.</p><p>というわけで,S2340T の納期も改善してきたタイミングでの,タッチ対応 Windows アプリケーション / Web アプリ開発者向け情報でしたー</p> </div> Sat, 09 Mar 2013 19:21:05 +0900 hatenablog://entry/13425511277527166490 Windows 8 Windows 7 看板の話 https://nyaruru.hatenablog.com/entry/2013/02/04/193803 <p>【注意】I'm not a lawyer だよ! This is not legal advice だもんね!<br /> <hr>Piro さんが長文を書かれていたので一部だけ切り出してつまみ食い.ただし <a class="keyword" href="http://d.hatena.ne.jp/keyword/GPL">GPL</a> vs BSDL の話ではなくて看板の話.</p> <blockquote cite="http://piro.sakura.ne.jp/latest/blosxom/topics/2013-02-03_license.htm"> <ul> <li>自分の作った物が誰にどう使われようとも構わない、極端な話、誰かが看板だけ掛け替えた「改良版」を作って商売していようとも全く構わない、という事であれば、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D1%A5%D6%A5%EA%A5%C3%A5%AF%A5%C9%A5%E1%A5%A4%A5%F3">パブリックドメイン</a>にしたり、あるいはBSDスタイルのライセンスを選択して問題ないでしょう。</li> <li>自分の作った物が看板を掛け替えただけの「改良版」として勝手に商売に使われるのは我慢ならない、やるならこっちにも分け前をよこせ、それが嫌なら無償で同じ条件でソースも含めて公開しろ、という事であれば、コピーレフトなライセンスを選択した方がいいでしょう。</li> <li>自分の作った物がアイデアだけ引き継がれるのはいいけど、自分の血と汗と涙の結晶である<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>が他人にそのまま利用されるのは腹立たしい。アイデアを同じように具現化したかったら、自分で同じだけの血と汗と涙を投じて実装し直して欲しい。という事であれば、<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>を公開しないクローズドライセンスにした方がいいでしょう。</li> <li>自分の作った物が<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>も含めて引き継がれていって欲しい、他の人が自分と同じような苦労をしなくてもいいようにしたい、人類共有の財産にしたい、という時に、コピーレフトにするべきなのか、それともBSDスタイルにするべきなのか。そこが問題です。</li> </ul> <cite><a href="http://piro.sakura.ne.jp/latest/blosxom/topics/2013-02-03_license.htm">Latest topics &gt; &#x300C;&#x30B3;&#x30D4;&#x30FC;&#x30EC;&#x30D5;&#x30C8;&#x3068;BSD&#x30B9;&#x30BF;&#x30A4;&#x30EB;&#x3067;&#x306F;BSD&#x30B9;&#x30BF;&#x30A4;&#x30EB;&#x306E;&#x65B9;&#x304C;&#x767A;&#x5C55;&#x3059;&#x308B;&#x306E;&#x3067;&#x306F;&#x300D;&#x3068;&#x3044;&#x3046;&#x8B70;&#x8AD6;&#x306B;&#x3064;&#x3044;&#x3066;&#x306E;&#x8AA4;&#x89E3;&#x3042;&#x308B;&#x3044;&#x306F;&#x8A00;&#x8449;&#x306E;&#x88CF;&#x306B;&#x3042;&#x308B;&#x6B3A;&#x779E; - outsider reflex</a><a href="http://b.hatena.ne.jp/entry/http://piro.sakura.ne.jp/latest/blosxom/topics/2013-02-03_license.htm" class="http-bookmark"><img src="http://b.hatena.ne.jp/entry/image/http://piro.sakura.ne.jp/latest/blosxom/topics/2013-02-03_license.htm" alt="" class="http-bookmark" /></a></cite> </blockquote> <p>これを読んで看板の方に反応しちゃったというか,つまり,ソフトウェアに十分以上の思い入れがあるなら,商標とるのも選択肢に入れるべきですかねと.</p> <ul> <li>自分の作ったソフトウェアに対するブランドイメージが,第三者の「改良版」で勝手に使われたり左右されたりするのは我慢ならない.ブランドに影響する活動はぜんぶうちを通してもらうし,新たに何か立ち上げるならブランド構築はゼロからスタートしてもらう → 商標取ろう</li> <li>自分の作ったソフトウェアに対するブランドイメージが,第三者の活動によってどう利用され・変化しようとかまわない.勝手にやってくれ. → なにもしない or 商標のとれない名前 (地名とか?) を使おう?</li> </ul><p>て感じなんですかね.<br /> 前者の例は,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%D7%A5%E9%A5%A4%A5%A8%A5%BF%A5%EA">プロプライエタリ</a>なソフトウェアはもちろん,OSS の世界でも大手 <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%BF%A1%BC">ディストリビューター</a> (<a class="keyword" href="http://d.hatena.ne.jp/keyword/Debian">Debian</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Fedora">Fedora</a>, <a class="keyword" href="http://d.hatena.ne.jp/keyword/Ubuntu">Ubuntu</a>, ...) や <a class="keyword" href="http://d.hatena.ne.jp/keyword/Mozilla">Mozilla</a>,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Arduino">Arduino</a> にしろ企業っぽいところはたいていそうです.仮に「改良版」で何か活動しようとしたい場合でも,看板の付け替えはほぼ確実に要求されています.仮に OSS のライセンスを守って著作権をクリアしても,あなたは <a class="keyword" href="http://d.hatena.ne.jp/keyword/Debian">Debian</a> Lite とか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Fedora">Fedora</a> Lite とか <a class="keyword" href="http://d.hatena.ne.jp/keyword/Firefox">Firefox</a> Lite という名前を使えないことになります.たぶんね.<br /> 後者としては,「~ごった煮版」「私家製~」「偽~」「Patched ~」「~版○○」とか煮え切らない名前で公開されているたくさんのソフトウェアの周辺にいくつもの例を見つけることができるでしょう.fork の盛んな OSS の世界ではこういった例もたくさん見ることができます.<br /> つまるところ,あなたが活動を行う上で,ブランドに対する姿勢によっては,商標が必要になるケースがあります.これはOSS・<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%D7%A5%E9%A5%A4%A5%A8%A5%BF%A5%EA">プロプライエタリ</a>どちらでも行われていることで,いずれの場合であっても世に先例を見つけることができるでしょう.</p> Mon, 04 Feb 2013 19:38:03 +0900 hatenablog://entry/6435922169448666054 2012年やったこと - Chromium 編 https://nyaruru.hatenablog.com/entry/2013/01/03/214030 <p>前回に引き続き今度は Chromium 編.chromium.org のアカウントを作ってもらったはいいものの,メールアドレスの 1 文字目を大文字にされて激しく凹むということもあった一年.</p> <div class="section"> <h4>Windows 8 向け TSF 対応</h4> <p>Chromium を Windows 8 向けに TSF 対応させるというミッション.いやな予感はしていたものの,Mozc の TSF 対応もあるのであまり積極的に手を出せずにいたら,結局ぎりぎりになって火消し案件として振ってきた,という感じの一件.</p> <ul> <li><a href="http://code.google.com/p/chromium/issues/detail?id=137627">http://code.google.com/p/chromium/issues/detail?id=137627</a></li> </ul><p>Windows 8 では IME の TSF 対応が注目されていたりするわけだけど,実は Immersive Mode で動作するブラウザの方も TSF に対応させる必要がある.対応させないと Immersive Mode で CJK の入力ができない.それはまずいというわけで TSF を扱ったことのある Mozc チーム (もっとも Mozc で TSF 経験者といっても私ぐらいだけど) に話が回ってきた.のが 7 月終わりから 8 月頭にかけて.Windows 8 の MSDN 向けリリースは 8 月 15 日.一般リリースは 10 月 26 日.<br /> 「どうしてこんなになるまで放っておいたんですかー!」……といっても始まらないので一時期は Mozc チームから 5 人ぐらいヘルプに回しつつ,6 週間 (これは Chromium の平均的なリリースサイクルでもある) でどうにか動くものをでっち上げる.結局細かいバグまで全部取り除くにはもう 1 サイクル (6週間) かかったけど.<br /> この間 Mozilla 方面からはこういう声も聞こえてきたり.<blockquote class="twitter-tweet" lang="HASH(0x1ed8608)"><p>jim martins何いってんだ。 (jimm) they had a problem with tsf and input imes, so they assinged five people from their japan office to it</p>&mdash; Makoto Kato (@makoto_kato) <a href="https://twitter.com/makoto_kato/statuses/245598805628686336">September 11, 2012</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script><br /> <blockquote class="twitter-tweet" lang="HASH(0x1ed8608)"><p>だよねー (jimm) man, google has unlimited resources</p>&mdash; Makoto Kato (@makoto_kato) <a href="https://twitter.com/makoto_kato/statuses/245599016279220224">September 11, 2012</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p><p>まあ実際は 5 人全員が働きっぱなしということはなくって,内容が専門的になってくるにつれ段階的に人数を減らしていく感じで.戦力の逐次投入の逆ができたという点では満足.<br /> ちなみに自分はリードエンジニアとして参加しつつ,コードを書くよりは主に設計と裏方に注力 (TSF 未経験者ばっかりなので,こうする方がむしろスケールすると判断).全コードのレビューをしたり,ドキュメントをメンテしたり,TSF についての軽い Tech Talk をしたり,Windows のデバッグテクニックのレクチャーをしたり.あとはアーキテクチャ上の最終決定を行ったり (これは胃が痛かった…).同僚がもりもりコードを書いてくれたのでほんと助かった.ぺこり.<br /> もちろん反省点も色々ある.一番大きな反省点は,Chromium のコードレビューに不慣れな人間 (自分含む) がいることを考慮していなかったところ.アプリケーションの TSF 対応では,メッセージポンプやテキストウィジットに手を入れる必要がある.もちろんこれらは重要コンポーネント,大物レビュアーが出てくるし自然とレビューの目も厳しくなる.もうちょっとコミットログや事前の根回しに注意していれば,レビュー期間は半分以下に収まったんじゃないかと思う.最初のキックオフの時にレビュー対策を盛り込んでおけば…… このあたりの文化的背景については <a href="http://twitter.com/omo2009">@omo2009</a> 先生がすばらしい記事を書いていらっしゃるので興味がある人はこちらをどうぞ.</p> <ul> <li><a href="http://steps.dodgson.org/b/2012/12/30/code-review-from-lowland/">&#x4E0B;&#x304B;&#x3089;&#x76EE;&#x7DDA;&#x306E;&#x30B3;&#x30FC;&#x30C9;&#x30EC;&#x30D3;&#x30E5;&#x30FC;</a></li> </ul> </div> <div class="section"> <h4>Handle IMR_QUERYCHARPOSITION even when there is no composition</h4> <p>コンポジション文字列が存在しない時でも IMR_QUERYCHARPOSITION に応答するという変更.実際には単にカーソル位置を返すだけ.</p> <ul> <li><a href="https://chromiumcodereview.appspot.com/11233028/">https://chromiumcodereview.appspot.com/11233028/</a></li> </ul><p>Mozc の TSF 対応を行なっている時に気づいた問題で,空文字列に対する<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms538782.aspx">ITfContextView::GetTextExt</a> でカーソル位置を取得するためにはこうなっていたほうが都合が良い,という変更.<br /> ブラウザと IME 両方に手を出していると,楽な側で直せるというのは便利.具体的には以下の差が現れる.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20130103/20130103213724.png" alt="f:id:NyaRuRu:20130103213724p:plain" title="f:id:NyaRuRu:20130103213724p:plain" class="hatena-fotolife" itemprop="image"></span><br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20130103/20130103213730.png" alt="f:id:NyaRuRu:20130103213730p:plain" title="f:id:NyaRuRu:20130103213730p:plain" class="hatena-fotolife" itemprop="image"></span><br /> Chromium 24 にてリリース予定.</p> </div> Thu, 03 Jan 2013 21:40:30 +0900 hatenablog://entry/12704830469097361356 2012年やったこと - Mozc 編 https://nyaruru.hatenablog.com/entry/2013/01/01/134011 <p>いままで仕事で書いたコード (Chromium とか Mozc とか) については基本的に言及しないようにしていたんですが,ソースコードが公開されている内容についてはまあいいかということでまとめてみます (もちろんソースコードが公開されていないことについても色々やってますが).とりあえず Mozc 編<a href="#f1" name="fn1" title="ここでは OSS Mozc に限らず,いわゆる code-name Mozc についての活動">*1</a>.順序は概ね時系列.</p> <div class="section"> <h4>Visual C++ 2010 対応</h4> <p>ちまちまとコンパイルエラーに対処.ビルドスクリプトを vcbuild に加えて msbuild にも対応させたぐらい.あとは gyp にも問題を見つけたので一件パッチを upstream.</p> <ul> <li><a href="http://code.google.com/p/gyp/issues/detail?id=244">http://code.google.com/p/gyp/issues/detail?id=244</a></li> </ul><p>1.3.975.10x にてリリース.</p> </div> <div class="section"> <h4>SHOW_INFOLIST_IMMEDIATELY compatibility flag</h4> <p>Windows 環境でのバグ.<br /> Meadow 3.0 や NTEmacs 22 で Mozc を利用していると,用例ウィンドウが表示されないというバグ.Mozc 開発チーム内で発見されて回ってきたもの.<br /> これの原因がなんというか脱力系.もともと用例ウィンドウは「最後の UI 更新から 500 ミリ秒経って何のアクションも起きていなければ表示する」というロジックで動いていた.ところが,Meadow 3.0 や NTEmacs 22 はポーリングを行っていて,より短い間隔で IME の UI 更新通知を送ってくる (実際には更新する必要がないケースでも).これをトリガーとして候補ウィンドウの再レイアウトが行われるため,永遠に「最後の UI 更新から 500 ミリ秒経過」という条件が成立しない.<br /> これらのアプリケーションではディレイなしに用例ウィンドウを表示するようにして対処.</p> <ul> <li><a href="http://code.google.com/p/mozc/source/diff?spec=svn96&r=96&format=side&path=/trunk/src/renderer/win32/win32_renderer_util.h&old_path=/trunk/src/renderer/win32/win32_renderer_util.h&old=93">http://code.google.com/p/mozc/source/diff?spec=svn96&r=96&format=side&path=/trunk/src/renderer/win32/win32_renderer_util.h&old_path=/trunk/src/renderer/win32/win32_renderer_util.h&old=93</a></li> </ul><p>1.3.975.102 にてリリース.</p> </div> <div class="section"> <h4>「半角空白を入力」が動作しないバグの修正</h4> <p>たまには変換エンジン側のバグも直してみようキャンペーン第一弾.<br /> カスタムキーマップにて「半角空白を入力」「全角空白を入力」というコマンドが選択可能であるにも関わらず,特定条件でうまく動作しないという問題,の修正.</p> <ul> <li><a href="http://productforums.google.com/d/topic/ime-ja/uazENEhWlnQ/discussion">http://productforums.google.com/d/topic/ime-ja/uazENEhWlnQ/discussion</a></li> </ul><p>1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>キャンセル後 IME を無効化</h4> <p>たまには変換エンジン側のバグも直してみようキャンペーン第二弾.<br /> ATOK と MS-IME のデフォルト設定の違いのひとつに,IME をオフにしたときに未確定の入力文字列を確定させるかそれともキャンセルさせるか,というものがある (MS-IME では確定,ATOK の ATOK キーマップではキャンセルさせるのがデフォルト).<br /> これまでのバージョンの Mozc では MS-IME にあわせて確定させていたのだけど,やっぱり ATOK スタイルが良いという人もいる.そういう人のためにカスタマイズの幅を増やしてみたという変更.<br /> といっても,これ以上コンフィグオプションを増やしたくはないよねということで,「キャンセル後 IME を無効化」というキーコマンド側を追加することで対処してみた.この方法だと,ATOK キー設定に自然に対応させられるのもよし.</p> <ul> <li><a href="http://productforums.google.com/d/topic/ime-ja/UPtnhv3nuxI/discussion">http://productforums.google.com/d/topic/ime-ja/UPtnhv3nuxI/discussion</a></li> <li><a href="http://productforums.google.com/d/topic/ime-ja/BYHVkC82iFU/discussion">http://productforums.google.com/d/topic/ime-ja/BYHVkC82iFU/discussion</a></li> </ul><p>ATOK (キーマップ) 派の人向けに実装しただけのつもりが,なぜか vim 方面の人に受けるという不思議な経験もした.</p> <ul> <li><a href="http://d.hatena.ne.jp/sifue/20120411/1334161078">SSHを介してVimを使う人に感動的なESCキーを押すとESCキーが効きつつIMEがオフになる設定 - しふーのブログ</a></li> </ul><p>バージョン 1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>サロゲートペア対応</h4> <p>クライアント側と変換エンジン側両方の修正.<br /> Windows クライアントに関しては,実際サロゲートペア対応をサボっていたのでその対応を粛々と.再変換とか確定取り消し周りが地味にめんどくさかった.<br /> 変換エンジン側は,UTF-8 を UCS2 に変換して処理している箇所がいくつか残っていたのでその残党狩り.<br /> この変更のおかげで,後の Unicode 絵文字対応がそこそこ楽になる.<br /> バージョン 1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>Mozc Issue 14</h4> <p>uim-mozc の開発者の人からのレポートで,Protocol Buffers のライブラリと動的リンクしていると,起動時にエラーになるので静的リンクに変更して欲しい,というもの.レポートから 1 年半以上放置されていたので見かねて修正.<br /> ちなみに Debian/Ubuntu/Fedora/Vineはこの辺まるっと無視して今も動的リンクしていたはず.ほんと静的リンク嫌いますよね……</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=14">http://code.google.com/p/mozc/issues/detail?id=14</a></li> </ul><p>1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>GCC 4.7 環境での warning つぶし</h4> <p>Linux 向け修正.<br /> タイトル通り.<br /> 1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>ibus_engine_delete_surrounding_text 対応</h4> <p>Linux の IBus 環境向け変更.IBus の比較的新しい API である ibus_engine_delete_surrounding_text を使用して,確定取り消し・再変換を実装するというもの.これ以前は Windows のようにバックスペースキーイベントを送っていた.<br /> ちょうど Firefox 側に関連バグが登録されていたのだけど,Mozc 側の問題ということで対処できた感じになる.</p> <ul> <li><a href="http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=6811">http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=6811</a></li> <li><a href="http://code.google.com/p/mozc/issues/detail?id=126">http://code.google.com/p/mozc/issues/detail?id=126</a></li> </ul><p>1.4.1003.10x にてリリース.</p> </div> <div class="section"> <h4>gtest なしでのビルドのサポート</h4> <p>openSUSE のパッケージで,Mozc が gtest に依存するのを独自パッチをあててまで回避しているっぽかったので,そういうことをしなくて良いように上流側で対処してみた,というもの.<br /> 1.4.1033.10x にてリリース.</p> </div> <div class="section"> <h4>compiler_specific.h 導入</h4> <p>コンパイラ依存コードの便利マクロ集.Chromium の同名のファイルにインスパイアされたもの.この頃から Clang 対応を考え始める.</p> <ul> <li><a href="http://src.chromium.org/viewvc/chrome/trunk/src/base/compiler_specific.h?view=markup">http://src.chromium.org/viewvc/chrome/trunk/src/base/compiler_specific.h?view=markup</a></li> <li><a href="https://code.google.com/p/mozc/source/browse/trunk/src/base/compiler_specific.h">https://code.google.com/p/mozc/source/browse/trunk/src/base/compiler_specific.h</a></li> </ul><p>1.5.1053.10x にてリリース</p> </div> <div class="section"> <h4>cURL 依存の排除</h4> <p>Linux 向け変更.<br /> OSS Mozc ではネットワーク機能を一切有効にしていないにもかかわらず,ビルドに cURL が必要という状態だったので,cURL なしでビルドできるようにしたというもの.<br /> 1.5.1053.10x にてリリース</p> </div> <div class="section"> <h4>QTBUG-25536 対策</h4> <p>Qt QString::toUcs4() がサロゲートペア領域の文字に対してうまく動かない,という問題に対する Mozc 側のワークアラウンド.</p> <pre class="code lang-cpp" data-lang="cpp" data-unlink><span class="synType">const</span> uint kData[] = { <span class="synConstant">0x10000</span> }; QString test = QString::fromUcs4(kData, <span class="synConstant">1</span>); <span class="synType">const</span> QVector&lt;uint&gt; ucs4s = test.toUcs4(); <span class="synStatement">if</span> (ucs4s.size() == <span class="synConstant">1</span>) { qDebug() &lt;&lt; <span class="synConstant">&quot;correct&quot;</span>; } <span class="synStatement">else</span> { qDebug() &lt;&lt; <span class="synConstant">&quot;wrong&quot;</span>; } </pre><p>このコード,最新の Qt 5.0.0 でも正しく動かない.ので,Mozc から QString::toUcs4() の呼び出しを削除する方向で対処.</p> <ul> <li><a href="https://code.google.com/p/mozc/issues/detail?id=158">https://code.google.com/p/mozc/issues/detail?id=158</a></li> <li><a href="https://bugreports.qt-project.org/browse/QTBUG-25536">https://bugreports.qt-project.org/browse/QTBUG-25536</a></li> </ul><p>1.5.1053.10x にてリリース</p> </div> <div class="section"> <h4>X11 Selection monitor</h4> <p>Linux 向け.<br /> ibus-mozc が GtkTextView でしか再変換ができなかったのを,もうちょっと対応環境を増やした,という変更.<br /> 諸悪の根源は,Gtk IM Module の get_surrounding_text がしょぼいことである.この API,カーソル周辺文字列 + カーソル位置しか取得できない.アンカー位置が取得できないため,現在選択されているテキストというのが分からない状態で再変換を実装しなければならない.<br /> 今回とった workaround は,xcb-xfixes を利用して,X11 のセレクションイベントをモニターするというもの.セレクションイベント経由で現在選択されているテキストを記録しておいて,get_surrounding_text で取得された周辺文字列 + カーソル位置と比較し,矛盾がないように選択領域を再構築する.<br /> xcb とかはじめて使ったのでなかなかにおもしろかった.</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=172">http://code.google.com/p/mozc/issues/detail?id=172</a></li> <li><a href="http://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/selection_monitor.cc">http://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/selection_monitor.cc</a></li> </ul><p>あと,このコードを書いているときに Linux 版 Firefox にサロゲートペア絡みのバグを見つけたので,Bugzilla に報告したところ,Mozilla Japan の中野さんに直して頂けました.感謝.</p> <ul> <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=757049">https://bugzilla.mozilla.org/show_bug.cgi?id=757049</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>Mac OS X Lion でのビルド対応</h4> <p>対応したつもりになって 1 年近く放置してしまったバグの対処.</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=91">http://code.google.com/p/mozc/issues/detail?id=91</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>scim-mozc is removed</h4> <p>予告通り scim-mozc をリポジトリから削除.<br /> 直接の原因は内部のメンテナの不在.<br /> まあ今更 SCIM もないでしょう.(Tizen を除く)</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=131">http://code.google.com/p/mozc/issues/detail?id=131</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>Debian-specific files are removed</h4> <p>Mozc のリポジトリに存在する Debian パッケージ定義ファイルがメンテナンスされていないので削除した,というもの.<br /> ちょうど Debian 本家でメンテナンスされているパッケージ定義ファイルとの乖離が激しくなってきたところだったというのも理由のひとつ.</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=132">http://code.google.com/p/mozc/issues/detail?id=132</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>IBus 1.4.1 未満のサポート停止</h4> <p>IBUS_CHECK_VERSION マクロがあちこちに散らばっていたので,一カ所にまとめた上,旧バージョンのサポートと停止.だいぶコードが綺麗になる.</p> <ul> <li><a href="http://code.google.com/p/mozc/issues/detail?id=156">http://code.google.com/p/mozc/issues/detail?id=156</a></li> <li><a href="http://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/ibus_header.h">http://code.google.com/p/mozc/source/browse/trunk/src/unix/ibus/ibus_header.h</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>Clang 対応開始</h4> <p>Clang revision 159409 を使用して発生する warning を全て解消 (または suppress).<br /> 1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>Visual C++ 2012 対応</h4> <p>ちなちまとコンパイルエラーに対処.<br /> 1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>#include &lt;Windows.h&gt; 撲滅運動</h4> <p>実に多くのヘッダファイルが不必要に #include &lt;Windows.h&gt; していることに気付きあちこち改良した,というもの.logging.h が &lt;Windows.h&gt; に依存するとかどうかと思う.</p> <ul> <li><a href="http://code.google.com/p/mozc/source/diff?spec=svn124&r=124&format=side&path=/trunk/src/base/logging.h&old_path=/trunk/src/base/logging.h&old=111">http://code.google.com/p/mozc/source/diff?spec=svn124&r=124&format=side&path=/trunk/src/base/logging.h&old_path=/trunk/src/base/logging.h&old=111</a></li> </ul><p>これでビルドがちょっとは速くなってくれるといいなぁと思いつつやったものの,目立っては高速化しなかった.残念.<br /> 1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>Ack-less IPC</h4> <p>Windows の IPC レイヤの改善.いままでの IPC クライアントは,<br /> 1. メッセージ送信<br /> 2. 応答受信<br /> 3. Ack 送信<br /> という手順を踏んでいたのを,3. でいきなり名前付きパイプを切断するように変更.切断イベントはどちらにしろサーバ側で検知可能なので,これを Ack イベントの代用とする.<br /> 実際これでレイテンシが数パーセント減ったのだから儲けものである.</p> <ul> <li><a href="http://code.google.com/p/mozc/source/diff?spec=svn124&r=124&format=side&path=/trunk/src/ipc/win32_ipc.cc">http://code.google.com/p/mozc/source/diff?spec=svn124&r=124&format=side&path=/trunk/src/ipc/win32_ipc.cc</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>StringPiece の移植</h4> <p>Mozc の portable library に StringPiece がないのが気になっていたので,えいやっと用意した一品.StringPiece については <a href="http://d.hatena.ne.jp/shinichiro_h/20100823#1282563465">hamaji さんの解説記事</a> とか参照のこと.</p> <ul> <li><a href="http://code.google.com/p/mozc/source/browse/trunk/src/base/string_piece.h">http://code.google.com/p/mozc/source/browse/trunk/src/base/string_piece.h</a></li> </ul><p>1.6.1187.102 にてリリース.</p> </div> <div class="section"> <h4>テンキーにあるコンマに対応</h4> <p>Apple 日本語キーボードのテンキーには,ピリオドキーだけでなくコンマキーもあるのですが,これに対応できていなかったという問題の修正.<br /> Mac では kVK_JIS_KeypadComma を使えば良いのですが,困ったのが Windows.<br /> なんと Brazilian キーボードにはテンキーにコンマがあるらしく,その仮想キーコードは VK_ABNT_C2 (0xC2) とのこと.実際,Apple 日本語キーボードを Windows 7 につなげてテンキーのコンマを押してもこの仮想キーコードが返ってきました.互換性への執念恐るべし.<br /> <a href="https://code.google.com/p/mozc/source/browse/trunk/src/win32/ime/ime_keyevent_handler.cc?r=124#253">https://code.google.com/p/mozc/source/browse/trunk/src/win32/ime/ime_keyevent_handler.cc?r=124#253</a></p> <pre class="code lang-cpp" data-lang="cpp" data-unlink> <span class="synComment">// The numpad comma on the Apple Japanese 109 keyboard is somehow mapped into</span> <span class="synComment">// VK_ABNT_C2, which is only defined in kbd.h.</span> <span class="synComment">// See also http://blogs.msdn.com/b/michkap/archive/2006/10/07/799605.aspx</span> <span class="synComment">// See also b/6639635.</span> KeyEvent::COMMA, <span class="synComment">// 0xC2: VK_ABNT_C2</span> </pre> <ul> <li><a href="http://productforums.google.com/d/msg/ime-ja/7OWCjtKpssg/FS-PHlmxvagJ">http://productforums.google.com/d/msg/ime-ja/7OWCjtKpssg/FS-PHlmxvagJ</a></li> </ul><p>1.6.1187.102 にてリリース.</p><p><hr><a href="http://nyaruru.hatenablog.com/entry/2013/03/31/172627">2012&#x5E74;&#x4ED6;&#x306B;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Mozc &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a>に続く.</p><p><hr>Chromium に関しては <a href="http://nyaruru.hatenablog.com/entry/2013/01/03/214030">2012&#x5E74;&#x3084;&#x3063;&#x305F;&#x3053;&#x3068; - Chromium &#x7DE8; - NyaRuRu&#x304C;&#x5730;&#x7403;&#x306B;&#x3044;&#x305F;&#x3053;&#x308D;</a> に続く.</p> </div><div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">ここでは OSS Mozc に限らず,いわゆる code-name Mozc についての活動</span></p> </div> Tue, 01 Jan 2013 13:40:11 +0900 hatenablog://entry/12704830469097229189 apt-get upgrade gcc considered harmful https://nyaruru.hatenablog.com/entry/2012/12/31/220400 <p>いまの仕事に就いたことで触れることのできた興味深いソフトウェア開発手法のひとつに,成果物に関するものであれば何であれ"<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>"の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%B8%A5%E7%A5%F3%B4%C9%CD%FD%A5%B7%A5%B9%A5%C6%A5%E0">バージョン管理システム</a>に関連づけるというものがある.使用するライブラリは言うに及ばず,ビルドに使用する<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>のバージョンまでもを,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>と同列にバージョン管理するわけだ.<br /> このような環境で仕事を続けることしばし,ふと気付けば,多くの <a class="keyword" href="http://d.hatena.ne.jp/keyword/Linux">Linux</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%A3%A5%B9%A5%C8%A5%EA%A5%D3%A5%E5%A1%BC%A5%B7%A5%E7%A5%F3">ディストリビューション</a>で喧伝されるうたい文句,「依存関係を賢く管理し,多数のユーザーによってテストされ,コマンド一発でインストールもアップデートもできる多数の開発ツール!」,というものは酷く色あせて聞こえるようになっていた.<br /> むしろ逆だ.<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D0%A1%BC%A5%B8%A5%E7%A5%F3%B4%C9%CD%FD%A5%B7%A5%B9%A5%C6%A5%E0">バージョン管理システム</a>とは異なるコマンドによって<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%B3%A5%F3%A5%D1%A5%A4%A5%E9">コンパイラ</a>やライブラリのバージョンが変化する!? そんなものは悪い冗談にしか聞こえない.そこにはコミットログも存在しなければ,コミット前のスモークテストも存在しない.ブランチを切ることもできなければ,不具合を見つけても<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%BD%A1%BC%A5%B9%A5%B3%A1%BC%A5%C9">ソースコード</a>のようには<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%ED%A1%BC%A5%EB%A5%D0%A5%C3%A5%AF">ロールバック</a>することもできない.<br /> <hr>などというようなことを『継続的デリバリー』を読みつつうなずいていた年末.いやー,本に書いてあるようなお手本運用を間近で見つつ仕事できるってのは刺激になっていいですねー.それではみなさま,来年も良いビルドを.<br /> <a href="http://d.hatena.ne.jp/asin/4048707876/hatendiarynya-22" class="asin"><img src="http://ecx.images-amazon.com/images/I/5119zam7gKL.jpg" alt="継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化" title="継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化" class="asin"></a></p> Mon, 31 Dec 2012 22:04:00 +0900 hatenablog://entry/12704830469097207754 サービスを最小特権で実行する https://nyaruru.hatenablog.com/entry/2012/10/15/010925 <p>今回は Windows サービスを作成する上でのセキュリティ上のポイントを軽く紹介する.<br /> <a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%20Vista">Windows Vista</a> では,サービスをより安全に実行するために Service Control Manager (SCM) の改善が行われている.ポイントとなるのは,必要特権リストの指定が可能になったこと,および制限された SID を割り当てられるようになったことだ.<br /> たとえば,特定ファイルを物理メモリ上に保持し続けるサービスを作りたいとする.この処理をサービスにする必要があるのは,それが特権を必要とするからだ.VirtualLock <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> でロック可能なメモリ領域は通常 30 ページに制限されており,SetProcessWorkingSetSize <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> でその制限を拡大するには,SE_INC_BASE_PRIORITY_NAME 特権が必要である.しかし,単純に System アカウントで動くサービスを作ったのでは,余分な特権まで有効にされてしまう.これは最小特権の原則に反する.<br /> ここで,以下のように ChangeServiceConfig2 <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を利用することで,サービスに付与される特権を制限できる.</p> <pre class="code lang-cpp" data-lang="cpp" data-unlink>SERVICE_REQUIRED_PRIVILEGES_INFO privileges_info = {}; privileges_info.pmszRequiredPrivileges = SE_INC_BASE_PRIORITY_NAME _T(<span class="synConstant">&quot;</span><span class="synSpecial">\0</span><span class="synConstant">&quot;</span>); ChangeServiceConfig2(service_handle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &amp;privileges_info); </pre><p>また,このサービスはファイルや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%C8%A5%EA">レジストリ</a>に書き込む必要がない.そこで,以下のように設定することで,意図せずファイルや<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%B8%A5%B9%A5%C8%A5%EA">レジストリ</a>に書き込もうとしたときに失敗するように構成できる.</p> <pre class="code lang-cpp" data-lang="cpp" data-unlink>SERVICE_SID_INFO sid_info = {}; sid_info.dwServiceSidType = SERVICE_SID_TYPE_RESTRICTED; ChangeServiceConfig2(service_handle, SERVICE_CONFIG_SERVICE_SID_INFO, &amp;sid_info); </pre><p>このように設定したサービスを起動し,Process Explorer でセキュリティ情報を見てみる.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121015/20121015010639.png" alt="f:id:NyaRuRu:20121015010639p:plain" title="f:id:NyaRuRu:20121015010639p:plain" class="hatena-fotolife"><br /> Restricted SID が設定されていること,"NT AUTHORITY\WRITE RESTRICTED" SID が設定されていること,特権が大幅に削除されていることなどがわかる.<br /> 実際,OS 標準のサービスは概ね最小特権で実行されている一方で,(残念ながら Microsoft Office を含む) OS 非標準のサービスは,デフォルトの特権を持ったまま動作しているものがほとんどだ.例えば,Office 2010 に付属する ImeDictUpdateService (Microsoft IME Dictionary Update) のセキュリティ属性は以下のようになる.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121015/20121015010658.png" alt="f:id:NyaRuRu:20121015010658p:plain" title="f:id:NyaRuRu:20121015010658p:plain" class="hatena-fotolife"><br /> デフォルトで付与される全ての特権を持ったまま実行されていることが分かる.これが本当に IME の辞書アップデートサービスであるなら,SeDebugPrivilege (スーパー特権のひとつ.プロセスのセキュリティ設定を無視して,(保護されたプロセスをのぞく) すべてのプロセスを開くことができる.) や,SeTimeZonePrivilege (文字通りタイムゾーンを設定するための特権) をはじめとした,多くの特権を削除しても恐らく動作は可能だろう.</p> <div class="section"> <h4>参考</h4> <p><a href="http://d.hatena.ne.jp/asin/4822294706/hatendiarynya-22" class="asin"><img src="http://ecx.images-amazon.com/images/I/51Maee3pGTL._SL160_.jpg" alt="インサイドWindows 第6版 上 (マイクロソフト公式解説書)" title="インサイドWindows 第6版 上 (マイクロソフト公式解説書)" class="asin"></a><br /> <a href="http://d.hatena.ne.jp/asin/4822294706/hatendiarynya-22">インサイドWindows 第6版 上 (マイクロソフト公式解説書)</a> であれば,P.352 「4.2.2 サービスアカウント/最小特権」あたりに詳しい.その他の参考資料については以下など.</p> <ul> <li><a href="http://blogs.technet.com/b/richard_macdonald/archive/2007/06/27/1375523.aspx"> Service Security in Windows Vista - Richard&#39;s Weblog - Site Home - TechNet Blogs </a></li> <li><a href="http://msdn.microsoft.com/ja-jp/magazine/cc164252.aspx">Windows &#x30B5;&#x30FC;&#x30D3;&#x30B9;&#x306E;&#x6A5F;&#x80FD;&#x5F37;&#x5316; / MSDN Magazine 2008</a></li> <li><a href="http://msdn.microsoft.com/ja-jp/magazine/cc163486.aspx#S13">&#x30A2;&#x30D7;&#x30EA;&#x30B1;&#x30FC;&#x30B7;&#x30E7;&#x30F3;&#x3067; Windows Vista &#x306E;&#x30E6;&#x30FC;&#x30B6;&#x30FC; &#x30A2;&#x30AB;&#x30A6;&#x30F3;&#x30C8;&#x5236;&#x5FA1;&#x3092;&#x6709;&#x52B9;&#x306B;&#x6D3B;&#x7528;&#x3059;&#x308B; - Windows Vista &#x3067; Windows &#x30B5;&#x30FC;&#x30D3;&#x30B9;&#x306E;&#x30BB;&#x30AD;&#x30E5;&#x30EA;&#x30C6;&#x30A3;&#x3092;&#x4FDD;&#x8B77;&#x3059;&#x308B; / MSDN Magazine 2007 Jan</a></li> </ul> </div> Mon, 15 Oct 2012 01:09:25 +0900 hatenablog://entry/12704591929891155580 Vista AppContainer 導入による Windows 開発への影響 https://nyaruru.hatenablog.com/entry/2012/10/08/185804 <p>Windows 8 では,AppContainer と呼ばれる新たな Sandbox メカニズムが導入される.Windows ストアアプリ (旧名: Windows Metro アプリ) や,Immersive モードの <a class="keyword" href="http://d.hatena.ne.jp/keyword/Internet%20Explorer">Internet Explorer</a> の<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%EC%A5%F3%A5%C0%A5%EA%A5%F3%A5%B0">レンダリング</a>プロセスなどが AppContainer で動作するプロセスの代表格だ.Windows ストアアプリ制作者にとって AppContainer が重要になるのはもちろんのこと,Windows ストアアプリ内で動作する必要のある <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> や<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%AF%A5%BB%A5%B7%A5%D3%A5%EA%A5%C6%A5%A3">アクセシビリティ</a>系ツールの制作者も,AppContainer について理解する必要がでてくる.</p> <div class="section"> <h4>AppContainer プロセスを確認する</h4> <p>Process Explorer 15.23 を用いて,AppContainer プロセスの特徴を確認してみよう.以下は Windows 8 付属の「ミュージック」アプリを起動し,Process Explorer にて表示してみたところだ.<br /> まず目に付く点として,WWAHost.exe プロセスの Integrity 欄に AppContainer と表示されていることが挙げられる.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121008/20121008185343.png" alt="f:id:NyaRuRu:20121008185343p:plain" title="f:id:NyaRuRu:20121008185343p:plain" class="hatena-fotolife"><br /> 次に WWAHost.exe プロセスのプロパティを表示し,Security Tab を選択してみる.プロセスのグループ一覧に,AppContainer と Capability という見慣れないグループがある.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121008/20121008185402.png" alt="f:id:NyaRuRu:20121008185402p:plain" title="f:id:NyaRuRu:20121008185402p:plain" class="hatena-fotolife"><br /> 前者は Windows ストアアプリごとに割り当てられるユニークな SID である.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a> 環境でアプリケーションごとに User ID が割り当てられるのと似ている.後者の Capability は,この Windows ストアアプリに許可された動作と対応している.「ミュージック」アプリは,</p> <ul> <li>インターネット接続へのアクセス</li> <li>ミュージックライブラリへのアクセス</li> </ul><p>が許可されているようだ.<br /> このように,AppContainer は,従来のトークン/SIDによるアクセス制御の拡張として実装されていることが分かる.例としては,Windows ストアアプリごとに SID が付与されることから,ある Windows ストアアプリにだけ,特定ディレクトリ以下へのアクセスを許すようなポリシーを設定することも可能である.</p> </div> <div class="section"> <h4>あるプロセスが AppContainer に属しているかどうかをプログラム的に判定する</h4> <p>あるプロセスが AppContainer に属しているかどうかをプログラム的に判定するには,プロセスのトークンハンドルに対して GetTokenInformation <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を使用する.Windows 8 (<a class="keyword" href="http://d.hatena.ne.jp/keyword/SDK">SDK</a>) 以降では TokenIsAppContainer フラグが使用でき,ここで 0 が返ってこなければプロセスは AppContainer で動作している.</p> </div> <div class="section"> <h4>あるプロセスが Immersive Mode かどうかをプログラム的に判定する</h4> <p>あるプロセスが没入型 UI を使用しているかどうかの判定には <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh448383.aspx">IsImmersiveProcess API</a> を用いる.この用途で GetTokenInformation/TokenIsAppContainer フラグを使用するべきではない.なぜか?<br /> それは Windows ストアアプリ風アプリケーション全てが AppContainer 内で動作するわけではないからだ.ブラウザという大きな例外がある.<br /> 「<a href="http://go.microsoft.com/fwlink/?LinkID=243079">Metro &#x30B9;&#x30BF;&#x30A4;&#x30EB;&#x5BFE;&#x5FDC;&#x30C7;&#x30B9;&#x30AF;&#x30C8;&#x30C3;&#x30D7; &#x30D6;&#x30E9;&#x30A6;&#x30B6;&#x30FC;&#x306E;&#x958B;&#x767A;</a>」というホワイトペーパーに解説されているとおり,Windows 8 対応のブラウザには以下の 3 種類が存在する.</p> <ol> <li>Windows Store app: AppContainer 内で動作する</li> <li>Desktop browsers: <a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> までと同様のモデルで動作する.Win32 <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> にフルアクセスが可能で,<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a> コンパイルや様々なマルチプロセス技術が利用可能.</li> <li>New experience enabled desktop browser: Windows ストアアプリ風の没入型 UI を備えつつ,Win32 <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> にフルアクセスが可能で,<a class="keyword" href="http://d.hatena.ne.jp/keyword/JIT">JIT</a> コンパイルや様々なマルチプロセス技術が利用可能.</li> </ol><p>この 3 つ目が問題だ.結果として,没入型 UI かどうかの判定と AppContainer で動いているかどうかの判定は分けて考える必要がある.</p> </div> <div class="section"> <h4>AppContainer の SID を取得する</h4> <p>プロセスのトークンハンドルに対して GetTokenInformation <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を使用する.Windows 8 (<a class="keyword" href="http://d.hatena.ne.jp/keyword/SDK">SDK</a>) 以降では TokenAppContainerSid フラグが使用でき,ここで返ってきたものが AppContainer の SID である.</p> </div> <div class="section"> <h4>AppContainer プロセスのオブジェクト<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a></h4> <p>引き続き,Process Explorer で AppContainer の動作を調べてみる.「View」→「Lower Pane View」から「Handles」を選択し,プロセス内で開かれているハンドル情報を調べてみよう.<br /> 開かれているハンドル名を見ていくと,セッション<a class="keyword" href="http://d.hatena.ne.jp/keyword/%CC%BE%C1%B0%B6%F5%B4%D6">名前空間</a>にさらに AppContainer SID が接頭辞として付加されていることに気付く.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121008/20121008185545.png" alt="f:id:NyaRuRu:20121008185545p:plain" title="f:id:NyaRuRu:20121008185545p:plain" class="hatena-fotolife"></p> <pre class="code" data-unlink>\Sessions\1\AppContainerNamedObjects\S-1-15-2-43664394-2685677502-394080391-3933305958-4167273977-1510959782-2102270723\RPC Control\OLE36E12F064548B659D96055B91BF5</pre><p>これに対応すると考えられる <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493.aspx">GetAppContainerNamedObjectPath API</a> の Remarks が興味深い.この Remarks は,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A2%A5%AF%A5%BB%A5%B7%A5%D3%A5%EA%A5%C6%A5%A3">アクセシビリティ</a>系など,別プロセス内で動作するツールに向けて書かれたものだ.</p> <blockquote cite="http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493.aspx"> <p>For assistive technology tools that work across Windows Store apps and desktop applications and have features that get loaded in the context of Windows Store apps, at times it may be necessary for the in-context feature to synchronize with the tool. Typically such synchronization is accomplished by establishing a named object in the user's session. Windows Store apps pose a challenge for this mechanism because, by default, named objects in the user's or global session are not accessible to Windows Store apps. We recommend that you update assistive technology tools to use UI Automation APIs or Magnification APIs to avoid such pitfalls. In the interim, it may be necessary to continue using named objects.</p> <cite><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/hh448493.aspx">GetAppContainerNamedObjectPath</a></cite> </blockquote> <p>デフォルトでは Windows Store アプリからは従来の名前付きオブジェクトにアクセスできないものの,アクセス権を設定しさえすればデスクトップアプリと Windows Store アプリの間で名前付きオブジェクトを共有することが依然として可能であることが示唆されている.なお,これは暫定的な措置であり,本来は UI Automation <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> や拡<a class="keyword" href="http://d.hatena.ne.jp/keyword/%C2%E7%B6%C0">大鏡</a> <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を用いて対処して欲しいようだ.</p> </div> <div class="section"> <h4>All Application Packages グループを利用したアクセス制御</h4> <p>実は,Windows 8 では ALL APPLICATION PACKAGES と呼ばれる特殊なグループが追加されている.このグループへのアクセス許可を設定することで,Windows Store アプリに一括して動作の許可や拒否を設定することができる.<br /> これについては,<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%D5%A5%A1%A5%A4%A5%EB%A5%B7%A5%B9%A5%C6%A5%E0">ファイルシステム</a>の例がわかりやすい.%SystemRoot% や %ProgramFiles% のセキュリティ設定を見てみよう.Windows 8 では,デフォルトで ALL APPLICATION PACKAGES グループに対する「読み取りと実行」「フォルダーの内容の一覧表示」「読み取り」アクセスが許可されている.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121008/20121008185631.png" alt="f:id:NyaRuRu:20121008185631p:plain" title="f:id:NyaRuRu:20121008185631p:plain" class="hatena-fotolife"><br /> 仮に <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> を開発するのであれば,仮に AppContainer 内で動作する場合であっても,<a class="keyword" href="http://d.hatena.ne.jp/keyword/ACL">ACL</a> 的にはこれらのディレクトリ (以下) に配置された設定ファイルや辞書データは自由に読み取りできるものと考えられる.<br /> また,試したわけではないが,AppContainer 内で動作する Windows Store アプリであっても,%ProgramFiles% 以下にインストールされたアプリケーション一覧や置かれたファイルの内容を取得することぐらいは可能なのかもしれない.これらの領域にセキュリティやプライバシーに関わるデータが置かれる場合は,悪意のある Windows Store アプリに読み取られる恐れがないか改めて確認されたい.<br /> さて,ALL APPLICATION PACKAGES だが,ファイルオブジェクト以外にも当然利用されているようだ.<br /> 以下は,TSF が利用していると思われる Mutex オブジェクトのセキュリティ情報である.<br /> <img src="http://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20121008/20121008185714.png" alt="f:id:NyaRuRu:20121008185714p:plain" title="f:id:NyaRuRu:20121008185714p:plain" class="hatena-fotolife"><br /> ALL APPLICATION PACKAGES に同期とクエリ許可が与えられていることが分かる.このように,DACL を設定することで,Windows Store アプリとデスクトップアプリの間で名前付きオブジェクトを共有することが可能になるのだろう.<br /> Windows Store アプリとデスクトップアプリの間のプロセス間通信についてもいずれいくつか書いてみたい.</p> </div> <div class="section"> <h4>参考</h4> <ul> <li><a href="http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/e92502b1-0b9f-4e02-9d72-e4e47e924a8f/"> Accessing named objects from an AppContainer </a> <ul> <li>AppContainer から名前付きオブジェクトにアクセスしたいというそのものずばりな質問</li> </ul></li> <li><a href="http://recxltd.blogspot.jp/2012/03/windows-8-app-container-security-notes.html">Research, Develop, Assess, Consult &amp; Educate | Recx: Windows 8 App Container Security Notes - Part 1</a> <ul> <li>AppContainer まとめ</li> </ul></li> <li><a href="http://technet.microsoft.com/en-us/library/hh832040.aspx#BKMK_AccessPermsGP"> Managing Client Access to the Windows Store </a></li> </ul> </div> Mon, 08 Oct 2012 18:58:04 +0900 hatenablog://entry/12704591929891049394 Windows 8 Google Chrome をデバッグする (1) https://nyaruru.hatenablog.com/entry/2012/09/30/015128 <p>Google Chrome のデイリーリリースバージョンは,炭鉱にて危険をいち早く察知するカナリアにたとえられ Canary 版と呼ばれている.<br /> (炭鉱で戦うものたちの熱い物語については『<a href="http://steps.dodgson.org/b/2012/05/20/gardening-with-canaries/">&#x70AD;&#x9271;&#x306E;&#x5EAD;&#x5E2B;</a>』を参照されたい)<br /> Google Chrome Canary 版は以下のページからインストールできる.<br /> <a href="https://tools.google.com/dlpage/chromesxs">https://tools.google.com/dlpage/chromesxs</a><br /> Canary 版と安定版は,インストール先フォルダから使用するプロファイルまで異なる別アプリケーションである (Side-by-side インストールと呼ばれている).両者を同時に起動することももちろん可能だ.また,Canary 版であっても Google Update の対象になることから,一度インストールしてしまえば後は自動で trunk を追いかけてくれる.<br /> 実は,Canary 版にはもうひとつ大きな特徴がある.それは,ビルドの副産物であるデバッグシンボルが公開されていることだ.ここで,デバッグシンボルが公開されていることで何が可能になるかについて,数回にわたって紹介してみたい.</p> <div class="section"> <h4 id="シンボルサーバの登録">シンボルサーバの登録</h4> <p>Windows エコシステムでのシンボルサーバの登録には,環境変数 _NT_SYMBOL_PATH を使用するのが一般的だ.Microsoft のシンボルサーバと Chrome のシンボルサーバを登録する場合,_NT_SYMBOL_PATH は次のように設定することになる.</p> <pre class="code bat" data-lang="bat" data-unlink>_NT_SYMBOL_PATH=srv*c:\SymCache*http://msdl.microsoft.com/download/symbols;srv*C:\SymCache*http://chromium-browser-symsrv.commondatastorage.googleapis.com</pre><p>"C:\SymCache" は別の名前に変更することも可能である.このフォルダにダウンロードされたシンボルデータがキャッシュされるので,なるべく高速なドライブを設定すると良い.<br /> 次に,よく利用する Sysinternals のツール群についてもシンボルパスを設定する.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20120930/20120930014804.png" width="481" height="248" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br /> Process Explorer と Process Monitor それぞれで,Options から Configure Symbols を選択する.Dbghelp.dll path については,Windows SDK 付属のものを選ぶとよい.64-bit 環境では x64 版の Dbghelp.dll を選択しよう.Symbol paths については先ほど同様に以下を設定する.</p> <pre class="code" data-lang="" data-unlink>srv*c:\SymCache*http://msdl.microsoft.com/download/symbols;srv*C:\SymCache*http://chromium-browser-symsrv.commondatastorage.googleapis.com</pre> </div> <div class="section"> <h4 id="Process-Explorer-を利用したハングアップ解析">Process Explorer を利用したハングアップ解析</h4> <p>Google Chrome Canary 版が無反応になったなら,Process Explorer を起動してみよう.デバッグシンボルが完備されていればその場でスレッドのコールスタックを見るのも容易である.(ただし,ここで最も慎重な次の一手はプロセスダンプをとることだ)<br /> 状況の保全のため,プロセスの全スレッドを中断させてみよう.一般的に,Chrome のウィンドウが無反応になったときには Chrome のブラウザプロセスの問題である.Process Explorer の "Process" 欄を何度かクリックして,表示モードをプロセスツリーに変更しよう.ここでルートに当たる chrome プロセスがブラウザプロセスである.(別の識別法として,プロセスの起動引数に --type オプションが付いていないプロセスを選ぶという方法もある)<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20120930/20120930014912.png" width="443" height="585" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br /> ブラウザプロセスを見つけたら,コンテキストメニューから Suspend を選択する.これでブラウザプロセスの動作が中断する.動作を中断させたら,コンテキストメニューから Properties を選択し,Threads タブに移動する.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20120930/20120930014932.png" width="526" height="624" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br /> ここでスレッドを選択し Stack ボタンをクリックすると,該当スレッドのコールスタックが表示される.<br /> <span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20120930/20120930014952.png" width="526" height="624" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br /> コールスタックを表示すると,非同期でシンボルのダウンロードが始まる.しばらくすると,Chrome のどういった関数が呼び出されていたのかが表示されるだろう.UI スレッドを探し出し,そのコールスタックを探し当てたら,それがハングアップの現場である.</p> </div> <div class="section"> <h4 id="Process-Monitor-を利用した-IO-モニタリング">Process Monitor を利用した I/O モニタリング</h4> <p>Process Monitor を利用することで,以下のような動作のモニタリングが可能になる.</p> <ul> <li>任意のファイルアクセス</li> <li>任意のレジストリアクセス</li> <li>任意のプロセス起動/スレッドイベント/DLL のロードとアンロード</li> <li>任意のネットワークアクセス</li> </ul><p>シンボルがセットされていると,これらの各イベント発生時のコールスタックが取得できるようになる.また,Tools メニューの各 Summary 項目から,選択したイベントの集計やクロス集計も可能である.例えば,プロセス起動時から終了時までの間にあるファイルへ行われた全てのファイルアクセスについて,コールスタックごとにその割合を分析するといったことが可能だ.</p><p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/N/NyaRuRu/20120930/20120930015009.png" width="900" height="714" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span><br /> Chrome を起動してあるページをブラウズし,終了するまでの間に行われた約 2000 回のファイル読み取りアクセスを,コールスタックを用いてブレイクダウンしている図</p><p>Process Monitor を用いた解析テクニックについては,例えば次の記事などが参考になる.</p> <ul> <li><a href="http://technet.microsoft.com/ja-jp/sysinternals/hh220627">IP &#x30A2;&#x30C9;&#x30EC;&#x30B9;&#x304C;&#x5909;&#x66F4;&#x3067;&#x304D;&#x306A;&#x3044;&#x5834;&#x5408;&#x306E;&#x5BFE;&#x5FDC; | Microsoft Learn</a></li> <li><a href="http://technet.microsoft.com/ja-jp/sysinternals/hh220632">&#x30D7;&#x30ED;&#x30B0;&#x30E9;&#x30E0;&#x304C;&#x8D77;&#x52D5;&#x3067;&#x304D;&#x306A;&#x3044;&#x5834;&#x5408;&#x306E;&#x5BFE;&#x5FDC; | Microsoft Learn</a></li> <li><a href="http://technet.microsoft.com/ja-jp/windows/gg986280">&#x958B;&#x304F;&#x306E;&#x306B;&#x6642;&#x9593;&#x304C;&#x304B;&#x304B;&#x308B; Project &#x30D5;&#x30A1;&#x30A4;&#x30EB;&#x306E;&#x554F;&#x984C; | Microsoft Learn</a></li> <li><a href="http://technet.microsoft.com/ja-jp/windows/hh757501">&#x30CF;&#x30F3;&#x30B0;&#x3057;&#x305F;&#x30B2;&#x30FC;&#x30E0; &#x30E9;&#x30F3;&#x30C1;&#x30E3;&#x30FC;&#x306E;&#x554F;&#x984C; | Microsoft Learn</a></li> <li><a href="http://technet.microsoft.com/ja-jp/windows/ee909534">Windows: &#x6975;&#x7AEF;&#x306A;&#x30B7;&#x30B9;&#x30C6;&#x30E0;&#x9045;&#x5EF6;&#x306E;&#x554F;&#x984C; | Microsoft Learn</a></li> </ul><p>次回,API モニタ編に続く.</p> </div> Sun, 30 Sep 2012 01:51:28 +0900 hatenablog://entry/12704591929890852234 SSD なら動作を変えるアプリケーションを作る https://nyaruru.hatenablog.com/entry/2012/09/29/063829 <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> 以降の OS では,<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a> 上のボリュームに対して<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%C7%A5%D5%A5%E9%A5%B0">デフラグ</a>がスケジューリングされません.これと同様に,ドライブ特性に応じた動作戦略の変更をアプリケーションでも行いたいこともあるでしょう.そのような場合にアプリケーションに組み込めるように,簡単なサンプルコードを書いてみます.<br /> 元ネタは,<a href="http://blogs.technet.com/b/filecab/archive/2009/11/25/windows-7-disk-defragmenter-user-interface-overview.aspx"> <br /> Windows 7 Disk Defragmenter User Interface Overview - The Storage Team at Microsoft - File Cabinet Blog - Site Home - TechNet Blogs <br /> </a> で解説されているアルゴリズムです. </p><p>以下,物理ドライブ "\\.\PhysicalDrive0" について,"no seek penalty" かどうかと,"nominal media rotation rate" かどうかの取得を行います.なお,前者はディスクポートドライバの動作に依存するため,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> 以降でなければ使用できませんが,管理者権限なしで動作するというメリットがあります.後者は ATA8-ACS に対応したデバイスであれば,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> より前の OS でも動作しますが,動作には管理者権限が必要です.<br /> 上記記事に解説されているように,これらの関数を組み合わせて使ってもよいですし,どちらか一方のみを使いある程度の false negative は諦めるという手もあります.</p> <pre class="code lang-cpp" data-lang="cpp" data-unlink><span class="synPreProc">#include </span><span class="synConstant">&lt;Windows.h&gt;</span> <span class="synPreProc">#include </span><span class="synConstant">&lt;WinIoCtl.h&gt;</span> <span class="synPreProc">#include </span><span class="synConstant">&lt;Ntddscsi.h&gt;</span> <span class="synPreProc">#include </span><span class="synConstant">&lt;Setupapi.h&gt;</span> <span class="synPreProc">#include </span><span class="synConstant">&lt;iostream&gt;</span> <span class="synPreProc">#include </span><span class="synConstant">&lt;string&gt;</span> <span class="synStatement">using</span> std::wstring; <span class="synStatement">using</span> std::wcout; <span class="synStatement">using</span> std::endl; <span class="synComment">// Returns S_OK if |physical_drive_path| has no seek penalty.</span> <span class="synComment">// Returns S_FALSE otherwise.</span> <span class="synComment">// Returns E_FAIL if fails to retrieve the status.</span> <span class="synComment">// |physical_drive_path| should be something like</span> <span class="synComment">// &quot;\\\\.\\PhysicalDrive0&quot;.</span> HRESULT HasNoSeekPenalty(<span class="synType">const</span> wstring&amp; physical_drive_path) { <span class="synComment">// We do not need write permission.</span> <span class="synType">const</span> HANDLE handle = ::CreateFileW( physical_drive_path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, <span class="synConstant">NULL</span>, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, <span class="synConstant">NULL</span>); <span class="synStatement">if</span> (handle == INVALID_HANDLE_VALUE) { <span class="synStatement">return</span> E_FAIL; } STORAGE_PROPERTY_QUERY query_seek_penalty = { StorageDeviceSeekPenaltyProperty, <span class="synComment">// PropertyId</span> PropertyStandardQuery, <span class="synComment">// QueryType,</span> }; DEVICE_SEEK_PENALTY_DESCRIPTOR query_seek_penalty_desc = {}; DWORD returned_query_seek_penalty_size = <span class="synConstant">0</span>; <span class="synType">const</span> BOOL query_seek_penalty_result = DeviceIoControl( handle, IOCTL_STORAGE_QUERY_PROPERTY, &amp;query_seek_penalty, <span class="synStatement">sizeof</span>(query_seek_penalty), &amp;query_seek_penalty_desc, <span class="synStatement">sizeof</span>(query_seek_penalty_desc), &amp;returned_query_seek_penalty_size, <span class="synConstant">NULL</span>); CloseHandle(handle); <span class="synStatement">if</span> (!query_seek_penalty_result) { <span class="synComment">// failed to retrieve data.</span> <span class="synStatement">return</span> E_FAIL; } <span class="synStatement">return</span> !query_seek_penalty_desc.IncursSeekPenalty ? S_OK : S_FALSE; } <span class="synComment">// Returns S_OK if |physical_drive_path| has nominal media</span> <span class="synComment">// rotation rate in terms of ATA8-ACS specification.</span> <span class="synComment">// http://www.t13.org/Documents/UploadedDocuments/docs2007/D1699r4-ATA8-ACS.pdf#Page=179</span> <span class="synComment">// Returns S_FALSE otherwise.</span> <span class="synComment">// Returns E_FAIL if fails to retrieve the status.</span> <span class="synComment">// |physical_drive_path| should be something like</span> <span class="synComment">// &quot;\\\\.\\PhysicalDrive0&quot;.</span> HRESULT HasNominalMediaRotationRate( <span class="synType">const</span> wstring&amp; physical_drive_path) { <span class="synComment">// In order to use IOCTL_ATA_PASS_THROUGH,</span> <span class="synComment">// We *do* need read/write permission, which means</span> <span class="synComment">// that the caller has admin privilege.</span> <span class="synType">const</span> HANDLE handle = CreateFileW( physical_drive_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, <span class="synConstant">NULL</span>, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, <span class="synConstant">NULL</span>); <span class="synStatement">if</span> (handle == INVALID_HANDLE_VALUE) { <span class="synStatement">return</span> E_FAIL; } <span class="synType">struct</span> ATAIdentifyDeviceQuery { ATA_PASS_THROUGH_EX header; WORD data[<span class="synConstant">256</span>]; }; ATAIdentifyDeviceQuery id_query = {}; id_query.header.Length = <span class="synStatement">sizeof</span>(id_query.header); id_query.header.AtaFlags = ATA_FLAGS_DATA_IN; id_query.header.DataTransferLength = <span class="synStatement">sizeof</span>(id_query.data); id_query.header.TimeOutValue = <span class="synConstant">3</span>; <span class="synComment">// sec</span> id_query.header.DataBufferOffset = <span class="synStatement">sizeof</span>(id_query.header); id_query.header.CurrentTaskFile[<span class="synConstant">6</span>] = <span class="synConstant">0xec</span>; <span class="synComment">// ATA IDENTIFY DEVICE command</span> DWORD retval_size = <span class="synConstant">0</span>; <span class="synType">const</span> BOOL result = DeviceIoControl( handle, IOCTL_ATA_PASS_THROUGH, &amp;id_query, id_query.header.DataTransferLength, &amp;id_query, id_query.header.DataTransferLength, &amp;retval_size, <span class="synConstant">NULL</span>); <span class="synStatement">if</span> (!result) { <span class="synStatement">return</span> E_FAIL; } <span class="synType">const</span> <span class="synType">int</span> kNominalMediaRotRateWordIndex = <span class="synConstant">217</span>; <span class="synComment">// RPM == 1 means this is non-rotate device</span> <span class="synStatement">return</span> id_query.data[kNominalMediaRotRateWordIndex] == <span class="synConstant">1</span> ? S_OK : S_FALSE; } <span class="synType">int</span> main() { <span class="synType">const</span> wstring <a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a> = <span class="synConstant">L&quot;</span><span class="synSpecial">\\\\</span><span class="synConstant">.</span><span class="synSpecial">\\</span><span class="synConstant">PhysicalDrive0&quot;</span>; <span class="synStatement">switch</span> (HasNoSeekPenalty(<a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a>)) { <span class="synStatement">case</span> S_OK: wcout &lt;&lt; <a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a> &lt;&lt; <span class="synConstant">L&quot; has no seek penalty.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; <span class="synStatement">case</span> S_FALSE: wcout &lt;&lt; <a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a> &lt;&lt; <span class="synConstant">L&quot; has seek penalty.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; <span class="synStatement">default</span>: wcout &lt;&lt; <span class="synConstant">L&quot;failed to retrieve the status.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; } <span class="synStatement">switch</span> (HasNominalMediaRotationRate(<a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a>)) { <span class="synStatement">case</span> S_OK: wcout &lt;&lt; <a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a> &lt;&lt; <span class="synConstant">L&quot; has no seek penalty.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; <span class="synStatement">case</span> S_FALSE: wcout &lt;&lt; <a class="keyword" href="http://d.hatena.ne.jp/keyword/kDrive">kDrive</a> &lt;&lt; <span class="synConstant">L&quot; has seek penalty.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; <span class="synStatement">default</span>: wcout &lt;&lt; <span class="synConstant">L&quot;failed to retrieve the status.&quot;</span> &lt;&lt; endl; <span class="synStatement">break</span>; } <span class="synStatement">return</span> <span class="synConstant">0</span>; } </pre><p>さて,"C:\Windows\System32\calc.exe" のようなパス名から,そのファイルが存在する物理ドライブ名を取得するにはどうすればよいでしょうか?<br /> これには,</p> <ol> <li>GetVolumePathName <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を利用してパスからマウントポイントを取得する</li> <li>GetVolumeNameForVolumeMountPoint <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> を利用して,論理ボリューム名を取得する</li> <li>IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS IO Control を利用して,物理ドライブの番号を取得する</li> </ol><p>という手順を踏みます.後は,得られた番号を "\\.\PhysicalDrive" の末尾に付ければ,物理ボリューム名が判明します.<br /> なお,ダイナミックボリュームでは,複数の物理ドライブにまたがった論理ボリュームが作成可能なことに注意してください.以下の関数は,指定されたパスに対応する物理ドライブ番号を返します.</p> <pre class="code lang-cpp" data-lang="cpp" data-unlink>vector&lt;<span class="synType">int</span>&gt; GetExtentsFromPath(<span class="synType">const</span> wstring&amp; path) { <a class="keyword" href="http://d.hatena.ne.jp/keyword/vector">vector</a>&lt;<span class="synType">int</span>&gt; extents; <span class="synType">wchar_t</span> mount_point[<span class="synConstant">1024</span>]; <span class="synStatement">if</span> (!GetVolumePathNameW( path.c_str(), mount_point, ARRAYSIZE(mount_point))) { <span class="synStatement">return</span> extents; } <span class="synType">wchar_t</span> volume_name[<span class="synConstant">1024</span>]; <span class="synStatement">if</span> (!GetVolumeNameForVolumeMountPointW( mount_point, volume_name, ARRAYSIZE(volume_name))) { <span class="synStatement">return</span> extents; } wstring volume = volume_name; <span class="synComment">// remove trailing '\\'</span> volume.resize(volume.size() - <span class="synConstant">1</span>); <span class="synComment">// We do not need write permission (nor admin rights).</span> <span class="synType">const</span> HANDLE volume_handle = CreateFileW( volume.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, <span class="synConstant">NULL</span>, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, <span class="synConstant">NULL</span>); VOLUME_DISK_EXTENTS initial_buffer = {}; DWORD returned_size = <span class="synConstant">0</span>; <span class="synType">const</span> BOOL get_volume_disk_result = DeviceIoControl( volume_handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, <span class="synConstant">NULL</span>, <span class="synConstant">0</span>, &amp;initial_buffer, <span class="synStatement">sizeof</span>(initial_buffer), &amp;returned_size, <span class="synConstant">NULL</span>); <span class="synType">const</span> DWORD query_size_error = GetLastError(); <span class="synStatement">if</span> (get_volume_disk_result != FALSE &amp;&amp; initial_buffer.NumberOfDiskExtents == <span class="synConstant">1</span>) { extents.push_back(initial_buffer.Extents[<span class="synConstant">0</span>].DiskNumber); <span class="synStatement">return</span> extents; } <span class="synStatement">if</span> (query_size_error != ERROR_MORE_DATA) { <span class="synStatement">return</span> extents; } <span class="synType">const</span> <span class="synType">size_t</span> buffer_size = <span class="synStatement">sizeof</span>(initial_buffer.NumberOfDiskExtents) + <span class="synStatement">sizeof</span>(initial_buffer.Extents) * initial_buffer.NumberOfDiskExtents; <span class="synType">char</span>* underlaying_buffer = <span class="synStatement">new</span> <span class="synType">char</span>[buffer_size]; VOLUME_DISK_EXTENTS* query_buffer = <span class="synStatement">reinterpret_cast</span>&lt;VOLUME_DISK_EXTENTS *&gt;( &amp;underlaying_buffer[<span class="synConstant">0</span>]); <span class="synType">const</span> BOOL devide_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ioc">ioc</a>_result = DeviceIoControl( volume_handle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, <span class="synConstant">NULL</span>, <span class="synConstant">0</span>, query_buffer, buffer_size, &amp;returned_size, <span class="synConstant">NULL</span>); <span class="synType">const</span> DWORD device_detail_result_error = ::GetLastError(); <span class="synStatement">if</span> (!!devide_<a class="keyword" href="http://d.hatena.ne.jp/keyword/ioc">ioc</a>_result) { <span class="synStatement">for</span> (DWORD i = <span class="synConstant">0</span>; i &lt; query_buffer-&gt;NumberOfDiskExtents; ++i) { extents.push_back(query_buffer-&gt;Extents[i].DiskNumber); } } <span class="synStatement">delete</span>[] underlaying_buffer; CloseHandle(volume_handle); <span class="synStatement">return</span> extents; } </pre><p>幸いなことに,上記処理は管理者権限なしでも動作します.<a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%207">Windows 7</a> 以降では,管理者に昇格する必要なしに,<a class="keyword" href="http://d.hatena.ne.jp/keyword/SSD">SSD</a> 上で動作しているらしいかどうかをアプリケーションが判別できるということになります.</p> Sat, 29 Sep 2012 06:38:29 +0900 hatenablog://entry/12704591929890838832 Windows 7 Metro スタイルアプリケーションと IME https://nyaruru.hatenablog.com/entry/20120619/p4 <p>Metro では,AppContainer という特殊な環境でアプリケーションが実行されます.<a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> DLL は <a href="#f1" name="fn1" title="Metro スタイルアプリケーションは,TSF のみのサポートとなりますから,IME というより Text Input Processor; TIP DLL と呼ぶ方が適切かもしれませんが">*1</a>,対象の Metro スタイルアプリケーションプロセスに読み込まれ,AppContainer の管理下で動作することが求められます.</p><p>実際,Microsoft は <a class="keyword" href="http://d.hatena.ne.jp/keyword/Windows%208">Windows 8</a> Release Preview の公開に合わせ,<a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh967425.aspx">Guidelines and checklist for IME development (Metro style apps)</a> というガイドラインの提供を開始しました<a href="#f2" name="fn2" title="一方で,予定されていた Metro アプリ用 IME サンプルに関する情報は[http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/6abc8b91-110c-4d60-b5b7-e113144902d9:title=削除されました].">*2</a>.同ドキュメントには,AppContainer 内で <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> の機能を実装する上で,次のようなケースに注意せよとあります.</p> <ul> <li>辞書ファイルの置き場所</li> <li>インターネットを利用したアップデート</li> <li>学習機能</li> <li>プロセス間での(設定や学習)情報の共有</li> </ul><p>同ドキュメントには,<a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> の学習機能や,プロセス間での(設定や学習)情報の共有機能の実装方法として,その AppContainer で可能であれば<a class="keyword" href="http://d.hatena.ne.jp/keyword/%A5%A6%A5%A7%A5%D6%A5%B5%A1%BC%A5%D3%A5%B9">ウェブサービス</a>を経由してこれらの機能を実装するよう書かれています.Mac や <a class="keyword" href="http://d.hatena.ne.jp/keyword/Android">Android</a> のように <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> プロセスを分離してくれていれば,<a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> 単体に別のアクセスコントロールを適用することも可能だったのでしょうが……</p><p>なお,Metro アプリケーションとデスクトップアプリケーションでは,利用可能なテクノロジに違いがあります.詳細については <a href="http://msdn.microsoft.com/en-us/library/windows/apps/br211369.aspx">API reference for Metro style apps</a> から辿ることができます.Metro 対応 <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> では IMM32 ではなく TSF を使う必要があることはガイドラインで明記されていましたが,その他の <a class="keyword" href="http://d.hatena.ne.jp/keyword/API">API</a> についてははっきりとは書かれていません.公開されると言われている Metro 対応 <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> サンプルでも読まないとはっきりしない予感がします.<br /> なお,こうして作られた <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> DLL は,従来のデスクトップアプリケーションに読み込まれても動作する必要があります.まさに Run Anywhere,<a class="keyword" href="http://d.hatena.ne.jp/keyword/Universal%20Binary">Universal Binary</a> というわけです.</p> <div class="footnote"> <p class="footnote"><a href="#fn1" name="f1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">Metro スタイルアプリケーションは,TSF のみのサポートとなりますから,<a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> というより Text Input Processor; TIP DLL と呼ぶ方が適切かもしれませんが</span></p> <p class="footnote"><a href="#fn2" name="f2" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">一方で,予定されていた Metro アプリ用 <a class="keyword" href="http://d.hatena.ne.jp/keyword/IME">IME</a> サンプルに関する情報は[http://social.<a class="keyword" href="http://d.hatena.ne.jp/keyword/msdn">msdn</a>.microsoft.com/Forums/en-US/winappswithnativecode/thread/6abc8b91-110c-4d60-b5b7-e113144902d9:title=削除されました].</span></p> </div> Tue, 19 Jun 2012 00:00:03 +0900 hatenablog://entry/12704591929890835242