summaryrefslogtreecommitdiffstats
path: root/sway/border.c
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-04-20 00:22:15 +0200
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-04-25 00:00:49 +0200
commit3e1f78ab26e8bc6b6cefd53ee137e97533c2695e (patch)
treef158bcae9fce9af29a35bd3ec0e32b81bff87662 /sway/border.c
parentUse tabs for indentation (diff)
downloadsway-3e1f78ab26e8bc6b6cefd53ee137e97533c2695e.tar.gz
sway-3e1f78ab26e8bc6b6cefd53ee137e97533c2695e.tar.zst
sway-3e1f78ab26e8bc6b6cefd53ee137e97533c2695e.zip
Add support for nested tabbed/stacked containers
Diffstat (limited to 'sway/border.c')
-rw-r--r--sway/border.c131
1 files changed, 83 insertions, 48 deletions
diff --git a/sway/border.c b/sway/border.c
index 2eefbbf5..cc329b6a 100644
--- a/sway/border.c
+++ b/sway/border.c
@@ -20,28 +20,31 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
20 (color >> (3*8) & 0xFF) / 255.0); 20 (color >> (3*8) & 0xFF) / 255.0);
21} 21}
22 22
23static cairo_t *create_border_buffer(swayc_t *view, struct wlc_geometry geo, cairo_surface_t **surface) { 23static cairo_t *create_border_buffer(swayc_t *view, struct wlc_geometry g, cairo_surface_t **surface) {
24 if (view->border == NULL) {
25 view->border = malloc(sizeof(struct border));
26 }
24 cairo_t *cr; 27 cairo_t *cr;
25 view->border_geometry = geo; 28 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, g.size.w);
26 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, geo.size.w); 29 view->border->buffer = calloc(stride * g.size.h, sizeof(unsigned char));
27 view->border = calloc(stride * geo.size.h, sizeof(unsigned char)); 30 view->border->geometry = g;
28 if (!view->border) { 31 if (!view->border->buffer) {
29 sway_log(L_DEBUG, "Unable to allocate buffer"); 32 sway_log(L_DEBUG, "Unable to allocate buffer");
30 return NULL; 33 return NULL;
31 } 34 }
32 *surface = cairo_image_surface_create_for_data(view->border, 35 *surface = cairo_image_surface_create_for_data(view->border->buffer,
33 CAIRO_FORMAT_ARGB32, geo.size.w, geo.size.h, stride); 36 CAIRO_FORMAT_ARGB32, g.size.w, g.size.h, stride);
34 if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) { 37 if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) {
35 free(view->border); 38 free(view->border);
36 view->border = NULL; 39 view->border->buffer = NULL;
37 sway_log(L_DEBUG, "Unable to allocate surface"); 40 sway_log(L_DEBUG, "Unable to allocate surface");
38 return NULL; 41 return NULL;
39 } 42 }
40 cr = cairo_create(*surface); 43 cr = cairo_create(*surface);
41 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) { 44 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
42 cairo_surface_destroy(*surface); 45 cairo_surface_destroy(*surface);
43 free(view->border); 46 free(view->border->buffer);
44 view->border = NULL; 47 view->border->buffer = NULL;
45 sway_log(L_DEBUG, "Unable to create cairo context"); 48 sway_log(L_DEBUG, "Unable to create cairo context");
46 return NULL; 49 return NULL;
47 } 50 }
@@ -92,15 +95,19 @@ int get_font_text_height(const char *font) {
92} 95}
93 96
94static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *colors, bool top) { 97static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *colors, bool top) {
98 struct wlc_geometry *g = &view->border->geometry;
95 struct wlc_geometry *b = &view->border_geometry; 99 struct wlc_geometry *b = &view->border_geometry;
96 struct wlc_geometry *v = &view->actual_geometry; 100 struct wlc_geometry *v = &view->actual_geometry;
97 101
102 int x = b->origin.x - g->origin.x;
103 int y = b->origin.y - g->origin.y;
104
98 // left border 105 // left border
99 int left_border = v->origin.x - b->origin.x; 106 int left_border = v->origin.x - b->origin.x;
100 if (left_border > 0) { 107 if (left_border > 0) {
101 render_sharp_line(cr, 108 render_sharp_line(cr,
102 colors->child_border, 109 colors->child_border,
103 0, 0, 110 x, y,
104 left_border, 111 left_border,
105 b->size.h); 112 b->size.h);
106 } 113 }
@@ -110,8 +117,8 @@ static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *col
110 if (right_border > 0) { 117 if (right_border > 0) {
111 render_sharp_line(cr, 118 render_sharp_line(cr,
112 colors->child_border, 119 colors->child_border,
113 b->size.w - right_border, 120 x + b->size.w - right_border,
114 0, 121 y,
115 right_border, 122 right_border,
116 b->size.h); 123 b->size.h);
117 } 124 }
@@ -121,7 +128,7 @@ static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *col
121 if (top && top_border > 0) { 128 if (top && top_border > 0) {
122 render_sharp_line(cr, 129 render_sharp_line(cr,
123 colors->child_border, 130 colors->child_border,
124 0, 0, 131 x, y,
125 b->size.w, 132 b->size.w,
126 top_border); 133 top_border);
127 } 134 }
@@ -131,16 +138,15 @@ static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *col
131 if (bottom_border > 0) { 138 if (bottom_border > 0) {
132 render_sharp_line(cr, 139 render_sharp_line(cr,
133 colors->child_border, 140 colors->child_border,
134 0, 141 x,
135 b->size.h - bottom_border, 142 y + b->size.h - bottom_border,
136 b->size.w, 143 b->size.w,
137 bottom_border); 144 bottom_border);
138 } 145 }
139} 146}
140 147
141static void render_title_bar(swayc_t *view, cairo_t *cr, struct border_colors *colors) { 148static void render_title_bar(swayc_t *view, cairo_t *cr, struct wlc_geometry *b, struct border_colors *colors) {
142 struct wlc_geometry *tb = &view->title_bar_geometry; 149 struct wlc_geometry *tb = &view->title_bar_geometry;
143 struct wlc_geometry *b = &view->border_geometry;
144 int x = MIN(tb->origin.x, tb->origin.x - b->origin.x); 150 int x = MIN(tb->origin.x, tb->origin.x - b->origin.x);
145 int y = MIN(tb->origin.y, tb->origin.y - b->origin.y); 151 int y = MIN(tb->origin.y, tb->origin.y - b->origin.y);
146 152
@@ -197,6 +203,34 @@ void map_update_view_border(swayc_t *view, void *data) {
197 } 203 }
198} 204}
199 205
206void update_tabbed_stacked_titlebars(swayc_t *c, cairo_t *cr, struct wlc_geometry *g, swayc_t *focused, swayc_t *focused_inactive) {
207 if (c->type == C_CONTAINER) {
208 if (c->parent->focused == c) {
209 render_title_bar(c, cr, g, &config->border_colors.focused_inactive);
210 } else {
211 render_title_bar(c, cr, g, &config->border_colors.unfocused);
212 }
213
214 if (!c->visible) {
215 return;
216 }
217
218 int i;
219 for (i = 0; i < c->children->length; ++i) {
220 swayc_t *child = c->children->items[i];
221 update_tabbed_stacked_titlebars(child, cr, g, focused, focused_inactive);
222 }
223 } else {
224 if (focused == c) {
225 render_title_bar(c, cr, g, &config->border_colors.focused);
226 } else if (focused_inactive == c) {
227 render_title_bar(c, cr, g, &config->border_colors.focused_inactive);
228 } else {
229 render_title_bar(c, cr, g, &config->border_colors.unfocused);
230 }
231 }
232}
233
200void update_view_border(swayc_t *view) { 234void update_view_border(swayc_t *view) {
201 if (!view->visible) { 235 if (!view->visible) {
202 return; 236 return;
@@ -205,12 +239,12 @@ void update_view_border(swayc_t *view) {
205 cairo_t *cr = NULL; 239 cairo_t *cr = NULL;
206 cairo_surface_t *surface = NULL; 240 cairo_surface_t *surface = NULL;
207 241
208 if (view->border) { 242 if (view->border && view->border->buffer) {
209 free(view->border); 243 free(view->border->buffer);
210 view->border = NULL; 244 view->border->buffer = NULL;
211 } 245 }
212 246
213 // get focused and focused_intactive views 247 // get focused and focused_inactive views
214 swayc_t *focused = get_focused_view(&root_container); 248 swayc_t *focused = get_focused_view(&root_container);
215 swayc_t *container = swayc_parent_by_type(view, C_CONTAINER); 249 swayc_t *container = swayc_parent_by_type(view, C_CONTAINER);
216 swayc_t *focused_inactive = NULL; 250 swayc_t *focused_inactive = NULL;
@@ -223,30 +257,27 @@ void update_view_border(swayc_t *view) {
223 } 257 }
224 } 258 }
225 259
226 swayc_t *p = view->parent; 260 // for tabbed/stacked layouts the focused view has to draw all the
227 261 // titlebars of the hidden views.
228 if (swayc_is_tabbed_stacked(view)) { 262 swayc_t *p = swayc_tabbed_stacked_parent(view);
229 cr = create_border_buffer(view, view->border_geometry, &surface); 263 if (p && view->parent->focused == view) {
230 if (focused == view) { 264 struct wlc_geometry g = {
265 .origin = {
266 .x = p->x,
267 .y = p->y
268 },
269 .size = {
270 .w = p->width,
271 .h = p->height
272 }
273 };
274 cr = create_border_buffer(view, g, &surface);
275 if (view == focused) {
231 render_borders(view, cr, &config->border_colors.focused, false); 276 render_borders(view, cr, &config->border_colors.focused, false);
232 } else if (focused_inactive == view) {
233 render_borders(view, cr, &config->border_colors.focused_inactive, false);
234 } else { 277 } else {
235 render_borders(view, cr, &config->border_colors.unfocused, false); 278 render_borders(view, cr, &config->border_colors.focused_inactive, false);
236 }
237
238 int i;
239 for (i = 0; i < p->children->length; ++i) {
240 swayc_t *child = p->children->items[i];
241
242 if (focused == child) {
243 render_title_bar(child, cr, &config->border_colors.focused);
244 } else if (focused_inactive == child) {
245 render_title_bar(child, cr, &config->border_colors.focused_inactive);
246 } else {
247 render_title_bar(child, cr, &config->border_colors.unfocused);
248 }
249 } 279 }
280 update_tabbed_stacked_titlebars(p, cr, &g, focused, focused_inactive);
250 } else { 281 } else {
251 switch (view->border_type) { 282 switch (view->border_type) {
252 case B_NONE: 283 case B_NONE:
@@ -274,13 +305,16 @@ void update_view_border(swayc_t *view) {
274 305
275 if (focused == view) { 306 if (focused == view) {
276 render_borders(view, cr, &config->border_colors.focused, false); 307 render_borders(view, cr, &config->border_colors.focused, false);
277 render_title_bar(view, cr, &config->border_colors.focused); 308 render_title_bar(view, cr, &view->border_geometry,
309 &config->border_colors.focused);
278 } else if (focused_inactive == view) { 310 } else if (focused_inactive == view) {
279 render_borders(view, cr, &config->border_colors.focused_inactive, false); 311 render_borders(view, cr, &config->border_colors.focused_inactive, false);
280 render_title_bar(view, cr, &config->border_colors.focused_inactive); 312 render_title_bar(view, cr, &view->border_geometry,
313 &config->border_colors.focused_inactive);
281 } else { 314 } else {
282 render_borders(view, cr, &config->border_colors.unfocused, false); 315 render_borders(view, cr, &config->border_colors.unfocused, false);
283 render_title_bar(view, cr, &config->border_colors.unfocused); 316 render_title_bar(view, cr, &view->border_geometry,
317 &config->border_colors.unfocused);
284 } 318 }
285 319
286 break; 320 break;
@@ -291,6 +325,7 @@ void update_view_border(swayc_t *view) {
291 cairo_surface_flush(surface); 325 cairo_surface_flush(surface);
292 cairo_surface_destroy(surface); 326 cairo_surface_destroy(surface);
293 } 327 }
328
294 if (cr) { 329 if (cr) {
295 cairo_destroy(cr); 330 cairo_destroy(cr);
296 } 331 }
@@ -316,7 +351,7 @@ void render_view_borders(wlc_handle view) {
316 } 351 }
317 } 352 }
318 353
319 if (c->border) { 354 if (c->border && c->border->buffer) {
320 wlc_pixels_write(WLC_RGBA8888, &c->border_geometry, c->border); 355 wlc_pixels_write(WLC_RGBA8888, &c->border->geometry, c->border->buffer);
321 } 356 }
322} 357}