mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Merge pull request #3108 from RedSoxFan/workspace-output-improved
Allow multiple outputs for workspace output
This commit is contained in:
		
						commit
						101515eb0c
					
				
					 5 changed files with 66 additions and 25 deletions
				
			
		|  | @ -183,7 +183,7 @@ struct side_gaps { | |||
|  */ | ||||
| struct workspace_config { | ||||
| 	char *workspace; | ||||
| 	char *output; | ||||
| 	list_t *outputs; | ||||
| 	int gaps_inner; | ||||
| 	struct side_gaps gaps_outer; | ||||
| }; | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
| 		return NULL; | ||||
| 	} | ||||
| 	wsc->workspace = strdup(ws_name); | ||||
| 	wsc->outputs = create_list(); | ||||
| 	wsc->gaps_inner = INT_MIN; | ||||
| 	wsc->gaps_outer.top = INT_MIN; | ||||
| 	wsc->gaps_outer.right = INT_MIN; | ||||
|  | @ -32,7 +33,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
| 
 | ||||
| void free_workspace_config(struct workspace_config *wsc) { | ||||
| 	free(wsc->workspace); | ||||
| 	free(wsc->output); | ||||
| 	free_flat_list(wsc->outputs); | ||||
| 	free(wsc); | ||||
| } | ||||
| 
 | ||||
|  | @ -141,18 +142,20 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
| 		} | ||||
| 	} | ||||
| 	if (output_location >= 0) { | ||||
| 		if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) { | ||||
| 		if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, | ||||
| 						output_location + 2))) { | ||||
| 			return error; | ||||
| 		} | ||||
| 		char *ws_name = join_args(argv, argc - 2); | ||||
| 		char *ws_name = join_args(argv, output_location); | ||||
| 		struct workspace_config *wsc = workspace_config_find_or_create(ws_name); | ||||
| 		free(ws_name); | ||||
| 		if (!wsc) { | ||||
| 			return cmd_results_new(CMD_FAILURE, "workspace output", | ||||
| 					"Unable to allocate workspace output"); | ||||
| 		} | ||||
| 		free(wsc->output); | ||||
| 		wsc->output = strdup(argv[output_location + 1]); | ||||
| 		for (int i = output_location + 1; i < argc; ++i) { | ||||
| 			list_add(wsc->outputs, strdup(argv[i])); | ||||
| 		} | ||||
| 	} else if (gaps_location >= 0) { | ||||
| 		if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { | ||||
| 			return error; | ||||
|  |  | |||
|  | @ -573,8 +573,12 @@ The default colors are: | |||
| 	Specifies that workspace _name_ should have the given gaps settings when it | ||||
| 	is created. | ||||
| 
 | ||||
| *workspace* <name> output <output> | ||||
| 	Specifies that workspace _name_ should be shown on the specified _output_. | ||||
| *workspace* <name> output <outputs...> | ||||
| 	Specifies that workspace _name_ should be shown on the specified _outputs_. | ||||
| 	Multiple outputs can be listed and the first available will be used. If the | ||||
| 	workspace gets placed on an output further down the list and an output that | ||||
| 	is higher on the list becomes available, the workspace will be move to the | ||||
| 	higher priority output. | ||||
| 
 | ||||
| *workspace\_auto\_back\_and\_forth* yes|no | ||||
| 	When _yes_, repeating a workspace switch command will switch back to the | ||||
|  |  | |||
|  | @ -31,6 +31,13 @@ static void restore_workspaces(struct sway_output *output) { | |||
| 				j--; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (other->workspaces->length == 0) { | ||||
| 			char *next = workspace_next_name(other->wlr_output->name); | ||||
| 			struct sway_workspace *ws = workspace_create(other, next); | ||||
| 			free(next); | ||||
| 			ipc_event_workspace(NULL, ws, "init"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Saved workspaces
 | ||||
|  |  | |||
|  | @ -33,16 +33,17 @@ struct workspace_config *workspace_find_config(const char *ws_name) { | |||
| struct sway_output *workspace_get_initial_output(const char *name) { | ||||
| 	// Check workspace configs for a workspace<->output pair
 | ||||
| 	struct workspace_config *wsc = workspace_find_config(name); | ||||
| 	if (wsc && wsc->output) { | ||||
| 		struct sway_output *output = output_by_name(wsc->output); | ||||
| 	if (wsc) { | ||||
| 		for (int i = 0; i < wsc->outputs->length; i++) { | ||||
| 			struct sway_output *output = output_by_name(wsc->outputs->items[i]); | ||||
| 			if (!output) { | ||||
| 			output = output_by_identifier(wsc->output); | ||||
| 				output = output_by_identifier(wsc->outputs->items[i]); | ||||
| 			} | ||||
| 		 | ||||
| 			if (output) { | ||||
| 				return output; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	// Otherwise put it on the focused output
 | ||||
| 	struct sway_seat *seat = input_manager_current_seat(); | ||||
| 	struct sway_workspace *focus = seat_get_focused_workspace(seat); | ||||
|  | @ -85,7 +86,6 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
| 	ws->floating = create_list(); | ||||
| 	ws->tiling = create_list(); | ||||
| 	ws->output_priority = create_list(); | ||||
| 	workspace_output_add_priority(ws, output); | ||||
| 
 | ||||
| 	ws->gaps_outer = config->gaps_outer; | ||||
| 	ws->gaps_inner = config->gaps_inner; | ||||
|  | @ -110,8 +110,16 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
| 			// Since default outer gaps can be smaller than the negation of
 | ||||
| 			// workspace specific inner gaps, check outer gaps again
 | ||||
| 			prevent_invalid_outer_gaps(ws); | ||||
| 
 | ||||
| 			// Add output priorities
 | ||||
| 			for (int i = 0; i < wsc->outputs->length; ++i) { | ||||
| 				list_add(ws->output_priority, strdup(wsc->outputs->items[i])); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// If not already added, add the output to the lowest priority
 | ||||
| 	workspace_output_add_priority(ws, output); | ||||
| 
 | ||||
| 	output_add_workspace(output, ws); | ||||
| 	output_sort_workspaces(output); | ||||
|  | @ -134,8 +142,7 @@ void workspace_destroy(struct sway_workspace *workspace) { | |||
| 
 | ||||
| 	free(workspace->name); | ||||
| 	free(workspace->representation); | ||||
| 	list_foreach(workspace->output_priority, free); | ||||
| 	list_free(workspace->output_priority); | ||||
| 	free_flat_list(workspace->output_priority); | ||||
| 	list_free(workspace->floating); | ||||
| 	list_free(workspace->tiling); | ||||
| 	list_free(workspace->current.floating); | ||||
|  | @ -178,7 +185,18 @@ static bool workspace_valid_on_output(const char *output_name, | |||
| 	struct sway_output *output = output_by_name(output_name); | ||||
| 	output_get_identifier(identifier, sizeof(identifier), output); | ||||
| 
 | ||||
| 	return !wsc || !wsc->output || strcmp(wsc->output, output_name) == 0 || strcasecmp(identifier, output_name) == 0; | ||||
| 	if (!wsc) { | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < wsc->outputs->length; i++) { | ||||
| 		if (strcmp(wsc->outputs->items[i], output_name) == 0 || | ||||
| 				strcmp(wsc->outputs->items[i], identifier) == 0) { | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static void workspace_name_from_binding(const struct sway_binding * binding, | ||||
|  | @ -281,13 +299,22 @@ char *workspace_next_name(const char *output_name) { | |||
| 	for (int i = 0; i < config->workspace_configs->length; ++i) { | ||||
| 		// Unlike with bindings, this does not guarantee order
 | ||||
| 		const struct workspace_config *wsc = config->workspace_configs->items[i]; | ||||
| 		if (wsc->output && strcmp(wsc->output, output_name) == 0 | ||||
| 				&& workspace_by_name(wsc->workspace) == NULL) { | ||||
| 		if (workspace_by_name(wsc->workspace)) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		bool found = false; | ||||
| 		for (int j = 0; j < wsc->outputs->length; ++j) { | ||||
| 			if (strcmp(wsc->outputs->items[j], output_name) == 0) { | ||||
| 				found = true; | ||||
| 				free(target); | ||||
| 				target = strdup(wsc->workspace); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if (found) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (target != NULL) { | ||||
| 		return target; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drew DeVault
						Drew DeVault