< Summary

Information
Class: /home/runner/work/TauriQt/TauriQt/tauri-runtime-qt/src/qt_window.cpp
Assembly: Default
File(s): /home/runner/work/TauriQt/TauriQt/tauri-runtime-qt/src/qt_window.cpp
Line coverage
34%
Covered lines: 174
Uncovered lines: 335
Coverable lines: 509
Total lines: 716
Line coverage: 34.1%
Branch coverage
20%
Covered branches: 46
Total branches: 230
Branch coverage: 20%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

/home/runner/work/TauriQt/TauriQt/tauri-runtime-qt/src/qt_window.cpp

#LineLine coverage
 1// SPDX-FileCopyrightText: 2026 Alper Çelik
 2// SPDX-License-Identifier: MIT OR Apache-2.0
 3
 4//! Top-level window registry for the Qt runtime.
 5//!
 6//! Owns one `QWidget` per Tauri window, keyed by the stable handle handed to
 7//! Rust. All entry points run on the Qt GUI thread (the runtime dispatchers
 8//! call them from the thread that owns the window) and each one tolerates an
 9//! unknown handle.
 10
 11#include "qt_window.hpp"
 12
 13// cxx-generated header of the bridge in `src/qt.rs`; declares the
 14// `qt_on_window_event` callback with the linkage cxx expects, so it must not
 15// be hand-declared here.
 16#include "tauri-runtime-qt/src/qt.rs.h"
 17#include "tauri-runtime-qt/src/bridge/window.rs.h"
 18
 19#include <QtCore/QCoreApplication>
 20#include <QtCore/QPointer>
 21#include <QtCore/QSize>
 22#include <QtCore/QString>
 23#include <QtCore/qnumeric.h>
 24#include <QtGui/QColor>
 25#include <QtGui/QCloseEvent>
 26#include <QtGui/QGuiApplication>
 27#include <QtGui/QIcon>
 28#include <QtGui/QImage>
 29#include <QtGui/QMoveEvent>
 30#include <QtGui/QPalette>
 31#include <QtGui/QPixmap>
 32#include <QtGui/QResizeEvent>
 33#include <QtGui/QScreen>
 34#include <QtGui/QStyleHints>
 35#include <QtGui/QWindow>
 36#include <QtWidgets/QApplication>
 37#include <QtWidgets/QLayout>
 38#include <QtWidgets/QStyle>
 39#include <QtWidgets/QVBoxLayout>
 40#include <QtWidgets/QWidget>
 41
 42#include <cstddef>
 43#include <cstdint>
 44#include <string>
 45#include <unordered_map>
 46
 47namespace {
 48
 49// Event kinds of `qt_on_window_event` (see qt_window.hpp / src/qt.rs).
 50constexpr std::int32_t kEventCloseRequested = 0;
 51constexpr std::int32_t kEventFocused = 1;
 52constexpr std::int32_t kEventUnfocused = 2;
 53constexpr std::int32_t kEventResized = 3;
 54constexpr std::int32_t kEventMoved = 4;
 55
 56/// Top-level window widget. Reports the window events tauri-runtime's
 57/// `on_window_event` needs; it deliberately has no `Q_OBJECT` (build.rs does
 58/// not run moc, so no meta-object code may be required by this class).
 59class TauriWindow final : public QWidget {
 60public:
 61    TauriWindow(std::uint64_t id, const QString& label)
 2162        : QWidget(nullptr, Qt::Window), m_id(id) {
 2163        setObjectName(label);
 2164    }
 65
 66    /// Connects the QWindow-level notifications. Must run on the GUI thread.
 67    /// The platform QWindow is recreated when the window flags change (e.g.
 68    /// `qt_window_set_decorations`), so this re-connects whenever the native
 69    /// handle differs from the one we are attached to; safe to call often.
 2170    void attach() {
 2171        QWindow* handle = windowHandle();
 2172        if (handle == nullptr) {
 073            winId();  // force the native window so windowHandle() is valid
 074            handle = windowHandle();
 075            if (handle == nullptr) {
 076                return;  // still not native: retry on the next attach()
 077            }
 078        }
 2179        if (handle == m_attached_handle) {
 080            return;  // already connected to this platform window
 081        }
 2182        m_attached_handle = handle;  // QPointer: nulls out if the handle dies
 2183        m_ready = true;              // the handle is known to Rust from here on
 84        // `QWindow::activeChanged` carries no argument (Qt 6): read the state.
 2185        QObject::connect(handle, &QWindow::activeChanged, this, [this]() {
 086            if (QWindow* current = m_attached_handle) {
 087                emit_event(current->isActive() ? kEventFocused : kEventUnfocused, std::string());
 088            }
 089        });
 2190    }
 91
 92    /// Enters or leaves fullscreen. Leaving restores the maximized state the
 93    /// window had before it went fullscreen (`showNormal()` would drop it).
 94    /// The request is mirrored because a window manager confirms
 95    /// `Qt::WindowFullScreen` asynchronously — `isFullScreen()` can still lag
 96    /// behind — while `qt_window_is_fullscreen` keeps reporting Qt's view.
 97    /// The state of a hidden window is applied when it is next shown.
 4298    void set_fullscreen(bool fullscreen) {
 4299        if (fullscreen) {
 21100            if (m_fullscreen_requested && isFullScreen()) {
 0101                return;
 0102            }
 21103            m_pre_fullscreen_state = windowState() & (Qt::WindowMinimized | Qt::WindowMaximized);
 21104            m_fullscreen_requested = true;
 21105            setWindowState(windowState() | Qt::WindowFullScreen);
 21106        } else {
 21107            if (!m_fullscreen_requested && !isFullScreen()) {
 0108                return;
 0109            }
 21110            m_fullscreen_requested = false;
 21111            setWindowState((windowState() & ~Qt::WindowFullScreen) | m_pre_fullscreen_state);
 21112        }
 42113        if (isVisible()) {
 42114            show();  // apply the new state immediately
 42115        }
 42116    }
 117
 118    /// Qt exposes neither a resizable getter nor a setter; the size hints are
 119    /// what a window manager honours, so disabling resizing pins the window to
 120    /// its current size (`minimumSize == maximumSize`) and remembers the
 121    /// constraints in force so that re-enabling restores them.
 0122    void set_resizable(bool resizable) {
 0123        if (resizable) {
 0124            if (!m_pinned_by_resizable) {
 0125                return;
 0126            }
 0127            setMinimumSize(m_pinned_min);
 0128            setMaximumSize(m_pinned_max);
 0129            m_pinned_by_resizable = false;
 0130        } else {
 0131            if (m_pinned_by_resizable) {
 0132                return;
 0133            }
 0134            m_pinned_min = minimumSize();
 0135            m_pinned_max = maximumSize();
 0136            m_pinned_by_resizable = true;
 0137            setMinimumSize(size());
 0138            setMaximumSize(size());
 0139        }
 0140    }
 141
 142    /// A window is resizable exactly while its size hints do not pin both
 143    /// dimensions to one value (`set_resizable(false)` installs
 144    /// `minimumSize == maximumSize`; explicit equal constraints pin it too).
 42145    bool is_resizable() const {
 42146        return minimumSize() != maximumSize();
 42147    }
 148
 149    /// Sets the minimum size from logical pixels. While resizing is disabled
 150    /// the remembered pre-pin constraint is kept coherent, so that
 151    /// `set_resizable(true)` restores what the caller last asked for.
 0152    void set_min_size(double width, double height) {
 0153        const QSize size(qRound(width), qRound(height));
 0154        if (m_pinned_by_resizable) {
 0155            m_pinned_min = size;
 0156        }
 0157        setMinimumSize(size);
 0158    }
 159
 160    /// Sets the maximum size from logical pixels.
 0161    void set_max_size(double width, double height) {
 0162        const QSize size(qRound(width), qRound(height));
 0163        if (m_pinned_by_resizable) {
 0164            m_pinned_max = size;
 0165        }
 0166        setMaximumSize(size);
 0167    }
 168
 169protected:
 0170    void closeEvent(QCloseEvent* event) override {
 171        // The Rust side observes the request and may re-issue `close` after
 172        // cleaning up; the callback is void, so the default handler runs.
 0173        emit_event(kEventCloseRequested, std::string());
 0174        QWidget::closeEvent(event);
 0175    }
 176
 21177    void resizeEvent(QResizeEvent* event) override {
 21178        QWidget::resizeEvent(event);
 21179        emit_event(kEventResized, std::to_string(event->size().width()) + "x" +
 21180                                     std::to_string(event->size().height()));
 21181    }
 182
 21183    void moveEvent(QMoveEvent* event) override {
 21184        QWidget::moveEvent(event);
 21185        emit_event(kEventMoved, std::to_string(event->pos().x()) + "," +
 21186                                    std::to_string(event->pos().y()));
 21187    }
 188
 189private:
 42190    void emit_event(std::int32_t kind, const std::string& payload) {
 42191        if (!m_ready) {
 42192            return;  // handle not returned to Rust yet
 42193        }
 0194        qt_on_window_event(m_id, kind, rust::Str(payload));
 0195    }
 196
 197    std::uint64_t m_id;
 198    QPointer<QWindow> m_attached_handle;
 199    bool m_ready = false;
 200    /// Window state to restore when leaving fullscreen.
 201    Qt::WindowStates m_pre_fullscreen_state = Qt::WindowNoState;
 202    /// The last fullscreen state requested (the window manager confirms the
 203    /// change asynchronously, so `windowState()` alone is not enough).
 204    bool m_fullscreen_requested = false;
 205    /// Size constraints in force before `set_resizable(false)` pinned them.
 206    QSize m_pinned_min{0, 0};
 207    QSize m_pinned_max{QWIDGETSIZE_MAX, QWIDGETSIZE_MAX};
 208    bool m_pinned_by_resizable = false;
 209};
 210
 2835211std::unordered_map<std::uint64_t, TauriWindow*>& registry() {
 2835212    static std::unordered_map<std::uint64_t, TauriWindow*> windows;
 2835213    return windows;
 2835214}
 215
 216std::uint64_t next_handle = 0;
 217
 218/// Lookup that never throws and never returns a dangling widget.
 1407219TauriWindow* find_window(std::uint64_t id) {
 1407220    if (id == 0) {
 0221        return nullptr;
 0222    }
 1407223    const auto it = registry().find(id);
 1407224    return it == registry().end() ? nullptr : it->second;
 1407225}
 226
 227/// Applies new window flags, restoring visibility: changing a window's flags
 228/// re-parents the widget (hiding it) and may replace the platform `QWindow`,
 229/// so the event connections are re-established as well.
 0230void apply_window_flags(TauriWindow* window, Qt::WindowFlags flags) {
 0231    if (flags == window->windowFlags()) {
 0232        return;  // a no-op flag change would needlessly hide and re-show it
 0233    }
 0234    const bool was_visible = window->isVisible();
 0235    window->setWindowFlags(flags);
 0236    if (was_visible) {
 0237        window->show();
 0238    }
 0239    window->attach();
 0240}
 241
 242/// tauri's `ResizeDirection` numbering (as mapped by `lib.rs`) to Qt edges.
 0243Qt::Edges edges_for_direction(std::int32_t direction) {
 0244    switch (direction) {
 0245        case 1:  // East
 0246            return Qt::RightEdge;
 0247        case 2:  // North
 0248            return Qt::TopEdge;
 0249        case 3:  // NorthEast
 0250            return Qt::TopEdge | Qt::RightEdge;
 0251        case 4:  // NorthWest
 0252            return Qt::TopEdge | Qt::LeftEdge;
 0253        case 5:  // South
 0254            return Qt::BottomEdge;
 0255        case 6:  // SouthEast
 0256            return Qt::BottomEdge | Qt::RightEdge;
 0257        case 7:  // SouthWest
 0258            return Qt::BottomEdge | Qt::LeftEdge;
 0259        case 8:  // West
 0260            return Qt::LeftEdge;
 0261        default:
 0262            return Qt::Edges();  // unknown: no direction
 0263    }
 0264}
 265
 266/// UTF-8 view of a QString for the Rust side.
 42267rust::String to_rust_string(const QString& text) {
 42268    const QByteArray utf8 = text.toUtf8();
 42269    return rust::String(utf8.constData(), static_cast<std::size_t>(utf8.size()));
 42270}
 271
 272}  // namespace
 273
 274uint64_t qt_window_create(rust::Str label, rust::Str title, int width, int height, bool visible,
 21275                          bool decorations) {
 21276    if (QCoreApplication::instance() == nullptr) {
 0277        return 0;  // a QWidget must not be constructed before the QApplication
 0278    }
 279
 21280    const std::uint64_t id = ++next_handle;
 21281    auto* window = new TauriWindow(id, QString::fromUtf8(label.data(), static_cast<int>(label.size())));
 21282    window->setWindowTitle(QString::fromUtf8(title.data(), static_cast<int>(title.size())));
 21283    if (width > 0 && height > 0) {
 21284        window->resize(width, height);
 21285    }
 21286    if (!decorations) {
 0287        window->setWindowFlag(Qt::FramelessWindowHint, true);
 0288    }
 289
 21290    registry().emplace(id, window);
 291
 21292    if (visible) {
 21293        window->show();
 21294    }
 21295    window->attach();
 21296    return id;
 21297}
 298
 0299void qt_window_show(uint64_t id) {
 0300    if (TauriWindow* window = find_window(id)) {
 0301        window->show();  // focus/raise are separate tauri calls (set_focus)
 0302        window->attach();
 0303    }
 0304}
 305
 0306void qt_window_hide(uint64_t id) {
 0307    if (TauriWindow* window = find_window(id)) {
 0308        window->hide();
 0309    }
 0310}
 311
 0312void qt_window_close(uint64_t id) {
 0313    if (TauriWindow* window = find_window(id)) {
 0314        window->close();  // delivers closeEvent -> kind 0, then hides
 0315    }
 0316}
 317
 21318void qt_window_set_title(uint64_t id, rust::Str title) {
 21319    if (TauriWindow* window = find_window(id)) {
 21320        window->setWindowTitle(QString::fromUtf8(title.data(), static_cast<int>(title.size())));
 21321    }
 21322}
 323
 0324void qt_window_set_size(uint64_t id, int width, int height) {
 0325    if (TauriWindow* window = find_window(id); window != nullptr && width > 0 && height > 0) {
 0326        window->resize(width, height);
 0327    }
 0328}
 329
 0330void qt_window_center(uint64_t id) {
 0331    TauriWindow* window = find_window(id);
 0332    if (window == nullptr) {
 0333        return;
 0334    }
 335
 0336    QScreen* screen = nullptr;
 0337    if (QWindow* handle = window->windowHandle()) {
 0338        screen = handle->screen();
 0339    }
 0340    if (screen == nullptr) {
 0341        screen = QGuiApplication::screenAt(window->frameGeometry().center());
 0342    }
 0343    if (screen == nullptr) {
 0344        screen = QGuiApplication::primaryScreen();
 0345    }
 0346    if (screen == nullptr) {
 0347        return;
 0348    }
 349
 0350    const QRect target = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, window->size(),
 0351                                             screen->availableGeometry());
 0352    window->move(target.topLeft());
 0353}
 354
 0355void qt_window_set_decorations(uint64_t id, bool decorations) {
 0356    TauriWindow* window = find_window(id);
 0357    if (window == nullptr) {
 0358        return;
 0359    }
 360
 0361    Qt::WindowFlags flags = window->windowFlags();
 0362    flags.setFlag(Qt::FramelessWindowHint, !decorations);
 0363    apply_window_flags(window, flags);
 0364}
 365
 0366void qt_window_set_maximized(uint64_t id, bool maximized) {
 0367    TauriWindow* window = find_window(id);
 0368    if (window == nullptr) {
 0369        return;
 0370    }
 371
 0372    const Qt::WindowStates state = window->windowState();
 0373    window->setWindowState(maximized ? (state | Qt::WindowMaximized) : (state & ~Qt::WindowMaximized));
 0374}
 375
 42376bool qt_window_is_visible(uint64_t id) {
 42377    TauriWindow* window = find_window(id);
 42378    return window != nullptr && window->isVisible();
 42379}
 380
 210381double qt_window_scale_factor(uint64_t id) {
 210382    TauriWindow* window = find_window(id);
 210383    if (window == nullptr) {
 0384        return 1.0;
 0385    }
 210386    if (QWindow* handle = window->windowHandle()) {
 210387        return handle->devicePixelRatio();  // correct under Wayland fractional scaling
 210388    }
 0389    return window->devicePixelRatioF();
 210390}
 391
 21392uint64_t qt_window_winid(uint64_t id) {
 21393    TauriWindow* window = find_window(id);
 21394    if (window == nullptr) {
 0395        return 0;
 0396    }
 21397    return static_cast<std::uint64_t>(window->winId());
 21398}
 399
 21400void qt_window_attach_webview(uint64_t window_id, uint64_t webview_native_id) {
 21401    TauriWindow* window = find_window(window_id);
 21402    if (window == nullptr || webview_native_id == 0) {
 0403        return;
 0404    }
 405
 406    // The webview agent hands us its QWebEngineView as an opaque pointer; the
 407    // widget fills the window's client area, so it is added to a zero-margin
 408    // layout that keeps it in sync with every resize.
 21409    auto* view = reinterpret_cast<QWidget*>(static_cast<quintptr>(webview_native_id));
 21410    if (view == nullptr) {
 0411        return;
 0412    }
 413
 21414    view->setParent(window);
 21415    QLayout* layout = window->layout();
 21416    if (layout == nullptr) {
 21417        auto* box = new QVBoxLayout(window);
 21418        box->setContentsMargins(0, 0, 0, 0);
 21419        box->setSpacing(0);
 21420        layout = box;
 21421    }
 21422    layout->addWidget(view);
 21423    view->show();
 21424}
 425
 426// ---- window worker: registry and platform ----
 427
 546428bool qt_window_alive(uint64_t id) {
 546429    return find_window(id) != nullptr;
 546430}
 431
 0432rust::String qt_window_platform() {
 0433    return to_rust_string(QGuiApplication::platformName());
 0434}
 435
 436// ---- geometry (Qt device-independent pixels) ----
 437
 42438QtWindowSize qt_window_inner_size(uint64_t id) {
 42439    TauriWindow* window = find_window(id);
 42440    if (window == nullptr) {
 0441        return {0.0, 0.0};
 0442    }
 42443    const QSize size = window->size();  // client area, excluding frame
 42444    return {static_cast<double>(size.width()), static_cast<double>(size.height())};
 42445}
 446
 42447QtWindowSize qt_window_outer_size(uint64_t id) {
 42448    TauriWindow* window = find_window(id);
 42449    if (window == nullptr) {
 0450        return {0.0, 0.0};
 0451    }
 42452    const QSize size = window->frameGeometry().size();
 42453    return {static_cast<double>(size.width()), static_cast<double>(size.height())};
 42454}
 455
 42456QtWindowPoint qt_window_inner_position(uint64_t id) {
 42457    TauriWindow* window = find_window(id);
 42458    if (window == nullptr) {
 0459        return {0.0, 0.0};
 0460    }
 42461    const QPoint origin = window->mapToGlobal(QPoint(0, 0));
 42462    return {static_cast<double>(origin.x()), static_cast<double>(origin.y())};
 42463}
 464
 42465QtWindowPoint qt_window_outer_position(uint64_t id) {
 42466    TauriWindow* window = find_window(id);
 42467    if (window == nullptr) {
 0468        return {0.0, 0.0};
 0469    }
 42470    const QPoint origin = window->frameGeometry().topLeft();
 42471    return {static_cast<double>(origin.x()), static_cast<double>(origin.y())};
 42472}
 473
 474// ---- state ----
 475
 42476rust::String qt_window_title(uint64_t id) {
 42477    TauriWindow* window = find_window(id);
 42478    if (window == nullptr) {
 0479        return rust::String();
 0480    }
 42481    return to_rust_string(window->windowTitle());
 42482}
 483
 0484int32_t qt_window_theme(uint64_t id) {
 0485    if (find_window(id) == nullptr) {
 0486        return 0;
 0487    }
 488    // 6.5+: the platform's colour scheme; `Unknown` means it does not report one.
 0489    switch (QGuiApplication::styleHints()->colorScheme()) {
 0490        case Qt::ColorScheme::Light:
 0491            return 1;
 0492        case Qt::ColorScheme::Dark:
 0493            return 2;
 0494        case Qt::ColorScheme::Unknown:
 0495        default:
 0496            return 0;
 0497    }
 0498}
 499
 42500bool qt_window_is_fullscreen(uint64_t id) {
 42501    TauriWindow* window = find_window(id);
 42502    return window != nullptr && window->isFullScreen();
 42503}
 504
 42505bool qt_window_is_minimized(uint64_t id) {
 42506    TauriWindow* window = find_window(id);
 42507    return window != nullptr && window->isMinimized();
 42508}
 509
 42510bool qt_window_is_maximized(uint64_t id) {
 42511    TauriWindow* window = find_window(id);
 42512    return window != nullptr && window->isMaximized();
 42513}
 514
 42515bool qt_window_is_focused(uint64_t id) {
 42516    TauriWindow* window = find_window(id);
 42517    return window != nullptr && window->isActiveWindow();
 42518}
 519
 42520bool qt_window_is_decorated(uint64_t id) {
 42521    TauriWindow* window = find_window(id);
 42522    return window != nullptr && !window->windowFlags().testFlag(Qt::FramelessWindowHint);
 42523}
 524
 42525bool qt_window_is_resizable(uint64_t id) {
 42526    TauriWindow* window = find_window(id);
 42527    return window != nullptr && window->is_resizable();
 42528}
 529
 0530bool qt_window_is_enabled(uint64_t id) {
 0531    TauriWindow* window = find_window(id);
 0532    return window != nullptr && window->isEnabled();
 0533}
 534
 42535bool qt_window_is_always_on_top(uint64_t id) {
 42536    TauriWindow* window = find_window(id);
 537    // The hint Qt hands the window manager. Wayland compositors never honour
 538    // it, and `qt_window_set_always_on_top` refuses to set it there, so the
 539    // flag reports the truth on both platforms.
 42540    return window != nullptr && window->windowFlags().testFlag(Qt::WindowStaysOnTopHint);
 42541}
 542
 0543bool qt_window_is_maximizable(uint64_t id) {
 0544    TauriWindow* window = find_window(id);
 0545    return window != nullptr && window->windowFlags().testFlag(Qt::WindowMaximizeButtonHint);
 0546}
 547
 0548bool qt_window_is_minimizable(uint64_t id) {
 0549    TauriWindow* window = find_window(id);
 0550    return window != nullptr && window->windowFlags().testFlag(Qt::WindowMinimizeButtonHint);
 0551}
 552
 0553bool qt_window_is_closable(uint64_t id) {
 0554    TauriWindow* window = find_window(id);
 0555    return window != nullptr && window->windowFlags().testFlag(Qt::WindowCloseButtonHint);
 0556}
 557
 558// ---- setters ----
 559
 42560void qt_window_set_fullscreen(uint64_t id, bool fullscreen) {
 42561    if (TauriWindow* window = find_window(id)) {
 42562        window->set_fullscreen(fullscreen);
 42563    }
 42564}
 565
 0566void qt_window_minimize(uint64_t id) {
 0567    if (TauriWindow* window = find_window(id)) {
 0568        window->showMinimized();
 0569    }
 0570}
 571
 0572void qt_window_unminimize(uint64_t id) {
 0573    TauriWindow* window = find_window(id);
 0574    if (window == nullptr) {
 0575        return;
 0576    }
 0577    window->setWindowState(window->windowState() & ~Qt::WindowMinimized);
 578    // Best effort: a Wayland compositor decides whether activation happens.
 0579    window->activateWindow();
 0580}
 581
 0582void qt_window_set_min_size(uint64_t id, double width, double height) {
 0583    if (TauriWindow* window = find_window(id)) {
 0584        window->set_min_size(width, height);
 0585    }
 0586}
 587
 0588void qt_window_set_max_size(uint64_t id, double width, double height) {
 0589    if (TauriWindow* window = find_window(id)) {
 0590        window->set_max_size(width, height);
 0591    }
 0592}
 593
 594bool qt_window_set_icon(uint64_t id, rust::Slice<const uint8_t> rgba, uint32_t width,
 0595                        uint32_t height) {
 0596    TauriWindow* window = find_window(id);
 0597    if (window == nullptr) {
 0598        return false;
 0599    }
 0600    const std::size_t expected =
 0601        static_cast<std::size_t>(width) * static_cast<std::size_t>(height) * 4u;
 0602    if (width == 0 || height == 0 || rgba.size() != expected) {
 0603        return false;
 0604    }
 605    // The QImage is a view onto the Rust buffer, so `QPixmap::fromImage` must
 606    // happen inside this call (it converts/copies into an owned pixmap).
 0607    const QImage image(rgba.data(), static_cast<int>(width), static_cast<int>(height),
 0608                       QImage::Format_RGBA8888);
 0609    window->setWindowIcon(QIcon(QPixmap::fromImage(image)));
 0610    return true;
 0611}
 612
 0613void qt_window_set_focus(uint64_t id) {
 0614    TauriWindow* window = find_window(id);
 0615    if (window == nullptr) {
 0616        return;
 0617    }
 618    // Both calls are activation requests: a Wayland compositor may refuse one
 619    // that did not follow user input, and Qt has no way to report that back.
 0620    window->activateWindow();
 0621    window->raise();
 0622}
 623
 0624void qt_window_set_resizable(uint64_t id, bool resizable) {
 0625    if (TauriWindow* window = find_window(id)) {
 0626        window->set_resizable(resizable);
 0627    }
 0628}
 629
 0630void qt_window_set_enabled(uint64_t id, bool enabled) {
 0631    if (TauriWindow* window = find_window(id)) {
 0632        window->setEnabled(enabled);
 0633    }
 0634}
 635
 0636void qt_window_set_always_on_top(uint64_t id, bool on_top) {
 0637    TauriWindow* window = find_window(id);
 0638    if (window == nullptr) {
 0639        return;
 0640    }
 0641    Qt::WindowFlags flags = window->windowFlags();
 0642    flags.setFlag(Qt::WindowStaysOnTopHint, on_top);
 0643    if (on_top) {
 644        // The two stacking hints contradict each other; keep them exclusive.
 0645        flags.setFlag(Qt::WindowStaysOnBottomHint, false);
 0646    }
 0647    apply_window_flags(window, flags);
 0648}
 649
 0650void qt_window_set_always_on_bottom(uint64_t id, bool on_bottom) {
 0651    TauriWindow* window = find_window(id);
 0652    if (window == nullptr) {
 0653        return;
 0654    }
 0655    Qt::WindowFlags flags = window->windowFlags();
 0656    flags.setFlag(Qt::WindowStaysOnBottomHint, on_bottom);
 0657    if (on_bottom) {
 0658        flags.setFlag(Qt::WindowStaysOnTopHint, false);
 0659    }
 0660    apply_window_flags(window, flags);
 0661}
 662
 0663void qt_window_set_background_color(uint64_t id, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
 0664    TauriWindow* window = find_window(id);
 0665    if (window == nullptr) {
 0666        return;
 0667    }
 0668    QPalette palette = window->palette();
 0669    palette.setColor(QPalette::Window, QColor(r, g, b, a));
 0670    window->setPalette(palette);
 0671    window->setAutoFillBackground(true);
 0672}
 673
 0674void qt_window_reset_background_color(uint64_t id) {
 0675    TauriWindow* window = find_window(id);
 0676    if (window == nullptr) {
 0677        return;
 0678    }
 0679    window->setPalette(QApplication::palette());
 0680    window->setAutoFillBackground(false);
 0681}
 682
 0683void qt_window_set_position(uint64_t id, int x, int y) {
 0684    if (TauriWindow* window = find_window(id)) {
 685        // For a top-level widget `move` is the frame position on the desktop.
 0686        window->move(x, y);
 0687    }
 0688}
 689
 0690bool qt_window_start_dragging(uint64_t id) {
 0691    TauriWindow* window = find_window(id);
 0692    if (window == nullptr) {
 0693        return false;
 0694    }
 0695    QWindow* handle = window->windowHandle();
 0696    if (handle == nullptr) {
 0697        return false;
 0698    }
 0699    return handle->startSystemMove();
 0700}
 701
 0702bool qt_window_start_resize_dragging(uint64_t id, int32_t direction) {
 0703    TauriWindow* window = find_window(id);
 0704    if (window == nullptr) {
 0705        return false;
 0706    }
 0707    QWindow* handle = window->windowHandle();
 0708    if (handle == nullptr) {
 0709        return false;
 0710    }
 0711    const Qt::Edges edges = edges_for_direction(direction);
 0712    if (edges == Qt::Edges()) {
 0713        return false;  // unknown direction: nothing to drag from
 0714    }
 0715    return handle->startSystemResize(edges);
 0716}

Methods/Properties

qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindowC2EmRK7QString
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow6attachEv
qt_window.cpp:_ZZN12_GLOBAL__N_111TauriWindow6attachEvENKUlvE_clEv
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow14set_fullscreenEb
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow13set_resizableEb
qt_window.cpp:_ZNK12_GLOBAL__N_111TauriWindow12is_resizableEv
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow12set_min_sizeEdd
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow12set_max_sizeEdd
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow10closeEventEP11QCloseEvent
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow11resizeEventEP12QResizeEvent
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow9moveEventEP10QMoveEvent
qt_window.cpp:_ZN12_GLOBAL__N_111TauriWindow10emit_eventEiRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
qt_window.cpp:_ZN12_GLOBAL__N_18registryEv
qt_window.cpp:_ZN12_GLOBAL__N_111find_windowEm
qt_window.cpp:_ZN12_GLOBAL__N_118apply_window_flagsEPNS_11TauriWindowE6QFlagsIN2Qt10WindowTypeEE
qt_window.cpp:_ZN12_GLOBAL__N_119edges_for_directionEi
qt_window.cpp:_ZN12_GLOBAL__N_114to_rust_stringERK7QString
_Z16qt_window_createN4rust10cxxbridge13StrES1_iibb
_Z14qt_window_showm
_Z14qt_window_hidem
_Z15qt_window_closem
_Z19qt_window_set_titlemN4rust10cxxbridge13StrE
_Z18qt_window_set_sizemii
_Z16qt_window_centerm
_Z25qt_window_set_decorationsmb
_Z23qt_window_set_maximizedmb
_Z20qt_window_is_visiblem
_Z22qt_window_scale_factorm
_Z15qt_window_winidm
_Z24qt_window_attach_webviewmm
_Z15qt_window_alivem
_Z18qt_window_platformv
_Z20qt_window_inner_sizem
_Z20qt_window_outer_sizem
_Z24qt_window_inner_positionm
_Z24qt_window_outer_positionm
_Z15qt_window_titlem
_Z15qt_window_themem
_Z23qt_window_is_fullscreenm
_Z22qt_window_is_minimizedm
_Z22qt_window_is_maximizedm
_Z20qt_window_is_focusedm
_Z22qt_window_is_decoratedm
_Z22qt_window_is_resizablem
_Z20qt_window_is_enabledm
_Z26qt_window_is_always_on_topm
_Z24qt_window_is_maximizablem
_Z24qt_window_is_minimizablem
_Z21qt_window_is_closablem
_Z24qt_window_set_fullscreenmb
_Z18qt_window_minimizem
_Z20qt_window_unminimizem
_Z22qt_window_set_min_sizemdd
_Z22qt_window_set_max_sizemdd
_Z18qt_window_set_iconmN4rust10cxxbridge15SliceIKhEEjj
_Z19qt_window_set_focusm
_Z23qt_window_set_resizablemb
_Z21qt_window_set_enabledmb
_Z27qt_window_set_always_on_topmb
_Z30qt_window_set_always_on_bottommb
_Z30qt_window_set_background_colormhhhh
_Z32qt_window_reset_background_colorm
_Z22qt_window_set_positionmii
_Z24qt_window_start_draggingm
_Z31qt_window_start_resize_draggingmi