diff options
| author | Drew DeVault <[email protected]> | 2018-05-16 21:54:16 -0400 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2018-05-16 21:54:16 -0400 | 
| commit | c2c5a3f5f6bdc061acae4e0583c4fd85c7ed21ac (patch) | |
| tree | 02f3205870487dbedb981a1770a6ec77c8894c15 /sway/desktop | |
| parent | fe24f58297b4fb7bad94a5bad1593f12a764356c (diff) | |
| parent | f0212d66eee61517ab1bb0f8bb68784d50e14c9a (diff) | |
Merge pull request #1982 from RyanDwyer/show-marks
Implement show_marks
Diffstat (limited to 'sway/desktop')
| -rw-r--r-- | sway/desktop/output.c | 165 | 
1 files changed, 117 insertions, 48 deletions
| diff --git a/sway/desktop/output.c b/sway/desktop/output.c index b12130d9..94562052 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -287,7 +287,6 @@ static void render_rect(struct wlr_output *wlr_output,  		wlr_backend_get_renderer(wlr_output->backend);  	struct wlr_box box = *_box; -	scale_box(&box, wlr_output->scale);  	pixman_region32_t damage;  	pixman_region32_init(&damage); @@ -313,26 +312,33 @@ damage_finish:  /**   * Render decorations for a view with "border normal". + * + * Care must be taken not to render over the same pixel multiple times, + * otherwise the colors will be incorrect when using opacity.   */  static void render_container_simple_border_normal(struct sway_output *output,  		pixman_region32_t *output_damage,  		struct sway_container *con, struct border_colors *colors, -		struct wlr_texture *title_texture) { +		struct wlr_texture *title_texture, struct wlr_texture *marks_texture) {  	struct wlr_box box;  	float color[4]; +	struct sway_view *view = con->sway_view; +	float output_scale = output->wlr_output->scale; -	if (con->sway_view->border_left) { +	if (view->border_left) {  		// Child border - left edge  		memcpy(&color, colors->child_border, sizeof(float) * 4);  		color[3] *= con->alpha;  		box.x = con->x;  		box.y = con->y + 1; -		box.width = con->sway_view->border_thickness; -		box.height = con->height - 1; +		box.width = view->border_thickness; +		box.height = con->height - 1 +			- view->border_thickness * view->border_bottom; +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} -	if (con->sway_view->border_right) { +	if (view->border_right) {  		// Child border - right edge  		if (con->parent->children->length == 1  				&& con->parent->layout == L_HORIZ) { @@ -341,14 +347,16 @@ static void render_container_simple_border_normal(struct sway_output *output,  			memcpy(&color, colors->child_border, sizeof(float) * 4);  		}  		color[3] *= con->alpha; -		box.x = con->x + con->width - con->sway_view->border_thickness; +		box.x = con->x + con->width - view->border_thickness;  		box.y = con->y + 1; -		box.width = con->sway_view->border_thickness; -		box.height = con->height - 1; +		box.width = view->border_thickness; +		box.height = con->height - 1 +			- view->border_thickness * view->border_bottom; +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} -	if (con->sway_view->border_bottom) { +	if (view->border_bottom) {  		// Child border - bottom edge  		if (con->parent->children->length == 1  				&& con->parent->layout == L_VERT) { @@ -358,9 +366,10 @@ static void render_container_simple_border_normal(struct sway_output *output,  		}  		color[3] *= con->alpha;  		box.x = con->x; -		box.y = con->y + con->height - con->sway_view->border_thickness; +		box.y = con->y + con->height - view->border_thickness;  		box.width = con->width; -		box.height = con->sway_view->border_thickness; +		box.height = view->border_thickness; +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} @@ -371,71 +380,118 @@ static void render_container_simple_border_normal(struct sway_output *output,  	box.y = con->y;  	box.width = con->width;  	box.height = 1; +	scale_box(&box, output_scale);  	render_rect(output->wlr_output, output_damage, &box, color);  	// Single pixel bar below title  	memcpy(&color, colors->border, sizeof(float) * 4);  	color[3] *= con->alpha; -	box.x = con->x + con->sway_view->border_thickness; -	box.y = con->sway_view->y - 1; -	box.width = con->width - con->sway_view->border_thickness * 2; +	box.x = con->x + view->border_thickness; +	box.y = view->y - 1; +	box.width = con->width - view->border_thickness * 2;  	box.height = 1; +	scale_box(&box, output_scale);  	render_rect(output->wlr_output, output_damage, &box, color); -	// Title background -	memcpy(&color, colors->background, sizeof(float) * 4); -	color[3] *= con->alpha; -	box.x = con->x -		+ con->sway_view->border_thickness * con->sway_view->border_left; -	box.y = con->y + 1; -	box.width = con->width -		- con->sway_view->border_thickness * con->sway_view->border_left -		- con->sway_view->border_thickness * con->sway_view->border_right; -	box.height = con->sway_view->y - con->y - 2; -	render_rect(output->wlr_output, output_damage, &box, color); +	// Setting these makes marks and title easier +	size_t inner_x = con->x + view->border_thickness * view->border_left; +	size_t inner_width = con->width - view->border_thickness * view->border_left +		- view->border_thickness * view->border_right; + +	// Marks +	size_t marks_width = 0; +	if (config->show_marks && marks_texture) { +		struct wlr_box texture_box; +		wlr_texture_get_size(marks_texture, +			&texture_box.width, &texture_box.height); +		texture_box.x = (inner_x + inner_width) * output_scale - texture_box.width; +		texture_box.y = (con->y + view->border_thickness) * output_scale; + +		float matrix[9]; +		wlr_matrix_project_box(matrix, &texture_box, +			WL_OUTPUT_TRANSFORM_NORMAL, +			0.0, output->wlr_output->transform_matrix); + +		render_texture(output->wlr_output, output_damage, marks_texture, +			&texture_box, matrix, con->alpha); +		marks_width = texture_box.width; +	}  	// Title text +	size_t title_width = 0;  	if (title_texture) { -		float output_scale = output->wlr_output->scale; -		struct wlr_box texture_box = { -			.x = box.x * output_scale, -			.y = box.y * output_scale, -		}; +		struct wlr_box texture_box;  		wlr_texture_get_size(title_texture,  			&texture_box.width, &texture_box.height); +		texture_box.x = inner_x * output_scale; +		texture_box.y = (con->y + view->border_thickness) * output_scale;  		float matrix[9];  		wlr_matrix_project_box(matrix, &texture_box,  			WL_OUTPUT_TRANSFORM_NORMAL,  			0.0, output->wlr_output->transform_matrix); -		texture_box.width = box.width * output_scale; +		if (inner_width * output_scale - marks_width < texture_box.width) { +			texture_box.width = inner_width * output_scale - marks_width; +		}  		render_texture(output->wlr_output, output_damage, title_texture, -			&texture_box, matrix, 1.0); +			&texture_box, matrix, con->alpha); +		title_width = texture_box.width; +	} + +	// Title background - above the text +	memcpy(&color, colors->background, sizeof(float) * 4); +	color[3] *= con->alpha; +	box.x = inner_x; +	box.y = con->y + 1; +	box.width = inner_width; +	box.height = view->border_thickness - 1; +	scale_box(&box, output_scale); +	render_rect(output->wlr_output, output_damage, &box, color); + +	// Title background - below the text +	box.y = (con->y + view->border_thickness + config->font_height) +		* output_scale; +	render_rect(output->wlr_output, output_damage, &box, color); + +	// Title background - filler between title and marks +	box.width = inner_width * output_scale - title_width - marks_width; +	if (box.width > 0) { +		box.x = inner_x * output_scale + title_width; +		box.y = (con->y + view->border_thickness) * output_scale; +		box.height = config->font_height * output_scale; +		render_rect(output->wlr_output, output_damage, &box, color);  	}  }  /**   * Render decorations for a view with "border pixel". + * + * Care must be taken not to render over the same pixel multiple times, + * otherwise the colors will be incorrect when using opacity.   */  static void render_container_simple_border_pixel(struct sway_output *output,  		pixman_region32_t *output_damage, struct sway_container *con,  		struct border_colors *colors) {  	struct wlr_box box;  	float color[4]; +	struct sway_view *view = con->sway_view; +	float output_scale = output->wlr_output->scale; -	if (con->sway_view->border_left) { +	if (view->border_left) {  		// Child border - left edge  		memcpy(&color, colors->child_border, sizeof(float) * 4);  		color[3] *= con->alpha;  		box.x = con->x; -		box.y = con->y; -		box.width = con->sway_view->border_thickness; -		box.height = con->height; +		box.y = con->y + view->border_thickness * view->border_top; +		box.width = view->border_thickness; +		box.height = con->height - view->border_thickness +			* (view->border_top + view->border_bottom); +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} -	if (con->sway_view->border_right) { +	if (view->border_right) {  		// Child border - right edge  		if (con->parent->children->length == 1  				&& con->parent->layout == L_HORIZ) { @@ -444,25 +500,28 @@ static void render_container_simple_border_pixel(struct sway_output *output,  			memcpy(&color, colors->child_border, sizeof(float) * 4);  		}  		color[3] *= con->alpha; -		box.x = con->x + con->width - con->sway_view->border_thickness; -		box.y = con->y; -		box.width = con->sway_view->border_thickness; -		box.height = con->height; +		box.x = con->x + con->width - view->border_thickness; +		box.y = con->y + view->border_thickness * view->border_top; +		box.width = view->border_thickness; +		box.height = con->height - view->border_thickness +			* (view->border_top + view->border_bottom); +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} -	if (con->sway_view->border_top) { +	if (view->border_top) {  		// Child border - top edge  		memcpy(&color, colors->child_border, sizeof(float) * 4);  		color[3] *= con->alpha;  		box.x = con->x;  		box.y = con->y;  		box.width = con->width; -		box.height = con->sway_view->border_thickness; +		box.height = view->border_thickness; +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	} -	if (con->sway_view->border_bottom) { +	if (view->border_bottom) {  		// Child border - bottom edge  		if (con->parent->children->length == 1  				&& con->parent->layout == L_VERT) { @@ -472,9 +531,10 @@ static void render_container_simple_border_pixel(struct sway_output *output,  		}  		color[3] *= con->alpha;  		box.x = con->x; -		box.y = con->y + con->height - con->sway_view->border_thickness; +		box.y = con->y + con->height - view->border_thickness;  		box.width = con->width; -		box.height = con->sway_view->border_thickness; +		box.height = view->border_thickness; +		scale_box(&box, output_scale);  		render_rect(output->wlr_output, output_damage, &box, color);  	}  } @@ -501,20 +561,24 @@ static void render_container_simple(struct sway_output *output,  			if (child->sway_view->border != B_NONE) {  				struct border_colors *colors;  				struct wlr_texture *title_texture; +				struct wlr_texture *marks_texture;  				if (focus == child || parent_focused) {  					colors = &config->border_colors.focused;  					title_texture = child->title_focused; +					marks_texture = child->sway_view->marks_focused;  				} else if (seat_get_focus_inactive(seat, con) == child) {  					colors = &config->border_colors.focused_inactive;  					title_texture = child->title_focused_inactive; +					marks_texture = child->sway_view->marks_focused_inactive;  				} else {  					colors = &config->border_colors.unfocused;  					title_texture = child->title_unfocused; +					marks_texture = child->sway_view->marks_unfocused;  				}  				if (child->sway_view->border == B_NORMAL) {  					render_container_simple_border_normal(output, damage, -						child, colors, title_texture); +						child, colors, title_texture, marks_texture);  				} else {  					render_container_simple_border_pixel(output, damage, child,  						colors); @@ -898,10 +962,15 @@ static void handle_transform(struct wl_listener *listener, void *data) {  	arrange_output(output->swayc);  } +static void handle_scale_iterator(struct sway_container *view, void *data) { +	view_update_marks_textures(view->sway_view); +} +  static void handle_scale(struct wl_listener *listener, void *data) {  	struct sway_output *output = wl_container_of(listener, output, scale);  	arrange_layers(output);  	arrange_output(output->swayc); +	container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL);  }  void handle_new_output(struct wl_listener *listener, void *data) { | 
