aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/layer-shell.c19
-rw-r--r--include/rootston/input.h2
-rw-r--r--include/wlr/types/wlr_layer_shell.h3
-rw-r--r--protocol/wlr-layer-shell-unstable-v1.xml6
-rw-r--r--rootston/desktop.c8
-rw-r--r--rootston/layer_shell.c12
-rw-r--r--rootston/seat.c11
-rw-r--r--types/wlr_layer_shell.c5
8 files changed, 47 insertions, 19 deletions
diff --git a/examples/layer-shell.c b/examples/layer-shell.c
index 870a3f22..245d762f 100644
--- a/examples/layer-shell.c
+++ b/examples/layer-shell.c
@@ -1,6 +1,7 @@
#define _POSIX_C_SOURCE 199309L
#include <assert.h>
#include <GLES2/gl2.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -28,7 +29,7 @@ struct wl_egl_window *egl_window;
struct wlr_egl_surface *egl_surface;
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 anchor = 0;
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,
&wl_shm_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) {
- if (output == 0 && !wl_output) {
- wl_output = wl_registry_bind(registry, name,
- &wl_output_interface, 1);
- } else {
- output--;
+ if (output != UINT32_MAX) {
+ if (!wl_output) {
+ wl_output = wl_registry_bind(registry, name,
+ &wl_output_interface, 1);
+ } else {
+ output--;
+ }
}
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
seat = wl_registry_bind(registry, name,
@@ -426,10 +429,6 @@ int main(int argc, char **argv) {
fprintf(stderr, "layer_shell not available\n");
return 1;
}
- if (wl_output == NULL) {
- fprintf(stderr, "wl_output not available\n");
- return 1;
- }
cursor_theme = wl_cursor_theme_load(NULL, 16, shm);
assert(cursor_theme);
diff --git a/include/rootston/input.h b/include/rootston/input.h
index 4395a0f7..ef46fab2 100644
--- a/include/rootston/input.h
+++ b/include/rootston/input.h
@@ -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_last_active_seat(struct roots_input *input);
+
#endif
diff --git a/include/wlr/types/wlr_layer_shell.h b/include/wlr/types/wlr_layer_shell.h
index 1312e568..79b3a4ea 100644
--- a/include/wlr/types/wlr_layer_shell.h
+++ b/include/wlr/types/wlr_layer_shell.h
@@ -27,6 +27,9 @@ struct wlr_layer_shell {
struct wl_listener display_destroy;
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;
} events;
diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml
index 3181c0bb..6a5d5d35 100644
--- a/protocol/wlr-layer-shell-unstable-v1.xml
+++ b/protocol/wlr-layer-shell-unstable-v1.xml
@@ -47,12 +47,16 @@
or manipulate a buffer prior to the first layer_surface.configure call
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
surface.
</description>
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
<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="namespace" type="string" summary="namespace for the layer surface"/>
</request>
diff --git a/rootston/desktop.c b/rootston/desktop.c
index 6ddf56b8..0949b5db 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -326,13 +326,7 @@ bool view_center(struct roots_view *view) {
struct roots_desktop *desktop = view->desktop;
struct roots_input *input = desktop->server->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;
- }
- }
+ struct roots_seat *seat = input_last_active_seat(input);
if (!seat) {
return false;
}
diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c
index 895b0385..b6f7ba4c 100644
--- a/rootston/layer_shell.c
+++ b/rootston/layer_shell.c
@@ -312,6 +312,18 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
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;
wl_signal_add(&layer_surface->surface->events.commit,
&roots_surface->surface_commit);
diff --git a/rootston/seat.c b/rootston/seat.c
index e12df7d6..44673c75 100644
--- a/rootston/seat.c
+++ b/rootston/seat.c
@@ -999,3 +999,14 @@ void roots_seat_end_compositor_grab(struct roots_seat *seat) {
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;
+}
diff --git a/types/wlr_layer_shell.c b/types/wlr_layer_shell.c
index c4e39a17..a567b8bc 100644
--- a/types/wlr_layer_shell.c
+++ b/types/wlr_layer_shell.c
@@ -276,6 +276,7 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface,
surface->added = true;
wlr_signal_emit_safe(&surface->shell->events.new_surface,
surface);
+ assert(surface->output);
}
if (surface->configured && wlr_surface_has_buffer(surface->surface) &&
!surface->mapped) {
@@ -319,7 +320,9 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client,
surface->shell = shell;
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,
&zwlr_layer_surface_v1_interface,
wl_resource_get_version(client_resource),