#include "viewport.hxx" #include #include #include 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(QApplication::instance()); if (!app) throw std::runtime_error("not a GUI application (WTF?)"); auto* native = app->nativeInterface(); 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()); }