@ -1,4 +1,5 @@
# include <strings.h>
# include <strings.h>
# include <wlr/types/wlr_output_layout.h>
# include <wlr/util/log.h>
# include <wlr/util/log.h>
# include "log.h"
# include "log.h"
# include "sway/commands.h"
# include "sway/commands.h"
@ -13,20 +14,16 @@
# include "stringop.h"
# include "stringop.h"
# include "util.h"
# include "util.h"
static bool parse_ movement_ direction( const char * name ,
static bool parse_ direction( const char * name ,
enum movement _direction * out ) {
enum wlr _direction * out ) {
if ( strcasecmp ( name , " left " ) = = 0 ) {
if ( strcasecmp ( name , " left " ) = = 0 ) {
* out = MOVE _LEFT;
* out = WLR_DIRECTION _LEFT;
} else if ( strcasecmp ( name , " right " ) = = 0 ) {
} else if ( strcasecmp ( name , " right " ) = = 0 ) {
* out = MOVE _RIGHT;
* out = WLR_DIRECTION _RIGHT;
} else if ( strcasecmp ( name , " up " ) = = 0 ) {
} else if ( strcasecmp ( name , " up " ) = = 0 ) {
* out = MOVE _UP;
* out = WLR_DIRECTION _UP;
} else if ( strcasecmp ( name , " down " ) = = 0 ) {
} else if ( strcasecmp ( name , " down " ) = = 0 ) {
* out = MOVE_DOWN ;
* out = WLR_DIRECTION_DOWN ;
} else if ( strcasecmp ( name , " parent " ) = = 0 ) {
* out = MOVE_PARENT ;
} else if ( strcasecmp ( name , " child " ) = = 0 ) {
* out = MOVE_CHILD ;
} else {
} else {
return false ;
return false ;
}
}
@ -38,7 +35,7 @@ static bool parse_movement_direction(const char *name,
* Get node in the direction of newly entered output .
* Get node in the direction of newly entered output .
*/
*/
static struct sway_node * get_node_in_output_direction (
static struct sway_node * get_node_in_output_direction (
struct sway_output * output , enum movement _direction dir ) {
struct sway_output * output , enum wlr _direction dir ) {
struct sway_seat * seat = config - > handler_context . seat ;
struct sway_seat * seat = config - > handler_context . seat ;
struct sway_workspace * ws = output_get_active_workspace ( output ) ;
struct sway_workspace * ws = output_get_active_workspace ( output ) ;
if ( ws - > fullscreen ) {
if ( ws - > fullscreen ) {
@ -48,7 +45,7 @@ static struct sway_node *get_node_in_output_direction(
if ( ws - > tiling - > length > 0 ) {
if ( ws - > tiling - > length > 0 ) {
switch ( dir ) {
switch ( dir ) {
case MOVE _LEFT:
case WLR_DIRECTION _LEFT:
if ( ws - > layout = = L_HORIZ | | ws - > layout = = L_TABBED ) {
if ( ws - > layout = = L_HORIZ | | ws - > layout = = L_TABBED ) {
// get most right child of new output
// get most right child of new output
container = ws - > tiling - > items [ ws - > tiling - > length - 1 ] ;
container = ws - > tiling - > items [ ws - > tiling - > length - 1 ] ;
@ -56,7 +53,7 @@ static struct sway_node *get_node_in_output_direction(
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
}
}
break ;
break ;
case MOVE _RIGHT:
case WLR_DIRECTION _RIGHT:
if ( ws - > layout = = L_HORIZ | | ws - > layout = = L_TABBED ) {
if ( ws - > layout = = L_HORIZ | | ws - > layout = = L_TABBED ) {
// get most left child of new output
// get most left child of new output
container = ws - > tiling - > items [ 0 ] ;
container = ws - > tiling - > items [ 0 ] ;
@ -64,7 +61,7 @@ static struct sway_node *get_node_in_output_direction(
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
}
}
break ;
break ;
case MOVE _UP:
case WLR_DIRECTION _UP:
if ( ws - > layout = = L_VERT | | ws - > layout = = L_STACKED ) {
if ( ws - > layout = = L_VERT | | ws - > layout = = L_STACKED ) {
// get most bottom child of new output
// get most bottom child of new output
container = ws - > tiling - > items [ ws - > tiling - > length - 1 ] ;
container = ws - > tiling - > items [ ws - > tiling - > length - 1 ] ;
@ -72,7 +69,7 @@ static struct sway_node *get_node_in_output_direction(
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
container = seat_get_focus_inactive_tiling ( seat , ws ) ;
}
}
break ;
break ;
case MOVE_DOWN: {
case WLR_DIRECTION_DOWN:
if ( ws - > layout = = L_VERT | | ws - > layout = = L_STACKED ) {
if ( ws - > layout = = L_VERT | | ws - > layout = = L_STACKED ) {
// get most top child of new output
// get most top child of new output
container = ws - > tiling - > items [ 0 ] ;
container = ws - > tiling - > items [ 0 ] ;
@ -81,9 +78,6 @@ static struct sway_node *get_node_in_output_direction(
}
}
break ;
break ;
}
}
default :
break ;
}
}
}
if ( container ) {
if ( container ) {
@ -95,11 +89,8 @@ static struct sway_node *get_node_in_output_direction(
}
}
static struct sway_node * node_get_in_direction ( struct sway_container * container ,
static struct sway_node * node_get_in_direction ( struct sway_container * container ,
struct sway_seat * seat , enum movement _direction dir ) {
struct sway_seat * seat , enum wlr _direction dir ) {
if ( container - > is_fullscreen ) {
if ( container - > is_fullscreen ) {
if ( dir = = MOVE_PARENT ) {
return NULL ;
}
// Fullscreen container with a direction - go straight to outputs
// Fullscreen container with a direction - go straight to outputs
struct sway_output * output = container - > workspace - > output ;
struct sway_output * output = container - > workspace - > output ;
struct sway_output * new_output = output_get_in_direction ( output , dir ) ;
struct sway_output * new_output = output_get_in_direction ( output , dir ) ;
@ -108,9 +99,6 @@ static struct sway_node *node_get_in_direction(struct sway_container *container,
}
}
return get_node_in_output_direction ( new_output , dir ) ;
return get_node_in_output_direction ( new_output , dir ) ;
}
}
if ( dir = = MOVE_PARENT ) {
return node_get_parent ( & container - > node ) ;
}
struct sway_container * wrap_candidate = NULL ;
struct sway_container * wrap_candidate = NULL ;
struct sway_container * current = container ;
struct sway_container * current = container ;
@ -122,15 +110,15 @@ static struct sway_node *node_get_in_direction(struct sway_container *container,
container_parent_layout ( current ) ;
container_parent_layout ( current ) ;
list_t * siblings = container_get_siblings ( current ) ;
list_t * siblings = container_get_siblings ( current ) ;
if ( dir = = MOVE_LEFT | | dir = = MOVE _RIGHT) {
if ( dir = = WLR_DIRECTION_LEFT | | dir = = WLR_DIRECTION _RIGHT) {
if ( parent_layout = = L_HORIZ | | parent_layout = = L_TABBED ) {
if ( parent_layout = = L_HORIZ | | parent_layout = = L_TABBED ) {
can_move = true ;
can_move = true ;
desired = idx + ( dir = = MOVE _LEFT ? - 1 : 1 ) ;
desired = idx + ( dir = = WLR_DIRECTION _LEFT ? - 1 : 1 ) ;
}
}
} else {
} else {
if ( parent_layout = = L_VERT | | parent_layout = = L_STACKED ) {
if ( parent_layout = = L_VERT | | parent_layout = = L_STACKED ) {
can_move = true ;
can_move = true ;
desired = idx + ( dir = = MOVE _UP ? - 1 : 1 ) ;
desired = idx + ( dir = = WLR_DIRECTION _UP ? - 1 : 1 ) ;
}
}
}
}
@ -200,9 +188,8 @@ static struct cmd_results *focus_output(struct sway_seat *seat,
struct sway_output * output = output_by_name ( identifier ) ;
struct sway_output * output = output_by_name ( identifier ) ;
if ( ! output ) {
if ( ! output ) {
enum movement_direction direction ;
enum wlr_direction direction ;
if ( ! parse_movement_direction ( identifier , & direction ) | |
if ( ! parse_direction ( identifier , & direction ) ) {
direction = = MOVE_PARENT | | direction = = MOVE_CHILD ) {
free ( identifier ) ;
free ( identifier ) ;
return cmd_results_new ( CMD_INVALID , " focus " ,
return cmd_results_new ( CMD_INVALID , " focus " ,
" There is no output with that name " ) ;
" There is no output with that name " ) ;
@ -220,6 +207,31 @@ static struct cmd_results *focus_output(struct sway_seat *seat,
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
}
static struct cmd_results * focus_parent ( void ) {
struct sway_seat * seat = config - > handler_context . seat ;
struct sway_container * con = config - > handler_context . container ;
if ( ! con | | con - > is_fullscreen ) {
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
struct sway_node * parent = node_get_parent ( & con - > node ) ;
if ( parent ) {
seat_set_focus ( seat , parent ) ;
seat_consider_warp_to_focus ( seat ) ;
}
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
static struct cmd_results * focus_child ( void ) {
struct sway_seat * seat = config - > handler_context . seat ;
struct sway_node * node = config - > handler_context . node ;
struct sway_node * focus = seat_get_active_tiling_child ( seat , node ) ;
if ( focus ) {
seat_set_focus ( seat , focus ) ;
seat_consider_warp_to_focus ( seat ) ;
}
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
struct cmd_results * cmd_focus ( int argc , char * * argv ) {
struct cmd_results * cmd_focus ( int argc , char * * argv ) {
if ( config - > reading | | ! config - > active ) {
if ( config - > reading | | ! config - > active ) {
return cmd_results_new ( CMD_DEFER , NULL , NULL ) ;
return cmd_results_new ( CMD_DEFER , NULL , NULL ) ;
@ -257,27 +269,21 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
return focus_output ( seat , argc , argv ) ;
return focus_output ( seat , argc , argv ) ;
}
}
enum movement_direction direction = 0 ;
if ( strcasecmp ( argv [ 0 ] , " parent " ) = = 0 ) {
if ( ! parse_movement_direction ( argv [ 0 ] , & direction ) ) {
return focus_parent ( ) ;
}
if ( strcasecmp ( argv [ 0 ] , " child " ) = = 0 ) {
return focus_child ( ) ;
}
enum wlr_direction direction = 0 ;
if ( ! parse_direction ( argv [ 0 ] , & direction ) ) {
return cmd_results_new ( CMD_INVALID , " focus " ,
return cmd_results_new ( CMD_INVALID , " focus " ,
" Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' "
" Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' "
" or 'focus output <direction|name>' " ) ;
" or 'focus output <direction|name>' " ) ;
}
}
if ( direction = = MOVE_CHILD ) {
struct sway_node * focus = seat_get_active_tiling_child ( seat , node ) ;
if ( focus ) {
seat_set_focus ( seat , focus ) ;
seat_consider_warp_to_focus ( seat ) ;
}
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
if ( node - > type = = N_WORKSPACE ) {
if ( node - > type = = N_WORKSPACE ) {
if ( direction = = MOVE_PARENT ) {
return cmd_results_new ( CMD_SUCCESS , NULL , NULL ) ;
}
// Jump to the next output
// Jump to the next output
struct sway_output * new_output =
struct sway_output * new_output =
output_get_in_direction ( workspace - > output , direction ) ;
output_get_in_direction ( workspace - > output , direction ) ;