diff --git a/.clang-tidy b/.clang-tidy index da14682..c83ed8f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -20,7 +20,6 @@ Checks: > -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-vararg, - -cppcoreguidelines-pro-type-union-access, -cppcoreguidelines-use-enum-class, google-global-names-in-headers, google-readability-casting, diff --git a/BUILD.md b/BUILD.md index d624a06..29aecac 100644 --- a/BUILD.md +++ b/BUILD.md @@ -15,7 +15,7 @@ Please make this descriptive enough to identify your specific package, for examp - `Nixpkgs` - `Fedora COPR (errornointernet/quickshell)` -If you are forking quickshell, please change `CRASHREPORT_URL` to your own issue tracker. +Please leave at least symbol names attached to the binary for debugging purposes. ### QML Module dir Currently all QML modules are statically linked to quickshell, but this is where @@ -33,7 +33,6 @@ Quickshell has a set of base dependencies you will always need, names vary by di - `cmake` - `qt6base` - `qt6declarative` -- `libdrm` - `qtshadertools` (build-time) - `spirv-tools` (build-time) - `pkg-config` (build-time) @@ -68,13 +67,7 @@ Dependencies: `cpptrace` Note: `-DVENDOR_CPPTRACE=ON` can be set to vendor cpptrace using FetchContent. -When using FetchContent, `libunwind` is required, and `libdwarf` can be provided by the -package manager or fetched with FetchContent. - -*Please ensure binaries have usable symbols.* We do not necessarily need full debuginfo, but -leaving symbols in the binary is extremely helpful. You can check if symbols are useful -by sending a SIGSEGV to the process and ensuring symbols for the quickshell binary are present -in the trace. +When using FetchContent, `libunwind` is required, and `libdwarf` can be provided by the package manager or fetched with FetchContent. ### Jemalloc We recommend leaving Jemalloc enabled as it will mask memory fragmentation caused @@ -147,6 +140,7 @@ Enables streaming video from monitors and toplevel windows through various proto To disable: `-DSCREENCOPY=OFF` Dependencies: +- `libdrm` - `libgbm` - `vulkan-headers` (build-time) @@ -242,7 +236,7 @@ Only `ninja` builds are tested, but makefiles may work. #### Configuring the build ```sh -$ cmake -GNinja -B build -DCMAKE_BUILD_TYPE=Release [additional disable flags from above here] +$ cmake -GNinja -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo [additional disable flags from above here] ``` Note that features you do not supply dependencies for MUST be disabled with their associated flags diff --git a/CMakeLists.txt b/CMakeLists.txt index 1226342..d57e322 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(QS_BUILD_OPTIONS "") -# should be changed for forks -set(CRASHREPORT_URL "https://github.com/outfoxxed/quickshell/issues/new?template=crash2.yml" CACHE STRING "Bugreport URL") - function(boption VAR NAME DEFAULT) cmake_parse_arguments(PARSE_ARGV 3 arg "" "REQUIRES" "") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 73e7931..39fab13 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,40 +1,235 @@ -# Contributing +# Contributing / Development +Instructions for development setup and upstreaming patches. -Thank you for taking the time to contribute. -To ensure nobody's time is wasted, please follow the rules below. +If you just want to build or package quickshell see [BUILD.md](BUILD.md). -## Acceptable Code Contributions +## Development -- All changes submitted MUST be **fully understood by the submitter**. If you do not know why or how - your change works, do not submit it to be merged. You must be able to explain your reasoning - for every change. +Install the dependencies listed in [BUILD.md](BUILD.md). +You probably want all of them even if you don't use all of them +to ensure tests work correctly and avoid passing a bunch of configure +flags when you need to wipe the build directory. -- Changes MUST be submitted by a human who will be responsible for them. Changes submitted without - a human in the loop such as automated tooling and AI Agents are **strictly disallowed**. Accounts - responsible for such contribution attempts **will be banned**. +Quickshell also uses `just` for common development command aliases. -- Changes MUST respect Quickshell's license and the license of any source works. Changes including - code from any other works must disclose the source of the code, explain why it was used, and - ensure the license is compatible. +The dependencies are also available as a nix shell or nix flake which we recommend +using with nix-direnv. -- Changes must follow the guidelines outlined in [HACKING.md](HACKING.md) for style and substance. +Common aliases: +- `just configure [ [extra cmake args]]` (note that you must specify debug/release to specify extra args) +- `just build` - runs the build, configuring if not configured already. +- `just run [args]` - runs quickshell with the given arguments +- `just clean` - clean up build artifacts. `just clean build` is somewhat common. -- Changes must stand on their own as a unit. Do not make multiple unrelated changes in one PR. - Changes depending on prior merges should be marked as a draft. +### Formatting +All contributions should be formatted similarly to what already exists. +Group related functionality together. -## Acceptable Non-code Contributions +Run the formatter using `just fmt`. +If the results look stupid, fix the clang-format file if possible, +or disable clang-format in the affected area +using `// clang-format off` and `// clang-format on`. -- Bug and crash reports. You must follow the instructions in the issue templates and provide the - information requested. +#### Style preferences not caught by clang-format +These are flexible. You can ignore them if it looks or works better to +for one reason or another. -- Feature requests can be made via Issues. Please check to ensure nobody else has requested the same feature. +Use `auto` if the type of a variable can be deduced automatically, instead of +redeclaring the returned value's type. Additionally, auto should be used when a +constructor takes arguments. -- Do not make insubstantial or pointless changes. +```cpp +auto x = ; // ok +auto x = QString::number(3); // ok +QString x; // ok +QString x = "foo"; // ok +auto x = QString("foo"); // ok -- Changes to project rules / policy / governance will not be entertained, except from significant - long-term contributors. These changes should not be addressed through contribution channels. +auto x = QString(); // avoid +QString x(); // avoid +QString x("foo"); // avoid +``` -## Merge timelines +Put newlines around logical units of code, and after closing braces. If the +most reasonable logical unit of code takes only a single line, it should be +merged into the next single line logical unit if applicable. +```cpp +// multiple units +auto x = ; // unit 1 +auto y = ; // unit 2 -We handle work for the most part on a push basis. If your PR has been ignored for a while -and is still relevant please bump it. +auto x = ; // unit 1 +emit this->y(); // unit 2 + +auto x1 = ; // unit 1 +auto x2 = ; // unit 1 +auto x3 = ; // unit 1 + +auto y1 = ; // unit 2 +auto y2 = ; // unit 2 +auto y3 = ; // unit 2 + +// one unit +auto x = ; +if (x...) { + // ... +} + +// if more than one variable needs to be used then add a newline +auto x = ; +auto y = ; + +if (x && y) { + // ... +} +``` + +Class formatting: +```cpp +//! Doc comment summary +/// Doc comment body +class Foo: public QObject { + // The Q_OBJECT macro comes first. Macros are ; terminated. + Q_OBJECT; + QML_ELEMENT; + QML_CLASSINFO(...); + // Properties must stay on a single line or the doc generator won't be able to pick them up + Q_PROPERTY(...); + /// Doc comment + Q_PROPERTY(...); + /// Doc comment + Q_PROPERTY(...); + +public: + // Classes should have explicit constructors if they aren't intended to + // implicitly cast. The constructor can be inline in the header if it has no body. + explicit Foo(QObject* parent = nullptr): QObject(parent) {} + + // Instance functions if applicable. + static Foo* instance(); + + // Member functions unrelated to properties come next + void function(); + void function(); + void function(); + + // Then Q_INVOKABLEs + Q_INVOKABLE function(); + /// Doc comment + Q_INVOKABLE function(); + /// Doc comment + Q_INVOKABLE function(); + + // Then property related functions, in the order (bindable, getter, setter). + // Related functions may be included here as well. Function bodies may be inline + // if they are a single expression. There should be a newline between each + // property's methods. + [[nodiscard]] QBindable bindableFoo() { return &this->bFoo; } + [[nodiscard]] T foo() const { return this->foo; } + void setFoo(); + + [[nodiscard]] T bar() const { return this->foo; } + void setBar(); + +signals: + // Signals that are not property change related go first. + // Property change signals go in property definition order. + void asd(); + void asd2(); + void fooChanged(); + void barChanged(); + +public slots: + // generally Q_INVOKABLEs are preferred to public slots. + void slot(); + +private slots: + // ... + +private: + // statics, then functions, then fields + static const foo BAR; + static void foo(); + + void foo(); + void bar(); + + // property related members are prefixed with `m`. + QString mFoo; + QString bar; + + // Bindables go last and should be prefixed with `b`. + Q_OBJECT_BINDABLE_PROPERTY(Foo, QString, bFoo, &Foo::fooChanged); +}; +``` + +### Linter +All contributions should pass the linter. + +Note that running the linter requires disabling precompiled +headers and including the test codepaths: +```sh +$ just configure debug -DNO_PCH=ON -DBUILD_TESTING=ON +$ just lint-changed +``` + +If the linter is complaining about something that you think it should not, +please disable the lint in your MR and explain your reasoning if it isn't obvious. + +### Tests +If you feel like the feature you are working on is very complex or likely to break, +please write some tests. We will ask you to directly if you send in an MR for an +overly complex or breakable feature. + +At least all tests that passed before your changes should still be passing +by the time your contribution is ready. + +You can run the tests using `just test` but you must enable them first +using `-DBUILD_TESTING=ON`. + +### Documentation +Most of quickshell's documentation is automatically generated from the source code. +You should annotate `Q_PROPERTY`s and `Q_INVOKABLE`s with doc comments. Note that the parser +cannot handle random line breaks and will usually require you to disable clang-format if the +lines are too long. + +Before submitting an MR, if adding new features please make sure the documentation is generated +reasonably using the `quickshell-docs` repo. We recommend checking it out at `/docs` in this repo. + +Doc comments take the form `///` or `///!` (summary) and work with markdown. +You can reference other types using the `@@[Module.][Type.][member]` shorthand +where all parts are optional. If module or type are not specified they will +be inferred as the current module. Member can be a `property`, `function()` or `signal(s)`. +Look at existing code for how it works. + +Quickshell modules additionally have a `module.md` file which contains a summary, description, +and list of headers to scan for documentation. + +## Contributing + +### Commits +Please structure your commit messages as `scope[!]: commit` where +the scope is something like `core` or `service/mpris`. (pick what has been +used historically or what makes sense if new). Add `!` for changes that break +existing APIs or functionality. + +Commit descriptions should contain a summary of the changes if they are not +sufficiently addressed in the commit message. + +Please squash/rebase additions or edits to previous changes and follow the +commit style to keep the history easily searchable at a glance. +Depending on the change, it is often reasonable to squash it into just +a single commit. (If you do not follow this we will squash your changes +for you.) + +### Sending patches +You may contribute by submitting a pull request on github, asking for +an account on our git server, or emailing patches / git bundles +directly to `outfoxxed@outfoxxed.me`. + +### Getting help +If you're getting stuck, you can come talk to us in the +[quickshell-development matrix room](https://matrix.to/#/#quickshell-development:outfoxxed.me) +for help on implementation, conventions, etc. +Feel free to ask for advice early in your implementation if you are +unsure. diff --git a/HACKING.md b/HACKING.md deleted file mode 100644 index 69357f1..0000000 --- a/HACKING.md +++ /dev/null @@ -1,226 +0,0 @@ -## Development - -Install the dependencies listed in [BUILD.md](BUILD.md). -You probably want all of them even if you don't use all of them -to ensure tests work correctly and avoid passing a bunch of configure -flags when you need to wipe the build directory. - -The dependencies are also available as a nix shell or nix flake which we recommend -using with nix-direnv. - -Quickshell uses `just` for common development command aliases. - -Common aliases: -- `just configure [ [extra cmake args]]` (note that you must specify debug/release to specify extra args) -- `just build` - runs the build, configuring if not configured already. -- `just run [args]` - runs quickshell with the given arguments -- `just clean` - clean up build artifacts. `just clean build` is somewhat common. - -### Formatting -All contributions should be formatted similarly to what already exists. -Group related functionality together. - -Run the formatter using `just fmt`. -If the results look stupid, fix the clang-format file if possible, -or disable clang-format in the affected area -using `// clang-format off` and `// clang-format on`. - -#### Style preferences not caught by clang-format -These are flexible. You can ignore them if it looks or works better to -for one reason or another. - -Use `auto` if the type of a variable can be deduced automatically, instead of -redeclaring the returned value's type. Additionally, auto should be used when a -constructor takes arguments. - -```cpp -auto x = ; // ok -auto x = QString::number(3); // ok -QString x; // ok -QString x = "foo"; // ok -auto x = QString("foo"); // ok - -auto x = QString(); // avoid -QString x(); // avoid -QString x("foo"); // avoid -``` - -Put newlines around logical units of code, and after closing braces. If the -most reasonable logical unit of code takes only a single line, it should be -merged into the next single line logical unit if applicable. -```cpp -// multiple units -auto x = ; // unit 1 -auto y = ; // unit 2 - -auto x = ; // unit 1 -emit this->y(); // unit 2 - -auto x1 = ; // unit 1 -auto x2 = ; // unit 1 -auto x3 = ; // unit 1 - -auto y1 = ; // unit 2 -auto y2 = ; // unit 2 -auto y3 = ; // unit 2 - -// one unit -auto x = ; -if (x...) { - // ... -} - -// if more than one variable needs to be used then add a newline -auto x = ; -auto y = ; - -if (x && y) { - // ... -} -``` - -Class formatting: -```cpp -//! Doc comment summary -/// Doc comment body -class Foo: public QObject { - // The Q_OBJECT macro comes first. Macros are ; terminated. - Q_OBJECT; - QML_ELEMENT; - QML_CLASSINFO(...); - // Properties must stay on a single line or the doc generator won't be able to pick them up - Q_PROPERTY(...); - /// Doc comment - Q_PROPERTY(...); - /// Doc comment - Q_PROPERTY(...); - -public: - // Classes should have explicit constructors if they aren't intended to - // implicitly cast. The constructor can be inline in the header if it has no body. - explicit Foo(QObject* parent = nullptr): QObject(parent) {} - - // Instance functions if applicable. - static Foo* instance(); - - // Member functions unrelated to properties come next - void function(); - void function(); - void function(); - - // Then Q_INVOKABLEs - Q_INVOKABLE function(); - /// Doc comment - Q_INVOKABLE function(); - /// Doc comment - Q_INVOKABLE function(); - - // Then property related functions, in the order (bindable, getter, setter). - // Related functions may be included here as well. Function bodies may be inline - // if they are a single expression. There should be a newline between each - // property's methods. - [[nodiscard]] QBindable bindableFoo() { return &this->bFoo; } - [[nodiscard]] T foo() const { return this->foo; } - void setFoo(); - - [[nodiscard]] T bar() const { return this->foo; } - void setBar(); - -signals: - // Signals that are not property change related go first. - // Property change signals go in property definition order. - void asd(); - void asd2(); - void fooChanged(); - void barChanged(); - -public slots: - // generally Q_INVOKABLEs are preferred to public slots. - void slot(); - -private slots: - // ... - -private: - // statics, then functions, then fields - static const foo BAR; - static void foo(); - - void foo(); - void bar(); - - // property related members are prefixed with `m`. - QString mFoo; - QString bar; - - // Bindables go last and should be prefixed with `b`. - Q_OBJECT_BINDABLE_PROPERTY(Foo, QString, bFoo, &Foo::fooChanged); -}; -``` - -Use lowercase .h suffixed Qt headers, e.g. `` over ``. - -### Linter -All contributions should pass the linter. - -Note that running the linter requires disabling precompiled -headers and including the test codepaths: -```sh -$ just configure debug -DNO_PCH=ON -DBUILD_TESTING=ON -$ just lint-changed -``` - -If the linter is complaining about something that you think it should not, -please disable the lint in your MR and explain your reasoning if it isn't obvious. - -### Tests -If you feel like the feature you are working on is very complex or likely to break, -please write some tests. We will ask you to directly if you send in an MR for an -overly complex or breakable feature. - -At least all tests that passed before your changes should still be passing -by the time your contribution is ready. - -You can run the tests using `just test` but you must enable them first -using `-DBUILD_TESTING=ON`. - -### Documentation -Most of quickshell's documentation is automatically generated from the source code. -You should annotate `Q_PROPERTY`s and `Q_INVOKABLE`s with doc comments. Note that the parser -cannot handle random line breaks and will usually require you to disable clang-format if the -lines are too long. - -Make sure new files containing doc comments are added to a `module.md` file. -See existing module files for reference. - -Doc comments take the form `///` or `///!` (summary) and work with markdown. -You can reference other types using the `@@[Module.][Type.][member]` shorthand -where all parts are optional. If module or type are not specified they will -be inferred as the current module. Member can be a `property`, `function()` or `signal(s)`. -Look at existing code for how it works. - -If you have made a user visible change since the last tagged release, describe it in -[changelog/next.md](changelog/next.md). - -## Contributing - -### Commits -Please structure your commit messages as `scope: commit` where -the scope is something like `core` or `service/mpris`. (pick what has been -used historically or what makes sense if new). - -Commit descriptions should contain a summary of the changes if they are not -sufficiently addressed in the commit message. - -Please squash/rebase additions or edits to previous changes and follow the -commit style to keep the history easily searchable at a glance. -Depending on the change, it is often reasonable to squash it into just -a single commit. (If you do not follow this we will squash your changes -for you.) - -### Getting help -If you're getting stuck, you can come talk to us in the -[quickshell-development matrix room](https://matrix.to/#/#quickshell-development:outfoxxed.me) -for help on implementation, conventions, etc. There is also a bridged [discord server](https://discord.gg/UtZeT3xNyT). -Feel free to ask for advice early in your implementation if you are -unsure. diff --git a/README.md b/README.md index 365bdb5..4491d24 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,7 @@ This repo is hosted at: - https://github.com/quickshell-mirror/quickshell # Contributing / Development -- [HACKING.md](HACKING.md) - Development instructions and policy. -- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution policy. -- [BUILD.md](BUILD.md) - Packaging and build instructions. +See [CONTRIBUTING.md](CONTRIBUTING.md) for details. #### License diff --git a/changelog/next.md b/changelog/next.md index e9b297c..4883c93 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -34,9 +34,6 @@ set shell id. - PwNodeLinkTracker ignores sound level monitoring programs. - Replaced breakpad with cpptrace. - Reloads are prevented if no file content has changed. -- Added `QS_DISABLE_FILE_WATCHER` environment variable to disable file watching. -- Added `QS_DISABLE_CRASH_HANDLER` environment variable to disable crash handling. -- Added `QS_CRASHREPORT_URL` environment variable to allow overriding the crash reporter link. ## Bug Fixes @@ -64,4 +61,3 @@ set shell id. - `vulkan-headers` has been added as a build-time dependency for screencopy (Vulkan backend support). - `breakpad` has been replaced by `cpptrace`, which is far easier to package, and the `CRASH_REPORTER` cmake variable has been replaced with `CRASH_HANDLER` to stop this from being easy to ignore. - `DISTRIBUTOR_DEBUGINFO_AVAILABLE` was removed as it is no longer important without breakpad. -- `libdrm` is now unconditionally required as a direct dependency. diff --git a/default.nix b/default.nix index 749ef49..02b8659 100644 --- a/default.nix +++ b/default.nix @@ -76,7 +76,6 @@ buildInputs = [ qt6.qtbase qt6.qtdeclarative - libdrm cli11 ] ++ lib.optional withQtSvg qt6.qtsvg @@ -89,7 +88,7 @@ ++ lib.optional withJemalloc jemalloc ++ lib.optional (withWayland && lib.strings.compareVersions qt6.qtbase.version "6.10.0" == -1) qt6.qtwayland ++ lib.optionals withWayland [ wayland wayland-protocols ] - ++ lib.optionals (withWayland && libgbm != null) [ libgbm vulkan-headers ] + ++ lib.optionals (withWayland && libgbm != null) [ libdrm libgbm vulkan-headers ] ++ lib.optional withX11 libxcb ++ lib.optional withPam pam ++ lib.optional withPipewire pipewire diff --git a/src/build/build.hpp.in b/src/build/build.hpp.in index acc3c58..2ab2db2 100644 --- a/src/build/build.hpp.in +++ b/src/build/build.hpp.in @@ -13,5 +13,4 @@ #define COMPILER "@CMAKE_CXX_COMPILER_ID@ (@CMAKE_CXX_COMPILER_VERSION@)" #define COMPILE_FLAGS "@CMAKE_CXX_FLAGS@" #define BUILD_CONFIGURATION "@QS_BUILD_OPTIONS@" -#define CRASHREPORT_URL "@CRASHREPORT_URL@" // NOLINTEND diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4824965..f0ca8ef 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,4 +1,3 @@ -pkg_check_modules(libdrm REQUIRED IMPORTED_TARGET libdrm) qt_add_library(quickshell-core STATIC plugin.cpp shell.cpp @@ -42,7 +41,6 @@ qt_add_library(quickshell-core STATIC colorquantizer.cpp toolsupport.cpp streamreader.cpp - debuginfo.cpp ) qt_add_qml_module(quickshell-core @@ -55,7 +53,7 @@ qt_add_qml_module(quickshell-core install_qml_module(quickshell-core) -target_link_libraries(quickshell-core PRIVATE Qt::Quick Qt::QuickPrivate Qt::Widgets quickshell-build PkgConfig::libdrm) +target_link_libraries(quickshell-core PRIVATE Qt::Quick Qt::QuickPrivate Qt::Widgets quickshell-build) qs_module_pch(quickshell-core SET large) diff --git a/src/core/debuginfo.cpp b/src/core/debuginfo.cpp deleted file mode 100644 index f26c72e..0000000 --- a/src/core/debuginfo.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include "debuginfo.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "build.hpp" - -namespace qs::debuginfo { - -QString qsVersion() { - return QS_VERSION " (revision " GIT_REVISION ", distributed by " DISTRIBUTOR ")"; -} - -QString qtVersion() { return qVersion() % QStringLiteral(" (built against " QT_VERSION_STR ")"); } - -QString gpuInfo() { - auto deviceCount = drmGetDevices2(0, nullptr, 0); - if (deviceCount < 0) return "Failed to get DRM device count: " % QString::number(deviceCount); - auto* devices = new drmDevicePtr[deviceCount]; - auto devicesArrayGuard = qScopeGuard([&] { delete[] devices; }); - auto r = drmGetDevices2(0, devices, deviceCount); - if (deviceCount < 0) return "Failed to get DRM devices: " % QString::number(r); - auto devicesGuard = qScopeGuard([&] { - for (auto i = 0; i != deviceCount; ++i) drmFreeDevice(&devices[i]); // NOLINT - }); - - QString info; - auto stream = QTextStream(&info); - - for (auto i = 0; i != deviceCount; ++i) { - auto* device = devices[i]; // NOLINT - - int deviceNodeType = -1; - if (device->available_nodes & (1 << DRM_NODE_RENDER)) deviceNodeType = DRM_NODE_RENDER; - else if (device->available_nodes & (1 << DRM_NODE_PRIMARY)) deviceNodeType = DRM_NODE_PRIMARY; - - if (deviceNodeType == -1) continue; - - auto* deviceNode = device->nodes[DRM_NODE_RENDER]; // NOLINT - - auto driver = [&]() -> QString { - auto fd = open(deviceNode, O_RDWR | O_CLOEXEC); - if (fd == -1) return ""; - auto fdGuard = qScopeGuard([&] { close(fd); }); - auto* ver = drmGetVersion(fd); - if (!ver) return ""; - auto verGuard = qScopeGuard([&] { drmFreeVersion(ver); }); - - // clang-format off - return QString(ver->name) - % ' ' % QString::number(ver->version_major) - % '.' % QString::number(ver->version_minor) - % '.' % QString::number(ver->version_patchlevel) - % " (" % ver->desc % ')'; - // clang-format on - }(); - - QString product = "unknown"; - QString address = "unknown"; - - auto hex = [](int num, int pad) { return QString::number(num, 16).rightJustified(pad, '0'); }; - - switch (device->bustype) { - case DRM_BUS_PCI: { - auto* b = device->businfo.pci; - auto* d = device->deviceinfo.pci; - address = "PCI " % hex(b->bus, 2) % ':' % hex(b->dev, 2) % '.' % hex(b->func, 1); - product = hex(d->vendor_id, 4) % ':' % hex(d->device_id, 4); - } break; - case DRM_BUS_USB: { - auto* b = device->businfo.usb; - auto* d = device->deviceinfo.usb; - address = "USB " % QString::number(b->bus) % ':' % QString::number(b->dev); - product = hex(d->vendor, 4) % ':' % hex(d->product, 4); - } break; - default: break; - } - - stream << "GPU " << deviceNode << "\n Driver: " << driver << "\n Model: " << product - << "\n Address: " << address << '\n'; - } - - return info; -} - -QString systemInfo() { - QString info; - auto stream = QTextStream(&info); - - stream << gpuInfo() << '\n'; - - stream << "/etc/os-release:"; - auto osReleaseFile = QFile("/etc/os-release"); - if (osReleaseFile.open(QFile::ReadOnly)) { - stream << '\n' << osReleaseFile.readAll() << '\n'; - osReleaseFile.close(); - } else { - stream << "FAILED TO OPEN\n"; - } - - stream << "/etc/lsb-release:"; - auto lsbReleaseFile = QFile("/etc/lsb-release"); - if (lsbReleaseFile.open(QFile::ReadOnly)) { - stream << '\n' << lsbReleaseFile.readAll(); - lsbReleaseFile.close(); - } else { - stream << "FAILED TO OPEN\n"; - } - - return info; -} - -QString combinedInfo() { - QString info; - auto stream = QTextStream(&info); - - stream << "===== Version Information =====\n"; - stream << "Quickshell: " << qsVersion() << '\n'; - stream << "Qt: " << qtVersion() << '\n'; - - stream << "\n===== Build Information =====\n"; - stream << "Build Type: " << BUILD_TYPE << '\n'; - stream << "Compiler: " << COMPILER << '\n'; - stream << "Compile Flags: " << COMPILE_FLAGS << '\n'; - stream << "Configuration:\n" << BUILD_CONFIGURATION << '\n'; - - stream << "\n===== System Information =====\n"; - stream << systemInfo(); - - return info; -} - -} // namespace qs::debuginfo diff --git a/src/core/debuginfo.hpp b/src/core/debuginfo.hpp deleted file mode 100644 index cc13f97..0000000 --- a/src/core/debuginfo.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -namespace qs::debuginfo { - -QString qsVersion(); -QString qtVersion(); -QString gpuInfo(); -QString systemInfo(); -QString combinedInfo(); - -} // namespace qs::debuginfo diff --git a/src/core/qmlglobal.cpp b/src/core/qmlglobal.cpp index 35504f6..6c26609 100644 --- a/src/core/qmlglobal.cpp +++ b/src/core/qmlglobal.cpp @@ -60,9 +60,7 @@ void QuickshellSettings::setWorkingDirectory(QString workingDirectory) { // NOLI emit this->workingDirectoryChanged(); } -bool QuickshellSettings::watchFiles() const { - return this->mWatchFiles && qEnvironmentVariableIsEmpty("QS_DISABLE_FILE_WATCHER"); -} +bool QuickshellSettings::watchFiles() const { return this->mWatchFiles; } void QuickshellSettings::setWatchFiles(bool watchFiles) { if (watchFiles == this->mWatchFiles) return; diff --git a/src/crash/interface.cpp b/src/crash/interface.cpp index 6a370ce..a3422d3 100644 --- a/src/crash/interface.cpp +++ b/src/crash/interface.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -13,22 +12,11 @@ #include #include #include -#include #include #include #include "build.hpp" -namespace { -QString crashreportUrl() { - if (auto url = qEnvironmentVariable("QS_CRASHREPORT_URL"); !url.isEmpty()) { - return url; - } - - return CRASHREPORT_URL; -} -} // namespace - class ReportLabel: public QWidget { public: ReportLabel(const QString& label, const QString& content, QWidget* parent): QWidget(parent) { @@ -79,16 +67,22 @@ CrashReporterGui::CrashReporterGui(QString reportFolder, int pid) if (qtVersionMatches) { mainLayout->addWidget( - new QLabel("Please open a bug report for this issue on the issue tracker.") + new QLabel("Please open a bug report for this issue via github or email.") ); } else { mainLayout->addWidget(new QLabel( "Please rebuild Quickshell against the current Qt version.\n" - "If this does not solve the problem, please open a bug report on the issue tracker." + "If this does not solve the problem, please open a bug report via github or email." )); } - mainLayout->addWidget(new ReportLabel("Tracker:", crashreportUrl(), this)); + mainLayout->addWidget(new ReportLabel( + "Github:", + "https://github.com/quickshell-mirror/quickshell/issues/new?template=crash2.yml", + this + )); + + mainLayout->addWidget(new ReportLabel("Email:", "quickshell-bugs@outfoxxed.me", this)); auto* buttons = new QWidget(this); buttons->setMinimumWidth(900); @@ -118,5 +112,10 @@ void CrashReporterGui::openFolder() { QDesktopServices::openUrl(QUrl::fromLocalFile(this->reportFolder)); } -void CrashReporterGui::openReportUrl() { QDesktopServices::openUrl(QUrl(crashreportUrl())); } +void CrashReporterGui::openReportUrl() { + QDesktopServices::openUrl( + QUrl("https://github.com/outfoxxed/quickshell/issues/new?template=crash2.yml") + ); +} + void CrashReporterGui::cancel() { QApplication::quit(); } diff --git a/src/crash/main.cpp b/src/crash/main.cpp index 05927f2..c406ba6 100644 --- a/src/crash/main.cpp +++ b/src/crash/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -14,18 +15,19 @@ #include #include #include +#include #include #include #include #include -#include "../core/debuginfo.hpp" #include "../core/instanceinfo.hpp" #include "../core/logcat.hpp" #include "../core/logging.hpp" #include "../core/logging_p.hpp" #include "../core/paths.hpp" #include "../core/ringbuf.hpp" +#include "build.hpp" #include "interface.hpp" namespace { @@ -169,15 +171,41 @@ void recordCrashInfo(const QDir& crashDir, const InstanceInfo& instance) { qCCritical(logCrashReporter) << "Failed to open crash info file for writing."; } else { auto stream = QTextStream(&extraInfoFile); - stream << qs::debuginfo::combinedInfo(); + stream << "===== Build Information =====\n"; + stream << "Git Revision: " << GIT_REVISION << '\n'; + stream << "Buildtime Qt Version: " << QT_VERSION_STR << "\n"; + stream << "Build Type: " << BUILD_TYPE << '\n'; + stream << "Compiler: " << COMPILER << '\n'; + stream << "Complie Flags: " << COMPILE_FLAGS << "\n\n"; + stream << "Build configuration:\n" << BUILD_CONFIGURATION << "\n"; - stream << "\n===== Instance Information =====\n"; + stream << "\n===== Runtime Information =====\n"; + stream << "Runtime Qt Version: " << qVersion() << '\n'; stream << "Signal: " << strsignal(crashSignal) << " (" << crashSignal << ")\n"; // NOLINT stream << "Crashed process ID: " << crashProc << '\n'; stream << "Run ID: " << instance.instanceId << '\n'; stream << "Shell ID: " << instance.shellId << '\n'; stream << "Config Path: " << instance.configPath << '\n'; + stream << "\n===== System Information =====\n\n"; + stream << "/etc/os-release:"; + auto osReleaseFile = QFile("/etc/os-release"); + if (osReleaseFile.open(QFile::ReadOnly)) { + stream << '\n' << osReleaseFile.readAll() << '\n'; + osReleaseFile.close(); + } else { + stream << "FAILED TO OPEN\n"; + } + + stream << "/etc/lsb-release:"; + auto lsbReleaseFile = QFile("/etc/lsb-release"); + if (lsbReleaseFile.open(QFile::ReadOnly)) { + stream << '\n' << lsbReleaseFile.readAll(); + lsbReleaseFile.close(); + } else { + stream << "FAILED TO OPEN\n"; + } + stream << "\n===== Stacktrace =====\n"; if (stacktrace.empty()) { stream << "(no trace available)\n"; diff --git a/src/launch/command.cpp b/src/launch/command.cpp index 807eb24..151fc24 100644 --- a/src/launch/command.cpp +++ b/src/launch/command.cpp @@ -25,12 +25,12 @@ #include #include -#include "../core/debuginfo.hpp" #include "../core/instanceinfo.hpp" #include "../core/logging.hpp" #include "../core/paths.hpp" #include "../io/ipccomm.hpp" #include "../ipc/ipc.hpp" +#include "build.hpp" #include "launch_p.hpp" namespace qs::launch { @@ -519,10 +519,20 @@ int runCommand(int argc, char** argv, QCoreApplication* coreApplication) { } if (state.misc.printVersion) { - if (state.log.verbosity == 0) { - qCInfo(logBare).noquote() << "Quickshell" << qs::debuginfo::qsVersion(); - } else { - qCInfo(logBare).noquote() << qs::debuginfo::combinedInfo(); + qCInfo(logBare).noquote().nospace() << "quickshell " << QS_VERSION << ", revision " + << GIT_REVISION << ", distributed by: " << DISTRIBUTOR; + + if (state.log.verbosity > 1) { + qCInfo(logBare).noquote() << "\nBuildtime Qt Version:" << QT_VERSION_STR; + qCInfo(logBare).noquote() << "Runtime Qt Version:" << qVersion(); + qCInfo(logBare).noquote() << "Compiler:" << COMPILER; + qCInfo(logBare).noquote() << "Compile Flags:" << COMPILE_FLAGS; + } + + if (state.log.verbosity > 0) { + qCInfo(logBare).noquote() << "\nBuild Type:" << BUILD_TYPE; + qCInfo(logBare).noquote() << "Build configuration:"; + qCInfo(logBare).noquote().nospace() << BUILD_CONFIGURATION; } } else if (*state.subcommand.log) { return readLogFile(state); diff --git a/src/launch/launch.cpp b/src/launch/launch.cpp index 3a9a2a5..ee7ca64 100644 --- a/src/launch/launch.cpp +++ b/src/launch/launch.cpp @@ -138,11 +138,9 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio }; #if CRASH_HANDLER - if (qEnvironmentVariableIsSet("QS_DISABLE_CRASH_HANDLER")) { - qInfo() << "Crash handling disabled."; - } else { - crash::CrashHandler::init(); + crash::CrashHandler::init(); + { auto* log = LogManager::instance(); crash::CrashHandler::setRelaunchInfo({ .instance = InstanceInfo::CURRENT,