aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-04-04 22:01:00 -0400
committerLibravatar GitHub <noreply@github.com>2018-04-04 22:01:00 -0400
commit5a646221815f6793f844412b82b185b415b32157 (patch)
tree490f5c672ea2362b1b4cf4e34e13232df0502270
parentMerge pull request #1705 from swaywm/swaylock-layers (diff)
parentImplement opacity command (diff)
downloadsway-5a646221815f6793f844412b82b185b415b32157.tar.gz
sway-5a646221815f6793f844412b82b185b415b32157.tar.zst
sway-5a646221815f6793f844412b82b185b415b32157.zip
Merge pull request #1707 from acrisci/transparency
Implement opacity command
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/tree/container.h2
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/opacity.c39
-rw-r--r--sway/desktop/output.c34
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.txt4
-rw-r--r--sway/tree/container.c2
8 files changed, 68 insertions, 16 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 66f097ea..edb5a213 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -123,6 +123,7 @@ sway_cmd cmd_mark;
123sway_cmd cmd_mode; 123sway_cmd cmd_mode;
124sway_cmd cmd_mouse_warping; 124sway_cmd cmd_mouse_warping;
125sway_cmd cmd_move; 125sway_cmd cmd_move;
126sway_cmd cmd_opacity;
126sway_cmd cmd_new_float; 127sway_cmd cmd_new_float;
127sway_cmd cmd_new_window; 128sway_cmd cmd_new_window;
128sway_cmd cmd_no_focus; 129sway_cmd cmd_no_focus;
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 277165ea..3a3a9429 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -83,6 +83,8 @@ struct sway_container {
83 83
84 list_t *marks; // list of char* 84 list_t *marks; // list of char*
85 85
86 float alpha;
87
86 struct { 88 struct {
87 struct wl_signal destroy; 89 struct wl_signal destroy;
88 // Raised after the tree updates, but before arrange_windows 90 // Raised after the tree updates, but before arrange_windows
diff --git a/sway/commands.c b/sway/commands.c
index 8156a08e..2786a879 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -163,6 +163,7 @@ static struct cmd_handler command_handlers[] = {
163 { "kill", cmd_kill }, 163 { "kill", cmd_kill },
164 { "layout", cmd_layout }, 164 { "layout", cmd_layout },
165 { "move", cmd_move }, 165 { "move", cmd_move },
166 { "opacity", cmd_opacity },
166 { "reload", cmd_reload }, 167 { "reload", cmd_reload },
167 { "split", cmd_split }, 168 { "split", cmd_split },
168 { "splith", cmd_splith }, 169 { "splith", cmd_splith },
diff --git a/sway/commands/opacity.c b/sway/commands/opacity.c
new file mode 100644
index 00000000..b8cd1f09
--- /dev/null
+++ b/sway/commands/opacity.c
@@ -0,0 +1,39 @@
1#include <assert.h>
2#include <stdlib.h>
3#include "sway/commands.h"
4#include "sway/tree/view.h"
5#include "log.h"
6
7static bool parse_opacity(const char *opacity, float *val) {
8 char *err;
9 *val = strtof(opacity, &err);
10 if (*val < 0 || *val > 1 || *err) {
11 return false;
12 }
13 return true;
14}
15
16struct cmd_results *cmd_opacity(int argc, char **argv) {
17 struct cmd_results *error = NULL;
18 if ((error = checkarg(argc, "layout", EXPECTED_EQUAL_TO, 1))) {
19 return error;
20 }
21
22 struct sway_container *con =
23 config->handler_context.current_container;
24
25 float opacity = 0.0f;
26
27 if (!parse_opacity(argv[0], &opacity)) {
28 return cmd_results_new(CMD_INVALID, "opacity <value>",
29 "Invalid value (expected 0..1): %s", argv[0]);
30 }
31
32 con->alpha = opacity;
33
34 if (con->type == C_VIEW) {
35 view_damage_whole(con->sway_view);
36 }
37
38 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
39}
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 8a4fb4a2..6cf5da48 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -75,7 +75,7 @@ static bool surface_intersect_output(struct wlr_surface *surface,
75 75
76static void render_surface(struct wlr_surface *surface, 76static void render_surface(struct wlr_surface *surface,
77 struct wlr_output *wlr_output, struct timespec *when, 77 struct wlr_output *wlr_output, struct timespec *when,
78 double ox, double oy, float rotation) { 78 double ox, double oy, float rotation, float alpha) {
79 struct wlr_renderer *renderer = 79 struct wlr_renderer *renderer =
80 wlr_backend_get_renderer(wlr_output->backend); 80 wlr_backend_get_renderer(wlr_output->backend);
81 81
@@ -95,8 +95,8 @@ static void render_surface(struct wlr_surface *surface,
95 wlr_matrix_project_box(matrix, &box, transform, rotation, 95 wlr_matrix_project_box(matrix, &box, transform, rotation,
96 wlr_output->transform_matrix); 96 wlr_output->transform_matrix);
97 97
98 // TODO: configurable alpha 98 wlr_render_texture_with_matrix(renderer, surface->texture,
99 wlr_render_texture_with_matrix(renderer, surface->texture, matrix, 1.0f); 99 matrix, alpha);
100 100
101 wlr_surface_send_frame_done(surface, when); 101 wlr_surface_send_frame_done(surface, when);
102 } 102 }
@@ -110,13 +110,13 @@ static void render_surface(struct wlr_surface *surface,
110 surface->current->width, surface->current->height, rotation); 110 surface->current->width, surface->current->height, rotation);
111 111
112 render_surface(subsurface->surface, wlr_output, when, 112 render_surface(subsurface->surface, wlr_output, when,
113 ox + sx, oy + sy, rotation); 113 ox + sx, oy + sy, rotation, alpha);
114 } 114 }
115} 115}
116 116
117static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, 117static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface,
118 struct wlr_output *wlr_output, struct timespec *when, double base_x, 118 struct wlr_output *wlr_output, struct timespec *when, double base_x,
119 double base_y, float rotation) { 119 double base_y, float rotation, float alpha) {
120 double width = surface->surface->current->width; 120 double width = surface->surface->current->width;
121 double height = surface->surface->current->height; 121 double height = surface->surface->current->height;
122 122
@@ -136,19 +136,19 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface,
136 width, height, rotation); 136 width, height, rotation);
137 137
138 render_surface(popup->surface, wlr_output, when, 138 render_surface(popup->surface, wlr_output, when,
139 base_x + popup_sx, base_y + popup_sy, rotation); 139 base_x + popup_sx, base_y + popup_sy, rotation, alpha);
140 render_xdg_v6_popups(popup, wlr_output, when, 140 render_xdg_v6_popups(popup, wlr_output, when,
141 base_x + popup_sx, base_y + popup_sy, rotation); 141 base_x + popup_sx, base_y + popup_sy, rotation, alpha);
142 } 142 }
143} 143}
144 144
145static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, 145static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface,
146 struct wlr_output *wlr_output, struct timespec *when, 146 struct wlr_output *wlr_output, struct timespec *when,
147 double lx, double ly, float rotation, 147 double lx, double ly, float rotation, float alpha,
148 bool is_child) { 148 bool is_child) {
149 if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { 149 if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) {
150 render_surface(surface->surface, wlr_output, when, 150 render_surface(surface->surface, wlr_output, when,
151 lx, ly, rotation); 151 lx, ly, rotation, alpha);
152 152
153 double width = surface->surface->current->width; 153 double width = surface->surface->current->width;
154 double height = surface->surface->current->height; 154 double height = surface->surface->current->height;
@@ -164,7 +164,7 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface,
164 width, height, rotation); 164 width, height, rotation);
165 165
166 render_wl_shell_surface(popup, wlr_output, when, 166 render_wl_shell_surface(popup, wlr_output, when,
167 lx + popup_x, ly + popup_y, rotation, true); 167 lx + popup_x, ly + popup_y, rotation, alpha, true);
168 } 168 }
169 } 169 }
170} 170}
@@ -181,6 +181,7 @@ static void render_view(struct sway_container *view, void *data) {
181 struct wlr_output *wlr_output = output->wlr_output; 181 struct wlr_output *wlr_output = output->wlr_output;
182 struct sway_view *sway_view = view->sway_view; 182 struct sway_view *sway_view = view->sway_view;
183 struct wlr_surface *surface = sway_view->surface; 183 struct wlr_surface *surface = sway_view->surface;
184 float alpha = sway_view->swayc->alpha;
184 185
185 if (!surface) { 186 if (!surface) {
186 return; 187 return;
@@ -191,17 +192,18 @@ static void render_view(struct sway_container *view, void *data) {
191 int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; 192 int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x;
192 int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; 193 int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y;
193 render_surface(surface, wlr_output, when, 194 render_surface(surface, wlr_output, when,
194 view->x - window_offset_x, view->y - window_offset_y, 0); 195 view->x - window_offset_x, view->y - window_offset_y, 0, alpha);
195 render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, 196 render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output,
196 when, view->x - window_offset_x, view->y - window_offset_y, 0); 197 when, view->x - window_offset_x, view->y - window_offset_y, 0, alpha);
197 break; 198 break;
198 } 199 }
199 case SWAY_WL_SHELL_VIEW: 200 case SWAY_WL_SHELL_VIEW:
200 render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, 201 render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output,
201 when, view->x, view->y, 0, false); 202 when, view->x, view->y, 0, alpha, false);
202 break; 203 break;
203 case SWAY_XWAYLAND_VIEW: 204 case SWAY_XWAYLAND_VIEW:
204 render_surface(surface, wlr_output, when, view->x, view->y, 0); 205 render_surface(surface, wlr_output, when, view->x, view->y,
206 0, alpha);
205 break; 207 break;
206 default: 208 default:
207 break; 209 break;
@@ -214,7 +216,7 @@ static void render_layer(struct sway_output *output, struct timespec *when,
214 wl_list_for_each(sway_layer, layer, link) { 216 wl_list_for_each(sway_layer, layer, link) {
215 struct wlr_layer_surface *layer = sway_layer->layer_surface; 217 struct wlr_layer_surface *layer = sway_layer->layer_surface;
216 render_surface(layer->surface, output->wlr_output, when, 218 render_surface(layer->surface, output->wlr_output, when,
217 sway_layer->geo.x, sway_layer->geo.y, 0); 219 sway_layer->geo.x, sway_layer->geo.y, 0, 1.0f);
218 wlr_surface_send_frame_done(layer->surface, when); 220 wlr_surface_send_frame_done(layer->surface, when);
219 } 221 }
220} 222}
@@ -288,7 +290,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
288 } 290 }
289 291
290 render_surface(xsurface->surface, wlr_output, &output->last_frame, 292 render_surface(xsurface->surface, wlr_output, &output->last_frame,
291 view_box.x - output_box->x, view_box.y - output_box->y, 0); 293 view_box.x - output_box->x, view_box.y - output_box->y, 0, 1.0f);
292 } 294 }
293 295
294 // TODO: Consider revising this when fullscreen windows are supported 296 // TODO: Consider revising this when fullscreen windows are supported
diff --git a/sway/meson.build b/sway/meson.build
index 91aab0a0..f210c195 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -15,6 +15,7 @@ sway_sources = files(
15 'commands/focus.c', 15 'commands/focus.c',
16 'commands/focus_follows_mouse.c', 16 'commands/focus_follows_mouse.c',
17 'commands/kill.c', 17 'commands/kill.c',
18 'commands/opacity.c',
18 'commands/include.c', 19 'commands/include.c',
19 'commands/input.c', 20 'commands/input.c',
20 'commands/layout.c', 21 'commands/layout.c',
diff --git a/sway/sway.5.txt b/sway/sway.5.txt
index 900e499a..59c3295a 100644
--- a/sway/sway.5.txt
+++ b/sway/sway.5.txt
@@ -413,6 +413,10 @@ The default colors are:
413 However, any mark that starts with an underscore will not be drawn even if the 413 However, any mark that starts with an underscore will not be drawn even if the
414 option is on. The default option is _on_. 414 option is on. The default option is _on_.
415 415
416**opacity** <value>::
417 Set the opacity of the window between 0 (completely transparent) and 1
418 (completely opaque).
419
416**unmark** <identifier>:: 420**unmark** <identifier>::
417 **Unmark** will remove _identifier_ from the list of current marks on a window. If 421 **Unmark** will remove _identifier_ from the list of current marks on a window. If
418 no _identifier_ is specified, then **unmark** will remove all marks. 422 no _identifier_ is specified, then **unmark** will remove all marks.
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 753f333c..3be08645 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -72,6 +72,8 @@ struct sway_container *container_create(enum sway_container_type type) {
72 c->layout = L_NONE; 72 c->layout = L_NONE;
73 c->workspace_layout = L_NONE; 73 c->workspace_layout = L_NONE;
74 c->type = type; 74 c->type = type;
75 c->alpha = 1.0f;
76
75 if (type != C_VIEW) { 77 if (type != C_VIEW) {
76 c->children = create_list(); 78 c->children = create_list();
77 } 79 }