summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-03-13 21:10:46 -0400
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2016-03-30 00:47:58 +0200
commitb903f7f655479b9ed095cf5b5950d963d525dd8c (patch)
treefe04ecc99f5ad6ca95ae1b445734e11c33cad114
parentWindow borders proof of concept (diff)
downloadsway-b903f7f655479b9ed095cf5b5950d963d525dd8c.tar.gz
sway-b903f7f655479b9ed095cf5b5950d963d525dd8c.tar.zst
sway-b903f7f655479b9ed095cf5b5950d963d525dd8c.zip
Implement some more on borders
Note that this segfaults ALL THE TIME in wlc code. Paging @Cloudef for help, I'm at a loss.
-rw-r--r--include/container.h15
-rw-r--r--include/render.h2
-rw-r--r--sway/container.c3
-rw-r--r--sway/handlers.c1
-rw-r--r--sway/layout.c1
-rw-r--r--sway/render.c111
6 files changed, 109 insertions, 24 deletions
diff --git a/include/container.h b/include/container.h
index a96beab9..815898d7 100644
--- a/include/container.h
+++ b/include/container.h
@@ -36,6 +36,12 @@ enum swayc_layouts {
36 L_LAYOUTS, 36 L_LAYOUTS,
37}; 37};
38 38
39enum swayc_border_types {
40 B_NONE, /**< No border */
41 B_PIXEL, /**< 1px border */
42 B_NORMAL /**< Normal border with title bar */
43};
44
39/** 45/**
40 * Stores information about a container. 46 * Stores information about a container.
41 * 47 *
@@ -109,6 +115,15 @@ struct sway_container {
109 * If this container's children include a fullscreen view, this is that view. 115 * If this container's children include a fullscreen view, this is that view.
110 */ 116 */
111 struct sway_container *fullscreen; 117 struct sway_container *fullscreen;
118 /**
119 * If this container is a view, this may be set to the window's decoration
120 * buffer (or NULL).
121 */
122 unsigned char *border;
123 enum swayc_border_types border_type;
124 struct wlc_geometry border_geometry;
125 struct wlc_geometry presumed_geometry;
126 int border_thickness;
112}; 127};
113 128
114enum visibility_mask { 129enum visibility_mask {
diff --git a/include/render.h b/include/render.h
index 19d3a52e..c3d1ca87 100644
--- a/include/render.h
+++ b/include/render.h
@@ -1,7 +1,9 @@
1#ifndef _SWAY_RENDER_H 1#ifndef _SWAY_RENDER_H
2#define _SWAY_RENDER_H 2#define _SWAY_RENDER_H
3#include <wlc/wlc.h> 3#include <wlc/wlc.h>
4#include "container.h"
4 5
5void render_view_borders(wlc_handle view); 6void render_view_borders(wlc_handle view);
7void update_view_border(swayc_t *view);
6 8
7#endif 9#endif
diff --git a/sway/container.c b/sway/container.c
index 9330a3de..ac0d3231 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -22,8 +22,11 @@ static swayc_t *new_swayc(enum swayc_types type) {
22 c->gaps = -1; 22 c->gaps = -1;
23 c->layout = L_NONE; 23 c->layout = L_NONE;
24 c->type = type; 24 c->type = type;
25 c->border_type = B_PIXEL; // TODO: Load default from config
26 c->border_thickness = 2;
25 if (type != C_VIEW) { 27 if (type != C_VIEW) {
26 c->children = create_list(); 28 c->children = create_list();
29 c->border_type = B_NONE;
27 } 30 }
28 return c; 31 return c;
29} 32}
diff --git a/sway/handlers.c b/sway/handlers.c
index dff682f5..47b649fd 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -357,6 +357,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
357 arrange_windows(view->parent, -1, -1); 357 arrange_windows(view->parent, -1, -1);
358 } 358 }
359 } 359 }
360 update_view_border(view);
360} 361}
361 362
362static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { 363static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
diff --git a/sway/layout.c b/sway/layout.c
index d9c4598f..be898c58 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -12,6 +12,7 @@
12#include "focus.h" 12#include "focus.h"
13#include "output.h" 13#include "output.h"
14#include "ipc-server.h" 14#include "ipc-server.h"
15#include "render.h"
15 16
16swayc_t root_container; 17swayc_t root_container;
17list_t *scratchpad; 18list_t *scratchpad;
diff --git a/sway/render.c b/sway/render.c
index a5ba2f4c..9388c1d0 100644
--- a/sway/render.c
+++ b/sway/render.c
@@ -2,6 +2,8 @@
2#include <wlc/wlc-render.h> 2#include <wlc/wlc-render.h>
3#include <cairo/cairo.h> 3#include <cairo/cairo.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <stdio.h>
6#include "container.h"
5 7
6void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { 8void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
7 cairo_set_source_rgba(cairo, 9 cairo_set_source_rgba(cairo,
@@ -11,40 +13,101 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
11 (color >> (0*8) & 0xFF) / 255.0); 13 (color >> (0*8) & 0xFF) / 255.0);
12} 14}
13 15
14cairo_t *create_cairo_context(int width, int height, int channels, 16cairo_t *create_border_buffer(swayc_t *view, struct wlc_geometry geo,
15 cairo_surface_t **surf, unsigned char **buf) { 17 cairo_surface_t **surface) {
18 const int channels = 4;
16 cairo_t *cr; 19 cairo_t *cr;
17 *buf = calloc(channels * width * height, sizeof(unsigned char)); 20 view->border_geometry = geo;
18 if (!*buf) { 21 view->border = calloc(channels * geo.size.w * geo.size.h,
22 sizeof(unsigned char));
23 if (!view->border) {
24 sway_log(L_DEBUG, "Unable to allocate buffer");
19 return NULL; 25 return NULL;
20 } 26 }
21 *surf = cairo_image_surface_create_for_data(*buf, CAIRO_FORMAT_ARGB32, 27 *surface = cairo_image_surface_create_for_data(view->border,
22 width, height, channels * width); 28 CAIRO_FORMAT_ARGB32, geo.size.w, geo.size.h, channels * geo.size.w);
23 if (cairo_surface_status(*surf) != CAIRO_STATUS_SUCCESS) { 29 if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) {
24 free(*buf); 30 free(view->border);
31 view->border = NULL;
32 sway_log(L_DEBUG, "Unable to allocate surface");
25 return NULL; 33 return NULL;
26 } 34 }
27 cr = cairo_create(*surf); 35 cr = cairo_create(*surface);
28 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) { 36 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
29 free(*buf); 37 cairo_surface_destroy(*surface);
38 free(view->border);
39 view->border = NULL;
40 sway_log(L_DEBUG, "Unable to create cairo context");
30 return NULL; 41 return NULL;
31 } 42 }
32 return cr; 43 return cr;
33} 44}
34 45
46void update_view_border(swayc_t *view) {
47 struct wlc_geometry geo;
48 wlc_view_get_visible_geometry(view->handle, &geo);
49 cairo_t *cr = NULL;
50 cairo_surface_t *surface = NULL;
51
52 if (view->border) {
53 free(view->border);
54 view->border = NULL;
55 }
56
57 switch (view->border_type) {
58 case B_NONE:
59 view->border_geometry = geo;
60 break;
61 case B_PIXEL:
62 geo.origin.x -= view->border_thickness;
63 geo.origin.y -= view->border_thickness;
64 geo.size.w += view->border_thickness * 2;
65 geo.size.h += view->border_thickness * 2;
66 if (geo.size.w <= 0 || geo.size.h <= 0) {
67 view->border = NULL;
68 break;
69 }
70 cr = create_border_buffer(view, geo, &surface);
71 if (!cr) {
72 break;
73 }
74 cairo_set_source_u32(cr, 0x0000FFFF);
75 cairo_paint(cr);
76 break;
77 case B_NORMAL:
78 // TODO
79 break;
80 }
81 if (surface) {
82 cairo_surface_flush(surface);
83 cairo_surface_destroy(surface);
84 }
85 if (cr) {
86 cairo_destroy(cr);
87 sway_log(L_DEBUG, "Created border for %p (%dx%d+%d,%d)", view,
88 geo.size.w, geo.size.h, geo.origin.x, geo.origin.y);
89 }
90 view->border_geometry = geo;
91}
92
35void render_view_borders(wlc_handle view) { 93void render_view_borders(wlc_handle view) {
36 const int bw = 2; 94 swayc_t *c = swayc_by_handle(view);
37 unsigned char *surf_data; 95 if (!c || c->border_type == B_NONE) {
38 cairo_surface_t *surf; 96 return;
39 struct wlc_geometry geo = *wlc_view_get_geometry(view); 97 }
40 cairo_t *cr = create_cairo_context(geo.size.w + bw * 2, geo.size.h + bw * 2, 4, &surf, &surf_data); 98 struct wlc_geometry geo;
41 cairo_set_source_u32(cr, 0x0000FFFF); 99 wlc_view_get_visible_geometry(view, &geo);
42 cairo_paint(cr); 100 if (geo.size.w != c->presumed_geometry.size.w
43 geo.origin.x -= bw; 101 || geo.size.h != c->presumed_geometry.size.h
44 geo.origin.y -= bw; 102 || geo.origin.x != c->presumed_geometry.origin.x
45 geo.size.w += bw * 2; 103 || geo.origin.y != c->presumed_geometry.origin.y) {
46 geo.size.h += bw * 2; 104 update_view_border(c);
47 wlc_pixels_write(WLC_RGBA8888, &geo, surf_data); 105 c->presumed_geometry = geo;
48 cairo_destroy(cr); 106 }
49 free(surf_data); 107 if (c->border) {
108 geo = c->border_geometry;
109 sway_log(L_DEBUG, "Rendering border for %p (%dx%d+%d,%d)", c,
110 geo.size.w, geo.size.h, geo.origin.x, geo.origin.y);
111 wlc_pixels_write(WLC_RGBA8888, &c->border_geometry, c->border);
112 }
50} 113}