aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2019-01-17 20:16:23 +1000
committerLibravatar emersion <contact@emersion.fr>2019-01-22 09:55:13 +0100
commit2301349ad59751640ed9e59dd22edeafaf09da39 (patch)
tree1726c2f8ec1cd9baaf27fbed62aa6a337bc85ce7
parentseat_create: set initial focus for added seats (diff)
downloadsway-2301349ad59751640ed9e59dd22edeafaf09da39.tar.gz
sway-2301349ad59751640ed9e59dd22edeafaf09da39.tar.zst
sway-2301349ad59751640ed9e59dd22edeafaf09da39.zip
Use noop output when there's no outputs connected
Instead of having NULL workspace->output pointers, use a noop output. This should be safer.
-rw-r--r--include/sway/server.h1
-rw-r--r--include/sway/tree/root.h4
-rw-r--r--sway/desktop/output.c2
-rw-r--r--sway/server.c6
-rw-r--r--sway/tree/output.c21
-rw-r--r--sway/tree/root.c10
-rw-r--r--sway/tree/view.c7
-rw-r--r--sway/tree/workspace.c6
8 files changed, 29 insertions, 28 deletions
diff --git a/include/sway/server.h b/include/sway/server.h
index 0f30653f..9242ceb7 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -24,6 +24,7 @@ struct sway_server {
24 const char *socket; 24 const char *socket;
25 25
26 struct wlr_backend *backend; 26 struct wlr_backend *backend;
27 struct wlr_backend *noop_backend;
27 28
28 struct wlr_compositor *compositor; 29 struct wlr_compositor *compositor;
29 struct wlr_data_device_manager *data_device_manager; 30 struct wlr_data_device_manager *data_device_manager;
diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h
index ceccc920..8f4deaa7 100644
--- a/include/sway/tree/root.h
+++ b/include/sway/tree/root.h
@@ -31,7 +31,9 @@ struct sway_root {
31 31
32 list_t *outputs; // struct sway_output 32 list_t *outputs; // struct sway_output
33 list_t *scratchpad; // struct sway_container 33 list_t *scratchpad; // struct sway_container
34 list_t *saved_workspaces; // For when there's no connected outputs 34
35 // For when there's no connected outputs
36 struct sway_output *noop_output;
35 37
36 struct { 38 struct {
37 struct wl_signal new_node; 39 struct wl_signal new_node;
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index edf77fbc..f18a118f 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -386,7 +386,7 @@ static void damage_handle_frame(struct wl_listener *listener, void *data) {
386void output_damage_whole(struct sway_output *output) { 386void output_damage_whole(struct sway_output *output) {
387 // The output can exist with no wlr_output if it's just been disconnected 387 // The output can exist with no wlr_output if it's just been disconnected
388 // and the transaction to evacuate it has't completed yet. 388 // and the transaction to evacuate it has't completed yet.
389 if (output && output->wlr_output) { 389 if (output && output->wlr_output && output->damage) {
390 wlr_output_damage_add_whole(output->damage); 390 wlr_output_damage_add_whole(output->damage);
391 } 391 }
392} 392}
diff --git a/sway/server.c b/sway/server.c
index 5ae9bb01..43dc3900 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -4,6 +4,7 @@
4#include <stdlib.h> 4#include <stdlib.h>
5#include <wayland-server.h> 5#include <wayland-server.h>
6#include <wlr/backend.h> 6#include <wlr/backend.h>
7#include <wlr/backend/noop.h>
7#include <wlr/backend/session.h> 8#include <wlr/backend/session.h>
8#include <wlr/render/wlr_renderer.h> 9#include <wlr/render/wlr_renderer.h>
9#include <wlr/types/wlr_compositor.h> 10#include <wlr/types/wlr_compositor.h>
@@ -25,6 +26,7 @@
25#include "sway/config.h" 26#include "sway/config.h"
26#include "sway/desktop/idle_inhibit_v1.h" 27#include "sway/desktop/idle_inhibit_v1.h"
27#include "sway/input/input-manager.h" 28#include "sway/input/input-manager.h"
29#include "sway/output.h"
28#include "sway/server.h" 30#include "sway/server.h"
29#include "sway/tree/root.h" 31#include "sway/tree/root.h"
30#if HAVE_XWAYLAND 32#if HAVE_XWAYLAND
@@ -36,6 +38,7 @@ bool server_privileged_prepare(struct sway_server *server) {
36 server->wl_display = wl_display_create(); 38 server->wl_display = wl_display_create();
37 server->wl_event_loop = wl_display_get_event_loop(server->wl_display); 39 server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
38 server->backend = wlr_backend_autocreate(server->wl_display, NULL); 40 server->backend = wlr_backend_autocreate(server->wl_display, NULL);
41 server->noop_backend = wlr_noop_backend_create(server->wl_display);
39 42
40 if (!server->backend) { 43 if (!server->backend) {
41 sway_log(SWAY_ERROR, "Unable to create backend"); 44 sway_log(SWAY_ERROR, "Unable to create backend");
@@ -116,6 +119,9 @@ bool server_init(struct sway_server *server) {
116 return false; 119 return false;
117 } 120 }
118 121
122 struct wlr_output *wlr_output = wlr_noop_add_output(server->noop_backend);
123 root->noop_output = output_create(wlr_output);
124
119 // This may have been set already via -Dtxn-timeout 125 // This may have been set already via -Dtxn-timeout
120 if (!server->txn_timeout_ms) { 126 if (!server->txn_timeout_ms) {
121 server->txn_timeout_ms = 200; 127 server->txn_timeout_ms = 200;
diff --git a/sway/tree/output.c b/sway/tree/output.c
index 50a2c535..5a992f2d 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -57,12 +57,12 @@ static void restore_workspaces(struct sway_output *output) {
57 } 57 }
58 58
59 // Saved workspaces 59 // Saved workspaces
60 for (int i = 0; i < root->saved_workspaces->length; ++i) { 60 while (root->noop_output->workspaces->length) {
61 struct sway_workspace *ws = root->saved_workspaces->items[i]; 61 struct sway_workspace *ws = root->noop_output->workspaces->items[0];
62 workspace_detach(ws);
62 output_add_workspace(output, ws); 63 output_add_workspace(output, ws);
63 ipc_event_workspace(NULL, ws, "move"); 64 ipc_event_workspace(NULL, ws, "move");
64 } 65 }
65 root->saved_workspaces->length = 0;
66 66
67 output_sort_workspaces(output); 67 output_sort_workspaces(output);
68} 68}
@@ -177,6 +177,9 @@ static void output_evacuate(struct sway_output *output) {
177 if (!new_output) { 177 if (!new_output) {
178 new_output = fallback_output; 178 new_output = fallback_output;
179 } 179 }
180 if (!new_output) {
181 new_output = root->noop_output;
182 }
180 183
181 if (workspace_is_empty(workspace)) { 184 if (workspace_is_empty(workspace)) {
182 // If floating is not empty, there are sticky containers to move 185 // If floating is not empty, there are sticky containers to move
@@ -187,14 +190,10 @@ static void output_evacuate(struct sway_output *output) {
187 continue; 190 continue;
188 } 191 }
189 192
190 if (new_output) { 193 workspace_output_add_priority(workspace, new_output);
191 workspace_output_add_priority(workspace, new_output); 194 output_add_workspace(new_output, workspace);
192 output_add_workspace(new_output, workspace); 195 output_sort_workspaces(new_output);
193 output_sort_workspaces(new_output); 196 ipc_event_workspace(NULL, workspace, "move");
194 ipc_event_workspace(NULL, workspace, "move");
195 } else {
196 list_add(root->saved_workspaces, workspace);
197 }
198 } 197 }
199} 198}
200 199
diff --git a/sway/tree/root.c b/sway/tree/root.c
index d4b97be3..ec6bccf6 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -39,7 +39,6 @@ struct sway_root *root_create(void) {
39 wl_signal_init(&root->events.new_node); 39 wl_signal_init(&root->events.new_node);
40 root->outputs = create_list(); 40 root->outputs = create_list();
41 root->scratchpad = create_list(); 41 root->scratchpad = create_list();
42 root->saved_workspaces = create_list();
43 42
44 root->output_layout_change.notify = output_layout_handle_change; 43 root->output_layout_change.notify = output_layout_handle_change;
45 wl_signal_add(&root->output_layout->events.change, 44 wl_signal_add(&root->output_layout->events.change,
@@ -50,7 +49,6 @@ struct sway_root *root_create(void) {
50void root_destroy(struct sway_root *root) { 49void root_destroy(struct sway_root *root) {
51 wl_list_remove(&root->output_layout_change.link); 50 wl_list_remove(&root->output_layout_change.link);
52 list_free(root->scratchpad); 51 list_free(root->scratchpad);
53 list_free(root->saved_workspaces);
54 list_free(root->outputs); 52 list_free(root->outputs);
55 wlr_output_layout_destroy(root->output_layout); 53 wlr_output_layout_destroy(root->output_layout);
56 free(root); 54 free(root);
@@ -327,8 +325,8 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data),
327 } 325 }
328 326
329 // Saved workspaces 327 // Saved workspaces
330 for (int i = 0; i < root->saved_workspaces->length; ++i) { 328 for (int i = 0; i < root->noop_output->workspaces->length; ++i) {
331 struct sway_workspace *ws = root->saved_workspaces->items[i]; 329 struct sway_workspace *ws = root->noop_output->workspaces->items[i];
332 workspace_for_each_container(ws, f, data); 330 workspace_for_each_container(ws, f, data);
333 } 331 }
334} 332}
@@ -380,8 +378,8 @@ struct sway_container *root_find_container(
380 } 378 }
381 379
382 // Saved workspaces 380 // Saved workspaces
383 for (int i = 0; i < root->saved_workspaces->length; ++i) { 381 for (int i = 0; i < root->noop_output->workspaces->length; ++i) {
384 struct sway_workspace *ws = root->saved_workspaces->items[i]; 382 struct sway_workspace *ws = root->noop_output->workspaces->items[i];
385 if ((result = workspace_find_container(ws, test, data))) { 383 if ((result = workspace_find_container(ws, test, data))) {
386 return result; 384 return result;
387 } 385 }
diff --git a/sway/tree/view.c b/sway/tree/view.c
index bc252521..edbfca97 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -518,9 +518,10 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
518 return node->sway_container->workspace; 518 return node->sway_container->workspace;
519 } 519 }
520 520
521 // If there's no focus_inactive workspace then we must be running without 521 // When there's no outputs connected, the above should match a workspace on
522 // any outputs connected 522 // the noop output.
523 return root->saved_workspaces->items[0]; 523 sway_assert(false, "Expected to find a workspace");
524 return NULL;
524} 525}
525 526
526static bool should_focus(struct sway_view *view) { 527static bool should_focus(struct sway_view *view) {
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index e89c0849..8b3eb2ad 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -158,13 +158,7 @@ void workspace_begin_destroy(struct sway_workspace *workspace) {
158 158
159 if (workspace->output) { 159 if (workspace->output) {
160 workspace_detach(workspace); 160 workspace_detach(workspace);
161 } else {
162 int index = list_find(root->saved_workspaces, workspace);
163 if (index != -1) {
164 list_del(root->saved_workspaces, index);
165 }
166 } 161 }
167
168 workspace->node.destroying = true; 162 workspace->node.destroying = true;
169 node_set_dirty(&workspace->node); 163 node_set_dirty(&workspace->node);
170} 164}