diff --git a/CefViewCore b/CefViewCore index 56f43757..e89ecd4f 160000 --- a/CefViewCore +++ b/CefViewCore @@ -1 +1 @@ -Subproject commit 56f437578cbf8ae5dda36ff6450768fcce86a840 +Subproject commit e89ecd4f373918570e36a054e3af0604fd9100ee diff --git a/example/QCefViewTest/MainWindow.cpp b/example/QCefViewTest/MainWindow.cpp index 89e57945..725f7ac6 100644 --- a/example/QCefViewTest/MainWindow.cpp +++ b/example/QCefViewTest/MainWindow.cpp @@ -284,22 +284,6 @@ MainWindow::onBtnNewBrowserClicked() w->show(); } -void -MainWindow::closeEvent(QCloseEvent* event) -{ - if (m_pLeftCefViewWidget) { - m_pLeftCefViewWidget->deleteLater(); - m_pLeftCefViewWidget = nullptr; - } - - if (m_pRightCefViewWidget) { - m_pRightCefViewWidget->deleteLater(); - m_pRightCefViewWidget = nullptr; - } - - event->accept(); -} - #ifndef Q_OS_MACOS void MainWindow::setupWindow() diff --git a/example/QCefViewTest/MainWindow.h b/example/QCefViewTest/MainWindow.h index 93e758d1..a555aee9 100644 --- a/example/QCefViewTest/MainWindow.h +++ b/example/QCefViewTest/MainWindow.h @@ -59,9 +59,6 @@ protected slots: void onBtnNewBrowserClicked(); -private: - void closeEvent(QCloseEvent* event) override; - private: Ui::MainWindow m_ui; diff --git a/example/QCefViewTest/index.in.html b/example/QCefViewTest/index.in.html index ad12d8ce..e6769cfe 100644 --- a/example/QCefViewTest/index.in.html +++ b/example/QCefViewTest/index.in.html @@ -86,6 +86,10 @@

Dragging area


Popup Browser By Script +
+ Close Current Window + +

An iframe with default borders:

diff --git a/include/QCefView.h b/include/QCefView.h index df632fa9..f47afe29 100644 --- a/include/QCefView.h +++ b/include/QCefView.h @@ -449,6 +449,12 @@ class QCEFVIEW_EXPORT QCefView : public QWidget /// The download item virtual void onUpdateDownloadItem(const QSharedPointer& item); + /// + /// Gets called on close request from web + /// + /// True to allow the close, false to cancel the close + virtual bool onRequestCloseFromWeb(); + #pragma region QWidget public slots: /// diff --git a/src/QCefView.cpp b/src/QCefView.cpp index a5cc5028..e6580937 100644 --- a/src/QCefView.cpp +++ b/src/QCefView.cpp @@ -22,7 +22,7 @@ QCefView::QCefView(const QString& url, : QWidget(parent, f) , d_ptr(new QCefViewPrivate(QCefContext::instance()->d_func(), this, url, setting)) { - + if (d_ptr->isOSRModeEnabled()) { // OSR mode setBackgroundRole(QPalette::Window); @@ -318,12 +318,20 @@ QCefView::onUpdateDownloadItem(const QSharedPointer& item) { } +bool +QCefView::onRequestCloseFromWeb() +{ + // delete self + deleteLater(); + + return true; +} + QVariant QCefView::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QCefView); - if (d->isOSRModeEnabled()) { // OSR mode auto r = d->onViewInputMethodQuery(query); @@ -347,7 +355,6 @@ QCefView::paintEvent(QPaintEvent* event) // for NCW mode, this makes sure QCefView will not be treated as transparent background painter.fillRect(rect(), palette().color(backgroundRole())); - if (d->isOSRModeEnabled()) { // OSR mode // 3. paint widget with its stylesheet diff --git a/src/details/CCefClientDelegate.cpp b/src/details/CCefClientDelegate.cpp index 399e099e..ebbf473d 100644 --- a/src/details/CCefClientDelegate.cpp +++ b/src/details/CCefClientDelegate.cpp @@ -39,7 +39,7 @@ CCefClientDelegate::processQueryRequest(CefRefPtr& browser, auto browserId = browser->GetIdentifier(); auto req = QString::fromStdString(request); - pCefViewPrivate_->q_ptr->cefQueryRequest(browserId, frameId, QCefQuery(req, query_id)); + emit pCefViewPrivate_->q_ptr->cefQueryRequest(browserId, frameId, QCefQuery(req, query_id)); } void @@ -72,7 +72,7 @@ CCefClientDelegate::invokeMethodNotify(CefRefPtr& browser, } auto browserId = browser->GetIdentifier(); - pCefViewPrivate_->q_ptr->invokeMethod(browserId, frameId, m, args); + emit pCefViewPrivate_->q_ptr->invokeMethod(browserId, frameId, m, args); } void @@ -88,5 +88,5 @@ CCefClientDelegate::reportJSResult(CefRefPtr& browser, QVariant qV; ValueConvertor::CefValueToQVariant(&qV, result.get()); auto c = QString::fromStdString(context); - pCefViewPrivate_->q_ptr->reportJavascriptResult(browserId, frameId, c, qV); + emit pCefViewPrivate_->q_ptr->reportJavascriptResult(browserId, frameId, c, qV); } diff --git a/src/details/CCefClientDelegate.h b/src/details/CCefClientDelegate.h index bbbab8cd..3ce7b315 100644 --- a/src/details/CCefClientDelegate.h +++ b/src/details/CCefClientDelegate.h @@ -144,6 +144,7 @@ class CCefClientDelegate bool& disableJavascriptAccess) override; virtual void onAfterCreate(CefRefPtr& browser) override; virtual bool doClose(CefRefPtr browser) override; + virtual bool requestClose(CefRefPtr browser) override; virtual void onBeforeClose(CefRefPtr browser) override; // LoadHandler diff --git a/src/details/CCefClientDelegate_DragHandler.cpp b/src/details/CCefClientDelegate_DragHandler.cpp index 80f1787d..0e35d574 100644 --- a/src/details/CCefClientDelegate_DragHandler.cpp +++ b/src/details/CCefClientDelegate_DragHandler.cpp @@ -34,5 +34,5 @@ CCefClientDelegate::draggableRegionChanged(CefRefPtr& browser, } } - pCefViewPrivate_->q_ptr->draggableRegionChanged(draggableRegion, nonDraggableRegion); + emit pCefViewPrivate_->q_ptr->draggableRegionChanged(draggableRegion, nonDraggableRegion); } diff --git a/src/details/CCefClientDelegate_LifeSpanHandler.cpp b/src/details/CCefClientDelegate_LifeSpanHandler.cpp index 60db2164..0b5f8199 100644 --- a/src/details/CCefClientDelegate_LifeSpanHandler.cpp +++ b/src/details/CCefClientDelegate_LifeSpanHandler.cpp @@ -1,6 +1,7 @@ #include "CCefClientDelegate.h" #include +#include #include "QCefSettingPrivate.h" #include "QCefViewPrivate.h" @@ -40,6 +41,8 @@ CCefClientDelegate::onBeforePopup(CefRefPtr& browser, QCefSettingPrivate::CopyFromCefBrowserSettings(&s, &settings); if (targetDisposition == CefLifeSpanHandler::WindowOpenDisposition::WOD_NEW_POPUP) { + // the new browser was created from javascript, we need to conform the CEF pop-up browser lifecycle + // because CEF need to return the new browser identity to javascript context Qt::ConnectionType c = pCefViewPrivate_->q_ptr->thread() == QThread::currentThread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; @@ -61,6 +64,7 @@ CCefClientDelegate::onBeforePopup(CefRefPtr& browser, }, c); } else { + // the new browser was created from non-javascript, we create a new browser instead cancel = true; QMetaObject::invokeMethod( pCefViewPrivate_, @@ -122,9 +126,31 @@ CCefClientDelegate::onAfterCreate(CefRefPtr& browser) bool CCefClientDelegate::doClose(CefRefPtr browser) { + qDebug() << "destroy browser from native"; + return false; } +bool +CCefClientDelegate::requestClose(CefRefPtr browser) +{ + qDebug() << "destroy browser request from web"; + + Qt::ConnectionType c = + pCefViewPrivate_->q_ptr->thread() == QThread::currentThread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; + + bool ignoreClose = false; + QMetaObject::invokeMethod( + pCefViewPrivate_, + [&]() { + // + ignoreClose = !(pCefViewPrivate_->requestCloseFromWeb(browser)); + }, + c); + + return ignoreClose; +} + void CCefClientDelegate::onBeforeClose(CefRefPtr browser) { diff --git a/src/details/CCefClientDelegate_LoadHandler.cpp b/src/details/CCefClientDelegate_LoadHandler.cpp index b9a16834..333e572a 100644 --- a/src/details/CCefClientDelegate_LoadHandler.cpp +++ b/src/details/CCefClientDelegate_LoadHandler.cpp @@ -11,7 +11,7 @@ CCefClientDelegate::loadingStateChanged(CefRefPtr& browser, if (!IsValidBrowser(browser)) return; - pCefViewPrivate_->q_ptr->loadingStateChanged(browser->GetIdentifier(), isLoading, canGoBack, canGoForward); + emit pCefViewPrivate_->q_ptr->loadingStateChanged(browser->GetIdentifier(), isLoading, canGoBack, canGoForward); } void @@ -20,7 +20,7 @@ CCefClientDelegate::loadStart(CefRefPtr& browser, CefRefPtrq_ptr->loadStart( + emit pCefViewPrivate_->q_ptr->loadStart( browser->GetIdentifier(), frame->GetIdentifier(), frame->IsMain(), transitionType); } @@ -30,7 +30,7 @@ CCefClientDelegate::loadEnd(CefRefPtr& browser, CefRefPtr& if (!IsValidBrowser(browser)) return; - pCefViewPrivate_->q_ptr->loadEnd(browser->GetIdentifier(), frame->GetIdentifier(), frame->IsMain(), httpStatusCode); + emit pCefViewPrivate_->q_ptr->loadEnd(browser->GetIdentifier(), frame->GetIdentifier(), frame->IsMain(), httpStatusCode); } void diff --git a/src/details/QCefViewPrivate.cpp b/src/details/QCefViewPrivate.cpp index 8d2dc331..a2e8351e 100644 --- a/src/details/QCefViewPrivate.cpp +++ b/src/details/QCefViewPrivate.cpp @@ -131,6 +131,8 @@ QCefViewPrivate::createCefBrowser(QCefView* view, const QString& url, const QCef void QCefViewPrivate::destroyCefBrowser() { + qDebug() << "destroy browser from native"; + if (!pClient_) return; @@ -226,7 +228,7 @@ QCefViewPrivate::onCefBrowserCreated(CefRefPtr browser, QWindow* win browser->GetHost()->CloseBrowser(true); return; } - + // adjust size/mask and attach to cef window ncw.qBrowserWindow_->applyMask(q_ptr->mask()); @@ -323,13 +325,21 @@ QCefViewPrivate::handleLoadError(CefRefPtr& browser, if (q->receivers(SIGNAL(loadError(int, qint64, bool, int, const QString&, const QString&))) > 0) { auto msg = QString::fromStdString(errorMsg); auto url = QString::fromStdString(failedUrl); - q->loadError(browser->GetIdentifier(), frame->GetIdentifier(), frame->IsMain(), errorCode, msg, url); + emit q->loadError(browser->GetIdentifier(), frame->GetIdentifier(), frame->IsMain(), errorCode, msg, url); return true; } return false; } +bool +QCefViewPrivate::requestCloseFromWeb(CefRefPtr& browser) +{ + Q_Q(QCefView); + + return q->onRequestCloseFromWeb(); +} + void QCefViewPrivate::onAppFocusChanged(QWidget* old, QWidget* now) { @@ -918,7 +928,7 @@ QCefViewPrivate::onViewWheelEvent(QWheelEvent* event) // angleDelta().y() provides the angle through which the common vertical mouse wheel was rotated since the previous // event. angleDelta().x() provides the angle through which the horizontal mouse wheel was rotated, if the mouse has - // a horizontal wheel; otherwise it stays at zero. + // a horizontal wheel; otherwise it stays at zero. pCefBrowser_->GetHost()->SendMouseWheelEvent( e, m & Qt::ShiftModifier ? d.x() : 0, m & Qt::ShiftModifier ? d.y() : d.y()); } diff --git a/src/details/QCefViewPrivate.h b/src/details/QCefViewPrivate.h index 6c79c7ff..6f333041 100644 --- a/src/details/QCefViewPrivate.h +++ b/src/details/QCefViewPrivate.h @@ -208,6 +208,8 @@ class QCefViewPrivate : public QObject const std::string& errorMsg, const std::string& failedUrl); + bool requestCloseFromWeb(CefRefPtr& browser); + public slots: void onAppFocusChanged(QWidget* old, QWidget* now);