mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	view: add MoveToOutput wrap attribute
				
					
				
			Support `wrap` in view_get_adjacent_output(). This means that when seeking
an adjacent output in a particular direction from an output that is
already furthest in that direction within the layout, rather than
returning NULL, wrap around from the leftmost to the rightmost, or topmost
to the bottommost and vice versa.
Example usage:
    <action name="MoveToOutput" direction="right" wrap="yes" />
Wrap is disabled by default to keep the user interface consistent.
			
			
This commit is contained in:
		
							parent
							
								
									7e338fc365
								
							
						
					
					
						commit
						3c3bcc2765
					
				
					 4 changed files with 69 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -397,6 +397,10 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
 | 
			
		|||
			}
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcmp(argument, "wrap")) {
 | 
			
		||||
			action_arg_add_bool(action, argument, parse_bool(content, false));
 | 
			
		||||
			goto cleanup;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case ACTION_TYPE_VIRTUAL_OUTPUT_ADD:
 | 
			
		||||
	case ACTION_TYPE_VIRTUAL_OUTPUT_REMOVE:
 | 
			
		||||
| 
						 | 
				
			
			@ -924,7 +928,8 @@ actions_run(struct view *activator, struct server *server,
 | 
			
		|||
			} else {
 | 
			
		||||
				/* Config parsing makes sure that direction is a valid direction */
 | 
			
		||||
				enum view_edge edge = action_get_int(action, "direction", 0);
 | 
			
		||||
				target = view_get_adjacent_output(view, edge);
 | 
			
		||||
				bool wrap = action_get_bool(action, "wrap", false);
 | 
			
		||||
				target = view_get_adjacent_output(view, edge, wrap);
 | 
			
		||||
			}
 | 
			
		||||
			if (!target) {
 | 
			
		||||
				wlr_log(WLR_ERROR, "Invalid output.");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										81
									
								
								src/view.c
									
										
									
									
									
								
							
							
						
						
									
										81
									
								
								src/view.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#include "common/macros.h"
 | 
			
		||||
#include "common/match.h"
 | 
			
		||||
#include "common/mem.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1519,8 +1520,44 @@ view_on_output_destroy(struct view *view)
 | 
			
		|||
	view->output = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum wlr_direction
 | 
			
		||||
opposite_direction(enum wlr_direction direction)
 | 
			
		||||
{
 | 
			
		||||
	switch (direction) {
 | 
			
		||||
	case WLR_DIRECTION_RIGHT:
 | 
			
		||||
		return WLR_DIRECTION_LEFT;
 | 
			
		||||
	case WLR_DIRECTION_LEFT:
 | 
			
		||||
		return WLR_DIRECTION_RIGHT;
 | 
			
		||||
	case WLR_DIRECTION_DOWN:
 | 
			
		||||
		return WLR_DIRECTION_UP;
 | 
			
		||||
	case WLR_DIRECTION_UP:
 | 
			
		||||
		return WLR_DIRECTION_DOWN;
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum wlr_direction
 | 
			
		||||
get_wlr_direction(enum view_edge edge)
 | 
			
		||||
{
 | 
			
		||||
	switch (edge) {
 | 
			
		||||
	case VIEW_EDGE_LEFT:
 | 
			
		||||
		return WLR_DIRECTION_LEFT;
 | 
			
		||||
	case VIEW_EDGE_RIGHT:
 | 
			
		||||
		return WLR_DIRECTION_RIGHT;
 | 
			
		||||
	case VIEW_EDGE_UP:
 | 
			
		||||
		return WLR_DIRECTION_UP;
 | 
			
		||||
	case VIEW_EDGE_DOWN:
 | 
			
		||||
		return WLR_DIRECTION_DOWN;
 | 
			
		||||
	case VIEW_EDGE_CENTER:
 | 
			
		||||
	case VIEW_EDGE_INVALID:
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct output *
 | 
			
		||||
view_get_adjacent_output(struct view *view, enum view_edge edge)
 | 
			
		||||
view_get_adjacent_output(struct view *view, enum view_edge edge, bool wrap)
 | 
			
		||||
{
 | 
			
		||||
	assert(view);
 | 
			
		||||
	struct output *output = view->output;
 | 
			
		||||
| 
						 | 
				
			
			@ -1530,7 +1567,7 @@ view_get_adjacent_output(struct view *view, enum view_edge edge)
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_box box = output_usable_area_in_layout_coords(view->output);
 | 
			
		||||
	struct wlr_box box = output_usable_area_in_layout_coords(output);
 | 
			
		||||
	int lx = box.x + box.width / 2;
 | 
			
		||||
	int ly = box.y + box.height / 2;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1538,28 +1575,23 @@ view_get_adjacent_output(struct view *view, enum view_edge edge)
 | 
			
		|||
	struct wlr_output *new_output = NULL;
 | 
			
		||||
	struct wlr_output *current_output = output->wlr_output;
 | 
			
		||||
	struct wlr_output_layout *layout = view->server->output_layout;
 | 
			
		||||
	switch (edge) {
 | 
			
		||||
	case VIEW_EDGE_LEFT:
 | 
			
		||||
		new_output = wlr_output_layout_adjacent_output(
 | 
			
		||||
			layout, WLR_DIRECTION_LEFT, current_output, lx, ly);
 | 
			
		||||
		break;
 | 
			
		||||
	case VIEW_EDGE_RIGHT:
 | 
			
		||||
		new_output = wlr_output_layout_adjacent_output(
 | 
			
		||||
			layout, WLR_DIRECTION_RIGHT, current_output, lx, ly);
 | 
			
		||||
		break;
 | 
			
		||||
	case VIEW_EDGE_UP:
 | 
			
		||||
		new_output = wlr_output_layout_adjacent_output(
 | 
			
		||||
			layout, WLR_DIRECTION_UP, current_output, lx, ly);
 | 
			
		||||
		break;
 | 
			
		||||
	case VIEW_EDGE_DOWN:
 | 
			
		||||
		new_output = wlr_output_layout_adjacent_output(
 | 
			
		||||
			layout, WLR_DIRECTION_DOWN, current_output, lx, ly);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	enum wlr_direction direction = get_wlr_direction(edge);
 | 
			
		||||
	new_output = wlr_output_layout_adjacent_output(layout, direction,
 | 
			
		||||
		current_output, lx, ly);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Optionally wrap around from top-to-bottom or left-to-right, and vice
 | 
			
		||||
	 * versa.
 | 
			
		||||
	 */
 | 
			
		||||
	if (wrap && !new_output) {
 | 
			
		||||
		new_output = wlr_output_layout_farthest_output(layout,
 | 
			
		||||
			opposite_direction(direction), current_output, lx, ly);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* When "adjacent" output is the same as the original, there is no adjacent */
 | 
			
		||||
	/*
 | 
			
		||||
	 * When "adjacent" output is the same as the original, there is no
 | 
			
		||||
	 * adjacent
 | 
			
		||||
	 */
 | 
			
		||||
	if (!new_output || new_output == current_output) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1633,7 +1665,8 @@ view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_wind
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/* Otherwise, move to edge of next adjacent display, if possible */
 | 
			
		||||
	struct output *output = view_get_adjacent_output(view, direction);
 | 
			
		||||
	struct output *output =
 | 
			
		||||
		view_get_adjacent_output(view, direction, /* wrap */ false);
 | 
			
		||||
	if (!output) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1792,7 +1825,7 @@ view_snap_to_edge(struct view *view, enum view_edge edge,
 | 
			
		|||
 | 
			
		||||
	if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) {
 | 
			
		||||
		/* We are already tiled for this edge; try to switch outputs */
 | 
			
		||||
		output = view_get_adjacent_output(view, edge);
 | 
			
		||||
		output = view_get_adjacent_output(view, edge, /* wrap */ false);
 | 
			
		||||
 | 
			
		||||
		if (!output) {
 | 
			
		||||
			/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue