diff options
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/desktop.c | 18 | ||||
-rw-r--r-- | sway/desktop/output.c | 9 | ||||
-rw-r--r-- | sway/desktop/render.c | 10 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 72 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 28 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 29 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 36 |
7 files changed, 115 insertions, 87 deletions
diff --git a/sway/desktop/desktop.c b/sway/desktop/desktop.c index 6575519d..72650397 100644 --- a/sway/desktop/desktop.c +++ b/sway/desktop/desktop.c @@ -22,3 +22,21 @@ void desktop_damage_whole_container(struct sway_container *con) { } } } + +void desktop_damage_box(struct wlr_box *box) { + for (int i = 0; i < root_container.children->length; ++i) { + struct sway_container *cont = root_container.children->items[i]; + output_damage_box(cont->sway_output, box); + } +} + +void desktop_damage_view(struct sway_view *view) { + desktop_damage_whole_container(view->swayc); + struct wlr_box box = { + .x = view->swayc->current.view_x - view->geometry.x, + .y = view->swayc->current.view_y - view->geometry.y, + .width = view->surface->current.width, + .height = view->surface->current.height, + }; + desktop_damage_box(&box); +} diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cb0b4a07..b4564fac 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -140,23 +140,20 @@ void output_surface_for_each_surface(struct sway_output *output, void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data) { - struct wlr_box geometry; - view_get_geometry(view, &geometry); struct surface_iterator_data data = { .user_iterator = iterator, .user_data = user_data, .output = output, .ox = view->swayc->current.view_x - output->swayc->current.swayc_x - - geometry.x, + - view->geometry.x, .oy = view->swayc->current.view_y - output->swayc->current.swayc_y - - geometry.y, + - view->geometry.y, .width = view->swayc->current.view_width, .height = view->swayc->current.view_height, .rotation = 0, // TODO }; - view_for_each_surface(view, - output_for_each_surface_iterator, &data); + view_for_each_surface(view, output_for_each_surface_iterator, &data); } void output_view_for_each_popup(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 28c5a3ed..a4b624b8 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -192,12 +192,12 @@ static void render_view_toplevels(struct sway_view *view, .damage = damage, .alpha = alpha, }; - struct wlr_box geometry; - view_get_geometry(view, &geometry); // Render all toplevels without descending into popups - output_surface_for_each_surface(output, view->surface, - view->swayc->current.view_x - output->wlr_output->lx - geometry.x, - view->swayc->current.view_y - output->wlr_output->ly - geometry.y, + double ox = + view->swayc->current.view_x - output->wlr_output->lx - view->geometry.x; + double oy = + view->swayc->current.view_y - output->wlr_output->ly - view->geometry.y; + output_surface_for_each_surface(output, view->surface, ox, oy, render_surface_iterator, &data); } diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7383c455..c300558a 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -6,6 +6,7 @@ #include <time.h> #include <wlr/types/wlr_buffer.h> #include "sway/debug.h" +#include "sway/desktop.h" #include "sway/desktop/idle_inhibit_v1.h" #include "sway/desktop/transaction.h" #include "sway/output.h" @@ -169,51 +170,17 @@ static void transaction_apply(struct sway_transaction *transaction) { transaction->instructions->items[i]; struct sway_container *container = instruction->container; - // Damage the old and new locations - struct wlr_box old_con_box = { - .x = container->current.swayc_x, - .y = container->current.swayc_y, - .width = container->current.swayc_width, - .height = container->current.swayc_height, - }; - struct wlr_box new_con_box = { - .x = instruction->state.swayc_x, - .y = instruction->state.swayc_y, - .width = instruction->state.swayc_width, - .height = instruction->state.swayc_height, - }; - // Handle geometry, which may overflow the bounds of the container - struct wlr_box old_surface_box = {0,0,0,0}; - struct wlr_box new_surface_box = {0,0,0,0}; - if (container->type == C_VIEW) { + // Damage the old location + desktop_damage_whole_container(container); + if (container->type == C_VIEW && container->sway_view->saved_buffer) { struct sway_view *view = container->sway_view; - if (container->sway_view->saved_buffer) { - old_surface_box.x = - container->current.view_x - view->saved_geometry.x; - old_surface_box.y = - container->current.view_y - view->saved_geometry.y; - old_surface_box.width = view->saved_buffer_width; - old_surface_box.height = view->saved_buffer_height; - } - struct wlr_surface *surface = container->sway_view->surface; - if (surface) { - struct wlr_box geometry; - view_get_geometry(view, &geometry); - new_surface_box.x = instruction->state.view_x - geometry.x; - new_surface_box.y = instruction->state.view_y - geometry.y; - new_surface_box.width = surface->current.width; - new_surface_box.height = surface->current.height; - } - } - for (int j = 0; j < root_container.current.children->length; ++j) { - struct sway_container *output = - root_container.current.children->items[j]; - if (output->sway_output) { - output_damage_box(output->sway_output, &old_con_box); - output_damage_box(output->sway_output, &new_con_box); - output_damage_box(output->sway_output, &old_surface_box); - output_damage_box(output->sway_output, &new_surface_box); - } + struct wlr_box box = { + .x = container->current.view_x - view->saved_geometry.x, + .y = container->current.view_y - view->saved_geometry.y, + .width = view->saved_buffer_width, + .height = view->saved_buffer_height, + }; + desktop_damage_box(&box); } // There are separate children lists for each instruction state, the @@ -230,6 +197,20 @@ static void transaction_apply(struct sway_transaction *transaction) { view_remove_saved_buffer(container->sway_view); } + // Damage the new location + desktop_damage_whole_container(container); + if (container->type == C_VIEW && container->sway_view->surface) { + struct sway_view *view = container->sway_view; + struct wlr_surface *surface = view->surface; + struct wlr_box box = { + .x = container->current.view_x - view->geometry.x, + .y = container->current.view_y - view->geometry.y, + .width = surface->current.width, + .height = surface->current.height, + }; + desktop_damage_box(&box); + } + container->instruction = NULL; } } @@ -323,7 +304,8 @@ static void transaction_commit(struct sway_transaction *transaction) { } if (con->type == C_VIEW) { view_save_buffer(con->sway_view); - view_get_geometry(con->sway_view, &con->sway_view->saved_geometry); + memcpy(&con->sway_view->saved_geometry, &con->sway_view->geometry, + sizeof(struct wlr_box)); } con->instruction = instruction; } diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 2b260357..aae129bd 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -7,6 +7,7 @@ #include <wlr/util/edges.h> #include "log.h" #include "sway/decoration.h" +#include "sway/desktop.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/server.h" @@ -122,16 +123,6 @@ static const char *get_string_prop(struct sway_view *view, } } -static void get_geometry(struct sway_view *view, struct wlr_box *box) { - struct sway_xdg_shell_view *xdg_shell_view = - xdg_shell_view_from_view(view); - if (xdg_shell_view == NULL) { - return; - } - struct wlr_xdg_surface *surface = view->wlr_xdg_surface; - wlr_xdg_surface_get_geometry(surface, box); -} - static uint32_t configure(struct sway_view *view, double lx, double ly, int width, int height) { struct sway_xdg_shell_view *xdg_shell_view = @@ -242,7 +233,6 @@ static void destroy(struct sway_view *view) { static const struct sway_view_impl view_impl = { .get_constraints = get_constraints, .get_string_prop = get_string_prop, - .get_geometry = get_geometry, .configure = configure, .set_activated = set_activated, .set_tiled = set_tiled, @@ -267,8 +257,24 @@ static void handle_commit(struct wl_listener *listener, void *data) { } if (view->swayc->instruction) { + wlr_xdg_surface_get_geometry(xdg_surface, &view->geometry); transaction_notify_view_ready_by_serial(view, xdg_surface->configure_serial); + } else { + struct wlr_box new_geo; + wlr_xdg_surface_get_geometry(xdg_surface, &new_geo); + + if ((new_geo.width != view->width || new_geo.height != view->height) && + container_is_floating(view->swayc)) { + // A floating view has unexpectedly sent a new size + desktop_damage_view(view); + view_update_size(view, new_geo.width, new_geo.height); + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + desktop_damage_view(view); + transaction_commit_dirty(); + } else { + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + } } view_damage_from(view); diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index bbc7456c..277c53a3 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -6,6 +6,7 @@ #include <wlr/types/wlr_xdg_shell_v6.h> #include "log.h" #include "sway/decoration.h" +#include "sway/desktop.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/server.h" @@ -121,16 +122,6 @@ static const char *get_string_prop(struct sway_view *view, } } -static void get_geometry(struct sway_view *view, struct wlr_box *box) { - struct sway_xdg_shell_v6_view *xdg_shell_v6_view = - xdg_shell_v6_view_from_view(view); - if (xdg_shell_v6_view == NULL) { - return; - } - struct wlr_xdg_surface_v6 *surface = view->wlr_xdg_surface_v6; - wlr_xdg_surface_v6_get_geometry(surface, box); -} - static uint32_t configure(struct sway_view *view, double lx, double ly, int width, int height) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = @@ -239,7 +230,6 @@ static void destroy(struct sway_view *view) { static const struct sway_view_impl view_impl = { .get_constraints = get_constraints, .get_string_prop = get_string_prop, - .get_geometry = get_geometry, .configure = configure, .set_activated = set_activated, .set_tiled = set_tiled, @@ -262,9 +252,26 @@ static void handle_commit(struct wl_listener *listener, void *data) { if (!view->swayc) { return; } + if (view->swayc->instruction) { + wlr_xdg_surface_v6_get_geometry(xdg_surface_v6, &view->geometry); transaction_notify_view_ready_by_serial(view, xdg_surface_v6->configure_serial); + } else { + struct wlr_box new_geo; + wlr_xdg_surface_v6_get_geometry(xdg_surface_v6, &new_geo); + + if ((new_geo.width != view->width || new_geo.height != view->height) && + container_is_floating(view->swayc)) { + // A floating view has unexpectedly sent a new size + desktop_damage_view(view); + view_update_size(view, new_geo.width, new_geo.height); + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + desktop_damage_view(view); + transaction_commit_dirty(); + } else { + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + } } view_damage_from(view); diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index e0c44b39..ce7235e4 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -277,6 +277,17 @@ static const struct sway_view_impl view_impl = { .destroy = destroy, }; +static void get_geometry(struct sway_view *view, struct wlr_box *box) { + box->x = box->y = 0; + if (view->surface) { + box->width = view->surface->current.width; + box->height = view->surface->current.height; + } else { + box->width = 0; + box->height = 0; + } +} + static void handle_commit(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, commit); @@ -285,18 +296,25 @@ static void handle_commit(struct wl_listener *listener, void *data) { struct wlr_surface_state *state = &xsurface->surface->current; if (view->swayc->instruction) { + get_geometry(view, &view->geometry); transaction_notify_view_ready_by_size(view, state->width, state->height); - } else if ((state->width != view->width || state->height != view->height) && + } else { + struct wlr_box new_geo; + get_geometry(view, &new_geo); + + if ((new_geo.width != view->width || new_geo.height != view->height) && container_is_floating(view->swayc)) { - // eg. The Firefox "Save As" dialog when downloading a file - // It maps at a small size then changes afterwards. - view->width = state->width; - view->height = state->height; - view->swayc->current.view_width = state->width; - view->swayc->current.view_height = state->height; - container_set_geometry_from_floating_view(view->swayc); - transaction_commit_dirty(); + // A floating view has unexpectedly sent a new size + // eg. The Firefox "Save As" dialog when downloading a file + desktop_damage_view(view); + view_update_size(view, new_geo.width, new_geo.height); + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + desktop_damage_view(view); + transaction_commit_dirty(); + } else { + memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + } } view_damage_from(view); |