Fix segv on group member exit + associated cleanups.
SVN revision: 10452
This commit is contained in:
parent
b43495e0d5
commit
3acff5462a
7
src/E.h
7
src/E.h
|
@ -1719,6 +1719,7 @@ void BackgroundsInit(void);
|
|||
|
||||
void EwinRefresh(EWin * ewin);
|
||||
void EwinUpdateAfterMoveResize(EWin * ewin, int resize);
|
||||
void EwinFixPosition(EWin * ewin);
|
||||
void ResizeEwin(EWin * ewin, int w, int h);
|
||||
void MoveEwin(EWin * ewin, int x, int y);
|
||||
void MoveResizeEwin(EWin * ewin, int x, int y, int w, int h);
|
||||
|
@ -2240,8 +2241,6 @@ int GrabThePointer(Window win);
|
|||
void UnGrabTheButtons(void);
|
||||
|
||||
/* groups.c */
|
||||
Group *CreateGroup(void);
|
||||
void FreeGroup(Group * g);
|
||||
void CopyGroupConfig(GroupConfig * src, GroupConfig * dest);
|
||||
void BreakWindowGroup(EWin * ewin, Group * g);
|
||||
void BuildWindowGroup(EWin ** ewins, int num);
|
||||
|
@ -2250,14 +2249,12 @@ Group *EwinsInGroup(EWin * ewin1, EWin * ewin2);
|
|||
char **GetWinGroupMemberNames(Group ** groups, int num);
|
||||
void AddEwinToGroup(EWin * ewin, Group * g);
|
||||
void RemoveEwinFromGroup(EWin * ewin, Group * g);
|
||||
void GroupsEwinRemove(EWin * ewin);
|
||||
void ShowHideWinGroups(EWin * ewin, Group * g, char onoff);
|
||||
void ChooseGroupDialog(EWin * ewin, char *message,
|
||||
char group_select, int action);
|
||||
void SaveGroups(void);
|
||||
void LoadGroups(void);
|
||||
void GroupSelectCallback(int val, void *data);
|
||||
void GroupFeatureChangeCallback(int val, void *data);
|
||||
void GroupCallback(int val, void *data);
|
||||
|
||||
/* handlers.c */
|
||||
void SignalsSetup(void);
|
||||
|
|
|
@ -1419,7 +1419,7 @@ static void
|
|||
DoKill(EWin * ewin, const void *params __UNUSED__, int nogroup)
|
||||
{
|
||||
EWin **gwins;
|
||||
int num, num_groups, i, j;
|
||||
int num, i;
|
||||
|
||||
if (!ewin)
|
||||
EDBUG_RETURN_;
|
||||
|
@ -1427,9 +1427,6 @@ DoKill(EWin * ewin, const void *params __UNUSED__, int nogroup)
|
|||
gwins = ListWinGroupMembersForEwin(ewin, ACTION_KILL, nogroup, &num);
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
num_groups = gwins[i]->num_groups;
|
||||
for (j = 0; j < num_groups; j++)
|
||||
RemoveEwinFromGroup(gwins[i], gwins[i]->groups[0]);
|
||||
ICCCM_Delete(gwins[i]);
|
||||
SoundPlay("SOUND_WINDOW_CLOSE");
|
||||
}
|
||||
|
|
|
@ -1291,16 +1291,6 @@ EwinCreate(Window win)
|
|||
EDBUG_RETURN(ewin);
|
||||
}
|
||||
|
||||
static void
|
||||
EwinRemoveFromGroups(EWin * ewin)
|
||||
{
|
||||
int num, i;
|
||||
|
||||
num = ewin->num_groups;
|
||||
for (i = 0; i < num; i++)
|
||||
RemoveEwinFromGroup(ewin, ewin->groups[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
EwinDestroy(EWin * ewin)
|
||||
{
|
||||
|
@ -1367,7 +1357,7 @@ EwinDestroy(EWin * ewin)
|
|||
Efree(ewin->session_id);
|
||||
FreePmapMask(&ewin->mini_pmm);
|
||||
FreePmapMask(&ewin->icon_pmm);
|
||||
EwinRemoveFromGroups(ewin);
|
||||
GroupsEwinRemove(ewin);
|
||||
Efree(ewin);
|
||||
|
||||
EDBUG_RETURN_;
|
||||
|
@ -1709,6 +1699,33 @@ EwinUpdateAfterMoveResize(EWin * ewin, int resize)
|
|||
ForceUpdatePagersForDesktop(ewin->desktop);
|
||||
}
|
||||
|
||||
void
|
||||
EwinFixPosition(EWin * ewin __UNUSED__)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if (ewin->state != EWIN_STATE_MAPPED)
|
||||
return;
|
||||
|
||||
x = ewin->x;
|
||||
y = ewin->y;
|
||||
if ((ewin->x + ewin->border->border.left + 1) > VRoot.w)
|
||||
x = VRoot.w - ewin->border->border.left - 1;
|
||||
else if ((ewin->x + ewin->w - ewin->border->border.right - 1) < 0)
|
||||
x = 0 - ewin->w + ewin->border->border.right + 1;
|
||||
if ((ewin->y + ewin->border->border.top + 1) > VRoot.h)
|
||||
y = VRoot.h - ewin->border->border.top - 1;
|
||||
else if ((ewin->y + ewin->h - ewin->border->border.bottom - 1) < 0)
|
||||
y = 0 - ewin->h + ewin->border->border.bottom + 1;
|
||||
|
||||
if (x != ewin->x || y != ewin->y)
|
||||
MoveEwin(ewin, x, y);
|
||||
|
||||
#if 0
|
||||
RememberImportantInfoForEwin(ewin);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MR_FLAGS_MOVE 1
|
||||
#define MR_FLAGS_RESIZE 2
|
||||
|
||||
|
|
149
src/groups.c
149
src/groups.c
|
@ -25,8 +25,8 @@
|
|||
|
||||
#define DISABLE_PAGER_ICONBOX_GROUPING 0
|
||||
|
||||
Group *
|
||||
CreateGroup()
|
||||
static Group *
|
||||
GroupCreate(void)
|
||||
{
|
||||
Group *g;
|
||||
double t;
|
||||
|
@ -53,17 +53,17 @@ CreateGroup()
|
|||
EDBUG_RETURN(g);
|
||||
}
|
||||
|
||||
void
|
||||
FreeGroup(Group * g)
|
||||
static void
|
||||
GroupDestroy(Group * g)
|
||||
{
|
||||
if (g)
|
||||
{
|
||||
if (g == current_group)
|
||||
current_group = NULL;
|
||||
if (g->members)
|
||||
Efree(g->members);
|
||||
Efree(g);
|
||||
}
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (g == current_group)
|
||||
current_group = NULL;
|
||||
if (g->members)
|
||||
Efree(g->members);
|
||||
Efree(g);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -107,7 +107,7 @@ BuildWindowGroup(EWin ** ewins, int num)
|
|||
int i;
|
||||
Group *g;
|
||||
|
||||
current_group = g = CreateGroup();
|
||||
current_group = g = GroupCreate();
|
||||
AddItem(g, NULL, g->index, LIST_TYPE_GROUP);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
|
@ -194,83 +194,66 @@ EwinsInGroup(EWin * ewin1, EWin * ewin2)
|
|||
void
|
||||
RemoveEwinFromGroup(EWin * ewin, Group * g)
|
||||
{
|
||||
int i, j, k, i2, x, y;
|
||||
int i, j, k, i2;
|
||||
|
||||
if (ewin && g)
|
||||
if (!ewin || !g)
|
||||
return;
|
||||
|
||||
for (k = 0; k < ewin->num_groups; k++)
|
||||
{
|
||||
if (ewin->groups)
|
||||
/* is the window actually part of the given group */
|
||||
if (ewin->groups[k] != g)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < g->num_members; i++)
|
||||
{
|
||||
for (k = 0; k < ewin->num_groups; k++)
|
||||
if (g->members[i] != ewin)
|
||||
continue;
|
||||
|
||||
/* remove it from the group */
|
||||
for (j = i; j < g->num_members - 1; j++)
|
||||
g->members[j] = g->members[j + 1];
|
||||
g->num_members--;
|
||||
if (g->num_members > 0)
|
||||
g->members =
|
||||
Erealloc(g->members, sizeof(EWin *) * g->num_members);
|
||||
else
|
||||
{
|
||||
/* if the window is actually part of the given group */
|
||||
if (ewin->groups[k] == g)
|
||||
{
|
||||
for (i = 0; i < g->num_members; i++)
|
||||
{
|
||||
if (g->members[i] == ewin)
|
||||
{
|
||||
/* remove it from the group */
|
||||
for (j = i; j < g->num_members - 1; j++)
|
||||
g->members[j] = g->members[j + 1];
|
||||
g->num_members--;
|
||||
if (g->num_members > 0)
|
||||
g->members =
|
||||
Erealloc(g->members,
|
||||
sizeof(EWin *) *
|
||||
g->num_members);
|
||||
else
|
||||
{
|
||||
RemoveItem((char *)g, 0,
|
||||
LIST_FINDBY_POINTER,
|
||||
LIST_TYPE_GROUP);
|
||||
FreeGroup(g);
|
||||
}
|
||||
/* and remove the group from the groups that the window is in */
|
||||
for (i2 = k; i2 < ewin->num_groups - 1; i2++)
|
||||
ewin->groups[i2] = ewin->groups[i2 + 1];
|
||||
ewin->num_groups--;
|
||||
if (ewin->num_groups <= 0)
|
||||
{
|
||||
Efree(ewin->groups);
|
||||
ewin->groups = NULL;
|
||||
ewin->num_groups = 0;
|
||||
}
|
||||
else
|
||||
ewin->groups =
|
||||
Erealloc(ewin->groups,
|
||||
sizeof(Group *) *
|
||||
ewin->num_groups);
|
||||
SaveGroups();
|
||||
|
||||
x = ewin->x;
|
||||
y = ewin->y;
|
||||
if ((ewin->x + ewin->border->border.left + 1) >
|
||||
VRoot.w)
|
||||
x = VRoot.w - ewin->border->border.left - 1;
|
||||
else if ((ewin->x + ewin->w -
|
||||
ewin->border->border.right - 1) < 0)
|
||||
x = 0 - ewin->w +
|
||||
ewin->border->border.right + 1;
|
||||
if ((ewin->y + ewin->border->border.top + 1) >
|
||||
VRoot.h)
|
||||
y = VRoot.h - ewin->border->border.top - 1;
|
||||
else if ((ewin->y + ewin->h -
|
||||
ewin->border->border.bottom - 1) < 0)
|
||||
y = 0 - ewin->h +
|
||||
ewin->border->border.bottom + 1;
|
||||
|
||||
MoveEwin(ewin, x, y);
|
||||
|
||||
RememberImportantInfoForEwin(ewin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoveItem((char *)g, 0,
|
||||
LIST_FINDBY_POINTER, LIST_TYPE_GROUP);
|
||||
GroupDestroy(g);
|
||||
}
|
||||
|
||||
/* and remove the group from the groups that the window is in */
|
||||
for (i2 = k; i2 < ewin->num_groups - 1; i2++)
|
||||
ewin->groups[i2] = ewin->groups[i2 + 1];
|
||||
ewin->num_groups--;
|
||||
if (ewin->num_groups <= 0)
|
||||
{
|
||||
Efree(ewin->groups);
|
||||
ewin->groups = NULL;
|
||||
ewin->num_groups = 0;
|
||||
}
|
||||
else
|
||||
ewin->groups =
|
||||
Erealloc(ewin->groups, sizeof(Group *) * ewin->num_groups);
|
||||
|
||||
SaveGroups();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GroupsEwinRemove(EWin * ewin)
|
||||
{
|
||||
int num, i;
|
||||
|
||||
num = ewin->num_groups;
|
||||
for (i = 0; i < num; i++)
|
||||
RemoveEwinFromGroup(ewin, ewin->groups[0]);
|
||||
}
|
||||
|
||||
char **
|
||||
GetWinGroupMemberNames(Group ** groups, int num)
|
||||
{
|
||||
|
@ -452,7 +435,7 @@ LoadGroups(void)
|
|||
word(s, 1, ss);
|
||||
if (!strcmp(ss, "NEW:"))
|
||||
{
|
||||
g = CreateGroup();
|
||||
g = GroupCreate();
|
||||
if (g)
|
||||
{
|
||||
word(s, 2, ss);
|
||||
|
@ -568,7 +551,7 @@ ChooseGroup(int val, void *data)
|
|||
data = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
GroupCallback(int val, void *data)
|
||||
{
|
||||
ShowHideWinGroups(tmp_ewin, tmp_groups[tmp_index], SET_OFF);
|
||||
|
|
35
src/ipc.c
35
src/ipc.c
|
@ -3967,13 +3967,11 @@ IPC_ReloadMenus(const char *params, Client * c)
|
|||
}
|
||||
|
||||
static void
|
||||
IPC_GroupInfo(const char *params, Client * c)
|
||||
IPC_GroupInfo(const char *params, Client * c __UNUSED__)
|
||||
{
|
||||
char buf[FILEPATH_LEN_MAX];
|
||||
char buf2[FILEPATH_LEN_MAX];
|
||||
Group **groups = NULL;
|
||||
int num_groups, i, j;
|
||||
char tmp[16];
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
|
@ -3991,18 +3989,14 @@ IPC_GroupInfo(const char *params, Client * c)
|
|||
|
||||
if (!group)
|
||||
{
|
||||
Esnprintf(buf, sizeof(buf), "Error: no such group: %d", gix);
|
||||
CommsSend(c, buf);
|
||||
IpcPrintf("Error: no such group: %d", gix);
|
||||
return;
|
||||
}
|
||||
groups = (Group **) Emalloc(sizeof(Group **));
|
||||
|
||||
groups = (Group **) Emalloc(sizeof(Group **));
|
||||
if (!groups)
|
||||
{
|
||||
Esnprintf(buf, sizeof(buf), "Error: no memory");
|
||||
CommsSend(c, buf);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
groups[0] = group;
|
||||
num_groups = 1;
|
||||
}
|
||||
|
@ -4010,21 +4004,16 @@ IPC_GroupInfo(const char *params, Client * c)
|
|||
{
|
||||
groups = (Group **) ListItemType(&num_groups, LIST_TYPE_GROUP);
|
||||
|
||||
Esnprintf(buf, sizeof(buf), "Number of groups: %d", num_groups);
|
||||
IpcPrintf("Number of groups: %d\n", num_groups);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_groups; i++)
|
||||
{
|
||||
for (j = 0; j < groups[i]->num_members; j++)
|
||||
{
|
||||
Esnprintf(tmp, sizeof(tmp), "%d", groups[i]->index);
|
||||
strcat(buf, tmp);
|
||||
strcat(buf, ": ");
|
||||
strcat(buf, groups[i]->members[j]->icccm.wm_name);
|
||||
strcat(buf, "\n");
|
||||
}
|
||||
Esnprintf(buf2, sizeof(buf2),
|
||||
" index: %d\n" " num_members: %d\n"
|
||||
IpcPrintf("%d: %s\n", groups[i]->index,
|
||||
groups[i]->members[j]->icccm.wm_name);
|
||||
|
||||
IpcPrintf(" index: %d\n" " num_members: %d\n"
|
||||
" iconify: %d\n" " kill: %d\n"
|
||||
" move: %d\n" " raise: %d\n"
|
||||
" set_border: %d\n" " stick: %d\n"
|
||||
|
@ -4034,14 +4023,10 @@ IPC_GroupInfo(const char *params, Client * c)
|
|||
groups[i]->cfg.move, groups[i]->cfg.raise,
|
||||
groups[i]->cfg.set_border, groups[i]->cfg.stick,
|
||||
groups[i]->cfg.shade, groups[i]->cfg.mirror);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
|
||||
if (groups)
|
||||
Efree(groups);
|
||||
|
||||
if (buf)
|
||||
CommsSend(c, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -3988,7 +3988,7 @@ CB_ConfigureGroup(int val, void *data)
|
|||
data = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
GroupSelectCallback(int val, void *data)
|
||||
{
|
||||
DialogItemCheckButtonSetState(di_border, tmp_cfgs[val].set_border);
|
||||
|
@ -4005,7 +4005,7 @@ GroupSelectCallback(int val, void *data)
|
|||
tmp_current_group = val;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
GroupFeatureChangeCallback(int val, void *data)
|
||||
{
|
||||
switch (val)
|
||||
|
|
Loading…
Reference in New Issue