5.7 KiB
Contributing
Contributions are welcome and encouraged.
To contribute fork this repository, make your changes, and open a pull request.
Setup
Clone with submodules — the shared widget library (dank-qml-common) is vendored at dank-qml-common/ and symlinked into quickshell/DankCommon:
git clone --recurse-submodules https://github.com/AvengeMedia/DankMaterialShell.git
# or, in an existing clone:
git submodule update --init
Install prek then activate pre-commit hooks:
prek install
Nix Development Shell
If you have Nix installed with flakes enabled, you can use the provided development shell which includes all necessary dependencies:
nix develop
This will provide:
- Go 1.25+ toolchain (go, gopls, delve, go-tools) and GNU Make
- Quickshell and required QML packages
- Properly configured QML2_IMPORT_PATH
The dev shell automatically creates the .qmlls.ini file in the quickshell/ directory.
Shared widgets (dank-qml-common)
Everything under quickshell/DankCommon/ (core widgets, the file browser, scroll physics, bundled fonts) is shared across the DMS suite and lives in the dank-qml-common submodule. It is a normal git worktree:
- Edit files under
dank-qml-common/(or through thequickshell/DankCommonsymlink — same files) and test in the running shell; hot reload works as usual. For isolated widget work, the library is its own runnable config with a gallery:qs -c dank-qml-common. - Commit and PR those changes in the
dank-qml-commonrepo:cd dank-qml-common && git switch -c my-change, push, open the PR there. - Once merged, bump the pointer here:
make update-common(updates the submodule and the nix flake input together), then commit alongside any DMS-side changes. If you only bump the submodule, CI syncsflake.lockto it automatically on master.
The submodule URL in .gitmodules is HTTPS so CI and anonymous clones keep working. To push over SSH instead of being prompted for credentials, add a push rewrite to your git config — fetches stay HTTPS, pushes use SSH:
git config --global url."git@github.com:AvengeMedia/".pushInsteadOf "https://github.com/AvengeMedia/"
Shared widgets read app-provided singletons (Theme, SettingsData, ...) through a documented contract — see the dank-qml-common README. If your change needs a new contract property, add it to the library's stub singletons in the same PR, then to quickshell/Common/ here when you bump.
Files in quickshell/Widgets/, quickshell/Common/, and quickshell/Modals/FileBrowser/ that moved to the library remain in place as thin wrappers, so import qs.Widgets, qs.Common, and qs.Modals.FileBrowser keep working for the shell and for plugins.
VSCode Setup
This is a monorepo, the easiest thing to do is to open an editor in either quickshell, core, or both depending on which part of the project you are working on.
QML (quickshell directory)
- Install the QML Extension
- Configure
ctrl+shift+p-> user preferences (json) with qmlls path
Note: Paths may vary by distribution. Below are examples for Arch Linux and Fedora.
Arch Linux:
{
"[qml]": {
"editor.defaultFormatter": "qt-project.qmlls",
"editor.formatOnSave": true
},
"qt-qml.doNotAskForQmllsDownload": true,
"qt-qml.qmlls.customExePath": "/usr/lib/qt6/bin/qmlls",
"qt-core.additionalQtPaths": [
{
"name": "Qt-6.x-linux-g++",
"path": "/usr/bin/qmake"
}
]
}
Fedora:
{
"[qml]": {
"editor.defaultFormatter": "qt-project.qmlls",
"editor.formatOnSave": true
},
"qt-qml.doNotAskForQmllsDownload": true,
"qt-qml.qmlls.customExePath": "/usr/bin/qmlls",
"qt-core.additionalQtPaths": [
{
"name": "Qt-6.x-Fedora-linux-g++",
"path": "/usr/bin/qmake6"
}
]
}
- Create empty
.qmlls.inifile inquickshell/directory
cd quickshell
touch .qmlls.ini
-
Restart dms to generate the
.qmlls.inifile -
Run
make lint-qmlfrom the repo root to lint QML entrypoints (requires the.qmlls.inigenerated above). The script needs the Qt 6qmllint; it checksqmllint6, Fedora'sqmllint-qt6,/usr/lib/qt6/bin/qmllint, thenqmllintinPATH. If your Qt 6 binary lives elsewhere, setQMLLINT=/path/to/qmllint. -
Make your changes, test, and open a pull request.
I18n/Localization
When adding user-facing strings, ensure they are wrapped in I18n.tr() with context, for example.
import qs.Common
Text {
text: I18n.tr("Hello World", "<This is context for the translators, example> Hello world greeting that appears on the lock screen")
}
Preferably, try to keep new terms to a minimum and re-use existing terms where possible. See quickshell/translations/en.json for the list of existing terms. (This isn't always possible obviously, but instead of using Auto-connect you would use Autoconnect since it's already translated)
Strings inside quickshell/DankCommon/ are owned by the dank-qml-common repo and synced through the DMS POEditor project, not this one — extraction here deliberately skips them. At runtime I18n merges both catalogs (app terms win), with the shared translations shipping inside the submodule at DankCommon/translations/poexports/.
GO (core directory)
- Install the Go Extension
- Ensure code is formatted with
make fmt - Add appropriate test coverage and ensure tests pass with
make test - Run
go mod tidy - Open pull request
Pull request
Include screenshots/video if applicable in your pull request if applicable, to visualize what your change is affecting.