aboutsummaryrefslogtreecommitdiff
path: root/libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp')
-rw-r--r--libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp b/libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp
new file mode 100644
index 0000000..69ad4b8
--- /dev/null
+++ b/libs/plugin_python/src/pybind11-qt/pybind11_qt_sip.cpp
@@ -0,0 +1,105 @@
+#include "pybind11_qt/details/pybind11_qt_sip.h"
+
+#include <stdexcept>
+
+#include <QString>
+
+#include <sip.h>
+
+namespace py = pybind11;
+
+namespace pybind11::detail::qt {
+
+ const sipAPIDef* sipAPI()
+ {
+ std::string exception;
+ static const sipAPIDef* sipApi = nullptr;
+ if (sipApi == nullptr) {
+ PyImport_ImportModule("PyQt6.sip");
+
+ {
+ auto errorObj = PyErr_Occurred();
+ if (errorObj != NULL) {
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_NormalizeException(&type, &value, &traceback);
+ if (traceback != NULL) {
+ py::handle h_type(type);
+ py::handle h_val(value);
+ py::handle h_tb(traceback);
+ py::object tb(py::module_::import("traceback"));
+ py::object fmt_exp(tb.attr("format_exception"));
+ py::object exp_list(fmt_exp(h_type, h_val, h_tb));
+ py::object exp_str(py::str("\n").attr("join")(exp_list));
+ exception = exp_str.cast<std::string>();
+ }
+ PyErr_Restore(type, value, traceback);
+ throw std::runtime_error{"Failed to load SIP API: " + exception};
+ }
+ }
+
+ sipApi = (const sipAPIDef*)PyCapsule_Import("PyQt6.sip._C_API", 0);
+ if (sipApi == NULL) {
+ auto errorObj = PyErr_Occurred();
+ if (errorObj != NULL) {
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback);
+ PyErr_NormalizeException(&type, &value, &traceback);
+ if (traceback != NULL) {
+ py::handle h_type(type);
+ py::handle h_val(value);
+ py::handle h_tb(traceback);
+ py::object tb(py::module_::import("traceback"));
+ py::object fmt_exp(tb.attr("format_exception"));
+ py::object exp_list(fmt_exp(h_type, h_val, h_tb));
+ py::object exp_str(py::str("\n").attr("join")(exp_list));
+ exception = exp_str.cast<std::string>();
+ }
+ PyErr_Restore(type, value, traceback);
+ }
+ throw std::runtime_error{"Failed to load SIP API: " + exception};
+ }
+ }
+ return sipApi;
+ }
+
+ namespace sip {
+ const sipTypeDef* api_find_type(const char* type)
+ {
+ return sipAPI()->api_find_type(type);
+ }
+
+ int api_can_convert_to_type(PyObject* pyObj, const sipTypeDef* td, int flags)
+ {
+ return sipAPI()->api_can_convert_to_type(pyObj, td, flags);
+ }
+
+ void api_transfer_to(PyObject* self, PyObject* owner)
+ {
+ sipAPI()->api_transfer_to(self, owner);
+ }
+
+ void api_transfer_back(PyObject* self)
+ {
+ sipAPI()->api_transfer_back(self);
+ }
+
+ PyObject* api_convert_from_type(void* cpp, const sipTypeDef* td, PyObject*)
+ {
+ return sipAPI()->api_convert_from_type(cpp, td, 0);
+ }
+
+ void* extract_data(PyObject* ptr)
+ {
+ if (PyObject_TypeCheck(ptr, sipAPI()->api_simplewrapper_type)) {
+ return reinterpret_cast<sipSimpleWrapper*>(ptr)->data;
+ }
+ else if (PyObject_TypeCheck(ptr, sipAPI()->api_wrapper_type)) {
+ return reinterpret_cast<sipWrapper*>(ptr)->super.data;
+ }
+ return nullptr;
+ }
+
+ } // namespace sip
+
+} // namespace pybind11::detail::qt