From dedd9071102ab784bca29f602e025d8b03fcb239 Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Wed, 24 Sep 2014 15:11:56 +0100 Subject: [PATCH 01/26] Fixed off by one errors that caused strange behaviour on the last Workspace. --- howm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/howm.c b/howm.c index 22fc46b..3219326 100644 --- a/howm.c +++ b/howm.c @@ -727,7 +727,7 @@ Client *find_client_by_win(xcb_window_t win) int w = 1, cur_ws = cw; Client *c = NULL; - for (found = false; w < WORKSPACES && !found; ++w) + for (found = false; w < WORKSPACES && !found; w++) for (c = wss[w].head; c && !(found = (win == c->win)); c = c->next) ; if (cur_ws != w) @@ -1227,7 +1227,7 @@ void remove_client(Client *c) Client **temp = NULL; int w = 1; - for (; w <= WORKSPACES; ++w) + for (; w <= WORKSPACES; w++) for (temp = &wss[w].head; *temp; temp = &(*temp)->next) if (*temp == c) goto found; From 15d4c342f6b6f897aa7e871e24ba321a41f71494 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 16:54:06 +0100 Subject: [PATCH 02/26] Fixed client_to_ws not looking at the correct workspace. prev_client assumed that we wanted to look on the current workspace- that isn't true for finding a previous client on another workspace (as we do in client_to_ws). --- howm.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/howm.c b/howm.c index 3219326..a60e1d9 100644 --- a/howm.c +++ b/howm.c @@ -218,7 +218,7 @@ static Client *next_client(Client *c); static void focus_next_client(const Arg *arg); static void focus_prev_client(const Arg *arg); static void update_focused_client(Client *c); -static Client *prev_client(Client *c); +static Client *prev_client(Client *c, int ws); static Client *create_client(xcb_window_t w); static void remove_client(Client *c); static Client *find_client_by_win(xcb_window_t w); @@ -778,16 +778,18 @@ xcb_keycode_t *keysym_to_keycode(xcb_keysym_t sym) * * @param c The client which needs to have its previous found. * + * @param ws The workspace that the client is on. + * * @return The previous client, so long as the given client isn't NULL and * there is more than one client. Else, NULL. */ -Client *prev_client(Client *c) +Client *prev_client(Client *c, int ws) { Client *p = NULL; - if (!c || !wss[cw].head || !wss[cw].head->next) + if (!c || !wss[ws].head || !wss[ws].head->next) return NULL; - for (p = wss[cw].head; p->next && p->next != c; p = p->next) + for (p = wss[ws].head; p->next && p->next != c; p = p->next) ; return p; } @@ -927,7 +929,7 @@ void update_focused_client(Client *c) return; } else if (c == wss[cw].prev_foc) { wss[cw].current = (wss[cw].prev_foc ? wss[cw].prev_foc : wss[cw].head); - wss[cw].prev_foc = prev_client(wss[cw].current); + wss[cw].prev_foc = prev_client(wss[cw].current, cw); } else if (c != wss[cw].current) { wss[cw].prev_foc = wss[cw].current; wss[cw].current = c; @@ -1237,7 +1239,7 @@ void remove_client(Client *c) *temp = c->next; log_info("Removing client <%p>", c); if (c == wss[w].prev_foc) - wss[w].prev_foc = prev_client(wss[w].current); + wss[w].prev_foc = prev_client(wss[w].current, cw); if (c == wss[w].current || !wss[w].head->next) wss[w].current = NULL; update_focused_client(wss[w].prev_foc); @@ -1290,7 +1292,7 @@ void enter_event(xcb_generic_event_t *ev) */ void move_down(Client *c) { - Client *prev = prev_client(c); + Client *prev = prev_client(c, cw); Client *n = (c->next) ? c->next : wss[cw].head; if (!c) @@ -1317,7 +1319,7 @@ void move_down(Client *c) */ void move_up(Client *c) { - Client *p = prev_client(c); + Client *p = prev_client(c, cw); Client *pp = NULL; if (!c) @@ -1365,7 +1367,7 @@ void focus_prev_client(const Arg *arg) return; log_info("Focusing previous client"); wss[cw].prev_foc = wss[cw].current; - update_focused_client(prev_client(wss[cw].prev_foc)); + update_focused_client(prev_client(wss[cw].prev_foc, cw)); } /** @@ -1627,13 +1629,13 @@ void move_client(int cnt, bool up) if (up) { if (wss[cw].current == wss[cw].head) return; - c = prev_client(wss[cw].current); + c = prev_client(wss[cw].current, cw); /* TODO optimise this by inserting the client only once * and in the correct location.*/ for (; cnt > 0; move_down(c), cnt--) ; } else { - if (wss[cw].current == prev_client(wss[cw].head)) + if (wss[cw].current == prev_client(wss[cw].head, cw)) return; cntcopy = cnt; for (c = wss[cw].current; cntcopy > 0; c = next_client(c), cntcopy--) @@ -1674,13 +1676,13 @@ void move_current_up(const Arg *arg) void client_to_ws(Client *c, const int ws) { Client *last; - Client *prev = prev_client(c); + Client *prev = prev_client(c, cw); /* Performed for the current workspace. */ if (!c || ws == cw) return; /* Target workspace. */ - last = prev_client(wss[ws].head); + last = prev_client(wss[ws].head, ws); if (!wss[ws].head) wss[ws].head = c; else if (last) @@ -2243,7 +2245,7 @@ static void toggle_bar(const Arg *arg) Client *create_client(xcb_window_t w) { Client *c = (Client *)calloc(1, sizeof(Client)); - Client *t = prev_client(wss[cw].head); /* Get the last element. */ + Client *t = prev_client(wss[cw].head, cw); /* Get the last element. */ uint32_t vals[1] = { XCB_EVENT_MASK_PROPERTY_CHANGE | (FOCUS_MOUSE ? XCB_EVENT_MASK_ENTER_WINDOW : 0)}; @@ -2572,7 +2574,7 @@ static void op_cut(const unsigned int type, int cnt) { Client *tail = wss[cw].current; Client *head = wss[cw].current; - Client *head_prev = prev_client(wss[cw].current); + Client *head_prev = prev_client(wss[cw].current, cw); bool wrap = false; if (!head) From ba4ea223724c7ed0a7287e037b520d7858fc2225 Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Wed, 24 Sep 2014 13:19:15 +0100 Subject: [PATCH 03/26] Added the basis of rules. Added the implementation of rules. When the client is to be spawned on a different workspace (without follow set to true) the client is expanded to be the full size of the display (larger than fullscreen) and appears behind all workspaces. --- config.h | 4 ++++ howm.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/config.h b/config.h index b427f83..6b35afb 100644 --- a/config.h +++ b/config.h @@ -83,6 +83,10 @@ static const char * const dmenu_cmd[] = {"dmenu_run", "-i", "-b", "-nb", "#70898f", "-nf", "black", "-sf", "#74718e", NULL}; +static const Rule rules[] = { + {"mpv", 5, false, false, false} +}; + /** @brief The standard key map, feel free to change them. * * In the form: diff --git a/howm.c b/howm.c index a60e1d9..11b96bb 100644 --- a/howm.c +++ b/howm.c @@ -73,6 +73,18 @@ typedef struct { const Arg arg; /**< The argument passed to the above function. */ } Key; +/** + * @brief Represents a rule that is applied to a client upon it starting. + */ +typedef struct { + const char *class; /**< The class or name of the client. */ + int ws; /**< The workspace that the client should be spawned + on (0 means current workspace). */ + bool follow; /**< If the client is spawned on another ws, shall we follow? */ + bool is_floating; /**< Spawn the client in a floating state? */ + bool is_fullscreen; /**< Spawn the client in a fullscreen state? */ +} Rule; + /** * @brief Represents an operator. * @@ -222,7 +234,7 @@ static Client *prev_client(Client *c, int ws); static Client *create_client(xcb_window_t w); static void remove_client(Client *c); static Client *find_client_by_win(xcb_window_t w); -static void client_to_ws(Client *c, const int ws); +static void client_to_ws(Client *c, const int ws, bool follow); static void current_to_ws(const Arg *arg); static void draw_clients(void); static void change_client_geom(Client *c, uint16_t x, uint16_t y, uint16_t w, uint16_t h); @@ -290,6 +302,7 @@ static xcb_keysym_t keycode_to_keysym(xcb_keycode_t keycode); static void ewmh_process_wm_state(Client *c, xcb_atom_t a, int action); /* Misc */ +static void apply_rules(Client *c); static void howm_info(void); static void save_last_ocm(void (*op) (const int unsigned, int), const unsigned int type, int cnt); static void save_last_cmd(void (*cmd)(const Arg *), const Arg *arg); @@ -649,7 +662,6 @@ void map_event(xcb_generic_event_t *ev) xcb_get_window_attributes_reply_t *wa; xcb_map_request_event_t *me = (xcb_map_request_event_t *)ev; xcb_ewmh_get_atoms_reply_t type; - bool floating = false; unsigned int i; Client *c; @@ -660,12 +672,15 @@ void map_event(xcb_generic_event_t *ev) } free(wa); + log_info("Mapping request for window <%d>", me->window); + + c = create_client(me->window); + if (xcb_ewmh_get_wm_window_type_reply(ewmh, xcb_ewmh_get_wm_window_type(ewmh, me->window), &type, NULL) == 1) { for (i = 0; i < type.atoms_len; i++) { xcb_atom_t a = type.atoms[i]; - if (a == ewmh->_NET_WM_WINDOW_TYPE_DOCK || a == ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR) { return; @@ -675,20 +690,17 @@ void map_event(xcb_generic_event_t *ev) || a == ewmh->_NET_WM_WINDOW_TYPE_POPUP_MENU || a == ewmh->_NET_WM_WINDOW_TYPE_TOOLTIP || a == ewmh->_NET_WM_WINDOW_TYPE_DIALOG) { - floating = true; + c->is_floating = true; } } } - log_info("Mapping request for window <%d>", me->window); - /* Rule stuff needs to be here. */ - c = create_client(me->window); - /* Assume that transient windows MUST float. */ xcb_icccm_get_wm_transient_for_reply(dpy, xcb_icccm_get_wm_transient_for_unchecked(dpy, me->window), &transient, NULL); c->is_transient = transient ? true : false; - c->is_floating = c->is_transient || floating; + if (c->is_transient) + c->is_floating = true; geom = xcb_get_geometry_reply(dpy, xcb_get_geometry_unchecked(dpy, me->window), NULL); if (geom) { @@ -703,6 +715,7 @@ void map_event(xcb_generic_event_t *ev) } grab_buttons(c); + apply_rules(c); arrange_windows(); xcb_map_window(dpy, c->win); update_focused_client(c); @@ -727,7 +740,7 @@ Client *find_client_by_win(xcb_window_t win) int w = 1, cur_ws = cw; Client *c = NULL; - for (found = false; w < WORKSPACES && !found; w++) + for (found = false; w <= WORKSPACES && !found; w++) for (c = wss[w].head; c && !(found = (win == c->win)); c = c->next) ; if (cur_ws != w) @@ -1193,6 +1206,7 @@ int get_non_tff_count(void) static Client *get_first_non_tff(void) { Client *c = NULL; + for (c = wss[cw].head; c && FFT(c); c = c->next) ; return c; @@ -1673,7 +1687,7 @@ void move_current_up(const Arg *arg) * @param c The client to be moved. * @param ws The ws that the client should be moved to. */ -void client_to_ws(Client *c, const int ws) +void client_to_ws(Client *c, const int ws, bool follow) { Client *last; Client *prev = prev_client(c, cw); @@ -1689,6 +1703,7 @@ void client_to_ws(Client *c, const int ws) last->next = c; else wss[ws].head->next = c; + wss[ws].client_cnt++; /* Current workspace. */ if (c == wss[cw].head || !prev) @@ -1697,9 +1712,10 @@ void client_to_ws(Client *c, const int ws) prev->next = c->next; c->next = NULL; xcb_unmap_window(dpy, c->win); + wss[cw].client_cnt--; update_focused_client(wss[cw].prev_foc); log_info("Moved client <%p> from <%d> to <%d>", c, cw, ws); - if (FOLLOW_SPAWN) { + if (follow) { change_ws(&(Arg){ .i = ws }); update_focused_client(c); } else { @@ -1715,7 +1731,7 @@ void client_to_ws(Client *c, const int ws) void current_to_ws(const Arg *arg) { - client_to_ws(wss[cw].current, arg->i); + client_to_ws(wss[cw].current, arg->i, FOLLOW_SPAWN); } /** @@ -2643,9 +2659,9 @@ static void op_cut(const unsigned int type, int cnt) */ static void focus_urgent(const Arg *arg) { + UNUSED(arg); Client *c; int w; - UNUSED(arg); for (w = 1; w <= WORKSPACES; w++) for (c = wss[w].head; c && !c->is_urgent; c = c->next) @@ -2668,6 +2684,7 @@ static void paste(const Arg *arg) UNUSED(arg); Client *head = stack_pop(&del_reg); Client *t, *c = head; + if (!head) { log_warn("No clients on stack."); return; @@ -2706,3 +2723,24 @@ static void paste(const Arg *arg) xcb_flush(dpy); update_focused_client(wss[cw].current); } + +static void apply_rules(Client *c) +{ + xcb_icccm_get_wm_class_reply_t wc; + unsigned int i; + + if (xcb_icccm_get_wm_class_reply(dpy, xcb_icccm_get_wm_class(dpy, + c->win), &wc, NULL)) { + for (i = 0; i < LENGTH(rules); i++) { + if (strstr(wc.instance_name, rules[i].class) + || strstr(wc.class_name, rules[i].class)) { + c->is_floating = rules[i].is_floating; + c->is_fullscreen = rules[i].is_fullscreen; + client_to_ws(c, rules[i].ws == 0 ? cw + : rules[i].ws, rules[i].follow); + break; + } + } + } + xcb_icccm_get_wm_class_reply_wipe(&wc); +} From c8c0799ed7095109ceaaf183bc0b3889cbb300b6 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 17:17:49 +0100 Subject: [PATCH 04/26] Prevented visual bugs and segfaults when a client was sent to a new workspace without focus following it. --- README.md | 4 ++-- config.h | 8 ++++++-- howm.c | 15 +++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3bad4b1..6a98391 100644 --- a/README.md +++ b/README.md @@ -68,10 +68,10 @@ Each option is described in detail below: #define FOCUS_MOUSE_CLICK false ``` -* **FOLLOW_SPAWN**: When true, focus will change to a new window when it is spawned. +* **FOLLOW_MOVE**: When true, focus will change to a a different workspace when a client is sent there. ``` -#define FOLLOW_SPAWN false +#define FOLLOW_MOVE false ``` * **GAP**: The size (in pixels) of the "useless gap" to place between windows. diff --git a/config.h b/config.h index 6b35afb..a4ef5b0 100644 --- a/config.h +++ b/config.h @@ -25,8 +25,9 @@ #define FOCUS_MOUSE false /** Clicking a window will focus it. */ #define FOCUS_MOUSE_CLICK true -/** Upon spawning a new window, move the mouse to the new window? */ -#define FOLLOW_SPAWN true +/** Upon moving a window to a different workspace, move the focus to the + * workspace? */ +#define FOLLOW_MOVE true /** The size (in pixels) of the useless gaps. */ #define GAP 2 /** Enable debugging output */ @@ -83,7 +84,10 @@ static const char * const dmenu_cmd[] = {"dmenu_run", "-i", "-b", "-nb", "#70898f", "-nf", "black", "-sf", "#74718e", NULL}; +/* Rules that are applied to clients as they are spawned. */ static const Rule rules[] = { + /* Class, WS, follow, float, fullscreen */ + {"dwb", 3, false, false, false} {"mpv", 5, false, false, false} }; diff --git a/howm.c b/howm.c index 11b96bb..bcf59ae 100644 --- a/howm.c +++ b/howm.c @@ -715,9 +715,9 @@ void map_event(xcb_generic_event_t *ev) } grab_buttons(c); + xcb_map_window(dpy, c->win); apply_rules(c); arrange_windows(); - xcb_map_window(dpy, c->win); update_focused_client(c); } @@ -1703,6 +1703,7 @@ void client_to_ws(Client *c, const int ws, bool follow) last->next = c; else wss[ws].head->next = c; + wss[ws].current = c; wss[ws].client_cnt++; /* Current workspace. */ @@ -1710,16 +1711,18 @@ void client_to_ws(Client *c, const int ws, bool follow) wss[cw].head = c->next; else prev->next = c->next; + wss[cw].current = prev; + wss[cw].client_cnt--; + c->next = NULL; xcb_unmap_window(dpy, c->win); - wss[cw].client_cnt--; - update_focused_client(wss[cw].prev_foc); + log_info("Moved client <%p> from <%d> to <%d>", c, cw, ws); if (follow) { + wss[ws].current = c; change_ws(&(Arg){ .i = ws }); - update_focused_client(c); } else { - arrange_windows(); + update_focused_client(prev); } } @@ -1731,7 +1734,7 @@ void client_to_ws(Client *c, const int ws, bool follow) void current_to_ws(const Arg *arg) { - client_to_ws(wss[cw].current, arg->i, FOLLOW_SPAWN); + client_to_ws(wss[cw].current, arg->i, FOLLOW_MOVE); } /** From 380ea4a20b603f6864ff870d9d03081bab7cfa8b Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 17:19:57 +0100 Subject: [PATCH 05/26] Added a warning about updating focus of clients on other workspaces. --- howm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/howm.c b/howm.c index bcf59ae..7865be9 100644 --- a/howm.c +++ b/howm.c @@ -927,6 +927,9 @@ void move_resize(xcb_window_t win, * @brief Sets c to the active window and gives it input focus. Sorts out * border colours as well. * + * WARNING: Do NOT use this to focus a client on another workspace. Instead, + * set wss[ws].current to the client that you want focused. + * * @param c The client that is currently in focus. */ void update_focused_client(Client *c) From 7cb2f022ebb09c7e59698bcc906f0264a587babf Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 17:20:49 +0100 Subject: [PATCH 06/26] Fixed a missing comma. --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index a4ef5b0..1a91d74 100644 --- a/config.h +++ b/config.h @@ -87,7 +87,7 @@ static const char * const dmenu_cmd[] = {"dmenu_run", "-i", "-b", /* Rules that are applied to clients as they are spawned. */ static const Rule rules[] = { /* Class, WS, follow, float, fullscreen */ - {"dwb", 3, false, false, false} + {"dwb", 3, false, false, false}, {"mpv", 5, false, false, false} }; From d7b96048494aadbadcd5069fc801233571afbbee Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Sat, 27 Sep 2014 17:15:48 +0100 Subject: [PATCH 07/26] Update README.md Added description of rules. --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 6a98391..a22cb9e 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Contents ===== * [Contributing](CONTRIBUTING.md) * [Configuration](#configuration) +* [Rules](#rules) * [Motions](#motions) * [Counts](#counts) * [Operators](#operators) @@ -196,6 +197,17 @@ Can be from 0 to 1. #define DELETE_REGISTER_SIZE 5 ``` +##Rules + +Rules can be used to tell howm to open certain applications on different workspaces and with certain properties set. + +A rule is made up of the following sections: +* **Name**: This is string that can be used to identify a window. It treats name as a substring, so "dw" would still work for the client "dwb". +* **Workspace**: When set to 0, the client will be opened on the current workspace. Otherwise, the client will be opened on the specified workspace. +* **Follow**: Should howm focus on the new client when it is spawned? +* **Floating**: Should the client be floating when it is spawned? +* **Fullscreen**: Should the client be fullscreen when it is spawned? + ##Motions For a good primer on motions, vim's [documentation](http://vimdoc.sourceforge.net/htmldoc/motion.html) explains them well. From 7e8af0e57e29e7ab3934027096ba702bebdce691 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 18:35:53 +0100 Subject: [PATCH 08/26] Added docs for apply_rules. --- howm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/howm.c b/howm.c index 7865be9..2dd701e 100644 --- a/howm.c +++ b/howm.c @@ -2730,6 +2730,12 @@ static void paste(const Arg *arg) update_focused_client(wss[cw].current); } +/** + * @brief Set the properties of a client that has just been created, + * according to the rules defined in the config file. + * + * @param c The client that has been created. + */ static void apply_rules(Client *c) { xcb_icccm_get_wm_class_reply_t wc; From 22355ca26edbe51e62d881e16ffacb3c0ab45a76 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 19:17:21 +0100 Subject: [PATCH 09/26] Fixed #31 and fixed a bug whereby cutting wouldn't cut all clients. --- howm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/howm.c b/howm.c index a60e1d9..66f2118 100644 --- a/howm.c +++ b/howm.c @@ -2605,8 +2605,13 @@ static void op_cut(const unsigned int type, int cnt) xcb_unmap_window(dpy, head->win); wss[cw].client_cnt--; while (cnt > 1) { - if (!tail->next && next_client(tail)) + if (!tail->next && next_client(tail)) { wrap = true; + /* Join the list into a circular linked list, + * just for now so that we don't miss any + * clients. */ + tail->next = next_client(tail); + } if (tail == wss[cw].prev_foc) wss[cw].prev_foc = NULL; tail = next_client(tail); @@ -2615,11 +2620,6 @@ static void op_cut(const unsigned int type, int cnt) wss[cw].client_cnt--; } - /* If cnt was greater than 1 and we have reached the end of the - * client list, we need to make it "circular".*/ - if (tail != head && head->next == NULL) - head->next = next_client(head); - if (head == wss[cw].head) { wss[cw].head = head == next_client(tail) ? NULL : next_client(tail); } else if (wrap) { @@ -2680,6 +2680,7 @@ static void paste(const Arg *arg) xcb_map_window(dpy, c->win); wss[cw].current = c; c = c->next; + wss[cw].client_cnt++; } } else if (!wss[cw].current->next) { wss[cw].current->next = head; @@ -2687,12 +2688,14 @@ static void paste(const Arg *arg) xcb_map_window(dpy, c->win); wss[cw].current = c; c = c->next; + wss[cw].client_cnt++; } } else { t = wss[cw].current->next; wss[cw].current->next = head; while (c) { xcb_map_window(dpy, c->win); + wss[cw].client_cnt++; if (!c->next) { c->next = t; wss[cw].current = c; From 2e575a8259da4fc597170aef2a1e9bc7854598e1 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 19:39:22 +0100 Subject: [PATCH 10/26] Fixed kill_client not playing nicely with other workspaces and not correctly restoring focus. Hopefully this will fix #32. Killing workspace/s and clients has become far faster too. This helps with #23. --- howm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/howm.c b/howm.c index 66f2118..d403f5f 100644 --- a/howm.c +++ b/howm.c @@ -692,7 +692,7 @@ void map_event(xcb_generic_event_t *ev) geom = xcb_get_geometry_reply(dpy, xcb_get_geometry_unchecked(dpy, me->window), NULL); if (geom) { - log_info("Mapped client's initial geom is %ux%u+%d+%d\n", geom->width, geom->height, geom->x, geom->y); + log_info("Mapped client's initial geom is %ux%u+%d+%d", geom->width, geom->height, geom->x, geom->y); if (c->is_floating) { c->w = geom->width > 1 ? geom->width : FLOAT_SPAWN_WIDTH; c->h = geom->height > 1 ? geom->height : FLOAT_SPAWN_HEIGHT; @@ -928,8 +928,7 @@ void update_focused_client(Client *c) xcb_delete_property(dpy, screen->root, ewmh->_NET_ACTIVE_WINDOW); return; } else if (c == wss[cw].prev_foc) { - wss[cw].current = (wss[cw].prev_foc ? wss[cw].prev_foc : wss[cw].head); - wss[cw].prev_foc = prev_client(wss[cw].current, cw); + wss[cw].prev_foc = prev_client(wss[cw].current = wss[cw].prev_foc, cw); } else if (c != wss[cw].current) { wss[cw].prev_foc = wss[cw].current; wss[cw].current = c; @@ -1239,13 +1238,12 @@ void remove_client(Client *c) *temp = c->next; log_info("Removing client <%p>", c); if (c == wss[w].prev_foc) - wss[w].prev_foc = prev_client(wss[w].current, cw); + wss[w].prev_foc = prev_client(wss[w].current, w); if (c == wss[w].current || !wss[w].head->next) - wss[w].current = NULL; - update_focused_client(wss[w].prev_foc); + wss[w].current = wss[w].prev_foc ? wss[w].prev_foc : wss[w].head; free(c); c = NULL; - wss[cw].client_cnt--; + wss[w].client_cnt--; } /** From 6828e2769b526b77af2a04a46b5cbca900006747 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 21:02:10 +0100 Subject: [PATCH 11/26] Reduced the amount of times windows are rearranged. #23 --- howm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/howm.c b/howm.c index d403f5f..e8006bf 100644 --- a/howm.c +++ b/howm.c @@ -703,7 +703,6 @@ void map_event(xcb_generic_event_t *ev) } grab_buttons(c); - arrange_windows(); xcb_map_window(dpy, c->win); update_focused_client(c); } @@ -2355,7 +2354,6 @@ static void set_fullscreen(Client *c, bool fscr) arrange_windows(); draw_clients(); } - update_focused_client(c); } static void set_urgent(Client *c, bool urg) From c5e4bfac090fdca1beda1710ed7a032d65910665 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sat, 27 Sep 2014 23:45:01 +0100 Subject: [PATCH 12/26] Initial implementation. FIXMEs need sorting and docs need adding. --- config.h | 4 ++++ howm.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/config.h b/config.h index 1a91d74..51514be 100644 --- a/config.h +++ b/config.h @@ -78,6 +78,8 @@ /** The amount of client lists that can be stored in the register before * needing to be pasted back. */ #define DELETE_REGISTER_SIZE 5 +#define SCRATCHPAD_HEIGHT 500 +#define SCRATCHPAD_WIDTH 500 static const char * const term_cmd[] = {"urxvt", NULL}; static const char * const dmenu_cmd[] = {"dmenu_run", "-i", "-b", @@ -119,6 +121,8 @@ static const Key keys[] = { { MODKEY, NORMAL, XK_b, toggle_bar, {NULL} }, { MODKEY, NORMAL, XK_period, replay, {NULL} }, { MODKEY, NORMAL, XK_p, paste, {NULL} }, + { MODKEY, NORMAL, XK_q, send_to_scratchpad, {NULL} }, + { MODKEY | ShiftMask, NORMAL, XK_q, get_from_scratchpad, {NULL} }, { MODKEY | ShiftMask, FLOATING, XK_k, resize_float_height, {.i = -10} }, { MODKEY | ShiftMask, FLOATING, XK_j, resize_float_height, {.i = 10} }, diff --git a/howm.c b/howm.c index aaa4968..3d198f4 100644 --- a/howm.c +++ b/howm.c @@ -249,6 +249,8 @@ static void set_fullscreen(Client *c, bool fscr); static void set_urgent(Client *c, bool urg); static void toggle_fullscreen(const Arg *arg); static void focus_urgent(const Arg *arg); +static void send_to_scratchpad(const Arg *arg); +static void get_from_scratchpad(const Arg *arg); /* Workspaces */ static void kill_ws(const int ws); @@ -353,17 +355,14 @@ static void(*layout_handler[]) (void) = { static void (*operator_func)(const unsigned int type, int cnt); +static Client *scratchpad; static struct stack del_reg; - static xcb_connection_t *dpy; static char *WM_ATOM_NAMES[] = { "WM_DELETE_WINDOW", "WM_PROTOCOLS" }; static xcb_atom_t wm_atoms[LENGTH(WM_ATOM_NAMES)]; static xcb_screen_t *screen; static xcb_ewmh_connection_t *ewmh; -static int numlockmask, retval; -/* We don't need the range of unsigned, so this prevents a conversion later. */ -static int last_ws, prev_layout; -static int cw = DEFAULT_WORKSPACE; +static int numlockmask, retval, last_ws, prev_layout, cw = DEFAULT_WORKSPACE; static uint32_t border_focus, border_unfocus, border_prev_focus, border_urgent; static unsigned int cur_mode, cur_state = OPERATOR_STATE, cur_cnt = 1; static uint16_t screen_height, screen_width; @@ -2756,3 +2755,60 @@ static void apply_rules(Client *c) } xcb_icccm_get_wm_class_reply_wipe(&wc); } + +void send_to_scratchpad(const Arg *arg) +{ + UNUSED(arg); + Client *c = wss[cw].current; + if (scratchpad || !c) + return; + + log_info("Sending client <%p> to scratchpad", c); + if (prev_client(c, cw)) + prev_client(c, cw)->next = c->next; + + /* TODO: This should be in a reusable function. */ + if (c == wss[cw].prev_foc) + wss[cw].prev_foc = prev_client(wss[cw].current, cw); + if (c == wss[cw].head) + wss[cw].head = c->next; + if (c == wss[cw].current || !wss[cw].head->next) + wss[cw].current = wss[cw].prev_foc ? wss[cw].prev_foc : wss[cw].head; + + xcb_unmap_window(dpy, c->win); + wss[cw].client_cnt--; + /* FIXME: Infinite loop if c is head as current is set to NULL. */ + update_focused_client(wss[cw].current); + scratchpad = c; +} + +void get_from_scratchpad(const Arg *arg) +{ + UNUSED(arg); + if (!scratchpad) + return; + + /* TODO: This should be in a reusable function. */ + if (!wss[cw].head) { + wss[cw].head = scratchpad; + } else if (!wss[cw].head->next) { + wss[cw].head->next = scratchpad; + } else { + prev_client(wss[cw].head, cw)->next = scratchpad; + } + + wss[cw].prev_foc = wss[cw].current; + wss[cw].current = scratchpad; + + scratchpad = NULL; + wss[cw].client_cnt++; + + wss[cw].current->is_floating = true; + wss[cw].current->w = SCRATCHPAD_WIDTH; + wss[cw].current->h = SCRATCHPAD_HEIGHT; + wss[cw].current->x = (screen_width / 2) - (wss[cw].current->w / 2); + wss[cw].current->y = (screen_height - wss[cw].bar_height - wss[cw].current->h) / 2; + + xcb_map_window(dpy, wss[cw].current->win); + update_focused_client(wss[cw].current); +} From bf7deaad34edd8677ae7017302b3f8bb5afa4979 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 00:07:25 +0100 Subject: [PATCH 13/26] Fixed the infinite looping. --- howm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/howm.c b/howm.c index 3d198f4..842fd09 100644 --- a/howm.c +++ b/howm.c @@ -2770,14 +2770,15 @@ void send_to_scratchpad(const Arg *arg) /* TODO: This should be in a reusable function. */ if (c == wss[cw].prev_foc) wss[cw].prev_foc = prev_client(wss[cw].current, cw); - if (c == wss[cw].head) - wss[cw].head = c->next; if (c == wss[cw].current || !wss[cw].head->next) wss[cw].current = wss[cw].prev_foc ? wss[cw].prev_foc : wss[cw].head; + if (c == wss[cw].head) { + wss[cw].head = c->next; + wss[cw].current = c->next; + } xcb_unmap_window(dpy, c->win); wss[cw].client_cnt--; - /* FIXME: Infinite loop if c is head as current is set to NULL. */ update_focused_client(wss[cw].current); scratchpad = c; } @@ -2789,13 +2790,13 @@ void get_from_scratchpad(const Arg *arg) return; /* TODO: This should be in a reusable function. */ - if (!wss[cw].head) { + if (!wss[cw].head) wss[cw].head = scratchpad; - } else if (!wss[cw].head->next) { + else if (!wss[cw].head->next) wss[cw].head->next = scratchpad; - } else { + else prev_client(wss[cw].head, cw)->next = scratchpad; - } + wss[cw].prev_foc = wss[cw].current; wss[cw].current = scratchpad; From 32e011013dcf0afc9f8fc60c73bf6476dddfd9b1 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 00:39:05 +0100 Subject: [PATCH 14/26] Added docs. --- config.h | 2 ++ howm.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/config.h b/config.h index 51514be..84d7dfc 100644 --- a/config.h +++ b/config.h @@ -78,7 +78,9 @@ /** The amount of client lists that can be stored in the register before * needing to be pasted back. */ #define DELETE_REGISTER_SIZE 5 +/** The height of the floating scratchpad window. */ #define SCRATCHPAD_HEIGHT 500 +/** The width of the floating scratchpad window. */ #define SCRATCHPAD_WIDTH 500 static const char * const term_cmd[] = {"urxvt", NULL}; diff --git a/howm.c b/howm.c index 842fd09..bd8e5e7 100644 --- a/howm.c +++ b/howm.c @@ -2756,6 +2756,11 @@ static void apply_rules(Client *c) xcb_icccm_get_wm_class_reply_wipe(&wc); } +/** + * @brief Send a client to the scratchpad and unmap it. + * + * @param arg Unused. + */ void send_to_scratchpad(const Arg *arg) { UNUSED(arg); @@ -2783,6 +2788,12 @@ void send_to_scratchpad(const Arg *arg) scratchpad = c; } +/** + * @brief Get a client from the scratchpad, attach it as the last item in the + * client list and set it to float. + * + * @param arg Unused. + */ void get_from_scratchpad(const Arg *arg) { UNUSED(arg); From a9f3f6103f774d7458d9c5e76eee3698c6f70c28 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 00:41:45 +0100 Subject: [PATCH 15/26] Added IRC notifications. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1c5c70f..288ec76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,3 +11,6 @@ before_install: - sudo apt-get install -y libxcb-ewmh1-dev - sudo apt-get install -y xcb-proto script: make debug +notifications: + irc: + "chat.freenode.net#howm" From 2f867e701ffb8ce6b49b4a6d1c60c3bb96c9589b Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 00:46:12 +0100 Subject: [PATCH 16/26] Attempt 2. --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 288ec76..a5ab4be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,5 +12,4 @@ before_install: - sudo apt-get install -y xcb-proto script: make debug notifications: - irc: - "chat.freenode.net#howm" + irc: "chat.freenode.net#howm" From bcc2d89a09d74c9cbdc597f4b811f4de20529a12 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 00:54:13 +0100 Subject: [PATCH 17/26] And again... --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a5ab4be..cb102bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,4 @@ before_install: - sudo apt-get install -y xcb-proto script: make debug notifications: - irc: "chat.freenode.net#howm" + irc: "irc.freenode.net#howm" From 3af8204d5784efb9c1b9e19ac82e6e0c00faa626 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 01:15:53 +0100 Subject: [PATCH 18/26] Added a check make option and adjusted the travis file accordingly. --- .travis.yml | 5 ++++- Makefile | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cb102bf..67536c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,9 @@ before_install: - sudo apt-get install -y libxcb-icccm4-dev - sudo apt-get install -y libxcb-ewmh1-dev - sudo apt-get install -y xcb-proto -script: make debug +before_script: + - wget https://raw.githubusercontent.com/torvalds/linux/master/scripts/checkpatch.pl + - chmod +x checkpatch.pl +script: make debug && make check notifications: irc: "irc.freenode.net#howm" diff --git a/Makefile b/Makefile index 909efe3..119775f 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,12 @@ install: @echo "Installing to $(DESTDIR)$(INSTALL_PREFIX)/bin" @install -m 0755 $(BIN_PATH)/$(BIN_NAME) $(DESTDIR)$(INSTALL_PREFIX)/bin +.PHONY: check +check: + @echo "Using checkpatch.pl to check style." + @./checkpatch.pl --no-tree --ignore LONG_LINE,NEW_TYPEDEFS -f howm.c + + # Removes all build files .PHONY: clean clean: From 7bc505f79fccc27cdfa36da03cc0b003001b8a0d Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 01:28:49 +0100 Subject: [PATCH 19/26] Fixed style issues. --- Makefile | 2 +- howm.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 119775f..2145f63 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,7 @@ install: .PHONY: check check: @echo "Using checkpatch.pl to check style." - @./checkpatch.pl --no-tree --ignore LONG_LINE,NEW_TYPEDEFS -f howm.c + @./checkpatch.pl --no-tree --ignore LONG_LINE,NEW_TYPEDEFS,UNNECESSARY_ELSE -f howm.c # Removes all build files diff --git a/howm.c b/howm.c index aaa4968..6451da7 100644 --- a/howm.c +++ b/howm.c @@ -95,7 +95,7 @@ typedef struct { int mod; /**< The mask of the modifiers pressed. */ xcb_keysym_t sym; /**< The keysym of the pressed key. */ unsigned int mode; /**< The mode within which this keypress is valid. */ - void (*func)(const int unsigned type, const int cnt); /**< The function to be + void (*func)(const unsigned int type, const int cnt); /**< The function to be * called when the key is pressed. */ } Operator; @@ -177,7 +177,7 @@ typedef struct { * combination of operator, count and motion (ocm). */ struct replay_state { - void (*last_op)(const int unsigned type, int cnt); /** The last operator to be called. */ + void (*last_op)(const unsigned int type, int cnt); /** The last operator to be called. */ void (*last_cmd)(const Arg *arg); /** The last command to be called. */ const Arg *last_arg; /** The last argument, passed to the last command. */ unsigned int last_type; /** The value determine by the last motion @@ -304,7 +304,7 @@ static void ewmh_process_wm_state(Client *c, xcb_atom_t a, int action); /* Misc */ static void apply_rules(Client *c); static void howm_info(void); -static void save_last_ocm(void (*op) (const int unsigned, int), const unsigned int type, int cnt); +static void save_last_ocm(void (*op) (const unsigned int, int), const unsigned int type, int cnt); static void save_last_cmd(void (*cmd)(const Arg *), const Arg *arg); static void replay(const Arg *arg); static void paste(const Arg *arg); @@ -487,9 +487,9 @@ uint32_t get_colour(char *colour) */ int main(int argc, char *argv[]) { - xcb_generic_event_t *ev; UNUSED(argc); UNUSED(argv); + xcb_generic_event_t *ev; dpy = xcb_connect(NULL, NULL); if (xcb_connection_has_error(dpy)) { @@ -516,6 +516,7 @@ int main(int argc, char *argv[]) cleanup(); xcb_disconnect(dpy); char *const argv[] = {HOWM_PATH, NULL}; + execv(argv[0], argv); } return EXIT_FAILURE; @@ -681,6 +682,7 @@ void map_event(xcb_generic_event_t *ev) &type, NULL) == 1) { for (i = 0; i < type.atoms_len; i++) { xcb_atom_t a = type.atoms[i]; + if (a == ewmh->_NET_WM_WINDOW_TYPE_DOCK || a == ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR) { return; @@ -1752,10 +1754,10 @@ int correct_ws(int ws) { if (ws > WORKSPACES) return ws - WORKSPACES; - else if (ws < 1) + if (ws < 1) return ws + WORKSPACES; - else - return ws; + + return ws; } /** From fe976af60930fdad926e335efd158415943db09c Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 17:45:59 +0100 Subject: [PATCH 20/26] Added static asserts. --- config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.h b/config.h index 84d7dfc..530e6e0 100644 --- a/config.h +++ b/config.h @@ -228,4 +228,6 @@ _Static_assert(BAR_HEIGHT >= 0, "BAR_HEIGHT can't be negative."); _Static_assert(FLOAT_SPAWN_HEIGHT >= 0, "FLOAT_SPAWN_HEIGHT can't be negative."); _Static_assert(FLOAT_SPAWN_WIDTH >= 0, "FLOAT_SPAWN_WIDTH can't be negative."); _Static_assert(LENGTH(wss) == WORKSPACES + 1, "wss must contain one more workspace than WORKSPACES."); +_Static_assert(SCRATCHPAD_WIDTH >= 0, "SCRATCHPAD_WIDTH can't be negative."); +_Static_assert(SCRATCHPAD_HEIGHT >= 0, "SCRATCHPAD_HEIGHT can't be negative."); #endif From 1a04f89df2975e66cadb33874307c852d4b1a4f6 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 18:04:10 +0100 Subject: [PATCH 21/26] Fixed the travis ci build. --- howm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/howm.c b/howm.c index bd8e5e7..542a108 100644 --- a/howm.c +++ b/howm.c @@ -2765,6 +2765,7 @@ void send_to_scratchpad(const Arg *arg) { UNUSED(arg); Client *c = wss[cw].current; + if (scratchpad || !c) return; From d3bf0d6f63e889587ca58c1f6324456ac14920c3 Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Sun, 28 Sep 2014 18:48:38 +0100 Subject: [PATCH 22/26] Update README.md Added scratchpad docs. --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index a22cb9e..70b13ec 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Contents * [Contributing](CONTRIBUTING.md) * [Configuration](#configuration) * [Rules](#rules) +* [Scratchpad](#scratchpad) * [Motions](#motions) * [Counts](#counts) * [Operators](#operators) @@ -197,6 +198,18 @@ Can be from 0 to 1. #define DELETE_REGISTER_SIZE 5 ``` +* **SCRATCHPAD_WIDTH**: The width of the floating scratchpad window. Read more [here](#scratchpad). + +``` +#define SCRATCHPAD_WIDTH 500 +``` + +* **SCRATCHPAD_HEIGHT**: The height of the floating scratchpad window. Read more [here](#scratchpad). + +``` +#define SCRATCHPAD_HEIGHT 500 +``` + ##Rules Rules can be used to tell howm to open certain applications on different workspaces and with certain properties set. @@ -208,6 +221,12 @@ A rule is made up of the following sections: * **Floating**: Should the client be floating when it is spawned? * **Fullscreen**: Should the client be fullscreen when it is spawned? +##Scratchpad + +The scratchpad is a location to store a single client out of view. When requesting a client back from the scratchpad, it will float in the center of the screen. This is useful for keeping a terminal handy or hiding your music player- only displaying it when it is really needed. + +The size of the scratchpad's client is defined by SCRATCHPAD_WIDTH and SCRATCHPAD_HEIGHT. + ##Motions For a good primer on motions, vim's [documentation](http://vimdoc.sourceforge.net/htmldoc/motion.html) explains them well. From c633f205d9ac1afa213259af1d595e797f9b7e05 Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Sun, 28 Sep 2014 18:52:01 +0100 Subject: [PATCH 23/26] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 70b13ec..771761d 100644 --- a/README.md +++ b/README.md @@ -198,14 +198,13 @@ Can be from 0 to 1. #define DELETE_REGISTER_SIZE 5 ``` -* **SCRATCHPAD_WIDTH**: The width of the floating scratchpad window. Read more [here](#scratchpad). +* **SCRATCHPAD_WIDTH**: The width of the floating scratchpad window. ``` #define SCRATCHPAD_WIDTH 500 ``` -* **SCRATCHPAD_HEIGHT**: The height of the floating scratchpad window. Read more [here](#scratchpad). - +* **SCRATCHPAD_HEIGHT**: The height of the floating scratchpad window. ``` #define SCRATCHPAD_HEIGHT 500 ``` From 72a175e739b2b5799dad0761a6e641fedac8e616 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 19:22:51 +0100 Subject: [PATCH 24/26] Another try at IRC notifications... --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 67536c7..71820c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_script: - chmod +x checkpatch.pl script: make debug && make check notifications: - irc: "irc.freenode.net#howm" + irc: "irc.freenode.org#howm" From d5f465137088f6dd54c26978a989b52096d52496 Mon Sep 17 00:00:00 2001 From: HarveyHunt Date: Sun, 28 Sep 2014 19:37:14 +0100 Subject: [PATCH 25/26] Changed travis-ci IRC message. --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 71820c0..33b6c83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,9 @@ before_script: - chmod +x checkpatch.pl script: make debug && make check notifications: - irc: "irc.freenode.org#howm" + irc: + channels: + - "irc.freenode.org#howm" + template: + - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}" + - "Build details : %{build_url}" From 8f431cf1c053a7c8479080317ea4e0a61f264d9b Mon Sep 17 00:00:00 2001 From: Harvey Hunt Date: Mon, 29 Sep 2014 12:49:17 +0100 Subject: [PATCH 26/26] Removed some dead code. --- howm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/howm.c b/howm.c index f46d79a..66b700c 100644 --- a/howm.c +++ b/howm.c @@ -726,10 +726,6 @@ void map_event(xcb_generic_event_t *ev) * @brief Search workspaces for a window, returning the client that it belongs * to. * - * During searching, the current workspace is changed so that all workspaces - * can be searched. Upon finding the client, the original workspace is - * restored. - * * @param win A valid XCB window that is used when searching all clients across * all desktops. * @@ -738,14 +734,12 @@ void map_event(xcb_generic_event_t *ev) Client *find_client_by_win(xcb_window_t win) { bool found; - int w = 1, cur_ws = cw; + int w = 1; Client *c = NULL; for (found = false; w <= WORKSPACES && !found; w++) for (c = wss[w].head; c && !(found = (win == c->win)); c = c->next) ; - if (cur_ws != w) - cw = cur_ws; return c; }