diff --git a/include/sway/container.h b/include/sway/container.h index f6aae7d1..09e29291 100644 --- a/include/sway/container.h +++ b/include/sway/container.h @@ -4,7 +4,6 @@ #include #include #include - #include "list.h" typedef struct sway_container swayc_t; @@ -76,7 +75,7 @@ struct sway_container { wlc_handle handle; union { - struct wlr_output *output; + struct sway_output *output; } _handle; /** @@ -186,10 +185,11 @@ enum visibility_mask { VISIBLE = true } visible; +struct sway_output; /** * Allocates a new output container. */ -swayc_t *new_output(struct wlr_output *wlr_output); +swayc_t *new_output(struct sway_output *sway_output); /** * Allocates a new workspace container. */ diff --git a/include/sway/output.h b/include/sway/output.h index e1bdd3f0..2a222238 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -1,9 +1,20 @@ #ifndef _SWAY_OUTPUT_H #define _SWAY_OUTPUT_H - +#include +#include +#include #include "container.h" #include "focus.h" +struct sway_server; + +struct sway_output { + struct wlr_output *wlr_output; + struct wl_listener frame; + struct sway_server *server; + struct timespec last_frame; +}; + // Position is absolute coordinates on the edge where the adjacent output // should be searched for. swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos); diff --git a/include/sway/server.h b/include/sway/server.h index f3e86bcb..043c1a33 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -33,5 +33,6 @@ void server_fini(struct sway_server *server); void server_run(struct sway_server *server); void output_add_notify(struct wl_listener *listener, void *data); +void output_remove_notify(struct wl_listener *listener, void *data); #endif diff --git a/sway/commands/focus.c b/sway/commands/focus.c index defaba29..c83157b8 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include diff --git a/sway/commands/move.c b/sway/commands/move.c index 8d89f2ef..52c73e22 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 51363e76..6d0bebc5 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -1,21 +1,60 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include #include #include +#include #include "sway/server.h" #include "sway/container.h" #include "sway/workspace.h" +#include "sway/output.h" #include "log.h" +static void output_frame_notify(struct wl_listener *listener, void *data) { + struct sway_output *soutput = wl_container_of( + listener, soutput, frame); + struct wlr_output *wlr_output = data; + struct sway_server *server = soutput->server; + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + wlr_output_make_current(wlr_output); + wlr_renderer_begin(server->renderer, wlr_output); + + wlr_renderer_end(server->renderer); + wlr_output_swap_buffers(wlr_output); + + soutput->last_frame = now; +} + void output_add_notify(struct wl_listener *listener, void *data) { struct sway_server *server = wl_container_of(listener, server, output_add); struct wlr_output *wlr_output = data; sway_log(L_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); - swayc_t *op = new_output(wlr_output); - if (!sway_assert(op, "Failed to allocate output")) { + + struct sway_output *output = calloc(1, sizeof(struct sway_output)); + output->wlr_output = wlr_output; + output->server = server; + + swayc_t *node = new_output(output); + if (!sway_assert(node, "Failed to allocate output")) { return; } + // Switch to workspace if we need to if (swayc_active_workspace() == NULL) { - swayc_t *ws = op->children->items[0]; + swayc_t *ws = node->children->items[0]; workspace_switch(ws); } + + output->frame.notify = output_frame_notify; + wl_signal_add(&wlr_output->events.frame, &output->frame); +} + +void output_remove_notify(struct wl_listener *listener, void *data) { + struct sway_server *server = wl_container_of(listener, server, output_remove); + struct wlr_output *wlr_output = data; + sway_log(L_DEBUG, "Output %p %s removed", wlr_output, wlr_output->name); + // TODO } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 064509c9..1579a2d9 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include @@ -5,6 +6,7 @@ #include #include #include +#include "sway/output.h" #include "sway/container.h" #include "sway/input.h" #include "sway/ipc-json.h" @@ -18,7 +20,7 @@ static json_object *ipc_json_create_rect(swayc_t *c) { struct wlr_box box; if (c->type == C_OUTPUT) { - wlr_output_effective_resolution(c->_handle.output, + wlr_output_effective_resolution(c->_handle.output->wlr_output, &box.width, &box.height); } else { box.width = c->width; diff --git a/sway/server.c b/sway/server.c index b7ce4612..a7f47af3 100644 --- a/sway/server.c +++ b/sway/server.c @@ -30,6 +30,10 @@ bool server_init(struct sway_server *server) { server->output_add.notify = output_add_notify; wl_signal_add(&server->backend->events.output_add, &server->output_add); + server->output_remove.notify = output_remove_notify; + wl_signal_add(&server->backend->events.output_remove, + &server->output_remove); + server->socket = wl_display_add_socket_auto(server->wl_display); if (!sway_assert(server->socket, "Unable to open wayland socket")) { wlr_backend_destroy(server->backend); diff --git a/sway/tree/container.c b/sway/tree/container.c index 61c9c5e3..25bb858e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -120,10 +120,11 @@ static void update_root_geometry() { // New containers -swayc_t *new_output(struct wlr_output *wlr_output) { +swayc_t *new_output(struct sway_output *sway_output) { struct wlr_box size; - wlr_output_effective_resolution(wlr_output, &size.width, &size.height); - const char *name = wlr_output->name; + wlr_output_effective_resolution(sway_output->wlr_output, + &size.width, &size.height); + const char *name = sway_output->wlr_output->name; // Find current outputs to see if this already exists { int i, len = root_container.children->length; @@ -131,7 +132,8 @@ swayc_t *new_output(struct wlr_output *wlr_output) { swayc_t *op = root_container.children->items[i]; const char *op_name = op->name; if (op_name && name && strcmp(op_name, name) == 0) { - sway_log(L_DEBUG, "restoring output %p: %s", wlr_output, op_name); + sway_log(L_DEBUG, "restoring output %p: %s", + sway_output, op_name); return op; } } @@ -164,7 +166,7 @@ swayc_t *new_output(struct wlr_output *wlr_output) { } swayc_t *output = new_swayc(C_OUTPUT); - output->_handle.output = wlr_output; + output->_handle.output = sway_output; output->name = name ? strdup(name) : NULL; output->width = size.width; output->height = size.width; diff --git a/sway/tree/output.c b/sway/tree/output.c index c0f29c5a..edfcac98 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include