mirror of
https://github.com/swaywm/sway.git
synced 2024-11-16 05:03:17 +00:00
Use noop output when there's no outputs connected
Instead of having NULL workspace->output pointers, use a noop output. This should be safer.
This commit is contained in:
parent
ab0248a545
commit
2301349ad5
|
@ -24,6 +24,7 @@ struct sway_server {
|
||||||
const char *socket;
|
const char *socket;
|
||||||
|
|
||||||
struct wlr_backend *backend;
|
struct wlr_backend *backend;
|
||||||
|
struct wlr_backend *noop_backend;
|
||||||
|
|
||||||
struct wlr_compositor *compositor;
|
struct wlr_compositor *compositor;
|
||||||
struct wlr_data_device_manager *data_device_manager;
|
struct wlr_data_device_manager *data_device_manager;
|
||||||
|
|
|
@ -31,7 +31,9 @@ struct sway_root {
|
||||||
|
|
||||||
list_t *outputs; // struct sway_output
|
list_t *outputs; // struct sway_output
|
||||||
list_t *scratchpad; // struct sway_container
|
list_t *scratchpad; // struct sway_container
|
||||||
list_t *saved_workspaces; // For when there's no connected outputs
|
|
||||||
|
// For when there's no connected outputs
|
||||||
|
struct sway_output *noop_output;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal new_node;
|
struct wl_signal new_node;
|
||||||
|
|
|
@ -386,7 +386,7 @@ static void damage_handle_frame(struct wl_listener *listener, void *data) {
|
||||||
void output_damage_whole(struct sway_output *output) {
|
void output_damage_whole(struct sway_output *output) {
|
||||||
// The output can exist with no wlr_output if it's just been disconnected
|
// The output can exist with no wlr_output if it's just been disconnected
|
||||||
// and the transaction to evacuate it has't completed yet.
|
// and the transaction to evacuate it has't completed yet.
|
||||||
if (output && output->wlr_output) {
|
if (output && output->wlr_output && output->damage) {
|
||||||
wlr_output_damage_add_whole(output->damage);
|
wlr_output_damage_add_whole(output->damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
|
#include <wlr/backend/noop.h>
|
||||||
#include <wlr/backend/session.h>
|
#include <wlr/backend/session.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/desktop/idle_inhibit_v1.h"
|
#include "sway/desktop/idle_inhibit_v1.h"
|
||||||
#include "sway/input/input-manager.h"
|
#include "sway/input/input-manager.h"
|
||||||
|
#include "sway/output.h"
|
||||||
#include "sway/server.h"
|
#include "sway/server.h"
|
||||||
#include "sway/tree/root.h"
|
#include "sway/tree/root.h"
|
||||||
#if HAVE_XWAYLAND
|
#if HAVE_XWAYLAND
|
||||||
|
@ -36,6 +38,7 @@ bool server_privileged_prepare(struct sway_server *server) {
|
||||||
server->wl_display = wl_display_create();
|
server->wl_display = wl_display_create();
|
||||||
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
|
server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
|
||||||
server->backend = wlr_backend_autocreate(server->wl_display, NULL);
|
server->backend = wlr_backend_autocreate(server->wl_display, NULL);
|
||||||
|
server->noop_backend = wlr_noop_backend_create(server->wl_display);
|
||||||
|
|
||||||
if (!server->backend) {
|
if (!server->backend) {
|
||||||
sway_log(SWAY_ERROR, "Unable to create backend");
|
sway_log(SWAY_ERROR, "Unable to create backend");
|
||||||
|
@ -116,6 +119,9 @@ bool server_init(struct sway_server *server) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_output *wlr_output = wlr_noop_add_output(server->noop_backend);
|
||||||
|
root->noop_output = output_create(wlr_output);
|
||||||
|
|
||||||
// This may have been set already via -Dtxn-timeout
|
// This may have been set already via -Dtxn-timeout
|
||||||
if (!server->txn_timeout_ms) {
|
if (!server->txn_timeout_ms) {
|
||||||
server->txn_timeout_ms = 200;
|
server->txn_timeout_ms = 200;
|
||||||
|
|
|
@ -57,12 +57,12 @@ static void restore_workspaces(struct sway_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saved workspaces
|
// Saved workspaces
|
||||||
for (int i = 0; i < root->saved_workspaces->length; ++i) {
|
while (root->noop_output->workspaces->length) {
|
||||||
struct sway_workspace *ws = root->saved_workspaces->items[i];
|
struct sway_workspace *ws = root->noop_output->workspaces->items[0];
|
||||||
|
workspace_detach(ws);
|
||||||
output_add_workspace(output, ws);
|
output_add_workspace(output, ws);
|
||||||
ipc_event_workspace(NULL, ws, "move");
|
ipc_event_workspace(NULL, ws, "move");
|
||||||
}
|
}
|
||||||
root->saved_workspaces->length = 0;
|
|
||||||
|
|
||||||
output_sort_workspaces(output);
|
output_sort_workspaces(output);
|
||||||
}
|
}
|
||||||
|
@ -177,6 +177,9 @@ static void output_evacuate(struct sway_output *output) {
|
||||||
if (!new_output) {
|
if (!new_output) {
|
||||||
new_output = fallback_output;
|
new_output = fallback_output;
|
||||||
}
|
}
|
||||||
|
if (!new_output) {
|
||||||
|
new_output = root->noop_output;
|
||||||
|
}
|
||||||
|
|
||||||
if (workspace_is_empty(workspace)) {
|
if (workspace_is_empty(workspace)) {
|
||||||
// If floating is not empty, there are sticky containers to move
|
// If floating is not empty, there are sticky containers to move
|
||||||
|
@ -187,14 +190,10 @@ static void output_evacuate(struct sway_output *output) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_output) {
|
|
||||||
workspace_output_add_priority(workspace, new_output);
|
workspace_output_add_priority(workspace, new_output);
|
||||||
output_add_workspace(new_output, workspace);
|
output_add_workspace(new_output, workspace);
|
||||||
output_sort_workspaces(new_output);
|
output_sort_workspaces(new_output);
|
||||||
ipc_event_workspace(NULL, workspace, "move");
|
ipc_event_workspace(NULL, workspace, "move");
|
||||||
} else {
|
|
||||||
list_add(root->saved_workspaces, workspace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ struct sway_root *root_create(void) {
|
||||||
wl_signal_init(&root->events.new_node);
|
wl_signal_init(&root->events.new_node);
|
||||||
root->outputs = create_list();
|
root->outputs = create_list();
|
||||||
root->scratchpad = create_list();
|
root->scratchpad = create_list();
|
||||||
root->saved_workspaces = create_list();
|
|
||||||
|
|
||||||
root->output_layout_change.notify = output_layout_handle_change;
|
root->output_layout_change.notify = output_layout_handle_change;
|
||||||
wl_signal_add(&root->output_layout->events.change,
|
wl_signal_add(&root->output_layout->events.change,
|
||||||
|
@ -50,7 +49,6 @@ struct sway_root *root_create(void) {
|
||||||
void root_destroy(struct sway_root *root) {
|
void root_destroy(struct sway_root *root) {
|
||||||
wl_list_remove(&root->output_layout_change.link);
|
wl_list_remove(&root->output_layout_change.link);
|
||||||
list_free(root->scratchpad);
|
list_free(root->scratchpad);
|
||||||
list_free(root->saved_workspaces);
|
|
||||||
list_free(root->outputs);
|
list_free(root->outputs);
|
||||||
wlr_output_layout_destroy(root->output_layout);
|
wlr_output_layout_destroy(root->output_layout);
|
||||||
free(root);
|
free(root);
|
||||||
|
@ -327,8 +325,8 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saved workspaces
|
// Saved workspaces
|
||||||
for (int i = 0; i < root->saved_workspaces->length; ++i) {
|
for (int i = 0; i < root->noop_output->workspaces->length; ++i) {
|
||||||
struct sway_workspace *ws = root->saved_workspaces->items[i];
|
struct sway_workspace *ws = root->noop_output->workspaces->items[i];
|
||||||
workspace_for_each_container(ws, f, data);
|
workspace_for_each_container(ws, f, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,8 +378,8 @@ struct sway_container *root_find_container(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saved workspaces
|
// Saved workspaces
|
||||||
for (int i = 0; i < root->saved_workspaces->length; ++i) {
|
for (int i = 0; i < root->noop_output->workspaces->length; ++i) {
|
||||||
struct sway_workspace *ws = root->saved_workspaces->items[i];
|
struct sway_workspace *ws = root->noop_output->workspaces->items[i];
|
||||||
if ((result = workspace_find_container(ws, test, data))) {
|
if ((result = workspace_find_container(ws, test, data))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,9 +518,10 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
|
||||||
return node->sway_container->workspace;
|
return node->sway_container->workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's no focus_inactive workspace then we must be running without
|
// When there's no outputs connected, the above should match a workspace on
|
||||||
// any outputs connected
|
// the noop output.
|
||||||
return root->saved_workspaces->items[0];
|
sway_assert(false, "Expected to find a workspace");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool should_focus(struct sway_view *view) {
|
static bool should_focus(struct sway_view *view) {
|
||||||
|
|
|
@ -158,13 +158,7 @@ void workspace_begin_destroy(struct sway_workspace *workspace) {
|
||||||
|
|
||||||
if (workspace->output) {
|
if (workspace->output) {
|
||||||
workspace_detach(workspace);
|
workspace_detach(workspace);
|
||||||
} else {
|
|
||||||
int index = list_find(root->saved_workspaces, workspace);
|
|
||||||
if (index != -1) {
|
|
||||||
list_del(root->saved_workspaces, index);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
workspace->node.destroying = true;
|
workspace->node.destroying = true;
|
||||||
node_set_dirty(&workspace->node);
|
node_set_dirty(&workspace->node);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue