From 380efa9a5c8b91241835fc67304f14dc5c2ee532 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 16:51:06 -0500 Subject: [PATCH 01/12] add key binding for cycle monitor --- src/config_parser.c | 11 +++++++++++ zwm.conf | 8 ++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/config_parser.c b/src/config_parser.c index 07ece76..2dec7a7 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -82,6 +82,7 @@ static const conf_mapper_t _cmapper_[] = { DEFINE_MAPPING("cycle_window", cycle_win_wrapper), DEFINE_MAPPING("reload_config", reload_config_wrapper), DEFINE_MAPPING("cycle_desktop", cycle_desktop_wrapper), + DEFINE_MAPPING("cycle_monitors", cycle_monitors), DEFINE_MAPPING("shift_window", shift_floating_window), DEFINE_MAPPING("grow_floating_window", grow_floating_window), DEFINE_MAPPING("shrink_floating_window", shrink_floating_window), @@ -344,6 +345,10 @@ write_default_config(const char *filename, config_t *c) "bind = super + right -> func(cycle_window:right)\n" "bind = super + left -> func(cycle_window:left)\n" "bind = super + down -> func(cycle_window:down)\n" + "\n" + "; cycle focus between monitors\n" + "bind = super|ctrl + right -> func(cycle_monitors:next)\n" + "bind = super|ctrl + left -> func(cycle_monitors:prev)\n" "\n" "; shift floating window position to the specified direction\n" "bind = shift + up -> func(shift_window:up)\n" @@ -776,6 +781,12 @@ set_key_args(conf_key_t *key, char *func, char *arg) } else if (strcmp(arg, "vertical") == 0) { key->arg->rd = VERTICAL_DIR; } + } else if (strcmp(func, "cycle_monitors") == 0) { + if (strcmp(arg, "next") == 0) { + key->arg->tr = NEXT; + } else if (strcmp(arg, "prev") == 0) { + key->arg->tr = PREV; + } } } diff --git a/zwm.conf b/zwm.conf index eb5b005..19f6ed2 100644 --- a/zwm.conf +++ b/zwm.conf @@ -112,7 +112,7 @@ bind = super + h -> func(resize:shrink) ; change the gaps between windows bind = super + i -> func(gap_handler:grow) bind = super + d -> func(gap_handler:shrink) - + ; toggle fullscreen mode bind = super + f -> func(fullscreen) @@ -124,7 +124,11 @@ bind = super + up -> func(cycle_window:up) bind = super + right -> func(cycle_window:right) bind = super + left -> func(cycle_window:left) bind = super + down -> func(cycle_window:down) - + +; cycle focus between monitors +bind = super|ctrl + right -> func(cycle_monitors:next) +bind = super|ctrl + left -> func(cycle_monitors:prev) + ; shift floating window position to the specified direction bind = shift + up -> func(shift_window:up) bind = shift + right -> func(shift_window:right) From 99be65d159db40d33841e64d43f0080a5d3689f9 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 16:51:24 -0500 Subject: [PATCH 02/12] add traversal type --- src/type.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/type.h b/src/type.h index 8e09753..e29d5b5 100644 --- a/src/type.h +++ b/src/type.h @@ -84,6 +84,11 @@ typedef enum { NONE /* no direction */ } direction_t; +typedef enum { + NEXT = 1, + PREV +} traversal_t; + typedef enum { ERROR, INFO, @@ -271,6 +276,7 @@ typedef struct { resize_t r; /* resize operation */ resize_dir_t rd; /* resize direction */ layout_t t; /* layout type */ + traversal_t tr; /* traversal direction */ direction_t d; /* movement direction */ state_t s; /* window state, used to change window state */ } arg_t; From bc712ec866c65bfbc362b888094e4eaeb87e01a3 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 16:51:58 -0500 Subject: [PATCH 03/12] initial cycle_monitors implementation --- src/zwm.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/zwm.h | 1 + 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/zwm.c b/src/zwm.c index 892478e..3e2c1e3 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -152,12 +152,14 @@ static const _key__t _keys_[] = { DEFINE_KEY(SUPER | SHIFT, XK_j, traverse_stack_wrapper, &((arg_t){.d = DOWN})), DEFINE_KEY(SUPER | SHIFT, XK_f, flip_node_wrapper, NULL), DEFINE_KEY(SUPER | SHIFT, XK_r, reload_config_wrapper, NULL), - DEFINE_KEY(SUPER | SHIFT, XK_Left, cycle_desktop_wrapper, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER | SHIFT, XK_Right, cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER | SHIFT, XK_Left, cycle_desktop_wrapper, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER | SHIFT, XK_Right, cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), DEFINE_KEY(SUPER | SHIFT, XK_y, grow_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), DEFINE_KEY(SUPER | SHIFT, XK_h, grow_floating_window, &((arg_t){.rd = VERTICAL_DIR})), DEFINE_KEY(SUPER | SHIFT, XK_t, shrink_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), DEFINE_KEY(SUPER | SHIFT, XK_g, shrink_floating_window, &((arg_t){.rd = VERTICAL_DIR})), + DEFINE_KEY(SUPER | CTRL, XK_Right, cycle_monitors, &((arg_t){.tr = NEXT})), + DEFINE_KEY(SUPER | CTRL, XK_Left, cycle_monitors, &((arg_t){.tr = PREV})), }; static const uint32_t _buttons_[] = { @@ -1537,6 +1539,63 @@ cycle_win_wrapper(arg_t *arg) return 0; } +void +move_mouse_to_monitor(monitor_t *m) +{ + if (!m) + return; + int x = (m->rectangle.x + m->rectangle.width / 2) + 40; + int y = (m->rectangle.y + m->rectangle.height / 2) + 40; + + /* does not work, lacking propr args */ + xcb_warp_pointer( + wm->connection, wm->root_window, XCB_NONE, 0, 0, 0, 0, x, y); + xcb_flush(wm->connection); +} + +int +cycle_monitors(arg_t *arg) +{ + if (!multi_monitors) + return 0; + traversal_t dir = arg->tr; + monitor_t *curr = curr_monitor; + monitor_t *m = NULL; + if (dir == NEXT) { + m = curr->next; + if (!m) { + /* wrap around to the first monitor */ + m = head_monitor; + } + } else if (dir == PREV) { + monitor_t *head = head_monitor; + monitor_t *prev = NULL; + while (head && head->next) { + if (head->next == curr) { + m = head; + break; + } + head = head->next; + } + + /* wrap around to the last monitor */ + if (!m) { + while (head && head->next) { + head = head->next; + } + m = head; + } + } + if (m && m != curr) { + _LOG_(INFO, "switching to monitor: %d", m->id); + curr_monitor = m; + move_mouse_to_monitor(m); + return 0; + } + _LOG_(INFO, "no monitor change occurred"); + return 0; +} + int traverse_stack_wrapper(arg_t *arg) { diff --git a/src/zwm.h b/src/zwm.h index 63992dd..ae66490 100644 --- a/src/zwm.h +++ b/src/zwm.h @@ -71,6 +71,7 @@ int traverse_stack_wrapper(arg_t *arg); int shift_floating_window(arg_t *arg); int shrink_floating_window(arg_t *arg); int grow_floating_window(arg_t *arg); +int cycle_monitors(arg_t *arg); int tile(node_t *node); int set_focus(node_t *n, bool flag); int swap_node_wrapper(); From d6a50aa5c866ad7f8f56b1fff5f24e0e15306052 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 16:52:35 -0500 Subject: [PATCH 04/12] initial cycle_monitors implementation --- src/zwm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zwm.c b/src/zwm.c index 3e2c1e3..0bc6e5d 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -1558,16 +1558,18 @@ cycle_monitors(arg_t *arg) { if (!multi_monitors) return 0; + traversal_t dir = arg->tr; monitor_t *curr = curr_monitor; monitor_t *m = NULL; + if (dir == NEXT) { m = curr->next; if (!m) { /* wrap around to the first monitor */ m = head_monitor; } - } else if (dir == PREV) { + } else { monitor_t *head = head_monitor; monitor_t *prev = NULL; while (head && head->next) { From 3d78b2011b9f060c0ab45a4e27cb982ac030e7f8 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 18:46:26 -0500 Subject: [PATCH 05/12] add focused desktop & node to monitors --- src/type.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/type.h b/src/type.h index e29d5b5..73f26b6 100644 --- a/src/type.h +++ b/src/type.h @@ -221,6 +221,7 @@ struct node_t { */ typedef struct { node_t *tree; /* the tree in this desktop */ + node_t *node; /* focused node */ char name[DLEN]; /* the name, it stringfeis the index of this desktop */ uint16_t id; /* the number of this desktop */ uint16_t n_count; /* the number of active windows/external nodes */ @@ -236,6 +237,7 @@ typedef struct { typedef struct monitor_t monitor_t; struct monitor_t { desktop_t **desktops; /* array of desktops */ + desktop_t *desk; /* focused desktop */ monitor_t *next; /* next monitor in list */ char name[DLEN]; /* monitor name (e.g. HDMI or eDP) */ uint32_t id; /* monitor identifier, used with xinerama */ From ef813a7724c9f52aa5069bfac55b03d22770ecbe Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Sun, 15 Dec 2024 18:47:18 -0500 Subject: [PATCH 06/12] refactor to focus_desktop & focus_node --- src/tree.c | 38 +++---- src/tree.h | 2 +- src/zwm.c | 326 ++++++++++++++++------------------------------------- src/zwm.h | 2 +- 4 files changed, 116 insertions(+), 252 deletions(-) diff --git a/src/tree.c b/src/tree.c index 8302809..a629a29 100644 --- a/src/tree.c +++ b/src/tree.c @@ -556,11 +556,7 @@ sort(node_t **s, int n) void restack(void) { - int idx = get_focused_desktop_idx(); - if (idx == -1) - return; - - node_t *root = curr_monitor->desktops[idx]->tree; + node_t *root = curr_monitor->desk->tree; if (root == NULL) return; @@ -571,11 +567,8 @@ restack(void) _LOG_(ERROR, "cannot allocate stack"); return; } - stack_and_lower(root, - stack, - &top, - stack_size, - curr_monitor->desktops[idx]->layout == STACK); + stack_and_lower( + root, stack, &top, stack_size, curr_monitor->desk->layout == STACK); if (top == 0) { if (stack[0]->client) raise_window(stack[0]->client->window); @@ -1125,12 +1118,7 @@ apply_layout(desktop_t *d, layout_t t) break; } case MASTER: { - xcb_window_t win = - get_window_under_cursor(wm->connection, wm->root_window); - if (win == XCB_NONE || win == wm->root_window) { - return; - } - node_t *n = find_node_by_window_id(root, win); + node_t *n = curr_monitor->desk->node; if (n == NULL) { return; } @@ -1138,13 +1126,7 @@ apply_layout(desktop_t *d, layout_t t) break; } case STACK: { - xcb_window_t win = - get_window_under_cursor(wm->connection, wm->root_window); - - if (win == XCB_NONE || win == wm->root_window) { - return; - } - node_t *n = find_node_by_window_id(root, win); + node_t *n = curr_monitor->desk->node; if (n == NULL) { return; } @@ -1363,7 +1345,7 @@ delete_node(node_t *node, desktop_t *d) _LOG_(ERROR, "node to be deleted is null"); return; } - + bool swap = node == d->node; if (IS_INTERNAL(node)) { _LOG_(ERROR, "node to be deleted is not an external node type: %d", @@ -1381,6 +1363,11 @@ delete_node(node_t *node, desktop_t *d) check = true; } + node_t *n = prev_node(node); + if (!n) { + n = next_node(node); + } + if (!unlink_node(node, d)) { _LOG_(ERROR, "could not unlink node.. abort"); return; @@ -1393,6 +1380,9 @@ delete_node(node_t *node, desktop_t *d) _FREE_(node->client); _FREE_(node); + if (!check) { + d->node = n; + } out: d->n_count -= 1; if (!is_tree_empty(d->tree)) { diff --git a/src/tree.h b/src/tree.h index c5abf14..2de5bb3 100644 --- a/src/tree.h +++ b/src/tree.h @@ -40,7 +40,7 @@ node_t *next_node(node_t *current); node_t *cycle_win(node_t *node, direction_t); node_t *find_left_leaf(node_t *root); node_t *find_any_leaf(node_t *root); -node_t *get_focused_node(node_t *n); +node_t *get_focused_node__(node_t *n); bool unlink_node(node_t *node, desktop_t *d); void horizontal_resize(node_t *n, resize_t t); void apply_master_layout(node_t *parent); diff --git a/src/zwm.c b/src/zwm.c index 0bc6e5d..786b13b 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -329,13 +329,7 @@ win_name(xcb_window_t win) int layout_handler(arg_t *arg) { - int i = get_focused_desktop_idx(); - if (i == -1) { - _LOG_(ERROR, "Cannot get focused desktop"); - return -1; - } - - desktop_t *d = curr_monitor->desktops[i]; + desktop_t *d = curr_monitor->desk; if (arg->t == STACK && d->n_count < 2) return 0; @@ -346,11 +340,7 @@ layout_handler(arg_t *arg) static node_t * get_foucsed_desktop_tree(void) { - int idx = get_focused_desktop_idx(); - if (idx == -1) - return NULL; - - node_t *root = curr_monitor->desktops[idx]->tree; + node_t *root = curr_monitor->desk->tree; if (root == NULL) return NULL; @@ -381,16 +371,12 @@ render_trees(void) int change_state(arg_t *arg) { - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - if (w == XCB_NONE) - return -1; - node_t *root = get_foucsed_desktop_tree(); + node_t *root = curr_monitor->desk->tree; if (root == NULL) return -1; - node_t *n = find_node_by_window_id(root, w); - + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; @@ -547,7 +533,7 @@ ewmh_set_supporting(xcb_window_t win, xcb_ewmh_conn_t *ewmh) } int -get_focused_desktop_idx(void) +get_focused_desktop_idx__(void) { if (curr_monitor == NULL) { _LOG_(ERROR, "curr_monitor is null"); @@ -790,24 +776,14 @@ swap_node_wrapper() _LOG_(ERROR, "Failed to swap node, current monitor is NULL"); return -1; } - - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - if (w == wm->root_window) { - return 0; - } - - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; if (swap_node(n) != 0) return -1; - return render_tree(root); + return render_tree(curr_monitor->desk->tree); } /* transfer_node_wrapper - handles transferring a node between desktops. @@ -822,33 +798,27 @@ swap_node_wrapper() int transfer_node_wrapper(arg_t *arg) { - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - if (w == wm->root_window) - return 0; - const int i = arg->idx; - int d = get_focused_desktop_idx(); - if (d == -1) - return d; - if (d == i) { + if (curr_monitor->desk->id == i) { _LOG_(INFO, "switch node to curr desktop... abort"); return 0; } - node_t *root = curr_monitor->desktops[d]->tree; + node_t *root = curr_monitor->desk->tree; if (is_tree_empty(root)) { return 0; } - node_t *node = get_focused_node(root); + node_t *node = curr_monitor->desk->node; + if (!node) { _LOG_(ERROR, "focused node is null"); return 0; } desktop_t *nd = curr_monitor->desktops[i]; - desktop_t *od = curr_monitor->desktops[d]; + desktop_t *od = curr_monitor->desk; #ifdef _DEBUG__ _LOG_(INFO, "new desktop %d nodes--------------", i + 1); log_tree_nodes(nd->tree); @@ -884,19 +854,17 @@ transfer_node_wrapper(arg_t *arg) int horizontal_resize_wrapper(arg_t *arg) { - const int i = get_focused_desktop_idx(); - if (i == -1) - return -1; - if (curr_monitor->desktops[i]->layout == STACK) { + if (curr_monitor->desk->layout == STACK) { return 0; } - node_t *root = curr_monitor->desktops[i]->tree; + node_t *root = curr_monitor->desk->tree; if (root == NULL) return -1; - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; + if (n == NULL) return -1; /* todo: if node was flipped, reize up or down instead */ @@ -913,11 +881,7 @@ horizontal_resize_wrapper(arg_t *arg) int grow_floating_window(arg_t *arg) { - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; @@ -957,11 +921,7 @@ grow_floating_window(arg_t *arg) int shrink_floating_window(arg_t *arg) { - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; @@ -996,11 +956,7 @@ shrink_floating_window(arg_t *arg) int resize_floating_window(arg_t *arg) { - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; @@ -1036,11 +992,7 @@ resize_floating_window(arg_t *arg) int shift_floating_window(arg_t *arg) { - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); + node_t *n = curr_monitor->desk->node; if (n == NULL) return -1; @@ -1089,16 +1041,7 @@ shift_floating_window(arg_t *arg) int set_fullscreen_wrapper() { - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - if (w == wm->root_window) { - return 0; - } - - node_t *n = find_node_by_window_id(root, w); + node_t *n = curr_monitor->desk->node; if (n == NULL) { _LOG_(ERROR, "cannot find focused node"); return -1; @@ -1398,13 +1341,14 @@ reload_config_wrapper() current_monitor = current_monitor->next; } } else if (conf.virtual_desktops < prev_virtual_desktops) { - int idx = get_focused_desktop_idx(); monitor_t *current_monitor = head_monitor; while (current_monitor) { for (int j = conf.virtual_desktops; j < prev_virtual_desktops; j++) { - if (idx == current_monitor->desktops[j]->id) { - switch_desktop_wrapper(&(arg_t){.idx = idx--}); + if (curr_monitor->desk->id == + current_monitor->desktops[j]->id) { + switch_desktop_wrapper(&(arg_t){ + .idx = curr_monitor->desk->id == 0 ? 1 : 0}); } if (current_monitor->desktops[j]) { if (!is_tree_empty( @@ -1436,13 +1380,9 @@ reload_config_wrapper() return false; } - const int di = get_focused_desktop_idx(); - if (di == -1) { - return false; - } - if (ewmh_update_current_desktop( - wm->ewmh, wm->screen_nbr, (uint32_t)di) != 0) { + wm->ewmh, wm->screen_nbr, (uint32_t)curr_monitor->desk->id) != + 0) { return false; } @@ -1457,7 +1397,7 @@ reload_config_wrapper() } out: - render_tree(curr_monitor->desktops[get_focused_desktop_idx()]->tree); + render_tree(curr_monitor->desk->tree); xcb_flush(wm->connection); return 0; } @@ -1478,29 +1418,19 @@ gap_handler(arg_t *arg) apply_monitor_layout_changes(current_monitor); current_monitor = current_monitor->next; } - - int idx = get_focused_desktop_idx(); - if (idx == -1) - return -1; - - render_tree(curr_monitor->desktops[idx]->tree); + render_tree(curr_monitor->desk->tree); xcb_flush(wm->connection); - return 0; } int flip_node_wrapper() { - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - - if (w == wm->root_window) - return 0; - - node_t *tree = get_foucsed_desktop_tree(); + node_t *tree = curr_monitor->desk->tree; if (!tree) return -1; - node_t *node = get_focused_node(tree); + + node_t *node = curr_monitor->desk->node; if (node == NULL) return -1; @@ -1512,16 +1442,14 @@ int cycle_win_wrapper(arg_t *arg) { direction_t d = arg->d; - node_t *root = get_foucsed_desktop_tree(); + node_t *root = curr_monitor->desk->tree; if (!root) { return 0; } - node_t *f = get_focused_node(root); + node_t *f = curr_monitor->desk->node; if (!f) { _LOG_(INFO, "cannot find focused window"); - xcb_window_t w = - get_window_under_cursor(wm->connection, wm->root_window); - f = find_node_by_window_id(root, w); + return -1; } node_t *next = cycle_win(f, d); if (next == NULL) { @@ -1535,7 +1463,7 @@ cycle_win_wrapper(arg_t *arg) set_focus(next, true); set_active_window_name(next->client->window); update_focus(root, next); - + curr_monitor->desk->node = next; return 0; } @@ -1601,17 +1529,12 @@ cycle_monitors(arg_t *arg) int traverse_stack_wrapper(arg_t *arg) { - direction_t d = arg->d; - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - - if (w == wm->root_window) - return 0; - - node_t *root = get_foucsed_desktop_tree(); + direction_t d = arg->d; + node_t *root = curr_monitor->desk->tree; if (!root) return -1; - node_t *node = get_focused_node(root); + node_t *node = curr_monitor->desk->node; node_t *n = d == UP ? next_node(node) : prev_node(node); if (n == NULL) { @@ -1619,6 +1542,7 @@ traverse_stack_wrapper(arg_t *arg) } set_focus(n, true); + curr_monitor->desk->node = n; if (has_floating_window(root)) restack(); @@ -1778,6 +1702,7 @@ init_desktop(void) d->is_focused = false; d->n_count = 0; d->tree = NULL; + d->node = NULL; return d; } @@ -1796,6 +1721,8 @@ init_monitor(void) m->is_occupied = false; m->is_wired = false; m->next = NULL; + m->desktops = NULL; + m->desk = NULL; return m; } @@ -2819,6 +2746,7 @@ setup_desktops(void) snprintf(d->name, sizeof(d->name), "%d", j + 1); curr->desktops[j] = d; } + curr->desk = curr->desktops[0]; _LOG_(INFO, "successfuly assigned desktops for monitor %s", curr->name); curr = curr->next; } @@ -2898,13 +2826,8 @@ setup_ewmh(void) return false; } - const int di = get_focused_desktop_idx(); - if (di == -1) { - return false; - } - - if (ewmh_update_current_desktop(wm->ewmh, wm->screen_nbr, (uint32_t)di) != - 0) { + if (ewmh_update_current_desktop( + wm->ewmh, wm->screen_nbr, (uint32_t)curr_monitor->desk->id) != 0) { return false; } @@ -3509,7 +3432,10 @@ send_client_message(xcb_window_t win, int close_or_kill_wrapper() { - xcb_window_t win = get_window_under_cursor(wm->connection, wm->root_window); + if (!curr_monitor->desk->node || !curr_monitor->desk->node->client) { + return 0; + } + xcb_window_t win = curr_monitor->desk->node->client->window; if (!window_exists(wm->connection, win)) return 0; return close_or_kill(win); @@ -3657,13 +3583,7 @@ kill_window(xcb_window_t win) xcb_icccm_get_text_property_reply_wipe(&t_reply); } - int curi = get_focused_desktop_idx(); - if (curi == -1) { - _LOG_(ERROR, "cannot find focused desktop"); - return curi; - } - - desktop_t *d = curr_monitor->desktops[curi]; + desktop_t *d = curr_monitor->desk; node_t *n = find_node_by_window_id(d->tree, win); client_t *c = (n) ? n->client : NULL; bool another_desktop = false; @@ -3875,6 +3795,7 @@ update_focused_desktop(int id) curr_monitor->desktops[i]->is_focused = false; } else { curr_monitor->desktops[i]->is_focused = true; + curr_monitor->desk = curr_monitor->desktops[i]; } } } @@ -3904,7 +3825,7 @@ switch_desktop_wrapper(arg_t *arg) if (switch_desktop(arg->idx) != 0) { return -1; } - node_t *tree = curr_monitor->desktops[arg->idx]->tree; + node_t *tree = curr_monitor->desk->tree; return render_tree(tree); } @@ -3915,31 +3836,32 @@ switch_desktop(const int nd) return 0; } - int current = get_focused_desktop_idx(); - if (current == -1) - return current; - if (nd == current) + node_t *tree_to_hide = curr_monitor->desk->tree; + node_t *tree_to_show = curr_monitor->desktops[nd]->tree; + desktop_t *target_desktop = curr_monitor->desktops[nd]; + + if (curr_monitor->desk == curr_monitor->desktops[nd]) return 0; update_focused_desktop(nd); - if (show_windows(curr_monitor->desktops[nd]->tree) != 0) { + if (show_windows(tree_to_show) != 0) { return -1; } - if (hide_windows(curr_monitor->desktops[current]->tree) != 0) { + if (hide_windows(tree_to_hide) != 0) { return -1; } - set_active_window_name(XCB_NONE); win_focus(focused_win, false); focused_win = XCB_NONE; #ifdef _DEBUG__ _LOG_(INFO, "new desktop %d nodes--------------", nd + 1); - log_tree_nodes(curr_monitor->desktops[nd]->tree); - _LOG_(INFO, "old desktop %d nodes--------------", current + 1); - log_tree_nodes(curr_monitor->desktops[current]->tree); + log_tree_nodes(tree_to_show); + _LOG_( + INFO, "old desktop %d nodes--------------", curr_monitor->desk->id + 1); + log_tree_nodes(tree_to_hide); #endif if (ewmh_update_current_desktop(wm->ewmh, wm->screen_nbr, nd) != 0) { @@ -3988,7 +3910,7 @@ fill_floating_rectangle(xcb_get_geometry_reply_t *geometry, rectangle_t *r) int cycle_desktop_wrapper(arg_t *arg) { - int current = get_focused_desktop_idx(); + int current = get_focused_desktop_idx__(); if (current == -1) { _LOG_(ERROR, "cnnot find current desktop"); return -1; @@ -4242,7 +4164,7 @@ handle_first_window(client_t *client, desktop_t *d) d->tree->rectangle = r; d->n_count += 1; set_focus(d->tree, true); - + d->node = d->tree; ewmh_update_client_list(); return tile(d->tree); } @@ -4255,25 +4177,18 @@ handle_subsequent_window(client_t *client, desktop_t *d) _LOG_(DEBUG, "handling tiled window %s id %d", name, client->window); _FREE_(name); #endif + node_t *n = NULL; - xcb_window_t wi = get_window_under_cursor(wm->connection, wm->root_window); - node_t *n = NULL; - - if (wm->bar && wi == wm->bar->window) { - n = find_any_leaf(d->tree); - } else { - n = get_focused_node(d->tree); - if (n == NULL || n->client == NULL) { - _LOG_(ERROR, "cannot find focused node"); - return 0; - } + n = curr_monitor->desk->node; + if (n == NULL || n->client == NULL) { + _LOG_(ERROR, "cannot find focused node"); + return 0; } if (IS_FLOATING(n->client) && !IS_ROOT(n)) { - _LOG_(INFO, "node under cursor is floating %d", wi); + _LOG_(INFO, "node under cursor is floating %d", n->client->window); n = find_any_leaf(d->tree); if (n == NULL) { - _LOG_(ERROR, "ret here"); return 0; } } @@ -4283,7 +4198,7 @@ handle_subsequent_window(client_t *client, desktop_t *d) } if (n == NULL || n->client == NULL) { - _LOG_(ERROR, "cannot find node with window id %d", wi); + _LOG_(ERROR, "cannot find node with window id"); return -1; } @@ -4303,7 +4218,7 @@ handle_subsequent_window(client_t *client, desktop_t *d) if (d->layout == STACK) { set_focus(new_node, true); } - + curr_monitor->desk->node = new_node; ewmh_update_client_list(); return render_tree(d->tree); } @@ -4334,17 +4249,10 @@ handle_floating_window(client_t *client, desktop_t *d) set_focus(d->tree, true); return tile(d->tree); } else { - xcb_window_t wi = - get_window_under_cursor(wm->connection, wm->root_window); - if (wi == wm->root_window || wi == 0) { - _FREE_(client); - return 0; - } - node_t *n = find_node_by_window_id(d->tree, wi); + node_t *n = curr_monitor->desk->node; n = n == NULL ? find_any_leaf(d->tree) : n; if (n == NULL || n->client == NULL) { _FREE_(client); - _LOG_(ERROR, "cannot find node with window id %d", wi); return -1; } @@ -4553,20 +4461,12 @@ handle_map_request(const xcb_event_t *event) return 0; } - int idx = get_focused_desktop_idx(); - if (idx == -1) { - _LOG_(ERROR, "cannot get focused desktop idx"); - return idx; - } - /* check if the window already exists in the tree to avoid duplication */ - if (find_node_by_window_id(curr_monitor->desktops[idx]->tree, win) != - NULL) { + if (find_node_by_window_id(curr_monitor->desk->tree, win) != NULL) { return 0; } - desktop_t *d = curr_monitor->desktops[idx]; - rule_t *rule = get_window_rule(win); + rule_t *rule = get_window_rule(win); if (rule) { if (rule->desktop_id != -1) { @@ -4574,15 +4474,15 @@ handle_map_request(const xcb_event_t *event) rule->desktop_id, win, rule->state == TILED); } if (rule->state == FLOATING) { - return handle_floating_window_request(win, d); + return handle_floating_window_request(win, curr_monitor->desk); } else if (rule->state == TILED) { - return handle_tiled_window_request(win, d); + return handle_tiled_window_request(win, curr_monitor->desk); } } ewmh_window_type_t wint = window_type(win); if ((apply_floating_hints(win) != -1 && wint != WINDOW_TYPE_DOCK)) { - return handle_floating_window_request(win, d); + return handle_floating_window_request(win, curr_monitor->desk); } if (wint == WINDOW_TYPE_NOTIFICATION) { map_floating(win); @@ -4591,12 +4491,14 @@ handle_map_request(const xcb_event_t *event) switch (wint) { case WINDOW_TYPE_UNKNOWN: - case WINDOW_TYPE_NORMAL: return handle_tiled_window_request(win, d); - case WINDOW_TYPE_DOCK: return handle_bar_request(win, d); + case WINDOW_TYPE_NORMAL: + return handle_tiled_window_request(win, curr_monitor->desk); + case WINDOW_TYPE_DOCK: return handle_bar_request(win, curr_monitor->desk); case WINDOW_TYPE_TOOLBAR_MENU: case WINDOW_TYPE_UTILITY: case WINDOW_TYPE_SPLASH: - case WINDOW_TYPE_DIALOG: return handle_floating_window_request(win, d); + case WINDOW_TYPE_DIALOG: + return handle_floating_window_request(win, curr_monitor->desk); default: return 0; } } @@ -4630,11 +4532,7 @@ handle_enter_notify(const xcb_event_t *event) return 0; } - const int curd = get_focused_desktop_idx(); - if (curd == -1) - return curd; - - node_t *root = curr_monitor->desktops[curd]->tree; + node_t *root = curr_monitor->desk->tree; if (!root) { return -1; } @@ -4684,7 +4582,7 @@ handle_enter_notify(const xcb_event_t *event) return -1; } } else { - if (curr_monitor->desktops[curd]->layout == STACK) { + if (curr_monitor->desk->layout == STACK) { if (win_focus(n->client->window, true) != 0) { _LOG_( ERROR, "cannot focus window %d (enter)", n->client->window); @@ -4701,6 +4599,7 @@ handle_enter_notify(const xcb_event_t *event) focused_win = n->client->window; update_focus(root, n); + curr_monitor->desk->node = n; if (has_floating_window(root)) { restack(); @@ -4738,14 +4637,11 @@ handle_leave_notify(const xcb_event_t *event) return 0; } - const int curd = get_focused_desktop_idx(); - if (curd == -1) - return -1; - if (curr_monitor->desktops[curd]->layout == STACK) { + if (curr_monitor->desk->layout == STACK) { return 0; } - node_t *root = curr_monitor->desktops[curd]->tree; + node_t *root = curr_monitor->desk->tree; xcb_window_t active_window = XCB_NONE; node_t *n = find_node_by_window_id(root, win); client_t *client = (n && n->client) ? n->client : NULL; @@ -4898,7 +4794,7 @@ handle_net_wm_state(xcb_window_t win_event, uint32_t action, uint32_t state) return 0; } - node_t *root = get_foucsed_desktop_tree(); + node_t *root = curr_monitor->desk->tree; if (!root) { return -1; } @@ -4928,16 +4824,14 @@ handle_net_wm_state(xcb_window_t win_event, uint32_t action, uint32_t state) break; case STATE_BELOW: { _LOG_WM_STATE_(BELOW, win, name); - if (curr_monitor->desktops[get_focused_desktop_idx()]->layout != - STACK) { + if (curr_monitor->desk->layout != STACK) { lower_window(win); } break; } case STATE_ABOVE: { _LOG_WM_STATE_(ABOVE, win, name); - if (curr_monitor->desktops[get_focused_desktop_idx()]->layout != - STACK) { + if (curr_monitor->desk->layout != STACK) { raise_window(win); } break; @@ -5022,9 +4916,7 @@ handle_net_wm_desktop(xcb_window_t win, uint32_t index) arrange_tree(d->tree, d->layout); } - int i = get_focused_desktop_idx(); - bool render = curr_monitor->desktops[i] == d; - + bool render = curr_monitor->desk == d; return render ? render_tree(d->tree) : 0; } @@ -5100,17 +4992,12 @@ handle_unmap_notify(const xcb_event_t *event) { xcb_unmap_notify_event_t *ev = (xcb_unmap_notify_event_t *)event; xcb_window_t win = ev->window; - int idx = get_focused_desktop_idx(); - if (idx == -1) - return -1; - #ifdef _DEBUG__ char *s = win_name(win); _LOG_(DEBUG, "recieved unmap notify for %d, name %s ", win, s); _FREE_(s); #endif - - node_t *root = curr_monitor->desktops[idx]->tree; + node_t *root = curr_monitor->desk->tree; if (root == NULL) return 0; @@ -5163,12 +5050,7 @@ handle_configure_request(const xcb_event_t *event) ev->width, ev->height); #endif - const int d = get_focused_desktop_idx(); - if (d == -1) { - return d; - } - - node_t *n = curr_monitor->desktops[d]->tree; + node_t *n = curr_monitor->desk->tree; bool is_managed = client_exist(n, win); if (!is_managed) { uint16_t mask = 0; @@ -5228,17 +5110,13 @@ handle_destroy_notify(const xcb_event_t *event) { xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t *)event; xcb_window_t win = ev->window; - int idx = get_focused_desktop_idx(); - if (idx == -1) - return -1; - #ifdef _DEBUG__ char *s = win_name(win); _LOG_(DEBUG, "recieved destroy notify for %d, name %s ", win, s); _FREE_(s); #endif - node_t *root = curr_monitor->desktops[idx]->tree; + node_t *root = curr_monitor->desk->tree; if (root == NULL) return 0; @@ -5305,12 +5183,7 @@ handle_button_press_event(const xcb_event_t *event) if (!window_exists(wm->connection, win)) { return 0; } - - const int curd = get_focused_desktop_idx(); - if (curd == -1) - return -1; - - node_t *root = curr_monitor->desktops[curd]->tree; + node_t *root = curr_monitor->desk->tree; node_t *n = find_node_by_window_id(root, win); client_t *client = (n && n->client) ? n->client : NULL; @@ -5341,7 +5214,7 @@ handle_button_press_event(const xcb_event_t *event) return -1; } } else { - if (curr_monitor->desktops[curd]->layout == STACK) { + if (curr_monitor->desk->layout == STACK) { if (win_focus(n->client->window, true) != 0) { _LOG_( ERROR, "cannot focus window %d (enter)", n->client->window); @@ -5358,6 +5231,7 @@ handle_button_press_event(const xcb_event_t *event) focused_win = n->client->window; update_focus(root, n); + curr_monitor->desk->node = n; if (has_floating_window(root)) { restack(); diff --git a/src/zwm.h b/src/zwm.h index ae66490..5173848 100644 --- a/src/zwm.h +++ b/src/zwm.h @@ -60,7 +60,7 @@ int cycle_win_wrapper(arg_t *arg); int set_fullscreen_wrapper(); int flip_node_wrapper(); int reload_config_wrapper(); -int get_focused_desktop_idx(); +int get_focused_desktop_idx__(); /* deprecated */ int switch_desktop_wrapper(arg_t *arg); int transfer_node_wrapper(arg_t *arg); int horizontal_resize_wrapper(arg_t *arg); From 1bca1556cb10b01e3e98c45b995ed0d919a7d5f8 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Mon, 16 Dec 2024 03:58:19 -0500 Subject: [PATCH 07/12] roll back --- src/tree.c | 26 ++++++--- src/tree.h | 2 +- src/type.h | 4 +- src/zwm.c | 165 +++++++++++++++++++++++++++++++++++++++-------------- src/zwm.h | 2 +- 5 files changed, 145 insertions(+), 54 deletions(-) diff --git a/src/tree.c b/src/tree.c index a629a29..f80d55d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1118,7 +1118,12 @@ apply_layout(desktop_t *d, layout_t t) break; } case MASTER: { - node_t *n = curr_monitor->desk->node; + xcb_window_t win = + get_window_under_cursor(wm->connection, wm->root_window); + if (win == XCB_NONE || win == wm->root_window) { + return; + } + node_t *n = find_node_by_window_id(root, win); if (n == NULL) { return; } @@ -1126,7 +1131,13 @@ apply_layout(desktop_t *d, layout_t t) break; } case STACK: { - node_t *n = curr_monitor->desk->node; + xcb_window_t win = + get_window_under_cursor(wm->connection, wm->root_window); + + if (win == XCB_NONE || win == wm->root_window) { + return; + } + node_t *n = find_node_by_window_id(root, win); if (n == NULL) { return; } @@ -1345,7 +1356,7 @@ delete_node(node_t *node, desktop_t *d) _LOG_(ERROR, "node to be deleted is null"); return; } - bool swap = node == d->node; + /*bool swap = node == d->node;*/ if (IS_INTERNAL(node)) { _LOG_(ERROR, "node to be deleted is not an external node type: %d", @@ -1363,10 +1374,10 @@ delete_node(node_t *node, desktop_t *d) check = true; } - node_t *n = prev_node(node); + /*node_t *n = prev_node(node); if (!n) { n = next_node(node); - } + }*/ if (!unlink_node(node, d)) { _LOG_(ERROR, "could not unlink node.. abort"); @@ -1375,14 +1386,15 @@ delete_node(node_t *node, desktop_t *d) if (check) { assert(!d->tree); + /*d->node = NULL;*/ } _FREE_(node->client); _FREE_(node); - if (!check) { + /*if (!check) { d->node = n; - } + }*/ out: d->n_count -= 1; if (!is_tree_empty(d->tree)) { diff --git a/src/tree.h b/src/tree.h index 2de5bb3..c5abf14 100644 --- a/src/tree.h +++ b/src/tree.h @@ -40,7 +40,7 @@ node_t *next_node(node_t *current); node_t *cycle_win(node_t *node, direction_t); node_t *find_left_leaf(node_t *root); node_t *find_any_leaf(node_t *root); -node_t *get_focused_node__(node_t *n); +node_t *get_focused_node(node_t *n); bool unlink_node(node_t *node, desktop_t *d); void horizontal_resize(node_t *n, resize_t t); void apply_master_layout(node_t *parent); diff --git a/src/type.h b/src/type.h index 73f26b6..356ba65 100644 --- a/src/type.h +++ b/src/type.h @@ -220,8 +220,8 @@ struct node_t { * the wm could have up to 10 desktops. */ typedef struct { - node_t *tree; /* the tree in this desktop */ - node_t *node; /* focused node */ + node_t *tree; /* the tree in this desktop */ + /* node_t *node; focused node */ char name[DLEN]; /* the name, it stringfeis the index of this desktop */ uint16_t id; /* the number of this desktop */ uint16_t n_count; /* the number of active windows/external nodes */ diff --git a/src/zwm.c b/src/zwm.c index 786b13b..31a7a6d 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -371,12 +371,15 @@ render_trees(void) int change_state(arg_t *arg) { + xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); + if (w == XCB_NONE) + return -1; - node_t *root = curr_monitor->desk->tree; + node_t *root = get_foucsed_desktop_tree(); if (root == NULL) return -1; - node_t *n = curr_monitor->desk->node; + node_t *n = find_node_by_window_id(root, w); if (n == NULL) return -1; @@ -533,7 +536,7 @@ ewmh_set_supporting(xcb_window_t win, xcb_ewmh_conn_t *ewmh) } int -get_focused_desktop_idx__(void) +get_focused_desktop_idx(void) { if (curr_monitor == NULL) { _LOG_(ERROR, "curr_monitor is null"); @@ -776,14 +779,24 @@ swap_node_wrapper() _LOG_(ERROR, "Failed to swap node, current monitor is NULL"); return -1; } - node_t *n = curr_monitor->desk->node; + + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); + if (w == wm->root_window) { + return 0; + } + + node_t *n = get_focused_node(root); if (n == NULL) return -1; if (swap_node(n) != 0) return -1; - return render_tree(curr_monitor->desk->tree); + return render_tree(root); } /* transfer_node_wrapper - handles transferring a node between desktops. @@ -798,6 +811,9 @@ swap_node_wrapper() int transfer_node_wrapper(arg_t *arg) { + xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); + if (w == wm->root_window) + return 0; const int i = arg->idx; if (curr_monitor->desk->id == i) { @@ -810,7 +826,7 @@ transfer_node_wrapper(arg_t *arg) return 0; } - node_t *node = curr_monitor->desk->node; + node_t *node = get_focused_node(root); if (!node) { _LOG_(ERROR, "focused node is null"); @@ -863,7 +879,7 @@ horizontal_resize_wrapper(arg_t *arg) if (root == NULL) return -1; - node_t *n = curr_monitor->desk->node; + node_t *n = get_focused_node(root); if (n == NULL) return -1; @@ -881,7 +897,11 @@ horizontal_resize_wrapper(arg_t *arg) int grow_floating_window(arg_t *arg) { - node_t *n = curr_monitor->desk->node; + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + node_t *n = get_focused_node(root); if (n == NULL) return -1; @@ -921,7 +941,11 @@ grow_floating_window(arg_t *arg) int shrink_floating_window(arg_t *arg) { - node_t *n = curr_monitor->desk->node; + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + node_t *n = get_focused_node(root); if (n == NULL) return -1; @@ -956,7 +980,11 @@ shrink_floating_window(arg_t *arg) int resize_floating_window(arg_t *arg) { - node_t *n = curr_monitor->desk->node; + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + node_t *n = get_focused_node(root); if (n == NULL) return -1; @@ -992,7 +1020,11 @@ resize_floating_window(arg_t *arg) int shift_floating_window(arg_t *arg) { - node_t *n = curr_monitor->desk->node; + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + node_t *n = get_focused_node(root); if (n == NULL) return -1; @@ -1041,7 +1073,16 @@ shift_floating_window(arg_t *arg) int set_fullscreen_wrapper() { - node_t *n = curr_monitor->desk->node; + node_t *root = curr_monitor->desk->tree; + if (root == NULL) + return -1; + + xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); + if (w == wm->root_window) { + return 0; + } + + node_t *n = find_node_by_window_id(root, w); if (n == NULL) { _LOG_(ERROR, "cannot find focused node"); return -1; @@ -1430,7 +1471,7 @@ flip_node_wrapper() if (!tree) return -1; - node_t *node = curr_monitor->desk->node; + node_t *node = get_focused_node(tree); if (node == NULL) return -1; @@ -1446,10 +1487,12 @@ cycle_win_wrapper(arg_t *arg) if (!root) { return 0; } - node_t *f = curr_monitor->desk->node; + node_t *f = get_focused_node(root); if (!f) { _LOG_(INFO, "cannot find focused window"); - return -1; + xcb_window_t w = + get_window_under_cursor(wm->connection, wm->root_window); + f = find_node_by_window_id(root, w); } node_t *next = cycle_win(f, d); if (next == NULL) { @@ -1463,7 +1506,7 @@ cycle_win_wrapper(arg_t *arg) set_focus(next, true); set_active_window_name(next->client->window); update_focus(root, next); - curr_monitor->desk->node = next; + /*curr_monitor->desk->node = next;*/ return 0; } @@ -1472,12 +1515,31 @@ move_mouse_to_monitor(monitor_t *m) { if (!m) return; - int x = (m->rectangle.x + m->rectangle.width / 2) + 40; - int y = (m->rectangle.y + m->rectangle.height / 2) + 40; + xcb_query_pointer_reply_t *ptr = xcb_query_pointer_reply( + wm->connection, + xcb_query_pointer(wm->connection, wm->root_window), + NULL); + + if (ptr == NULL) { + _LOG_(ERROR, "failed to query pointer"); + return; + } + + int pointer_x = ptr->root_x; + int pointer_y = ptr->root_y; - /* does not work, lacking propr args */ - xcb_warp_pointer( - wm->connection, wm->root_window, XCB_NONE, 0, 0, 0, 0, x, y); + int x = (m->rectangle.x + m->rectangle.width / 2) + 100; + int y = (m->rectangle.y + m->rectangle.height / 2) + 100; + + xcb_warp_pointer(wm->connection, + wm->root_window, + wm->root_window, + pointer_x, + pointer_y, + curr_monitor->rectangle.width, + curr_monitor->rectangle.height, + x, + y); xcb_flush(wm->connection); } @@ -1516,12 +1578,16 @@ cycle_monitors(arg_t *arg) m = head; } } + if (m && m != curr) { - _LOG_(INFO, "switching to monitor: %d", m->id); - curr_monitor = m; + _LOG_(INFO, "switching monitor: '%s' -> '%s'", curr->name, m->name); + /* when a mouse moves, we update the current monitor in the enter_notify + * handler */ move_mouse_to_monitor(m); + /*curr_monitor = m;*/ return 0; } + _LOG_(INFO, "no monitor change occurred"); return 0; } @@ -1529,12 +1595,17 @@ cycle_monitors(arg_t *arg) int traverse_stack_wrapper(arg_t *arg) { - direction_t d = arg->d; - node_t *root = curr_monitor->desk->tree; + direction_t d = arg->d; + xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); + + if (w == wm->root_window) + return 0; + + node_t *root = curr_monitor->desk->tree; if (!root) return -1; - node_t *node = curr_monitor->desk->node; + node_t *node = get_focused_node(root); node_t *n = d == UP ? next_node(node) : prev_node(node); if (n == NULL) { @@ -1542,7 +1613,7 @@ traverse_stack_wrapper(arg_t *arg) } set_focus(n, true); - curr_monitor->desk->node = n; + /*curr_monitor->desk->node = n;*/ if (has_floating_window(root)) restack(); @@ -1702,7 +1773,7 @@ init_desktop(void) d->is_focused = false; d->n_count = 0; d->tree = NULL; - d->node = NULL; + /*d->node = NULL;*/ return d; } @@ -3432,10 +3503,7 @@ send_client_message(xcb_window_t win, int close_or_kill_wrapper() { - if (!curr_monitor->desk->node || !curr_monitor->desk->node->client) { - return 0; - } - xcb_window_t win = curr_monitor->desk->node->client->window; + xcb_window_t win = get_window_under_cursor(wm->connection, wm->root_window); if (!window_exists(wm->connection, win)) return 0; return close_or_kill(win); @@ -3910,7 +3978,7 @@ fill_floating_rectangle(xcb_get_geometry_reply_t *geometry, rectangle_t *r) int cycle_desktop_wrapper(arg_t *arg) { - int current = get_focused_desktop_idx__(); + int current = get_focused_desktop_idx(); if (current == -1) { _LOG_(ERROR, "cnnot find current desktop"); return -1; @@ -4164,7 +4232,7 @@ handle_first_window(client_t *client, desktop_t *d) d->tree->rectangle = r; d->n_count += 1; set_focus(d->tree, true); - d->node = d->tree; + /*d->node = d->tree;*/ ewmh_update_client_list(); return tile(d->tree); } @@ -4177,12 +4245,17 @@ handle_subsequent_window(client_t *client, desktop_t *d) _LOG_(DEBUG, "handling tiled window %s id %d", name, client->window); _FREE_(name); #endif - node_t *n = NULL; + xcb_window_t wi = get_window_under_cursor(wm->connection, wm->root_window); + node_t *n = NULL; - n = curr_monitor->desk->node; - if (n == NULL || n->client == NULL) { - _LOG_(ERROR, "cannot find focused node"); - return 0; + if (wm->bar && wi == wm->bar->window) { + n = find_any_leaf(d->tree); + } else { + n = get_focused_node(d->tree); + if (n == NULL || n->client == NULL) { + _LOG_(ERROR, "cannot find focused node"); + return 0; + } } if (IS_FLOATING(n->client) && !IS_ROOT(n)) { @@ -4218,7 +4291,7 @@ handle_subsequent_window(client_t *client, desktop_t *d) if (d->layout == STACK) { set_focus(new_node, true); } - curr_monitor->desk->node = new_node; + /*curr_monitor->desk->node = new_node;*/ ewmh_update_client_list(); return render_tree(d->tree); } @@ -4249,7 +4322,13 @@ handle_floating_window(client_t *client, desktop_t *d) set_focus(d->tree, true); return tile(d->tree); } else { - node_t *n = curr_monitor->desk->node; + xcb_window_t wi = + get_window_under_cursor(wm->connection, wm->root_window); + if (wi == wm->root_window || wi == 0) { + _FREE_(client); + return 0; + } + node_t *n = find_node_by_window_id(d->tree, wi); n = n == NULL ? find_any_leaf(d->tree) : n; if (n == NULL || n->client == NULL) { _FREE_(client); @@ -4599,7 +4678,7 @@ handle_enter_notify(const xcb_event_t *event) focused_win = n->client->window; update_focus(root, n); - curr_monitor->desk->node = n; + /*curr_monitor->desk->node = n;*/ if (has_floating_window(root)) { restack(); @@ -5231,7 +5310,7 @@ handle_button_press_event(const xcb_event_t *event) focused_win = n->client->window; update_focus(root, n); - curr_monitor->desk->node = n; + /*curr_monitor->desk->node = n;*/ if (has_floating_window(root)) { restack(); diff --git a/src/zwm.h b/src/zwm.h index 5173848..ae66490 100644 --- a/src/zwm.h +++ b/src/zwm.h @@ -60,7 +60,7 @@ int cycle_win_wrapper(arg_t *arg); int set_fullscreen_wrapper(); int flip_node_wrapper(); int reload_config_wrapper(); -int get_focused_desktop_idx__(); /* deprecated */ +int get_focused_desktop_idx(); int switch_desktop_wrapper(arg_t *arg); int transfer_node_wrapper(arg_t *arg); int horizontal_resize_wrapper(arg_t *arg); From 96705bda7ecc0bd3f8e07913fb040ce060aeca23 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Wed, 25 Dec 2024 01:11:31 -0500 Subject: [PATCH 08/12] remove redundant calls & add some useless docs --- src/tree.c | 4 +- src/zwm.c | 427 +++++++++++++++++++++++++---------------------------- 2 files changed, 200 insertions(+), 231 deletions(-) diff --git a/src/tree.c b/src/tree.c index f80d55d..195878c 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1119,7 +1119,7 @@ apply_layout(desktop_t *d, layout_t t) } case MASTER: { xcb_window_t win = - get_window_under_cursor(wm->connection, wm->root_window); + get_window_under_cursor(wm->connection, wm->root_window); if (win == XCB_NONE || win == wm->root_window) { return; } @@ -1132,7 +1132,7 @@ apply_layout(desktop_t *d, layout_t t) } case STACK: { xcb_window_t win = - get_window_under_cursor(wm->connection, wm->root_window); + get_window_under_cursor(wm->connection, wm->root_window); if (win == XCB_NONE || win == wm->root_window) { return; diff --git a/src/zwm.c b/src/zwm.c index 31a7a6d..d8513c0 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -90,18 +90,18 @@ #define WM_INSTANCE_NAME "null" wm_t *wm = NULL; -config_t conf = {0}; -xcb_window_t focused_win = XCB_NONE; -xcb_window_t meta_window = XCB_NONE; -bool is_kgrabbed = false; monitor_t *prim_monitor = NULL; monitor_t *curr_monitor = NULL; monitor_t *head_monitor = NULL; +xcb_cursor_context_t *cursor_ctx = NULL; +xcb_window_t focused_win = XCB_NONE; +xcb_window_t meta_window = XCB_NONE; +bool is_kgrabbed = false; bool using_xrandr = false; bool multi_monitors = false; bool using_xinerama = false; +config_t conf = {0}; uint8_t randr_base = 0; -xcb_cursor_context_t *cursor_ctx; xcb_cursor_t cursors[CURSOR_MAX]; /* clang-format off */ @@ -115,51 +115,51 @@ static const _key__t _keys_[] = { DEFINE_KEY(SUPER, XK_Return, exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"alacritty"}})), DEFINE_KEY(SUPER, XK_space, exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"dmenu_run"}})), DEFINE_KEY(SUPER, XK_p, exec_process, &((arg_t){.argc = 3, .cmd = (char *[]){"rofi", "-show", "drun"}})), - DEFINE_KEY(SUPER, XK_1, switch_desktop_wrapper, &((arg_t){.idx = 0})), - DEFINE_KEY(SUPER, XK_2, switch_desktop_wrapper, &((arg_t){.idx = 1})), - DEFINE_KEY(SUPER, XK_3, switch_desktop_wrapper, &((arg_t){.idx = 2})), - DEFINE_KEY(SUPER, XK_4, switch_desktop_wrapper, &((arg_t){.idx = 3})), - DEFINE_KEY(SUPER, XK_5, switch_desktop_wrapper, &((arg_t){.idx = 4})), - DEFINE_KEY(SUPER, XK_6, switch_desktop_wrapper, &((arg_t){.idx = 5})), - DEFINE_KEY(SUPER, XK_7, switch_desktop_wrapper, &((arg_t){.idx = 6})), - DEFINE_KEY(SUPER, XK_Left, cycle_win_wrapper, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER, XK_Right, cycle_win_wrapper, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER, XK_Up, cycle_win_wrapper, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER, XK_Down, cycle_win_wrapper, &((arg_t){.d = DOWN})), - DEFINE_KEY(SUPER, XK_l, horizontal_resize_wrapper, &((arg_t){.r = GROW})), - DEFINE_KEY(SUPER, XK_h, horizontal_resize_wrapper, &((arg_t){.r = SHRINK})), + DEFINE_KEY(SUPER, XK_1, switch_desktop_wrapper, &((arg_t){.idx = 0})), + DEFINE_KEY(SUPER, XK_2, switch_desktop_wrapper, &((arg_t){.idx = 1})), + DEFINE_KEY(SUPER, XK_3, switch_desktop_wrapper, &((arg_t){.idx = 2})), + DEFINE_KEY(SUPER, XK_4, switch_desktop_wrapper, &((arg_t){.idx = 3})), + DEFINE_KEY(SUPER, XK_5, switch_desktop_wrapper, &((arg_t){.idx = 4})), + DEFINE_KEY(SUPER, XK_6, switch_desktop_wrapper, &((arg_t){.idx = 5})), + DEFINE_KEY(SUPER, XK_7, switch_desktop_wrapper, &((arg_t){.idx = 6})), + DEFINE_KEY(SUPER, XK_Left, cycle_win_wrapper, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER, XK_Right, cycle_win_wrapper, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER, XK_Up, cycle_win_wrapper, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER, XK_Down, cycle_win_wrapper, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER, XK_l, horizontal_resize_wrapper, &((arg_t){.r = GROW})), + DEFINE_KEY(SUPER, XK_h, horizontal_resize_wrapper, &((arg_t){.r = SHRINK})), DEFINE_KEY(SUPER, XK_f, set_fullscreen_wrapper, NULL), DEFINE_KEY(SUPER, XK_s, swap_node_wrapper, NULL), - DEFINE_KEY(SUPER, XK_i, gap_handler, &((arg_t){.r = GROW})), - DEFINE_KEY(SUPER, XK_d, gap_handler, &((arg_t){.r = SHRINK})), - DEFINE_KEY(SUPER | SHIFT, XK_Left, shift_floating_window, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER | SHIFT, XK_Right, shift_floating_window, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER | SHIFT, XK_Up, shift_floating_window, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER | SHIFT, XK_Down, shift_floating_window, &((arg_t){.d = DOWN})), - DEFINE_KEY(SUPER | ALT, XK_f, change_state, &((arg_t){.s = FLOATING})), - DEFINE_KEY(SUPER | ALT, XK_t, change_state, &((arg_t){.s = TILED})), - DEFINE_KEY(SUPER | SHIFT, XK_1, transfer_node_wrapper, &((arg_t){.idx = 0})), - DEFINE_KEY(SUPER | SHIFT, XK_2, transfer_node_wrapper, &((arg_t){.idx = 1})), - DEFINE_KEY(SUPER | SHIFT, XK_3, transfer_node_wrapper, &((arg_t){.idx = 2})), - DEFINE_KEY(SUPER | SHIFT, XK_4, transfer_node_wrapper, &((arg_t){.idx = 3})), - DEFINE_KEY(SUPER | SHIFT, XK_5, transfer_node_wrapper, &((arg_t){.idx = 4})), - DEFINE_KEY(SUPER | SHIFT, XK_6, transfer_node_wrapper, &((arg_t){.idx = 5})), - DEFINE_KEY(SUPER | SHIFT, XK_7, transfer_node_wrapper, &((arg_t){.idx = 6})), - DEFINE_KEY(SUPER | SHIFT, XK_m, layout_handler, &((arg_t){.t = MASTER})), - DEFINE_KEY(SUPER | SHIFT, XK_d, layout_handler, &((arg_t){.t = DEFAULT})), - DEFINE_KEY(SUPER | SHIFT, XK_s, layout_handler, &((arg_t){.t = STACK})), - DEFINE_KEY(SUPER | SHIFT, XK_k, traverse_stack_wrapper, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER | SHIFT, XK_j, traverse_stack_wrapper, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER, XK_i, gap_handler, &((arg_t){.r = GROW})), + DEFINE_KEY(SUPER, XK_d, gap_handler, &((arg_t){.r = SHRINK})), + DEFINE_KEY(SUPER | SHIFT, XK_Left, shift_floating_window, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER | SHIFT, XK_Right, shift_floating_window, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER | SHIFT, XK_Up, shift_floating_window, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER | SHIFT, XK_Down, shift_floating_window, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER | ALT, XK_f, change_state, &((arg_t){.s = FLOATING})), + DEFINE_KEY(SUPER | ALT, XK_t, change_state, &((arg_t){.s = TILED})), + DEFINE_KEY(SUPER | SHIFT, XK_1, transfer_node_wrapper, &((arg_t){.idx = 0})), + DEFINE_KEY(SUPER | SHIFT, XK_2, transfer_node_wrapper, &((arg_t){.idx = 1})), + DEFINE_KEY(SUPER | SHIFT, XK_3, transfer_node_wrapper, &((arg_t){.idx = 2})), + DEFINE_KEY(SUPER | SHIFT, XK_4, transfer_node_wrapper, &((arg_t){.idx = 3})), + DEFINE_KEY(SUPER | SHIFT, XK_5, transfer_node_wrapper, &((arg_t){.idx = 4})), + DEFINE_KEY(SUPER | SHIFT, XK_6, transfer_node_wrapper, &((arg_t){.idx = 5})), + DEFINE_KEY(SUPER | SHIFT, XK_7, transfer_node_wrapper, &((arg_t){.idx = 6})), + DEFINE_KEY(SUPER | SHIFT, XK_m, layout_handler, &((arg_t){.t = MASTER})), + DEFINE_KEY(SUPER | SHIFT, XK_d, layout_handler, &((arg_t){.t = DEFAULT})), + DEFINE_KEY(SUPER | SHIFT, XK_s, layout_handler, &((arg_t){.t = STACK})), + DEFINE_KEY(SUPER | SHIFT, XK_k, traverse_stack_wrapper, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER | SHIFT, XK_j, traverse_stack_wrapper, &((arg_t){.d = DOWN})), DEFINE_KEY(SUPER | SHIFT, XK_f, flip_node_wrapper, NULL), DEFINE_KEY(SUPER | SHIFT, XK_r, reload_config_wrapper, NULL), - DEFINE_KEY(SUPER | SHIFT, XK_Left, cycle_desktop_wrapper, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER | SHIFT, XK_Right, cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER | SHIFT, XK_y, grow_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_h, grow_floating_window, &((arg_t){.rd = VERTICAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_t, shrink_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_g, shrink_floating_window, &((arg_t){.rd = VERTICAL_DIR})), - DEFINE_KEY(SUPER | CTRL, XK_Right, cycle_monitors, &((arg_t){.tr = NEXT})), - DEFINE_KEY(SUPER | CTRL, XK_Left, cycle_monitors, &((arg_t){.tr = PREV})), + DEFINE_KEY(SUPER | SHIFT, XK_Left, cycle_desktop_wrapper, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER | SHIFT, XK_Right, cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER | SHIFT, XK_y, grow_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, XK_h, grow_floating_window, &((arg_t){.rd = VERTICAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, XK_t, shrink_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, XK_g, shrink_floating_window, &((arg_t){.rd = VERTICAL_DIR})), + DEFINE_KEY(SUPER | CTRL, XK_Right, cycle_monitors, &((arg_t){.tr = NEXT})), + DEFINE_KEY(SUPER | CTRL, XK_Left, cycle_monitors, &((arg_t){.tr = PREV})), }; static const uint32_t _buttons_[] = { @@ -246,7 +246,7 @@ static const event_handler_entry_t _handlers_[] = { * keybinds take action */ DEFINE_MAPPING(XCB_KEY_PRESS, handle_key_press), /* mapping notify - is generated when keyboard mapping is changed, - * it only ungrab the re-grab the keys */ + * it only ungrab the re-grab the keys */ DEFINE_MAPPING(XCB_MAPPING_NOTIFY, handle_mapping_notify), /* will be implemented if needed */ /* DEFINE_MAPPING(XCB_MOTION_NOTIFY, handle_motion_notify),*/ @@ -330,6 +330,8 @@ int layout_handler(arg_t *arg) { desktop_t *d = curr_monitor->desk; + /* if stack layout is requested on a dekstop with 1 window, ignore the + * request */ if (arg->t == STACK && d->n_count < 2) return 0; @@ -337,13 +339,14 @@ layout_handler(arg_t *arg) return render_tree(d->tree); } +/* useles after + * https://github.com/yazeed1s/zwm/pull/36 */ static node_t * -get_foucsed_desktop_tree(void) +get_foucsed_desktop_tree__(void) { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return NULL; - + int i = get_focused_desktop_idx(); + assert(i >= 0 && i < conf.virtual_desktops); + node_t *root = curr_monitor->desktops[i]->tree; return root; } @@ -375,11 +378,7 @@ change_state(arg_t *arg) if (w == XCB_NONE) return -1; - node_t *root = get_foucsed_desktop_tree(); - if (root == NULL) - return -1; - - node_t *n = find_node_by_window_id(root, w); + node_t *n = find_node_by_window_id(curr_monitor->desk->tree, w); if (n == NULL) return -1; @@ -466,7 +465,7 @@ change_state(arg_t *arg) } } - return render_tree(root); + return render_tree(curr_monitor->desk->tree); } static xcb_ewmh_conn_t * @@ -500,6 +499,9 @@ ewmh_init(xcb_conn_t *conn) static int ewmh_set_supporting(xcb_window_t win, xcb_ewmh_conn_t *ewmh) { + /* when a user runs xprop -root, some of the info in the output are coming + * from this func, like the pid, supported hints, and name. Other info like + * desktop names and numbers are set in other fucntions. */ pid_t wm_pid = getpid(); xcb_cookie_t supporting_cookie_root = xcb_ewmh_set_supporting_wm_check_checked(ewmh, wm->root_window, win); @@ -522,12 +524,12 @@ ewmh_set_supporting(xcb_window_t win, xcb_ewmh_conn_t *ewmh) return -1; } if ((err = xcb_request_check(ewmh->connection, name_cookie))) { - fprintf(stderr, "Error setting WM name: %d", err->error_code); + _LOG_(ERROR, "Error setting WM name: %d", err->error_code); _FREE_(err); return -1; } if ((err = xcb_request_check(ewmh->connection, pid_cookie))) { - fprintf(stderr, "Error setting WM PID: %d", err->error_code); + _LOG_(ERROR, "Error setting WM PID: %d", err->error_code); _FREE_(err); return -1; } @@ -589,9 +591,9 @@ ewmh_update_desktop_names(void) memset(names, 0, sizeof(names)); for (int n = 0; n < prim_monitor->n_of_desktops; n++) { - desktop_t *d = prim_monitor->desktops[n]; - for (int j = 0; d->name[j] != '\0' && (offset + j) < sizeof(names); - j++) { + desktop_t *d = prim_monitor->desktops[n]; + size_t nn = sizeof(names); + for (int j = 0; d->name[j] != '\0' && (offset + j) < nn; j++) { names[offset + j] = d->name[j]; } offset += strlen(d->name); @@ -780,23 +782,19 @@ swap_node_wrapper() return -1; } - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); if (w == wm->root_window) { return 0; } - node_t *n = get_focused_node(root); - if (n == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; if (swap_node(n) != 0) return -1; - return render_tree(root); + return render_tree(curr_monitor->desk->tree); } /* transfer_node_wrapper - handles transferring a node between desktops. @@ -821,14 +819,12 @@ transfer_node_wrapper(arg_t *arg) return 0; } - node_t *root = curr_monitor->desk->tree; - if (is_tree_empty(root)) { + if (is_tree_empty(curr_monitor->desk->tree)) { return 0; } - node_t *node = get_focused_node(root); - - if (!node) { + node_t *node = NULL; + if (!(node = get_focused_node(curr_monitor->desk->tree))) { _LOG_(ERROR, "focused node is null"); return 0; } @@ -875,21 +871,17 @@ horizontal_resize_wrapper(arg_t *arg) return 0; } - node_t *root = curr_monitor->desk->tree; - if (root == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; - node_t *n = get_focused_node(root); - - if (n == NULL) - return -1; /* todo: if node was flipped, reize up or down instead */ grab_pointer(wm->root_window, false); /* steal the pointer and prevent it from sending * enter_notify events (which focuses the window * being under cursor as the resize happens); */ horizontal_resize(n, arg->r); - render_tree(root); + render_tree(curr_monitor->desk->tree); ungrab_pointer(); return 0; } @@ -897,12 +889,8 @@ horizontal_resize_wrapper(arg_t *arg) int grow_floating_window(arg_t *arg) { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); - if (n == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; if (n->client && n->client->state != FLOATING) @@ -941,12 +929,8 @@ grow_floating_window(arg_t *arg) int shrink_floating_window(arg_t *arg) { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); - if (n == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; if (n->client && n->client->state != FLOATING) @@ -980,12 +964,8 @@ shrink_floating_window(arg_t *arg) int resize_floating_window(arg_t *arg) { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); - if (n == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; if (n->client && n->client->state != FLOATING) @@ -1020,12 +1000,8 @@ resize_floating_window(arg_t *arg) int shift_floating_window(arg_t *arg) { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - - node_t *n = get_focused_node(root); - if (n == NULL) + node_t *n = NULL; + if (!(n = get_focused_node(curr_monitor->desk->tree))) return -1; if (n->client && n->client->state != FLOATING) @@ -1073,16 +1049,12 @@ shift_floating_window(arg_t *arg) int set_fullscreen_wrapper() { - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return -1; - xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); if (w == wm->root_window) { return 0; } - node_t *n = find_node_by_window_id(root, w); + node_t *n = find_node_by_window_id(curr_monitor->desk->tree, w); if (n == NULL) { _LOG_(ERROR, "cannot find focused node"); return -1; @@ -1156,13 +1128,16 @@ set_fullscreen(node_t *n, bool flag) xcb_flush(wm->connection); return 0; } - +/* change_colors is called when a user changes the border color in the config + * file */ static int change_colors(node_t *root) { if (root == NULL) return 0; - + /* win_foucs internally changes the border color of a window, if the focus + * param is set to true it applies the active_border_color, otherwise the + * normal_border_color is chosen */ if (root->node_type != INTERNAL_NODE && root->client) { if (win_focus(root->client->window, root->is_focused) != 0) { _LOG_(ERROR, "cannot focus node"); @@ -1177,100 +1152,69 @@ change_colors(node_t *root) return 0; } +static rectangle_t +calculate_monitor_area(const monitor_t *m, + uint16_t w, + uint16_t h, + uint16_t bar_height) +{ + return (rectangle_t){ + .x = (int16_t)(m->rectangle.x + conf.window_gap), + .y = (int16_t)(m->rectangle.y + bar_height + conf.window_gap), + .width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width), + .height = (uint16_t)(h - bar_height - 2 * conf.window_gap - + 2 * conf.border_width)}; +} -/* TODO: rewrite this */ static void apply_monitor_layout_changes(monitor_t *m) { for (int d = 0; d < m->n_of_desktops; ++d) { - if (!m->desktops[d]) - continue; - if (is_tree_empty(m->desktops[d]->tree)) + if (!m->desktops[d] || is_tree_empty(m->desktops[d]->tree)) continue; - layout_t l = m->desktops[d]->layout; - node_t *tree = m->desktops[d]->tree; - if (l == DEFAULT) { - rectangle_t r = {0}; - uint16_t w = m->rectangle.width; - uint16_t h = m->rectangle.height; - int16_t x = m->rectangle.x; - int16_t y = m->rectangle.y; - if (wm->bar && m == prim_monitor) { - r.x = (int16_t)(x + conf.window_gap); - r.y = - (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); - r.width = - (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = - (uint16_t)(h - wm->bar->rectangle.height - - 2 * conf.window_gap - 2 * conf.border_width); - } else { - r.x = x + conf.window_gap; - r.y = y + conf.window_gap; - r.width = w - 2 * conf.window_gap - 2 * conf.border_width; - r.height = h - 2 * conf.window_gap - 2 * conf.border_width; - } - tree->rectangle = r; - apply_default_layout(tree); - } else if (l == MASTER) { - node_t *ms = find_master_node(tree); + + layout_t layout = m->desktops[d]->layout; + node_t *tree = m->desktops[d]->tree; + uint16_t w = m->rectangle.width; + uint16_t h = m->rectangle.height; + uint16_t bar_height = + (wm->bar && m == prim_monitor) ? wm->bar->rectangle.height : 0; + + if (layout == DEFAULT || layout == STACK) { + tree->rectangle = calculate_monitor_area(m, w, h, bar_height); + + if (layout == DEFAULT) + apply_default_layout(tree); + else + apply_stack_layout(tree); + + } else if (layout == MASTER) { + node_t *ms = find_master_node(tree); + if (!ms && !(ms = find_any_leaf(tree))) + return; + + ms->is_master = true; const double ratio = 0.70; - uint16_t w = m->rectangle.width; - uint16_t h = m->rectangle.height; - int16_t x = m->rectangle.x; - int16_t y = m->rectangle.y; uint16_t master_width = (uint16_t)(w * ratio); uint16_t r_width = (uint16_t)(w * (1 - ratio)); - if (ms == NULL) { - ms = find_any_leaf(tree); - if (ms == NULL) { - return; - } - } - ms->is_master = true; - uint16_t bar_height = - wm->bar == NULL ? 0 : wm->bar->rectangle.height; - const rectangle_t r1 = { - .x = (int16_t)(x + conf.window_gap), - .y = (int16_t)(y + bar_height + conf.window_gap), - .width = (uint16_t)(master_width - 2 * conf.window_gap), - .height = (uint16_t)(h - 2 * conf.window_gap - bar_height), - }; - const rectangle_t r2 = { - .x = (int16_t)(x + master_width), - .y = (int16_t)(y + bar_height + conf.window_gap), - .width = (uint16_t)(r_width - (1 * conf.window_gap)), + + rectangle_t r1 = { + .x = (int16_t)(m->rectangle.x + conf.window_gap), + .y = (int16_t)(m->rectangle.y + bar_height + conf.window_gap), + .width = (uint16_t)(master_width - 2 * conf.window_gap), + .height = (uint16_t)(h - 2 * conf.window_gap - bar_height), + }; + rectangle_t r2 = { + .x = (int16_t)(m->rectangle.x + master_width), + .y = (int16_t)(m->rectangle.y + bar_height + conf.window_gap), + .width = (uint16_t)(r_width - conf.window_gap), .height = (uint16_t)(h - 2 * conf.window_gap - bar_height), }; ms->rectangle = r1; tree->rectangle = r2; apply_master_layout(tree); - } else if (l == STACK) { - rectangle_t r = {0}; - uint16_t w = m->rectangle.width; - uint16_t h = m->rectangle.height; - int16_t x = m->rectangle.x; - int16_t y = m->rectangle.y; - if (wm->bar && m == prim_monitor) { - r.x = (int16_t)(x + conf.window_gap); - r.y = - (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); - r.width = - (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = - (uint16_t)(h - wm->bar->rectangle.height - - 2 * conf.window_gap - 2 * conf.border_width); - } else { - r.x = x + conf.window_gap; - r.y = y + conf.window_gap; - r.width = - (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = - (uint16_t)(h - 2 * conf.window_gap - 2 * conf.border_width); - } - tree->rectangle = r; - apply_stack_layout(tree); - } else if (l == GRID) { + + } else if (layout == GRID) { // todo } } @@ -1286,15 +1230,22 @@ arrange_trees(void) } } +/* reload_config_wrapper is called when a user changes the config file and wants + * to apply the changes to the wm. The config file contains many values and + * rules, so the easiest way (lazy way) to handle this is to zero out the config + * struct along with the rules and keys lists, and populate them again from the + * config file */ int reload_config_wrapper() { + /* store the old config values so i can compare them later with the new + * values to determine what needs to be done */ uint16_t prev_border_width = conf.border_width; uint16_t prev_window_gap = conf.window_gap; uint32_t prev_active_border_color = conf.active_border_color; uint32_t prev_normal_border_color = conf.normal_border_color; int prev_virtual_desktops = conf.virtual_desktops; - + /* clear the config data structures */ memset(&conf, 0, sizeof(config_t)); ungrab_keys(wm->connection, wm->root_window); @@ -1468,11 +1419,8 @@ int flip_node_wrapper() { node_t *tree = curr_monitor->desk->tree; - if (!tree) - return -1; - - node_t *node = get_focused_node(tree); - if (node == NULL) + node_t *node = NULL; + if (!(node = get_focused_node(tree))) return -1; flip_node(node); @@ -1482,17 +1430,13 @@ flip_node_wrapper() int cycle_win_wrapper(arg_t *arg) { - direction_t d = arg->d; - node_t *root = curr_monitor->desk->tree; - if (!root) { - return 0; - } - node_t *f = get_focused_node(root); - if (!f) { + direction_t d = arg->d; + node_t *f = NULL; + if (!(f = get_focused_node(curr_monitor->desk->tree))) { _LOG_(INFO, "cannot find focused window"); xcb_window_t w = get_window_under_cursor(wm->connection, wm->root_window); - f = find_node_by_window_id(root, w); + f = find_node_by_window_id(curr_monitor->desk->tree, w); } node_t *next = cycle_win(f, d); if (next == NULL) { @@ -1505,7 +1449,7 @@ cycle_win_wrapper(arg_t *arg) #endif set_focus(next, true); set_active_window_name(next->client->window); - update_focus(root, next); + update_focus(curr_monitor->desk->tree, next); /*curr_monitor->desk->node = next;*/ return 0; } @@ -1601,12 +1545,11 @@ traverse_stack_wrapper(arg_t *arg) if (w == wm->root_window) return 0; - node_t *root = curr_monitor->desk->tree; - if (!root) + node_t *node = NULL; + if (!(node = get_focused_node(curr_monitor->desk->tree))) return -1; - node_t *node = get_focused_node(root); - node_t *n = d == UP ? next_node(node) : prev_node(node); + node_t *n = d == UP ? next_node(node) : prev_node(node); if (n == NULL) { return -1; @@ -1614,7 +1557,7 @@ traverse_stack_wrapper(arg_t *arg) set_focus(n, true); /*curr_monitor->desk->node = n;*/ - if (has_floating_window(root)) + if (has_floating_window(curr_monitor->desk->tree)) restack(); return 0; @@ -2001,7 +1944,7 @@ get_connected_monitor_count_xrandr() xcb_randr_get_screen_resources_current_reply_t *sres = xcb_randr_get_screen_resources_current_reply(wm->connection, c, NULL); if (sres == NULL) { - fprintf(stderr, "Failed to get screen resources"); + _LOG_(ERROR, "Failed to get screen resources"); return -1; } int len = xcb_randr_get_screen_resources_current_outputs_length(sres); @@ -2479,7 +2422,7 @@ destroy_monitor(monitor_t *m) _LOG_(ERROR, "attempted to destroy a NULL monitor."); return; } - + /* unlink the monitor first */ _LOG_(INFO, "removing m from linked list"); unlink_monitor(&head_monitor, m); assert(!get_monitor_by_randr_id(m->randr_id)); @@ -2687,7 +2630,9 @@ update_monitors(uint32_t *changes) _LOG_(ERROR, "failed to merge desktops from %s", r->name); continue; } - /* destroy the disconnected monitor */ + /* destroy the disconnected monitor, this unlinks the monitor from + * the list, frees its desktops and trees, and then free the monitor + * itslef */ destroy_monitor(r); } *changes &= ~_NONE; @@ -2707,7 +2652,7 @@ handle_monitor_changes(void) * list and assign desktops to it. * 2- an exisitng monitor was * disconnected, we need to merge its desktops with the primary monitor - * then remove it and free its desktops. + * then remove it and free its desktops and trees. * 3- a resolution or oreintation was changed for an existing * monitor, we need to recaluclate the rectangle for it and resize its * trees @@ -2789,11 +2734,16 @@ get_monitor_from_desktop(desktop_t *desktop) return NULL; } +/* set_desktop is called when 1- zwm starts and monitors were intially set up + * and need to have desktops assigned to them. 2- when xrandr forces monitor + * changes */ static bool setup_desktops(void) { monitor_t *curr = head_monitor; while (curr) { + /* becaues this function is also called when monitors change, we need + * to skip old monitors in the list. */ if (curr && curr->desktops) { _LOG_(INFO, "monitor %s already has desktops... skipping", @@ -3155,6 +3105,8 @@ set_input_focus(xcb_conn_t *conn, return 0; } +/* tile - maps the window to its correct postion and sets its width and height + */ int tile(node_t *node) { @@ -3566,6 +3518,10 @@ ungrab_keys(xcb_conn_t *conn, xcb_window_t win) } } +/* map_floating - is called on windows that I do not wanna insert into the tree, + * like notification windows and many other short-lived windows. Not to confuse + * this with handle_floating_window, that function inserts floating windows into + * the tree */ static void map_floating(xcb_window_t x) { @@ -3586,6 +3542,10 @@ map_floating(xcb_window_t x) xcb_map_window(wm->connection, x); } +/* find_window_in_desktops - is used to find where a given window is located in + * monitors<->desktops. It assigns the reaults to the out parameters + * **curr_desktop + * **curr_node */ static void find_window_in_desktops(desktop_t **curr_desktop, node_t **curr_node, @@ -4563,6 +4523,10 @@ handle_map_request(const xcb_event_t *event) if ((apply_floating_hints(win) != -1 && wint != WINDOW_TYPE_DOCK)) { return handle_floating_window_request(win, curr_monitor->desk); } + + /* notification windows are short-lived, they dont deserve entering the + * tree. Thus, we just map them as is, and they go away on their own shortly + * after */ if (wint == WINDOW_TYPE_NOTIFICATION) { map_floating(win); return 0; @@ -4598,11 +4562,17 @@ handle_enter_notify(const xcb_event_t *event) _LOG_(DEBUG, "recieved enter notify for %d, name %s ", win, name); _FREE_(name); #endif + /* ignore events with 1- non-normal modes. Those are because a grab + * activated/deactivated. 2- events with detail "inferior". This detail + * means that the cursor was previously inside of a child window and now + * left that child window, it happens with broswer menues, code edeitor + * completion menues etc */ if (ev->mode != XCB_NOTIFY_MODE_NORMAL || ev->detail == XCB_NOTIFY_DETAIL_INFERIOR) { return 0; } + /* if the cursor enters a status bar window, ignore the event */ if (wm->bar && win == wm->bar->window) { return 0; } @@ -5076,17 +5046,14 @@ handle_unmap_notify(const xcb_event_t *event) _LOG_(DEBUG, "recieved unmap notify for %d, name %s ", win, s); _FREE_(s); #endif - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return 0; - if (wm->bar && wm->bar->window == win) { hide_bar(win); - render_tree(root); + render_tree(curr_monitor->desk->tree); return 0; } - if (!client_exist(root, win) && !client_exist_in_desktops(win)) { + if (!client_exist(curr_monitor->desk->tree, win) && + !client_exist_in_desktops(win)) { #ifdef _DEBUG__ char *name = win_name(win); _LOG_(DEBUG, "cannot find win %d, name %s", win, name); @@ -5195,17 +5162,14 @@ handle_destroy_notify(const xcb_event_t *event) _FREE_(s); #endif - node_t *root = curr_monitor->desk->tree; - if (root == NULL) - return 0; - if (wm->bar && wm->bar->window == win) { hide_bar(win); - render_tree(root); + render_tree(curr_monitor->desk->tree); return 0; } - if (!client_exist(root, win) && !client_exist_in_desktops(win)) { + if (!client_exist(curr_monitor->desk->tree, win) && + !client_exist_in_desktops(win)) { #ifdef _DEBUG__ char *name = win_name(win); _LOG_(DEBUG, "cannot find win %d, name %s", win, name); @@ -5444,11 +5408,15 @@ xcb_event_to_string(uint8_t type) } } +/* handle_event - receives x events and handle them as it should. + * Since the wm is an x client itself, and is subscribed to substructure redirections, + * the x server will redirect any event it recevies to the wm */ static int handle_event(xcb_event_t *event) { uint8_t event_type = event->response_type & ~0x80; + /* xinerima is ignored here */ if (using_xrandr && event_type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { _LOG_(INFO, "monitor update was requested"); @@ -5466,6 +5434,7 @@ handle_event(xcb_event_t *event) return 0; } +/* event_loop - the main loop that listens to redirected x events */ static void event_loop(wm_t *w) { From 8869f843124d03fe5b1b72fa57692658755791d3 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Wed, 25 Dec 2024 23:49:15 -0500 Subject: [PATCH 09/12] add rectangle helper functions --- src/tree.c | 195 +++++++++++++++++++++-------------------------------- src/zwm.c | 5 +- 2 files changed, 78 insertions(+), 122 deletions(-) diff --git a/src/tree.c b/src/tree.c index 195878c..b5d419b 100644 --- a/src/tree.c +++ b/src/tree.c @@ -189,54 +189,64 @@ insert_floating_node(node_t *node, desktop_t *d) } node->node_type = EXTERNAL_NODE; } +static void +split_rect(node_t *n, split_type_t s) +{ + const int16_t gap = conf.window_gap - conf.border_width; + const int16_t half_width = (n->rectangle.width - gap) / 2; + const int16_t half_height = (n->rectangle.height - gap) / 2; + node_t *n1 = n->first_child; + node_t *n2 = n->second_child; + rectangle_t *fr = &n1->rectangle; + rectangle_t *sr = &n2->rectangle; + if (s == HORIZONTAL_TYPE) { + fr->x = n->rectangle.x; + fr->y = n->rectangle.y; + fr->width = half_width; + fr->height = n->rectangle.height; + if (!IS_FLOATING(n1->client)) { + sr->x = n->rectangle.x + fr->width + conf.window_gap + + conf.border_width; + sr->y = n->rectangle.y; + sr->width = n->rectangle.width - fr->width - conf.window_gap - + conf.border_width; + sr->height = n->rectangle.height; + } else { + *sr = n->rectangle; + } + } else { + fr->x = n->rectangle.x; + fr->y = n->rectangle.y; + fr->width = n->rectangle.width; + fr->height = half_height; + if (!IS_FLOATING(n2->client)) { + sr->x = n->rectangle.x; + sr->y = n->rectangle.y + fr->height + conf.window_gap + + conf.border_width; + sr->width = n->rectangle.width; + sr->height = n->rectangle.height - fr->height - conf.window_gap - + conf.border_width; + } else { + *sr = n->rectangle; + } + } +} -/* split_node - splits a node's rectangle in half, the split could be vertical - * or horizontal depending on (width > height)? */ +/* split_node - splits a node's rectangle in half, the split could be + * vertical or horizontal depending on (width > height)? */ static void split_node(node_t *n, node_t *nd) { - rectangle_t *first_rect = &n->first_child->rectangle; - rectangle_t *second_rect = &n->second_child->rectangle; if (IS_FLOATING(nd->client)) { - *first_rect = n->floating_rectangle = n->rectangle; + n->first_child->rectangle = n->floating_rectangle = n->rectangle; return; } if (n->rectangle.width >= n->rectangle.height) { /* horizontal split */ - const int16_t gap = conf.window_gap - conf.border_width; - const int16_t half_width = (n->rectangle.width - gap) / 2; - first_rect->x = n->rectangle.x; - first_rect->y = n->rectangle.y; - first_rect->width = half_width; - first_rect->height = n->rectangle.height; - if (!IS_FLOATING(n->first_child->client)) { - second_rect->x = n->rectangle.x + first_rect->width + - conf.window_gap + conf.border_width; - second_rect->y = n->rectangle.y; - second_rect->width = n->rectangle.width - first_rect->width - - conf.window_gap - conf.border_width; - second_rect->height = n->rectangle.height; - } else { - *second_rect = n->rectangle; - } + split_rect(n, HORIZONTAL_TYPE); } else { /* verticall split */ - const int16_t gap = conf.window_gap - conf.border_width; - const int16_t half_height = (n->rectangle.height - gap) / 2; - first_rect->x = n->rectangle.x; - first_rect->y = n->rectangle.y; - first_rect->width = n->rectangle.width; - first_rect->height = half_height; - if (!IS_FLOATING(n->first_child->client)) { - second_rect->x = n->rectangle.x; - second_rect->y = n->rectangle.y + first_rect->height + - conf.window_gap + conf.border_width; - second_rect->width = n->rectangle.width; - second_rect->height = n->rectangle.height - first_rect->height - - conf.window_gap - conf.border_width; - } else { - *second_rect = n->rectangle; - } + split_rect(n, VERTICAL_TYPE); } } @@ -382,45 +392,18 @@ resize_subtree(node_t *parent) if (parent == NULL) return; - rectangle_t r, r2 = {0}; - if (parent->rectangle.width >= parent->rectangle.height) { - r.x = parent->rectangle.x; - r.y = parent->rectangle.y; - r.width = - (parent->rectangle.width - (conf.window_gap - conf.border_width)) / - 2; - r.height = parent->rectangle.height; - r2.x = (int16_t)(parent->rectangle.x + r.width + conf.window_gap + - conf.border_width); - r2.y = parent->rectangle.y; - r2.width = parent->rectangle.width - r.width - conf.window_gap - - conf.border_width; - r2.height = parent->rectangle.height; + split_rect(parent, HORIZONTAL_TYPE); } else { - r.x = parent->rectangle.x; - r.y = parent->rectangle.y; - r.width = parent->rectangle.width; - r.height = - (parent->rectangle.height - (conf.window_gap - conf.border_width)) / - 2; - r2.x = parent->rectangle.x; - r2.y = (int16_t)(parent->rectangle.y + r.height + conf.window_gap + - conf.border_width); - r2.width = parent->rectangle.width; - r2.height = parent->rectangle.height - r.height - conf.window_gap - - conf.border_width; + split_rect(parent, VERTICAL_TYPE); } if (parent->first_child) { - parent->first_child->rectangle = r; if (IS_INTERNAL(parent->first_child)) { resize_subtree(parent->first_child); } } - if (parent->second_child) { - parent->second_child->rectangle = r2; if (IS_INTERNAL(parent->second_child)) { resize_subtree(parent->second_child); } @@ -884,6 +867,27 @@ apply_default_layout(node_t *root) } } +static void +calculate_base_rect(rectangle_t *r, monitor_t *m) +{ + uint16_t w = m->rectangle.width; + uint16_t h = m->rectangle.height; + uint16_t x = m->rectangle.x; + uint16_t y = m->rectangle.y; + if (wm->bar && m == prim_monitor) { + r->x = (int16_t)(x + conf.window_gap); + r->y = (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); + r->width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); + r->height = (uint16_t)(h - wm->bar->rectangle.height - + 2 * conf.window_gap - 2 * conf.border_width); + } else { + r->x = (int16_t)(x + conf.window_gap); + r->y = (int16_t)(y + conf.window_gap); + r->width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); + r->height = (uint16_t)(h - 2 * conf.window_gap - 2 * conf.border_width); + } +} + /* default_layout - applies the default layout to the tree. * * initializes the default layout for the entire screen or @@ -895,24 +899,8 @@ default_layout(node_t *root) { if (root == NULL) return; - rectangle_t r = {0}; - uint16_t w = curr_monitor->rectangle.width; - uint16_t h = curr_monitor->rectangle.height; - uint16_t x = curr_monitor->rectangle.x; - uint16_t y = curr_monitor->rectangle.y; - if (wm->bar && curr_monitor == prim_monitor) { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); - r.width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = (uint16_t)(h - wm->bar->rectangle.height - - 2 * conf.window_gap - 2 * conf.border_width); - } else { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + conf.window_gap); - r.width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = (uint16_t)(h - 2 * conf.window_gap - 2 * conf.border_width); - } + calculate_base_rect(&r, curr_monitor); root->rectangle = r; apply_default_layout(root); } @@ -1077,23 +1065,8 @@ apply_stack_layout(node_t *root) static void stack_layout(node_t *root) { - rectangle_t r = {0}; - uint16_t w = curr_monitor->rectangle.width; - uint16_t h = curr_monitor->rectangle.height; - const uint16_t x = curr_monitor->rectangle.x; - const uint16_t y = curr_monitor->rectangle.y; - if (wm->bar && curr_monitor == prim_monitor) { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); - r.width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = (uint16_t)(h - wm->bar->rectangle.height - - 2 * conf.window_gap - 2 * conf.border_width); - } else { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + conf.window_gap); - r.width = (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = (uint16_t)(h - 2 * conf.window_gap - 2 * conf.border_width); - } + rectangle_t r = {0}; + calculate_base_rect(&r, curr_monitor); root->rectangle = r; apply_stack_layout(root); } @@ -1395,7 +1368,7 @@ delete_node(node_t *node, desktop_t *d) /*if (!check) { d->node = n; }*/ -out: + d->n_count -= 1; if (!is_tree_empty(d->tree)) { arrange_tree(d->tree, d->layout); @@ -1835,25 +1808,7 @@ transfer_node(node_t *node, desktop_t *d) if (is_tree_empty(d->tree)) { rectangle_t r = {0}; - uint16_t w = curr_monitor->rectangle.width; - uint16_t h = curr_monitor->rectangle.height; - uint16_t x = curr_monitor->rectangle.x; - uint16_t y = curr_monitor->rectangle.y; - if (wm->bar && curr_monitor == prim_monitor) { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + wm->bar->rectangle.height + conf.window_gap); - r.width = - (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = (uint16_t)(h - wm->bar->rectangle.height - - 2 * conf.window_gap - 2 * conf.border_width); - } else { - r.x = (int16_t)(x + conf.window_gap); - r.y = (int16_t)(y + conf.window_gap); - r.width = - (uint16_t)(w - 2 * conf.window_gap - 2 * conf.border_width); - r.height = - (uint16_t)(h - 2 * conf.window_gap - 2 * conf.border_width); - } + calculate_base_rect(&r, curr_monitor); node->node_type = ROOT_NODE; d->tree = node; d->tree->rectangle = r; diff --git a/src/zwm.c b/src/zwm.c index d8513c0..c8cac00 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -3642,6 +3642,7 @@ kill_window(xcb_window_t win) if (is_tree_empty(d->tree)) { set_active_window_name(XCB_NONE); + focused_win = XCB_NONE; } if (!another_desktop) { @@ -5409,8 +5410,8 @@ xcb_event_to_string(uint8_t type) } /* handle_event - receives x events and handle them as it should. - * Since the wm is an x client itself, and is subscribed to substructure redirections, - * the x server will redirect any event it recevies to the wm */ + * Since the wm is an x client itself, and is subscribed to substructure + * redirections, the x server will redirect any event it recevies to the wm */ static int handle_event(xcb_event_t *event) { From 2f6725dbd10a1a7524920a6836471b3280ec2a7b Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Fri, 3 Jan 2025 18:25:31 +0300 Subject: [PATCH 10/12] add key macro --- src/helper.h | 1 + src/zwm.c | 98 ++++++++++++++++++++++++++-------------------------- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/helper.h b/src/helper.h index c6c8e7c..14e16de 100644 --- a/src/helper.h +++ b/src/helper.h @@ -41,6 +41,7 @@ #define DEFINE_KEY(mask, keysym, handler, arg) {mask, keysym, handler, arg} #define DEFINE_MAPPING(name, value) {name, value} +#define _KEY(k) XK_#k /* spent way too many hours hunting double-free bugs. This should handle it. */ #define _FREE_(ptr) \ diff --git a/src/zwm.c b/src/zwm.c index c8cac00..f51019f 100644 --- a/src/zwm.c +++ b/src/zwm.c @@ -111,55 +111,55 @@ xcb_cursor_t cursors[CURSOR_MAX]; /* see X11/keysymdef.h */ static const _key__t _keys_[] = { - DEFINE_KEY(SUPER, XK_w, close_or_kill_wrapper, NULL), - DEFINE_KEY(SUPER, XK_Return, exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"alacritty"}})), - DEFINE_KEY(SUPER, XK_space, exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"dmenu_run"}})), - DEFINE_KEY(SUPER, XK_p, exec_process, &((arg_t){.argc = 3, .cmd = (char *[]){"rofi", "-show", "drun"}})), - DEFINE_KEY(SUPER, XK_1, switch_desktop_wrapper, &((arg_t){.idx = 0})), - DEFINE_KEY(SUPER, XK_2, switch_desktop_wrapper, &((arg_t){.idx = 1})), - DEFINE_KEY(SUPER, XK_3, switch_desktop_wrapper, &((arg_t){.idx = 2})), - DEFINE_KEY(SUPER, XK_4, switch_desktop_wrapper, &((arg_t){.idx = 3})), - DEFINE_KEY(SUPER, XK_5, switch_desktop_wrapper, &((arg_t){.idx = 4})), - DEFINE_KEY(SUPER, XK_6, switch_desktop_wrapper, &((arg_t){.idx = 5})), - DEFINE_KEY(SUPER, XK_7, switch_desktop_wrapper, &((arg_t){.idx = 6})), - DEFINE_KEY(SUPER, XK_Left, cycle_win_wrapper, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER, XK_Right, cycle_win_wrapper, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER, XK_Up, cycle_win_wrapper, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER, XK_Down, cycle_win_wrapper, &((arg_t){.d = DOWN})), - DEFINE_KEY(SUPER, XK_l, horizontal_resize_wrapper, &((arg_t){.r = GROW})), - DEFINE_KEY(SUPER, XK_h, horizontal_resize_wrapper, &((arg_t){.r = SHRINK})), - DEFINE_KEY(SUPER, XK_f, set_fullscreen_wrapper, NULL), - DEFINE_KEY(SUPER, XK_s, swap_node_wrapper, NULL), - DEFINE_KEY(SUPER, XK_i, gap_handler, &((arg_t){.r = GROW})), - DEFINE_KEY(SUPER, XK_d, gap_handler, &((arg_t){.r = SHRINK})), - DEFINE_KEY(SUPER | SHIFT, XK_Left, shift_floating_window, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER | SHIFT, XK_Right, shift_floating_window, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER | SHIFT, XK_Up, shift_floating_window, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER | SHIFT, XK_Down, shift_floating_window, &((arg_t){.d = DOWN})), - DEFINE_KEY(SUPER | ALT, XK_f, change_state, &((arg_t){.s = FLOATING})), - DEFINE_KEY(SUPER | ALT, XK_t, change_state, &((arg_t){.s = TILED})), - DEFINE_KEY(SUPER | SHIFT, XK_1, transfer_node_wrapper, &((arg_t){.idx = 0})), - DEFINE_KEY(SUPER | SHIFT, XK_2, transfer_node_wrapper, &((arg_t){.idx = 1})), - DEFINE_KEY(SUPER | SHIFT, XK_3, transfer_node_wrapper, &((arg_t){.idx = 2})), - DEFINE_KEY(SUPER | SHIFT, XK_4, transfer_node_wrapper, &((arg_t){.idx = 3})), - DEFINE_KEY(SUPER | SHIFT, XK_5, transfer_node_wrapper, &((arg_t){.idx = 4})), - DEFINE_KEY(SUPER | SHIFT, XK_6, transfer_node_wrapper, &((arg_t){.idx = 5})), - DEFINE_KEY(SUPER | SHIFT, XK_7, transfer_node_wrapper, &((arg_t){.idx = 6})), - DEFINE_KEY(SUPER | SHIFT, XK_m, layout_handler, &((arg_t){.t = MASTER})), - DEFINE_KEY(SUPER | SHIFT, XK_d, layout_handler, &((arg_t){.t = DEFAULT})), - DEFINE_KEY(SUPER | SHIFT, XK_s, layout_handler, &((arg_t){.t = STACK})), - DEFINE_KEY(SUPER | SHIFT, XK_k, traverse_stack_wrapper, &((arg_t){.d = UP})), - DEFINE_KEY(SUPER | SHIFT, XK_j, traverse_stack_wrapper, &((arg_t){.d = DOWN})), - DEFINE_KEY(SUPER | SHIFT, XK_f, flip_node_wrapper, NULL), - DEFINE_KEY(SUPER | SHIFT, XK_r, reload_config_wrapper, NULL), - DEFINE_KEY(SUPER | SHIFT, XK_Left, cycle_desktop_wrapper, &((arg_t){.d = LEFT})), - DEFINE_KEY(SUPER | SHIFT, XK_Right, cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), - DEFINE_KEY(SUPER | SHIFT, XK_y, grow_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_h, grow_floating_window, &((arg_t){.rd = VERTICAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_t, shrink_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), - DEFINE_KEY(SUPER | SHIFT, XK_g, shrink_floating_window, &((arg_t){.rd = VERTICAL_DIR})), - DEFINE_KEY(SUPER | CTRL, XK_Right, cycle_monitors, &((arg_t){.tr = NEXT})), - DEFINE_KEY(SUPER | CTRL, XK_Left, cycle_monitors, &((arg_t){.tr = PREV})), + DEFINE_KEY(SUPER, _KEY(w), close_or_kill_wrapper, NULL), + DEFINE_KEY(SUPER, _KEY(Return), exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"alacritty"}})), + DEFINE_KEY(SUPER, _KEY(space), exec_process, &((arg_t){.argc = 1, .cmd = (char *[]){"dmenu_run"}})), + DEFINE_KEY(SUPER, _KEY(p), exec_process, &((arg_t){.argc = 3, .cmd = (char *[]){"rofi", "-show", "drun"}})), + DEFINE_KEY(SUPER, _KEY(1), switch_desktop_wrapper, &((arg_t){.idx = 0})), + DEFINE_KEY(SUPER, _KEY(2), switch_desktop_wrapper, &((arg_t){.idx = 1})), + DEFINE_KEY(SUPER, _KEY(3), switch_desktop_wrapper, &((arg_t){.idx = 2})), + DEFINE_KEY(SUPER, _KEY(4), switch_desktop_wrapper, &((arg_t){.idx = 3})), + DEFINE_KEY(SUPER, _KEY(5), switch_desktop_wrapper, &((arg_t){.idx = 4})), + DEFINE_KEY(SUPER, _KEY(6), switch_desktop_wrapper, &((arg_t){.idx = 5})), + DEFINE_KEY(SUPER, _KEY(7), switch_desktop_wrapper, &((arg_t){.idx = 6})), + DEFINE_KEY(SUPER, _KEY(Left), cycle_win_wrapper, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER, _KEY(Right), cycle_win_wrapper, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER, _KEY(Up), cycle_win_wrapper, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER, _KEY(Down), cycle_win_wrapper, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER, _KEY(l), horizontal_resize_wrapper, &((arg_t){.r = GROW})), + DEFINE_KEY(SUPER, _KEY(h), horizontal_resize_wrapper, &((arg_t){.r = SHRINK})), + DEFINE_KEY(SUPER, _KEY(f), set_fullscreen_wrapper, NULL), + DEFINE_KEY(SUPER, _KEY(s), swap_node_wrapper, NULL), + DEFINE_KEY(SUPER, _KEY(i), gap_handler, &((arg_t){.r = GROW})), + DEFINE_KEY(SUPER, _KEY(d), gap_handler, &((arg_t){.r = SHRINK})), + DEFINE_KEY(SUPER | SHIFT, _KEY(Left), shift_floating_window, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER | SHIFT, _KEY(Right), shift_floating_window, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER | SHIFT, _KEY(Up), shift_floating_window, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER | SHIFT, _KEY(Down), shift_floating_window, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER | ALT, _KEY(f), change_state, &((arg_t){.s = FLOATING})), + DEFINE_KEY(SUPER | ALT, _KEY(t), change_state, &((arg_t){.s = TILED})), + DEFINE_KEY(SUPER | SHIFT, _KEY(1), transfer_node_wrapper, &((arg_t){.idx = 0})), + DEFINE_KEY(SUPER | SHIFT, _KEY(2), transfer_node_wrapper, &((arg_t){.idx = 1})), + DEFINE_KEY(SUPER | SHIFT, _KEY(3), transfer_node_wrapper, &((arg_t){.idx = 2})), + DEFINE_KEY(SUPER | SHIFT, _KEY(4), transfer_node_wrapper, &((arg_t){.idx = 3})), + DEFINE_KEY(SUPER | SHIFT, _KEY(5), transfer_node_wrapper, &((arg_t){.idx = 4})), + DEFINE_KEY(SUPER | SHIFT, _KEY(6), transfer_node_wrapper, &((arg_t){.idx = 5})), + DEFINE_KEY(SUPER | SHIFT, _KEY(7), transfer_node_wrapper, &((arg_t){.idx = 6})), + DEFINE_KEY(SUPER | SHIFT, _KEY(m), layout_handler, &((arg_t){.t = MASTER})), + DEFINE_KEY(SUPER | SHIFT, _KEY(d), layout_handler, &((arg_t){.t = DEFAULT})), + DEFINE_KEY(SUPER | SHIFT, _KEY(s), layout_handler, &((arg_t){.t = STACK})), + DEFINE_KEY(SUPER | SHIFT, _KEY(k), traverse_stack_wrapper, &((arg_t){.d = UP})), + DEFINE_KEY(SUPER | SHIFT, _KEY(j), traverse_stack_wrapper, &((arg_t){.d = DOWN})), + DEFINE_KEY(SUPER | SHIFT, _KEY(f), flip_node_wrapper, NULL), + DEFINE_KEY(SUPER | SHIFT, _KEY(r), reload_config_wrapper, NULL), + DEFINE_KEY(SUPER | SHIFT, _KEY(Left), cycle_desktop_wrapper, &((arg_t){.d = LEFT})), + DEFINE_KEY(SUPER | SHIFT, _KEY(Right), cycle_desktop_wrapper, &((arg_t){.d = RIGHT})), + DEFINE_KEY(SUPER | SHIFT, _KEY(y), grow_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, _KEY(h), grow_floating_window, &((arg_t){.rd = VERTICAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, _KEY(t), shrink_floating_window, &((arg_t){.rd = HORIZONTAL_DIR})), + DEFINE_KEY(SUPER | SHIFT, _KEY(g), shrink_floating_window, &((arg_t){.rd = VERTICAL_DIR})), + DEFINE_KEY(SUPER | CTRL, _KEY(Right), cycle_monitors, &((arg_t){.tr = NEXT})), + DEFINE_KEY(SUPER | CTRL, _KEY(Left), cycle_monitors, &((arg_t){.tr = PREV})), }; static const uint32_t _buttons_[] = { From 48b6f44b56cede3a2e13857fc9bed154aa9dd922 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Fri, 3 Jan 2025 18:38:20 +0300 Subject: [PATCH 11/12] fix key macro --- src/helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper.h b/src/helper.h index 14e16de..141eafa 100644 --- a/src/helper.h +++ b/src/helper.h @@ -41,7 +41,7 @@ #define DEFINE_KEY(mask, keysym, handler, arg) {mask, keysym, handler, arg} #define DEFINE_MAPPING(name, value) {name, value} -#define _KEY(k) XK_#k +#define _KEY(k) XK_##k /* spent way too many hours hunting double-free bugs. This should handle it. */ #define _FREE_(ptr) \ From f2febca1cdcd37d09fe8fbf82dcc4cb8d1e47744 Mon Sep 17 00:00:00 2001 From: Yazeed1s Date: Fri, 3 Jan 2025 19:15:57 +0300 Subject: [PATCH 12/12] update readme --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 707ba72..5d64a46 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,7 @@ rule = wm_class("firefox"), state(tiled), desktop(-1) - **change_state**: Set window state (FLAOTING, TILED). - **grow_floating_window**: Grow floating window (horizontally or vertically). - **shrink_floating_window**: Shrink floating window (horizontally or vertically). + - **cycle_monitors**: Cycle between monitors (left or right, relative to the linked-list order not the physical positioning). - Default keys @@ -320,14 +321,16 @@ bind = shift + up -> func(shift_window:up) bind = shift + right -> func(shift_window:right) bind = shift + left -> func(shift_window:left) bind = shift + down -> func(shift_window:down) +bind = shift + f -> func(change_state:float) +bind = shift + t -> func(change_state:tile) bind = super|shift + t -> func(shrink_floating_window:horizontal) bind = super|shift + g -> func(shrink_floating_window:vertical) bind = super|shift + y -> func(grow_floating_window:horizontal) bind = super|shift + h -> func(grow_floating_window:vertical) -bind = shift + t -> func(change_state:tile) -bind = shift + f -> func(change_state:float) bind = super|shift + left -> func(cycle_desktop:left) bind = super|shift + right -> func(cycle_desktop:right) +bind = super|ctrl + right -> func(cycle_monitors:next) +bind = super|ctrl + left -> func(cycle_monitors:prev) bind = super|shift + 1 -> func(transfer_node:1) bind = super|shift + 2 -> func(transfer_node:2) bind = super|shift + 3 -> func(transfer_node:3) @@ -369,6 +372,8 @@ More options will be added in the future as development progresses. | `super + shift + h` | grow floating windows vertically | | `super + shift + t` | shrink floating windows horizontally | | `super + shift + g` | shrink floating windows vertically | +| `super + ctrl + →` | focus/change monitor right | +| `super + ctrl + ←` | focus/change monitor left | | `super + s` | swap window's orientation | | `super + ←` | focus window on the left | | `super + ↑` | focus window above |