A tiling window manager

Rip out groups

These were only really useful before vscreens and now having both
just adds a useless layer in between frames and vscreens.

Add vscreen names, along with a vrename command. vscreens can now
be referred to (by vmove, etc.) by their name or number.

+723 -1331
+109 -301
actions.c
··· 44 arg_KEYMAP, 45 arg_KEY, 46 arg_GRAVITY, 47 - arg_GROUP, 48 arg_HOOK, 49 arg_VARIABLE, 50 arg_RAW, ··· 56 float fnumber; 57 rp_window *win; 58 rp_keymap *keymap; 59 - rp_group *group; 60 struct list_head *hook; 61 struct set_var *variable; 62 struct rp_key *key; ··· 200 static cmdret *cmd_focusup(int interactive, struct cmdarg **args); 201 static cmdret *cmd_frestore(int interactive, struct cmdarg **args); 202 static cmdret *cmd_fselect(int interactive, struct cmdarg **args); 203 - static cmdret *cmd_gdelete(int interactive, struct cmdarg **args); 204 static cmdret *cmd_getenv(int interactive, struct cmdarg **args); 205 static cmdret *cmd_getsel(int interactive, struct cmdarg **args); 206 - static cmdret *cmd_gmerge(int interactive, struct cmdarg **args); 207 - static cmdret *cmd_gmove(int interactive, struct cmdarg **args); 208 - static cmdret *cmd_gnew(int interactive, struct cmdarg **args); 209 - static cmdret *cmd_gnewbg(int interactive, struct cmdarg **args); 210 - static cmdret *cmd_gnext(int interactive, struct cmdarg **args); 211 - static cmdret *cmd_gnumber(int interactive, struct cmdarg **args); 212 - static cmdret *cmd_gother(int interactive, struct cmdarg **args); 213 - static cmdret *cmd_gprev(int interactive, struct cmdarg **args); 214 static cmdret *cmd_gravity(int interactive, struct cmdarg **args); 215 - static cmdret *cmd_grename(int interactive, struct cmdarg **args); 216 - static cmdret *cmd_groups(int interactive, struct cmdarg **args); 217 - static cmdret *cmd_gselect(int interactive, struct cmdarg **args); 218 static cmdret *cmd_h_split(int interactive, struct cmdarg **args); 219 static cmdret *cmd_help(int interactive, struct cmdarg **args); 220 static cmdret *cmd_inext(int interactive, struct cmdarg **args); ··· 274 static cmdret *cmd_verbexec(int interactive, struct cmdarg **args); 275 static cmdret *cmd_version(int interactive, struct cmdarg **args); 276 static cmdret *cmd_vmove(int interactive, struct cmdarg **args); 277 static cmdret *cmd_vselect(int interactive, struct cmdarg **args); 278 static cmdret *cmd_windows(int interactive, struct cmdarg **args); 279 ··· 460 "Frames: ", arg_REST); 461 add_command("fselect", cmd_fselect, 1, 1, 1, 462 "", arg_FRAME); 463 - add_command("gdelete", cmd_gdelete, 1, 0, 0, 464 - "Group:", arg_GROUP); 465 add_command("getenv", cmd_getenv, 1, 1, 1, 466 "Variable: ", arg_STRING); 467 add_command("getsel", cmd_getsel, 0, 0, 0); 468 - add_command("gmerge", cmd_gmerge, 1, 1, 1, 469 - "Group: ", arg_GROUP); 470 - add_command("gmove", cmd_gmove, 1, 1, 1, 471 - "Group: ", arg_GROUP); 472 - add_command("gnew", cmd_gnew, 1, 1, 1, 473 - "Name: ", arg_STRING); 474 - add_command("gnewbg", cmd_gnewbg, 1, 1, 1, 475 - "Name: ", arg_STRING); 476 - add_command("gnext", cmd_gnext, 0, 0, 0); 477 - add_command("gnumber", cmd_gnumber, 2, 1, 1, 478 - "Number: ", arg_NUMBER, 479 - "Number: ", arg_NUMBER); 480 - add_command("gother", cmd_gother, 0, 0, 0); 481 - add_command("gprev", cmd_gprev, 0, 0, 0); 482 add_command("gravity", cmd_gravity, 1, 0, 0, 483 "Gravity: ", arg_GRAVITY); 484 - add_command("grename", cmd_grename, 1, 1, 1, 485 - "Change group name to: ", arg_REST); 486 - add_command("groups", cmd_groups, 0, 0, 0); 487 - add_command("gselect", cmd_gselect, 1, 1, 1, 488 - "Group: ", arg_GROUP); 489 add_command("help", cmd_help, 1, 0, 0, 490 "Keymap: ", arg_KEYMAP); 491 add_command("hsplit", cmd_h_split, 1, 0, 0, ··· 584 "/bin/sh -c ", arg_SHELLCMD); 585 add_command("version", cmd_version, 0, 0, 0); 586 add_command("vmove", cmd_vmove, 1, 1, 1, 587 - "Virtual Screen: ", arg_NUMBER); 588 add_command("vselect", cmd_vselect, 1, 1, 1, 589 - "Virtual Screen: ", arg_NUMBER); 590 add_command("vsplit", cmd_v_split, 1, 0, 0, 591 "Split: ", arg_STRING); 592 add_command("windows", cmd_windows, 1, 0, 0, ··· 1367 { 1368 rp_window *cur, *win; 1369 cur = current_window(); 1370 - win = group_prev_window(rp_current_group, cur); 1371 1372 if (win) 1373 set_active_window(win); ··· 1399 { 1400 rp_window *cur, *win; 1401 cur = current_window(); 1402 - win = group_next_window(rp_current_group, cur); 1403 1404 if (win) 1405 set_active_window(win); ··· 1432 rp_window *w; 1433 1434 /* w = find_window_other (); */ 1435 - w = group_last_window(rp_current_vscreen->current_group); 1436 if (!w) 1437 return cmdret_new(RET_FAILURE, "%s", MESSAGE_NO_OTHER_WINDOW); 1438 ··· 1503 INIT_LIST_HEAD(list); 1504 1505 /* Gather the names of all the windows. */ 1506 - list_for_each_entry(cur, &rp_current_group->mapped_windows, node) { 1507 struct sbuf *name; 1508 1509 name = sbuf_new(0); ··· 1543 ret = cmdret_new(RET_SUCCESS, NULL); 1544 } else if ((n = string_to_positive_int(str)) >= 0) { 1545 /* try by number */ 1546 - rp_window_elem *elem = group_find_window_by_number( 1547 - rp_current_group, n); 1548 1549 if (elem) { 1550 goto_window(elem->win); ··· 1764 } 1765 1766 static struct list_head * 1767 - group_completions(char *str) 1768 { 1769 - struct list_head *list; 1770 - rp_group *cur; 1771 1772 - /* Initialize our list. */ 1773 - list = xmalloc(sizeof(struct list_head)); 1774 - INIT_LIST_HEAD(list); 1775 1776 - /* Grab all the group names. */ 1777 - list_for_each_entry(cur, &(rp_current_screen->current_vscreen->groups), 1778 - node) { 1779 - struct sbuf *s; 1780 1781 - s = sbuf_new(0); 1782 - /* 1783 - * A group may not have a name, so if it doesn't, use it's 1784 - * number. 1785 - */ 1786 - if (cur->name) { 1787 - sbuf_copy(s, cur->name); 1788 - } else { 1789 - sbuf_printf(s, "%d", cur->number); 1790 - } 1791 1792 - list_add_tail(&s->node, list); 1793 - } 1794 1795 - return list; 1796 } 1797 1798 static struct list_head * ··· 2061 if (name) { 2062 /* try by number */ 2063 if ((n = string_to_positive_int(name)) >= 0) { 2064 - rp_window_elem *elem = group_find_window_by_number( 2065 - rp_current_group, n); 2066 if (elem) 2067 win = elem->win; 2068 } else { ··· 2151 } 2152 2153 /* 2154 - * Given a string, find a matching group. First check if the string exactly 2155 - * matches a group name, then check if it is a number & lastly check if it 2156 - * partially matches the name of a group. 2157 */ 2158 - static rp_group * 2159 - find_group(char *str) 2160 { 2161 - rp_group *group; 2162 int n; 2163 2164 - /* Check if the user typed a group number. */ 2165 n = string_to_positive_int(str); 2166 if (n >= 0) { 2167 - group = groups_find_group_by_number(rp_current_vscreen, n); 2168 - if (group) 2169 - return group; 2170 } 2171 2172 /* Exact matches are special cases. */ 2173 - if ((group = groups_find_group_by_name(rp_current_vscreen, str, 1))) 2174 - return group; 2175 2176 - group = groups_find_group_by_name(rp_current_vscreen, str, 0); 2177 - return group; 2178 } 2179 2180 static cmdret * 2181 - read_group(struct argspec *spec, struct sbuf *s, struct cmdarg **arg) 2182 { 2183 char *input; 2184 2185 if (s) 2186 input = xstrdup(sbuf_get(s)); 2187 else 2188 - input = get_input(spec->prompt, hist_GROUP, group_completions); 2189 2190 if (input) { 2191 - rp_group *g = find_group(input); 2192 - 2193 - if (g) { 2194 *arg = xmalloc(sizeof(struct cmdarg)); 2195 - (*arg)->type = arg_GROUP; 2196 - (*arg)->arg.group = g; 2197 (*arg)->string = input; 2198 return NULL; 2199 } 2200 2201 - cmdret *ret = cmdret_new(RET_FAILURE, "unknown group '%s'", 2202 input); 2203 free(input); 2204 return ret; ··· 2283 list = xmalloc(sizeof(struct list_head)); 2284 INIT_LIST_HEAD(list); 2285 2286 - /* Grab all the group names. */ 2287 list_for_each_entry(cur, &set_vars, node) { 2288 struct sbuf *s; 2289 ··· 2401 case arg_FRAME: 2402 ret = read_frame(s, arg); 2403 break; 2404 - case arg_GROUP: 2405 - ret = read_group(spec, s, arg); 2406 break; 2407 case arg_HOOK: 2408 ret = read_hook(spec, s, arg); ··· 2615 case arg_SHELLCMD: 2616 case arg_KEYMAP: 2617 case arg_GRAVITY: 2618 - case arg_GROUP: 2619 case arg_HOOK: 2620 case arg_VARIABLE: 2621 case arg_RAW: ··· 2859 child->pid = pid; 2860 child->terminated = 0; 2861 child->frame = frame; 2862 - child->group = rp_current_group; 2863 child->vscreen = rp_current_vscreen; 2864 child->screen = rp_current_screen; 2865 child->window_mapped = 0; ··· 2886 /* Gather the args. */ 2887 new_number = ARG(0, number); 2888 if (args[1]) 2889 - win = group_find_window_by_number(rp_current_group, 2890 ARG(1, number)); 2891 - else { 2892 - rp_group *g = rp_current_group; 2893 - win = group_find_window(&g->mapped_windows, current_window()); 2894 - } 2895 2896 /* Make the switch. */ 2897 if (new_number >= 0 && win) { 2898 /* Find other window with same number and give it old number. */ 2899 - other_win = group_find_window_by_number(rp_current_group, 2900 new_number); 2901 if (other_win != NULL) { 2902 old_number = win->number; 2903 other_win->number = old_number; 2904 2905 /* Resort the window in the list */ 2906 - group_resort_window(rp_current_group, other_win); 2907 } else { 2908 - numset_release(rp_current_group->numset, win->number); 2909 } 2910 2911 win->number = new_number; 2912 - numset_add_num(rp_current_group->numset, new_number); 2913 2914 /* resort the the window in the list */ 2915 - group_resort_window(rp_current_group, win); 2916 2917 /* Update the window list. */ 2918 update_window_names(win->win->vscr->screen, ··· 4365 if (current_window() != NULL) { 4366 rp_window *win = current_window(); 4367 rp_window_elem *win_elem; 4368 - win_elem = group_find_window(&(rp_current_group->mapped_windows), 4369 win); 4370 if (!win_elem) 4371 - win_elem = group_find_window( 4372 - &(rp_current_group->unmapped_windows), win); 4373 - 4374 - if (!win_elem) { 4375 - rp_group *g = groups_find_group_by_window(win); 4376 - if (g != NULL) 4377 - win_elem = group_find_window(&g->mapped_windows, 4378 - win); 4379 - if (!win_elem && g != NULL) 4380 - win_elem = group_find_window( 4381 - &g->unmapped_windows, win); 4382 - } 4383 4384 if (win_elem) { 4385 char *s; ··· 4963 } 4964 4965 cmdret * 4966 - cmd_gnext(int interactive, struct cmdarg **args) 4967 - { 4968 - set_current_group(group_next_group(rp_current_vscreen)); 4969 - return cmdret_new(RET_SUCCESS, NULL); 4970 - } 4971 - 4972 - cmdret * 4973 - cmd_gprev(int interactive, struct cmdarg **args) 4974 - { 4975 - set_current_group(group_prev_group(rp_current_vscreen)); 4976 - return cmdret_new(RET_SUCCESS, NULL); 4977 - } 4978 - 4979 - cmdret * 4980 - cmd_gother(int interactive, struct cmdarg **args) 4981 { 4982 - set_current_group(group_last_group(rp_current_vscreen)); 4983 - return cmdret_new(RET_SUCCESS, NULL); 4984 - } 4985 4986 - cmdret * 4987 - cmd_gnew(int interactive, struct cmdarg **args) 4988 - { 4989 - if (groups_find_group_by_name(rp_current_vscreen, ARG_STRING(0), 1)) 4990 - return cmdret_new(RET_FAILURE, "gnew: group already exists"); 4991 - set_current_group(group_add_new_group(rp_current_vscreen, ARG_STRING(0))); 4992 - return cmdret_new(RET_SUCCESS, NULL); 4993 - } 4994 4995 - cmdret * 4996 - cmd_gnewbg(int interactive, struct cmdarg **args) 4997 - { 4998 - if (groups_find_group_by_name(rp_current_vscreen, ARG_STRING(0), 1)) 4999 - return cmdret_new(RET_FAILURE, "gnewbg: group already exists"); 5000 - group_add_new_group(rp_current_vscreen, ARG_STRING(0)); 5001 return cmdret_new(RET_SUCCESS, NULL); 5002 } 5003 5004 cmdret * 5005 - cmd_gnumber(int interactive, struct cmdarg **args) 5006 { 5007 - int old_number, new_number; 5008 - rp_group *other_g, *g; 5009 5010 - struct numset *g_numset = group_get_numset(rp_current_vscreen); 5011 - 5012 - /* Gather the args. */ 5013 - new_number = ARG(0, number); 5014 - if (args[1]) 5015 - g = groups_find_group_by_number(rp_current_vscreen, 5016 - ARG(1, number)); 5017 else 5018 - g = rp_current_group; 5019 5020 - /* Make the switch. */ 5021 - if (new_number >= 0 && g) { 5022 - /* Find other window with same number and give it old number. */ 5023 - other_g = groups_find_group_by_number(rp_current_vscreen, 5024 - new_number); 5025 - if (other_g != NULL) { 5026 - old_number = g->number; 5027 - other_g->number = old_number; 5028 - 5029 - /* Resort the window in the list */ 5030 - group_resort_group(other_g); 5031 - } else { 5032 - numset_release(g_numset, g->number); 5033 - } 5034 - 5035 - g->number = new_number; 5036 - numset_add_num(g_numset, new_number); 5037 - 5038 - /* resort the the window in the list */ 5039 - group_resort_group(g); 5040 - 5041 - /* Update the group list. */ 5042 - update_group_names(rp_current_screen); 5043 - } 5044 return cmdret_new(RET_SUCCESS, NULL); 5045 } 5046 5047 cmdret * 5048 - cmd_grename(int interactive, struct cmdarg **args) 5049 { 5050 - if (groups_find_group_by_name(rp_current_vscreen, ARG_STRING(0), 1)) 5051 - return cmdret_new(RET_FAILURE, "grename: duplicate group name"); 5052 - group_rename(rp_current_group, ARG_STRING(0)); 5053 - 5054 - /* Update the group list. */ 5055 - update_group_names(rp_current_screen); 5056 - 5057 - return cmdret_new(RET_SUCCESS, NULL); 5058 - } 5059 - 5060 - cmdret * 5061 - cmd_gselect(int interactive, struct cmdarg **args) 5062 - { 5063 - rp_group *g; 5064 - 5065 - g = find_group(ARG_STRING(0)); 5066 - 5067 - if (g) 5068 - set_current_group(g); 5069 - else 5070 - return cmd_groups(interactive, NULL); 5071 - 5072 - return cmdret_new(RET_SUCCESS, NULL); 5073 - } 5074 - 5075 - /* Show all the groups, with the current one highlighted. */ 5076 - cmdret * 5077 - cmd_groups(int interactive, struct cmdarg **args) 5078 - { 5079 - struct sbuf *group_list = NULL; 5080 int dummy; 5081 5082 if (interactive) { 5083 - show_group_bar(rp_current_screen); 5084 return cmdret_new(RET_SUCCESS, NULL); 5085 } else { 5086 cmdret *ret; 5087 5088 - group_list = sbuf_new(0); 5089 - get_group_list(rp_current_vscreen, "\n", group_list, &dummy, 5090 &dummy); 5091 - ret = cmdret_new(RET_SUCCESS, "%s", sbuf_get(group_list)); 5092 - sbuf_free(group_list); 5093 return ret; 5094 } 5095 - } 5096 - 5097 - /* Move a window to a different group. */ 5098 - cmdret * 5099 - cmd_gmove(int interactive, struct cmdarg **args) 5100 - { 5101 - if (current_window() == NULL) 5102 - return cmdret_new(RET_FAILURE, "gmove: no focused window"); 5103 - 5104 - group_move_window(ARG(0, group), current_window()); 5105 - return cmdret_new(RET_SUCCESS, NULL); 5106 - } 5107 - 5108 - cmdret * 5109 - cmd_gmerge(int interactive, struct cmdarg **args) 5110 - { 5111 - groups_merge(ARG(0, group), rp_current_group); 5112 - return cmdret_new(RET_SUCCESS, NULL); 5113 } 5114 5115 cmdret * ··· 5176 } 5177 5178 cmdret * 5179 - cmd_gdelete(int interactive, struct cmdarg **args) 5180 - { 5181 - rp_group *g; 5182 - 5183 - if (args[0] == NULL) 5184 - g = rp_current_group; 5185 - else 5186 - g = ARG(0, group); 5187 - 5188 - switch (group_delete_group(g)) { 5189 - case GROUP_DELETE_GROUP_OK: 5190 - break; 5191 - case GROUP_DELETE_GROUP_NONEMPTY: 5192 - return cmdret_new(RET_FAILURE, 5193 - "gdelete: non-empty group"); 5194 - break; 5195 - case GROUP_DELETE_LAST_GROUP: 5196 - return cmdret_new(RET_FAILURE, 5197 - "gdelete: cannot delete the sole group"); 5198 - break; 5199 - default: 5200 - return cmdret_new(RET_FAILURE, 5201 - "gdelete: unknown return code (this shouldn't happen)"); 5202 - } 5203 - 5204 - return cmdret_new(RET_SUCCESS, NULL); 5205 - } 5206 - 5207 - cmdret * 5208 cmd_readkey(int interactive, struct cmdarg **args) 5209 { 5210 char *keysym_name; ··· 5550 return cmd_next(interactive, args); 5551 5552 /* CUR !in cycle list, so LAST marks last node. */ 5553 - last = group_prev_window(rp_current_group, cur); 5554 5555 if (last) 5556 - for (win = group_next_window(rp_current_group, cur); 5557 win; 5558 - win = group_next_window(rp_current_group, win)) { 5559 if (win->res_class 5560 && strcmp(cur->res_class, win->res_class)) { 5561 set_active_window_force(win); ··· 5578 return cmd_next(interactive, args); 5579 5580 /* CUR !in cycle list, so LAST marks last node. */ 5581 - last = group_next_window(rp_current_group, cur); 5582 5583 if (last) 5584 - for (win = group_prev_window(rp_current_group, cur); 5585 win; 5586 - win = group_prev_window(rp_current_group, win)) { 5587 if (win->res_class 5588 && strcmp(cur->res_class, win->res_class)) { 5589 set_active_window_force(win); ··· 5606 return cmd_next(interactive, args); 5607 5608 /* CUR !in cycle list, so LAST marks last node. */ 5609 - last = group_prev_window(rp_current_group, cur); 5610 5611 if (last) 5612 - for (win = group_next_window(rp_current_group, cur); 5613 win; 5614 - win = group_next_window(rp_current_group, win)) { 5615 if (win->res_class 5616 && !strcmp(cur->res_class, win->res_class)) { 5617 set_active_window_force(win); ··· 5634 return cmd_next(interactive, args); 5635 5636 /* CUR !in cycle list, so LAST marks last node. */ 5637 - last = group_next_window(rp_current_group, cur); 5638 5639 if (last) 5640 - for (win = group_prev_window(rp_current_group, cur); 5641 win; 5642 - win = group_prev_window(rp_current_group, win)) { 5643 if (win->res_class 5644 && !strcmp(cur->res_class, win->res_class)) { 5645 set_active_window_force(win); ··· 5659 5660 cur = current_window(); 5661 if (cur) 5662 - w = group_last_window_by_class(rp_current_group, cur->res_class); 5663 5664 if (!w) 5665 return cmdret_new(RET_FAILURE, "%s", MESSAGE_NO_OTHER_WINDOW); ··· 5676 5677 cur = current_window(); 5678 if (cur) 5679 - w = group_last_window_by_class_complement(rp_current_group, 5680 cur->res_class); 5681 5682 if (!w) ··· 5864 5865 n = string_to_positive_int(ARG_STRING(0)); 5866 if (n >= 0) { 5867 - v = vscreens_find_vscreen_by_number(rp_current_screen, n); 5868 if (v) { 5869 vscreen_move_window(v, w); 5870 set_current_vscreen(v); ··· 5874 } 5875 5876 return cmdret_new(RET_FAILURE, "vmove: invalid virtual screen"); 5877 - } 5878 - 5879 - cmdret * 5880 - cmd_vselect(int interactive, struct cmdarg **args) 5881 - { 5882 - rp_vscreen *v; 5883 - int n; 5884 - 5885 - n = string_to_positive_int(ARG_STRING(0)); 5886 - if (n >= 0) { 5887 - v = vscreens_find_vscreen_by_number(rp_current_screen, n); 5888 - if (v) { 5889 - set_current_vscreen(v); 5890 - return cmdret_new(RET_SUCCESS, NULL); 5891 - } 5892 - } 5893 - 5894 - return cmdret_new(RET_FAILURE, "vselect: invalid virtual screen"); 5895 } 5896 5897 cmdret *
··· 44 arg_KEYMAP, 45 arg_KEY, 46 arg_GRAVITY, 47 + arg_VSCREEN, 48 arg_HOOK, 49 arg_VARIABLE, 50 arg_RAW, ··· 56 float fnumber; 57 rp_window *win; 58 rp_keymap *keymap; 59 + rp_vscreen *vscreen; 60 struct list_head *hook; 61 struct set_var *variable; 62 struct rp_key *key; ··· 200 static cmdret *cmd_focusup(int interactive, struct cmdarg **args); 201 static cmdret *cmd_frestore(int interactive, struct cmdarg **args); 202 static cmdret *cmd_fselect(int interactive, struct cmdarg **args); 203 static cmdret *cmd_getenv(int interactive, struct cmdarg **args); 204 static cmdret *cmd_getsel(int interactive, struct cmdarg **args); 205 static cmdret *cmd_gravity(int interactive, struct cmdarg **args); 206 static cmdret *cmd_h_split(int interactive, struct cmdarg **args); 207 static cmdret *cmd_help(int interactive, struct cmdarg **args); 208 static cmdret *cmd_inext(int interactive, struct cmdarg **args); ··· 262 static cmdret *cmd_verbexec(int interactive, struct cmdarg **args); 263 static cmdret *cmd_version(int interactive, struct cmdarg **args); 264 static cmdret *cmd_vmove(int interactive, struct cmdarg **args); 265 + static cmdret *cmd_vrename(int interactive, struct cmdarg **args); 266 + static cmdret *cmd_vscreens(int interactive, struct cmdarg **args); 267 static cmdret *cmd_vselect(int interactive, struct cmdarg **args); 268 static cmdret *cmd_windows(int interactive, struct cmdarg **args); 269 ··· 450 "Frames: ", arg_REST); 451 add_command("fselect", cmd_fselect, 1, 1, 1, 452 "", arg_FRAME); 453 add_command("getenv", cmd_getenv, 1, 1, 1, 454 "Variable: ", arg_STRING); 455 add_command("getsel", cmd_getsel, 0, 0, 0); 456 add_command("gravity", cmd_gravity, 1, 0, 0, 457 "Gravity: ", arg_GRAVITY); 458 add_command("help", cmd_help, 1, 0, 0, 459 "Keymap: ", arg_KEYMAP); 460 add_command("hsplit", cmd_h_split, 1, 0, 0, ··· 553 "/bin/sh -c ", arg_SHELLCMD); 554 add_command("version", cmd_version, 0, 0, 0); 555 add_command("vmove", cmd_vmove, 1, 1, 1, 556 + "Virtual Screen: ", arg_VSCREEN); 557 + add_command("vrename", cmd_vrename, 1, 1, 1, 558 + "Change virtual screen name to: ", arg_REST); 559 + add_command("vscreens", cmd_vscreens, 0, 0, 0); 560 add_command("vselect", cmd_vselect, 1, 1, 1, 561 + "Virtual Screen: ", arg_VSCREEN); 562 add_command("vsplit", cmd_v_split, 1, 0, 0, 563 "Split: ", arg_STRING); 564 add_command("windows", cmd_windows, 1, 0, 0, ··· 1339 { 1340 rp_window *cur, *win; 1341 cur = current_window(); 1342 + win = vscreen_prev_window(rp_current_vscreen, cur); 1343 1344 if (win) 1345 set_active_window(win); ··· 1371 { 1372 rp_window *cur, *win; 1373 cur = current_window(); 1374 + win = vscreen_next_window(rp_current_vscreen, cur); 1375 1376 if (win) 1377 set_active_window(win); ··· 1404 rp_window *w; 1405 1406 /* w = find_window_other (); */ 1407 + w = vscreen_last_window(rp_current_vscreen); 1408 if (!w) 1409 return cmdret_new(RET_FAILURE, "%s", MESSAGE_NO_OTHER_WINDOW); 1410 ··· 1475 INIT_LIST_HEAD(list); 1476 1477 /* Gather the names of all the windows. */ 1478 + list_for_each_entry(cur, &rp_current_vscreen->mapped_windows, node) { 1479 struct sbuf *name; 1480 1481 name = sbuf_new(0); ··· 1515 ret = cmdret_new(RET_SUCCESS, NULL); 1516 } else if ((n = string_to_positive_int(str)) >= 0) { 1517 /* try by number */ 1518 + rp_window_elem *elem = vscreen_find_window_by_number( 1519 + rp_current_vscreen, n); 1520 1521 if (elem) { 1522 goto_window(elem->win); ··· 1736 } 1737 1738 static struct list_head * 1739 + vscreen_completions(char *str) 1740 { 1741 + struct list_head *list; 1742 + rp_vscreen *cur; 1743 1744 + /* Initialize our list. */ 1745 + list = xmalloc(sizeof(struct list_head)); 1746 + INIT_LIST_HEAD(list); 1747 1748 + /* Grab all the vscreen names. */ 1749 + list_for_each_entry(cur, &(rp_current_screen)->vscreens, node) { 1750 + struct sbuf *s; 1751 1752 + s = sbuf_new(0); 1753 + if (cur->name) { 1754 + sbuf_copy(s, cur->name); 1755 + } else { 1756 + sbuf_printf(s, "%d", cur->number); 1757 + } 1758 1759 + list_add_tail(&s->node, list); 1760 + } 1761 1762 + return list; 1763 } 1764 1765 static struct list_head * ··· 2028 if (name) { 2029 /* try by number */ 2030 if ((n = string_to_positive_int(name)) >= 0) { 2031 + rp_window_elem *elem = vscreen_find_window_by_number( 2032 + rp_current_vscreen, n); 2033 if (elem) 2034 win = elem->win; 2035 } else { ··· 2118 } 2119 2120 /* 2121 + * Given a string, find a matching vscreen. First check if the string exactly 2122 + * matches a vscreen name, then check if it is a number & lastly check if it 2123 + * partially matches the name of a vscreen. 2124 */ 2125 + static rp_vscreen * 2126 + find_vscreen(char *str) 2127 { 2128 + rp_vscreen *vscreen; 2129 int n; 2130 2131 + /* Check if the user typed a vsceen number. */ 2132 n = string_to_positive_int(str); 2133 if (n >= 0) { 2134 + vscreen = screen_find_vscreen_by_number(rp_current_screen, n); 2135 + if (vscreen) 2136 + return vscreen; 2137 } 2138 2139 /* Exact matches are special cases. */ 2140 + if ((vscreen = screen_find_vscreen_by_name(rp_current_screen, str, 1))) 2141 + return vscreen; 2142 2143 + vscreen = screen_find_vscreen_by_name(rp_current_screen, str, 0); 2144 + return vscreen; 2145 } 2146 2147 static cmdret * 2148 + read_vscreen(struct argspec *spec, struct sbuf *s, struct cmdarg **arg) 2149 { 2150 char *input; 2151 2152 if (s) 2153 input = xstrdup(sbuf_get(s)); 2154 else 2155 + input = get_input(spec->prompt, hist_VSCREEN, 2156 + vscreen_completions); 2157 2158 if (input) { 2159 + rp_vscreen *v = find_vscreen(input); 2160 + if (v) { 2161 *arg = xmalloc(sizeof(struct cmdarg)); 2162 + (*arg)->type = arg_VSCREEN; 2163 + (*arg)->arg.vscreen = v; 2164 (*arg)->string = input; 2165 return NULL; 2166 } 2167 2168 + cmdret *ret = cmdret_new(RET_FAILURE, "unknown vscreen '%s'", 2169 input); 2170 free(input); 2171 return ret; ··· 2250 list = xmalloc(sizeof(struct list_head)); 2251 INIT_LIST_HEAD(list); 2252 2253 + /* Grab all the vscreen names. */ 2254 list_for_each_entry(cur, &set_vars, node) { 2255 struct sbuf *s; 2256 ··· 2368 case arg_FRAME: 2369 ret = read_frame(s, arg); 2370 break; 2371 + case arg_VSCREEN: 2372 + ret = read_vscreen(spec, s, arg); 2373 break; 2374 case arg_HOOK: 2375 ret = read_hook(spec, s, arg); ··· 2582 case arg_SHELLCMD: 2583 case arg_KEYMAP: 2584 case arg_GRAVITY: 2585 + case arg_VSCREEN: 2586 case arg_HOOK: 2587 case arg_VARIABLE: 2588 case arg_RAW: ··· 2826 child->pid = pid; 2827 child->terminated = 0; 2828 child->frame = frame; 2829 child->vscreen = rp_current_vscreen; 2830 child->screen = rp_current_screen; 2831 child->window_mapped = 0; ··· 2852 /* Gather the args. */ 2853 new_number = ARG(0, number); 2854 if (args[1]) 2855 + win = vscreen_find_window_by_number(rp_current_vscreen, 2856 ARG(1, number)); 2857 + else 2858 + win = vscreen_find_window(&rp_current_vscreen->mapped_windows, 2859 + current_window()); 2860 2861 /* Make the switch. */ 2862 if (new_number >= 0 && win) { 2863 /* Find other window with same number and give it old number. */ 2864 + other_win = vscreen_find_window_by_number(rp_current_vscreen, 2865 new_number); 2866 if (other_win != NULL) { 2867 old_number = win->number; 2868 other_win->number = old_number; 2869 2870 /* Resort the window in the list */ 2871 + vscreen_resort_window(rp_current_vscreen, other_win); 2872 } else { 2873 + numset_release(rp_current_vscreen->numset, win->number); 2874 } 2875 2876 win->number = new_number; 2877 + numset_add_num(rp_current_vscreen->numset, new_number); 2878 2879 /* resort the the window in the list */ 2880 + vscreen_resort_window(rp_current_vscreen, win); 2881 2882 /* Update the window list. */ 2883 update_window_names(win->win->vscr->screen, ··· 4330 if (current_window() != NULL) { 4331 rp_window *win = current_window(); 4332 rp_window_elem *win_elem; 4333 + win_elem = vscreen_find_window(&rp_current_vscreen->mapped_windows, 4334 win); 4335 if (!win_elem) 4336 + win_elem = vscreen_find_window( 4337 + &rp_current_vscreen->unmapped_windows, win); 4338 4339 if (win_elem) { 4340 char *s; ··· 4918 } 4919 4920 cmdret * 4921 + cmd_vrename(int interactive, struct cmdarg **args) 4922 { 4923 + if (screen_find_vscreen_by_name(rp_current_screen, ARG_STRING(0), 1)) 4924 + return cmdret_new(RET_FAILURE, "vrename: duplicate vscreen name"); 4925 + vscreen_rename(rp_current_vscreen, ARG_STRING(0)); 4926 4927 + /* Update the vscreen list. */ 4928 + update_vscreen_names(rp_current_screen); 4929 4930 return cmdret_new(RET_SUCCESS, NULL); 4931 } 4932 4933 cmdret * 4934 + cmd_vselect(int interactive, struct cmdarg **args) 4935 { 4936 + rp_vscreen *v; 4937 4938 + v = find_vscreen(ARG_STRING(0)); 4939 + if (v) 4940 + set_current_vscreen(v); 4941 else 4942 + return cmd_vscreens(interactive, NULL); 4943 4944 return cmdret_new(RET_SUCCESS, NULL); 4945 } 4946 4947 + /* Show all the vscreens, with the current one highlighted. */ 4948 cmdret * 4949 + cmd_vscreens(int interactive, struct cmdarg **args) 4950 { 4951 + struct sbuf *vscreen_list = NULL; 4952 int dummy; 4953 4954 if (interactive) { 4955 + show_vscreen_bar(rp_current_screen); 4956 return cmdret_new(RET_SUCCESS, NULL); 4957 } else { 4958 cmdret *ret; 4959 4960 + vscreen_list = sbuf_new(0); 4961 + get_vscreen_list(rp_current_screen, "\n", vscreen_list, &dummy, 4962 &dummy); 4963 + ret = cmdret_new(RET_SUCCESS, "%s", sbuf_get(vscreen_list)); 4964 + sbuf_free(vscreen_list); 4965 return ret; 4966 } 4967 } 4968 4969 cmdret * ··· 5030 } 5031 5032 cmdret * 5033 cmd_readkey(int interactive, struct cmdarg **args) 5034 { 5035 char *keysym_name; ··· 5375 return cmd_next(interactive, args); 5376 5377 /* CUR !in cycle list, so LAST marks last node. */ 5378 + last = vscreen_prev_window(rp_current_vscreen, cur); 5379 5380 if (last) 5381 + for (win = vscreen_next_window(rp_current_vscreen, cur); 5382 win; 5383 + win = vscreen_next_window(rp_current_vscreen, win)) { 5384 if (win->res_class 5385 && strcmp(cur->res_class, win->res_class)) { 5386 set_active_window_force(win); ··· 5403 return cmd_next(interactive, args); 5404 5405 /* CUR !in cycle list, so LAST marks last node. */ 5406 + last = vscreen_next_window(rp_current_vscreen, cur); 5407 5408 if (last) 5409 + for (win = vscreen_prev_window(rp_current_vscreen, cur); 5410 win; 5411 + win = vscreen_prev_window(rp_current_vscreen, win)) { 5412 if (win->res_class 5413 && strcmp(cur->res_class, win->res_class)) { 5414 set_active_window_force(win); ··· 5431 return cmd_next(interactive, args); 5432 5433 /* CUR !in cycle list, so LAST marks last node. */ 5434 + last = vscreen_prev_window(rp_current_vscreen, cur); 5435 5436 if (last) 5437 + for (win = vscreen_next_window(rp_current_vscreen, cur); 5438 win; 5439 + win = vscreen_next_window(rp_current_vscreen, win)) { 5440 if (win->res_class 5441 && !strcmp(cur->res_class, win->res_class)) { 5442 set_active_window_force(win); ··· 5459 return cmd_next(interactive, args); 5460 5461 /* CUR !in cycle list, so LAST marks last node. */ 5462 + last = vscreen_next_window(rp_current_vscreen, cur); 5463 5464 if (last) 5465 + for (win = vscreen_prev_window(rp_current_vscreen, cur); 5466 win; 5467 + win = vscreen_prev_window(rp_current_vscreen, win)) { 5468 if (win->res_class 5469 && !strcmp(cur->res_class, win->res_class)) { 5470 set_active_window_force(win); ··· 5484 5485 cur = current_window(); 5486 if (cur) 5487 + w = vscreen_last_window_by_class(rp_current_vscreen, 5488 + cur->res_class); 5489 5490 if (!w) 5491 return cmdret_new(RET_FAILURE, "%s", MESSAGE_NO_OTHER_WINDOW); ··· 5502 5503 cur = current_window(); 5504 if (cur) 5505 + w = vscreen_last_window_by_class_complement(rp_current_vscreen, 5506 cur->res_class); 5507 5508 if (!w) ··· 5690 5691 n = string_to_positive_int(ARG_STRING(0)); 5692 if (n >= 0) { 5693 + v = screen_find_vscreen_by_number(rp_current_screen, n); 5694 if (v) { 5695 vscreen_move_window(v, w); 5696 set_current_vscreen(v); ··· 5700 } 5701 5702 return cmdret_new(RET_FAILURE, "vmove: invalid virtual screen"); 5703 } 5704 5705 cmdret *
+11 -12
bar.c
··· 35 /* Possible values for bar_is_raised status. */ 36 #define BAR_IS_HIDDEN 0 37 #define BAR_IS_WINDOW_LIST 1 38 - #define BAR_IS_GROUP_LIST 2 39 #define BAR_IS_MESSAGE 3 40 #define BAR_IS_STICKY 4 41 ··· 168 reset_alarm(); 169 } 170 171 - /* Show group listing in bar. */ 172 void 173 - show_group_bar(rp_screen *s) 174 { 175 - s->bar_is_raised = BAR_IS_GROUP_LIST; 176 XMapRaised(dpy, s->bar_window); 177 - update_group_names(s); 178 179 /* Switch to the default colormap */ 180 if (current_window()) ··· 272 case BAR_IS_WINDOW_LIST: 273 update_window_names(s, defaults.window_fmt); 274 break; 275 - case BAR_IS_GROUP_LIST: 276 - update_group_names(s); 277 break; 278 case BAR_IS_STICKY: 279 hide_bar(s, 0); ··· 550 * Note that we use marked_message_internal to avoid resetting the alarm. 551 */ 552 void 553 - update_group_names(rp_screen *s) 554 { 555 struct sbuf *bar_buffer; 556 int mark_start = 0; 557 int mark_end = 0; 558 char *delimiter; 559 560 - if (s->bar_is_raised != BAR_IS_GROUP_LIST) 561 return; 562 563 delimiter = (defaults.window_list_style == STYLE_ROW) ? " " : "\n"; 564 565 bar_buffer = sbuf_new(0); 566 567 - get_group_list(s->current_vscreen, delimiter, bar_buffer, &mark_start, 568 - &mark_end); 569 marked_message_internal(sbuf_get(bar_buffer), mark_start, mark_end, 570 - BAR_IS_GROUP_LIST); 571 572 sbuf_free(bar_buffer); 573 }
··· 35 /* Possible values for bar_is_raised status. */ 36 #define BAR_IS_HIDDEN 0 37 #define BAR_IS_WINDOW_LIST 1 38 + #define BAR_IS_VSCREEN_LIST 2 39 #define BAR_IS_MESSAGE 3 40 #define BAR_IS_STICKY 4 41 ··· 168 reset_alarm(); 169 } 170 171 + /* Show vscreen listing in bar. */ 172 void 173 + show_vscreen_bar(rp_screen *s) 174 { 175 + s->bar_is_raised = BAR_IS_VSCREEN_LIST; 176 XMapRaised(dpy, s->bar_window); 177 + update_vscreen_names(s); 178 179 /* Switch to the default colormap */ 180 if (current_window()) ··· 272 case BAR_IS_WINDOW_LIST: 273 update_window_names(s, defaults.window_fmt); 274 break; 275 + case BAR_IS_VSCREEN_LIST: 276 + update_vscreen_names(s); 277 break; 278 case BAR_IS_STICKY: 279 hide_bar(s, 0); ··· 550 * Note that we use marked_message_internal to avoid resetting the alarm. 551 */ 552 void 553 + update_vscreen_names(rp_screen *s) 554 { 555 struct sbuf *bar_buffer; 556 int mark_start = 0; 557 int mark_end = 0; 558 char *delimiter; 559 560 + if (s->bar_is_raised != BAR_IS_VSCREEN_LIST) 561 return; 562 563 delimiter = (defaults.window_list_style == STYLE_ROW) ? " " : "\n"; 564 565 bar_buffer = sbuf_new(0); 566 567 + get_vscreen_list(s, delimiter, bar_buffer, &mark_start, &mark_end); 568 marked_message_internal(sbuf_get(bar_buffer), mark_start, mark_end, 569 + BAR_IS_VSCREEN_LIST); 570 571 sbuf_free(bar_buffer); 572 }
+2 -2
bar.h
··· 24 void init_bar(void); 25 void redraw_sticky_bar_text(rp_screen *s, int force); 26 void update_window_names(rp_screen *s, char *fmt); 27 - void update_group_names(rp_screen *s); 28 void update_bar(rp_screen *s); 29 void show_bar(rp_screen *s, char *fmt); 30 - void show_group_bar(rp_screen *s); 31 void hide_bar(rp_screen *s, int force); 32 int bar_y(rp_screen *s, int height); 33 int bar_x(rp_screen *s, int width);
··· 24 void init_bar(void); 25 void redraw_sticky_bar_text(rp_screen *s, int force); 26 void update_window_names(rp_screen *s, char *fmt); 27 + void update_vscreen_names(rp_screen *s); 28 void update_bar(rp_screen *s); 29 void show_bar(rp_screen *s, char *fmt); 30 + void show_vscreen_bar(rp_screen *s); 31 void hide_bar(rp_screen *s, int force); 32 int bar_y(rp_screen *s, int height); 33 int bar_x(rp_screen *s, int width);
+2 -2
config.h
··· 100 */ 101 #define IGNORE_BADWINDOW 1 102 103 - /* This is the name of the first group that is created. */ 104 - #define DEFAULT_GROUP_NAME "default" 105 106 /* Maximum allowed history size */ 107 #define MAX_HISTORY_SIZE 100
··· 100 */ 101 #define IGNORE_BADWINDOW 1 102 103 + /* This is the name of the first vscreen that is created. */ 104 + #define DEFAULT_VSCREEN_NAME "default" 105 106 /* Maximum allowed history size */ 107 #define MAX_HISTORY_SIZE 100
+17 -42
data.h
··· 36 typedef struct rp_keymap rp_keymap; 37 typedef struct rp_frame rp_frame; 38 typedef struct rp_child_info rp_child_info; 39 - typedef struct rp_group rp_group; 40 typedef struct rp_window_elem rp_window_elem; 41 typedef struct rp_completions rp_completions; 42 typedef struct rp_input_line rp_input_line; ··· 82 83 /* 84 * A number uniquely identifying this window. This is a different 85 - * number than the one given to it by the group it is in. This number 86 - * is used for internal purposes, whereas the group number is what the 87 - * user sees. 88 */ 89 int number; 90 ··· 140 struct list_head node; 141 }; 142 143 - /* 144 - * An rp_group is a group of windows. By default all windows are added to the 145 - * same group. But a new group can be created. All new windows will be part of 146 - * this new current group. The windows of any other group may be visible in 147 - * another frame, but will not show up in the window list and will not be 148 - * accessible with select, next, or prev. These window navigation commands only 149 - * navigate the current group. 150 - */ 151 - struct rp_group { 152 - rp_vscreen *vscreen; 153 - 154 - /* 155 - * The name and number of this group. This is to allow the user to 156 - * quickly jump to the desired group. 157 - */ 158 - char *name; 159 - int number; 160 - 161 - /* For determining the last group. */ 162 - int last_access; 163 - 164 - /* The list of windows participating in this group. */ 165 - struct list_head mapped_windows, unmapped_windows; 166 - 167 - /* 168 - * This numset is responsible for giving out numbers for each window in 169 - * the group. 170 - */ 171 - struct numset *numset; 172 - 173 - /* This structure can exist in a list. */ 174 - struct list_head node; 175 - }; 176 - 177 struct rp_global_screen { 178 Window root, wm_check; 179 unsigned long fg_color, bg_color, fw_color, bw_color; /* The pixel color. */ ··· 203 /* Virtual screen number, handled by rp_screen's vscreens_numset */ 204 int number; 205 206 /* 207 * A list of frames that may or may not contain windows. There should 208 * always be one in the list. ··· 218 */ 219 int current_frame; 220 221 - struct numset *group_numset; 222 - struct list_head groups; 223 - rp_group *current_group; 224 225 struct list_head node; 226 }; ··· 388 int terminated; 389 390 /* what was current when it was launched? */ 391 - rp_group *group; 392 rp_frame *frame; 393 rp_screen *screen; 394 rp_vscreen *vscreen;
··· 36 typedef struct rp_keymap rp_keymap; 37 typedef struct rp_frame rp_frame; 38 typedef struct rp_child_info rp_child_info; 39 typedef struct rp_window_elem rp_window_elem; 40 typedef struct rp_completions rp_completions; 41 typedef struct rp_input_line rp_input_line; ··· 81 82 /* 83 * A number uniquely identifying this window. This is a different 84 + * number than the one given to it by the vscreen it is in. This number 85 + * is used for internal purposes, whereas the vscreen number is what 86 + * the user sees. 87 */ 88 int number; 89 ··· 139 struct list_head node; 140 }; 141 142 struct rp_global_screen { 143 Window root, wm_check; 144 unsigned long fg_color, bg_color, fw_color, bw_color; /* The pixel color. */ ··· 168 /* Virtual screen number, handled by rp_screen's vscreens_numset */ 169 int number; 170 171 + /* Name */ 172 + char *name; 173 + 174 + /* For determining the last vscreen. */ 175 + int last_access; 176 + 177 /* 178 * A list of frames that may or may not contain windows. There should 179 * always be one in the list. ··· 189 */ 190 int current_frame; 191 192 + /* The list of windows participating in this vscreen. */ 193 + struct list_head mapped_windows, unmapped_windows; 194 + 195 + /* 196 + * This numset is responsible for giving out numbers for each window in 197 + * the vscreen. 198 + */ 199 + struct numset *numset; 200 201 struct list_head node; 202 }; ··· 364 int terminated; 365 366 /* what was current when it was launched? */ 367 rp_frame *frame; 368 rp_screen *screen; 369 rp_vscreen *vscreen;
+10 -21
events.c
··· 48 void 49 show_rudeness_msg(rp_window *win, int raised) 50 { 51 - rp_group *g = groups_find_group_by_window(win); 52 - rp_window_elem *elem = group_find_window(&g->mapped_windows, win); 53 54 - if (win->vscr != rp_current_vscreen) { 55 - if (win->transient) 56 - marked_message_printf(0, 0, raised ? 57 - MESSAGE_RAISE_TRANSIENT_VSCREEN : 58 - MESSAGE_MAP_TRANSIENT_VSCREEN, 59 - elem->number, window_name(win), win->vscr->number); 60 - else 61 - marked_message_printf(0, 0, raised ? 62 - MESSAGE_RAISE_WINDOW_VSCREEN : 63 - MESSAGE_MAP_WINDOW_VSCREEN, 64 - elem->number, window_name(win), win->vscr->number); 65 - } else if (g == rp_current_group) { 66 if (win->transient) 67 marked_message_printf(0, 0, raised ? 68 MESSAGE_RAISE_TRANSIENT : MESSAGE_MAP_TRANSIENT, ··· 74 } else { 75 if (win->transient) 76 marked_message_printf(0, 0, raised ? 77 - MESSAGE_RAISE_TRANSIENT_GROUP : 78 - MESSAGE_MAP_TRANSIENT_GROUP, 79 - elem->number, window_name(win), g->name); 80 else 81 marked_message_printf(0, 0, raised ? 82 - MESSAGE_RAISE_WINDOW_GROUP : MESSAGE_MAP_WINDOW_GROUP, 83 - elem->number, window_name(win), g->name); 84 } 85 } 86 ··· 385 PRINT_DEBUG(("Received _NET_CURRENT_DESKTOP = %ld\n", 386 ev->data.l[0])); 387 388 - v = vscreens_find_vscreen_by_number(s, ev->data.l[0]); 389 if (v) 390 set_current_vscreen(v); 391 } else { ··· 555 */ 556 child_info->window_mapped = 1; 557 } 558 - /* TODO: also adopt group information? */ 559 } 560 } else if (ev->xproperty.atom == XA_WM_NAME) { 561 PRINT_DEBUG(("updating window name\n"));
··· 48 void 49 show_rudeness_msg(rp_window *win, int raised) 50 { 51 + rp_vscreen *v = win->vscr; 52 + rp_window_elem *elem = vscreen_find_window(&v->mapped_windows, win); 53 54 + if (v == rp_current_vscreen) { 55 if (win->transient) 56 marked_message_printf(0, 0, raised ? 57 MESSAGE_RAISE_TRANSIENT : MESSAGE_MAP_TRANSIENT, ··· 63 } else { 64 if (win->transient) 65 marked_message_printf(0, 0, raised ? 66 + MESSAGE_RAISE_TRANSIENT_VSCREEN : 67 + MESSAGE_MAP_TRANSIENT_VSCREEN, 68 + elem->number, window_name(win), win->vscr->number); 69 else 70 marked_message_printf(0, 0, raised ? 71 + MESSAGE_RAISE_WINDOW_VSCREEN : 72 + MESSAGE_MAP_WINDOW_VSCREEN, 73 + elem->number, window_name(win), win->vscr->number); 74 } 75 } 76 ··· 375 PRINT_DEBUG(("Received _NET_CURRENT_DESKTOP = %ld\n", 376 ev->data.l[0])); 377 378 + v = screen_find_vscreen_by_number(s, ev->data.l[0]); 379 if (v) 380 set_current_vscreen(v); 381 } else { ··· 545 */ 546 child_info->window_mapped = 1; 547 } 548 } 549 } else if (ev->xproperty.atom == XA_WM_NAME) { 550 PRINT_DEBUG(("updating window name\n"));
+1 -3
globals.c
··· 259 LIST_HEAD(rp_key_hook); 260 LIST_HEAD(rp_switch_win_hook); 261 LIST_HEAD(rp_switch_frame_hook); 262 - LIST_HEAD(rp_switch_group_hook); 263 LIST_HEAD(rp_switch_screen_hook); 264 LIST_HEAD(rp_quit_hook); 265 LIST_HEAD(rp_restart_hook); ··· 271 {{"key", &rp_key_hook}, 272 {"switchwin", &rp_switch_win_hook}, 273 {"switchframe", &rp_switch_frame_hook}, 274 - {"switchgroup", &rp_switch_group_hook}, 275 {"switchscreen", &rp_switch_screen_hook}, 276 {"deletewindow", &rp_delete_window_hook}, 277 {"quit", &rp_quit_hook}, ··· 592 593 list_for_each_safe_entry(cur, iter, tmp, &rp_screens, node) { 594 list_for_each_entry(vcur, &cur->vscreens, node) 595 - free_groups(vcur); 596 597 list_del(&cur->node); 598 screen_free(cur);
··· 259 LIST_HEAD(rp_key_hook); 260 LIST_HEAD(rp_switch_win_hook); 261 LIST_HEAD(rp_switch_frame_hook); 262 LIST_HEAD(rp_switch_screen_hook); 263 LIST_HEAD(rp_quit_hook); 264 LIST_HEAD(rp_restart_hook); ··· 270 {{"key", &rp_key_hook}, 271 {"switchwin", &rp_switch_win_hook}, 272 {"switchframe", &rp_switch_frame_hook}, 273 {"switchscreen", &rp_switch_screen_hook}, 274 {"deletewindow", &rp_delete_window_hook}, 275 {"quit", &rp_quit_hook}, ··· 590 591 list_for_each_safe_entry(cur, iter, tmp, &rp_screens, node) { 592 list_for_each_entry(vcur, &cur->vscreens, node) 593 + vscreen_del(vcur); 594 595 list_del(&cur->node); 596 screen_free(cur);
-9
globals.h
··· 54 #define COMPLETION_NEXT 0 55 #define COMPLETION_PREVIOUS 1 56 57 - /* Error codes for group_delete_group() */ 58 - #define GROUP_DELETE_GROUP_OK 0 59 - #define GROUP_DELETE_GROUP_NONEMPTY 1 60 - #define GROUP_DELETE_LAST_GROUP 2 61 - 62 /* Font styles */ 63 #define STYLE_NORMAL 0 64 #define STYLE_INVERSE 1 65 - 66 - /* The list of groups. */ 67 - extern struct list_head rp_groups; 68 69 /* Whether or not we support xrandr */ 70 extern int rp_have_xrandr; ··· 181 extern struct list_head rp_key_hook; 182 extern struct list_head rp_switch_win_hook; 183 extern struct list_head rp_switch_frame_hook; 184 - extern struct list_head rp_switch_group_hook; 185 extern struct list_head rp_switch_screen_hook; 186 extern struct list_head rp_delete_window_hook; 187 extern struct list_head rp_quit_hook;
··· 54 #define COMPLETION_NEXT 0 55 #define COMPLETION_PREVIOUS 1 56 57 /* Font styles */ 58 #define STYLE_NORMAL 0 59 #define STYLE_INVERSE 1 60 61 /* Whether or not we support xrandr */ 62 extern int rp_have_xrandr; ··· 173 extern struct list_head rp_key_hook; 174 extern struct list_head rp_switch_win_hook; 175 extern struct list_head rp_switch_frame_hook; 176 extern struct list_head rp_switch_screen_hook; 177 extern struct list_head rp_delete_window_hook; 178 extern struct list_head rp_quit_hook;
-718
group.c
··· 1 - /* 2 - * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca> 3 - * 4 - * This program is free software; you can redistribute it and/or modify it 5 - * under the terms of the GNU General Public License as published by the Free 6 - * Software Foundation; either version 2 of the License, or (at your option) 7 - * any later version. 8 - * 9 - * This program is distributed in the hope that it will be useful, but WITHOUT 10 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 - * more details. 13 - * 14 - * You should have received a copy of the GNU General Public License along with 15 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 - * Place, Suite 330, Boston, MA 02111-1307 USA. 17 - */ 18 - 19 - #include "sdorfehs.h" 20 - 21 - #include <string.h> 22 - 23 - void group_insert_window(struct list_head *h, rp_window_elem *w); 24 - 25 - static void 26 - set_current_group_1(rp_group *g) 27 - { 28 - static int counter = 1; 29 - g->vscreen->current_group = g; 30 - g->last_access = counter++; 31 - } 32 - 33 - void 34 - init_groups(rp_vscreen *v) 35 - { 36 - rp_group *g; 37 - 38 - v->group_numset = numset_new(); 39 - INIT_LIST_HEAD(&v->groups); 40 - 41 - /* 42 - * Create the first group in the list (We always need at least one). 43 - */ 44 - g = group_new(v, numset_request(v->group_numset), DEFAULT_GROUP_NAME); 45 - set_current_group_1(g); 46 - list_add_tail(&g->node, &v->groups); 47 - } 48 - 49 - void 50 - free_groups(rp_vscreen *v) 51 - { 52 - rp_group *cur; 53 - struct list_head *iter, *tmp; 54 - 55 - list_for_each_safe_entry(cur, iter, tmp, &v->groups, node) { 56 - group_free(cur); 57 - } 58 - } 59 - 60 - struct numset * 61 - group_get_numset(rp_vscreen *v) 62 - { 63 - return v->group_numset; 64 - } 65 - 66 - /* 67 - * get the group list and store it in buffer delimiting each window with delim. 68 - * mark_start and mark_end will be filled with the text positions for the start 69 - * and end of the current window. 70 - */ 71 - void 72 - get_group_list(rp_vscreen *vscreen, char *delim, struct sbuf *buffer, 73 - int *mark_start, int *mark_end) 74 - { 75 - rp_group *cur, *last; 76 - 77 - if (buffer == NULL) 78 - return; 79 - 80 - sbuf_clear(buffer); 81 - 82 - last = group_last_group(vscreen); 83 - 84 - /* Generate the string. */ 85 - list_for_each_entry(cur, &vscreen->groups, node) { 86 - char *fmt; 87 - char separator; 88 - 89 - if (cur == vscreen->current_group) 90 - *mark_start = strlen(sbuf_get(buffer)); 91 - 92 - if (cur == vscreen->current_group) 93 - separator = '*'; 94 - else if (cur == last) 95 - separator = '+'; 96 - else 97 - separator = '-'; 98 - 99 - /* 100 - * A hack, pad the group with a space at the beginning and end 101 - * if there is no delimiter. 102 - */ 103 - if (!delim) 104 - sbuf_concat(buffer, " "); 105 - 106 - fmt = xsprintf("%d%c%s", cur->number, separator, cur->name); 107 - sbuf_concat(buffer, fmt); 108 - free(fmt); 109 - 110 - /* 111 - * A hack, pad the group with a space at the beginning and end 112 - * if there is no delimiter. 113 - */ 114 - if (!delim) 115 - sbuf_concat(buffer, " "); 116 - 117 - /* 118 - * Only put the delimiter between the group, and not after the 119 - * the last group. 120 - */ 121 - if (delim && cur->node.next != &vscreen->groups) 122 - sbuf_concat(buffer, delim); 123 - 124 - if (cur == vscreen->current_group) 125 - *mark_end = strlen(sbuf_get(buffer)); 126 - } 127 - } 128 - 129 - rp_group * 130 - group_new(rp_vscreen *vscreen, int number, char *name) 131 - { 132 - rp_group *g; 133 - 134 - g = xmalloc(sizeof(rp_group)); 135 - 136 - g->vscreen = vscreen; 137 - if (name) 138 - g->name = xstrdup(name); 139 - else 140 - g->name = NULL; 141 - g->last_access = 0; 142 - g->number = number; 143 - g->numset = numset_new(); 144 - INIT_LIST_HEAD(&g->unmapped_windows); 145 - INIT_LIST_HEAD(&g->mapped_windows); 146 - 147 - return g; 148 - } 149 - 150 - void 151 - group_free(rp_group *g) 152 - { 153 - free(g->name); 154 - numset_free(g->numset); 155 - numset_release(g->vscreen->group_numset, g->number); 156 - free(g); 157 - } 158 - 159 - rp_group * 160 - group_add_new_group(rp_vscreen *vscreen, char *name) 161 - { 162 - rp_group *g; 163 - rp_group *cur; 164 - 165 - g = group_new(vscreen, numset_request(vscreen->group_numset), name); 166 - 167 - list_for_each_entry(cur, &vscreen->groups, node) { 168 - if (cur->number > g->number) { 169 - list_add_tail(&g->node, &cur->node); 170 - return g; 171 - } 172 - } 173 - 174 - list_add_tail(&g->node, &vscreen->groups); 175 - 176 - return g; 177 - } 178 - 179 - void 180 - group_resort_group(rp_group *g) 181 - { 182 - rp_group *cur; 183 - struct list_head *last = &g->vscreen->groups; 184 - 185 - list_del(&g->node); 186 - list_for_each_entry(cur, &g->vscreen->groups, node) { 187 - if (cur->number > g->number) { 188 - list_add(&g->node, last); 189 - return; 190 - } 191 - last = &cur->node; 192 - } 193 - list_add(&g->node, last); 194 - } 195 - 196 - void 197 - group_rename(rp_group *g, char *name) 198 - { 199 - free(g->name); 200 - g->name = xstrdup(name); 201 - } 202 - 203 - rp_group * 204 - group_next_group(rp_vscreen *vscreen) 205 - { 206 - return list_next_entry(vscreen->current_group, &vscreen->groups, node); 207 - } 208 - 209 - rp_group * 210 - group_prev_group(rp_vscreen *vscreen) 211 - { 212 - return list_prev_entry(vscreen->current_group, &vscreen->groups, node); 213 - } 214 - 215 - rp_group * 216 - group_last_group(rp_vscreen *vscreen) 217 - { 218 - int last_access = 0; 219 - rp_group *most_recent = NULL; 220 - rp_group *cur; 221 - 222 - list_for_each_entry(cur, &vscreen->groups, node) { 223 - if (cur != vscreen->current_group && 224 - cur->last_access > last_access) { 225 - most_recent = cur; 226 - last_access = cur->last_access; 227 - } 228 - } 229 - return most_recent; 230 - } 231 - 232 - rp_group * 233 - groups_find_group_by_name(rp_vscreen *v, char *s, int exact_match) 234 - { 235 - rp_group *cur; 236 - 237 - if (!exact_match) { 238 - list_for_each_entry(cur, &v->groups, node) { 239 - if (cur->name && str_comp(s, cur->name, strlen(s))) 240 - return cur; 241 - } 242 - } else { 243 - list_for_each_entry(cur, &v->groups, node) { 244 - if (cur->name && !strcmp(cur->name, s)) 245 - return cur; 246 - } 247 - } 248 - 249 - return NULL; 250 - } 251 - 252 - rp_group * 253 - groups_find_group_by_number(rp_vscreen *v, int n) 254 - { 255 - rp_group *cur; 256 - 257 - list_for_each_entry(cur, &v->groups, node) { 258 - if (cur->number == n) 259 - return cur; 260 - } 261 - 262 - return NULL; 263 - } 264 - 265 - /* Return the first group that contains the window. */ 266 - rp_group * 267 - groups_find_group_by_window(rp_window *win) 268 - { 269 - rp_group *cur; 270 - rp_window_elem *elem; 271 - 272 - list_for_each_entry(cur, &win->vscr->groups, node) { 273 - elem = group_find_window(&cur->mapped_windows, win); 274 - if (elem) 275 - return cur; 276 - } 277 - 278 - return NULL; 279 - } 280 - 281 - 282 - /* Return the first group that is g. */ 283 - rp_group * 284 - groups_find_group_by_group(rp_group *g) 285 - { 286 - rp_group *cur; 287 - 288 - list_for_each_entry(cur, &g->vscreen->groups, node) { 289 - if (cur == g) 290 - return cur; 291 - } 292 - 293 - return NULL; 294 - } 295 - 296 - rp_window_elem * 297 - group_find_window(struct list_head *list, rp_window *win) 298 - { 299 - rp_window_elem *cur; 300 - 301 - list_for_each_entry(cur, list, node) { 302 - if (cur->win == win) 303 - return cur; 304 - } 305 - 306 - return NULL; 307 - } 308 - 309 - rp_window_elem * 310 - group_find_window_by_number(rp_group *g, int num) 311 - { 312 - rp_window_elem *cur; 313 - 314 - list_for_each_entry(cur, &g->mapped_windows, node) { 315 - if (cur->number == num) 316 - return cur; 317 - } 318 - 319 - return NULL; 320 - 321 - } 322 - 323 - /* 324 - * Insert a window_elem into the correct spot in the group's window list to 325 - * preserve window number ordering. 326 - */ 327 - void 328 - group_insert_window(struct list_head *h, rp_window_elem *w) 329 - { 330 - rp_window_elem *cur; 331 - 332 - list_for_each_entry(cur, h, node) { 333 - if (cur->number > w->number) { 334 - list_add_tail(&w->node, &cur->node); 335 - return; 336 - } 337 - } 338 - 339 - list_add_tail(&w->node, h); 340 - } 341 - 342 - static int 343 - group_in_list(struct list_head *h, rp_window_elem *w) 344 - { 345 - rp_window_elem *cur; 346 - 347 - list_for_each_entry(cur, h, node) { 348 - if (cur == w) 349 - return 1; 350 - } 351 - 352 - return 0; 353 - } 354 - 355 - /* 356 - * If a window_elem's number has changed then the list has to be resorted. 357 - */ 358 - void 359 - group_resort_window(rp_group *g, rp_window_elem *w) 360 - { 361 - /* Only a mapped window can be resorted. */ 362 - if (!group_in_list(&g->mapped_windows, w)) { 363 - PRINT_DEBUG(("Attempting to restort an unmapped window!\n")); 364 - return; 365 - } 366 - list_del(&w->node); 367 - group_insert_window(&g->mapped_windows, w); 368 - } 369 - 370 - void 371 - group_add_window(rp_group *g, rp_window *w) 372 - { 373 - rp_window_elem *we; 374 - 375 - /* Create our container structure for the window. */ 376 - we = xmalloc(sizeof(rp_window_elem)); 377 - we->win = w; 378 - we->number = -1; 379 - 380 - /* Finally, add it to our list. */ 381 - list_add_tail(&we->node, &g->unmapped_windows); 382 - } 383 - 384 - void 385 - group_map_window(rp_group *g, rp_window *win) 386 - { 387 - rp_window_elem *we; 388 - 389 - we = group_find_window(&g->unmapped_windows, win); 390 - 391 - if (we) { 392 - we->number = numset_request(g->numset); 393 - list_del(&we->node); 394 - group_insert_window(&g->mapped_windows, we); 395 - } 396 - } 397 - 398 - void 399 - groups_map_window(rp_vscreen *vscreen, rp_window *win) 400 - { 401 - rp_group *cur; 402 - 403 - list_for_each_entry(cur, &vscreen->groups, node) { 404 - group_map_window(cur, win); 405 - } 406 - } 407 - 408 - void 409 - group_unmap_window(rp_group *g, rp_window *win) 410 - { 411 - rp_window_elem *we; 412 - 413 - we = group_find_window(&g->mapped_windows, win); 414 - 415 - if (we) { 416 - numset_release(g->numset, we->number); 417 - list_move_tail(&we->node, &g->unmapped_windows); 418 - } 419 - } 420 - 421 - void 422 - groups_unmap_window(rp_window *win) 423 - { 424 - rp_group *cur; 425 - 426 - list_for_each_entry(cur, &win->vscr->groups, node) { 427 - group_unmap_window(cur, win); 428 - } 429 - } 430 - 431 - void 432 - group_del_window(rp_group *g, rp_window *win) 433 - { 434 - rp_window_elem *cur; 435 - struct list_head *iter, *tmp; 436 - 437 - /* The assumption is that a window is unmapped before it's deleted. */ 438 - list_for_each_safe_entry(cur, iter, tmp, &g->unmapped_windows, node) { 439 - if (cur->win == win) { 440 - list_del(&cur->node); 441 - free(cur); 442 - } 443 - } 444 - 445 - /* 446 - * Make sure the window isn't in the list of mapped windows. This would 447 - * mean there is a bug. 448 - */ 449 - #ifdef DEBUG 450 - list_for_each_entry(cur, &g->mapped_windows, node) { 451 - if (cur->win == win) 452 - PRINT_DEBUG(("This window wasn't removed from the " 453 - "mapped window list.\n")); 454 - } 455 - #endif 456 - } 457 - 458 - /* Remove the window from any groups in resides in. */ 459 - void 460 - groups_del_window(rp_window *win) 461 - { 462 - rp_group *cur; 463 - 464 - list_for_each_entry(cur, &win->vscr->groups, node) { 465 - group_del_window(cur, win); 466 - } 467 - } 468 - 469 - rp_window * 470 - group_last_window(rp_group *g) 471 - { 472 - rp_frame *f; 473 - rp_window_elem *most_recent = NULL; 474 - rp_window_elem *cur; 475 - int last_access = 0; 476 - 477 - f = current_frame(g->vscreen); 478 - list_for_each_entry(cur, &g->mapped_windows, node) { 479 - if (cur->win->sticky_frame != EMPTY && 480 - (!f || (cur->win->sticky_frame != f->number))) 481 - continue; 482 - 483 - if (cur->win->last_access >= last_access 484 - && cur->win != current_window() 485 - && !find_windows_frame(cur->win) 486 - && (cur->win->vscr == g->vscreen || rp_have_xrandr)) { 487 - most_recent = cur; 488 - last_access = cur->win->last_access; 489 - } 490 - } 491 - 492 - if (most_recent) 493 - return most_recent->win; 494 - 495 - return NULL; 496 - } 497 - 498 - rp_window * 499 - group_next_window(rp_group *g, rp_window *win) 500 - { 501 - rp_window_elem *cur, *we; 502 - rp_frame *f; 503 - 504 - /* If there is no window, then get the last accessed one. */ 505 - if (win == NULL) 506 - return group_last_window(g); 507 - 508 - /* 509 - * If we can't find the window, then it's in a different group, so get 510 - * the last accessed one in this group. 511 - */ 512 - we = group_find_window(&g->mapped_windows, win); 513 - if (we == NULL) 514 - return group_last_window(g); 515 - 516 - /* 517 - * The window is in this group, so find the next one in the list that 518 - * isn't already displayed. 519 - */ 520 - f = current_frame(g->vscreen); 521 - for (cur = list_next_entry(we, &g->mapped_windows, node); 522 - cur != we; 523 - cur = list_next_entry(cur, &g->mapped_windows, node)) { 524 - if (cur->win->sticky_frame != EMPTY && 525 - (!f || (cur->win->sticky_frame != f->number))) 526 - continue; 527 - 528 - if (!find_windows_frame(cur->win) && 529 - (cur->win->vscr == win->vscr || rp_have_xrandr)) 530 - return cur->win; 531 - } 532 - 533 - return NULL; 534 - } 535 - 536 - rp_window * 537 - group_prev_window(rp_group *g, rp_window *win) 538 - { 539 - rp_window_elem *cur, *we; 540 - rp_frame *f; 541 - 542 - /* If there is no window, then get the last accessed one. */ 543 - if (win == NULL) 544 - return group_last_window(g); 545 - 546 - /* 547 - * If we can't find the window, then it's in a different group, so get 548 - * the last accessed one in this group. 549 - */ 550 - we = group_find_window(&g->mapped_windows, win); 551 - if (we == NULL) 552 - return group_last_window(g); 553 - 554 - /* 555 - * The window is in this group, so find the previous one in the list 556 - * that isn't already displayed. 557 - */ 558 - f = current_frame(g->vscreen); 559 - for (cur = list_prev_entry(we, &g->mapped_windows, node); 560 - cur != we; 561 - cur = list_prev_entry(cur, &g->mapped_windows, node)) { 562 - if (cur->win->sticky_frame != EMPTY && 563 - (!f || (cur->win->sticky_frame != f->number))) 564 - continue; 565 - 566 - if (!find_windows_frame(cur->win) && 567 - (cur->win->vscr == win->vscr || rp_have_xrandr)) 568 - return cur->win; 569 - } 570 - 571 - return NULL; 572 - 573 - } 574 - 575 - void 576 - group_move_window(rp_group *to, rp_window *win) 577 - { 578 - rp_group *cur, *from = NULL; 579 - rp_window_elem *we = NULL; 580 - 581 - /* 582 - * Find the group that the window belongs to. FIXME: If the window 583 - * exists in multiple groups, then we're going to find the first group 584 - * with this window in it. 585 - */ 586 - list_for_each_entry(cur, &win->vscr->groups, node) { 587 - we = group_find_window(&cur->mapped_windows, win); 588 - if (we) { 589 - from = cur; 590 - break; 591 - } 592 - } 593 - 594 - if (we == NULL || from == NULL) { 595 - PRINT_DEBUG(("Unable to find window in mapped window lists.\n")); 596 - return; 597 - } 598 - /* Manually remove the window from one group... */ 599 - numset_release(from->numset, we->number); 600 - list_del(&we->node); 601 - 602 - /* and shove it into the other one. */ 603 - we->number = numset_request(to->numset); 604 - group_insert_window(&to->mapped_windows, we); 605 - } 606 - 607 - void 608 - groups_merge(rp_group *from, rp_group *to) 609 - { 610 - rp_window_elem *cur; 611 - struct list_head *iter, *tmp; 612 - 613 - /* Merging a group with itself makes no sense. */ 614 - if (from == to) 615 - return; 616 - 617 - /* Move the unmapped windows. */ 618 - list_for_each_safe_entry(cur, iter, tmp, &from->unmapped_windows, node) { 619 - list_del(&cur->node); 620 - list_add_tail(&cur->node, &to->unmapped_windows); 621 - } 622 - 623 - /* Move the mapped windows. */ 624 - list_for_each_safe_entry(cur, iter, tmp, &from->mapped_windows, node) { 625 - numset_release(from->numset, cur->number); 626 - list_del(&cur->node); 627 - 628 - cur->number = numset_request(to->numset); 629 - group_insert_window(&to->mapped_windows, cur); 630 - } 631 - } 632 - 633 - void 634 - set_current_group(rp_group *g) 635 - { 636 - if (g == NULL || g->vscreen->current_group == g) 637 - return; 638 - 639 - set_current_group_1(g); 640 - 641 - /* Call the switch group hook. */ 642 - hook_run(&rp_switch_group_hook); 643 - } 644 - 645 - int 646 - group_delete_group(rp_group *g) 647 - { 648 - if (list_empty(&(g->mapped_windows)) 649 - && list_empty(&(g->unmapped_windows))) { 650 - /* don't delete the last group */ 651 - if (list_size(&g->vscreen->groups) == 1) 652 - return GROUP_DELETE_LAST_GROUP; 653 - 654 - /* we can safely delete the group */ 655 - if (g == g->vscreen->current_group) { 656 - rp_group *next = group_last_group(g->vscreen); 657 - set_current_group(next ? next : 658 - group_next_group(g->vscreen)); 659 - } 660 - list_del(&(g->node)); 661 - group_free(g); 662 - return GROUP_DELETE_GROUP_OK; 663 - } else { 664 - return GROUP_DELETE_GROUP_NONEMPTY; 665 - } 666 - } 667 - 668 - /* Used by :cother / :iother */ 669 - rp_window * 670 - group_last_window_by_class(rp_group *g, char *class) 671 - { 672 - int last_access = 0; 673 - rp_window_elem *most_recent = NULL; 674 - rp_window_elem *cur; 675 - rp_vscreen *v = rp_current_vscreen; 676 - 677 - list_for_each_entry(cur, &g->mapped_windows, node) { 678 - if (cur->win->last_access >= last_access 679 - && cur->win != current_window() 680 - && !find_windows_frame(cur->win) 681 - && (cur->win->vscr == v || rp_have_xrandr) 682 - && strcmp(class, cur->win->res_class)) { 683 - most_recent = cur; 684 - last_access = cur->win->last_access; 685 - } 686 - } 687 - 688 - if (most_recent) 689 - return most_recent->win; 690 - 691 - return NULL; 692 - } 693 - 694 - /* Used by :cother / :iother */ 695 - rp_window * 696 - group_last_window_by_class_complement(rp_group *g, char *class) 697 - { 698 - int last_access = 0; 699 - rp_window_elem *most_recent = NULL; 700 - rp_window_elem *cur; 701 - rp_vscreen *v = rp_current_vscreen; 702 - 703 - list_for_each_entry(cur, &g->mapped_windows, node) { 704 - if (cur->win->last_access >= last_access 705 - && cur->win != current_window() 706 - && !find_windows_frame(cur->win) 707 - && (cur->win->vscr == v || rp_have_xrandr) 708 - && !strcmp(class, cur->win->res_class)) { 709 - most_recent = cur; 710 - last_access = cur->win->last_access; 711 - } 712 - } 713 - 714 - if (most_recent) 715 - return most_recent->win; 716 - 717 - return NULL; 718 - }
···
-75
group.h
··· 1 - /* 2 - * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca> 3 - * 4 - * This program is free software; you can redistribute it and/or modify it 5 - * under the terms of the GNU General Public License as published by the Free 6 - * Software Foundation; either version 2 of the License, or (at your option) 7 - * any later version. 8 - * 9 - * This program is distributed in the hope that it will be useful, but WITHOUT 10 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 - * more details. 13 - * 14 - * You should have received a copy of the GNU General Public License along with 15 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 16 - * Place, Suite 330, Boston, MA 02111-1307 USA. 17 - */ 18 - 19 - #ifndef GROUP_H 20 - #define GROUP_H 21 - 22 - void init_groups(rp_vscreen *v); 23 - void free_groups(rp_vscreen *v); 24 - 25 - void group_add_window(rp_group *g, rp_window *w); 26 - void group_resort_window(rp_group *g, rp_window_elem *w); 27 - void group_free(rp_group *g); 28 - rp_group *group_new(rp_vscreen *vscreen, int number, char *name); 29 - int group_delete_group(rp_group *g); 30 - 31 - void group_del_window(rp_group *g, rp_window *win); 32 - void groups_del_window(rp_window *win); 33 - 34 - void group_map_window(rp_group *g, rp_window *win); 35 - void groups_map_window(rp_vscreen *v, rp_window *win); 36 - 37 - void group_unmap_window(rp_group *g, rp_window *win); 38 - void groups_unmap_window(rp_window *win); 39 - 40 - struct numset *group_get_numset(rp_vscreen *v); 41 - void get_group_list(rp_vscreen *v, char *delim, struct sbuf *buffer, 42 - int *mark_start, int *mark_end); 43 - 44 - rp_window *group_prev_window(rp_group *g, rp_window *win); 45 - rp_window *group_next_window(rp_group *g, rp_window *win); 46 - rp_group *groups_find_group_by_name(rp_vscreen *v, char *s, int exact_match); 47 - rp_group *groups_find_group_by_number(rp_vscreen *v, int n); 48 - rp_group *groups_find_group_by_window(rp_window *win); 49 - rp_group *groups_find_group_by_group(rp_group *g); 50 - 51 - rp_window *group_last_window(rp_group *g); 52 - 53 - rp_group *group_prev_group(rp_vscreen *vscreen); 54 - rp_group *group_next_group(rp_vscreen *vscreen); 55 - rp_group *group_last_group(rp_vscreen *vscreen); 56 - 57 - void group_resort_group(rp_group *g); 58 - 59 - rp_group *group_add_new_group(rp_vscreen *vscreen, char *name); 60 - void group_rename(rp_group *g, char *name); 61 - 62 - rp_window_elem *group_find_window(struct list_head *list, rp_window *win); 63 - rp_window_elem *group_find_window_by_number(rp_group *g, int num); 64 - 65 - void group_move_window(rp_group *to, rp_window *win); 66 - void groups_merge(rp_group *from, rp_group *to); 67 - 68 - void set_current_group(rp_group *g); 69 - 70 - rp_window *group_last_window_by_class(rp_group *g, char *class); 71 - rp_window *group_last_window_by_class_complement(rp_group *g, char *class); 72 - 73 - rp_group *current_group(void); 74 - #define rp_current_group (rp_current_screen->current_vscreen->current_group) 75 - #endif
···
+1 -1
history.h
··· 22 enum { 23 hist_NONE = 0, hist_COMMAND, hist_SHELLCMD, 24 hist_SELECT, hist_KEYMAP, hist_KEY, 25 - hist_WINDOW, hist_GRAVITY, hist_GROUP, 26 hist_HOOK, hist_VARIABLE, hist_PROMPT, 27 hist_OTHER, 28 /* must be last, do not use, for length only: */
··· 22 enum { 23 hist_NONE = 0, hist_COMMAND, hist_SHELLCMD, 24 hist_SELECT, hist_KEYMAP, hist_KEY, 25 + hist_WINDOW, hist_GRAVITY, hist_VSCREEN, 26 hist_HOOK, hist_VARIABLE, hist_PROMPT, 27 hist_OTHER, 28 /* must be last, do not use, for length only: */
+4 -5
manage.c
··· 392 unmanage(rp_window *w) 393 { 394 list_del(&w->node); 395 - groups_del_window(w); 396 397 remove_atom(rp_glob_screen.root, _net_client_list, XA_WINDOW, w->w); 398 remove_atom(rp_glob_screen.root, _net_client_list_stacking, XA_WINDOW, ··· 840 list_del(&win->node); 841 insert_into_list(win, &rp_mapped_window); 842 843 - /* Update all groups. */ 844 - groups_map_window(win->vscr, win); 845 846 /* 847 * The window has never been accessed since it was brought back from the ··· 939 940 list_move_tail(&win->node, &rp_unmapped_window); 941 942 - /* Update the groups. */ 943 - groups_unmap_window(win); 944 945 ignore_badwindow++; 946
··· 392 unmanage(rp_window *w) 393 { 394 list_del(&w->node); 395 + vscreen_del_window(w->vscr, w); 396 397 remove_atom(rp_glob_screen.root, _net_client_list, XA_WINDOW, w->w); 398 remove_atom(rp_glob_screen.root, _net_client_list_stacking, XA_WINDOW, ··· 840 list_del(&win->node); 841 insert_into_list(win, &rp_mapped_window); 842 843 + vscreen_map_window(win->vscr, win); 844 845 /* 846 * The window has never been accessed since it was brought back from the ··· 938 939 list_move_tail(&win->node, &rp_unmapped_window); 940 941 + /* Update the vscreens. */ 942 + vscreen_unmap_window(win->vscr, win); 943 944 ignore_badwindow++; 945
+1 -5
messages.h
··· 28 29 #define MESSAGE_RAISE_TRANSIENT "Raise request from transient window %d (%s)" 30 #define MESSAGE_RAISE_WINDOW "Raise request from window %d (%s)" 31 - #define MESSAGE_RAISE_TRANSIENT_GROUP "Raise request from transient window %d (%s) in group %s" 32 - #define MESSAGE_RAISE_WINDOW_GROUP "Raise request from window %d (%s) in group %s" 33 #define MESSAGE_RAISE_TRANSIENT_VSCREEN "Raise request from transient window %d (%s) on vscreen %d" 34 #define MESSAGE_RAISE_WINDOW_VSCREEN "Raise request from window %d (%s) on vscreen %d" 35 #define MESSAGE_MAP_TRANSIENT "New transient window %d (%s)" 36 #define MESSAGE_MAP_WINDOW "New window %d (%s)" 37 - #define MESSAGE_MAP_TRANSIENT_GROUP "New transient window %d (%s) in group %s" 38 - #define MESSAGE_MAP_WINDOW_GROUP "New window %d (%s) in group %s" 39 #define MESSAGE_MAP_TRANSIENT_VSCREEN "New transient window %d (%s) on vscreen %d" 40 #define MESSAGE_MAP_WINDOW_VSCREEN "New window %d (%s) on vscreen %d" 41 ··· 44 #define MESSAGE_PROMPT_SHELL_COMMAND "/bin/sh -c " 45 #define MESSAGE_PROMPT_COMMAND ":" 46 #define MESSAGE_PROMPT_XTERM_COMMAND MESSAGE_PROMPT_SHELL_COMMAND TERM_PROG " -e " 47 - #define MESSAGE_PROMPT_SWITCH_TO_GROUP "Switch to group: " 48 #define MESSAGE_PROMPT_SELECT_VAR "Variable: " 49 #define MESSAGE_PROMPT_VAR_VALUE "Value: " 50
··· 28 29 #define MESSAGE_RAISE_TRANSIENT "Raise request from transient window %d (%s)" 30 #define MESSAGE_RAISE_WINDOW "Raise request from window %d (%s)" 31 #define MESSAGE_RAISE_TRANSIENT_VSCREEN "Raise request from transient window %d (%s) on vscreen %d" 32 #define MESSAGE_RAISE_WINDOW_VSCREEN "Raise request from window %d (%s) on vscreen %d" 33 #define MESSAGE_MAP_TRANSIENT "New transient window %d (%s)" 34 #define MESSAGE_MAP_WINDOW "New window %d (%s)" 35 #define MESSAGE_MAP_TRANSIENT_VSCREEN "New transient window %d (%s) on vscreen %d" 36 #define MESSAGE_MAP_WINDOW_VSCREEN "New window %d (%s) on vscreen %d" 37 ··· 40 #define MESSAGE_PROMPT_SHELL_COMMAND "/bin/sh -c " 41 #define MESSAGE_PROMPT_COMMAND ":" 42 #define MESSAGE_PROMPT_XTERM_COMMAND MESSAGE_PROMPT_SHELL_COMMAND TERM_PROG " -e " 43 + #define MESSAGE_PROMPT_SWITCH_TO_VSCREEN "Switch to vscreen: " 44 #define MESSAGE_PROMPT_SELECT_VAR "Variable: " 45 #define MESSAGE_PROMPT_VAR_VALUE "Value: " 46
+18 -66
sdorfehs.1
··· 160 .It Cm switchframe 161 Run after a frame actually switched, but before the window in it is 162 focused. 163 - .It Cm switchgroup 164 - Run after selecting a new group. 165 .It Cm switchscreen 166 Run when the user switches to a different screen. 167 .It Cm switchwin ··· 215 .It Ic cother 216 Like 217 .Ic other 218 - but switch to the window of the current group that was last accessed and 219 has another resource class but is not currently visible. 220 .It Ic curframe Pq Ic C\-a F 221 Show a bar marking the current frame. ··· 380 .Ic set Ns 381 ting 382 .Ar framesels . 383 - .It Ic gdelete Op Ar group 384 - If the optional argument 385 - .Ar group 386 - is supplied, delete 387 - .Ar group . 388 - Otherwise delete the current group. 389 - If the last group is deleted, a new group with name 390 - .Li default 391 - is created. 392 - The group has to be empty, otherwise it cannot be deleted. 393 .It Ic getenv Ar variable 394 Output the value of the environment variable 395 .Ar variable . 396 .It Ic getsel 397 Paste the current X Selection into the current window. 398 - .It Ic gmerge Ar group 399 - Move all windows from group 400 - .Ar group 401 - into the current group. 402 - .It Ic gmove Ar group 403 - Move the current window into group 404 - .Ar group . 405 - .It Ic gnew Ar group 406 - Create a new group with name 407 - .Ar group 408 - and select it. 409 - Most window commands only see (and thus select, consider next, 410 - previous or last) windows within the group active when they are 411 - issued. 412 - .It Ic gnewbg Ar group 413 - Create a new group named 414 - .Ar group , 415 - but do not select it. 416 - .It Ic gnext 417 - Select the next group. 418 - Most window commands only see windows in the effective group. 419 - .It Ic gnumber Op Ar old new 420 - Give the number 421 - .Ar new 422 - to the group with the number 423 - .Ar old 424 - or the current group. 425 - .It Ic gother 426 - Select the last accessed group. 427 - Most window commands only see windows in the effective group. 428 - .It Ic gprev 429 - Select the prior group. 430 - Most window commands only see windows in the effective group. 431 .It Ic gravity Op Cm nw | w | sw | n | c | s | ne | e | se 432 Change how in its frame the current window is aligned. 433 - .It Ic grename 434 - Rename current group. 435 - .It Ic groups 436 - Output a list of all groups with their number. 437 - .It Ic gselect Ar group 438 - Select the group named 439 - .Ar group . 440 .It Ic help Op Ar keymap 441 If the optional parameter 442 .Ar keymap ··· 490 .It Ic iother 491 Like 492 .Ic other 493 - but switch to the window of the current group that was last accessed and 494 has the same resource class but is not currently visible. 495 .It Ic kill Pq Ic C\-a K 496 Close the X-connection of the X-client responsible for the current window. ··· 530 and can be called with 531 .Ic readkey . 532 .It Ic next Pq Ic C\-a Return | C\-a n | C\-a space 533 - Switch to the next window in the current group. 534 .It Ic nextscreen Pq Ic C\-a N 535 Switch to the next screen. (If you have multiple physical ones.) 536 .It Ic number Ar new Op Ar old ··· 543 Remove all frames on the current screen except the current frame and 544 maximize this one to the size of the whole screen. 545 .It Ic other Pq Ic C\-a C\-a 546 - Switch to the window of the current group that was last 547 accessed but is not currently visible. 548 .It Ic prev Pq Ic C\-a p 549 - Switch to the previous window in the current group. 550 .It Ic prevscreen Pq Ic C\-a P 551 Switch to the previous screen. (If you have multiple physical ones.) 552 .It Ic prompt Op Ar prompt ··· 675 .It Ic select ( Cm \- | Ar name | Ar number ) Pq Ic C\-a \&' 676 If a number is given, switch to the window with number 677 .Ar number . 678 - If a name is given, switch to the window in the current group with 679 name 680 .Ar name . 681 Blank the current frame, if ··· 788 after showing a message with the command. 789 .It Ic version Pq Ic C\-a v 790 Output version and compile time information. 791 - .It Ic vselect Oo Ar vscreenno Oc 792 - Switch to the virtual screen numbered 793 - .Ar vscreenno . 794 - .It Ic vmove Oo Ar vscreenno Oc 795 - Move the current window to the virtual screen numbered 796 - .Ar vscreenno . 797 .It Ic vsplit Oo Ar l Ns Li / Ns Ar p | Ar "pixels-from-top" | Li \- Ns Ar "pixels-from-bottom" Oc Pq Ic C\-a s 798 Split the current frame into upper frame and a lower frame. 799 If no parameter is given, split in halves. ··· 818 in front of the number or not. 819 .It Ic windows Oo Ar format Oc Pq Ic C\-a w 820 In interactive mode, 821 - show the list of all windows in the current group for the duration 822 specified by the variable 823 .Va msgwait . 824 If ··· 897 .Li %20t 898 .Pc 899 .Pp 900 - In non\-interactive mode, output the list of windows in the current group 901 line by line. 902 The format string can be overwritten by the optional parameter 903 .Ar format .
··· 160 .It Cm switchframe 161 Run after a frame actually switched, but before the window in it is 162 focused. 163 .It Cm switchscreen 164 Run when the user switches to a different screen. 165 .It Cm switchwin ··· 213 .It Ic cother 214 Like 215 .Ic other 216 + but switch to the window of the current vscreen that was last accessed and 217 has another resource class but is not currently visible. 218 .It Ic curframe Pq Ic C\-a F 219 Show a bar marking the current frame. ··· 378 .Ic set Ns 379 ting 380 .Ar framesels . 381 .It Ic getenv Ar variable 382 Output the value of the environment variable 383 .Ar variable . 384 .It Ic getsel 385 Paste the current X Selection into the current window. 386 .It Ic gravity Op Cm nw | w | sw | n | c | s | ne | e | se 387 Change how in its frame the current window is aligned. 388 .It Ic help Op Ar keymap 389 If the optional parameter 390 .Ar keymap ··· 438 .It Ic iother 439 Like 440 .Ic other 441 + but switch to the window of the current vscreen that was last accessed and 442 has the same resource class but is not currently visible. 443 .It Ic kill Pq Ic C\-a K 444 Close the X-connection of the X-client responsible for the current window. ··· 478 and can be called with 479 .Ic readkey . 480 .It Ic next Pq Ic C\-a Return | C\-a n | C\-a space 481 + Switch to the next window in the current vscreen. 482 .It Ic nextscreen Pq Ic C\-a N 483 Switch to the next screen. (If you have multiple physical ones.) 484 .It Ic number Ar new Op Ar old ··· 491 Remove all frames on the current screen except the current frame and 492 maximize this one to the size of the whole screen. 493 .It Ic other Pq Ic C\-a C\-a 494 + Switch to the window of the current vscreen that was last 495 accessed but is not currently visible. 496 .It Ic prev Pq Ic C\-a p 497 + Switch to the previous window in the current vscreen. 498 .It Ic prevscreen Pq Ic C\-a P 499 Switch to the previous screen. (If you have multiple physical ones.) 500 .It Ic prompt Op Ar prompt ··· 623 .It Ic select ( Cm \- | Ar name | Ar number ) Pq Ic C\-a \&' 624 If a number is given, switch to the window with number 625 .Ar number . 626 + If a name is given, switch to the window in the current vscreen with 627 name 628 .Ar name . 629 Blank the current frame, if ··· 736 after showing a message with the command. 737 .It Ic version Pq Ic C\-a v 738 Output version and compile time information. 739 + .It Ic vmove Oo Ar vscreen Oc 740 + Move the current window to the virtual screen 741 + .Ar vscreen . 742 + .It Ic vrename 743 + Rename current vscreen. 744 + .It Ic vscreens 745 + Output a list of all vscreens with their number. 746 + .It Ic vselect Ar vscreen 747 + Select the vscreen named 748 + .Ar vscreen . 749 .It Ic vsplit Oo Ar l Ns Li / Ns Ar p | Ar "pixels-from-top" | Li \- Ns Ar "pixels-from-bottom" Oc Pq Ic C\-a s 750 Split the current frame into upper frame and a lower frame. 751 If no parameter is given, split in halves. ··· 770 in front of the number or not. 771 .It Ic windows Oo Ar format Oc Pq Ic C\-a w 772 In interactive mode, 773 + show the list of all windows in the current vscreen for the duration 774 specified by the variable 775 .Va msgwait . 776 If ··· 849 .Li %20t 850 .Pc 851 .Pp 852 + In non\-interactive mode, output the list of windows in the current vscreen 853 line by line. 854 The format string can be overwritten by the optional parameter 855 .Ar format .
-1
sdorfehs.h
··· 78 #include "frame.h" 79 #include "screen.h" 80 #include "vscreen.h" 81 - #include "group.h" 82 #include "editor.h" 83 #include "history.h" 84 #include "completions.h"
··· 78 #include "frame.h" 79 #include "screen.h" 80 #include "vscreen.h" 81 #include "editor.h" 82 #include "history.h" 83 #include "completions.h"
+6 -12
split.c
··· 265 rp_window_elem *most_recent = NULL; 266 rp_window_elem *cur; 267 268 - list_for_each_entry(cur, &rp_current_group->mapped_windows, node) { 269 - if ((cur->win->vscr == v || rp_have_xrandr) 270 - && cur->win != current_window() 271 && cur->win->sticky_frame != frame->number 272 && !find_windows_frame(cur->win) 273 && cur->win->last_access >= last_access ··· 937 frame = current_frame(rp_current_vscreen); 938 win = current_window(); 939 if (win) { 940 - rp_group *g; 941 - 942 - g = groups_find_group_by_window(win); 943 - if (g) 944 - elem = group_find_window(&g->mapped_windows, win); 945 - else 946 - warnx("window 0x%lx not in any group\n", 947 (unsigned long)win->w); 948 } 949 /* A frame doesn't always contain a window. */ 950 msgbuf = sbuf_new(0); 951 if (elem) 952 format_string(msg, elem, msgbuf); 953 - else { 954 sbuf_concat(msgbuf, EMPTY_FRAME_MESSAGE); 955 - } 956 957 width = defaults.bar_x_padding * 2 958 + rp_text_width(s, msgbuf->data, msgbuf->len, NULL);
··· 265 rp_window_elem *most_recent = NULL; 266 rp_window_elem *cur; 267 268 + list_for_each_entry(cur, &v->mapped_windows, node) { 269 + if (cur->win != current_window() 270 && cur->win->sticky_frame != frame->number 271 && !find_windows_frame(cur->win) 272 && cur->win->last_access >= last_access ··· 936 frame = current_frame(rp_current_vscreen); 937 win = current_window(); 938 if (win) { 939 + elem = vscreen_find_window(&win->vscr->mapped_windows, win); 940 + if (!elem) 941 + warnx("window 0x%lx not on any vscreen\n", 942 (unsigned long)win->w); 943 } 944 /* A frame doesn't always contain a window. */ 945 msgbuf = sbuf_new(0); 946 if (elem) 947 format_string(msg, elem, msgbuf); 948 + else 949 sbuf_concat(msgbuf, EMPTY_FRAME_MESSAGE); 950 951 width = defaults.bar_x_padding * 2 952 + rp_text_width(s, msgbuf->data, msgbuf->len, NULL);
+485 -38
vscreen.c
··· 22 rp_vscreen *vscreen_next(void); 23 rp_vscreen *vscreen_prev(void); 24 25 void 26 init_vscreen(rp_vscreen *v, rp_screen *s) 27 { 28 v->screen = s; 29 v->number = numset_request(s->vscreens_numset); 30 v->frames_numset = numset_new(); 31 32 - init_groups(v); 33 } 34 35 void ··· 40 rp_window *cur; 41 42 if (v->number != 0) 43 - target = vscreens_find_vscreen_by_number(s, 0); 44 45 list_for_each_entry(cur, &rp_mapped_window, node) { 46 if (cur->vscr == v && target) ··· 105 106 if (scr->current_vscreen == cur) 107 set_current_vscreen( 108 - vscreens_find_vscreen_by_number(scr, 109 0)); 110 111 vscreen_del(cur); ··· 127 return 0; 128 } 129 130 - rp_vscreen * 131 - vscreens_find_vscreen_by_number(rp_screen *s, int n) 132 - { 133 - rp_vscreen *cur; 134 - 135 - list_for_each_entry(cur, &s->vscreens, node) { 136 - if (cur->number == n) 137 - return cur; 138 - } 139 - 140 - return NULL; 141 - } 142 - 143 /* Returns a pointer to a list of frames. */ 144 struct list_head * 145 vscreen_copy_frameset(rp_vscreen *v) ··· 246 247 rp_current_screen = v->screen; 248 v->screen->current_vscreen = v; 249 250 list_for_each_entry(frame, &rp_current_vscreen->frames, node) { 251 if (frame->restore_win_number == EMPTY) ··· 287 } 288 289 void 290 - vscreen_move_window(rp_vscreen *v, rp_window *w) 291 { 292 - rp_group *cur, *oldg = NULL; 293 - rp_window_elem *we = NULL; 294 - rp_window *last; 295 rp_frame *f; 296 297 - /* find the group this window is currently in */ 298 - list_for_each_entry(cur, &w->vscr->groups, node) { 299 - we = group_find_window(&cur->mapped_windows, w); 300 - if (we) { 301 - oldg = cur; 302 - break; 303 - } 304 } 305 306 - /* and its frame */ 307 f = find_windows_frame(w); 308 - 309 - /* move it to the new vscreen in its current group */ 310 - group_move_window(v->current_group, w); 311 - w->vscr = v; 312 w->sticky_frame = EMPTY; 313 314 /* forget that this window was in the frame it was in */ 315 if (f) 316 f->win_number = EMPTY; 317 318 - /* cycle the window's old group */ 319 - if (oldg) { 320 - last = group_last_window(oldg); 321 - if (last) 322 - set_active_window_force(last); 323 } 324 325 - hide_window(w); 326 }
··· 22 rp_vscreen *vscreen_next(void); 23 rp_vscreen *vscreen_prev(void); 24 25 + static int vscreen_access = 1; 26 + 27 void 28 init_vscreen(rp_vscreen *v, rp_screen *s) 29 { 30 v->screen = s; 31 v->number = numset_request(s->vscreens_numset); 32 v->frames_numset = numset_new(); 33 + v->numset = numset_new(); 34 + v->last_access = 0; 35 36 + if (v->number == 0) 37 + v->name = xstrdup(DEFAULT_VSCREEN_NAME); 38 + else 39 + v->name = xsprintf("%d", v->number); 40 + 41 + INIT_LIST_HEAD(&v->unmapped_windows); 42 + INIT_LIST_HEAD(&v->mapped_windows); 43 } 44 45 void ··· 50 rp_window *cur; 51 52 if (v->number != 0) 53 + target = screen_find_vscreen_by_number(s, 0); 54 55 list_for_each_entry(cur, &rp_mapped_window, node) { 56 if (cur->vscr == v && target) ··· 115 116 if (scr->current_vscreen == cur) 117 set_current_vscreen( 118 + screen_find_vscreen_by_number(scr, 119 0)); 120 121 vscreen_del(cur); ··· 137 return 0; 138 } 139 140 /* Returns a pointer to a list of frames. */ 141 struct list_head * 142 vscreen_copy_frameset(rp_vscreen *v) ··· 243 244 rp_current_screen = v->screen; 245 v->screen->current_vscreen = v; 246 + v->last_access = vscreen_access++; 247 248 list_for_each_entry(frame, &rp_current_vscreen->frames, node) { 249 if (frame->restore_win_number == EMPTY) ··· 285 } 286 287 void 288 + vscreen_move_window(rp_vscreen *to, rp_window *w) 289 { 290 + rp_vscreen *from = w->vscr; 291 rp_frame *f; 292 + rp_window_elem *we; 293 294 + we = vscreen_find_window(&from->mapped_windows, w); 295 + if (we == NULL) { 296 + PRINT_DEBUG(("Unable to find window in mapped window lists.\n")); 297 + return; 298 } 299 300 f = find_windows_frame(w); 301 + w->vscr = to; 302 w->sticky_frame = EMPTY; 303 304 /* forget that this window was in the frame it was in */ 305 if (f) 306 f->win_number = EMPTY; 307 308 + numset_release(from->numset, we->number); 309 + list_del(&we->node); 310 + 311 + we->number = numset_request(to->numset); 312 + vscreen_insert_window(&to->mapped_windows, we); 313 + 314 + if (to == rp_current_vscreen) 315 + set_active_window_force(w); 316 + else 317 + hide_window(w); 318 + } 319 + 320 + struct numset * 321 + vscreen_get_numset(rp_vscreen *v) 322 + { 323 + return v->numset; 324 + } 325 + 326 + /* 327 + * Get the vscreen list and store it in buffer delimiting each window with 328 + * delim. mark_start and mark_end will be filled with the text positions for 329 + * the start and end of the current window. 330 + */ 331 + void 332 + get_vscreen_list(rp_screen *screen, char *delim, struct sbuf *buffer, 333 + int *mark_start, int *mark_end) 334 + { 335 + rp_vscreen *cur, *last; 336 + 337 + if (buffer == NULL) 338 + return; 339 + 340 + sbuf_clear(buffer); 341 + 342 + last = screen_last_vscreen(screen); 343 + list_for_each_entry(cur, &screen->vscreens, node) { 344 + char *fmt; 345 + char separator; 346 + 347 + if (cur == screen->current_vscreen) { 348 + *mark_start = strlen(sbuf_get(buffer)); 349 + separator = '*'; 350 + } else if (cur == last) 351 + separator = '+'; 352 + else 353 + separator = '-'; 354 + 355 + /* 356 + * A hack, pad the vscreen with a space at the beginning and end 357 + * if there is no delimiter. 358 + */ 359 + if (!delim) 360 + sbuf_concat(buffer, " "); 361 + 362 + fmt = xsprintf("%d%c%s", cur->number, separator, cur->name); 363 + sbuf_concat(buffer, fmt); 364 + free(fmt); 365 + 366 + /* 367 + * A hack, pad the vscreen with a space at the beginning and 368 + * end if there is no delimiter. 369 + */ 370 + if (!delim) 371 + sbuf_concat(buffer, " "); 372 + 373 + /* 374 + * Only put the delimiter between the vscreen, and not after 375 + * the the last vscreen. 376 + */ 377 + if (delim && cur->node.next != &screen->vscreens) 378 + sbuf_concat(buffer, delim); 379 + 380 + if (cur == screen->current_vscreen) 381 + *mark_end = strlen(sbuf_get(buffer)); 382 + } 383 + } 384 + 385 + void 386 + vscreen_rename(rp_vscreen *v, char *name) 387 + { 388 + free(v->name); 389 + v->name = xstrdup(name); 390 + } 391 + 392 + rp_vscreen * 393 + vscreen_next_vscreen(rp_vscreen *vscreen) 394 + { 395 + return list_next_entry(vscreen->screen->current_vscreen, 396 + &vscreen->screen->vscreens, node); 397 + } 398 + 399 + rp_vscreen * 400 + vscreen_prev_vscreen(rp_vscreen *vscreen) 401 + { 402 + return list_prev_entry(vscreen->screen->current_vscreen, 403 + &vscreen->screen->vscreens, node); 404 + } 405 + 406 + rp_vscreen * 407 + screen_last_vscreen(rp_screen *screen) 408 + { 409 + int last_access = 0; 410 + rp_vscreen *most_recent = NULL; 411 + rp_vscreen *cur; 412 + 413 + list_for_each_entry(cur, &screen->vscreens, node) { 414 + if (cur != screen->current_vscreen && 415 + cur->last_access > last_access) { 416 + most_recent = cur; 417 + last_access = cur->last_access; 418 + } 419 + } 420 + return most_recent; 421 + } 422 + 423 + rp_vscreen * 424 + screen_find_vscreen_by_number(rp_screen *s, int n) 425 + { 426 + rp_vscreen *cur; 427 + 428 + list_for_each_entry(cur, &s->vscreens, node) { 429 + if (cur->number == n) 430 + return cur; 431 + } 432 + 433 + return NULL; 434 + } 435 + 436 + rp_vscreen * 437 + screen_find_vscreen_by_name(rp_screen *s, char *name, int exact_match) 438 + { 439 + rp_vscreen *cur; 440 + 441 + if (exact_match) { 442 + list_for_each_entry(cur, &s->vscreens, node) { 443 + if (cur->name && !strcmp(cur->name, name)) 444 + return cur; 445 + } 446 + } else { 447 + list_for_each_entry(cur, &s->vscreens, node) { 448 + if (cur->name && str_comp(name, cur->name, 449 + strlen(name))) 450 + return cur; 451 + } 452 + } 453 + 454 + return NULL; 455 + } 456 + 457 + rp_window_elem * 458 + vscreen_find_window(struct list_head *list, rp_window *win) 459 + { 460 + rp_window_elem *cur; 461 + 462 + list_for_each_entry(cur, list, node) { 463 + if (cur->win == win) 464 + return cur; 465 + } 466 + 467 + return NULL; 468 + } 469 + 470 + rp_window_elem * 471 + vscreen_find_window_by_number(rp_vscreen *v, int num) 472 + { 473 + rp_window_elem *cur; 474 + 475 + list_for_each_entry(cur, &v->mapped_windows, node) { 476 + if (cur->number == num) 477 + return cur; 478 + } 479 + 480 + return NULL; 481 + 482 + } 483 + 484 + /* 485 + * Insert a window_elem into the correct spot in the vscreen's window list to 486 + * preserve window number ordering. 487 + */ 488 + void 489 + vscreen_insert_window(struct list_head *h, rp_window_elem *w) 490 + { 491 + rp_window_elem *cur; 492 + 493 + list_for_each_entry(cur, h, node) { 494 + if (cur->number > w->number) { 495 + list_add_tail(&w->node, &cur->node); 496 + return; 497 + } 498 + } 499 + 500 + list_add_tail(&w->node, h); 501 + } 502 + 503 + static int 504 + vscreen_in_list(struct list_head *h, rp_window_elem *w) 505 + { 506 + rp_window_elem *cur; 507 + 508 + list_for_each_entry(cur, h, node) { 509 + if (cur == w) 510 + return 1; 511 + } 512 + 513 + return 0; 514 + } 515 + 516 + /* 517 + * If a window_elem's number has changed then the list has to be resorted. 518 + */ 519 + void 520 + vscreen_resort_window(rp_vscreen *v, rp_window_elem *w) 521 + { 522 + /* Only a mapped window can be resorted. */ 523 + if (!vscreen_in_list(&v->mapped_windows, w)) { 524 + PRINT_DEBUG(("Attempting to resort an unmapped window!\n")); 525 + return; 526 + } 527 + list_del(&w->node); 528 + vscreen_insert_window(&v->mapped_windows, w); 529 + } 530 + 531 + void 532 + vscreen_add_window(rp_vscreen *v, rp_window *w) 533 + { 534 + rp_window_elem *we; 535 + 536 + /* Create our container structure for the window. */ 537 + we = xmalloc(sizeof(rp_window_elem)); 538 + we->win = w; 539 + we->number = -1; 540 + 541 + /* Finally, add it to our list. */ 542 + list_add_tail(&we->node, &v->unmapped_windows); 543 + } 544 + 545 + void 546 + vscreen_map_window(rp_vscreen *v, rp_window *win) 547 + { 548 + rp_window_elem *we; 549 + 550 + we = vscreen_find_window(&v->unmapped_windows, win); 551 + if (we) { 552 + we->number = numset_request(v->numset); 553 + list_del(&we->node); 554 + vscreen_insert_window(&v->mapped_windows, we); 555 + } 556 + } 557 + 558 + void 559 + vscreen_unmap_window(rp_vscreen *v, rp_window *win) 560 + { 561 + rp_window_elem *we; 562 + 563 + we = vscreen_find_window(&v->mapped_windows, win); 564 + if (we) { 565 + numset_release(v->numset, we->number); 566 + list_move_tail(&we->node, &v->unmapped_windows); 567 + } 568 + } 569 + 570 + void 571 + vscreen_del_window(rp_vscreen *v, rp_window *win) 572 + { 573 + rp_window_elem *cur; 574 + struct list_head *iter, *tmp; 575 + 576 + /* The assumption is that a window is unmapped before it's deleted. */ 577 + list_for_each_safe_entry(cur, iter, tmp, &v->unmapped_windows, node) { 578 + if (cur->win == win) { 579 + list_del(&cur->node); 580 + free(cur); 581 + } 582 + } 583 + 584 + /* 585 + * Make sure the window isn't in the list of mapped windows. This would 586 + * mean there is a bug. 587 + */ 588 + #ifdef DEBUG 589 + list_for_each_entry(cur, &v->mapped_windows, node) { 590 + if (cur->win == win) 591 + PRINT_DEBUG(("This window wasn't removed from the " 592 + "mapped window list.\n")); 593 + } 594 + #endif 595 + } 596 + 597 + rp_window * 598 + vscreen_last_window(rp_vscreen *v) 599 + { 600 + rp_frame *f; 601 + rp_window_elem *most_recent = NULL; 602 + rp_window_elem *cur; 603 + int last_access = 0; 604 + 605 + f = current_frame(v); 606 + list_for_each_entry(cur, &v->mapped_windows, node) { 607 + if (cur->win->sticky_frame != EMPTY && 608 + (!f || (cur->win->sticky_frame != f->number))) 609 + continue; 610 + 611 + if (cur->win->last_access >= last_access 612 + && cur->win != current_window() 613 + && !find_windows_frame(cur->win) 614 + && (cur->win->vscr == v || rp_have_xrandr)) { 615 + most_recent = cur; 616 + last_access = cur->win->last_access; 617 + } 618 + } 619 + 620 + if (most_recent) 621 + return most_recent->win; 622 + 623 + return NULL; 624 + } 625 + 626 + rp_window * 627 + vscreen_next_window(rp_vscreen *v, rp_window *win) 628 + { 629 + rp_window_elem *cur, *we; 630 + rp_frame *f; 631 + 632 + /* If there is no window, then get the last accessed one. */ 633 + if (win == NULL) 634 + return vscreen_last_window(v); 635 + 636 + /* 637 + * If we can't find the window, then it's in a different vscreen, so 638 + * get the last accessed one in this vscreen. 639 + */ 640 + we = vscreen_find_window(&v->mapped_windows, win); 641 + if (we == NULL) 642 + return vscreen_last_window(v); 643 + 644 + /* 645 + * The window is in this vscreen, so find the next one in the list that 646 + * isn't already displayed. 647 + */ 648 + f = current_frame(v); 649 + for (cur = list_next_entry(we, &v->mapped_windows, node); 650 + cur != we; 651 + cur = list_next_entry(cur, &v->mapped_windows, node)) { 652 + if (cur->win->sticky_frame != EMPTY && 653 + (!f || (cur->win->sticky_frame != f->number))) 654 + continue; 655 + 656 + if (!find_windows_frame(cur->win) && 657 + (cur->win->vscr == win->vscr || rp_have_xrandr)) 658 + return cur->win; 659 + } 660 + 661 + return NULL; 662 + } 663 + 664 + rp_window * 665 + vscreen_prev_window(rp_vscreen *v, rp_window *win) 666 + { 667 + rp_window_elem *cur, *we; 668 + rp_frame *f; 669 + 670 + /* If there is no window, then get the last accessed one. */ 671 + if (win == NULL) 672 + return vscreen_last_window(v); 673 + 674 + /* 675 + * If we can't find the window, then it's in a different vscreen, so 676 + * get the last accessed one in this vscreen. 677 + */ 678 + we = vscreen_find_window(&v->mapped_windows, win); 679 + if (we == NULL) 680 + return vscreen_last_window(v); 681 + 682 + /* 683 + * The window is in this vscreen, so find the previous one in the list 684 + * that isn't already displayed. 685 + */ 686 + f = current_frame(v); 687 + for (cur = list_prev_entry(we, &v->mapped_windows, node); 688 + cur != we; 689 + cur = list_prev_entry(cur, &v->mapped_windows, node)) { 690 + if (cur->win->sticky_frame != EMPTY && 691 + (!f || (cur->win->sticky_frame != f->number))) 692 + continue; 693 + 694 + if (!find_windows_frame(cur->win) && rp_have_xrandr) 695 + return cur->win; 696 } 697 698 + return NULL; 699 + } 700 + 701 + void 702 + vscreens_merge(rp_vscreen *from, rp_vscreen *to) 703 + { 704 + rp_window_elem *cur; 705 + struct list_head *iter, *tmp; 706 + 707 + /* Merging a vscreen with itself makes no sense. */ 708 + if (from == to) 709 + return; 710 + 711 + /* Move the unmapped windows. */ 712 + list_for_each_safe_entry(cur, iter, tmp, &from->unmapped_windows, node) { 713 + list_del(&cur->node); 714 + list_add_tail(&cur->node, &to->unmapped_windows); 715 + } 716 + 717 + /* Move the mapped windows. */ 718 + list_for_each_safe_entry(cur, iter, tmp, &from->mapped_windows, node) { 719 + numset_release(from->numset, cur->number); 720 + list_del(&cur->node); 721 + 722 + cur->number = numset_request(to->numset); 723 + vscreen_insert_window(&to->mapped_windows, cur); 724 + } 725 + } 726 + 727 + /* Used by :cother / :iother */ 728 + rp_window * 729 + vscreen_last_window_by_class(rp_vscreen *v, char *class) 730 + { 731 + int last_access = 0; 732 + rp_window_elem *most_recent = NULL; 733 + rp_window_elem *cur; 734 + 735 + list_for_each_entry(cur, &v->mapped_windows, node) { 736 + if (cur->win->last_access >= last_access 737 + && cur->win != current_window() 738 + && !find_windows_frame(cur->win) 739 + && strcmp(class, cur->win->res_class)) { 740 + most_recent = cur; 741 + last_access = cur->win->last_access; 742 + } 743 + } 744 + 745 + if (most_recent) 746 + return most_recent->win; 747 + 748 + return NULL; 749 + } 750 + 751 + /* Used by :cother / :iother */ 752 + rp_window * 753 + vscreen_last_window_by_class_complement(rp_vscreen *v, char *class) 754 + { 755 + int last_access = 0; 756 + rp_window_elem *most_recent = NULL; 757 + rp_window_elem *cur; 758 + 759 + list_for_each_entry(cur, &v->mapped_windows, node) { 760 + if (cur->win->last_access >= last_access 761 + && cur->win != current_window() 762 + && !find_windows_frame(cur->win) 763 + && !strcmp(class, cur->win->res_class)) { 764 + most_recent = cur; 765 + last_access = cur->win->last_access; 766 + } 767 + } 768 + 769 + if (most_recent) 770 + return most_recent->win; 771 + 772 + return NULL; 773 }
+39 -1
vscreen.h
··· 24 void vscreen_free(rp_vscreen *v); 25 int vscreens_resize(int n); 26 27 - rp_vscreen *vscreens_find_vscreen_by_number(rp_screen *s, int n); 28 29 struct list_head *vscreen_copy_frameset(rp_vscreen *v); 30 void vscreen_restore_frameset(rp_vscreen *v, struct list_head *head); ··· 35 36 void set_current_vscreen(rp_vscreen *v); 37 void vscreen_move_window(rp_vscreen *v, rp_window *w); 38 39 #define rp_current_vscreen (rp_current_screen->current_vscreen) 40
··· 24 void vscreen_free(rp_vscreen *v); 25 int vscreens_resize(int n); 26 27 + rp_vscreen *screen_find_vscreen_by_number(rp_screen *s, int n); 28 + rp_vscreen *screen_find_vscreen_by_name(rp_screen *s, char *name, int exact_match); 29 30 struct list_head *vscreen_copy_frameset(rp_vscreen *v); 31 void vscreen_restore_frameset(rp_vscreen *v, struct list_head *head); ··· 36 37 void set_current_vscreen(rp_vscreen *v); 38 void vscreen_move_window(rp_vscreen *v, rp_window *w); 39 + 40 + 41 + void vscreen_add_window(rp_vscreen *v, rp_window *w); 42 + void vscreen_resort_window(rp_vscreen *v, rp_window_elem *w); 43 + void vscreen_insert_window(struct list_head *h, rp_window_elem *w); 44 + 45 + void vscreen_del_window(rp_vscreen *v, rp_window *win); 46 + 47 + void vscreen_map_window(rp_vscreen *v, rp_window *win); 48 + 49 + void vscreen_unmap_window(rp_vscreen *v, rp_window *win); 50 + 51 + struct numset *vscreen_get_numset(rp_vscreen *v); 52 + void get_vscreen_list(rp_screen *s, char *delim, struct sbuf *buffer, 53 + int *mark_start, int *mark_end); 54 + 55 + rp_window *vscreen_prev_window(rp_vscreen *v, rp_window *win); 56 + rp_window *vscreen_next_window(rp_vscreen *v, rp_window *win); 57 + 58 + rp_window *vscreen_last_window(rp_vscreen *v); 59 + 60 + rp_vscreen *vscreen_prev_vscreen(rp_vscreen *v); 61 + rp_vscreen *vscreen_next_vscreen(rp_vscreen *v); 62 + rp_vscreen *screen_last_vscreen(rp_screen *screen); 63 + 64 + void vscreen_rename(rp_vscreen *v, char *name); 65 + 66 + rp_window_elem *vscreen_find_window(struct list_head *list, rp_window *win); 67 + rp_window_elem *vscreen_find_window_by_number(rp_vscreen *g, int num); 68 + 69 + void vscreen_move_window(rp_vscreen *to, rp_window *win); 70 + void vscreens_merge(rp_vscreen *from, rp_vscreen *to); 71 + 72 + void set_current_vscreen(rp_vscreen *v); 73 + 74 + rp_window *vscreen_last_window_by_class(rp_vscreen *v, char *class); 75 + rp_window *vscreen_last_window_by_class_complement(rp_vscreen *v, char *class); 76 77 #define rp_current_vscreen (rp_current_screen->current_vscreen) 78
+17 -17
window.c
··· 140 cur->pid = pid; 141 cur->terminated = 0; 142 cur->frame = current_frame(rp_current_vscreen); 143 - cur->group = rp_current_group; 144 cur->vscreen = rp_current_vscreen; 145 cur->screen = rp_current_screen; 146 cur->window_mapped = 0; ··· 156 { 157 struct rp_child_info *child_info; 158 rp_window *new_window; 159 - rp_group *group = NULL; 160 int frame_num = -1; 161 162 new_window = xmalloc(sizeof(rp_window)); ··· 203 child_info->vscreen, child_info->frame); 204 205 PRINT_DEBUG(("frame=%p\n", frame)); 206 - group = groups_find_group_by_group(child_info->group); 207 if (frame) 208 frame_num = frame->number; 209 /* Only map the first window in the launch frame. */ ··· 212 } 213 214 /* 215 - * Add the window to the group its pid was launched in or the current 216 * one. 217 */ 218 - if (group) 219 - group_add_window(group, new_window); 220 else 221 - group_add_window(new_window->vscr->current_group, new_window); 222 223 PRINT_DEBUG(("frame_num: %d\n", frame_num)); 224 if (frame_num >= 0) ··· 283 rp_window_elem *cur; 284 285 if (!exact_match) { 286 - list_for_each_entry(cur, &rp_current_group->mapped_windows, 287 node) { 288 if (str_comp(name, window_name(cur->win), strlen(name))) 289 return cur->win; 290 } 291 } else { 292 - list_for_each_entry(cur, &rp_current_group->mapped_windows, 293 node) { 294 if (!strcmp(name, window_name(cur->win))) 295 return cur->win; ··· 300 return NULL; 301 } 302 303 rp_window * 304 find_window_other(rp_vscreen *vscreen) 305 { 306 - return group_last_window(vscreen->current_group); 307 } 308 309 /* ··· 530 sbuf_clear(buffer); 531 find_window_other(rp_current_vscreen); 532 533 - list_for_each_entry(we, &rp_current_group->mapped_windows, node) { 534 if (we->win != current_window()) 535 continue; 536 ··· 555 sbuf_clear(buffer); 556 find_window_other(rp_current_vscreen); 557 558 - /* We only loop through the current group to look for windows. */ 559 - list_for_each_entry(we, &rp_current_group->mapped_windows, node) { 560 PRINT_DEBUG(("%d-%s\n", we->number, window_name(we->win))); 561 562 if (we->win == current_window()) ··· 582 * Only put the delimiter between the windows, and not after 583 * the the last window. 584 */ 585 - if (delim && we->node.next != &rp_current_group->mapped_windows) 586 sbuf_concat(buffer, delim); 587 588 if (we->win == current_window()) { ··· 609 610 list_for_each_safe_entry(cur, iter, tmp, &rp_unmapped_window, node) { 611 list_del(&cur->node); 612 - groups_del_window(cur); 613 free_window(cur); 614 } 615 616 list_for_each_safe_entry(cur, iter, tmp, &rp_mapped_window, node) { 617 list_del(&cur->node); 618 - groups_unmap_window(cur); 619 - groups_del_window(cur); 620 free_window(cur); 621 } 622
··· 140 cur->pid = pid; 141 cur->terminated = 0; 142 cur->frame = current_frame(rp_current_vscreen); 143 cur->vscreen = rp_current_vscreen; 144 cur->screen = rp_current_screen; 145 cur->window_mapped = 0; ··· 155 { 156 struct rp_child_info *child_info; 157 rp_window *new_window; 158 + rp_vscreen *vscreen = NULL; 159 int frame_num = -1; 160 161 new_window = xmalloc(sizeof(rp_window)); ··· 202 child_info->vscreen, child_info->frame); 203 204 PRINT_DEBUG(("frame=%p\n", frame)); 205 + vscreen = child_info->vscreen; 206 if (frame) 207 frame_num = frame->number; 208 /* Only map the first window in the launch frame. */ ··· 211 } 212 213 /* 214 + * Add the window to the vscreen its pid was launched in or the current 215 * one. 216 */ 217 + if (vscreen) 218 + vscreen_add_window(vscreen, new_window); 219 else 220 + vscreen_add_window(new_window->vscr, new_window); 221 222 PRINT_DEBUG(("frame_num: %d\n", frame_num)); 223 if (frame_num >= 0) ··· 282 rp_window_elem *cur; 283 284 if (!exact_match) { 285 + list_for_each_entry(cur, &rp_current_vscreen->mapped_windows, 286 node) { 287 if (str_comp(name, window_name(cur->win), strlen(name))) 288 return cur->win; 289 } 290 } else { 291 + list_for_each_entry(cur, &rp_current_vscreen->mapped_windows, 292 node) { 293 if (!strcmp(name, window_name(cur->win))) 294 return cur->win; ··· 299 return NULL; 300 } 301 302 + /* TODO: remove this */ 303 rp_window * 304 find_window_other(rp_vscreen *vscreen) 305 { 306 + return vscreen_last_window(vscreen); 307 } 308 309 /* ··· 530 sbuf_clear(buffer); 531 find_window_other(rp_current_vscreen); 532 533 + list_for_each_entry(we, &rp_current_vscreen->mapped_windows, node) { 534 if (we->win != current_window()) 535 continue; 536 ··· 555 sbuf_clear(buffer); 556 find_window_other(rp_current_vscreen); 557 558 + /* We only loop through the current vscreen to look for windows. */ 559 + list_for_each_entry(we, &rp_current_vscreen->mapped_windows, node) { 560 PRINT_DEBUG(("%d-%s\n", we->number, window_name(we->win))); 561 562 if (we->win == current_window()) ··· 582 * Only put the delimiter between the windows, and not after 583 * the the last window. 584 */ 585 + if (delim && we->node.next != &rp_current_vscreen->mapped_windows) 586 sbuf_concat(buffer, delim); 587 588 if (we->win == current_window()) { ··· 609 610 list_for_each_safe_entry(cur, iter, tmp, &rp_unmapped_window, node) { 611 list_del(&cur->node); 612 + vscreen_del_window(cur->vscr, cur); 613 free_window(cur); 614 } 615 616 list_for_each_safe_entry(cur, iter, tmp, &rp_mapped_window, node) { 617 list_del(&cur->node); 618 + vscreen_unmap_window(cur->vscr, cur); 619 + vscreen_del_window(cur->vscr, cur); 620 free_window(cur); 621 } 622