How to close one CefBrowserView without closing CefWindow?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

How to close one CefBrowserView without closing CefWindow?

Postby paveldvlip » Sat Aug 13, 2022 5:50 am

I have a tabbed CefWindow and a lot of CefBrowserViews inside. Question: How to close one browser without closing CefWindow? After calling CefBrowserHost::CloseBrowser(false) I get a request to close the window in CefWindowDelegate::CanClose() where I return false since I can't close a window that has other open tabs. After that, the browser continues to work and there is no way to tell it that it can be closed. :shock:
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Re: How to close one CefBrowserView without closing CefWindo

Postby magreenblatt » Sat Aug 13, 2022 9:15 am

Remove the BrowserView from the parent View first and then call CloseBrowser(true)?
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: How to close one CefBrowserView without closing CefWindo

Postby paveldvlip » Sat Aug 13, 2022 10:10 am

magreenblatt wrote:Remove the BrowserView from the parent View first and then call CloseBrowser(true)?

I am receiving a message from a tab's close button via the OnButtonPressed() function. Here I am calling CloseBrowser(false). Then in DoClose() I remove the CefBrowserView from the CefWindow and call CloseBrowser(true). This has no effect because OnBeforeClose() is not called and the browser stays alive and continues to send and receive internet traffic. What am I doing wrong?
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Re: How to close one CefBrowserView without closing CefWindo

Postby magreenblatt » Sat Aug 13, 2022 10:36 am

Are you releasing all references to the CefBrowserView and CefBrowser? Are you returning true from DoClose? See also the DoClose documentation: https://github.com/chromiumembedded/cef ... ler.h#L106
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: How to close one CefBrowserView without closing CefWindo

Postby paveldvlip » Sat Aug 13, 2022 11:40 am

magreenblatt wrote:Are you releasing all references to the CefBrowserView and CefBrowser? Are you returning true from DoClose? See also the DoClose documentation: https://github.com/chromiumembedded/cef ... ler.h#L106

Yes, I released all references except ClientHandler::m_browser, which is released in OnBeforeClose(), but this function is not called. After the CefBrowserView is removed from the CefWindow, the CanClose() function is not called. The browser disappears from the window, but continues to work in the background. When the application is closed by calling CefShutdown(), errors about incorrect shutdown occur in the console. If I close the window manually before calling CefShutdown(), then the browsers close correctly and there are no errors.
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Re: How to close one CefBrowserView without closing CefWindo

Postby paveldvlip » Sat Aug 13, 2022 12:00 pm

I think the problem is that when calling the CloseBrowser(true) function, it waits for the window to close and the window_destroyed_ flag to be set, exiting immediately without doing anything.
https://bitbucket.org/chromiumembedded/ ... #lines-262
Code: Select all
void AlloyBrowserHostImpl::CloseBrowser(bool force_close) {
  if (CEF_CURRENTLY_ON_UIT()) {
    // Exit early if a close attempt is already pending and this method is
    // called again from somewhere other than WindowDestroyed().
    if (destruction_state_ >= DESTRUCTION_STATE_PENDING &&
        (IsWindowless() || !window_destroyed_)) {
      if (force_close && destruction_state_ == DESTRUCTION_STATE_PENDING) {
        // Upgrade the destruction state.
        destruction_state_ = DESTRUCTION_STATE_ACCEPTED;
      }
      return;
    }

    if (destruction_state_ < DESTRUCTION_STATE_ACCEPTED) {
      destruction_state_ = (force_close ? DESTRUCTION_STATE_ACCEPTED
                                        : DESTRUCTION_STATE_PENDING);
    }

    content::WebContents* contents = web_contents();
    if (contents && contents->NeedToFireBeforeUnloadOrUnloadEvents()) {
      // Will result in a call to BeforeUnloadFired() and, if the close isn't
      // canceled, CloseContents().
      contents->DispatchBeforeUnload(false /* auto_cancel */);
    } else {
      CloseContents(contents);
    }
  } else {
    CEF_POST_TASK(CEF_UIT, base::BindOnce(&AlloyBrowserHostImpl::CloseBrowser,
                                          this, force_close));
  }
}

In this case, there is no way to call the WindowDestroyed() function that sets this flag
Code: Select all
void AlloyBrowserHostImpl::WindowDestroyed() {
  CEF_REQUIRE_UIT();
  DCHECK(!window_destroyed_);
  window_destroyed_ = true;
  CloseBrowser(true);
}

It turns out that it is impossible to close the browser without closing the window!
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Re: How to close one CefBrowserView without closing CefWindo

Postby magreenblatt » Sat Aug 13, 2022 3:44 pm

WindowDestroyed should be called when the underlying Views object is deleted: https://github.com/chromiumembedded/cef ... pl.cc#L182

That would normally happen when the Views hierarchy containing the BrowserView is torn down. If the BrowserView is removed, then it should happen when all references are released. You can debug the code to find out what’s going wrong.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: How to close one CefBrowserView without closing CefWindo

Postby paveldvlip » Fri Aug 19, 2022 5:41 pm

I deleted all references to CefBrowserView, but the browser does not close because it keeps a link to its own CefBrowserView
https://github.com/chromiumembedded/cef ... mpl.cc#L31
Code: Select all
// static
CefRefPtr<CefBrowserView> CefBrowserView::GetForBrowser(
    CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UIT_RETURN(nullptr);

  CefBrowserHostBase* browser_impl =
      static_cast<CefBrowserHostBase*>(browser.get());
  if (browser_impl && browser_impl->is_views_hosted())
    return browser_impl->GetBrowserView();
  return nullptr;
}

Can you provide any working version of the source code where deleting CefBrowserView without closing the entire window causes the browser to close? There are no examples of such use in the documentation or cef/tests. Is there any other way to organize work with several browsers in one window?
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Re: How to close one CefBrowserView without closing CefWindo

Postby magreenblatt » Fri Aug 19, 2022 6:15 pm

I’m not aware of a working example. This is why it needs to be debugged.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: How to close one CefBrowserView without closing CefWindo

Postby paveldvlip » Sat Aug 20, 2022 6:48 am

Debugging step by step does not give anything, since part of the source code is missing, and many functions and subfunctions do not bring any understanding of where and what exactly to look for.

Is it possible to make the WindowDestroyed() function callable directly from the program? This will solve the problem. Moreover, the true value is returned in the DoClose() function.
paveldvlip
Techie
 
Posts: 22
Joined: Thu Mar 30, 2017 7:53 am

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 26 guests