mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Add output wrapping
This fixes issue #733. Now if the user focuses output right but is at the rightmost monitor, the focus will wrap the the leftmost monitor. This commit adds a new function, swayc_opposite_output, which selects the opposite output given a position and a direction. Now, when calling output_by_name, we first check if there is an adjacent output to switch to. If that fails, we call swayc_opposite_output to handle wrapping.
This commit is contained in:
		
							parent
							
								
									c1e6cc3257
								
							
						
					
					
						commit
						eda4bad725
					
				
					 2 changed files with 72 additions and 5 deletions
				
			
		| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
// Position is absolute coordinates on the edge where the adjacent output
 | 
					// Position is absolute coordinates on the edge where the adjacent output
 | 
				
			||||||
// should be searched for.
 | 
					// should be searched for.
 | 
				
			||||||
swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos);
 | 
					swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos);
 | 
				
			||||||
 | 
					swayc_t *swayc_opposite_output(enum movement_direction dir, const struct wlc_point *abs_pos);
 | 
				
			||||||
swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir, const struct wlc_point *abs_pos, bool pick_closest);
 | 
					swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir, const struct wlc_point *abs_pos, bool pick_closest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Place absolute coordinates for given container into given wlc_point.
 | 
					// Place absolute coordinates for given container into given wlc_point.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,14 +13,29 @@ void output_get_scaled_size(wlc_handle handle, struct wlc_size *size) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
 | 
					swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
 | 
				
			||||||
 | 
						swayc_t *output = NULL;
 | 
				
			||||||
 | 
						// If there is no output directly next to the current one, use
 | 
				
			||||||
 | 
						// swayc_opposite_output to wrap.
 | 
				
			||||||
	if (strcasecmp(name, "left") == 0) {
 | 
						if (strcasecmp(name, "left") == 0) {
 | 
				
			||||||
		return swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true);
 | 
							output = swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true);
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								output = swayc_opposite_output(MOVE_RIGHT, abs_pos);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else if (strcasecmp(name, "right") == 0) {
 | 
						} else if (strcasecmp(name, "right") == 0) {
 | 
				
			||||||
		return swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true);
 | 
							output = swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true);
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								output = swayc_opposite_output(MOVE_LEFT, abs_pos);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else if (strcasecmp(name, "up") == 0) {
 | 
						} else if (strcasecmp(name, "up") == 0) {
 | 
				
			||||||
		return swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true);
 | 
							output = swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true);
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								output = swayc_opposite_output(MOVE_DOWN, abs_pos);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else if (strcasecmp(name, "down") == 0) {
 | 
						} else if (strcasecmp(name, "down") == 0) {
 | 
				
			||||||
		return swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true);
 | 
							output = swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true);
 | 
				
			||||||
 | 
							if (!output) {
 | 
				
			||||||
 | 
								output = swayc_opposite_output(MOVE_UP, abs_pos);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		for(int i = 0; i < root_container.children->length; ++i) {
 | 
							for(int i = 0; i < root_container.children->length; ++i) {
 | 
				
			||||||
			swayc_t *c = root_container.children->items[i];
 | 
								swayc_t *c = root_container.children->items[i];
 | 
				
			||||||
| 
						 | 
					@ -29,7 +44,58 @@ swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					swayc_t *swayc_opposite_output(enum movement_direction dir,
 | 
				
			||||||
 | 
							const struct wlc_point *abs_pos) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Search through all the outputs and pick the output whose edge covers the
 | 
				
			||||||
 | 
						// given position, and is at leftmost/rightmost/upmost/downmost side of the
 | 
				
			||||||
 | 
						// screen (decided by the direction given).
 | 
				
			||||||
 | 
						swayc_t *opposite = NULL;
 | 
				
			||||||
 | 
						char *dir_text = NULL;
 | 
				
			||||||
 | 
						switch(dir) {
 | 
				
			||||||
 | 
							case MOVE_LEFT:
 | 
				
			||||||
 | 
							case MOVE_RIGHT: ;
 | 
				
			||||||
 | 
								for (int i = 0; i < root_container.children->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *c = root_container.children->items[i];
 | 
				
			||||||
 | 
									if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) {
 | 
				
			||||||
 | 
										if (!opposite) {
 | 
				
			||||||
 | 
											opposite = c;
 | 
				
			||||||
 | 
										} else if ((dir == MOVE_LEFT && c->x < opposite->x)
 | 
				
			||||||
 | 
												|| (dir == MOVE_RIGHT && c->x > opposite->x)) {
 | 
				
			||||||
 | 
											opposite = c;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dir_text = dir == MOVE_LEFT ? "leftmost" : "rightmost";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case MOVE_UP:
 | 
				
			||||||
 | 
							case MOVE_DOWN: ;
 | 
				
			||||||
 | 
								for (int i = 0; i < root_container.children->length; ++i) {
 | 
				
			||||||
 | 
									swayc_t *c = root_container.children->items[i];
 | 
				
			||||||
 | 
									if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) {
 | 
				
			||||||
 | 
										if (!opposite) {
 | 
				
			||||||
 | 
											opposite = c;
 | 
				
			||||||
 | 
										} else if ((dir == MOVE_UP && c->y < opposite->y)
 | 
				
			||||||
 | 
												|| (dir == MOVE_DOWN && c->y > opposite->y)) {
 | 
				
			||||||
 | 
											opposite = c;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dir_text = dir == MOVE_UP ? "upmost" : "downmost";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								sway_abort("Function called with invalid argument.");
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (opposite) {
 | 
				
			||||||
 | 
							sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s from y-position %i",
 | 
				
			||||||
 | 
									opposite->name, opposite->width, opposite->height, opposite->x, opposite->y,
 | 
				
			||||||
 | 
									dir_text, abs_pos->y);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return opposite;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Position is where on the edge (as absolute position) the adjacent output should be searched for.
 | 
					// Position is where on the edge (as absolute position) the adjacent output should be searched for.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue