aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop/xdg_shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/xdg_shell.c')
-rw-r--r--sway/desktop/xdg_shell.c78
1 files changed, 46 insertions, 32 deletions
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index d2b8822c..ab35b98f 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -8,6 +8,7 @@
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/server.h"
+#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/layout.h"
#include "sway/tree/view.h"
@@ -87,18 +88,14 @@ static const char *get_string_prop(struct sway_view *view, enum sway_view_prop p
}
}
-static void configure(struct sway_view *view, double lx, double ly, int width,
- int height) {
+static uint32_t configure(struct sway_view *view, double lx, double ly,
+ int width, int height) {
struct sway_xdg_shell_view *xdg_shell_view =
xdg_shell_view_from_view(view);
if (xdg_shell_view == NULL) {
- return;
+ return 0;
}
-
- xdg_shell_view->pending_width = width;
- xdg_shell_view->pending_height = height;
- wlr_xdg_toplevel_set_size(view->wlr_xdg_surface, width, height);
- view_update_position(view, lx, ly);
+ return wlr_xdg_toplevel_set_size(view->wlr_xdg_surface, width, height);
}
static void set_activated(struct sway_view *view, bool activated) {
@@ -146,16 +143,12 @@ static void _close(struct sway_view *view) {
}
}
-static void destroy(struct sway_view *view) {
+static void _free(struct sway_view *view) {
struct sway_xdg_shell_view *xdg_shell_view =
xdg_shell_view_from_view(view);
if (xdg_shell_view == NULL) {
return;
}
- wl_list_remove(&xdg_shell_view->destroy.link);
- wl_list_remove(&xdg_shell_view->map.link);
- wl_list_remove(&xdg_shell_view->unmap.link);
- wl_list_remove(&xdg_shell_view->request_fullscreen.link);
free(xdg_shell_view);
}
@@ -167,25 +160,23 @@ static const struct sway_view_impl view_impl = {
.wants_floating = wants_floating,
.for_each_surface = for_each_surface,
.close = _close,
- .destroy = destroy,
+ .free = _free,
};
static void handle_commit(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, commit);
struct sway_view *view = &xdg_shell_view->view;
- if (view->swayc && container_is_floating(view->swayc)) {
- int width = view->wlr_xdg_surface->geometry.width;
- int height = view->wlr_xdg_surface->geometry.height;
- if (!width && !height) {
- width = view->wlr_xdg_surface->surface->current->width;
- height = view->wlr_xdg_surface->surface->current->height;
- }
- view_update_size(view, width, height);
- } else {
- view_update_size(view, xdg_shell_view->pending_width,
- xdg_shell_view->pending_height);
+ struct wlr_xdg_surface *xdg_surface = view->wlr_xdg_surface;
+
+ if (!view->swayc) {
+ return;
}
+
+ if (view->swayc->instructions->length) {
+ transaction_notify_view_ready(view, xdg_surface->configure_serial);
+ }
+
view_update_title(view, false);
view_damage_from(view);
}
@@ -200,11 +191,18 @@ static void handle_new_popup(struct wl_listener *listener, void *data) {
static void handle_unmap(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, unmap);
+ struct sway_view *view = &xdg_shell_view->view;
- view_unmap(&xdg_shell_view->view);
+ if (!sway_assert(view->surface, "Cannot unmap unmapped view")) {
+ return;
+ }
+
+ struct sway_container *parent = view_unmap(view);
+ arrange_and_commit(parent);
wl_list_remove(&xdg_shell_view->commit.link);
wl_list_remove(&xdg_shell_view->new_popup.link);
+ view->surface = NULL;
}
static void handle_map(struct wl_listener *listener, void *data) {
@@ -219,8 +217,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_width = view->wlr_xdg_surface->surface->current->width;
view->natural_height = view->wlr_xdg_surface->surface->current->height;
}
+
view_map(view, view->wlr_xdg_surface->surface);
+ if (xdg_surface->toplevel->client_pending.fullscreen) {
+ view_set_fullscreen(view, true);
+ }
+ arrange_and_commit(view->swayc->parent);
+
xdg_shell_view->commit.notify = handle_commit;
wl_signal_add(&xdg_surface->surface->events.commit,
&xdg_shell_view->commit);
@@ -228,16 +232,22 @@ static void handle_map(struct wl_listener *listener, void *data) {
xdg_shell_view->new_popup.notify = handle_new_popup;
wl_signal_add(&xdg_surface->events.new_popup,
&xdg_shell_view->new_popup);
-
- if (xdg_surface->toplevel->client_pending.fullscreen) {
- view_set_fullscreen(view, true);
- }
}
static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, destroy);
- view_destroy(&xdg_shell_view->view);
+ struct sway_view *view = &xdg_shell_view->view;
+ if (!sway_assert(view->swayc == NULL || view->swayc->destroying,
+ "Tried to destroy a mapped view")) {
+ return;
+ }
+ wl_list_remove(&xdg_shell_view->destroy.link);
+ wl_list_remove(&xdg_shell_view->map.link);
+ wl_list_remove(&xdg_shell_view->unmap.link);
+ wl_list_remove(&xdg_shell_view->request_fullscreen.link);
+ view->wlr_xdg_surface = NULL;
+ view_destroy(view);
}
static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
@@ -246,6 +256,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
struct wlr_xdg_toplevel_set_fullscreen_event *e = data;
struct wlr_xdg_surface *xdg_surface =
xdg_shell_view->view.wlr_xdg_surface;
+ struct sway_view *view = &xdg_shell_view->view;
if (!sway_assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL,
"xdg_shell requested fullscreen of surface with role %i",
@@ -256,7 +267,10 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
return;
}
- view_set_fullscreen(&xdg_shell_view->view, e->fullscreen);
+ view_set_fullscreen(view, e->fullscreen);
+
+ struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
+ arrange_and_commit(ws);
}
void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {