aboutsummaryrefslogtreecommitdiff
path: root/rootston
diff options
context:
space:
mode:
Diffstat (limited to 'rootston')
-rw-r--r--rootston/desktop.c21
-rw-r--r--rootston/output.c33
-rw-r--r--rootston/wl_shell.c23
3 files changed, 72 insertions, 5 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c
index bef0fad4..d5cac575 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -103,6 +103,12 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly,
for (int i = desktop->views->length - 1; i >= 0; --i) {
struct roots_view *view = desktop->views->items[i];
+ if (view->type == ROOTS_WL_SHELL_VIEW &&
+ view->wl_shell_surface->state ==
+ WLR_WL_SHELL_SURFACE_STATE_POPUP) {
+ continue;
+ }
+
double view_sx = lx - view->x;
double view_sy = ly - view->y;
@@ -138,6 +144,21 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly,
}
}
+ if (view->type == ROOTS_WL_SHELL_VIEW) {
+ // TODO: test if this works with rotated views
+ double popup_sx, popup_sy;
+ struct wlr_wl_shell_surface *popup =
+ wlr_wl_shell_surface_popup_at(view->wl_shell_surface,
+ view_sx, view_sy, &popup_sx, &popup_sy);
+
+ if (popup) {
+ *sx = view_sx - popup_sx;
+ *sy = view_sy - popup_sy;
+ *surface = popup->surface;
+ return view;
+ }
+ }
+
double sub_x, sub_y;
struct wlr_subsurface *subsurface =
wlr_surface_subsurface_at(view->wlr_surface,
diff --git a/rootston/output.c b/rootston/output.c
index 4ce10ea2..39a90fe3 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -19,7 +19,6 @@ static inline int64_t timespec_to_msec(const struct timespec *a) {
static void render_surface(struct wlr_surface *surface,
struct roots_desktop *desktop, struct wlr_output *wlr_output,
struct timespec *when, double lx, double ly, float rotation) {
- wlr_surface_flush_damage(surface);
if (surface->texture->valid) {
int width = surface->current->buffer_width;
int height = surface->current->buffer_height;
@@ -98,13 +97,39 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface,
}
}
+static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, struct roots_desktop *desktop,
+ struct wlr_output *wlr_output, struct timespec *when, double lx,
+ double ly, float rotation, bool is_child) {
+ if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) {
+ render_surface(surface->surface, desktop, wlr_output, when,
+ lx, ly, rotation);
+ struct wlr_wl_shell_surface *popup;
+ wl_list_for_each(popup, &surface->popups, popup_link) {
+ render_wl_shell_surface(popup, desktop, wlr_output, when,
+ lx + popup->transient_state->x,
+ ly + popup->transient_state->y,
+ rotation, true);
+ }
+ }
+}
+
static void render_view(struct roots_view *view, struct roots_desktop *desktop,
struct wlr_output *wlr_output, struct timespec *when) {
- render_surface(view->wlr_surface, desktop, wlr_output, when,
- view->x, view->y, view->rotation);
- if (view->type == ROOTS_XDG_SHELL_V6_VIEW) {
+ switch (view->type) {
+ case ROOTS_XDG_SHELL_V6_VIEW:
+ render_surface(view->wlr_surface, desktop, wlr_output, when,
+ view->x, view->y, view->rotation);
render_xdg_v6_popups(view->xdg_surface_v6, desktop, wlr_output,
when, view->x, view->y, view->rotation);
+ break;
+ case ROOTS_WL_SHELL_VIEW:
+ render_wl_shell_surface(view->wl_shell_surface, desktop, wlr_output,
+ when, view->x, view->y, view->rotation, false);
+ break;
+ case ROOTS_XWAYLAND_VIEW:
+ render_surface(view->wlr_surface, desktop, wlr_output, when,
+ view->x, view->y, view->rotation);
+ break;
}
}
diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c
index 009a8c06..34f53c7a 100644
--- a/rootston/wl_shell.c
+++ b/rootston/wl_shell.c
@@ -73,6 +73,14 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
free(roots_surface);
}
+static int shell_surface_compare_equals(const void *item, const void *cmp_to) {
+ const struct roots_view *view = item;
+ if (view->type == ROOTS_WL_SHELL_VIEW && view->wl_shell_surface == cmp_to) {
+ return 0;
+ }
+ return -1;
+}
+
void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
struct roots_desktop *desktop =
wl_container_of(listener, desktop, wl_shell_surface);
@@ -107,7 +115,20 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
struct roots_view *view = calloc(1, sizeof(struct roots_view));
view->type = ROOTS_WL_SHELL_VIEW;
- view->x = view->y = 200;
+
+ if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TRANSIENT) {
+ // we need to map it relative to the parent
+ int i =
+ list_seq_find(desktop->views,
+ shell_surface_compare_equals, surface->parent);
+ if (i != -1) {
+ struct roots_view *parent = desktop->views->items[i];
+ view->x = parent->x + surface->transient_state->x;
+ view->y = parent->y + surface->transient_state->y;
+ }
+ } else {
+ view->x = view->y = 200;
+ }
view->wl_shell_surface = surface;
view->roots_wl_shell_surface = roots_surface;
view->wlr_surface = surface->surface;