diff --git a/CMakeLists.txt b/CMakeLists.txt index 4902a83..abec58b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,5 +31,5 @@ find_package(Qt6 REQUIRED COMPONENTS ${QT_FPDEPS}) qt_standard_project_setup(REQUIRES 6.6) -add_subdirectory(src/wayland) add_subdirectory(src/core) +add_subdirectory(src/wayland) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 60d2b92..deb5612 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,5 +1,6 @@ qt_add_executable(quickshell main.cpp + plugin.cpp shell.cpp variants.cpp rootwrapper.cpp @@ -17,5 +18,3 @@ qt_add_executable(quickshell ) qt_add_qml_module(quickshell URI QuickShell) - -target_link_libraries(quickshell PRIVATE ${QT_DEPS} quickshell-waylandplugin) diff --git a/src/core/main.cpp b/src/core/main.cpp index 0fa915b..8d4a5e3 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -8,6 +8,7 @@ #include #include +#include "plugin.hpp" #include "rootwrapper.hpp" int main(int argc, char** argv) { @@ -38,6 +39,8 @@ int main(int argc, char** argv) { return -1; } + QuickshellPlugin::initPlugins(); + // Base window transparency appears to be additive. // Use a fully transparent window with a colored rect. QQuickWindow::setDefaultAlphaBuffer(true); diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp new file mode 100644 index 0000000..036fde2 --- /dev/null +++ b/src/core/plugin.cpp @@ -0,0 +1,35 @@ +#include "plugin.hpp" +#include + +#include // NOLINT (what??) + +// defined by moc. see below comment. +void qml_register_types_QuickShell(); // NOLINT + +static QVector plugins; // NOLINT + +void QuickshellPlugin::registerPlugin(QuickshellPlugin& plugin) { plugins.push_back(&plugin); } + +void QuickshellPlugin::initPlugins() { + plugins.erase( + std::remove_if( + plugins.begin(), + plugins.end(), + [](QuickshellPlugin* plugin) { return !plugin->applies(); } + ), + plugins.end() + ); + + for (QuickshellPlugin* plugin: plugins) { + plugin->init(); + } + + // This seems incredibly stupid but it appears qt will not register the module types + // if types are already defined for the module, meaning qmlRegisterType does not work + // unless the module types are already registered. + qml_register_types_QuickShell(); + + for (QuickshellPlugin* plugin: plugins) { + plugin->registerTypes(); + } +} diff --git a/src/core/plugin.hpp b/src/core/plugin.hpp new file mode 100644 index 0000000..92f1bc2 --- /dev/null +++ b/src/core/plugin.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +class QuickshellPlugin { +public: + QuickshellPlugin() = default; + virtual ~QuickshellPlugin() = default; + QuickshellPlugin(QuickshellPlugin&&) = delete; + QuickshellPlugin(const QuickshellPlugin&) = delete; + void operator=(QuickshellPlugin&&) = delete; + void operator=(const QuickshellPlugin&) = delete; + + virtual bool applies() { return true; } + virtual void init() {} + virtual void registerTypes() {} + + static void registerPlugin(QuickshellPlugin& plugin); + static void initPlugins(); +}; + +// NOLINTBEGIN +#define QS_REGISTER_PLUGIN(clazz) \ + [[gnu::constructor]] void qsInitPlugin() { \ + static clazz plugin; \ + QuickshellPlugin::registerPlugin(plugin); \ + } +// NOLINTEND diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 89cac23..e1f6a5d 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -5,6 +5,11 @@ qt_add_library(quickshell-wayland STATIC waylandlayershell.cpp ) +# required to make sure the constructor is linked +add_library(quickshell-wayland-init OBJECT init.cpp) + +target_link_libraries(quickshell PRIVATE ${QT_DEPS} quickshell-waylandplugin quickshell-wayland-init) + qt_add_qml_module(quickshell-wayland URI QuickShell.Wayland) find_package(PkgConfig REQUIRED) @@ -13,6 +18,7 @@ pkg_check_modules(wayland REQUIRED IMPORTED_TARGET wayland-client wayland-protoc find_package(Qt6 REQUIRED COMPONENTS WaylandClient) target_link_libraries(quickshell-wayland PRIVATE ${QT_DEPS} wayland-client) +target_link_libraries(quickshell-wayland-init PRIVATE ${QT_DEPS} wayland-client) # wayland protocols diff --git a/src/wayland/init.cpp b/src/wayland/init.cpp new file mode 100644 index 0000000..156c708 --- /dev/null +++ b/src/wayland/init.cpp @@ -0,0 +1,19 @@ +#include +#include + +#include "../core/plugin.hpp" +#include "waylandlayershell.hpp" + +namespace { + +class WaylandPlugin: public QuickshellPlugin { + bool applies() override { return QGuiApplication::platformName() == "wayland"; } + + void registerTypes() override { + qmlRegisterType("QuickShell", 1, 0, "PanelWindow"); + } +}; + +QS_REGISTER_PLUGIN(WaylandPlugin); + +} // namespace diff --git a/src/wayland/waylandlayershell.hpp b/src/wayland/waylandlayershell.hpp index 2aff223..90075bc 100644 --- a/src/wayland/waylandlayershell.hpp +++ b/src/wayland/waylandlayershell.hpp @@ -87,7 +87,6 @@ private: class WaylandPanelInterface: public PanelWindowInterface { Q_OBJECT; - QML_NAMED_ELEMENT(PanelWindow); // temp public: explicit WaylandPanelInterface(QObject* parent = nullptr);