@ -5,6 +5,7 @@
# include "sway/commands.h"
# include "sway/output.h"
# include "sway/tree/arrange.h"
# include "sway/tree/container.h"
# include "sway/tree/root.h"
# include "sway/tree/view.h"
# include "sway/tree/workspace.h"
@ -13,180 +14,6 @@
static const char expected_syntax [ ] =
" Expected 'swap container with id|con_id|mark <arg>' " ;
static void swap_places ( struct sway_container * con1 ,
struct sway_container * con2 ) {
struct sway_container * temp = malloc ( sizeof ( struct sway_container ) ) ;
temp - > pending . x = con1 - > pending . x ;
temp - > pending . y = con1 - > pending . y ;
temp - > pending . width = con1 - > pending . width ;
temp - > pending . height = con1 - > pending . height ;
temp - > width_fraction = con1 - > width_fraction ;
temp - > height_fraction = con1 - > height_fraction ;
temp - > pending . parent = con1 - > pending . parent ;
temp - > pending . workspace = con1 - > pending . workspace ;
bool temp_floating = container_is_floating ( con1 ) ;
con1 - > pending . x = con2 - > pending . x ;
con1 - > pending . y = con2 - > pending . y ;
con1 - > pending . width = con2 - > pending . width ;
con1 - > pending . height = con2 - > pending . height ;
con1 - > width_fraction = con2 - > width_fraction ;
con1 - > height_fraction = con2 - > height_fraction ;
con2 - > pending . x = temp - > pending . x ;
con2 - > pending . y = temp - > pending . y ;
con2 - > pending . width = temp - > pending . width ;
con2 - > pending . height = temp - > pending . height ;
con2 - > width_fraction = temp - > width_fraction ;
con2 - > height_fraction = temp - > height_fraction ;
int temp_index = container_sibling_index ( con1 ) ;
if ( con2 - > pending . parent ) {
container_insert_child ( con2 - > pending . parent , con1 ,
container_sibling_index ( con2 ) ) ;
} else if ( container_is_floating ( con2 ) ) {
workspace_add_floating ( con2 - > pending . workspace , con1 ) ;
} else {
workspace_insert_tiling ( con2 - > pending . workspace , con1 ,
container_sibling_index ( con2 ) ) ;
}
if ( temp - > pending . parent ) {
container_insert_child ( temp - > pending . parent , con2 , temp_index ) ;
} else if ( temp_floating ) {
workspace_add_floating ( temp - > pending . workspace , con2 ) ;
} else {
workspace_insert_tiling ( temp - > pending . workspace , con2 , temp_index ) ;
}
free ( temp ) ;
}
static void swap_focus ( struct sway_container * con1 ,
struct sway_container * con2 , struct sway_seat * seat ,
struct sway_container * focus ) {
if ( focus = = con1 | | focus = = con2 ) {
struct sway_workspace * ws1 = con1 - > pending . workspace ;
struct sway_workspace * ws2 = con2 - > pending . workspace ;
enum sway_container_layout layout1 = container_parent_layout ( con1 ) ;
enum sway_container_layout layout2 = container_parent_layout ( con2 ) ;
if ( focus = = con1 & & ( layout2 = = L_TABBED | | layout2 = = L_STACKED ) ) {
if ( workspace_is_visible ( ws2 ) ) {
seat_set_focus ( seat , & con2 - > node ) ;
}
seat_set_focus_container ( seat , ws1 ! = ws2 ? con2 : con1 ) ;
} else if ( focus = = con2 & & ( layout1 = = L_TABBED
| | layout1 = = L_STACKED ) ) {
if ( workspace_is_visible ( ws1 ) ) {
seat_set_focus ( seat , & con1 - > node ) ;
}
seat_set_focus_container ( seat , ws1 ! = ws2 ? con1 : con2 ) ;
} else if ( ws1 ! = ws2 ) {
seat_set_focus_container ( seat , focus = = con1 ? con2 : con1 ) ;
} else {
seat_set_focus_container ( seat , focus ) ;
}
} else {
seat_set_focus_container ( seat , focus ) ;
}
if ( root - > fullscreen_global ) {
seat_set_focus ( seat ,
seat_get_focus_inactive ( seat , & root - > fullscreen_global - > node ) ) ;
}
}
void container_swap ( struct sway_container * con1 , struct sway_container * con2 ) {
if ( ! sway_assert ( con1 & & con2 , " Cannot swap with nothing " ) ) {
return ;
}
if ( ! sway_assert ( ! container_has_ancestor ( con1 , con2 )
& & ! container_has_ancestor ( con2 , con1 ) ,
" Cannot swap ancestor and descendant " ) ) {
return ;
}
sway_log ( SWAY_DEBUG , " Swapping containers %zu and %zu " ,
con1 - > node . id , con2 - > node . id ) ;
bool scratch1 = con1 - > scratchpad ;
bool hidden1 = container_is_scratchpad_hidden ( con1 ) ;
bool scratch2 = con2 - > scratchpad ;
bool hidden2 = container_is_scratchpad_hidden ( con2 ) ;
if ( scratch1 ) {
if ( hidden1 ) {
root_scratchpad_show ( con1 ) ;
}
root_scratchpad_remove_container ( con1 ) ;
}
if ( scratch2 ) {
if ( hidden2 ) {
root_scratchpad_show ( con2 ) ;
}
root_scratchpad_remove_container ( con2 ) ;
}
enum sway_fullscreen_mode fs1 = con1 - > pending . fullscreen_mode ;
if ( fs1 ) {
container_fullscreen_disable ( con1 ) ;
}
enum sway_fullscreen_mode fs2 = con2 - > pending . fullscreen_mode ;
if ( fs2 ) {
container_fullscreen_disable ( con2 ) ;
}
struct sway_seat * seat = config - > handler_context . seat ;
struct sway_container * focus = seat_get_focused_container ( seat ) ;
struct sway_workspace * vis1 =
output_get_active_workspace ( con1 - > pending . workspace - > output ) ;
struct sway_workspace * vis2 =
output_get_active_workspace ( con2 - > pending . workspace - > output ) ;
if ( ! sway_assert ( vis1 & & vis2 , " con1 or con2 are on an output without a "
" workspace. This should not happen " ) ) {
return ;
}
char * stored_prev_name = NULL ;
if ( seat - > prev_workspace_name ) {
stored_prev_name = strdup ( seat - > prev_workspace_name ) ;
}
swap_places ( con1 , con2 ) ;
if ( ! workspace_is_visible ( vis1 ) ) {
seat_set_focus ( seat , seat_get_focus_inactive ( seat , & vis1 - > node ) ) ;
}
if ( ! workspace_is_visible ( vis2 ) ) {
seat_set_focus ( seat , seat_get_focus_inactive ( seat , & vis2 - > node ) ) ;
}
swap_focus ( con1 , con2 , seat , focus ) ;
if ( stored_prev_name ) {
free ( seat - > prev_workspace_name ) ;
seat - > prev_workspace_name = stored_prev_name ;
}
if ( scratch1 ) {
root_scratchpad_add_container ( con2 , NULL ) ;
if ( ! hidden1 ) {
root_scratchpad_show ( con2 ) ;
}
}
if ( scratch2 ) {
root_scratchpad_add_container ( con1 , NULL ) ;
if ( ! hidden2 ) {
root_scratchpad_show ( con1 ) ;
}
}
if ( fs1 ) {
container_set_fullscreen ( con2 , fs1 ) ;
}
if ( fs2 ) {
container_set_fullscreen ( con1 , fs2 ) ;
}
}
static bool test_con_id ( struct sway_container * container , void * data ) {
size_t * con_id = data ;
return container - > node . id = = * con_id ;