chromiumembedded / cef

Chromium Embedded Framework (CEF). A simple framework for embedding Chromium-based browsers in other applications.
https://bitbucket.org/chromiumembedded/cef/
Other
3.09k stars 450 forks source link

chrome: win: Changing window visibility during app startup results in empty browser contents #3638

Closed magreenblatt closed 4 months ago

magreenblatt commented 5 months ago

To Reproduce Steps to reproduce the behavior:

  1. Add a window->Restore() call at the end of SimpleWindowDelegate::OnWindowCreated
  2. Run as cefsimple --enable-chrome-runtime --use-views --initial-show-state=minimized

Expected behavior The window should launch as non-minimized with visible browser contents. Instead, the browser contents are empty.

Versions (please complete the following information):

Additional context

More details on occlusion detection here.

More details on Views Show/Restore implementation in https://crbug.com/1523795 and https://github.com/chromiumembedded/cef/issues/3630#issuecomment-1906250261

magreenblatt commented 5 months ago

When the event handler gets notified of an event, it usually kicks off new occlusion calculation, which runs after a 16ms timer.

Looks like (according to occlusion tracker) the window is initially visible. 16ms after Restore it determines that the window is still visible. However, 80ms after Restore it decides that the window is hidden, and the status remains hidden thereafter.

[14724:17708:0202/133004.014:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.014:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:22892:0202/133004.042:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.321:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.415:WARNING:simple_app.cc(33)] Show
[14724:17708:0202/133004.418:WARNING:window_tree_host.cc(564)] WindowTreeHost::UpdateCompositorVisibility visible=1 is_transitioning_to_hidden=0
[14724:17708:0202/133004.418:WARNING:compositor.cc(531)] Compositor::SetVisible visible=1
[14724:17708:0202/133004.421:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.421:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:17708:0202/133004.422:WARNING:simple_app.cc(43)] Restore
[14724:17708:0202/133004.442:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[14724:17708:0202/133004.442:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.442:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:17708:0202/133004.442:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.442:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:17708:0202/133004.509:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=HIDDEN occluded_region.isEmpty=1
[14724:17708:0202/133004.509:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[14724:17708:0202/133004.509:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[14724:17708:0202/133004.756:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[14724:17708:0202/133005.126:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
magreenblatt commented 5 months ago

WindowTreeHost::SetNativeWindowOcclusionState state=HIDDEN occluded_region.isEmpty=1

It appears that the HIDDEN status is due to the window being IsIconic at the time that NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::ComputeNativeWindowOcclusionStatus executes (here). The only call to ComputeNativeWindowOcclusionStatus is before Show.

magreenblatt commented 5 months ago

Manually minimizing the window and then clicking the taskbar button (which fixes the contents display) results in the following:

[16696:18492:0202/133316.435:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[16696:18492:0202/133316.435:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[16696:18492:0202/133316.435:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[16696:18492:0202/133316.435:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[16696:18492:0202/133316.451:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[16696:18492:0202/133316.451:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[16696:18492:0202/133317.766:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[16696:18492:0202/133317.766:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[16696:18492:0202/133317.766:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[16696:18492:0202/133317.766:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[16696:18492:0202/133317.770:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[16696:18492:0202/133317.770:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[16696:18492:0202/133317.770:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=UNKNOWN occluded_region.isEmpty=1
[16696:18492:0202/133317.772:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[16696:18492:0202/133317.774:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[16696:18492:0202/133317.774:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[16696:18492:0202/133317.774:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[16696:18492:0202/133317.774:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[16696:18220:0202/133317.807:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[16696:18492:0202/133317.808:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=VISIBLE occluded_region.isEmpty=1
[16696:18492:0202/133317.858:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
magreenblatt commented 5 months ago

WindowTreeHost::SetNativeWindowOcclusionState state=UNKNOWN occluded_region.isEmpty=1

That call originates from:

    ui_aura.dll!aura::WindowTreeHost::SetNativeWindowOcclusionState(aura::Window::OcclusionState state, const SkRegion & occluded_region) Line 442  C++
    ui_aura.dll!aura::NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged(aura::Window * window, bool visible) Line 137  C++
    ui_aura.dll!aura::Window::NotifyWindowVisibilityChangedAtReceiver(aura::Window * target, bool visible) Line 1210    C++
    ui_aura.dll!aura::Window::NotifyWindowVisibilityChangedDown(aura::Window * target, bool visible) Line 1217  C++
    ui_aura.dll!aura::Window::NotifyWindowVisibilityChanged(aura::Window * target, bool visible) Line 1198  C++
    ui_aura.dll!aura::Window::SetVisibleInternal(bool visible) Line 1014    C++
    ui_aura.dll!aura::Window::Show() Line 359   C++
    ui_views.dll!views::DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored(bool restored) Line 1040  C++
    ui_views.dll!views::HWNDMessageHandler::OnSize(unsigned int param, const gfx::Size & size) Line 2674    C++
    ui_views.dll!views::HWNDMessageHandler::_ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned __int64 wParam, __int64 lParam, __int64 & lResult, unsigned long dwMsgMapID) Line 482  C++
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1083    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
magreenblatt commented 5 months ago

There are 2 calls to DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored during initial window Show/Restore. Both end up being ignored.

The first call to DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored during window creation (with |restored=false|) is ignored because IsNativeWidgetInitialized returns false.

>   ui_views.dll!views::DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored(bool restored) Line 1037  C++
    ui_views.dll!views::HWNDMessageHandler::OnSize(unsigned int param, const gfx::Size & size) Line 2674    C++
    ui_views.dll!views::HWNDMessageHandler::_ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned __int64 wParam, __int64 lParam, __int64 & lResult, unsigned long dwMsgMapID) Line 482  C++
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1083    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
    ui_gfx.dll!base::win::WrappedWindowProc<&gfx::WindowImpl::WndProc>(HWND__ * hwnd, unsigned int message, unsigned __int64 wparam, __int64 lparam) Line 74    C++
    [External Code] 
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1090    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
    ui_gfx.dll!base::win::WrappedWindowProc<&gfx::WindowImpl::WndProc>(HWND__ * hwnd, unsigned int message, unsigned __int64 wparam, __int64 lparam) Line 74    C++
    [External Code] 
    ui_gfx.dll!gfx::WindowImpl::Init(HWND__ * parent, const gfx::Rect & bounds) Line 223    C++
    ui_views.dll!views::HWNDMessageHandler::Init(HWND__ * parent, const gfx::Rect & bounds) Line 444    C++
    ui_views.dll!views::DesktopWindowTreeHostWin::Init(const views::Widget::InitParams & params) Line 207   C++
    ui_views.dll!views::DesktopNativeWidgetAura::InitNativeWidget(views::Widget::InitParams params) Line 578    C++
    ui_views.dll!views::Widget::Init(views::Widget::InitParams params) Line 471 C++
    libcef.dll!CefWindowView::CreateWidget(HWND__ * parent_widget) Line 532 C++
    libcef.dll!CefWindowImpl::CreateWidget(HWND__ * parent_widget) Line 762 C++
    libcef.dll!CefWindowImpl::Create(scoped_refptr<CefWindowDelegate> delegate, HWND__ * parent_widget) Line 123    C++
    libcef.dll!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 112  C++
    libcef.dll!cef_window_create_top_level(_cef_window_delegate_t * delegate) Line 48   C++
    cefsimple.exe!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 45    C++
    cefsimple.exe!SimpleApp::OnContextInitialized() Line 153    C++

The second call from Restore (with |restore=true|) results in a call to Show, however that is ignored in Window::SetVisibleInternal due to "No change".

>   ui_aura.dll!aura::Window::SetVisibleInternal(bool visible) Line 992 C++
    ui_aura.dll!aura::Window::Show() Line 359   C++
    ui_views.dll!views::DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored(bool restored) Line 1040  C++
    ui_views.dll!views::HWNDMessageHandler::OnSize(unsigned int param, const gfx::Size & size) Line 2674    C++
    ui_views.dll!views::HWNDMessageHandler::_ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned __int64 wParam, __int64 lParam, __int64 & lResult, unsigned long dwMsgMapID) Line 482  C++
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1083    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
    ui_gfx.dll!base::win::WrappedWindowProc<&gfx::WindowImpl::WndProc>(HWND__ * hwnd, unsigned int message, unsigned __int64 wparam, __int64 lparam) Line 74    C++
    [External Code] 
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1090    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
    ui_gfx.dll!base::win::WrappedWindowProc<&gfx::WindowImpl::WndProc>(HWND__ * hwnd, unsigned int message, unsigned __int64 wparam, __int64 lparam) Line 74    C++
    [External Code] 
    ui_views.dll!views::HWNDMessageHandler::OnSysCommand(unsigned int notification_code, const gfx::Point & point) Line 2762    C++
    ui_views.dll!views::HWNDMessageHandler::_ProcessWindowMessage(HWND__ * hWnd, unsigned int uMsg, unsigned __int64 wParam, __int64 lParam, __int64 & lResult, unsigned long dwMsgMapID) Line 484  C++
    ui_views.dll!views::HWNDMessageHandler::OnWndProc(unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 1083    C++
    ui_gfx.dll!gfx::WindowImpl::WndProc(HWND__ * hwnd, unsigned int message, unsigned __int64 w_param, __int64 l_param) Line 321    C++
    ui_gfx.dll!base::win::WrappedWindowProc<&gfx::WindowImpl::WndProc>(HWND__ * hwnd, unsigned int message, unsigned __int64 wparam, __int64 lparam) Line 74    C++
    [External Code] 
    ui_views.dll!views::HWNDMessageHandler::ExecuteSystemMenuCommand(int command) Line 1499 C++
    ui_views.dll!views::HWNDMessageHandler::Restore() Line 736  C++
    ui_views.dll!views::DesktopWindowTreeHostWin::Restore() Line 439    C++
    ui_views.dll!views::DesktopNativeWidgetAura::Restore() Line 1023    C++
    ui_views.dll!views::Widget::Restore() Line 951  C++
    libcef.dll!CefWindowImpl::Restore() Line 252    C++
    libcef.dll!`anonymous namespace'::window_restore(_cef_window_t * self) Line 289 C++
    cefsimple.exe!CefWindowCToCpp::Restore() Line 281   C++
    cefsimple.exe!`anonymous namespace'::SimpleWindowDelegate::OnWindowCreated(scoped_refptr<CefWindow> window) Line 50 C++
    cefsimple.exe!`anonymous namespace'::window_delegate_on_window_created(_cef_window_delegate_t * self, _cef_window_t * window) Line 42   C++
    libcef.dll!CefWindowDelegateCToCpp::OnWindowCreated(scoped_refptr<CefWindow> window) Line 41    C++
    libcef.dll!CefWindowImpl::CreateWidget(HWND__ * parent_widget) Line 781 C++
    libcef.dll!CefWindowImpl::Create(scoped_refptr<CefWindowDelegate> delegate, HWND__ * parent_widget) Line 123    C++
    libcef.dll!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 112  C++
    libcef.dll!cef_window_create_top_level(_cef_window_delegate_t * delegate) Line 48   C++
    cefsimple.exe!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 45    C++
    cefsimple.exe!SimpleApp::OnContextInitialized() Line 153    C++
magreenblatt commented 5 months ago

The second call from Restore (with |restore=true|) results in a call to Show, however that is ignored in Window::SetVisibleInternal due to "No change".

[14724:17708:0202/133004.014:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.014:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:22892:0202/133004.042:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[14724:17708:0202/133004.321:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.321:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[14724:17708:0202/133004.415:WARNING:simple_app.cc(33)] Show

The Window having visible status prior to Show (and prior to Restore) seems logically wrong. We want the Window to transition from hidden to visible when Restore is called.

The initial visibility status comes via:

>   ui_aura.dll!aura::WindowTreeHost::UpdateCompositorVisibility(bool visible) Line 564 C++
    ui_aura.dll!aura::WindowTreeHost::OnAcceleratedWidgetMadeVisible(bool value) Line 637   C++
    ui_views.dll!views::DesktopWindowTreeHostWin::Show(ui::WindowShowState show_state, const gfx::Rect & restore_bounds) Line 287   C++
    ui_views.dll!views::DesktopNativeWidgetAura::Show(ui::WindowShowState show_state, const gfx::Rect & restore_bounds) Line 925    C++
    ui_views.dll!views::Widget::Show() Line 862 C++
    libcef.dll!CefWindowImpl::Show() Line 132   C++
    libcef.dll!`anonymous namespace'::window_show(_cef_window_t * self) Line 66 C++
    cefsimple.exe!CefWindowCToCpp::Show() Line 66   C++
    cefsimple.exe!`anonymous namespace'::SimpleWindowDelegate::OnWindowCreated(scoped_refptr<CefWindow> window) Line 37 C++

Calling OnAcceleratedWidgetMadeVisible(true) might not make sense in this case, where |show_state=SHOW_STATE_MINIMIZED|.

magreenblatt commented 4 months ago

Creating the initial tab with WindowOpenDisposition::NEW_FOREGROUND_TAB via the chrome::AddTabAt call in ChromeBrowserHostImpl::Create will create the WebContents as initially visible, resulting a call to Show() via RenderFrameHostManager::EnsureRenderFrameHostVisibilityConsistent. We therefore want to use NEW_BACKGROUND_TAB instead when creating the window as initially minimized. This also requires changing NormalizeDisposition to allow this in combination with an empty tab strip.

>   content.dll!content::RenderWidgetHostViewBase::Show() Line 776  C++
    content.dll!content::RenderFrameHostManager::EnsureRenderFrameHostVisibilityConsistent() Line 5163  C++
    content.dll!content::RenderFrameHostManager::ReinitializeMainRenderFrame(content::RenderFrameHostImpl * render_frame_host) Line 4373    C++
    content.dll!content::RenderFrameHostManager::GetFrameHostForNavigation(content::NavigationRequest * request, content::BrowsingContextGroupSwap * browsing_context_group_swap, std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> * reason) Line 1800 C++
    content.dll!content::RenderFrameHostManager::DidCreateNavigationRequest(content::NavigationRequest * request) Line 1356 C++
    content.dll!content::FrameTreeNode::TakeNavigationRequest(std::__Cr::unique_ptr<content::NavigationRequest,std::__Cr::default_delete<content::NavigationRequest>> navigation_request) Line 612  C++
    content.dll!content::Navigator::Navigate(std::__Cr::unique_ptr<content::NavigationRequest,std::__Cr::default_delete<content::NavigationRequest>> request, content::ReloadType reload_type) Line 776 C++
    content.dll!content::NavigationControllerImpl::NavigateWithoutEntry(const content::NavigationController::LoadURLParams & params) Line 3741  C++
    content.dll!content::NavigationControllerImpl::LoadURLWithParams(const content::NavigationController::LoadURLParams & params) Line 1369 C++
    libcef.dll!`anonymous namespace'::LoadURLInContents(content::WebContents * target_contents, const GURL & url, NavigateParams * params) Line 491 C++
    libcef.dll!Navigate(NavigateParams * params) Line 874   C++
    libcef.dll!chrome::AddAndReturnTabAt(Browser * browser, const GURL & url, int idx, bool foreground, std::__Cr::optional<tab_groups::TabGroupId> group) Line 47  C++
    libcef.dll!chrome::AddTabAt(Browser * browser, const GURL & url, int idx, bool foreground, std::__Cr::optional<tab_groups::TabGroupId> group) Line 64   C++
    libcef.dll!ChromeBrowserHostImpl::Create(const CefBrowserCreateParams & params) Line 72 C++
    libcef.dll!CefBrowserHostBase::Create(CefBrowserCreateParams & create_params) Line 169  C++
    libcef.dll!CefBrowserViewImpl::OnBrowserViewAdded() Line 226    C++
    libcef.dll!ChromeBrowserView::AddedToWidget() Line 57   C++
    ui_views.dll!views::View::PropagateAddNotifications(const views::ViewHierarchyChangedDetails & details, bool is_added_to_widget) Line 3097  C++
    ui_views.dll!views::View::AddChildViewAtImpl(views::View * view, unsigned __int64 index) Line 2982  C++
    libcef.dll!views::View::AddChildView<views::View>(views::View * view) Line 451  C++
    libcef.dll!CefPanelImpl<CefWindowView,CefWindow,CefWindowDelegate>::AddChildView(scoped_refptr<CefView> view) Line 123  C++
    libcef.dll!`anonymous namespace'::window_add_child_view(_cef_panel_t * self, _cef_view_t * view) Line 841   C++
    cefsimple.exe!CefWindowCToCpp::AddChildView(scoped_refptr<CefView> view) Line 816   C++
    cefsimple.exe!`anonymous namespace'::SimpleWindowDelegate::OnWindowCreated(scoped_refptr<CefWindow> window) Line 30 C++
    cefsimple.exe!`anonymous namespace'::window_delegate_on_window_created(_cef_window_delegate_t * self, _cef_window_t * window) Line 42   C++
    libcef.dll!CefWindowDelegateCToCpp::OnWindowCreated(scoped_refptr<CefWindow> window) Line 41    C++
    libcef.dll!CefWindowImpl::CreateWidget(HWND__ * parent_widget) Line 781 C++
    libcef.dll!CefWindowImpl::Create(scoped_refptr<CefWindowDelegate> delegate, HWND__ * parent_widget) Line 123    C++
    libcef.dll!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 112  C++
    libcef.dll!cef_window_create_top_level(_cef_window_delegate_t * delegate) Line 48   C++
    cefsimple.exe!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 45    C++
    cefsimple.exe!SimpleApp::OnContextInitialized() Line 153    C++
magreenblatt commented 4 months ago

We therefore want to use NEW_BACKGROUND_TAB instead when creating the window as initially minimized.

Window visibility status looks good after this change.

Calling content_window()->Show() from DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored instead of DesktopWindowTreeHostWin::Show also seems to work. Visible status now comes after Restore and the occlusion detector (finally) sets the window as VISIBLE.

[22200:20952:0205/135301.271:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[22200:20952:0205/135301.271:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[22200:20952:0205/135301.400:WARNING:simple_app.cc(33)] Show
[22200:20952:0205/135301.400:WARNING:simple_app.cc(43)] Restore
[22200:20952:0205/135301.438:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:20952:0205/135301.438:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.438:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:26452:0205/135301.469:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135301.553:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=HIDDEN occluded_region.isEmpty=1
[22200:20952:0205/135301.553:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[22200:20952:0205/135301.553:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[22200:26452:0205/135301.584:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:26452:0205/135301.616:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135301.736:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=VISIBLE occluded_region.isEmpty=1
[22200:20952:0205/135301.737:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135301.737:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:20952:0205/135301.738:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:20952:0205/135301.738:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:26452:0205/135301.770:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135301.938:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:20952:0205/135302.371:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:26452:0205/135302.402:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135302.487:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[22200:20952:0205/135302.488:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[22200:20952:0205/135302.490:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[22200:20952:0205/135302.490:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=1
[22200:26452:0205/135302.521:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135302.601:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
[22200:20952:0205/135302.849:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1574, 1130
magreenblatt commented 4 months ago

The below changes delay assignment of visible status until after the call to Restore() (or user clicks the taskbar icon to restore). This causes the occlusion detector to behave as expected.

Summary of changes for DesktopWindowTreeHostWin:

  1. In DesktopWindowTreeHostWin::Init, don't call window()->Show() when params.show_state == ui::SHOW_STATE_MINIMIZED
  2. In DesktopWindowTreeHostWin::Show, don't call OnAcceleratedWidgetMadeVisible(true) or content_window()->Show() when show_state == ui::SHOW_STATE_MINIMIZED
  3. In DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored, call content_window()->Show() before window()->Show()

Summary of changes for ChromeBrowserHostImpl::Create:

  1. Pass foreground=false to chrome::AddTabAt when initial show state is minimized.
  2. Change NormalizeDisposition to allow WindowOpenDisposition::NEW_BACKGROUND_TAB in combination with an empty tab strip.
magreenblatt commented 4 months ago

There is still an issue with white flash when the occlusion detector briefly transitions from HIDDEN to VISIBLE after the call to Restore(). This does not occur when first restore comes from manually clicking the taskbar button.

[22200:26452:0205/135301.469:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135301.553:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=HIDDEN occluded_region.isEmpty=1
[22200:20952:0205/135301.553:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=0
[22200:20952:0205/135301.553:WARNING:native_window_occlusion_tracker_win.cc(134)] NativeWindowOcclusionTrackerWin::OnWindowVisibilityChanged visible=0
[22200:26452:0205/135301.584:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:26452:0205/135301.616:WARNING:native_window_occlusion_tracker_win.cc(566)] ComputeNativeWindowOcclusionStatus
[22200:20952:0205/135301.736:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=VISIBLE occluded_region.isEmpty=1

From https://chromium.googlesource.com/chromium/src/+/master/docs/windows_native_window_occlusion_tracking.md:

If a window is falsely determined to be occluded, the content area will be white.

magreenblatt commented 4 months ago

There is still an issue with white flash when the occlusion detector briefly transitions from HIDDEN to VISIBLE after the call to Restore()

We could delay the call to NativeWindowOcclusionTrackerWin::Enable for initially-minimized windows. This should be fine now that minimized windows are initially hidden per the above changes.

>   ui_aura.dll!aura::NativeWindowOcclusionTrackerWin::Enable(aura::Window * window) Line 109   C++
    ui_aura.dll!aura::NativeWindowOcclusionTracker::EnableNativeWindowOcclusionTracking(aura::WindowTreeHost * host) Line 34    C++
    ui_aura.dll!aura::WindowTreeHost::OnAcceleratedWidgetAvailable() Line 682   C++
    ui_views.dll!views::DesktopWindowTreeHostWin::Init(const views::Widget::InitParams & params) Line 209   C++
    ui_views.dll!views::DesktopNativeWidgetAura::InitNativeWidget(views::Widget::InitParams params) Line 578    C++
    ui_views.dll!views::Widget::Init(views::Widget::InitParams params) Line 471 C++
    libcef.dll!CefWindowView::CreateWidget(HWND__ * parent_widget) Line 532 C++
    libcef.dll!CefWindowImpl::CreateWidget(HWND__ * parent_widget) Line 762 C++
    libcef.dll!CefWindowImpl::Create(scoped_refptr<CefWindowDelegate> delegate, HWND__ * parent_widget) Line 123    C++
    libcef.dll!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 112  C++
    libcef.dll!cef_window_create_top_level(_cef_window_delegate_t * delegate) Line 48   C++
    cefsimple.exe!CefWindow::CreateTopLevelWindow(scoped_refptr<CefWindowDelegate> delegate) Line 45    C++
    cefsimple.exe!SimpleApp::OnContextInitialized() Line 153    C++
magreenblatt commented 4 months ago

There is still an issue with white flash

Looks like this particular white flash is unrelated to the occlusion detector. It reproduces with just:

cefclient.exe --use-views --enable-chrome-runtime --background-color=black --url=about:blank

Adding --hide-frame makes it go away.

magreenblatt commented 4 months ago

It looks like we can do without the Show() changes here, and just delay the NativeWindowOcclusionTrackerWin::Enable call until DesktopWindowTreeHostWin::HandleWindowMinimizedOrRestored. This works in cefclient calling Restore() after Show() in ViewsWindow::Show.

Running as:

cefclient --use-views --enable-chrome-runtime --initial-show-state=minimized --background-color=black --hide-frame

Renders properly without a white flash.

Debug output as follows:

[26696:30020:0205/160202.300:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[26696:30020:0205/160203.716:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[26696:30020:0205/160203.755:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[26696:30020:0205/160203.768:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[26696:30020:0205/160203.768:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[26696:30020:0205/160203.768:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 0, 0
[26696:30020:0205/160203.999:WARNING:views_window.cc(183)] Show
[26696:30020:0205/160203.999:WARNING:window_tree_host.cc(564)] WindowTreeHost::UpdateCompositorVisibility visible=1 is_transitioning_to_hidden=0
[26696:30020:0205/160203.999:WARNING:compositor.cc(531)] Compositor::SetVisible visible=1
[26696:30020:0205/160204.037:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[26696:30020:0205/160204.039:WARNING:views_window.cc(185)] Restore
[26696:30020:0205/160204.083:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1600, 1056
[26696:30020:0205/160204.092:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[26696:30020:0205/160204.094:WARNING:window.cc(1198)] Window::NotifyWindowVisibilityChanged visible=1
[26696:31152:0205/160204.133:WARNING:native_window_occlusion_tracker_win.cc(573)] ComputeNativeWindowOcclusionStatus
[26696:31152:0205/160204.409:WARNING:native_window_occlusion_tracker_win.cc(573)] ComputeNativeWindowOcclusionStatus
[26696:30020:0205/160204.532:WARNING:window_tree_host.cc(454)] WindowTreeHost::SetNativeWindowOcclusionState state=VISIBLE occluded_region.isEmpty=1
[26696:30020:0205/160206.076:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1600, 1056
[26696:30020:0205/160206.501:WARNING:render_widget_host_impl.cc(1107)] viewport_pixel_rect = 1600, 1056