qt-tracing/ui/src/viewport.cxx
2025-11-15 19:14:12 +03:00

75 lines
1.7 KiB
C++

#include "viewport.hxx"
#include <QApplication>
#include <QEvent>
#include <QGuiApplication>
Viewport::Viewport(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f) {
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
}
Viewport::~Viewport() = default;
void Viewport::setView(RedrawArgs new_args) {
args = new_args;
update();
}
QPaintEngine* Viewport::paintEngine() const {
return nullptr;
}
bool Viewport::event(QEvent* event) {
switch (event->type()) {
case QEvent::Type::WinIdChange:
recreate();
break;
default:
break;
}
return QWidget::event(event);
}
void Viewport::paintEvent(QPaintEvent* event) {
if (!core)
recreate();
core->redraw(args);
}
void Viewport::resizeEvent(QResizeEvent* event) {
if (!core)
return;
updateSize();
QWidget::resizeEvent(event);
}
void Viewport::recreate() try {
auto* app = qobject_cast<QGuiApplication*>(QApplication::instance());
if (!app)
throw std::runtime_error("not a GUI application (WTF?)");
auto* native = app->nativeInterface<QNativeInterface::QX11Application>();
if (!native)
throw std::runtime_error("X11 interface is not available");
auto* xcb_connection = native->connection();
std::uint32_t x11_window = winId();
fprintf(stderr, "connection %p, window %#08x\n", xcb_connection, x11_window);
core.reset();
core = BoxCore::from_xcb(xcb_connection, x11_window);
updateSize();
} catch (const std::exception& e) {
fprintf(stderr, "failed to recreate the viewport: %s", e.what());
}
void Viewport::updateSize() {
const QSize device_size = size() * devicePixelRatio();
core->configure(device_size.width(), device_size.height());
}