From bb2c02749da09120694334ccf45667cda8bafaee Mon Sep 17 00:00:00 2001 From: gxt_kt Date: Mon, 27 Feb 2023 19:54:01 +0800 Subject: [PATCH] add win+(shift)+h/j/k/l to move focus window or switch two window --- DEF/config.h | 22 +++- commit.diff | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++ dwm.c | 261 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 611 insertions(+), 5 deletions(-) create mode 100644 commit.diff diff --git a/DEF/config.h b/DEF/config.h index 108434da..33bfb78c 100644 --- a/DEF/config.h +++ b/DEF/config.h @@ -126,6 +126,18 @@ static Key keys[] = { /* modifier key function argument */ { MODKEY, XK_equal, togglesystray, {0} }, /* super + | 切换 托盘栏显示状态 */ +//----------------------------------------------------------------------------- + { MODKEY, XK_h, focusdir, {.i = 0 } }, // 切换聚焦窗口 + { MODKEY, XK_j, focusdir, {.i = 1 } }, // 切换聚焦窗口 + { MODKEY, XK_k, focusdir, {.i = 2 } }, // 切换聚焦窗口 + { MODKEY, XK_l, focusdir, {.i = 3 } }, // 切换聚焦窗口 +//----------------------------------------------------------------------------- + { MODKEY|ShiftMask, XK_h, ExchangeClient, {.i = 0} }, // 移动窗口 + { MODKEY|ShiftMask, XK_j, ExchangeClient, {.i = 1 } }, // 移动窗口 + { MODKEY|ShiftMask, XK_k, ExchangeClient, {.i = 2 } }, // 移动窗口 + { MODKEY|ShiftMask, XK_l, ExchangeClient, {.i = 3} }, // 移动窗口 +//----------------------------------------------------------------------------- + { MODKEY, XK_Tab, focusstack, {.i = +1} }, /* super tab | 本tag内切换聚焦窗口 */ { MODKEY|ShiftMask, XK_Tab, focusstack, {.i = -1} }, /* super shift tab | 本tag内切换聚焦窗口 */ { MODKEY, XK_Up, focusstack, {.i = -1} }, /* super up | 本tag内切换聚焦窗口 */ @@ -141,8 +153,8 @@ static Key keys[] = { { MODKEY, XK_comma, setmfact, {.f = -0.05} }, /* super , | 缩小主工作区 */ { MODKEY, XK_period, setmfact, {.f = +0.05} }, /* super . | 放大主工作区 */ - { MODKEY, XK_h, hidewin, {0} }, /* super h | 隐藏 窗口 */ - { MODKEY|ShiftMask, XK_h, restorewin, {0} }, /* super shift h | 取消隐藏 窗口 */ + // { MODKEY, XK_h, hidewin, {0} }, /* super h | 隐藏 窗口 */ + // { MODKEY|ShiftMask, XK_h, restorewin, {0} }, /* super shift h | 取消隐藏 窗口 */ { MODKEY|ShiftMask, XK_Return, zoom, {0} }, /* super shift enter | 将当前聚焦窗口置为主窗口 */ @@ -188,11 +200,11 @@ static Key keys[] = { { MODKEY|ShiftMask, XK_d, spawn, SHCMD("~/scripts/call_rofi.sh drun") }, /* super shift d | rofi: 执行drun */ { MODKEY, XK_p, spawn, SHCMD("~/scripts/call_rofi.sh custom") }, /* super p | rofi: 执行自定义脚本 */ { MODKEY|ShiftMask, XK_p, spawn, SHCMD("~/scripts/call_rofi.sh window") }, /* super shift p | rofi: 执行window */ - { MODKEY, XK_k, spawn, SHCMD("~/scripts/blurlock.sh") }, /* super k | 锁定屏幕 */ + // { MODKEY, XK_k, spawn, SHCMD("~/scripts/blurlock.sh") }, /* super k | 锁定屏幕 */ { MODKEY|ShiftMask, XK_Up, spawn, SHCMD("~/scripts/set_vol.sh up") }, /* super shift up | 音量加 */ { MODKEY|ShiftMask, XK_Down, spawn, SHCMD("~/scripts/set_vol.sh down") }, /* super shift down | 音量减 */ { MODKEY|ShiftMask, XK_a, spawn, SHCMD("flameshot gui -c -p ~/Pictures/screenshots") }, /* super shift a | 截图 */ - { MODKEY|ShiftMask, XK_k, spawn, SHCMD("~/scripts/screenkey.sh") }, /* super shift k | 打开键盘输入显示 */ + // { MODKEY|ShiftMask, XK_k, spawn, SHCMD("~/scripts/screenkey.sh") }, /* super shift k | 打开键盘输入显示 */ { MODKEY|ShiftMask, XK_q, spawn, SHCMD("kill -9 $(xprop | grep _NET_WM_PID | awk '{print $3}')") }, /* super shift q | 选中某个窗口并强制kill */ { ShiftMask|ControlMask, XK_c, spawn, SHCMD("xclip -o | xclip -selection c") }, /* super shift c | 进阶复制 */ @@ -207,7 +219,7 @@ static Key keys[] = { TAGKEYS(XK_m, 5, "~/scripts/music_player.sh") TAGKEYS(XK_0, 6, "linuxqq") TAGKEYS(XK_w, 7, "/opt/apps/com.qq.weixin.deepin/files/run.sh") - TAGKEYS(XK_l, 8, "/opt/apps/com.qq.weixin.work.deepin/files/run.sh") + // TAGKEYS(XK_l, 8, "/opt/apps/com.qq.weixin.work.deepin/files/run.sh") }; static Button buttons[] = { /* click event mask button function argument */ diff --git a/commit.diff b/commit.diff new file mode 100644 index 00000000..c3c4a10f --- /dev/null +++ b/commit.diff @@ -0,0 +1,333 @@ +diff --git a/DEF/config.h b/DEF/config.h +index 108434d..33bfb78 100644 +--- a/DEF/config.h ++++ b/DEF/config.h +@@ -126,6 +126,18 @@ static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_equal, togglesystray, {0} }, /* super + | 切换 托盘栏显示状态 */ + ++//----------------------------------------------------------------------------- ++ { MODKEY, XK_h, focusdir, {.i = 0 } }, // 切换聚焦窗口 ++ { MODKEY, XK_j, focusdir, {.i = 1 } }, // 切换聚焦窗口 ++ { MODKEY, XK_k, focusdir, {.i = 2 } }, // 切换聚焦窗口 ++ { MODKEY, XK_l, focusdir, {.i = 3 } }, // 切换聚焦窗口 ++//----------------------------------------------------------------------------- ++ { MODKEY|ShiftMask, XK_h, ExchangeClient, {.i = 0} }, // 移动窗口 ++ { MODKEY|ShiftMask, XK_j, ExchangeClient, {.i = 1 } }, // 移动窗口 ++ { MODKEY|ShiftMask, XK_k, ExchangeClient, {.i = 2 } }, // 移动窗口 ++ { MODKEY|ShiftMask, XK_l, ExchangeClient, {.i = 3} }, // 移动窗口 ++//----------------------------------------------------------------------------- ++ + { MODKEY, XK_Tab, focusstack, {.i = +1} }, /* super tab | 本tag内切换聚焦窗口 */ + { MODKEY|ShiftMask, XK_Tab, focusstack, {.i = -1} }, /* super shift tab | 本tag内切换聚焦窗口 */ + { MODKEY, XK_Up, focusstack, {.i = -1} }, /* super up | 本tag内切换聚焦窗口 */ +@@ -141,8 +153,8 @@ static Key keys[] = { + { MODKEY, XK_comma, setmfact, {.f = -0.05} }, /* super , | 缩小主工作区 */ + { MODKEY, XK_period, setmfact, {.f = +0.05} }, /* super . | 放大主工作区 */ + +- { MODKEY, XK_h, hidewin, {0} }, /* super h | 隐藏 窗口 */ +- { MODKEY|ShiftMask, XK_h, restorewin, {0} }, /* super shift h | 取消隐藏 窗口 */ ++ // { MODKEY, XK_h, hidewin, {0} }, /* super h | 隐藏 窗口 */ ++ // { MODKEY|ShiftMask, XK_h, restorewin, {0} }, /* super shift h | 取消隐藏 窗口 */ + + { MODKEY|ShiftMask, XK_Return, zoom, {0} }, /* super shift enter | 将当前聚焦窗口置为主窗口 */ + +@@ -188,11 +200,11 @@ static Key keys[] = { + { MODKEY|ShiftMask, XK_d, spawn, SHCMD("~/scripts/call_rofi.sh drun") }, /* super shift d | rofi: 执行drun */ + { MODKEY, XK_p, spawn, SHCMD("~/scripts/call_rofi.sh custom") }, /* super p | rofi: 执行自定义脚本 */ + { MODKEY|ShiftMask, XK_p, spawn, SHCMD("~/scripts/call_rofi.sh window") }, /* super shift p | rofi: 执行window */ +- { MODKEY, XK_k, spawn, SHCMD("~/scripts/blurlock.sh") }, /* super k | 锁定屏幕 */ ++ // { MODKEY, XK_k, spawn, SHCMD("~/scripts/blurlock.sh") }, /* super k | 锁定屏幕 */ + { MODKEY|ShiftMask, XK_Up, spawn, SHCMD("~/scripts/set_vol.sh up") }, /* super shift up | 音量加 */ + { MODKEY|ShiftMask, XK_Down, spawn, SHCMD("~/scripts/set_vol.sh down") }, /* super shift down | 音量减 */ + { MODKEY|ShiftMask, XK_a, spawn, SHCMD("flameshot gui -c -p ~/Pictures/screenshots") }, /* super shift a | 截图 */ +- { MODKEY|ShiftMask, XK_k, spawn, SHCMD("~/scripts/screenkey.sh") }, /* super shift k | 打开键盘输入显示 */ ++ // { MODKEY|ShiftMask, XK_k, spawn, SHCMD("~/scripts/screenkey.sh") }, /* super shift k | 打开键盘输入显示 */ + { MODKEY|ShiftMask, XK_q, spawn, SHCMD("kill -9 $(xprop | grep _NET_WM_PID | awk '{print $3}')") }, /* super shift q | 选中某个窗口并强制kill */ + { ShiftMask|ControlMask, XK_c, spawn, SHCMD("xclip -o | xclip -selection c") }, /* super shift c | 进阶复制 */ + +@@ -207,7 +219,7 @@ static Key keys[] = { + TAGKEYS(XK_m, 5, "~/scripts/music_player.sh") + TAGKEYS(XK_0, 6, "linuxqq") + TAGKEYS(XK_w, 7, "/opt/apps/com.qq.weixin.deepin/files/run.sh") +- TAGKEYS(XK_l, 8, "/opt/apps/com.qq.weixin.work.deepin/files/run.sh") ++ // TAGKEYS(XK_l, 8, "/opt/apps/com.qq.weixin.work.deepin/files/run.sh") + }; + static Button buttons[] = { + /* click event mask button function argument */ +diff --git a/dwm.c b/dwm.c +index 9afb6fb..36aaaca 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -336,6 +336,9 @@ static void view(const Arg *arg); + static void viewtoleft(const Arg *arg); + static void viewtoright(const Arg *arg); + ++void ExchangeClient(const Arg *arg); ++void focusdir(const Arg *arg); ++ + static Client *wintoclient(Window w); + static Monitor *wintomon(Window w); + static Client *wintosystrayicon(Window w); +@@ -3671,3 +3674,261 @@ main(int argc, char *argv[]) + XCloseDisplay(dpy); + return EXIT_SUCCESS; + } ++ ++ ++Client *DirectionSelect(const Arg *arg) { ++ Client *tempClients[100]; ++ Client *c = NULL, *tc = selmon->sel; ++ int last = -1, cur = 0, issingle = issinglewin(NULL); ++ ++ if (tc && tc->isfullscreen) /* no support for focusstack with fullscreen windows */ ++ return NULL; ++ if (!tc) ++ tc = selmon->clients; ++ if (!tc) ++ return NULL; ++ ++ for (c = selmon->clients; c; c = c->next) { ++ if (ISVISIBLE(c) && (issingle || !HIDDEN(c))) { ++ last ++; ++ tempClients[last] = c; ++ if (c == tc) cur = last; ++ } ++ } ++ ++ if (last < 0) return NULL; ++ int sel_x=tc->x; ++ int sel_y=tc->y; ++ long long int distance=LLONG_MAX; ++ int temp_focus=0; ++ Client *tempFocusClients=NULL; ++ if (arg) { ++ if (arg->i == 3) { ++ for (int _i = 0; _i <= last; _i++) { ++ // 第一步先筛选出右边的窗口 优先选择同一层次的 ++ if (tempClients[_i]->x > sel_x && tempClients[_i]->y == sel_y) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ // 没筛选到,再去除同一层次的要求,重新筛选 ++ if (!tempFocusClients) { ++ distance = LLONG_MAX; ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->x > sel_x) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ } ++ // 确认选择 ++ if (tempFocusClients && tempFocusClients->x <= 16384 && ++ tempFocusClients->y <= 16384) { ++ c = tempFocusClients; ++ } ++ } else if (arg->i == 0) { // left ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->x < sel_x && tempClients[_i]->y == sel_y) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ if (!tempFocusClients) { ++ distance = LLONG_MAX; ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->x < sel_x) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ } ++ if (tempFocusClients && tempFocusClients->x <= 16384 && ++ tempFocusClients->y <= 16384) { ++ c = tempFocusClients; ++ } ++ } else if (arg->i == 1) { // up ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->y > sel_y && tempClients[_i]->x == sel_x) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ if (!tempFocusClients) { ++ distance = LLONG_MAX; ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->y > sel_y) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ } ++ if (tempFocusClients && tempFocusClients->x <= 16384 && ++ tempFocusClients->y <= 16384) { ++ c = tempFocusClients; ++ } ++ } else if (arg->i == 2) { // down ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->y < sel_y && tempClients[_i]->x == sel_x) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ if (!tempFocusClients) { ++ distance = LLONG_MAX; ++ for (int _i = 0; _i <= last; _i++) { ++ if (tempClients[_i]->y < sel_y) { ++ int dis_x = tempClients[_i]->x - sel_x; ++ int dis_y = tempClients[_i]->y - sel_y; ++ long long int tmp_distance = ++ dis_x * dis_x + dis_y * dis_y; // 计算距离 ++ if (tmp_distance < distance) { ++ distance = tmp_distance; ++ tempFocusClients = tempClients[_i]; ++ } ++ } ++ } ++ } ++ if (tempFocusClients && tempFocusClients->x <= 16384 && ++ tempFocusClients->y <= 16384) { ++ c = tempFocusClients; ++ } ++ } else { ++ return NULL; ++ } ++ } ++ return c; ++} ++ ++void ++focusdir(const Arg *arg) ++{ ++ Client *c = NULL; ++ int issingle = issinglewin(NULL); ++ ++ c=DirectionSelect(arg); ++ ++ if (issingle) { ++ if (c) ++ hideotherwins(&(Arg) { .v = c }); ++ } else { ++ if (c) { ++ pointerfocuswin(c); ++ restack(selmon); ++ } ++ } ++} ++ ++void ExchangeTwoClient(Client* c1, Client* c2) { ++ if(c1==NULL || c2==NULL || c1->mon!=c2->mon) { return ; } ++ ++ // 先找c1的上一个节点 ++ Client head1; ++ Client *headp1=&head1; ++ headp1->next=selmon->clients; ++ Client *tmp1 = headp1; ++ for (; tmp1 != NULL; tmp1 = tmp1->next) { ++ if(tmp1->next!=NULL) { ++ if( tmp1->next==c1 ) ++ break; ++ } else { ++ break; ++ } ++ } ++ ++ // 再找c2的上一个节点 ++ Client head2; ++ Client *headp2=&head2; ++ headp2->next=selmon->clients; ++ Client *tmp2 = headp2; ++ for (; tmp2 != NULL; tmp2 = tmp2->next) { ++ if(tmp2->next!=NULL) { ++ if( tmp2->next==c2 ) ++ break; ++ } else { ++ break; ++ } ++ } ++ ++ if(tmp1==NULL) { /* gDebug("tmp1==null"); */ return ; } ++ if(tmp2==NULL) {/* gDebug("tmp2==null"); */ return ; } ++ if(tmp1->next==NULL) {/* gDebug("tmp1->next==null"); */ return ; } ++ if(tmp2->next==NULL) { /* gDebug("tmp2->next==null"); */return ; } ++ ++ // 当c1和c2为相邻节点时 ++ if(c1->next==c2) { ++ c1->next=c2->next; ++ c2->next=c1; ++ tmp1->next=c2; ++ } else if(c2->next==c1) { ++ c2->next=c1->next; ++ c1->next=c2; ++ tmp2->next=c1; ++ } else { // 不为相邻节点 ++ tmp1->next=c2; ++ tmp2->next=c1; ++ Client* tmp=c1->next; ++ c1->next=c2->next; ++ c2->next=tmp; ++ } ++ ++ // 当更换节点为头节点时,重置头节点 ++ if(c1==selmon->clients) { ++ selmon->clients=c2; ++ }else if(c2==selmon->clients) { ++ selmon->clients=c1; ++ } ++ ++ focus(c1); ++ arrange(c1->mon); ++ pointerfocuswin(c1); ++} ++void ++ExchangeClient(const Arg *arg) ++{ ++ Client *c = selmon->sel; ++ if (c && (c->isfloating || c->isfullscreen)) ++ return; ++ ExchangeTwoClient(c,DirectionSelect(arg)); ++} diff --git a/dwm.c b/dwm.c index 9afb6fbc..36aaaca2 100644 --- a/dwm.c +++ b/dwm.c @@ -336,6 +336,9 @@ static void view(const Arg *arg); static void viewtoleft(const Arg *arg); static void viewtoright(const Arg *arg); +void ExchangeClient(const Arg *arg); +void focusdir(const Arg *arg); + static Client *wintoclient(Window w); static Monitor *wintomon(Window w); static Client *wintosystrayicon(Window w); @@ -3671,3 +3674,261 @@ main(int argc, char *argv[]) XCloseDisplay(dpy); return EXIT_SUCCESS; } + + +Client *DirectionSelect(const Arg *arg) { + Client *tempClients[100]; + Client *c = NULL, *tc = selmon->sel; + int last = -1, cur = 0, issingle = issinglewin(NULL); + + if (tc && tc->isfullscreen) /* no support for focusstack with fullscreen windows */ + return NULL; + if (!tc) + tc = selmon->clients; + if (!tc) + return NULL; + + for (c = selmon->clients; c; c = c->next) { + if (ISVISIBLE(c) && (issingle || !HIDDEN(c))) { + last ++; + tempClients[last] = c; + if (c == tc) cur = last; + } + } + + if (last < 0) return NULL; + int sel_x=tc->x; + int sel_y=tc->y; + long long int distance=LLONG_MAX; + int temp_focus=0; + Client *tempFocusClients=NULL; + if (arg) { + if (arg->i == 3) { + for (int _i = 0; _i <= last; _i++) { + // 第一步先筛选出右边的窗口 优先选择同一层次的 + if (tempClients[_i]->x > sel_x && tempClients[_i]->y == sel_y) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + // 没筛选到,再去除同一层次的要求,重新筛选 + if (!tempFocusClients) { + distance = LLONG_MAX; + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->x > sel_x) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + // 确认选择 + if (tempFocusClients && tempFocusClients->x <= 16384 && + tempFocusClients->y <= 16384) { + c = tempFocusClients; + } + } else if (arg->i == 0) { // left + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->x < sel_x && tempClients[_i]->y == sel_y) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + distance = LLONG_MAX; + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->x < sel_x) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + if (tempFocusClients && tempFocusClients->x <= 16384 && + tempFocusClients->y <= 16384) { + c = tempFocusClients; + } + } else if (arg->i == 1) { // up + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->y > sel_y && tempClients[_i]->x == sel_x) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + distance = LLONG_MAX; + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->y > sel_y) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + if (tempFocusClients && tempFocusClients->x <= 16384 && + tempFocusClients->y <= 16384) { + c = tempFocusClients; + } + } else if (arg->i == 2) { // down + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->y < sel_y && tempClients[_i]->x == sel_x) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients) { + distance = LLONG_MAX; + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->y < sel_y) { + int dis_x = tempClients[_i]->x - sel_x; + int dis_y = tempClients[_i]->y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + if (tempFocusClients && tempFocusClients->x <= 16384 && + tempFocusClients->y <= 16384) { + c = tempFocusClients; + } + } else { + return NULL; + } + } + return c; +} + +void +focusdir(const Arg *arg) +{ + Client *c = NULL; + int issingle = issinglewin(NULL); + + c=DirectionSelect(arg); + + if (issingle) { + if (c) + hideotherwins(&(Arg) { .v = c }); + } else { + if (c) { + pointerfocuswin(c); + restack(selmon); + } + } +} + +void ExchangeTwoClient(Client* c1, Client* c2) { + if(c1==NULL || c2==NULL || c1->mon!=c2->mon) { return ; } + + // 先找c1的上一个节点 + Client head1; + Client *headp1=&head1; + headp1->next=selmon->clients; + Client *tmp1 = headp1; + for (; tmp1 != NULL; tmp1 = tmp1->next) { + if(tmp1->next!=NULL) { + if( tmp1->next==c1 ) + break; + } else { + break; + } + } + + // 再找c2的上一个节点 + Client head2; + Client *headp2=&head2; + headp2->next=selmon->clients; + Client *tmp2 = headp2; + for (; tmp2 != NULL; tmp2 = tmp2->next) { + if(tmp2->next!=NULL) { + if( tmp2->next==c2 ) + break; + } else { + break; + } + } + + if(tmp1==NULL) { /* gDebug("tmp1==null"); */ return ; } + if(tmp2==NULL) {/* gDebug("tmp2==null"); */ return ; } + if(tmp1->next==NULL) {/* gDebug("tmp1->next==null"); */ return ; } + if(tmp2->next==NULL) { /* gDebug("tmp2->next==null"); */return ; } + + // 当c1和c2为相邻节点时 + if(c1->next==c2) { + c1->next=c2->next; + c2->next=c1; + tmp1->next=c2; + } else if(c2->next==c1) { + c2->next=c1->next; + c1->next=c2; + tmp2->next=c1; + } else { // 不为相邻节点 + tmp1->next=c2; + tmp2->next=c1; + Client* tmp=c1->next; + c1->next=c2->next; + c2->next=tmp; + } + + // 当更换节点为头节点时,重置头节点 + if(c1==selmon->clients) { + selmon->clients=c2; + }else if(c2==selmon->clients) { + selmon->clients=c1; + } + + focus(c1); + arrange(c1->mon); + pointerfocuswin(c1); +} +void +ExchangeClient(const Arg *arg) +{ + Client *c = selmon->sel; + if (c && (c->isfloating || c->isfullscreen)) + return; + ExchangeTwoClient(c,DirectionSelect(arg)); +}