aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Rouven Czerwinski <rouven@czerwinskis.de>2019-06-16 17:36:00 +0200
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-06-16 12:29:16 -0400
commitddad41f423db14f89f765fc134d45d1ea8a60caf (patch)
tree02a17ffe6af7d5939129f02291036cb1633dddf9
parentAdd missing underscore in bindswitch documentation (diff)
downloadsway-ddad41f423db14f89f765fc134d45d1ea8a60caf.tar.gz
sway-ddad41f423db14f89f765fc134d45d1ea8a60caf.tar.zst
sway-ddad41f423db14f89f765fc134d45d1ea8a60caf.zip
Fix sway crashes for scratchpad layouts
Currently container_replace removes the container from the scratchpad and re-adds it afterwards. For the split commands this results in the container being send to the scratchpad, which results in a NULL segfault if the same container should be shown. Pass an optional workspace to root_scratchpad_add_container, if the workspace is passed the window will continue to show on the workspace. If NULL is passed it is sent to the scratchpad. This was an issue if no other window except the scratchpad container was on the workspace. Fixes #4240
-rw-r--r--include/sway/tree/root.h6
-rw-r--r--sway/commands/move.c2
-rw-r--r--sway/tree/container.c4
-rw-r--r--sway/tree/root.c27
4 files changed, 25 insertions, 14 deletions
diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h
index c4f84207..799d751a 100644
--- a/include/sway/tree/root.h
+++ b/include/sway/tree/root.h
@@ -46,8 +46,12 @@ void root_destroy(struct sway_root *root);
46 46
47/** 47/**
48 * Move a container to the scratchpad. 48 * Move a container to the scratchpad.
49 * If a workspace is passed, the container is assumed to have been in
50 * the scratchpad before and is shown on the workspace.
51 * The ws parameter can safely be NULL.
49 */ 52 */
50void root_scratchpad_add_container(struct sway_container *con); 53void root_scratchpad_add_container(struct sway_container *con,
54 struct sway_workspace *ws);
51 55
52/** 56/**
53 * Remove a container from the scratchpad. 57 * Remove a container from the scratchpad.
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 9c6e69ec..6fd66f28 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -856,7 +856,7 @@ static struct cmd_results *cmd_move_to_scratchpad(void) {
856 } 856 }
857 857
858 if (!con->scratchpad) { 858 if (!con->scratchpad) {
859 root_scratchpad_add_container(con); 859 root_scratchpad_add_container(con, NULL);
860 } else if (con->workspace) { 860 } else if (con->workspace) {
861 root_scratchpad_hide(con); 861 root_scratchpad_hide(con);
862 } 862 }
diff --git a/sway/tree/container.c b/sway/tree/container.c
index c4d21f0a..89a47151 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1378,10 +1378,12 @@ void container_replace(struct sway_container *container,
1378 struct sway_container *replacement) { 1378 struct sway_container *replacement) {
1379 enum sway_fullscreen_mode fullscreen = container->fullscreen_mode; 1379 enum sway_fullscreen_mode fullscreen = container->fullscreen_mode;
1380 bool scratchpad = container->scratchpad; 1380 bool scratchpad = container->scratchpad;
1381 struct sway_workspace *ws = NULL;
1381 if (fullscreen != FULLSCREEN_NONE) { 1382 if (fullscreen != FULLSCREEN_NONE) {
1382 container_fullscreen_disable(container); 1383 container_fullscreen_disable(container);
1383 } 1384 }
1384 if (scratchpad) { 1385 if (scratchpad) {
1386 ws = container->workspace;
1385 root_scratchpad_show(container); 1387 root_scratchpad_show(container);
1386 root_scratchpad_remove_container(container); 1388 root_scratchpad_remove_container(container);
1387 } 1389 }
@@ -1390,7 +1392,7 @@ void container_replace(struct sway_container *container,
1390 container_detach(container); 1392 container_detach(container);
1391 } 1393 }
1392 if (scratchpad) { 1394 if (scratchpad) {
1393 root_scratchpad_add_container(replacement); 1395 root_scratchpad_add_container(replacement, ws);
1394 } 1396 }
1395 switch (fullscreen) { 1397 switch (fullscreen) {
1396 case FULLSCREEN_WORKSPACE: 1398 case FULLSCREEN_WORKSPACE:
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 1dabc287..55d78487 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -54,7 +54,7 @@ void root_destroy(struct sway_root *root) {
54 free(root); 54 free(root);
55} 55}
56 56
57void root_scratchpad_add_container(struct sway_container *con) { 57void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
58 if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) { 58 if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
59 return; 59 return;
60 } 60 }
@@ -77,18 +77,23 @@ void root_scratchpad_add_container(struct sway_container *con) {
77 container_detach(con); 77 container_detach(con);
78 con->scratchpad = true; 78 con->scratchpad = true;
79 list_add(root->scratchpad, con); 79 list_add(root->scratchpad, con);
80 80 if (ws) {
81 struct sway_seat *seat = input_manager_current_seat(); 81 workspace_add_floating(ws, con);
82 struct sway_node *new_focus = NULL;
83 if (parent) {
84 arrange_container(parent);
85 new_focus = seat_get_focus_inactive(seat, &parent->node);
86 } 82 }
87 if (!new_focus) { 83
88 arrange_workspace(workspace); 84 if (!ws) {
89 new_focus = seat_get_focus_inactive(seat, &workspace->node); 85 struct sway_seat *seat = input_manager_current_seat();
86 struct sway_node *new_focus = NULL;
87 if (parent) {
88 arrange_container(parent);
89 new_focus = seat_get_focus_inactive(seat, &parent->node);
90 }
91 if (!new_focus) {
92 arrange_workspace(workspace);
93 new_focus = seat_get_focus_inactive(seat, &workspace->node);
94 }
95 seat_set_focus(seat, new_focus);
90 } 96 }
91 seat_set_focus(seat, new_focus);
92 97
93 ipc_event_window(con, "move"); 98 ipc_event_window(con, "move");
94} 99}