Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

アウトライン解析ダイアログボックスをドッキング時にスプリッターをドラッグしてリサイズするとウィンドウの描画がちらつく問題を解消 #1592

Merged
merged 1 commit into from
Mar 18, 2021

Conversation

beru
Copy link
Contributor

@beru beru commented Mar 17, 2021

PR の目的

タイトルに書かれている通りです。

カテゴリ

  • その他の問題

PR の背景

リサイズ時に表示がちらつく問題があるので対処を行いました。

PR のメリット

アウトライン解析ウィンドウの表示がちらつく問題が解消されます。

PR のデメリット (トレードオフとかあれば)

特にないと思います。

強いて言えばウィンドウの拡張スタイルに WS_EX_COMPOSITED を指定したのでメモリ使用量が少し増加するかもしれません。

仕様・動作説明

従来実装で CDlgFuncList::OnSize においてコントロールに対して行っていた 「ちらつき防止用の試行錯誤」 の UpdateWindow 呼び出しを削除しました。これを削除しないとちらつきが残ってしまうためです。

PR の影響範囲

画面表示に関してだけ影響があると思います。

テスト内容

テスト1

手順

  • 何かテキストファイルを開く(例:README.md
  • メニューの検索 > アウトライン解析 (F11) を選択してアウトライン解析ウィンドウを表示する
  • アウトライン解析ウィンドウをリサイズ中に表示がちらつかない事を確認する
  • アウトライン解析ウィンドウをドラッグしてエディタウィンドウにドッキングする
  • ドッキングしたアウトライン解析ウィンドウとエディタウィンドウの間のスプリッターをドラッグしてウィンドウをリサイズ中にアウトライン解析ウィンドウの表示がちらつかない事を確認する

関連 issue, PR

#1424

参考資料

https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles

WS_EX_COMPOSITED

Paints all descendants of a window in bottom-to-top painting order using double-buffering. Bottom-to-top painting order allows a descendent window to have translucency (alpha) and transparency (color-key) effects, but only if the descendent window also has the WS_EX_TRANSPARENT bit set. Double-buffering allows the window and its descendents to be painted without flicker. This cannot be used if the window has a class style of either CS_OWNDC or CS_CLASSDC.
Windows 2000: This style is not supported.

リソースファイルの IDD_FUNCLIST に WS_EX_COMPOSITED 拡張スタイルを指定

CDlgFuncList::OnSize においてコントロールに対して行っていた 「ちらつき防止用の試行錯誤」 の UpdateWindow 呼び出しを削除
@sonarcloud
Copy link

sonarcloud bot commented Mar 17, 2021

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@AppVeyorBot
Copy link

Build sakura 1.0.3563 completed (commit 66cfcef7e0 by @beru)

Copy link
Member

@kengoide kengoide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows 10 環境で動かしてみましたが良さそうに見えました。Windows 7 の DWM 無効モードでも正しく動作するのかどうかが少し気になります。

アウトライン解析ウィンドウをドラッグしてエディタウィンドウにドッキングする

こんな機能があったとは…!

@berryzplus
Copy link
Contributor

「ちらつく」という感覚的表現は嫌いなのですが、この修正に問題はないと思います。

「ちらつき現象」は、背景をクリアした⇒描画した⇒・・・を1回以上繰り返したときに発生します。
WindowsGDIの描画機構は基本的に、事務処理専用のi3端末搭載の超貧弱GPUでも動くように作られています。
プログラムが要求した描画命令はある程度結合されて実行されるので、全域クリアとかしない限りは背景クリアが画面表示されるよりも前に描画が実行され、画面表示されるのは「クリアして描画」の描画後になります。

本来、描画命令がダイレクトに画面に反映させるプログラムを書くほうがちょっと大変な作業なんですが、サクラエディタの背景クリアは基本的に「全域クリア」なので「クリアそのもの」に時間がかかり、これがちらつきの原因となっております。対策として考えられるのは引数なしのInvalidateRectやUpdateWindowをできるだけコールしないことなんすけど、作業的にめんどいのが難点なんですよね。

Windows7は今年の初めにEOLを迎えたので気にしなくてよい認識っす。

@beru
Copy link
Contributor Author

beru commented Mar 18, 2021

レビューありがとうございました。Merge します。

@beru beru merged commit 22d577f into sakura-editor:master Mar 18, 2021
@beru beru deleted the CDlgFuncList_resize_flickering branch March 18, 2021 19:25
@beru
Copy link
Contributor Author

beru commented Mar 21, 2021

Windows 10 環境で動かしてみましたが良さそうに見えました。Windows 7 の DWM 無効モードでも正しく動作するのかどうかが少し気になります。

もうしばらく Windows 7 使っていないのと動かせるPCを持っていないので確認が難しいです。

DWMはWindows Vistaから導入されましたね。デスクトップ描画で3フレーム遅延する問題があるみたいですね。

WS_EX_COMPOSITED 指定すると オフスクリーンバッファを使う事で描画が完了してから表示を行う事でちらつきを減らす事が出来ます。これはDWMが登場する前のGDI描画の頃から使われていた方法なのでDWMを強制的に無効にしても正しく動作すると思います。

アウトライン解析ウィンドウをドラッグしてエディタウィンドウにドッキングする

こんな機能があったとは…!

個人的にはドッキングするとエディタの画面が狭くなって使いづらい感じがするので使ってません。

@beru
Copy link
Contributor Author

beru commented Mar 21, 2021

「ちらつく」という感覚的表現は嫌いなのですが、この修正に問題はないと思います。

「ちらつき現象」は、背景をクリアした⇒描画した⇒・・・を1回以上繰り返したときに発生します。
WindowsGDIの描画機構は基本的に、事務処理専用のi3端末搭載の超貧弱GPUでも動くように作られています。
プログラムが要求した描画命令はある程度結合されて実行されるので、全域クリアとかしない限りは背景クリアが画面表示されるよりも前に描画が実行され、画面表示されるのは「クリアして描画」の描画後になります。

本来、描画命令がダイレクトに画面に反映させるプログラムを書くほうがちょっと大変な作業なんですが、サクラエディタの背景クリアは基本的に「全域クリア」なので「クリアそのもの」に時間がかかり、これがちらつきの原因となっております。対策として考えられるのは引数なしのInvalidateRectやUpdateWindowをできるだけコールしないことなんすけど、作業的にめんどいのが難点なんですよね。

ハードウェアに関してはPCが登場してからもう何十年も経って色々と強化され続けているので(とはいえ値段相応に性能差は存在しますが)どちらかというとソフトウェア側の問題だとは思います。

ソフトウェア側が色々と描画を行いますが、きりの良いタイミングで表示の更新が行われない場合に、本来は表示するべきではない描画途中の絵が一時的に画面表示されてしまい、それをユーザーがちらつきと感じるんだと思います。

サクラエディタはコモンコントロールやGDIを使っているので行える対策としてはオフスクリーンバッファを使うようにする事と不必要な再描画をなるべく控えるという事だと思います。

もう20年くらい前に詳しい人に Windows API のプログラミングは何でいちいち WM_PAINT で描画を行うような作りが一般的なのか聞いてみたところ、昔はメモリが少なかったのでオフスクリーンバッファをデフォルトで使うような作りには出来なかったからじゃないかと言われたような記憶があります。

まぁそんなこんなで今となってもレガシーな実装のサクラエディタではちらつき現象がちょっと残ってます。

@beru
Copy link
Contributor Author

beru commented Mar 21, 2021

#1600 のテストをしようと思って下記のファイル

https://raw.githubusercontent.com/erlang/epmd/master/src/epmd.erl

を保存してサクラエディタで表示してみたんですが、アウトライン解析の表示がはげしく変になっています。
C++の場合はTreeViewで問題が無いようですがErlangだとListViewで問題が起きてます。

@beru
Copy link
Contributor Author

beru commented Mar 21, 2021

ちらつきを減らす為にダイアログ側に拡張スタイルの WS_EX_COMPOSITED を付けたんですが、SysListView32 コントロールの LVS_REPORT でヘッダ表示を行うのとかなり相性が悪いようです。LVS_NOCOLUMNHEADER を付けてカラムヘッダを表示しないようにすれば問題は起きないですがそういうわけにも行かないので、この変更は revert します。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💩degradation🧻🚽 デグレ (前に動いていた機能が動かなくなった)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants