use crate::compat::queue::{tailq_insert_tail, tailq_remove};
use crate::*;
pub static CMD_SWAP_WINDOW_ENTRY: cmd_entry = cmd_entry {
name: "swap-window",
alias: Some("swapw"),
args: args_parse::new("ds:t:", 0, 0, None),
usage: "[-d] [-s src-window] [-t dst-window]",
source: cmd_entry_flag::new(
b's',
cmd_find_type::CMD_FIND_WINDOW,
cmd_find_flags::CMD_FIND_DEFAULT_MARKED,
),
target: cmd_entry_flag::new(
b't',
cmd_find_type::CMD_FIND_WINDOW,
cmd_find_flags::empty(),
),
flags: cmd_flag::empty(),
exec: cmd_swap_window_exec,
};
unsafe fn cmd_swap_window_exec(self_: *mut cmd, item: *mut cmdq_item) -> cmd_retval {
unsafe {
let args = cmd_get_args(self_);
let source = cmdq_get_source(item);
let target = cmdq_get_target(item);
let src = (*source).s;
let dst = (*target).s;
let wl_src = (*source).wl;
let wl_dst = (*target).wl;
let sg_src = session_group_contains(src);
let sg_dst = session_group_contains(dst);
if src != dst && !sg_src.is_null() && !sg_dst.is_null() && sg_src == sg_dst {
cmdq_error!(item, "can't move window, sessions are grouped");
return cmd_retval::CMD_RETURN_ERROR;
}
if (*wl_dst).window == (*wl_src).window {
return cmd_retval::CMD_RETURN_NORMAL;
}
let w_dst = (*wl_dst).window;
tailq_remove::<_, discr_wentry>(&raw mut (*w_dst).winlinks, wl_dst);
let w_src = (*wl_src).window;
tailq_remove::<_, discr_wentry>(&raw mut (*w_src).winlinks, wl_src);
(*wl_dst).window = w_src;
tailq_insert_tail::<_, discr_wentry>(&raw mut (*w_src).winlinks, wl_dst);
(*wl_src).window = w_dst;
tailq_insert_tail::<_, discr_wentry>(&raw mut (*w_dst).winlinks, wl_src);
if args_has(args, 'd') {
session_select(dst, (*wl_dst).idx);
if src != dst {
session_select(src, (*wl_src).idx);
}
}
session_group_synchronize_from(src);
server_redraw_session_group(src);
if src != dst {
session_group_synchronize_from(dst);
server_redraw_session_group(dst);
}
recalculate_sizes();
cmd_retval::CMD_RETURN_NORMAL
}
}