mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	ssd: dynamically look up window icons in titlebar for output scales
by introducing scaled_icon_buffer.
This commit is contained in:
		
							parent
							
								
									5e29f79258
								
							
						
					
					
						commit
						dc474521ab
					
				
					 9 changed files with 225 additions and 102 deletions
				
			
		
							
								
								
									
										40
									
								
								include/common/scaled-icon-buffer.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/common/scaled-icon-buffer.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					#ifndef LABWC_SCALED_ICON_BUFFER_H
 | 
				
			||||||
 | 
					#define LABWC_SCALED_ICON_BUFFER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_scene_tree;
 | 
				
			||||||
 | 
					struct wlr_scene_node;
 | 
				
			||||||
 | 
					struct wlr_scene_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scaled_icon_buffer {
 | 
				
			||||||
 | 
						struct scaled_scene_buffer *scaled_buffer;
 | 
				
			||||||
 | 
						struct wlr_scene_buffer *scene_buffer;
 | 
				
			||||||
 | 
						struct server *server;
 | 
				
			||||||
 | 
						char *app_id;
 | 
				
			||||||
 | 
						char *icon_name;
 | 
				
			||||||
 | 
						int width;
 | 
				
			||||||
 | 
						int height;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create an auto scaling icon buffer, providing a wlr_scene_buffer node for
 | 
				
			||||||
 | 
					 * display. It gets destroyed automatically when the backing scaled_scene_buffer
 | 
				
			||||||
 | 
					 * is being destroyed which in turn happens automatically when the backing
 | 
				
			||||||
 | 
					 * wlr_scene_buffer (or one of its parents) is being destroyed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct scaled_icon_buffer *scaled_icon_buffer_create(
 | 
				
			||||||
 | 
						struct wlr_scene_tree *parent, struct server *server,
 | 
				
			||||||
 | 
						int width, int height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void scaled_icon_buffer_set_app_id(struct scaled_icon_buffer *self,
 | 
				
			||||||
 | 
						const char *app_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void scaled_icon_buffer_set_icon_name(struct scaled_icon_buffer *self,
 | 
				
			||||||
 | 
						const char *icon_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Obtain scaled_icon_buffer from wlr_scene_node */
 | 
				
			||||||
 | 
					struct scaled_icon_buffer *scaled_icon_buffer_from_node(struct wlr_scene_node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* LABWC_SCALED_ICON_BUFFER_H */
 | 
				
			||||||
| 
						 | 
					@ -66,10 +66,6 @@ struct scaled_img_buffer {
 | 
				
			||||||
struct scaled_img_buffer *scaled_img_buffer_create(struct wlr_scene_tree *parent,
 | 
					struct scaled_img_buffer *scaled_img_buffer_create(struct wlr_scene_tree *parent,
 | 
				
			||||||
	struct lab_img *img, int width, int height);
 | 
						struct lab_img *img, int width, int height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Update image, width and height of the scaled_img_buffer */
 | 
					 | 
				
			||||||
void scaled_img_buffer_update(struct scaled_img_buffer *self,
 | 
					 | 
				
			||||||
	struct lab_img *img, int width, int height);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Obtain scaled_img_buffer from wlr_scene_node */
 | 
					/* Obtain scaled_img_buffer from wlr_scene_node */
 | 
				
			||||||
struct scaled_img_buffer *scaled_img_buffer_from_node(struct wlr_scene_node *node);
 | 
					struct scaled_img_buffer *scaled_img_buffer_from_node(struct wlr_scene_node *node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,10 +24,16 @@ struct ssd_button {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	uint8_t state_set;
 | 
						uint8_t state_set;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Button nodes for each combination of hover/toggled/rounded states.
 | 
						 * Image buffers for each combination of hover/toggled/rounded states.
 | 
				
			||||||
	 * nodes[state_set] should be displayed.
 | 
						 * img_buffers[state_set] is displayed. Some of these can be NULL
 | 
				
			||||||
 | 
						 * (e.g. img_buffers[LAB_BS_ROUNDED] is set only for corner buttons).
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * When "type" is LAB_SSD_BUTTON_WINDOW_ICON, these are all NULL and
 | 
				
			||||||
 | 
						 * window_icon is used instead.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct wlr_scene_node *nodes[LAB_BS_ALL + 1];
 | 
						struct scaled_img_buffer *img_buffers[LAB_BS_ALL + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *window_icon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ labwc_sources += files(
 | 
				
			||||||
  'parse-bool.c',
 | 
					  'parse-bool.c',
 | 
				
			||||||
  'parse-double.c',
 | 
					  'parse-double.c',
 | 
				
			||||||
  'scaled-font-buffer.c',
 | 
					  'scaled-font-buffer.c',
 | 
				
			||||||
 | 
					  'scaled-icon-buffer.c',
 | 
				
			||||||
  'scaled-img-buffer.c',
 | 
					  'scaled-img-buffer.c',
 | 
				
			||||||
  'scaled-rect-buffer.c',
 | 
					  'scaled-rect-buffer.c',
 | 
				
			||||||
  'scaled-scene-buffer.c',
 | 
					  'scaled-scene-buffer.c',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										123
									
								
								src/common/scaled-icon-buffer.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/common/scaled-icon-buffer.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,123 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
 | 
					#define _POSIX_C_SOURCE 200809L
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include "common/macros.h"
 | 
				
			||||||
 | 
					#include "common/mem.h"
 | 
				
			||||||
 | 
					#include "common/scaled-icon-buffer.h"
 | 
				
			||||||
 | 
					#include "common/scaled-scene-buffer.h"
 | 
				
			||||||
 | 
					#include "common/string-helpers.h"
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "config/rcxml.h"
 | 
				
			||||||
 | 
					#include "desktop-entry.h"
 | 
				
			||||||
 | 
					#include "img/img.h"
 | 
				
			||||||
 | 
					#include "node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct lab_data_buffer *
 | 
				
			||||||
 | 
					_create_buffer(struct scaled_scene_buffer *scaled_buffer, double scale)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if HAVE_LIBSFDO
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *self = scaled_buffer->data;
 | 
				
			||||||
 | 
						int icon_size = MIN(self->width, self->height);
 | 
				
			||||||
 | 
						struct lab_img *img = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (self->icon_name) {
 | 
				
			||||||
 | 
							img = desktop_entry_load_icon(self->server,
 | 
				
			||||||
 | 
								self->icon_name, icon_size, scale);
 | 
				
			||||||
 | 
						} else if (self->app_id) {
 | 
				
			||||||
 | 
							img = desktop_entry_load_icon_from_app_id(self->server,
 | 
				
			||||||
 | 
								self->app_id, icon_size, scale);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!img) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct lab_data_buffer *buffer =
 | 
				
			||||||
 | 
							lab_img_render(img, self->width, self->height, scale);
 | 
				
			||||||
 | 
						lab_img_destroy(img);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					_destroy(struct scaled_scene_buffer *scaled_buffer)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *self = scaled_buffer->data;
 | 
				
			||||||
 | 
						free(self->app_id);
 | 
				
			||||||
 | 
						free(self->icon_name);
 | 
				
			||||||
 | 
						free(self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					_equal(struct scaled_scene_buffer *scaled_buffer_a,
 | 
				
			||||||
 | 
						struct scaled_scene_buffer *scaled_buffer_b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *a = scaled_buffer_a->data;
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *b = scaled_buffer_b->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return str_equal(a->app_id, b->app_id)
 | 
				
			||||||
 | 
							&& str_equal(a->icon_name, b->icon_name)
 | 
				
			||||||
 | 
							&& a->width == b->width
 | 
				
			||||||
 | 
							&& a->height == b->height;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct scaled_scene_buffer_impl impl = {
 | 
				
			||||||
 | 
						.create_buffer = _create_buffer,
 | 
				
			||||||
 | 
						.destroy = _destroy,
 | 
				
			||||||
 | 
						.equal = _equal,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scaled_icon_buffer *
 | 
				
			||||||
 | 
					scaled_icon_buffer_create(struct wlr_scene_tree *parent, struct server *server,
 | 
				
			||||||
 | 
						int width, int height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scaled_scene_buffer *scaled_buffer = scaled_scene_buffer_create(
 | 
				
			||||||
 | 
							parent, &impl, /* drop_buffer */ true);
 | 
				
			||||||
 | 
						struct scaled_icon_buffer *self = znew(*self);
 | 
				
			||||||
 | 
						self->scaled_buffer = scaled_buffer;
 | 
				
			||||||
 | 
						self->scene_buffer = scaled_buffer->scene_buffer;
 | 
				
			||||||
 | 
						self->server = server;
 | 
				
			||||||
 | 
						self->width = width;
 | 
				
			||||||
 | 
						self->height = height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scaled_buffer->data = self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					scaled_icon_buffer_set_app_id(struct scaled_icon_buffer *self,
 | 
				
			||||||
 | 
						const char *app_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(app_id);
 | 
				
			||||||
 | 
						if (str_equal(self->app_id, app_id)) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xstrdup_replace(self->app_id, app_id);
 | 
				
			||||||
 | 
						scaled_scene_buffer_request_update(self->scaled_buffer, self->width, self->height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					scaled_icon_buffer_set_icon_name(struct scaled_icon_buffer *self,
 | 
				
			||||||
 | 
						const char *icon_name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(icon_name);
 | 
				
			||||||
 | 
						if (str_equal(self->icon_name, icon_name)) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xstrdup_replace(self->icon_name, icon_name);
 | 
				
			||||||
 | 
						scaled_scene_buffer_request_update(self->scaled_buffer, self->width, self->height);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct scaled_icon_buffer *
 | 
				
			||||||
 | 
					scaled_icon_buffer_from_node(struct wlr_scene_node *node)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct scaled_scene_buffer *scaled_buffer =
 | 
				
			||||||
 | 
							node_scaled_scene_buffer_from_node(node);
 | 
				
			||||||
 | 
						assert(scaled_buffer->impl == &impl);
 | 
				
			||||||
 | 
						return scaled_buffer->data;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -66,18 +66,6 @@ scaled_img_buffer_create(struct wlr_scene_tree *parent, struct lab_img *img,
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					 | 
				
			||||||
scaled_img_buffer_update(struct scaled_img_buffer *self, struct lab_img *img,
 | 
					 | 
				
			||||||
	int width, int height)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	assert(img);
 | 
					 | 
				
			||||||
	lab_img_destroy(self->img);
 | 
					 | 
				
			||||||
	self->img = lab_img_copy(img);
 | 
					 | 
				
			||||||
	self->width = width;
 | 
					 | 
				
			||||||
	self->height = height;
 | 
					 | 
				
			||||||
	scaled_scene_buffer_request_update(self->scaled_buffer, width, height);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct scaled_img_buffer *
 | 
					struct scaled_img_buffer *
 | 
				
			||||||
scaled_img_buffer_from_node(struct wlr_scene_node *node)
 | 
					scaled_img_buffer_from_node(struct wlr_scene_node *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
#include "common/box.h"
 | 
					#include "common/box.h"
 | 
				
			||||||
#include "common/list.h"
 | 
					#include "common/list.h"
 | 
				
			||||||
#include "common/mem.h"
 | 
					#include "common/mem.h"
 | 
				
			||||||
 | 
					#include "common/scaled-icon-buffer.h"
 | 
				
			||||||
#include "common/scaled-img-buffer.h"
 | 
					#include "common/scaled-img-buffer.h"
 | 
				
			||||||
#include "labwc.h"
 | 
					#include "labwc.h"
 | 
				
			||||||
#include "node.h"
 | 
					#include "node.h"
 | 
				
			||||||
| 
						 | 
					@ -92,6 +93,10 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
 | 
				
			||||||
	button_root->node = &parent->node;
 | 
						button_root->node = &parent->node;
 | 
				
			||||||
	wlr_scene_node_set_position(button_root->node, x, y);
 | 
						wlr_scene_node_set_position(button_root->node, x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ssd_button *button = ssd_button_descriptor_create(button_root->node);
 | 
				
			||||||
 | 
						button->type = type;
 | 
				
			||||||
 | 
						button->view = view;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Hitbox */
 | 
						/* Hitbox */
 | 
				
			||||||
	float invisible[4] = { 0, 0, 0, 0 };
 | 
						float invisible[4] = { 0, 0, 0, 0 };
 | 
				
			||||||
	add_scene_rect(part_list, type, parent,
 | 
						add_scene_rect(part_list, type, parent,
 | 
				
			||||||
| 
						 | 
					@ -99,29 +104,47 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
 | 
				
			||||||
		invisible);
 | 
							invisible);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Icons */
 | 
						/* Icons */
 | 
				
			||||||
	struct wlr_scene_node *nodes[LAB_BS_ALL + 1] = {0};
 | 
						int button_width = rc.theme->window_button_width;
 | 
				
			||||||
	for (uint8_t state_set = LAB_BS_DEFAULT;
 | 
						int button_height = rc.theme->window_button_height;
 | 
				
			||||||
			state_set <= LAB_BS_ALL; state_set++) {
 | 
						/*
 | 
				
			||||||
		if (!imgs[state_set]) {
 | 
						 * Ensure a small amount of horizontal padding within the button
 | 
				
			||||||
			continue;
 | 
						 * area (2px on each side with the default 26px button width).
 | 
				
			||||||
		}
 | 
						 * A new theme setting could be added to configure this. Using
 | 
				
			||||||
		struct ssd_part *icon_part = add_scene_part(part_list, type);
 | 
						 * an existing setting (padding.width or window.button.spacing)
 | 
				
			||||||
		struct scaled_img_buffer *img_buffer = scaled_img_buffer_create(
 | 
						 * was considered, but these settings have distinct purposes
 | 
				
			||||||
			parent, imgs[state_set], rc.theme->window_button_width,
 | 
						 * already and are zero by default.
 | 
				
			||||||
			rc.theme->window_button_height);
 | 
						 */
 | 
				
			||||||
		assert(img_buffer);
 | 
						int icon_padding = button_width / 10;
 | 
				
			||||||
		icon_part->node = &img_buffer->scene_buffer->node;
 | 
					
 | 
				
			||||||
		wlr_scene_node_set_enabled(icon_part->node, false);
 | 
						if (type == LAB_SSD_BUTTON_WINDOW_ICON) {
 | 
				
			||||||
		nodes[state_set] = icon_part->node;
 | 
							struct ssd_part *icon_part = add_scene_part(part_list, type);
 | 
				
			||||||
	}
 | 
							struct scaled_icon_buffer *icon_buffer =
 | 
				
			||||||
	/* Initially show non-hover, non-toggled, unrounded variant */
 | 
								scaled_icon_buffer_create(parent, view->server,
 | 
				
			||||||
	wlr_scene_node_set_enabled(nodes[0], true);
 | 
									button_width - 2 * icon_padding, button_height);
 | 
				
			||||||
 | 
							assert(icon_buffer);
 | 
				
			||||||
 | 
							icon_part->node = &icon_buffer->scene_buffer->node;
 | 
				
			||||||
 | 
							wlr_scene_node_set_position(icon_part->node, icon_padding, 0);
 | 
				
			||||||
 | 
							button->window_icon = icon_buffer;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							for (uint8_t state_set = LAB_BS_DEFAULT;
 | 
				
			||||||
 | 
									state_set <= LAB_BS_ALL; state_set++) {
 | 
				
			||||||
 | 
								if (!imgs[state_set]) {
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								struct ssd_part *icon_part = add_scene_part(part_list, type);
 | 
				
			||||||
 | 
								struct scaled_img_buffer *img_buffer = scaled_img_buffer_create(
 | 
				
			||||||
 | 
									parent, imgs[state_set], rc.theme->window_button_width,
 | 
				
			||||||
 | 
									rc.theme->window_button_height);
 | 
				
			||||||
 | 
								assert(img_buffer);
 | 
				
			||||||
 | 
								icon_part->node = &img_buffer->scene_buffer->node;
 | 
				
			||||||
 | 
								wlr_scene_node_set_enabled(icon_part->node, false);
 | 
				
			||||||
 | 
								button->img_buffers[state_set] = img_buffer;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/* Initially show non-hover, non-toggled, unrounded variant */
 | 
				
			||||||
 | 
							wlr_scene_node_set_enabled(
 | 
				
			||||||
 | 
								&button->img_buffers[LAB_BS_DEFAULT]->scene_buffer->node, true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ssd_button *button = ssd_button_descriptor_create(button_root->node);
 | 
					 | 
				
			||||||
	button->type = type;
 | 
					 | 
				
			||||||
	button->view = view;
 | 
					 | 
				
			||||||
	button->state_set = 0;
 | 
					 | 
				
			||||||
	memcpy(button->nodes, nodes, sizeof(nodes));
 | 
					 | 
				
			||||||
	return button_root;
 | 
						return button_root;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "common/mem.h"
 | 
					#include "common/mem.h"
 | 
				
			||||||
#include "common/scaled-font-buffer.h"
 | 
					#include "common/scaled-font-buffer.h"
 | 
				
			||||||
 | 
					#include "common/scaled-icon-buffer.h"
 | 
				
			||||||
#include "common/scaled-img-buffer.h"
 | 
					#include "common/scaled-img-buffer.h"
 | 
				
			||||||
#include "common/scene-helpers.h"
 | 
					#include "common/scene-helpers.h"
 | 
				
			||||||
#include "common/string-helpers.h"
 | 
					#include "common/string-helpers.h"
 | 
				
			||||||
| 
						 | 
					@ -127,11 +128,12 @@ update_button_state(struct ssd_button *button, enum lab_button_state state,
 | 
				
			||||||
	/* Switch the displayed icon buffer to the new one */
 | 
						/* Switch the displayed icon buffer to the new one */
 | 
				
			||||||
	for (uint8_t state_set = LAB_BS_DEFAULT;
 | 
						for (uint8_t state_set = LAB_BS_DEFAULT;
 | 
				
			||||||
			state_set <= LAB_BS_ALL; state_set++) {
 | 
								state_set <= LAB_BS_ALL; state_set++) {
 | 
				
			||||||
		if (!button->nodes[state_set]) {
 | 
							struct scaled_img_buffer *buffer = button->img_buffers[state_set];
 | 
				
			||||||
 | 
							if (!buffer) {
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		wlr_scene_node_set_enabled(
 | 
							wlr_scene_node_set_enabled(&buffer->scene_buffer->node,
 | 
				
			||||||
			button->nodes[state_set], button->state_set == state_set);
 | 
								state_set == button->state_set);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -584,37 +586,6 @@ ssd_update_window_icon(struct ssd *ssd)
 | 
				
			||||||
	free(ssd->state.app_id);
 | 
						free(ssd->state.app_id);
 | 
				
			||||||
	ssd->state.app_id = xstrdup(app_id);
 | 
						ssd->state.app_id = xstrdup(app_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct theme *theme = ssd->view->server->theme;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Ensure a small amount of horizontal padding within the button
 | 
					 | 
				
			||||||
	 * area (2px on each side with the default 26px button width).
 | 
					 | 
				
			||||||
	 * A new theme setting could be added to configure this. Using
 | 
					 | 
				
			||||||
	 * an existing setting (padding.width or window.button.spacing)
 | 
					 | 
				
			||||||
	 * was considered, but these settings have distinct purposes
 | 
					 | 
				
			||||||
	 * already and are zero by default.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	int icon_padding = theme->window_button_width / 10;
 | 
					 | 
				
			||||||
	int icon_size = MIN(theme->window_button_width - 2 * icon_padding,
 | 
					 | 
				
			||||||
		theme->window_button_height);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Load/render icons at the max scale of any usable output (at
 | 
					 | 
				
			||||||
	 * this point in time). We don't want to be constantly reloading
 | 
					 | 
				
			||||||
	 * icons as views are moved between outputs.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * TODO: currently there's no signal to reload/render icons if
 | 
					 | 
				
			||||||
	 * outputs are reconfigured and the max scale changes.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	float icon_scale = output_max_scale(ssd->view->server);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct lab_img *icon_img = desktop_entry_load_icon_from_app_id(
 | 
					 | 
				
			||||||
		ssd->view->server, app_id, icon_size, icon_scale);
 | 
					 | 
				
			||||||
	if (!icon_img) {
 | 
					 | 
				
			||||||
		wlr_log(WLR_DEBUG, "icon could not be loaded for %s", app_id);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct ssd_sub_tree *subtree;
 | 
						struct ssd_sub_tree *subtree;
 | 
				
			||||||
	FOR_EACH_STATE(ssd, subtree) {
 | 
						FOR_EACH_STATE(ssd, subtree) {
 | 
				
			||||||
		struct ssd_part *part = ssd_get_part(
 | 
							struct ssd_part *part = ssd_get_part(
 | 
				
			||||||
| 
						 | 
					@ -623,23 +594,10 @@ ssd_update_window_icon(struct ssd *ssd)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Replace all the buffers in the button with the window icon */
 | 
					 | 
				
			||||||
		struct ssd_button *button = node_ssd_button_from_node(part->node);
 | 
							struct ssd_button *button = node_ssd_button_from_node(part->node);
 | 
				
			||||||
		for (uint8_t state_set = LAB_BS_DEFAULT;
 | 
							assert(button->window_icon);
 | 
				
			||||||
				state_set <= LAB_BS_ALL; state_set++) {
 | 
							scaled_icon_buffer_set_app_id(button->window_icon, app_id);
 | 
				
			||||||
			struct wlr_scene_node *node = button->nodes[state_set];
 | 
					 | 
				
			||||||
			if (node) {
 | 
					 | 
				
			||||||
				struct scaled_img_buffer *img_buffer =
 | 
					 | 
				
			||||||
					scaled_img_buffer_from_node(node);
 | 
					 | 
				
			||||||
				scaled_img_buffer_update(img_buffer, icon_img,
 | 
					 | 
				
			||||||
					theme->window_button_width - 2 * icon_padding,
 | 
					 | 
				
			||||||
					theme->window_button_height);
 | 
					 | 
				
			||||||
				wlr_scene_node_set_position(node, icon_padding, 0);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} FOR_EACH_END
 | 
						} FOR_EACH_END
 | 
				
			||||||
 | 
					 | 
				
			||||||
	lab_img_destroy(icon_img);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/theme.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/theme.c
									
										
									
									
									
								
							| 
						 | 
					@ -293,12 +293,6 @@ load_buttons(struct theme *theme)
 | 
				
			||||||
		.type = LAB_SSD_BUTTON_WINDOW_MENU,
 | 
							.type = LAB_SSD_BUTTON_WINDOW_MENU,
 | 
				
			||||||
		.state_set = 0,
 | 
							.state_set = 0,
 | 
				
			||||||
		.fallback_button = (const char[]){ 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00 },
 | 
							.fallback_button = (const char[]){ 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00 },
 | 
				
			||||||
	}, {
 | 
					 | 
				
			||||||
		/* menu icon is loaded again as a fallback of window icon */
 | 
					 | 
				
			||||||
		.name = "menu",
 | 
					 | 
				
			||||||
		.type = LAB_SSD_BUTTON_WINDOW_ICON,
 | 
					 | 
				
			||||||
		.state_set = 0,
 | 
					 | 
				
			||||||
		.fallback_button = (const char[]){ 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00 },
 | 
					 | 
				
			||||||
	}, {
 | 
						}, {
 | 
				
			||||||
		.name = "iconify",
 | 
							.name = "iconify",
 | 
				
			||||||
		.type = LAB_SSD_BUTTON_ICONIFY,
 | 
							.type = LAB_SSD_BUTTON_ICONIFY,
 | 
				
			||||||
| 
						 | 
					@ -344,12 +338,6 @@ load_buttons(struct theme *theme)
 | 
				
			||||||
		.type = LAB_SSD_BUTTON_WINDOW_MENU,
 | 
							.type = LAB_SSD_BUTTON_WINDOW_MENU,
 | 
				
			||||||
		.state_set = LAB_BS_HOVERD,
 | 
							.state_set = LAB_BS_HOVERD,
 | 
				
			||||||
		/* no fallback (non-hover variant is used instead) */
 | 
							/* no fallback (non-hover variant is used instead) */
 | 
				
			||||||
	}, {
 | 
					 | 
				
			||||||
		/* menu_hover icon is loaded again as a fallback of window icon */
 | 
					 | 
				
			||||||
		.name = "menu_hover",
 | 
					 | 
				
			||||||
		.type = LAB_SSD_BUTTON_WINDOW_ICON,
 | 
					 | 
				
			||||||
		.state_set = LAB_BS_HOVERD,
 | 
					 | 
				
			||||||
		/* no fallback (non-hover variant is used instead) */
 | 
					 | 
				
			||||||
	}, {
 | 
						}, {
 | 
				
			||||||
		.name = "iconify_hover",
 | 
							.name = "iconify_hover",
 | 
				
			||||||
		.type = LAB_SSD_BUTTON_ICONIFY,
 | 
							.type = LAB_SSD_BUTTON_ICONIFY,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue