Merge pull request #887 from swaywm/layer-optional-output

Update layer shell with optional wl_output
This commit is contained in:
Drew DeVault 2018-04-23 11:11:41 +02:00 committed by GitHub
commit da944cccb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 19 deletions

View file

@ -1,6 +1,7 @@
#define _POSIX_C_SOURCE 199309L #define _POSIX_C_SOURCE 199309L
#include <assert.h> #include <assert.h>
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -28,7 +29,7 @@ struct wl_egl_window *egl_window;
struct wlr_egl_surface *egl_surface; struct wlr_egl_surface *egl_surface;
struct wl_callback *frame_callback; struct wl_callback *frame_callback;
static uint32_t output = 0; static uint32_t output = UINT32_MAX;
static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND;
static uint32_t anchor = 0; static uint32_t anchor = 0;
static uint32_t width = 256, height = 256; static uint32_t width = 256, height = 256;
@ -283,11 +284,13 @@ static void handle_global(void *data, struct wl_registry *registry,
shm = wl_registry_bind(registry, name, shm = wl_registry_bind(registry, name,
&wl_shm_interface, 1); &wl_shm_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) { } else if (strcmp(interface, "wl_output") == 0) {
if (output == 0 && !wl_output) { if (output != UINT32_MAX) {
wl_output = wl_registry_bind(registry, name, if (!wl_output) {
&wl_output_interface, 1); wl_output = wl_registry_bind(registry, name,
} else { &wl_output_interface, 1);
output--; } else {
output--;
}
} }
} else if (strcmp(interface, wl_seat_interface.name) == 0) { } else if (strcmp(interface, wl_seat_interface.name) == 0) {
seat = wl_registry_bind(registry, name, seat = wl_registry_bind(registry, name,
@ -426,10 +429,6 @@ int main(int argc, char **argv) {
fprintf(stderr, "layer_shell not available\n"); fprintf(stderr, "layer_shell not available\n");
return 1; return 1;
} }
if (wl_output == NULL) {
fprintf(stderr, "wl_output not available\n");
return 1;
}
cursor_theme = wl_cursor_theme_load(NULL, 16, shm); cursor_theme = wl_cursor_theme_load(NULL, 16, shm);
assert(cursor_theme); assert(cursor_theme);

View file

@ -30,4 +30,6 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view);
struct roots_seat *input_get_seat(struct roots_input *input, char *name); struct roots_seat *input_get_seat(struct roots_input *input, char *name);
struct roots_seat *input_last_active_seat(struct roots_input *input);
#endif #endif

View file

@ -27,6 +27,9 @@ struct wlr_layer_shell {
struct wl_listener display_destroy; struct wl_listener display_destroy;
struct { struct {
// struct wlr_layer_surface *
// Note: the output may be NULL. In this case, it is your
// responsibility to assign an output before returning.
struct wl_signal new_surface; struct wl_signal new_surface;
} events; } events;

View file

@ -47,12 +47,16 @@
or manipulate a buffer prior to the first layer_surface.configure call or manipulate a buffer prior to the first layer_surface.configure call
must also be treated as errors. must also be treated as errors.
You may pass NULL for output to allow the compositor to decide which
output to use. Generally this will be the one that the user most
recently interacted with.
Clients can specify a namespace that defines the purpose of the layer Clients can specify a namespace that defines the purpose of the layer
surface. surface.
</description> </description>
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
<arg name="surface" type="object" interface="wl_surface"/> <arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output"/> <arg name="output" type="object" interface="wl_output" allow-null="true"/>
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
<arg name="namespace" type="string" summary="namespace for the layer surface"/> <arg name="namespace" type="string" summary="namespace for the layer surface"/>
</request> </request>

View file

@ -326,13 +326,7 @@ bool view_center(struct roots_view *view) {
struct roots_desktop *desktop = view->desktop; struct roots_desktop *desktop = view->desktop;
struct roots_input *input = desktop->server->input; struct roots_input *input = desktop->server->input;
struct roots_seat *seat = NULL, *_seat; struct roots_seat *seat = input_last_active_seat(input);
wl_list_for_each(_seat, &input->seats, link) {
if (!seat || (seat->seat->last_event.tv_sec > _seat->seat->last_event.tv_sec &&
seat->seat->last_event.tv_nsec > _seat->seat->last_event.tv_nsec)) {
seat = _seat;
}
}
if (!seat) { if (!seat) {
return false; return false;
} }

View file

@ -312,6 +312,18 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
return; return;
} }
if (!layer_surface->output) {
struct roots_input *input = desktop->server->input;
struct roots_seat *seat = input_last_active_seat(input);
assert(seat); // Technically speaking we should handle this case
struct wlr_output *output =
wlr_output_layout_output_at(desktop->layout,
seat->cursor->cursor->x,
seat->cursor->cursor->y);
assert(output); // And this one
layer_surface->output = output;
}
roots_surface->surface_commit.notify = handle_surface_commit; roots_surface->surface_commit.notify = handle_surface_commit;
wl_signal_add(&layer_surface->surface->events.commit, wl_signal_add(&layer_surface->surface->events.commit,
&roots_surface->surface_commit); &roots_surface->surface_commit);

View file

@ -999,3 +999,14 @@ void roots_seat_end_compositor_grab(struct roots_seat *seat) {
cursor->mode = ROOTS_CURSOR_PASSTHROUGH; cursor->mode = ROOTS_CURSOR_PASSTHROUGH;
} }
struct roots_seat *input_last_active_seat(struct roots_input *input) {
struct roots_seat *seat = NULL, *_seat;
wl_list_for_each(_seat, &input->seats, link) {
if (!seat || (seat->seat->last_event.tv_sec > _seat->seat->last_event.tv_sec &&
seat->seat->last_event.tv_nsec > _seat->seat->last_event.tv_nsec)) {
seat = _seat;
}
}
return seat;
}

View file

@ -276,6 +276,7 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface,
surface->added = true; surface->added = true;
wlr_signal_emit_safe(&surface->shell->events.new_surface, wlr_signal_emit_safe(&surface->shell->events.new_surface,
surface); surface);
assert(surface->output);
} }
if (surface->configured && wlr_surface_has_buffer(surface->surface) && if (surface->configured && wlr_surface_has_buffer(surface->surface) &&
!surface->mapped) { !surface->mapped) {
@ -319,7 +320,9 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
surface->shell = shell; surface->shell = shell;
surface->surface = wlr_surface; surface->surface = wlr_surface;
surface->output = wlr_output_from_resource(output_resource); if (output_resource) {
surface->output = wlr_output_from_resource(output_resource);
}
surface->resource = wl_resource_create(wl_client, surface->resource = wl_resource_create(wl_client,
&zwlr_layer_surface_v1_interface, &zwlr_layer_surface_v1_interface,
wl_resource_get_version(client_resource), wl_resource_get_version(client_resource),