Skip to content

Commit a20f062

Browse files
committed
stashed_change_wsitem
1 parent bd2efe0 commit a20f062

File tree

3 files changed

+73
-118
lines changed

3 files changed

+73
-118
lines changed

2bwm.c

+69-115
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static void cleanup(void);
118118
static uint32_t getwmdesktop(xcb_drawable_t);
119119
static void addtoworkspace(struct client *, uint32_t);
120120
static void grabbuttons(struct client *);
121-
static void delfromworkspace(struct client *, uint32_t);
121+
static void delfromworkspace(struct client *);
122122
static void unkillablewindow(struct client *);
123123
static void fixwindow(struct client *);
124124
static uint32_t getcolor(const char *);
@@ -188,10 +188,13 @@ focusnext(const Arg *arg)
188188
}
189189

190190
void
191-
delfromworkspace(struct client *client, uint32_t ws)
191+
delfromworkspace(struct client *client)
192192
{
193-
delitem(&wslist[ws], client->wsitem[ws]);
194-
client->wsitem[ws] = NULL;
193+
if(client->ws < 0)
194+
return;
195+
delitem(&wslist[client->ws], client->wsitem);
196+
client->wsitem = NULL;
197+
client->ws = -1;
195198
}
196199

197200
void
@@ -459,7 +462,8 @@ addtoworkspace(struct client *client, uint32_t ws)
459462
return;
460463

461464
/* Remember our place in the workspace window list. */
462-
client->wsitem[ws] = item;
465+
client->wsitem = item;
466+
client->ws = ws;
463467
item->data = client;
464468

465469
/* Set window hint property so we can survive a crash. Like "fixed" */
@@ -482,36 +486,31 @@ changeworkspace_helper(const uint32_t ws)
482486
xcb_query_pointer_reply_t *pointer;
483487
struct client *client;
484488
struct item *item;
485-
486-
487489
if (ws == curws)
488490
return;
489-
490491
xcb_ewmh_set_current_desktop(ewmh, 0, ws);
492+
/* Go through list of current ws.
493+
* Unmap everything that isn't fixed. */
491494
for (item=wslist[curws]; item != NULL;) {
492-
/* Go through list of current ws.
493-
* Unmap everything that isn't fixed. */
494495
client = item->data;
495496
item = item->next;
496497
setborders(client,false);
497-
if (!client->fixed)
498+
if (!client->fixed){
498499
xcb_unmap_window(conn, client->id);
499-
else{
500+
}else{
501+
// correct order is delete first add later.
502+
delfromworkspace(client);
500503
addtoworkspace(client,ws);
501-
delfromworkspace(client,curws);
502504
}
503505
}
504-
505506
for (item=wslist[ws]; item != NULL; item = item->next) {
506507
client = item->data;
507508
if (!client->fixed && !client->iconic)
508509
xcb_map_window(conn, client->id);
509510
}
510-
511511
curws = ws;
512512
pointer = xcb_query_pointer_reply(conn, xcb_query_pointer(conn,
513513
screen->root), 0);
514-
515514
if(pointer == NULL)
516515
setfocus(NULL);
517516
else {
@@ -599,9 +598,9 @@ sendtoworkspace(const Arg *arg)
599598
{
600599
if (NULL == focuswin||focuswin->fixed||arg->i == curws)
601600
return;
602-
601+
// correct order is delete first add later.
602+
delfromworkspace(focuswin);
603603
addtoworkspace(focuswin, arg->i);
604-
delfromworkspace(focuswin, curws);
605604
xcb_unmap_window(conn, focuswin->id);
606605
xcb_flush(conn);
607606
}
@@ -643,14 +642,10 @@ forgetclient(struct client *client)
643642

644643
if (NULL == client)
645644
return;
646-
647645
if (client->id == top_win)
648646
top_win = 0;
649-
650-
/* Delete client from the workspace lists it belongs to.
651-
* (can be on several) */
652-
for (ws=0; ws < WORKSPACES; ws ++)
653-
if (NULL != client->wsitem[ws]) delfromworkspace(client, ws);
647+
/* Delete client from the workspace list it belongs to. */
648+
delfromworkspace(client);
654649

655650
/* Remove from global window list. */
656651
freeitem(&winlist, NULL, client->winitem);
@@ -960,8 +955,8 @@ setupwin(xcb_window_t win)
960955
client->winitem = item;
961956

962957
/* Initialize workspace pointers. */
963-
for (ws=0; ws < WORKSPACES; ws ++)
964-
client->wsitem[ws] = NULL;
958+
client->wsitem = NULL;
959+
client->ws = -1;
965960

966961
/* Get window geometry. */
967962
getgeom(&client->id, &client->x, &client->y, &client->width,
@@ -1503,91 +1498,56 @@ movewindow(xcb_drawable_t win, const int16_t x, const int16_t y)
15031498

15041499
xcb_flush(conn);
15051500
}
1506-
1507-
/* Change focus to next in window ring. */
15081501
void
15091502
focusnext_helper(bool arg)
15101503
{
15111504
struct client *cl = NULL;
1512-
/* no windows on current workspace*/
1513-
if (NULL == wslist[curws])
1505+
struct item *head = wslist[curws];
1506+
struct item *tail,*item = NULL;
1507+
// no windows on current workspace
1508+
if (NULL == head)
15141509
return;
1515-
/* If we currently have no focus focus first in list. */
1516-
if (NULL == focuswin || NULL == focuswin->wsitem[curws]) {
1517-
cl = wslist[curws]->data;
1518-
while (cl->iconic==true && cl->wsitem[curws]->next!=NULL)
1519-
cl = cl->wsitem[curws]->next->data;
1520-
} else {
1510+
// if no focus on current workspace, find first valid item on list.
1511+
if (NULL == focuswin || focuswin->ws != curws) {
1512+
for(item = head;item != NULL;item = item->next){
1513+
cl = item->data;
1514+
if(!cl->iconic)
1515+
break;
1516+
}
1517+
}else{
1518+
// find tail of list and make list circular.
1519+
for(tail = head = item = wslist[curws]; item != NULL;
1520+
tail = item,item = item->next);
1521+
head->prev = tail;
1522+
tail->next = head;
15211523
if (arg == TWOBWM_FOCUS_NEXT) {
1522-
if (NULL == focuswin->wsitem[curws]->prev) {
1523-
/* We were at the head of list.
1524-
* Focusing on last window in list unless
1525-
* we were already there.*/
1526-
cl = wslist[curws]->data;
1527-
1528-
/* Go to the end of the list */
1529-
while(cl->wsitem[curws]->next != NULL)
1530-
cl = cl->wsitem[curws]->next->data;
1531-
/* walk backward until we find
1532-
* a window that isn't iconic */
1533-
while(cl->iconic == true)
1534-
cl = cl->wsitem[curws]->prev->data;
1535-
} else
1536-
if (focuswin!=wslist[curws]->data) {
1537-
cl = focuswin->wsitem[curws]->prev->data;
1538-
while (cl->iconic == true
1539-
&& cl->wsitem[curws]->prev
1540-
!= NULL)
1541-
cl = cl->wsitem[curws]->prev->data;
1542-
/* move to the head an didn't find a
1543-
* window to focus so move to the end
1544-
* starting from the focused win */
1545-
if(cl->iconic == true) {
1546-
cl = focuswin;
1547-
/* Go to the end of the list */
1548-
while(cl->wsitem[curws]->next
1549-
!= NULL)
1550-
cl = cl->wsitem[curws]->next->data;
1551-
while (cl->iconic == true)
1552-
cl = cl->wsitem[curws]->prev->data;
1553-
}
1554-
}
1555-
} else {
1556-
/* We were at the tail of list.
1557-
* Focusing on last window in list unless we
1558-
* were already there.*/
1559-
if (NULL == focuswin->wsitem[curws]->next) {
1560-
/* We were at the end of list.
1561-
* Focusing on first window in list unless we
1562-
* were already there. */
1563-
cl = wslist[curws]->data;
1564-
while(cl->iconic && cl->wsitem[curws]->next
1565-
!= NULL)
1566-
cl = cl->wsitem[curws]->next->data;
1567-
} else {
1568-
cl = focuswin->wsitem[curws]->next->data;
1569-
while (cl->iconic == true
1570-
&& cl->wsitem[curws]->next
1571-
!= NULL)
1572-
cl = cl->wsitem[curws]->next->data;
1573-
/* we reached the end of the list without a
1574-
* new win to focus, so reloop from the head */
1575-
if (cl->iconic == true) {
1576-
cl = wslist[curws]->data;
1577-
while(cl->iconic
1578-
&& cl->wsitem[curws]->next
1579-
!= NULL)
1580-
cl = cl->wsitem[curws]->next->data;
1581-
}
1582-
}
1524+
// start from focus next and find first valid item on circular list.
1525+
head = item = focuswin->wsitem->next;
1526+
do{
1527+
cl = item->data;
1528+
if(!cl->iconic)
1529+
break;
1530+
item = item->next;
1531+
}while(item != head);
1532+
}else{
1533+
// start from focus previous and find first valid on circular list.
1534+
tail = item = focuswin->wsitem->prev;
1535+
do{
1536+
cl = item->data;
1537+
if(!cl->iconic)
1538+
break;
1539+
item = item->prev;
1540+
}while(item != tail);
15831541
}
1542+
// restore list.
1543+
wslist[curws]->prev->next = NULL;
1544+
wslist[curws]->prev = NULL;
15841545
}
1585-
/* if NULL focuswin */
1586-
if (NULL != cl && focuswin != cl && cl->iconic==false) {
1587-
raisewindow(cl->id);
1588-
centerpointer(cl->id,cl);
1589-
setfocus(cl);
1590-
}
1546+
if(!item || !(cl = item->data) || cl->iconic)
1547+
return;
1548+
raisewindow(cl->id);
1549+
centerpointer(cl->id,cl);
1550+
setfocus(cl);
15911551
}
15921552
/* Mark window win as unfocused. */
15931553
void setunfocus(void)
@@ -1609,8 +1569,9 @@ findclient(const xcb_drawable_t *win)
16091569
for (item = winlist; item != NULL; item = item->next) {
16101570
client = item->data;
16111571

1612-
if (*win == client->id)
1572+
if (*win == client->id){
16131573
return client;
1574+
}
16141575
}
16151576

16161577
return NULL;
@@ -1856,7 +1817,7 @@ snapwindow(struct client *client)
18561817
void
18571818
mousemove(const int16_t rel_x, const int16_t rel_y)
18581819
{
1859-
if (focuswin == NULL || focuswin->wsitem[curws] == NULL)
1820+
if (focuswin == NULL || focuswin->ws != curws)
18601821
return;
18611822

18621823
focuswin->x = rel_x;
@@ -2282,15 +2243,12 @@ getpointer(const xcb_drawable_t *win, int16_t *x, int16_t *y)
22822243

22832244
pointer = xcb_query_pointer_reply(conn,
22842245
xcb_query_pointer(conn, *win), 0);
2285-
2246+
if (NULL == pointer)
2247+
return false;
22862248
*x = pointer->win_x;
22872249
*y = pointer->win_y;
22882250

22892251
free(pointer);
2290-
2291-
if (NULL == pointer)
2292-
return false;
2293-
22942252
return true;
22952253
}
22962254

@@ -2975,7 +2933,6 @@ unmapnotify(xcb_generic_event_t *ev)
29752933
{
29762934
xcb_unmap_notify_event_t *e = (xcb_unmap_notify_event_t *)ev;
29772935
struct client *client = NULL;
2978-
29792936
/*
29802937
* Find the window in our current workspace list, then forget about it.
29812938
* Note that we might not know about the window we got the UnmapNotify
@@ -2990,14 +2947,11 @@ unmapnotify(xcb_generic_event_t *ev)
29902947
* If we do this, we need to keep track of our own windows and
29912948
* ignore UnmapNotify on them.
29922949
*/
2993-
29942950
client = findclient( & e->window);
2995-
if (NULL == client || client->wsitem[curws]==NULL)
2951+
if (NULL == client || client->ws != curws)
29962952
return;
2997-
29982953
if (focuswin!=NULL && client->id == focuswin->id)
29992954
focuswin = NULL;
3000-
30012955
if (client->iconic == false)
30022956
forgetclient(client);
30032957

config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static key keys[] = {
160160
{ MOD |SHIFT , XK_v, sendtonextworkspace,{}},
161161
{ MOD |SHIFT , XK_c, sendtoprevworkspace,{}},
162162
// Iconify the window
163-
//{ MOD , XK_i, hide, {}},
163+
{ MOD , XK_i, hide, {}},
164164
// Make the window unkillable
165165
{ MOD , XK_a, unkillable, {}},
166166
// Make the window appear always on top

types.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct monitor {
77
};
88
typedef union {
99
const char** com;
10-
const int8_t i;
10+
const uint32_t i;
1111
} Arg;
1212
typedef struct {
1313
unsigned int mod;
@@ -36,7 +36,8 @@ struct client { // Everything we know about a window.
3636
bool fixed,unkillable,vertmaxed,hormaxed,maxed,verthor,ignore_borders,iconic;
3737
struct monitor *monitor; // The physical output this window is on.
3838
struct item *winitem; // Pointer to our place in global windows list.
39-
struct item *wsitem[WORKSPACES];// Pointer to our place in every workspace window list.
39+
struct item *wsitem; // Pointer to workspace window list.
40+
int ws; // In which workspace this window belongs to.
4041
};
4142
struct winconf { // Window configuration data.
4243
int16_t x, y;

0 commit comments

Comments
 (0)