mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Move view marks properties to container struct
Like border properties, this will be needed to implement layout saving and restoring.
This commit is contained in:
		
							parent
							
								
									480b03b734
								
							
						
					
					
						commit
						9fc736f4e1
					
				
					 16 changed files with 236 additions and 261 deletions
				
			
		|  | @ -127,6 +127,12 @@ struct sway_container { | |||
| 	size_t title_height; | ||||
| 	size_t title_baseline; | ||||
| 
 | ||||
| 	list_t *marks; // char *
 | ||||
| 	struct wlr_texture *marks_focused; | ||||
| 	struct wlr_texture *marks_focused_inactive; | ||||
| 	struct wlr_texture *marks_unfocused; | ||||
| 	struct wlr_texture *marks_urgent; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_signal destroy; | ||||
| 	} events; | ||||
|  | @ -304,4 +310,26 @@ struct sway_container *container_split(struct sway_container *child, | |||
| bool container_is_transient_for(struct sway_container *child, | ||||
| 		struct sway_container *ancestor); | ||||
| 
 | ||||
| /**
 | ||||
|  * Find any container that has the given mark and return it. | ||||
|  */ | ||||
| struct sway_container *container_find_mark(char *mark); | ||||
| 
 | ||||
| /**
 | ||||
|  * Find any container that has the given mark and remove the mark from the | ||||
|  * container. Returns true if it matched a container. | ||||
|  */ | ||||
| bool container_find_and_unmark(char *mark); | ||||
| 
 | ||||
| /**
 | ||||
|  * Remove all marks from the container. | ||||
|  */ | ||||
| void container_clear_marks(struct sway_container *container); | ||||
| 
 | ||||
| bool container_has_mark(struct sway_container *container, char *mark); | ||||
| 
 | ||||
| void container_add_mark(struct sway_container *container, char *mark); | ||||
| 
 | ||||
| void container_update_marks_textures(struct sway_container *container); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -100,12 +100,6 @@ struct sway_view { | |||
| 	bool destroying; | ||||
| 
 | ||||
| 	list_t *executed_criteria; // struct criteria *
 | ||||
| 	list_t *marks;             // char *
 | ||||
| 
 | ||||
| 	struct wlr_texture *marks_focused; | ||||
| 	struct wlr_texture *marks_focused_inactive; | ||||
| 	struct wlr_texture *marks_unfocused; | ||||
| 	struct wlr_texture *marks_urgent; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; | ||||
|  | @ -352,28 +346,6 @@ void view_update_title(struct sway_view *view, bool force); | |||
|  */ | ||||
| void view_execute_criteria(struct sway_view *view); | ||||
| 
 | ||||
| /**
 | ||||
|  * Find any view that has the given mark and return it. | ||||
|  */ | ||||
| struct sway_view *view_find_mark(char *mark); | ||||
| 
 | ||||
| /**
 | ||||
|  * Find any view that has the given mark and remove the mark from the view. | ||||
|  * Returns true if it matched a view. | ||||
|  */ | ||||
| bool view_find_and_unmark(char *mark); | ||||
| 
 | ||||
| /**
 | ||||
|  * Remove all marks from the view. | ||||
|  */ | ||||
| void view_clear_marks(struct sway_view *view); | ||||
| 
 | ||||
| bool view_has_mark(struct sway_view *view, char *mark); | ||||
| 
 | ||||
| void view_add_mark(struct sway_view *view, char *mark); | ||||
| 
 | ||||
| void view_update_marks_textures(struct sway_view *view); | ||||
| 
 | ||||
| /**
 | ||||
|  * Returns true if there's a possibility the view may be rendered on screen. | ||||
|  * Intended for damage tracking. | ||||
|  |  | |||
|  | @ -5,9 +5,7 @@ | |||
| #include "sway/tree/container.h" | ||||
| 
 | ||||
| static void rebuild_textures_iterator(struct sway_container *con, void *data) { | ||||
| 	if (con->view) { | ||||
| 		view_update_marks_textures(con->view); | ||||
| 	} | ||||
| 	container_update_marks_textures(con); | ||||
| 	container_update_title_textures(con); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,11 +19,10 @@ struct cmd_results *cmd_mark(int argc, char **argv) { | |||
| 		return error; | ||||
| 	} | ||||
| 	struct sway_container *container = config->handler_context.container; | ||||
| 	if (!container || !container->view) { | ||||
| 	if (!container) { | ||||
| 		return cmd_results_new(CMD_INVALID, "mark", | ||||
| 				"Only views can have marks"); | ||||
| 				"Only containers can have marks"); | ||||
| 	} | ||||
| 	struct sway_view *view = container->view; | ||||
| 
 | ||||
| 	bool add = false, toggle = false; | ||||
| 	while (argc > 0 && strncmp(*argv, "--", 2) == 0) { | ||||
|  | @ -47,22 +46,24 @@ struct cmd_results *cmd_mark(int argc, char **argv) { | |||
| 	} | ||||
| 
 | ||||
| 	char *mark = join_args(argv, argc); | ||||
| 	bool had_mark = view_has_mark(view, mark); | ||||
| 	bool had_mark = container_has_mark(container, mark); | ||||
| 
 | ||||
| 	if (!add) { | ||||
| 		// Replacing
 | ||||
| 		view_clear_marks(view); | ||||
| 		container_clear_marks(container); | ||||
| 	} | ||||
| 
 | ||||
| 	view_find_and_unmark(mark); | ||||
| 	container_find_and_unmark(mark); | ||||
| 
 | ||||
| 	if (!toggle || !had_mark) { | ||||
| 		view_add_mark(view, mark); | ||||
| 		container_add_mark(container, mark); | ||||
| 	} | ||||
| 
 | ||||
| 	free(mark); | ||||
| 	view_update_marks_textures(view); | ||||
| 	view_execute_criteria(view); | ||||
| 	container_update_marks_textures(container); | ||||
| 	if (container->view) { | ||||
| 		view_execute_criteria(container->view); | ||||
| 	} | ||||
| 
 | ||||
| 	return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||||
| } | ||||
|  |  | |||
|  | @ -488,12 +488,12 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) { | |||
| 		} | ||||
| 		destination = seat_get_focus_inactive(seat, &new_output->node); | ||||
| 	} else if (strcasecmp(argv[1], "mark") == 0) { | ||||
| 		struct sway_view *dest_view = view_find_mark(argv[2]); | ||||
| 		if (dest_view == NULL) { | ||||
| 		struct sway_container *dest_con = container_find_mark(argv[2]); | ||||
| 		if (dest_con == NULL) { | ||||
| 			return cmd_results_new(CMD_FAILURE, "move", | ||||
| 					"Mark '%s' not found", argv[2]); | ||||
| 		} | ||||
| 		destination = &dest_view->container->node; | ||||
| 		destination = &dest_con->node; | ||||
| 	} else { | ||||
| 		return cmd_results_new(CMD_INVALID, "move", expected_syntax); | ||||
| 	} | ||||
|  |  | |||
|  | @ -10,9 +10,7 @@ | |||
| #include "log.h" | ||||
| 
 | ||||
| static void rebuild_textures_iterator(struct sway_container *con, void *data) { | ||||
| 	if (con->view) { | ||||
| 		view_update_marks_textures(con->view); | ||||
| 	} | ||||
| 	container_update_marks_textures(con); | ||||
| 	container_update_title_textures(con); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,9 +11,7 @@ | |||
| #include "util.h" | ||||
| 
 | ||||
| static void rebuild_marks_iterator(struct sway_container *con, void *data) { | ||||
| 	if (con->view) { | ||||
| 		view_update_marks_textures(con->view); | ||||
| 	} | ||||
| 	container_update_marks_textures(con); | ||||
| } | ||||
| 
 | ||||
| struct cmd_results *cmd_show_marks(int argc, char **argv) { | ||||
|  |  | |||
|  | @ -159,8 +159,8 @@ static bool test_id(struct sway_container *container, void *id) { | |||
| } | ||||
| 
 | ||||
| static bool test_mark(struct sway_container *container, void *mark) { | ||||
| 	if (container->view && container->view->marks->length) { | ||||
| 		return !list_seq_find(container->view->marks, | ||||
| 	if (container->marks->length) { | ||||
| 		return !list_seq_find(container->marks, | ||||
| 				(int (*)(const void *, const void *))strcmp, mark); | ||||
| 	} | ||||
| 	return false; | ||||
|  |  | |||
|  | @ -9,10 +9,8 @@ | |||
| #include "stringop.h" | ||||
| 
 | ||||
| static void remove_all_marks_iterator(struct sway_container *con, void *data) { | ||||
| 	if (con->view) { | ||||
| 		view_clear_marks(con->view); | ||||
| 		view_update_marks_textures(con->view); | ||||
| 	} | ||||
| 	container_clear_marks(con); | ||||
| 	container_update_marks_textures(con); | ||||
| } | ||||
| 
 | ||||
| // unmark                  Remove all marks from all views
 | ||||
|  | @ -21,15 +19,10 @@ static void remove_all_marks_iterator(struct sway_container *con, void *data) { | |||
| // [criteria] unmark foo   Remove single mark from matched view
 | ||||
| 
 | ||||
| struct cmd_results *cmd_unmark(int argc, char **argv) { | ||||
| 	// Determine the view
 | ||||
| 	struct sway_view *view = NULL; | ||||
| 	// Determine the container
 | ||||
| 	struct sway_container *con = NULL; | ||||
| 	if (config->handler_context.using_criteria) { | ||||
| 		struct sway_container *container = config->handler_context.container; | ||||
| 		if (!container || !container->view) { | ||||
| 			return cmd_results_new(CMD_INVALID, "unmark", | ||||
| 					"Only views can have marks"); | ||||
| 		} | ||||
| 		view = container->view; | ||||
| 		con = config->handler_context.container; | ||||
| 	} | ||||
| 
 | ||||
| 	// Determine the mark
 | ||||
|  | @ -38,20 +31,20 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { | |||
| 		mark = join_args(argv, argc); | ||||
| 	} | ||||
| 
 | ||||
| 	if (view && mark) { | ||||
| 		// Remove the mark from the given view
 | ||||
| 		if (view_has_mark(view, mark)) { | ||||
| 			view_find_and_unmark(mark); | ||||
| 	if (con && mark) { | ||||
| 		// Remove the mark from the given container
 | ||||
| 		if (container_has_mark(con, mark)) { | ||||
| 			container_find_and_unmark(mark); | ||||
| 		} | ||||
| 	} else if (view && !mark) { | ||||
| 		// Clear all marks from the given view
 | ||||
| 		view_clear_marks(view); | ||||
| 		view_update_marks_textures(view); | ||||
| 	} else if (!view && mark) { | ||||
| 		// Remove mark from whichever view has it
 | ||||
| 		view_find_and_unmark(mark); | ||||
| 	} else if (con && !mark) { | ||||
| 		// Clear all marks from the given container
 | ||||
| 		container_clear_marks(con); | ||||
| 		container_update_marks_textures(con); | ||||
| 	} else if (!con && mark) { | ||||
| 		// Remove mark from whichever container has it
 | ||||
| 		container_find_and_unmark(mark); | ||||
| 	} else { | ||||
| 		// Remove all marks from all views
 | ||||
| 		// Remove all marks from all containers
 | ||||
| 		root_for_each_container(remove_all_marks_iterator, NULL); | ||||
| 	} | ||||
| 	free(mark); | ||||
|  |  | |||
|  | @ -121,8 +121,9 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
| 
 | ||||
| 	if (criteria->con_mark) { | ||||
| 		bool exists = false; | ||||
| 		for (int i = 0; i < view->marks->length; ++i) { | ||||
| 			if (regex_cmp(view->marks->items[i], criteria->con_mark) == 0) { | ||||
| 		struct sway_container *con = view->container; | ||||
| 		for (int i = 0; i < con->marks->length; ++i) { | ||||
| 			if (regex_cmp(con->marks->items[i], criteria->con_mark) == 0) { | ||||
| 				exists = true; | ||||
| 				break; | ||||
| 			} | ||||
|  |  | |||
|  | @ -532,9 +532,7 @@ static void handle_transform(struct wl_listener *listener, void *data) { | |||
| 
 | ||||
| static void update_textures(struct sway_container *con, void *data) { | ||||
| 	container_update_title_textures(con); | ||||
| 	if (con->view) { | ||||
| 		view_update_marks_textures(con->view); | ||||
| 	} | ||||
| 	container_update_marks_textures(con); | ||||
| } | ||||
| 
 | ||||
| static void handle_scale(struct wl_listener *listener, void *data) { | ||||
|  |  | |||
|  | @ -625,19 +625,19 @@ static void render_containers_linear(struct sway_output *output, | |||
| 			if (view_is_urgent(view)) { | ||||
| 				colors = &config->border_colors.urgent; | ||||
| 				title_texture = child->title_urgent; | ||||
| 				marks_texture = view->marks_urgent; | ||||
| 				marks_texture = child->marks_urgent; | ||||
| 			} else if (state->focused || parent->focused) { | ||||
| 				colors = &config->border_colors.focused; | ||||
| 				title_texture = child->title_focused; | ||||
| 				marks_texture = view->marks_focused; | ||||
| 				marks_texture = child->marks_focused; | ||||
| 			} else if (child == parent->active_child) { | ||||
| 				colors = &config->border_colors.focused_inactive; | ||||
| 				title_texture = child->title_focused_inactive; | ||||
| 				marks_texture = view->marks_focused_inactive; | ||||
| 				marks_texture = child->marks_focused_inactive; | ||||
| 			} else { | ||||
| 				colors = &config->border_colors.unfocused; | ||||
| 				title_texture = child->title_unfocused; | ||||
| 				marks_texture = view->marks_unfocused; | ||||
| 				marks_texture = child->marks_unfocused; | ||||
| 			} | ||||
| 
 | ||||
| 			if (state->border == B_NORMAL) { | ||||
|  | @ -681,19 +681,19 @@ static void render_containers_tabbed(struct sway_output *output, | |||
| 		if (urgent) { | ||||
| 			colors = &config->border_colors.urgent; | ||||
| 			title_texture = child->title_urgent; | ||||
| 			marks_texture = view ? view->marks_urgent : NULL; | ||||
| 			marks_texture = child->marks_urgent; | ||||
| 		} else if (cstate->focused || parent->focused) { | ||||
| 			colors = &config->border_colors.focused; | ||||
| 			title_texture = child->title_focused; | ||||
| 			marks_texture = view ? view->marks_focused : NULL; | ||||
| 			marks_texture = child->marks_focused; | ||||
| 		} else if (child == parent->active_child) { | ||||
| 			colors = &config->border_colors.focused_inactive; | ||||
| 			title_texture = child->title_focused_inactive; | ||||
| 			marks_texture = view ? view->marks_focused_inactive : NULL; | ||||
| 			marks_texture = child->marks_focused_inactive; | ||||
| 		} else { | ||||
| 			colors = &config->border_colors.unfocused; | ||||
| 			title_texture = child->title_unfocused; | ||||
| 			marks_texture = view ? view->marks_unfocused : NULL; | ||||
| 			marks_texture = child->marks_unfocused; | ||||
| 		} | ||||
| 
 | ||||
| 		int x = cstate->con_x + tab_width * i; | ||||
|  | @ -746,19 +746,19 @@ static void render_containers_stacked(struct sway_output *output, | |||
| 		if (urgent) { | ||||
| 			colors = &config->border_colors.urgent; | ||||
| 			title_texture = child->title_urgent; | ||||
| 			marks_texture = view ? view->marks_urgent : NULL; | ||||
| 			marks_texture = child->marks_urgent; | ||||
| 		} else if (cstate->focused || parent->focused) { | ||||
| 			colors = &config->border_colors.focused; | ||||
| 			title_texture = child->title_focused; | ||||
| 			marks_texture = view ? view->marks_focused : NULL; | ||||
| 			marks_texture = child->marks_focused; | ||||
| 		} else if (child == parent->active_child) { | ||||
| 			colors = &config->border_colors.focused_inactive; | ||||
| 			title_texture = child->title_focused_inactive; | ||||
| 			marks_texture = view ? view->marks_focused_inactive : NULL; | ||||
| 			marks_texture = child->marks_focused_inactive; | ||||
| 		} else { | ||||
| 			colors = &config->border_colors.unfocused; | ||||
| 			title_texture = child->title_unfocused; | ||||
| 			marks_texture = view ? view->marks_unfocused : NULL; | ||||
| 			marks_texture = child->marks_unfocused; | ||||
| 		} | ||||
| 
 | ||||
| 		int y = parent->box.y + titlebar_height * i; | ||||
|  | @ -841,15 +841,15 @@ static void render_floating_container(struct sway_output *soutput, | |||
| 		if (view_is_urgent(view)) { | ||||
| 			colors = &config->border_colors.urgent; | ||||
| 			title_texture = con->title_urgent; | ||||
| 			marks_texture = view->marks_urgent; | ||||
| 			marks_texture = con->marks_urgent; | ||||
| 		} else if (con->current.focused) { | ||||
| 			colors = &config->border_colors.focused; | ||||
| 			title_texture = con->title_focused; | ||||
| 			marks_texture = view->marks_focused; | ||||
| 			marks_texture = con->marks_focused; | ||||
| 		} else { | ||||
| 			colors = &config->border_colors.unfocused; | ||||
| 			title_texture = con->title_unfocused; | ||||
| 			marks_texture = view->marks_unfocused; | ||||
| 			marks_texture = con->marks_unfocused; | ||||
| 		} | ||||
| 
 | ||||
| 		if (con->current.border == B_NORMAL) { | ||||
|  |  | |||
|  | @ -230,9 +230,9 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
| 			app_id ? json_object_new_string(app_id) : NULL); | ||||
| 
 | ||||
| 	json_object *marks = json_object_new_array(); | ||||
| 	list_t *view_marks = c->view->marks; | ||||
| 	for (int i = 0; i < view_marks->length; ++i) { | ||||
| 		json_object_array_add(marks, json_object_new_string(view_marks->items[i])); | ||||
| 	list_t *con_marks = c->marks; | ||||
| 	for (int i = 0; i < con_marks->length; ++i) { | ||||
| 		json_object_array_add(marks, json_object_new_string(con_marks->items[i])); | ||||
| 	} | ||||
| 
 | ||||
| 	json_object_object_add(object, "marks", marks); | ||||
|  |  | |||
|  | @ -563,11 +563,9 @@ static void ipc_get_workspaces_callback(struct sway_workspace *workspace, | |||
| 
 | ||||
| static void ipc_get_marks_callback(struct sway_container *con, void *data) { | ||||
| 	json_object *marks = (json_object *)data; | ||||
| 	if (con->view && con->view->marks) { | ||||
| 		for (int i = 0; i < con->view->marks->length; ++i) { | ||||
| 			char *mark = (char *)con->view->marks->items[i]; | ||||
| 			json_object_array_add(marks, json_object_new_string(mark)); | ||||
| 		} | ||||
| 	for (int i = 0; i < con->marks->length; ++i) { | ||||
| 		char *mark = (char *)con->marks->items[i]; | ||||
| 		json_object_array_add(marks, json_object_new_string(mark)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ struct sway_container *container_create(struct sway_view *view) { | |||
| 		c->children = create_list(); | ||||
| 		c->current.children = create_list(); | ||||
| 	} | ||||
| 	c->marks = create_list(); | ||||
| 	c->outputs = create_list(); | ||||
| 
 | ||||
| 	wl_signal_init(&c->events.destroy); | ||||
|  | @ -66,6 +67,13 @@ void container_destroy(struct sway_container *con) { | |||
| 	list_free(con->current.children); | ||||
| 	list_free(con->outputs); | ||||
| 
 | ||||
| 	list_foreach(con->marks, free); | ||||
| 	list_free(con->marks); | ||||
| 	wlr_texture_destroy(con->marks_focused); | ||||
| 	wlr_texture_destroy(con->marks_focused_inactive); | ||||
| 	wlr_texture_destroy(con->marks_unfocused); | ||||
| 	wlr_texture_destroy(con->marks_urgent); | ||||
| 
 | ||||
| 	if (con->view) { | ||||
| 		if (con->view->container == con) { | ||||
| 			con->view->container = NULL; | ||||
|  | @ -996,9 +1004,7 @@ void container_discover_outputs(struct sway_container *con) { | |||
| 	double new_scale = new_output ? new_output->wlr_output->scale : -1; | ||||
| 	if (old_scale != new_scale) { | ||||
| 		container_update_title_textures(con); | ||||
| 		if (con->view) { | ||||
| 			view_update_marks_textures(con->view); | ||||
| 		} | ||||
| 		container_update_marks_textures(con); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -1218,3 +1224,142 @@ bool container_is_transient_for(struct sway_container *child, | |||
| 		child->view && ancestor->view && | ||||
| 		view_is_transient_for(child->view, ancestor->view); | ||||
| } | ||||
| 
 | ||||
| static bool find_by_mark_iterator(struct sway_container *con, void *data) { | ||||
| 	char *mark = data; | ||||
| 	return container_has_mark(con, mark); | ||||
| } | ||||
| 
 | ||||
| struct sway_container *container_find_mark(char *mark) { | ||||
| 	return root_find_container(find_by_mark_iterator, mark); | ||||
| } | ||||
| 
 | ||||
| bool container_find_and_unmark(char *mark) { | ||||
| 	struct sway_container *con = root_find_container( | ||||
| 		find_by_mark_iterator, mark); | ||||
| 	if (!con) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < con->marks->length; ++i) { | ||||
| 		char *con_mark = con->marks->items[i]; | ||||
| 		if (strcmp(con_mark, mark) == 0) { | ||||
| 			free(con_mark); | ||||
| 			list_del(con->marks, i); | ||||
| 			container_update_marks_textures(con); | ||||
| 			ipc_event_window(con, "mark"); | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void container_clear_marks(struct sway_container *con) { | ||||
| 	list_foreach(con->marks, free); | ||||
| 	con->marks->length = 0; | ||||
| 	ipc_event_window(con, "mark"); | ||||
| } | ||||
| 
 | ||||
| bool container_has_mark(struct sway_container *con, char *mark) { | ||||
| 	for (int i = 0; i < con->marks->length; ++i) { | ||||
| 		char *item = con->marks->items[i]; | ||||
| 		if (strcmp(item, mark) == 0) { | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void container_add_mark(struct sway_container *con, char *mark) { | ||||
| 	list_add(con->marks, strdup(mark)); | ||||
| 	ipc_event_window(con, "mark"); | ||||
| } | ||||
| 
 | ||||
| static void update_marks_texture(struct sway_container *con, | ||||
| 		struct wlr_texture **texture, struct border_colors *class) { | ||||
| 	struct sway_output *output = container_get_effective_output(con); | ||||
| 	if (!output) { | ||||
| 		return; | ||||
| 	} | ||||
| 	if (*texture) { | ||||
| 		wlr_texture_destroy(*texture); | ||||
| 		*texture = NULL; | ||||
| 	} | ||||
| 	if (!con->marks->length) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	size_t len = 0; | ||||
| 	for (int i = 0; i < con->marks->length; ++i) { | ||||
| 		char *mark = con->marks->items[i]; | ||||
| 		if (mark[0] != '_') { | ||||
| 			len += strlen(mark) + 2; | ||||
| 		} | ||||
| 	} | ||||
| 	char *buffer = calloc(len + 1, 1); | ||||
| 	char *part = malloc(len + 1); | ||||
| 
 | ||||
| 	if (!sway_assert(buffer && part, "Unable to allocate memory")) { | ||||
| 		free(buffer); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < con->marks->length; ++i) { | ||||
| 		char *mark = con->marks->items[i]; | ||||
| 		if (mark[0] != '_') { | ||||
| 			sprintf(part, "[%s]", mark); | ||||
| 			strcat(buffer, part); | ||||
| 		} | ||||
| 	} | ||||
| 	free(part); | ||||
| 
 | ||||
| 	double scale = output->wlr_output->scale; | ||||
| 	int width = 0; | ||||
| 	int height = con->title_height * scale; | ||||
| 
 | ||||
| 	cairo_t *c = cairo_create(NULL); | ||||
| 	get_text_size(c, config->font, &width, NULL, NULL, scale, false, | ||||
| 			"%s", buffer); | ||||
| 	cairo_destroy(c); | ||||
| 
 | ||||
| 	cairo_surface_t *surface = cairo_image_surface_create( | ||||
| 			CAIRO_FORMAT_ARGB32, width, height); | ||||
| 	cairo_t *cairo = cairo_create(surface); | ||||
| 	cairo_set_source_rgba(cairo, class->background[0], class->background[1], | ||||
| 			class->background[2], class->background[3]); | ||||
| 	cairo_paint(cairo); | ||||
| 	PangoContext *pango = pango_cairo_create_context(cairo); | ||||
| 	cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | ||||
| 	cairo_set_source_rgba(cairo, class->text[0], class->text[1], | ||||
| 			class->text[2], class->text[3]); | ||||
| 	cairo_move_to(cairo, 0, 0); | ||||
| 
 | ||||
| 	pango_printf(cairo, config->font, scale, false, "%s", buffer); | ||||
| 
 | ||||
| 	cairo_surface_flush(surface); | ||||
| 	unsigned char *data = cairo_image_surface_get_data(surface); | ||||
| 	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | ||||
| 	struct wlr_renderer *renderer = wlr_backend_get_renderer( | ||||
| 			output->wlr_output->backend); | ||||
| 	*texture = wlr_texture_from_pixels( | ||||
| 			renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | ||||
| 	cairo_surface_destroy(surface); | ||||
| 	g_object_unref(pango); | ||||
| 	cairo_destroy(cairo); | ||||
| 	free(buffer); | ||||
| } | ||||
| 
 | ||||
| void container_update_marks_textures(struct sway_container *con) { | ||||
| 	if (!config->show_marks) { | ||||
| 		return; | ||||
| 	} | ||||
| 	update_marks_texture(con, &con->marks_focused, | ||||
| 			&config->border_colors.focused); | ||||
| 	update_marks_texture(con, &con->marks_focused_inactive, | ||||
| 			&config->border_colors.focused_inactive); | ||||
| 	update_marks_texture(con, &con->marks_unfocused, | ||||
| 			&config->border_colors.unfocused); | ||||
| 	update_marks_texture(con, &con->marks_urgent, | ||||
| 			&config->border_colors.urgent); | ||||
| 	container_damage_whole(con); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										155
									
								
								sway/tree/view.c
									
										
									
									
									
								
							
							
						
						
									
										155
									
								
								sway/tree/view.c
									
										
									
									
									
								
							|  | @ -35,7 +35,6 @@ void view_init(struct sway_view *view, enum sway_view_type type, | |||
| 	view->type = type; | ||||
| 	view->impl = impl; | ||||
| 	view->executed_criteria = create_list(); | ||||
| 	view->marks = create_list(); | ||||
| 	view->allow_request_urgent = true; | ||||
| 	wl_signal_init(&view->events.unmap); | ||||
| } | ||||
|  | @ -55,13 +54,6 @@ void view_destroy(struct sway_view *view) { | |||
| 	} | ||||
| 	list_free(view->executed_criteria); | ||||
| 
 | ||||
| 	list_foreach(view->marks, free); | ||||
| 	list_free(view->marks); | ||||
| 
 | ||||
| 	wlr_texture_destroy(view->marks_focused); | ||||
| 	wlr_texture_destroy(view->marks_focused_inactive); | ||||
| 	wlr_texture_destroy(view->marks_unfocused); | ||||
| 	wlr_texture_destroy(view->marks_urgent); | ||||
| 	free(view->title_format); | ||||
| 
 | ||||
| 	if (view->impl->destroy) { | ||||
|  | @ -937,153 +929,6 @@ void view_update_title(struct sway_view *view, bool force) { | |||
| 	ipc_event_window(view->container, "title"); | ||||
| } | ||||
| 
 | ||||
| static bool find_by_mark_iterator(struct sway_container *con, | ||||
| 		void *data) { | ||||
| 	char *mark = data; | ||||
| 	return con->view && view_has_mark(con->view, mark); | ||||
| } | ||||
| 
 | ||||
| struct sway_view *view_find_mark(char *mark) { | ||||
| 	struct sway_container *container = root_find_container( | ||||
| 			find_by_mark_iterator, mark); | ||||
| 	if (!container) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return container->view; | ||||
| } | ||||
| 
 | ||||
| bool view_find_and_unmark(char *mark) { | ||||
| 	struct sway_container *container = root_find_container( | ||||
| 		find_by_mark_iterator, mark); | ||||
| 	if (!container) { | ||||
| 		return false; | ||||
| 	} | ||||
| 	struct sway_view *view = container->view; | ||||
| 
 | ||||
| 	for (int i = 0; i < view->marks->length; ++i) { | ||||
| 		char *view_mark = view->marks->items[i]; | ||||
| 		if (strcmp(view_mark, mark) == 0) { | ||||
| 			free(view_mark); | ||||
| 			list_del(view->marks, i); | ||||
| 			view_update_marks_textures(view); | ||||
| 			ipc_event_window(container, "mark"); | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void view_clear_marks(struct sway_view *view) { | ||||
| 	list_foreach(view->marks, free); | ||||
| 	view->marks->length = 0; | ||||
| 	ipc_event_window(view->container, "mark"); | ||||
| } | ||||
| 
 | ||||
| bool view_has_mark(struct sway_view *view, char *mark) { | ||||
| 	for (int i = 0; i < view->marks->length; ++i) { | ||||
| 		char *item = view->marks->items[i]; | ||||
| 		if (strcmp(item, mark) == 0) { | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void view_add_mark(struct sway_view *view, char *mark) { | ||||
| 	list_add(view->marks, strdup(mark)); | ||||
| 	ipc_event_window(view->container, "mark"); | ||||
| } | ||||
| 
 | ||||
| static void update_marks_texture(struct sway_view *view, | ||||
| 		struct wlr_texture **texture, struct border_colors *class) { | ||||
| 	struct sway_output *output = | ||||
| 		container_get_effective_output(view->container); | ||||
| 	if (!output) { | ||||
| 		return; | ||||
| 	} | ||||
| 	if (*texture) { | ||||
| 		wlr_texture_destroy(*texture); | ||||
| 		*texture = NULL; | ||||
| 	} | ||||
| 	if (!view->marks->length) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	size_t len = 0; | ||||
| 	for (int i = 0; i < view->marks->length; ++i) { | ||||
| 		char *mark = view->marks->items[i]; | ||||
| 		if (mark[0] != '_') { | ||||
| 			len += strlen(mark) + 2; | ||||
| 		} | ||||
| 	} | ||||
| 	char *buffer = calloc(len + 1, 1); | ||||
| 	char *part = malloc(len + 1); | ||||
| 
 | ||||
| 	if (!sway_assert(buffer && part, "Unable to allocate memory")) { | ||||
| 		free(buffer); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < view->marks->length; ++i) { | ||||
| 		char *mark = view->marks->items[i]; | ||||
| 		if (mark[0] != '_') { | ||||
| 			sprintf(part, "[%s]", mark); | ||||
| 			strcat(buffer, part); | ||||
| 		} | ||||
| 	} | ||||
| 	free(part); | ||||
| 
 | ||||
| 	double scale = output->wlr_output->scale; | ||||
| 	int width = 0; | ||||
| 	int height = view->container->title_height * scale; | ||||
| 
 | ||||
| 	cairo_t *c = cairo_create(NULL); | ||||
| 	get_text_size(c, config->font, &width, NULL, NULL, scale, false, | ||||
| 			"%s", buffer); | ||||
| 	cairo_destroy(c); | ||||
| 
 | ||||
| 	cairo_surface_t *surface = cairo_image_surface_create( | ||||
| 			CAIRO_FORMAT_ARGB32, width, height); | ||||
| 	cairo_t *cairo = cairo_create(surface); | ||||
| 	cairo_set_source_rgba(cairo, class->background[0], class->background[1], | ||||
| 			class->background[2], class->background[3]); | ||||
| 	cairo_paint(cairo); | ||||
| 	PangoContext *pango = pango_cairo_create_context(cairo); | ||||
| 	cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); | ||||
| 	cairo_set_source_rgba(cairo, class->text[0], class->text[1], | ||||
| 			class->text[2], class->text[3]); | ||||
| 	cairo_move_to(cairo, 0, 0); | ||||
| 
 | ||||
| 	pango_printf(cairo, config->font, scale, false, "%s", buffer); | ||||
| 
 | ||||
| 	cairo_surface_flush(surface); | ||||
| 	unsigned char *data = cairo_image_surface_get_data(surface); | ||||
| 	int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | ||||
| 	struct wlr_renderer *renderer = wlr_backend_get_renderer( | ||||
| 			output->wlr_output->backend); | ||||
| 	*texture = wlr_texture_from_pixels( | ||||
| 			renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); | ||||
| 	cairo_surface_destroy(surface); | ||||
| 	g_object_unref(pango); | ||||
| 	cairo_destroy(cairo); | ||||
| 	free(buffer); | ||||
| } | ||||
| 
 | ||||
| void view_update_marks_textures(struct sway_view *view) { | ||||
| 	if (!config->show_marks) { | ||||
| 		return; | ||||
| 	} | ||||
| 	update_marks_texture(view, &view->marks_focused, | ||||
| 			&config->border_colors.focused); | ||||
| 	update_marks_texture(view, &view->marks_focused_inactive, | ||||
| 			&config->border_colors.focused_inactive); | ||||
| 	update_marks_texture(view, &view->marks_unfocused, | ||||
| 			&config->border_colors.unfocused); | ||||
| 	update_marks_texture(view, &view->marks_urgent, | ||||
| 			&config->border_colors.urgent); | ||||
| 	container_damage_whole(view->container); | ||||
| } | ||||
| 
 | ||||
| bool view_is_visible(struct sway_view *view) { | ||||
| 	if (view->container->node.destroying) { | ||||
| 		return false; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ryan Dwyer
						Ryan Dwyer