diff --git a/src/client.c b/src/client.c index 1c6ee0b..1f55ff2 100644 --- a/src/client.c +++ b/src/client.c @@ -85,7 +85,8 @@ Client* wm_client_create(Wm *wm, Window w) XSelectInput(wm->display, c->window, FocusChangeMask | EnterWindowMask | PointerMotionMask); - wm_client_set_atom(wm, c, "_NET_WM_DESKTOP", (unsigned char*)&c->ws, XA_CARDINAL, 1); + wm_client_set_atom(wm, c, "_NET_WM_DESKTOP", (unsigned char*)&c->ws->index, + XA_CARDINAL, 1); XFree(xtp.value); @@ -136,7 +137,7 @@ void wm_client_handle_window_types(Wm *wm, Client *c, XMapRequestEvent e) XFree(prop_ret); } -void wm_client_hide(Wm *wm, Client *c) +void wm_client_hide(Wm *wm, Client *c) { RETURN_IF_NULL(c); @@ -174,6 +175,8 @@ void wm_client_focus(Wm *wm, Client *c) XA_WINDOW, 1); c->focused = true; wm->focused_client = c; + TreeNode *node = wm_treenode_ptr_find_client_node(c->ws->tree, c); + c->ws->focused_node = node; wm_monitor_clients_border(wm, c->m); } diff --git a/src/wm.c b/src/wm.c index 9cbb5f8..bba2bcf 100644 --- a/src/wm.c +++ b/src/wm.c @@ -203,7 +203,8 @@ void wm_ws_tree_insert_client(Wm *wm, Workspace *ws, Client *client) return; } - TreeNode *focused_node = wm_treenode_ptr_find_focused_client_node(ws->tree); + TreeNode *focused_node = ws->focused_node ? ws->focused_node : + wm_treenode_ptr_find_focused_client_node(ws->tree); assert(focused_node); Client *old_client = focused_node->client; @@ -215,6 +216,7 @@ void wm_ws_tree_insert_client(Wm *wm, Workspace *ws, Client *client) wm_treenode_split_space(focused_node, &child1->pos, &child2->pos); child1->client = old_client; child2->client = client; + focused_node->client = NULL; wm_nodearray_push(&focused_node->children, child1); wm_nodearray_push(&focused_node->children, child2); @@ -228,6 +230,9 @@ void wm_switch_ws(Wm *wm, size_t ws) int wscc = 0; Client *c; + DEBUG_PRINT("switching to ws %d, clients:", ws); + wm_treenode_print(wm->smon->workspaces[ws].tree); + PtrArray current_ws_clients = wm_treenode_find_client_nodes_ptr( wm->smon->workspaces[wm->smon->selws].tree); @@ -258,10 +263,38 @@ void wm_switch_ws(Wm *wm, size_t ws) DEBUG_PRINT("wm_switch_ws focused ws client count: %d\n", wscc); + if (CURRENT_WS(wm).focused_node) + wm_client_focus(wm, CURRENT_WS(wm).focused_node->client); + + wm_layout(wm, wm->smon); + wm_ptrarray_free(¤t_ws_clients); wm_ptrarray_free(&switch_ws_clients); } +void wm_move_client_ws(Wm *wm, int ws) +{ + if (ws > wm->smon->wscount) + return; + + TreeNode *focused_node = wm_treenode_ptr_find_focused_client_node(CURRENT_WS(wm).tree); + Client *moved_client = focused_node->client; + + wm_ws_tree_insert_client(wm, &wm->smon->workspaces[ws], moved_client); + wm_client_hide(wm, moved_client); + moved_client->ws = &wm->smon->workspaces[ws]; + wm_client_set_atom(wm, moved_client, "_NET_WM_DESKTOP", + (unsigned char*)&moved_client->ws->index, XA_CARDINAL, + CURRENT_WS(wm).index); + + wm_treenode_remove_node(wm, CURRENT_WS(wm).tree, focused_node); + CURRENT_WS(wm).focused_node = NULL; + + char *str = wm_treenode_to_str(wm->smon->workspaces[ws].tree); + DEBUG_PRINT("move target ws tree: %s\n", str); + wm_layout(wm, wm->smon); +} + void wm_layout(Wm *wm, Monitor *m) { RETURN_IF_NULL(m); @@ -547,6 +580,13 @@ void wm_kb_switch_ws(Wm *wm, Arg *args) wm_switch_ws(wm, args->i); } +void wm_kb_move_client_ws(Wm *wm, Arg *args) +{ + RETURN_IF_NULL(args) + + wm_move_client_ws(wm, args->i); +} + void wm_kb_focus_dir(Wm *wm, Arg *args) { Client *c; diff --git a/src/wm.h b/src/wm.h index 8ecbead..d34bf97 100644 --- a/src/wm.h +++ b/src/wm.h @@ -63,6 +63,8 @@ if (c == NULL) \ #define WM_WS_NAME_LEN 64 +#define CURRENT_WS(wm) (wm)->smon->workspaces[(wm)->smon->selws] + typedef struct Client Client; typedef struct Workspace Workspace; typedef struct Monitor Monitor; @@ -93,6 +95,7 @@ struct Monitor { struct Workspace { TreeNode *tree; + TreeNode *focused_node; size_t index; char name[WM_WS_NAME_LEN]; Monitor *monitor; @@ -140,6 +143,7 @@ void wm_ws_tree_insert_client(Wm *wm, Workspace *ws, Client *client); void wm_spawn(Wm* wm, char **str); void wm_switch_ws(Wm* wm, size_t ws); +void wm_move_client_ws(Wm *wm, int ws); void wm_mainloop(Wm* wm); void wm_init(Wm *wm); void wm_exit(Wm *wm); @@ -148,6 +152,7 @@ void wm_grab_keys(Wm *wm); void wm_kb_spawn(Wm *wm, Arg *args); void wm_kb_kill(Wm *wm, Arg *args); void wm_kb_switch_ws(Wm *wm, Arg *args); +void wm_kb_move_client_ws(Wm *wm, Arg *args); void wm_kb_focus_dir(Wm *wm, Arg *args); void wm_kb_move_dir(Wm *wm, Arg *args); void wm_kb_exit(Wm* wm, Arg *args);