aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/output.c')
-rw-r--r--sway/tree/output.c98
1 files changed, 76 insertions, 22 deletions
diff --git a/sway/tree/output.c b/sway/tree/output.c
index 52826c91..2d11195e 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -1,14 +1,13 @@
1#define _POSIX_C_SOURCE 200809L
2#include <assert.h> 1#include <assert.h>
3#include <ctype.h> 2#include <ctype.h>
4#include <string.h> 3#include <string.h>
5#include <strings.h> 4#include <strings.h>
6#include <wlr/types/wlr_output_damage.h>
7#include "sway/ipc-server.h" 5#include "sway/ipc-server.h"
8#include "sway/layers.h" 6#include "sway/layers.h"
9#include "sway/output.h" 7#include "sway/output.h"
10#include "sway/tree/arrange.h" 8#include "sway/tree/arrange.h"
11#include "sway/tree/workspace.h" 9#include "sway/tree/workspace.h"
10#include "sway/server.h"
12#include "log.h" 11#include "log.h"
13#include "util.h" 12#include "util.h"
14 13
@@ -87,9 +86,51 @@ static void restore_workspaces(struct sway_output *output) {
87 output_sort_workspaces(output); 86 output_sort_workspaces(output);
88} 87}
89 88
89static void destroy_scene_layers(struct sway_output *output) {
90 wlr_scene_node_destroy(&output->fullscreen_background->node);
91
92 scene_node_disown_children(output->layers.tiling);
93 scene_node_disown_children(output->layers.fullscreen);
94
95 wlr_scene_node_destroy(&output->layers.shell_background->node);
96 wlr_scene_node_destroy(&output->layers.shell_bottom->node);
97 wlr_scene_node_destroy(&output->layers.tiling->node);
98 wlr_scene_node_destroy(&output->layers.fullscreen->node);
99 wlr_scene_node_destroy(&output->layers.shell_top->node);
100 wlr_scene_node_destroy(&output->layers.shell_overlay->node);
101 wlr_scene_node_destroy(&output->layers.session_lock->node);
102}
103
90struct sway_output *output_create(struct wlr_output *wlr_output) { 104struct sway_output *output_create(struct wlr_output *wlr_output) {
91 struct sway_output *output = calloc(1, sizeof(struct sway_output)); 105 struct sway_output *output = calloc(1, sizeof(struct sway_output));
92 node_init(&output->node, N_OUTPUT, output); 106 node_init(&output->node, N_OUTPUT, output);
107
108 bool failed = false;
109 output->layers.shell_background = alloc_scene_tree(root->staging, &failed);
110 output->layers.shell_bottom = alloc_scene_tree(root->staging, &failed);
111 output->layers.tiling = alloc_scene_tree(root->staging, &failed);
112 output->layers.fullscreen = alloc_scene_tree(root->staging, &failed);
113 output->layers.shell_top = alloc_scene_tree(root->staging, &failed);
114 output->layers.shell_overlay = alloc_scene_tree(root->staging, &failed);
115 output->layers.session_lock = alloc_scene_tree(root->staging, &failed);
116
117 if (!failed) {
118 output->fullscreen_background = wlr_scene_rect_create(
119 output->layers.fullscreen, 0, 0, (float[4]){0.f, 0.f, 0.f, 1.f});
120
121 if (!output->fullscreen_background) {
122 sway_log(SWAY_ERROR, "Unable to allocate a background rect");
123 failed = true;
124 }
125 }
126
127 if (failed) {
128 destroy_scene_layers(output);
129 wlr_scene_output_destroy(output->scene_output);
130 free(output);
131 return NULL;
132 }
133
93 output->wlr_output = wlr_output; 134 output->wlr_output = wlr_output;
94 wlr_output->data = output; 135 wlr_output->data = output;
95 output->detected_subpixel = wlr_output->subpixel; 136 output->detected_subpixel = wlr_output->subpixel;
@@ -102,11 +143,6 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
102 output->workspaces = create_list(); 143 output->workspaces = create_list();
103 output->current.workspaces = create_list(); 144 output->current.workspaces = create_list();
104 145
105 size_t len = sizeof(output->layers) / sizeof(output->layers[0]);
106 for (size_t i = 0; i < len; ++i) {
107 wl_list_init(&output->layers[i]);
108 }
109
110 return output; 146 return output;
111} 147}
112 148
@@ -146,7 +182,7 @@ void output_enable(struct sway_output *output) {
146 182
147 input_manager_configure_xcursor(); 183 input_manager_configure_xcursor();
148 184
149 wl_signal_emit(&root->events.new_node, &output->node); 185 wl_signal_emit_mutable(&root->events.new_node, &output->node);
150 186
151 arrange_layers(output); 187 arrange_layers(output);
152 arrange_root(); 188 arrange_root();
@@ -238,20 +274,14 @@ void output_destroy(struct sway_output *output) {
238 "which is still referenced by transactions")) { 274 "which is still referenced by transactions")) {
239 return; 275 return;
240 } 276 }
277
278 destroy_scene_layers(output);
241 list_free(output->workspaces); 279 list_free(output->workspaces);
242 list_free(output->current.workspaces); 280 list_free(output->current.workspaces);
243 wl_event_source_remove(output->repaint_timer); 281 wl_event_source_remove(output->repaint_timer);
244 free(output); 282 free(output);
245} 283}
246 284
247static void untrack_output(struct sway_container *con, void *data) {
248 struct sway_output *output = data;
249 int index = list_find(con->outputs, output);
250 if (index != -1) {
251 list_del(con->outputs, index);
252 }
253}
254
255void output_disable(struct sway_output *output) { 285void output_disable(struct sway_output *output) {
256 if (!sway_assert(output->enabled, "Expected an enabled output")) { 286 if (!sway_assert(output->enabled, "Expected an enabled output")) {
257 return; 287 return;
@@ -262,23 +292,20 @@ void output_disable(struct sway_output *output) {
262 } 292 }
263 293
264 sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name); 294 sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name);
265 wl_signal_emit(&output->events.disable, output); 295 wl_signal_emit_mutable(&output->events.disable, output);
266 296
267 output_evacuate(output); 297 output_evacuate(output);
268 298
269 root_for_each_container(untrack_output, output);
270
271 list_del(root->outputs, index); 299 list_del(root->outputs, index);
272 300
273 output->enabled = false; 301 output->enabled = false;
274 output->current_mode = NULL;
275 302
276 arrange_root(); 303 arrange_root();
277 304
278 // Reconfigure all devices, since devices with map_to_output directives for 305 // Reconfigure all devices, since devices with map_to_output directives for
279 // an output that goes offline should stop sending events as long as the 306 // an output that goes offline should stop sending events as long as the
280 // output remains offline. 307 // output remains offline.
281 input_manager_configure_all_inputs(); 308 input_manager_configure_all_input_mappings();
282} 309}
283 310
284void output_begin_destroy(struct sway_output *output) { 311void output_begin_destroy(struct sway_output *output) {
@@ -286,7 +313,7 @@ void output_begin_destroy(struct sway_output *output) {
286 return; 313 return;
287 } 314 }
288 sway_log(SWAY_DEBUG, "Destroying output '%s'", output->wlr_output->name); 315 sway_log(SWAY_DEBUG, "Destroying output '%s'", output->wlr_output->name);
289 wl_signal_emit(&output->node.events.destroy, &output->node); 316 wl_signal_emit_mutable(&output->node.events.destroy, &output->node);
290 317
291 output->node.destroying = true; 318 output->node.destroying = true;
292 node_set_dirty(&output->node); 319 node_set_dirty(&output->node);
@@ -390,6 +417,33 @@ void output_get_box(struct sway_output *output, struct wlr_box *box) {
390 box->height = output->height; 417 box->height = output->height;
391} 418}
392 419
420static void handle_destroy_non_desktop(struct wl_listener *listener, void *data) {
421 struct sway_output_non_desktop *output =
422 wl_container_of(listener, output, destroy);
423
424 sway_log(SWAY_DEBUG, "Destroying non-desktop output '%s'", output->wlr_output->name);
425
426 int index = list_find(root->non_desktop_outputs, output);
427 list_del(root->non_desktop_outputs, index);
428
429 wl_list_remove(&output->destroy.link);
430
431 free(output);
432}
433
434struct sway_output_non_desktop *output_non_desktop_create(
435 struct wlr_output *wlr_output) {
436 struct sway_output_non_desktop *output =
437 calloc(1, sizeof(struct sway_output_non_desktop));
438
439 output->wlr_output = wlr_output;
440
441 wl_signal_add(&wlr_output->events.destroy, &output->destroy);
442 output->destroy.notify = handle_destroy_non_desktop;
443
444 return output;
445}
446
393enum sway_container_layout output_get_default_layout( 447enum sway_container_layout output_get_default_layout(
394 struct sway_output *output) { 448 struct sway_output *output) {
395 if (config->default_orientation != L_NONE) { 449 if (config->default_orientation != L_NONE) {