fix: post viewport sync to CEF UI thread
- commit
- 51fc2d45370b447414b5dbff64ba15bb2077306d
- author
- brice · · 2026-05-16 15:10 UTC
- parent
- 0fa06a1
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +42 -3
M internal/infrastructure/cef/webview_viewport.go +12 -3
| @@ -265,10 +265,19 @@ func (wv *WebView) disconnectViewportSyncHooksOnGTKThread() { | |||
| 265 | 265 | } | |
| 266 | 266 | ||
| 267 | 267 | func (wv *WebView) notifyViewportSyncOnCEFUIThread(host viewportSyncBrowserHost, visible bool) { | |
| 268 | - | notifyBrowserViewportSync(host, visible) | |
| 269 | - | if wv != nil { | |
| 270 | - | wv.reapplyCurrentZoomForBackingScale("viewport-sync") | |
| 268 | + | if host == nil { | |
| 269 | + | return | |
| 270 | + | } | |
| 271 | + | task := cefNewTask(cefTaskFunc(func() { | |
| 272 | + | notifyBrowserViewportSync(host, visible) | |
| 273 | + | if wv != nil { | |
| 274 | + | wv.reapplyCurrentZoomForBackingScale("viewport-sync") | |
| 275 | + | } | |
| 276 | + | })) | |
| 277 | + | if task == nil { | |
| 278 | + | return | |
| 271 | 279 | } | |
| 280 | + | cefPostDelayedTask(purecef.ThreadIDTidUi, task, 0) | |
| 272 | 281 | } | |
| 273 | 282 | ||
| 274 | 283 | func notifyBrowserViewportSync(host viewportSyncBrowserHost, visible bool) { | |
| @@ -265,10 +265,19 @@ func (wv *WebView) disconnectViewportSyncHooksOnGTKThread() { | |||||
| 265 | } | 265 | } | ||
| 266 | 266 | ||||
| 267 | func (wv *WebView) notifyViewportSyncOnCEFUIThread(host viewportSyncBrowserHost, visible bool) { | 267 | func (wv *WebView) notifyViewportSyncOnCEFUIThread(host viewportSyncBrowserHost, visible bool) { | ||
| 268 | - | notifyBrowserViewportSync(host, visible) | 268 | + | if host == nil { |
| 269 | - | if wv != nil { | 269 | + | return |
| 270 | - | wv.reapplyCurrentZoomForBackingScale("viewport-sync") | 270 | + | } |
| 271 | + | task := cefNewTask(cefTaskFunc(func() { | |||
| 272 | + | notifyBrowserViewportSync(host, visible) | |||
| 273 | + | if wv != nil { | |||
| 274 | + | wv.reapplyCurrentZoomForBackingScale("viewport-sync") | |||
| 275 | + | } | |||
| 276 | + | })) | |||
| 277 | + | if task == nil { | |||
| 278 | + | return | |||
| 271 | } | 279 | } | ||
| 280 | + | cefPostDelayedTask(purecef.ThreadIDTidUi, task, 0) | |||
| 272 | } | 281 | } | ||
| 273 | 282 | ||||
| 274 | func notifyBrowserViewportSync(host viewportSyncBrowserHost, visible bool) { | 283 | func notifyBrowserViewportSync(host viewportSyncBrowserHost, visible bool) { | ||
M internal/infrastructure/cef/webview_viewport_test.go +30 -0
| @@ -48,6 +48,36 @@ func TestNotifyBrowserViewportSync_HiddenSkipsWasHidden(t *testing.T) { | |||
| 48 | 48 | require.Equal(t, []string{"NotifyScreenInfoChanged", "WasResized", "Invalidate"}, host.calls) | |
| 49 | 49 | } | |
| 50 | 50 | ||
| 51 | + | func TestNotifyViewportSyncOnCEFUIThread_PostsCEFWork(t *testing.T) { | |
| 52 | + | oldNewTask := cefNewTask | |
| 53 | + | oldPostDelayedTask := cefPostDelayedTask | |
| 54 | + | defer func() { | |
| 55 | + | cefNewTask = oldNewTask | |
| 56 | + | cefPostDelayedTask = oldPostDelayedTask | |
| 57 | + | }() | |
| 58 | + | ||
| 59 | + | cefNewTask = func(task purecef.Task) purecef.Task { return task } | |
| 60 | + | ||
| 61 | + | var scheduled purecef.Task | |
| 62 | + | cefPostDelayedTask = func(threadID purecef.ThreadID, task purecef.Task, delayMs int64) int32 { | |
| 63 | + | require.Equal(t, purecef.ThreadIDTidUi, threadID) | |
| 64 | + | require.Zero(t, delayMs) | |
| 65 | + | require.NotNil(t, task) | |
| 66 | + | scheduled = task | |
| 67 | + | return 1 | |
| 68 | + | } | |
| 69 | + | ||
| 70 | + | host := &viewportSyncOrderHost{} | |
| 71 | + | wv := &WebView{} | |
| 72 | + | wv.notifyViewportSyncOnCEFUIThread(host, true) | |
| 73 | + | ||
| 74 | + | require.Empty(t, host.calls) | |
| 75 | + | require.NotNil(t, scheduled) | |
| 76 | + | ||
| 77 | + | scheduled.Execute() | |
| 78 | + | require.Equal(t, []string{"WasHidden", "NotifyScreenInfoChanged", "WasResized", "Invalidate"}, host.calls) | |
| 79 | + | } | |
| 80 | + | ||
| 51 | 81 | func TestScheduleResizeRepaintPulse_CoalescesToLatestSequence(t *testing.T) { | |
| 52 | 82 | oldNewTask := cefNewTask | |
| 53 | 83 | oldPostDelayedTask := cefPostDelayedTask | |
| @@ -48,6 +48,36 @@ func TestNotifyBrowserViewportSync_HiddenSkipsWasHidden(t *testing.T) { | |||||
| 48 | require.Equal(t, []string{"NotifyScreenInfoChanged", "WasResized", "Invalidate"}, host.calls) | 48 | require.Equal(t, []string{"NotifyScreenInfoChanged", "WasResized", "Invalidate"}, host.calls) | ||
| 49 | } | 49 | } | ||
| 50 | 50 | ||||
| 51 | + | func TestNotifyViewportSyncOnCEFUIThread_PostsCEFWork(t *testing.T) { | |||
| 52 | + | oldNewTask := cefNewTask | |||
| 53 | + | oldPostDelayedTask := cefPostDelayedTask | |||
| 54 | + | defer func() { | |||
| 55 | + | cefNewTask = oldNewTask | |||
| 56 | + | cefPostDelayedTask = oldPostDelayedTask | |||
| 57 | + | }() | |||
| 58 | + | ||||
| 59 | + | cefNewTask = func(task purecef.Task) purecef.Task { return task } | |||
| 60 | + | ||||
| 61 | + | var scheduled purecef.Task | |||
| 62 | + | cefPostDelayedTask = func(threadID purecef.ThreadID, task purecef.Task, delayMs int64) int32 { | |||
| 63 | + | require.Equal(t, purecef.ThreadIDTidUi, threadID) | |||
| 64 | + | require.Zero(t, delayMs) | |||
| 65 | + | require.NotNil(t, task) | |||
| 66 | + | scheduled = task | |||
| 67 | + | return 1 | |||
| 68 | + | } | |||
| 69 | + | ||||
| 70 | + | host := &viewportSyncOrderHost{} | |||
| 71 | + | wv := &WebView{} | |||
| 72 | + | wv.notifyViewportSyncOnCEFUIThread(host, true) | |||
| 73 | + | ||||
| 74 | + | require.Empty(t, host.calls) | |||
| 75 | + | require.NotNil(t, scheduled) | |||
| 76 | + | ||||
| 77 | + | scheduled.Execute() | |||
| 78 | + | require.Equal(t, []string{"WasHidden", "NotifyScreenInfoChanged", "WasResized", "Invalidate"}, host.calls) | |||
| 79 | + | } | |||
| 80 | + | ||||
| 51 | func TestScheduleResizeRepaintPulse_CoalescesToLatestSequence(t *testing.T) { | 81 | func TestScheduleResizeRepaintPulse_CoalescesToLatestSequence(t *testing.T) { | ||
| 52 | oldNewTask := cefNewTask | 82 | oldNewTask := cefNewTask | ||
| 53 | oldPostDelayedTask := cefPostDelayedTask | 83 | oldPostDelayedTask := cefPostDelayedTask | ||