Skip to content

Commit

Permalink
Fix macOS NCW
Browse files Browse the repository at this point in the history
  • Loading branch information
tishion authored and L-Super committed Sep 22, 2023
1 parent 96fcb27 commit 39e02fb
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 66 deletions.
4 changes: 3 additions & 1 deletion example/QCefViewTest/CefViewWidget.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "CefViewWidget.h"
#include "CefViewWidget.h"

#if defined(Q_OS_WIN)
#include <windows.h>
Expand All @@ -19,6 +19,8 @@
CefViewWidget::CefViewWidget(const QString url, const QCefSetting* setting, QWidget* parent /* = 0*/)
: QCefView(url, setting, parent)
{
setStyleSheet("background: blue;");

connect(this, &CefViewWidget::draggableRegionChanged, this, &CefViewWidget::onDraggableRegionChanged);
connect(this, &CefViewWidget::nativeBrowserCreated, this, &CefViewWidget::onNativeBrowserWindowCreated);
}
Expand Down
2 changes: 1 addition & 1 deletion example/QCefViewTest/MainWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "MainWindow.h"
#include "MainWindow.h"

#include <QCoreApplication>
#include <QDebug>
Expand Down
6 changes: 6 additions & 0 deletions example/QCefViewTest/MainWindow.ui
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="leftCefViewContainer" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(217, 183, 255)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_cefContainer">
<property name="spacing">
<number>0</number>
Expand All @@ -199,6 +202,9 @@
</layout>
</widget>
<widget class="QWidget" name="rightCefViewContainer" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(217, 183, 255)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_cefContainer_2">
<property name="spacing">
<number>0</number>
Expand Down
8 changes: 7 additions & 1 deletion example/QCefViewTest/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <QApplication>
#include <QApplication>
#include <QDir>

#include <QCefContext.h>

Expand Down Expand Up @@ -41,6 +42,11 @@ main(int argc, char* argv[])
config.addCommandLineSwitchWithValue("remote-allow-origins", "*");
// config.addCommandLineSwitchWithValue("disable-features", "BlinkGenPropertyTrees,TranslateUI,site-per-process");

#if defined(Q_OS_MACOS) && defined(QT_DEBUG)
// cef bugs on macos debug build
config.setCachePath(QDir::tempPath());
#endif

// create QCefContext instance with config,
// the lifecycle of cefContext must be the same as QApplication instance
QCefContext cefContext(&a, argc, argv, &config);
Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ source_group(
FILES ${QCefView_details_SRC_FILES}
)

if(USE_SANDBOX AND(OS_WINDOWS OR OS_MACOS))
add_definitions(-DCEF_USE_SANDBOX)
endif()

if(OS_WINDOWS)
file(GLOB_RECURSE QCefView_Windows_SRC_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/win/*.h"
Expand Down
9 changes: 6 additions & 3 deletions src/details/CCefClientDelegate_LifeSpanHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,16 @@ CCefClientDelegate::onAfterCreate(CefRefPtr<CefBrowser>& browser)

QWindow* w = nullptr;

if (!pCefViewPrivate_->isOSRModeEnabled() /*|| browser->IsPopup()*/) {
// create QWindow from native browser window handle
if (!pCefViewPrivate_->isOSRModeEnabled() && !browser->IsPopup()) {
// NCW mode and not pop-up browser
w = QWindow::fromWinId((WId)(browser->GetHost()->GetWindowHandle()));
}

Qt::ConnectionType c = Qt::DirectConnection;
if (pCefViewPrivate_->q_ptr->thread() != QThread::currentThread()) {
// change connection type
if (!pCefViewPrivate_->isOSRModeEnabled() /*|| browser->IsPopup()*/) {
if (!pCefViewPrivate_->isOSRModeEnabled()) {
// NCW mode
c = Qt::QueuedConnection;
} else {
// OSR mode
Expand All @@ -108,9 +109,11 @@ CCefClientDelegate::onAfterCreate(CefRefPtr<CefBrowser>& browser)
}

if (browser->IsPopup()) {
// pop-up window
QMetaObject::invokeMethod(
pCefViewPrivate_, [=]() { pCefViewPrivate_->onAfterCefPopupCreated(browser); }, c);
} else {
// new normal browser
QMetaObject::invokeMethod(
pCefViewPrivate_, [=]() { pCefViewPrivate_->onCefBrowserCreated(browser, w); }, c);
}
Expand Down
4 changes: 1 addition & 3 deletions src/details/QCefContextPrivate.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "QCefContextPrivate.h"
#include "QCefContextPrivate.h"

#pragma region qt_headers
#include <QThread>
Expand Down Expand Up @@ -178,11 +178,9 @@ QCefContextPrivate::onAboutToQuit()
}
}

#if defined(Q_OS_MACOS)
void
QCefContextPrivate::performCefLoopWork()
{
// process cef work
CefDoMessageLoopWork();
}
#endif
4 changes: 1 addition & 3 deletions src/details/QCefContextPrivate.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once

#pragma region std_headers
#include <atomic>
Expand Down Expand Up @@ -172,12 +172,10 @@ public slots:
/// </summary>
void onAboutToQuit();

#if defined(Q_OS_MACOS)
/// <summary>
///
/// </summary>
void performCefLoopWork();
#endif

protected:
/// <summary>
Expand Down
95 changes: 47 additions & 48 deletions src/details/QCefViewPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ QCefViewPrivate::destroyCefBrowser()
return;

if (!isOSRModeEnabled_) {
// remove from children, prevent from being destroyed
// remove from parent, prevent from being destroyed
ncw.qBrowserWidget_->setParent(nullptr);
ncw.qBrowserWidget_->deleteLater();
ncw.qBrowserWindow_->detachCefWindow();
}

Expand Down Expand Up @@ -214,38 +216,35 @@ QCefViewPrivate::onCefBrowserCreated(CefRefPtr<CefBrowser> browser, QWindow* win

qDebug() << "CEF Window Native ID:" << window->winId();

// adjust size and attach to cef window
ncw.qBrowserWindow_->resize(q_ptr->size());
ncw.qBrowserWindow_->attachCefWindow(window);

// create QWidget from cef browser widow, this will re-parent the CEF browser window
QWidget* browserWidget = QWidget::createWindowContainer(
ncw.qBrowserWindow_, q_ptr, Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);

Q_ASSERT_X(browserWidget, "QCefViewPrivateNCW::createBrowser", "Failed to create QWidget from cef browser window");
if (!browserWidget) {
// create widget for cef window
ncw.qBrowserWidget_ = ncw.qBrowserWindow_->attachCefWindow(window, q_ptr);
Q_ASSERT_X(ncw.qBrowserWidget_, //
"QCefViewPrivateNCW::createBrowser", //
"Failed to create QWidget from cef browser window");
if (!ncw.qBrowserWidget_) {
qWarning() << "Failed to create QWidget from cef browser window";
browser->GetHost()->CloseBrowser(true);
return;
}

// adjust size/mask and attach to cef window
ncw.qBrowserWindow_->applyMask(q_ptr->mask());

// capture the resource
ncw.qBrowserWidget_ = browserWidget;
// resize to eliminate flicker
ncw.qBrowserWidget_->resize(q_ptr->size());

// monitor the focus changed event globally
connect(qApp, &QApplication::focusChanged, this, &QCefViewPrivate::onAppFocusChanged);

// initialize the layout and add browser widget to the layout
QGridLayout* layout = new QGridLayout();
QGridLayout* layout = new QGridLayout(q_ptr);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(ncw.qBrowserWidget_);
q_ptr->setLayout(layout);

// update mask
if (ncw.qBrowserWindow_) {
ncw.qBrowserWindow_->setMask(q_ptr->mask());
}
// monitor the focus changed event globally
disconnect(this, SLOT(onAppFocusChanged(QWidget*, QWidget*)));
connect(qApp, //
SIGNAL(focusChanged(QWidget*, QWidget*)), //
this, //
SLOT(onAppFocusChanged(QWidget*, QWidget*)) //
);
}
}

Expand All @@ -259,8 +258,8 @@ QCefViewPrivate::onBeforeNewBrowserCreate(qint64 sourceFrameId,
{
Q_Q(QCefView);

// this is a fake popup browser, we just cancel it and then
// we create a new QCefView instance to replace the fake popup browser
// this is a fake pop-up browser, we just cancel it and then
// we create a new QCefView instance to replace the fake pop-up browser
q->onNewBrowser(sourceFrameId, //
targetUrl, //
targetFrameName, //
Expand Down Expand Up @@ -367,7 +366,7 @@ QCefViewPrivate::onViewScreenChanged(QScreen* screen)
} else {
Q_Q(QCefView);
if (ncw.qBrowserWindow_)
ncw.qBrowserWindow_->setMask(q->mask());
ncw.qBrowserWindow_->applyMask(q->mask());
}
}

Expand Down Expand Up @@ -482,15 +481,15 @@ QCefViewPrivate::onContextMenuDestroyed(QObject* obj)
void
QCefViewPrivate::onOsrUpdateViewFrame(const QImage& frame, const QRegion& region)
{
//#if defined(QT_DEBUG)
// qint64 elapsedMs = paintTimer_.restart();
// // qDebug() << "===== CEF view frame update since last frame:" << elapsedMs;
// if (elapsedMs >= 20)
// qDebug() << "===== CEF view frame update stutter detected:" << elapsedMs;
//
// QElapsedTimer updateDurationTimer;
// updateDurationTimer.start();
//#endif
// #if defined(QT_DEBUG)
// qint64 elapsedMs = paintTimer_.restart();
// // qDebug() << "===== CEF view frame update since last frame:" << elapsedMs;
// if (elapsedMs >= 20)
// qDebug() << "===== CEF view frame update stutter detected:" << elapsedMs;
//
// QElapsedTimer updateDurationTimer;
// updateDurationTimer.start();
// #endif

if (osr.qCefViewFrame_.size() != frame.size() || osr.transparentPaintingEnabled) {
// update full image
Expand All @@ -506,9 +505,9 @@ QCefViewPrivate::onOsrUpdateViewFrame(const QImage& frame, const QRegion& region
}
emit updateOsrFrame();

//#if defined(QT_DEBUG)
// qDebug() << "===== CEF frame update duration:" << elapsedMs;
//#endif
// #if defined(QT_DEBUG)
// qDebug() << "===== CEF frame update duration:" << elapsedMs;
// #endif
}

void
Expand Down Expand Up @@ -791,7 +790,7 @@ QCefViewPrivate::onViewSizeChanged(const QSize& size, const QSize& oldSize)
} else {
Q_Q(QCefView);
if (ncw.qBrowserWindow_)
ncw.qBrowserWindow_->setMask(q->mask());
ncw.qBrowserWindow_->applyMask(q->mask());
}
}

Expand All @@ -803,16 +802,16 @@ QCefViewPrivate::onViewKeyEvent(QKeyEvent* event)
if (!pCefBrowser_)
return;

//#if defined(QT_DEBUG)
// qDebug("==== onViewKeyEvent:key=%d, nativeVirtualKey=0x%02x, nativeScanCode=0x%02x, modifiers=0x%08x, "
// "nativeModifiers=0x%08x, text=%s",
// (Qt::Key)(event->key()),
// event->nativeVirtualKey(),
// event->nativeScanCode(),
// (quint32)(event->modifiers()),
// event->nativeModifiers(),
// event->text().toStdString().c_str());
//#endif
// #if defined(QT_DEBUG)
// qDebug("==== onViewKeyEvent:key=%d, nativeVirtualKey=0x%02x, nativeScanCode=0x%02x, modifiers=0x%08x, "
// "nativeModifiers=0x%08x, text=%s",
// (Qt::Key)(event->key()),
// event->nativeVirtualKey(),
// event->nativeScanCode(),
// (quint32)(event->modifiers()),
// event->nativeModifiers(),
// event->text().toStdString().c_str());
// #endif

CefKeyEvent e;
MapQKeyEventToCefKeyEvent(event, e);
Expand Down
43 changes: 38 additions & 5 deletions src/details/QCefWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,62 @@
QCefWindow::QCefWindow()
: QWindow()
{
setFlag(Qt::FramelessWindowHint);
this->setFlag(Qt::FramelessWindowHint);
}

QCefWindow::~QCefWindow()
{
qDebug() << this << "is being destructed";
}

void
QCefWindow::attachCefWindow(QWindow* win)
QWidget*
QCefWindow::attachCefWindow(QWindow* win, QWidget* parent)
{
detachCefWindow();
// keep cef window
cefWindow_ = win;
cefWindow_->setParent(this);

#if defined(Q_OS_MACOS)
// for macOS we just create the widget with CEF window,
// and current QCefWindow is useless
QWindow* widgetSourceWindow = cefWindow_;
#else
// for Windows & Linux we create the widget with
// current QCefWindow
win->setParent(this);
QWindow* widgetSourceWindow = this;
#endif

return QWidget::createWindowContainer(widgetSourceWindow, //
parent, //
Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
}

void
QCefWindow::detachCefWindow()
{
if (cefWindow_) {
#if defined(Q_OS_MACOS)

#else
cefWindow_->hide();
cefWindow_->setParent(nullptr);
#endif
cefWindow_ = nullptr;
}
}

void
QCefWindow::applyMask(const QRegion& region)
{
#if defined(Q_OS_MACOS)
if (cefWindow_) {
cefWindow_->setMask(region);
}
#else
this->setMask(region);
#endif
}

QWindow*
QCefWindow::cefWindow()
{
Expand All @@ -40,8 +70,11 @@ QCefWindow::cefWindow()
void
QCefWindow::resizeEvent(QResizeEvent* e)
{
#if defined(Q_OS_MACOS)
#else
if (cefWindow_) {
cefWindow_->resize(e->size());
}
#endif
QWindow::resizeEvent(e);
}
Loading

0 comments on commit 39e02fb

Please sign in to comment.