Skip to content

Commit

Permalink
Fix popup window logic - use CEF built-in popup management
Browse files Browse the repository at this point in the history
  • Loading branch information
tishion committed Aug 26, 2023
1 parent 172d213 commit 36abfa5
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 143 deletions.
3 changes: 2 additions & 1 deletion example/QCefViewTest/CefViewWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ CefViewWidget::onBeforePopup(qint64 frameId,
const QString& targetFrameName,
QCefView::CefWindowOpenDisposition targetDisposition,
QRect& rect,
QCefSetting& settings)
QCefSetting& settings,
bool& disableJavascript)
{
// create new QCefView as popup browser
settings.setBackgroundColor(Qt::red);
Expand Down
3 changes: 2 additions & 1 deletion example/QCefViewTest/CefViewWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ protected slots:
const QString& targetFrameName,
QCefView::CefWindowOpenDisposition targetDisposition,
QRect& rect,
QCefSetting& settings) override;
QCefSetting& settings,
bool& disableJavascript) override;

void onNewDownloadItem(const QSharedPointer<QCefDownloadItem>& item, const QString& suggestedName) override;

Expand Down
2 changes: 1 addition & 1 deletion example/QCefViewTest/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ MainWindow::createRightCefView()

// this site is for test web events
m_pRightCefViewWidget = new CefViewWidget("", &setting, this);
m_pRightCefViewWidget->navigateToUrl("https://fastest.fish/test-files");
m_pRightCefViewWidget->navigateToUrl("https://www.javatpoint.com/oprweb/test.jsp?filename=javascript-window-close-method1");

//
// m_pRightCefViewWidget = new CefViewWidget("https://mdn.dev/", &setting, this);
Expand Down
37 changes: 16 additions & 21 deletions include/QCefView.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class QCEFVIEW_EXPORT QCefView : public QWidget
/// </summary>
/// <param name="parent">The parent</param>
/// <param name="f">The Qt WindowFlags</param>
QCefView(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
explicit QCefView(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());

/// <summary>
/// Destructs the QCefView instance
Expand Down Expand Up @@ -107,12 +107,6 @@ class QCEFVIEW_EXPORT QCefView : public QWidget
/// <returns>The browser id</returns>
int browserId();

/// <summary>
/// Gets whether the browser is created as popup browser
/// </summary>
/// <returns>True if it is popup browser; otherwise false</returns>
bool isPopup();

/// <summary>
/// Navigates to the content.
/// </summary>
Expand Down Expand Up @@ -408,19 +402,6 @@ class QCEFVIEW_EXPORT QCefView : public QWidget
/// <param name="window">The native browser windows</param>
void nativeBrowserCreated(QWindow* window);

/// <summary>
/// Gets called right after the popup browser was created.
/// </summary>
/// <param name="popup">The new created popup QCefView instance</param>
/// <remarks>
/// The lifecycle of the popup browser is managed by the owner of the popup browser,
/// thus do not try to hold the popup browser instance.
/// If you need to implement browser tab, you should override the <see cref="onBeforePopup"/> method
/// and create your own QCefView browser instance then you can manipulate the created one as whatever
/// you want.
/// </remarks>
void popupCreated(QCefView* popup);

protected:
/// <summary>
/// Gets called before the popup browser created
Expand All @@ -437,7 +418,21 @@ class QCEFVIEW_EXPORT QCefView : public QWidget
const QString& targetFrameName,
QCefView::CefWindowOpenDisposition targetDisposition,
QRect& rect,
QCefSetting& settings);
QCefSetting& settings,
bool& disableJavascript);

/// <summary>
/// Gets called right after the popup browser was created.
/// </summary>
/// <param name="popup">The new created popup QCefView instance</param>
/// <remarks>
/// The lifecycle of the popup browser is managed by the owner of the popup browser,
/// thus do not try to hold the popup browser instance.
/// If you need to implement browser tab, you should override the <see cref="onBeforePopup"/> method
/// and create your own QCefView browser instance then you can manipulate the created one as whatever
/// you want.
/// </remarks>
void onPopupCreated(QWidget* popup, const QString& url, const QString& name);

/// <summary>
/// Gets called on new download item was required. Keep reference to the download item
Expand Down
33 changes: 20 additions & 13 deletions src/QCefView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <QStyleOption>
#include <QVBoxLayout>
#include <QtDebug>
#include <QMainWindow>
#pragma endregion qt_headers

#include <QCefContext.h>
Expand All @@ -32,7 +33,7 @@ QCefView::QCefView(const QString url,
setMouseTracking(true);
setFocusPolicy(Qt::WheelFocus);

// create browser
// create cef browser
d_ptr->createCefBrowser(this, url, setting);
}

Expand All @@ -46,9 +47,6 @@ QCefView::~QCefView()
qDebug() << this << "is being destructed";

if (d_ptr) {
// close all popup browsers
d_ptr->closeAllPopupBrowsers();

// destroy under layer cef browser
d_ptr->destroyCefBrowser();
d_ptr.reset();
Expand Down Expand Up @@ -82,14 +80,6 @@ QCefView::browserId()
return d->browserId();
}

bool
QCefView::isPopup()
{
Q_D(QCefView);

return d->isPopup();
}

void
QCefView::navigateToString(const QString& content)
{
Expand Down Expand Up @@ -288,11 +278,28 @@ QCefView::onBeforePopup(qint64 frameId,
const QString& targetFrameName,
QCefView::CefWindowOpenDisposition targetDisposition,
QRect& rect,
QCefSetting& settings)
QCefSetting& settings,
bool& disableJavascript)
{
return false;
}

void
QCefView::onPopupCreated(QWidget* popup, const QString& url, const QString& name)
{
// create a top level window container
QMainWindow* popupWin = new QMainWindow();
popupWin->setAttribute(Qt::WA_DeleteOnClose, true);
popupWin->setWindowTitle(name);
popupWin->resize(popup->size());

// add the popup browser widget into the window
popupWin->setCentralWidget(popup);

// show window
popupWin->show();
}

void
QCefView::onNewDownloadItem(const QSharedPointer<QCefDownloadItem>& item, const QString& suggestedName)
{
Expand Down
2 changes: 1 addition & 1 deletion src/details/CCefClientDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class CCefClientDelegate
CefLifeSpanHandler::WindowOpenDisposition targetDisposition,
CefWindowInfo& windowInfo,
CefBrowserSettings& settings,
bool& DisableJavascriptAccess) override;
bool& disableJavascriptAccess) override;
virtual void onAfterCreate(CefRefPtr<CefBrowser>& browser) override;
virtual bool doClose(CefRefPtr<CefBrowser> browser) override;
virtual void onBeforeClose(CefRefPtr<CefBrowser> browser) override;
Expand Down
51 changes: 33 additions & 18 deletions src/details/CCefClientDelegate_LifeSpanHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,34 @@ CCefClientDelegate::onBeforePopup(CefRefPtr<CefBrowser>& browser,
CefLifeSpanHandler::WindowOpenDisposition targetDisposition,
CefWindowInfo& windowInfo,
CefBrowserSettings& settings,
bool& DisableJavascriptAccess)
bool& disableJavascriptAccess)
{
if (pCefViewPrivate_) {
bool cancelPopup = true;

Qt::ConnectionType c =
pCefViewPrivate_->q_ptr->thread() == QThread::currentThread() ? Qt::DirectConnection : Qt::QueuedConnection;
if (!pCefViewPrivate_)
return cancelPopup;

QMetaObject::invokeMethod(
pCefViewPrivate_,
[=]() {
pCefViewPrivate_->onBeforeCefPopupCreate(
browser, frameId, targetUrl, targetFrameName, targetDisposition, windowInfo, settings);
},
c);
}
// determine the connection type
Qt::ConnectionType c =
pCefViewPrivate_->q_ptr->thread() == QThread::currentThread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection;

// invoke the method
QMetaObject::invokeMethod(
pCefViewPrivate_,
[&]() {
cancelPopup = pCefViewPrivate_->onBeforeCefPopupBrowserCreate(browser, //
frameId, //
targetUrl, //
targetFrameName, //
targetDisposition, //
windowInfo, //
settings, //
disableJavascriptAccess //
);
},
c);

// QCefView doesn't use CEF built-in popup browser
return true;
return cancelPopup;
}

void
Expand All @@ -41,7 +51,7 @@ CCefClientDelegate::onAfterCreate(CefRefPtr<CefBrowser>& browser)

QWindow* w = nullptr;
// #if !defined(CEF_USE_OSR)
if (!pCefViewPrivate_->isOSRModeEnabled() /*|| browser->IsPopup()*/) {
if (!pCefViewPrivate_->isOSRModeEnabled() || browser->IsPopup()) {
// create QWindow from native browser window handle
w = QWindow::fromWinId((WId)(browser->GetHost()->GetWindowHandle()));
}
Expand All @@ -51,7 +61,7 @@ CCefClientDelegate::onAfterCreate(CefRefPtr<CefBrowser>& browser)
if (pCefViewPrivate_->q_ptr->thread() != QThread::currentThread()) {
// change connection type
// #if !defined(CEF_USE_OSR)
if (!pCefViewPrivate_->isOSRModeEnabled() /*|| browser->IsPopup()*/) {
if (!pCefViewPrivate_->isOSRModeEnabled() || browser->IsPopup()) {
c = Qt::QueuedConnection;
} else {
// #else
Expand All @@ -65,8 +75,13 @@ CCefClientDelegate::onAfterCreate(CefRefPtr<CefBrowser>& browser)
}
}

QMetaObject::invokeMethod(
pCefViewPrivate_, [=]() { pCefViewPrivate_->onCefBrowserCreated(browser, w); }, c);
if (browser->IsPopup()) {
QMetaObject::invokeMethod(
pCefViewPrivate_, [=]() { pCefViewPrivate_->onCefPopupBrowserCreated(browser, w); }, c);
} else {
QMetaObject::invokeMethod(
pCefViewPrivate_, [=]() { pCefViewPrivate_->onCefBrowserCreated(browser, w); }, c);
}
}

bool
Expand Down
Loading

0 comments on commit 36abfa5

Please sign in to comment.