aboutsummaryrefslogtreecommitdiffstats
path: root/CONTRIBUTING.md
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-10-06 11:52:17 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2018-10-06 11:52:28 -0400
commit85961f63bfe922831011f75860b3acde3d890a9f (patch)
treea6544fad6ee8fd081382a29fb683b10c59decf17 /CONTRIBUTING.md
parentMerge pull request #2693 from RyanDwyer/move-sticky-in-seat (diff)
downloadsway-85961f63bfe922831011f75860b3acde3d890a9f.tar.gz
sway-85961f63bfe922831011f75860b3acde3d890a9f.tar.zst
sway-85961f63bfe922831011f75860b3acde3d890a9f.zip
Update CONTRIBUTING.md
Diffstat (limited to 'CONTRIBUTING.md')
-rw-r--r--CONTRIBUTING.md363
1 files changed, 188 insertions, 175 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f450563a..a5a5111f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,30 +1,12 @@
1# Contributing to sway 1# Contributing to sway
2 2
3Contributing just involves sending a pull request. You will probably be more 3Contributing just involves sending a pull request. You will probably be more
4successful with your contribution if you visit the [IRC 4successful with your contribution if you visit
5channel](http://webchat.freenode.net/?channels=sway-devel&uio=d4) upfront and discuss 5[#sway-devel](https://webchat.freenode.net/?channels=sway-devel) on
6your plans. 6irc.freenode.net upfront and discuss your plans.
7 7
8## Release Cycle 8Note: rules are made to be broken. Adjust or ignore any/all of these as you see
9 9fit, but be prepared to justify it to your peers.
10The master branch of sway is always working towards becoming the next release.
11That release will go through each of these three stages:
12
13**In development**: during this time the release lives in the master branch and
14is considered unstable. All pull requests merged during this time will land in
15the release. Only developers are encouraged to run this version.
16
17**Release candidate**: at some point (usually when development is fairly quiet),
18SirCmpwn will announce an upcoming release candidate, often 2 weeks in
19advance. When the two weeks are up, a branch is cut (i.e. 0.8-rc1) and from
20that point only bugfixes land in this branch. Each week, if bugfixes landed
21during the week, a new RC is cut. During the RC phase, more adventurous users
22are encouraged to upgrade and start looking for and reporting bugs (especially
23in new features).
24
25**Stable release**: when no substantial changes are merged into an RC for one
26week, it's released as a new stable version of sway. At this point, all users
27are encouraged to upgrade.
28 10
29## Pull Requests 11## Pull Requests
30 12
@@ -33,34 +15,44 @@ don't, however, allow me to make a suggestion: feature branches pulled from
33upstream. Try this: 15upstream. Try this:
34 16
351. Fork sway 171. Fork sway
362. Clone your fork 182. `git clone https://github.com/username/sway && cd sway`
373. git remote add upstream git://github.com/swaywm/sway.git 193. `git remote add upstream https://github.com/swaywm/sway`
38 20
39You only need to do this once. You're never going to use your fork's master 21You only need to do this once. You're never going to use your fork's master
40branch. Instead, when you start working on a feature, do this: 22branch. Instead, when you start working on a feature, do this:
41 23
421. git fetch upstream 241. `git fetch upstream`
432. git checkout -b add-so-and-so-feature upstream/master 252. `git checkout -b add-so-and-so-feature upstream/master`
443. work 263. Add and commit your changes
454. git push -u origin add-so-and-so-feature 274. `git push -u origin add-so-and-so-feature`
465. Make pull request from your feature branch 285. Make a pull request from your feature branch
29
30When you submit your pull request, your commit log should do most of the talking
31when it comes to describing your changes and their motivation. In addition to
32this, your pull request's comments will ideally include a test plan that the
33reviewers can use to (1) demonstrate the problem on master, if applicable and
34(2) verify that the problem no longer exists with your changes applied (or that
35your new features work correctly). Document all of the edge cases you're aware
36of so we can adequately test them - then verify the test plan yourself before
37submitting.
47 38
48## Commit Messages 39## Commit Messages
49 40
50Please strive to write good commit messages. Here's some guidelines to follow: 41Please strive to write good commit messages. Here's some guidelines to follow:
51 42
52The first line should be limited to 50 characters and should be a sentence that 43The first line should be limited to 50 characters and should be a sentence that
53completes the thought [When applied, this commit will...] "Implement cmd_move" 44completes the thought [When applied, this commit will...] *"Implement
54or "Fix #742" or "Improve performance of arrange_windows on ARM" or similar. 45cmd_move"* or *"Fix #742"* or *"Improve performance of arrange_windows on ARM"*
46or similar.
55 47
56The subsequent lines should be seperated from the subject line by a single 48The subsequent lines should be separated from the subject line by a single
57blank line, and include optional details. In this you can give justification 49blank line, and include optional details. In this you can give justification
58for the change, [reference Github 50for the change, [reference Github
59issues](https://help.github.com/articles/closing-issues-via-commit-messages/), 51issues](https://help.github.com/articles/closing-issues-via-commit-messages/),
60or explain some of the subtler details of your patch. This is important because 52or explain some of the subtler details of your patch. This is important because
61when someone finds a line of code they don't understand later, they can use the 53when someone finds a line of code they don't understand later, they can use the
62`git blame` command to find out what the author was thinking when they wrote 54`git blame` command to find out what the author was thinking when they wrote
63it. It's also easier to review your pull requests if they're seperated into 55it. It's also easier to review your pull requests if they're separated into
64logical commits that have good commit messages and justify themselves in the 56logical commits that have good commit messages and justify themselves in the
65extended commit description. 57extended commit description.
66 58
@@ -68,157 +60,178 @@ As a good rule of thumb, anything you might put into the pull request
68description on Github is probably fair game for going into the extended commit 60description on Github is probably fair game for going into the extended commit
69message as well. 61message as well.
70 62
71## Coding Style 63See [here](https://chris.beams.io/posts/git-commit/) for more details.
72 64
73Sway is written in C. The style guidelines is [kernel 65## Code Review
74style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but all braces go 66
75on the same line (*"but K&R says so!" is a silly way of justifying something*). 67When your changes are submitted for review, one or more core committers will
76Some points to note: 68look over them. Smaller changes might be merged with little fanfare, but larger
77 69changes will typically see review from several people. Be prepared to receive
78* Do not use typedefs unless you have a good reason 70some feedback - you may be asked to make changes to your work. Our code review
79* Do not use macros unless you have a *really* good reason 71process is:
80* Align `case` with `switch` 72
81* Tabs, not spaces 731. **Triage** the pull request. Do the commit messages make sense? Is a test
82* `char *pointer` - note position of `*` 74 plan necessary and/or present? Add anyone as reviewers that you think should
83* Use logging with reckless abandon 75 be there (using the relevant GitHub feature, if you have the permissions, or
84* Always include braces for if/for/while/etc, even for one-liners 76 with an @mention if necessary).
85 772. **Review** the code. Look for code style violations, naming convention
86An example of well formatted code: 78 violations, buffer overflows, memory leaks, logic errors, non-portable code
87 79 (including GNU-isms), etc. For significant changes to the public API, loop in
88```C 80 a couple more people for discussion.
89#include <stdio.h> 813. **Execute** the test plan, if present.
90#include <stdlib.h> 824. **Merge** the pull request when all reviewers approve.
91#include "log.h" 835. **File** follow-up tickets if appropriate.
92#include "example.h" 84
93 85## Style Reference
94struct foobar { 86
95 char *foo; 87Sway is written in C with a style similar to the [kernel
96 int bar; 88style](https://www.kernel.org/doc/Documentation/process/coding-style.rst), but
97 long baz; 89with a few notable differences.
98}; // Do not typedef without a good reason 90
99 91Try to keep your code conforming to C11 and POSIX as much as possible, and do
100int main(int argc, const char **argv) { 92not use GNU extensions.
101 if (argc != 4) { 93
102 sway_abort("Do not run this program manually. See man 5 sway and look for output options."); 94### Brackets
95
96Brackets always go on the same line, including in functions.
97Always include brackets for if/while/for, even if it's a single statement.
98```c
99void function(void) {
100 if (condition1) {
101 do_thing1();
103 } 102 }
104 103
105 if (!registry->desktop_shell) { 104 if (condition2) {
106 sway_abort("swaybg requires the compositor to support the desktop-shell extension."); 105 do_thing2();
106 } else {
107 do_thing3();
107 } 108 }
109}
110```
111
112### Indentation
113
114Indentations are a single tab.
115
116For long lines that need to be broken, the continuation line should be indented
117with an additional tab.
118
119If the line being broken is opening a new block (functions, if, while, etc.),
120the continuation line should be indented with two tabs, so they can't be
121misread as being part of the block.
122
123```c
124really_long_function(argument1, argument2, ...,
125 argument3, argument4);
126
127if (condition1 && condition2 && ...
128 condition3 && condition4) {
129 do_thing();
130}
131```
132
133Try to break the line in the place which you think is the most appropriate to
134balance the lines.
135
136### Line Length
137
138Try to keep your lines under 80 columns, but you can go up to 100 if it
139improves readability. Don't break lines indiscriminately, try to find nice
140breaking points so your code is easy to read.
141
142### Names
143
144Global function and type names should be prefixed with `sway_submodule_` (e.g.
145`struct sway_output`, `sway_output_destroy`). For static functions and
146types local to a file, the names chosen aren't as important. Static functions
147shouldn't have a `sway_` prefix.
148
149For include guards, use the header's filename relative to include. Uppercase
150all of the characters, and replace any invalid characters with an underscore.
108 151
109 int desired_output = atoi(argv[1]); 152### Construction/Destruction Functions
110 sway_log(WLR_INFO, "Using output %d of %d", desired_output, registry->outputs->length); 153
111 int i; 154For functions that are responsible for constructing and destructing an object,
112 struct output_state *output = registry->outputs->items[desired_output]; 155they should be written as a pair of one of two forms:
113 struct window *window = window_setup(registry, 100, 100, false); 156
114 if (!window) { 157* `init`/`finish`: These initialize/deinitialize a type, but are **NOT**
115 sway_abort("Failed to create surfaces."); 158 responsible for allocating it. They should accept a pointer to some
159 pre-allocated memory (e.g. a member of a struct).
160* `create`/`destroy`: These also initialize/deinitialize, but will return a
161 pointer to a `malloc`ed chunk of memory, and will `free` it in `destroy`.
162
163A destruction function should always be able to accept a NULL pointer or a
164zeroed value and exit cleanly; this simplifies error handling a lot.
165
166### Error Codes
167
168For functions not returning a value, they should return a (stdbool.h) bool to
169indicated if they succeeded or not.
170
171### Macros
172
173Keep the use of macros to a minimum, especially if a function can do the job. If
174you do need to use them, try to keep them close to where they're being used and
175`#undef` them after.
176
177### Example
178
179```c
180struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
181 struct wlr_backend *backend;
182 if (getenv("WAYLAND_DISPLAY") || getenv("_WAYLAND_DISPLAY")) {
183 backend = attempt_wl_backend(display);
184 if (backend) {
185 return backend;
186 }
116 } 187 }
117 window->width = output->width; 188
118 window->height = output->height; 189 const char *x11_display = getenv("DISPLAY");
119 desktop_shell_set_background(registry->desktop_shell, output->output, window->surface); 190 if (x11_display) {
120 list_add(surfaces, window); 191 return wlr_x11_backend_create(display, x11_display);
121
122 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[2]);
123 double width = cairo_image_surface_get_width(image);
124 double height = cairo_image_surface_get_height(image);
125
126 const char *scaling_mode_str = argv[3];
127 enum scaling_mode scaling_mode;
128 if (strcmp(scaling_mode_str, "stretch") == 0) {
129 scaling_mode = SCALING_MODE_STRETCH;
130 } else if (strcmp(scaling_mode_str, "fill") == 0) {
131 scaling_mode = SCALING_MODE_FILL;
132 } else if (strcmp(scaling_mode_str, "fit") == 0) {
133 scaling_mode = SCALING_MODE_FIT;
134 } else if (strcmp(scaling_mode_str, "center") == 0) {
135 scaling_mode = SCALING_MODE_CENTER;
136 } else if (strcmp(scaling_mode_str, "tile") == 0) {
137 scaling_mode = SCALING_MODE_TILE;
138 } else {
139 sway_abort("Unsupported scaling mode: %s", scaling_mode_str);
140 } 192 }
141 193
142 for (i = 0; i < surfaces->length; ++i) { 194 // Attempt DRM+libinput
143 struct window *window = surfaces->items[i]; 195
144 if (window_prerender(window) && window->cairo) { 196 struct wlr_session *session = wlr_session_create(display);
145 switch (scaling_mode) { 197 if (!session) {
146 case SCALING_MODE_STRETCH: 198 wlr_log(WLR_ERROR, "Failed to start a DRM session");
147 cairo_scale(window->cairo, 199 return NULL;
148 (double) window->width / width, 200 }
149 (double) window->height / height); 201
150 cairo_set_source_surface(window->cairo, image, 0, 0); 202 int gpu = wlr_session_find_gpu(session);
151 break; 203 if (gpu == -1) {
152 case SCALING_MODE_FILL: 204 wlr_log(WLR_ERROR, "Failed to open DRM device");
153 { 205 goto error_session;
154 double window_ratio = (double) window->width / window->height;
155 double bg_ratio = width / height;
156
157 if (window_ratio > bg_ratio) {
158 double scale = (double) window->width / width;
159 cairo_scale(window->cairo, scale, scale);
160 cairo_set_source_surface(window->cairo, image,
161 0,
162 (double) window->height/2 / scale - height/2);
163 } else {
164 double scale = (double) window->height / height;
165 cairo_scale(window->cairo, scale, scale);
166 cairo_set_source_surface(window->cairo, image,
167 (double) window->width/2 / scale - width/2,
168 0);
169 }
170 break;
171 }
172 case SCALING_MODE_FIT:
173 {
174 double window_ratio = (double) window->width / window->height;
175 double bg_ratio = width / height;
176
177 if (window_ratio > bg_ratio) {
178 double scale = (double) window->height / height;
179 cairo_scale(window->cairo, scale, scale);
180 cairo_set_source_surface(window->cairo, image,
181 (double) window->width/2 / scale - width/2,
182 0);
183 } else {
184 double scale = (double) window->width / width;
185 cairo_scale(window->cairo, scale, scale);
186 cairo_set_source_surface(window->cairo, image,
187 0,
188 (double) window->height/2 / scale - height/2);
189 }
190 break;
191 }
192 case SCALING_MODE_CENTER:
193 cairo_set_source_surface(window->cairo, image,
194 (double) window->width/2 - width/2,
195 (double) window->height/2 - height/2);
196 break;
197 case SCALING_MODE_TILE:
198 {
199 cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
200 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
201 cairo_set_source(window->cairo, pattern);
202 break;
203 }
204 default:
205 sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
206 }
207
208 cairo_paint(window->cairo);
209
210 window_render(window);
211 }
212 } 206 }
213 207
214 while (wl_display_dispatch(registry->display) != -1); 208 backend = wlr_multi_backend_create(session);
209 if (!backend) {
210 goto error_gpu;
211 }
215 212
216 for (i = 0; i < surfaces->length; ++i) { 213 struct wlr_backend *libinput = wlr_libinput_backend_create(display, session);
217 struct window *window = surfaces->items[i]; 214 if (!libinput) {
218 window_teardown(window); 215 goto error_multi;
219 } 216 }
220 list_free(surfaces); 217
221 registry_teardown(registry); 218 struct wlr_backend *drm = wlr_drm_backend_create(display, session, gpu);
222 return 0; 219 if (!drm) {
220 goto error_libinput;
221 }
222
223 wlr_multi_backend_add(backend, libinput);
224 wlr_multi_backend_add(backend, drm);
225 return backend;
226
227error_libinput:
228 wlr_backend_destroy(libinput);
229error_multi:
230 wlr_backend_destroy(backend);
231error_gpu:
232 wlr_session_close_file(session, gpu);
233error_session:
234 wlr_session_destroy(session);
235 return NULL;
223} 236}
224``` 237```