PR Guidelines
PR Requirements
- Clean, not hacky code
- Described changes and why they were there
- Following the style (see below)
Code Style
Please read this if you are submitting a PR, in order to minimize the amount of style nits received, and save the time for the maintainers.
Before you submit
Make sure you ran clang-format: clang-format -i src/**/*{cpp,hpp}
Check if your changes don’t violate clang-tidy
. Usually this is built into your IDE.
Clang-format
This is non-negotiable. Your code must be formatted.
Clang-tidy
Clang-tidy violations are not hard requirements, but please try to minimize them, and only ignore them if it’s absolutely necessary.
I’ve tweaked it so that in 99% of cases you absolutely should fix it.
Other
Some stuff clang-tidy / clang-format won’t catch:
- No uninitialized primitives (int, float, double, size_t, etc.)
- No short ifs. if your if/else body contains 1 line (not 1 statement) do not put
{}
around it. - The above rule does not apply to loops / etc
- Consider adding a
;
inside of empty function bodies - Whenever you’re initializing vectors arrays or maps with a lot of elements, add a
,
after the last element to make the styling nicer - Consider forward-declaring things in headers if possible instead of including. Speeds up compile times.
- no
using namespace std;
, andusing namespace (anything else)
is only allowed in source files, not headers. - prefer guards rather than nesting.
if(!valid) return;
is much better thanif (valid) { /* a billion things */ }
Naming conventions
Although we’ve used hungarian notation in the past, we are moving away from it.
The current, and new code, should use camelCase
with an m_
prefix if the variable is a member of a class. (not a struct)
Additionally:
- classes have a prefix of
C
:CMyClass
- structs have a prefix of
S
:SMyStruct
- namespaces have a prefix of
N
:NMyNamespace
- interfaces have a prefix of
I
:IMyInterface
- global pointers for singletons have a prefix of
g_
:g_someManager
- constant variables are in CAPS:
const auto MYVARIABLE = ...
General code requirements
No raw pointers
This is a simple rule - don’t use raw pointers (e.g. CMyClass*
) unless absolutely necessary. You have UP
, SP
and WP
at your disposal.
These are unique, shared and weak pointers respectively.
No malloc
Unless absolutely necessary, do not use malloc / free. You will forget to free the memory.
Avoid dubious cleanups
If a function is a C-style allocator, e.g. some_c_call_make_new()
, it will likely require a some_c_call_free()
. In these cases, either:
- wrap the thing in a C++ class, or
- if used only within one function, use a
CScopeGuard
to always free it when the function exits.
Use the STL
Generally, use the STL instead of trying to reinvent the wheel.
Use hyprutils
Hyprutils provides a lot of utilities that are well-suited for hyprland (and other hypr* projects) specifically. Use them.
No absolute includes from /src
Imagine this scenario:
src/
a/
a.hpp
b/
b.hpp
If you are in a.hpp
and want to include b.hpp
, you must use ../b/b.hpp
, and cannot use b/b.hpp
. The latter will break plugins.
One exception you might notice in the code is absolute paths from the root are allowed, e.g. protocols/some-protocol.hpp
.
Test your changes
Run and test your changes to make sure they work!