diff options
author | Drew DeVault <sir@cmpwn.com> | 2016-03-13 21:10:46 -0400 |
---|---|---|
committer | Mikkel Oscar Lyderik <mikkeloscar@gmail.com> | 2016-03-30 00:47:58 +0200 |
commit | b903f7f655479b9ed095cf5b5950d963d525dd8c (patch) | |
tree | fe04ecc99f5ad6ca95ae1b445734e11c33cad114 /sway | |
parent | Window borders proof of concept (diff) | |
download | sway-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.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/container.c | 3 | ||||
-rw-r--r-- | sway/handlers.c | 1 | ||||
-rw-r--r-- | sway/layout.c | 1 | ||||
-rw-r--r-- | sway/render.c | 111 |
4 files changed, 92 insertions, 24 deletions
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 | ||
362 | static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { | 363 | static 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 | ||
16 | swayc_t root_container; | 17 | swayc_t root_container; |
17 | list_t *scratchpad; | 18 | list_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 | ||
6 | void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { | 8 | void 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 | ||
14 | cairo_t *create_cairo_context(int width, int height, int channels, | 16 | cairo_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 | ||
46 | void 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 | |||
35 | void render_view_borders(wlc_handle view) { | 93 | void 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 | } |