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 | 14 | ||||
| -rw-r--r-- | sway/desktop/transaction.c | 51 | ||||
| -rw-r--r-- | sway/desktop/xdg_shell.c | 20 | ||||
| -rw-r--r-- | sway/desktop/xdg_shell_v6.c | 21 | ||||
| -rw-r--r-- | sway/desktop/xwayland.c | 34 | 
7 files changed, 132 insertions, 35 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 43ed9793..1e4f196b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -144,15 +144,16 @@ void output_view_for_each_surface(struct sway_output *output,  		.user_iterator = iterator,  		.user_data = user_data,  		.output = output, -		.ox = view->swayc->current.view_x - output->swayc->current.swayc_x, -		.oy = view->swayc->current.view_y - output->swayc->current.swayc_y, +		.ox = view->swayc->current.view_x - output->swayc->current.swayc_x +			- view->geometry.x, +		.oy = view->swayc->current.view_y - output->swayc->current.swayc_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 6e1e31f0..7c48d0d2 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -193,9 +193,11 @@ static void render_view_toplevels(struct sway_view *view,  		.alpha = alpha,  	};  	// Render all toplevels without descending into popups -	output_surface_for_each_surface(output, view->surface, -			view->swayc->current.view_x - output->wlr_output->lx, -			view->swayc->current.view_y - output->wlr_output->ly, +	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);  } @@ -227,8 +229,10 @@ static void render_saved_view(struct sway_view *view,  		return;  	}  	struct wlr_box box = { -		.x = view->swayc->current.view_x - output->swayc->current.swayc_x, -		.y = view->swayc->current.view_y - output->swayc->current.swayc_y, +		.x = view->swayc->current.view_x - output->swayc->current.swayc_x - +			view->saved_geometry.x, +		.y = view->swayc->current.view_y - output->swayc->current.swayc_y - +			view->saved_geometry.y,  		.width = view->saved_buffer_width,  		.height = view->saved_buffer_height,  	}; diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index e89f01d8..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,25 +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_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_box = { -			.x = instruction->state.swayc_x, -			.y = instruction->state.swayc_y, -			.width = instruction->state.swayc_width, -			.height = instruction->state.swayc_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_box); -				output_damage_box(output->sway_output, &new_box); -			} +		// 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; +			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 @@ -204,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;  	}  } @@ -297,6 +304,8 @@ static void transaction_commit(struct sway_transaction *transaction) {  		}  		if (con->type == C_VIEW) {  			view_save_buffer(con->sway_view); +			memcpy(&con->sway_view->saved_geometry, &con->sway_view->geometry, +					sizeof(struct wlr_box));  		}  		con->instruction = instruction;  	} @@ -355,7 +364,9 @@ static void set_instruction_ready(  	}  	instruction->container->instruction = NULL; -	transaction_progress_queue(); +	if (!txn_debug) { +		transaction_progress_queue(); +	}  }  void transaction_notify_view_ready_by_serial(struct sway_view *view, diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 6a7a3f7f..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" @@ -107,7 +108,8 @@ static void get_constraints(struct sway_view *view, double *min_width,  	*max_height = state->max_height > 0 ? state->max_height : DBL_MAX;  } -static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { +static const char *get_string_prop(struct sway_view *view, +		enum sway_view_prop prop) {  	if (xdg_shell_view_from_view(view) == NULL) {  		return NULL;  	} @@ -255,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 5b3c7b2b..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" @@ -106,7 +107,8 @@ static void get_constraints(struct sway_view *view, double *min_width,  	*max_height = state->max_height > 0 ? state->max_height : DBL_MAX;  } -static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { +static const char *get_string_prop(struct sway_view *view, +		enum sway_view_prop prop) {  	if (xdg_shell_v6_view_from_view(view) == NULL) {  		return NULL;  	} @@ -250,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 14f59b9c..ce7235e4 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -277,18 +277,44 @@ 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);  	struct sway_view *view = &xwayland_view->view;  	struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; -	struct wlr_surface_state *surface_state = &xsurface->surface->current; +	struct wlr_surface_state *state = &xsurface->surface->current;  	if (view->swayc->instruction) { +		get_geometry(view, &view->geometry);  		transaction_notify_view_ready_by_size(view, -				surface_state->width, surface_state->height); -	} else if (container_is_floating(view->swayc)) { -		view_update_size(view, surface_state->width, surface_state->height); +				state->width, state->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)) { +			// 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); | 
