IPC window operation tweaks:

- Enable targeting multiple windows (wildcard in name spec).
- Enable non-group operations.


SVN revision: 22964
This commit is contained in:
Kim Woelders 2006-05-28 09:54:39 +00:00
parent e571517853
commit d05850e996
3 changed files with 230 additions and 140 deletions

View File

@ -387,7 +387,6 @@ EWin *EwinFindByPtr(const EWin * ewin);
EWin *EwinFindByFrame(Window win);
EWin *EwinFindByClient(Window win);
EWin *EwinFindByChildren(Window win);
EWin *EwinFindByString(const char *win, int type);
EWin **EwinListTransients(const EWin * ewin, int *num, int group);
EWin **EwinListTransientFor(const EWin * ewin, int *num);

View File

@ -96,52 +96,6 @@ EwinFindByChildren(Window win)
return NULL;
}
EWin *
EwinFindByString(const char *match, int type)
{
EWin *ewin = NULL;
EWin *const *ewins;
int i, num, len;
char ewinid[FILEPATH_LEN_MAX];
const char *name;
len = strlen(match);
if (len <= 0)
goto done;
ewins = EwinListGetAll(&num);
if (ewins == NULL)
goto done;
for (i = 0; i < num; i++)
{
if (type == '+')
{
/* Match start of window ID */
sprintf(ewinid, "%x", (unsigned)_EwinGetClientXwin(ewins[i]));
if (strncmp(ewinid, match, len))
continue;
}
else if (type == '=')
{
/* Match name (substring) */
name = ewins[i]->icccm.wm_name;
if (!name)
continue;
if (!strstr(name, match))
continue;
}
else
goto done;
ewin = ewins[i];
break;
}
done:
return ewin;
}
EWin **
ListWinGroupMembersForEwin(const EWin * ewin, int action, char nogroup,
int *pnum)

323
src/ipc.c
View File

@ -79,28 +79,132 @@ IpcPrintf(const char *fmt, ...)
bufsiz += len;
}
static EWin *
IpcFindEwin(const char *windowid)
static EWin **
IpcFindEwins(const char *match, int *pnum, int *pflags)
{
unsigned int win;
EWin *ewin, **lst;
EWin *const *ewins;
int type;
int i, num, len, nfound, match_one, flags;
if (!strcmp(windowid, "*") || !strcmp(windowid, "%")
|| !strcmp(windowid, "current"))
return GetContextEwin();
if (pnum)
*pnum = 0;
if (isdigit(windowid[0]))
if (!match || !match[0])
return NULL;
ewin = NULL;
flags = 0;
if (!strcmp(match, "*") || !strcmp(match, "=") || !strcmp(match, "current"))
{
sscanf(windowid, "%x", &win);
return EwinFindByChildren(win);
ewin = GetContextEwin();
if (match[0] == '=')
flags = 1; /* Nogroup */
goto do_one;
}
if (windowid[0] == '+')
return EwinFindByString(windowid + 1, '+');
if (isdigit(match[0]))
{
unsigned int win;
if (windowid[0] == '=')
return EwinFindByString(windowid + 1, '=');
sscanf(match, "%x", &win);
ewin = EwinFindByChildren(win);
goto do_one;
}
return EwinFindByString(windowid, '=');
match_one = 1;
if (!strcmp(match, "all"))
{
type = 'a';
match_one = 0;
flags = 1; /* Nogroup */
}
else if (match[0] == '=')
{
type = 's';
match++;
flags = 1; /* Nogroup */
}
else if (strchr(match, '*'))
{
type = 'w';
match_one = 0;
flags = 1; /* Nogroup */
}
else
{
type = 's';
}
len = strlen(match);
if (len <= 0)
return NULL;
ewins = EwinListGetAll(&num);
if (!ewins)
return NULL;
nfound = 0;
lst = NULL;
for (i = 0; i < num; i++)
{
ewin = ewins[i];
if (type == 'a') /* All */
{
}
else if (type == 'w') /* Wildcard */
{
if (!matchregexp(match, ewin->icccm.wm_name))
continue;
}
else /* Match name (substring) */
{
const char *name;
name = ewin->icccm.wm_name;
if (!name)
continue;
if (!strstr(name, match))
continue;
}
nfound++;
lst = Erealloc(lst, nfound * sizeof(EWin *));
lst[nfound - 1] = ewin;
if (match_one)
break;
}
goto done;
do_one:
if (!ewin)
return NULL;
nfound = 1;
lst = Emalloc(sizeof(EWin *));
if (!lst)
return NULL;
lst[0] = ewin;
done:
if (pnum)
*pnum = nfound;
if (pflags)
*pflags = flags;
return lst;
}
static EWin *
IpcFindEwin(const char *match)
{
EWin *ewin, **lst;
lst = IpcFindEwins(match, NULL, NULL);
if (!lst)
return NULL;
ewin = lst[0];
Efree(lst);
return ewin;
}
static int
@ -315,18 +419,33 @@ static void
IPC_WinList(const char *params, Client * c __UNUSED__)
{
static const char *const TxtPG[] = { "NW", "NE", "SW", "SE" };
char param1[FILEPATH_LEN_MAX];
EWin *const *lst, *e;
char format[8];
const char *match;
EWin **lst, *e;
int num, i;
param1[0] = '\0';
word(params, 1, param1);
format[0] = '\0';
match = params;
if (match)
{
num = 0;
sscanf(params, "%8s %n", format, &num);
match += num;
}
if (!match || !match[0])
match = "all";
lst = IpcFindEwins(match, &num, NULL);
if (!lst)
{
IpcPrintf("No windows matching %s\n", match);
return;
}
lst = EwinListGetAll(&num);
for (i = 0; i < num; i++)
{
e = lst[i];
switch (param1[0])
switch (format[0])
{
case '\0':
IpcPrintf("%#lx : %s\n", _EwinGetClientXwin(e),
@ -366,8 +485,7 @@ IPC_WinList(const char *params, Client * c __UNUSED__)
break;
}
}
if (num <= 0)
IpcPrintf("No windows\n");
Efree(lst);
}
#if 0 /* TBD */
@ -398,51 +516,15 @@ doMoveConstrainedNoGroup(EWin * ewin, const char *params)
#endif
static void
IPC_WinOps(const char *params, Client * c __UNUSED__)
IpcWinop(const WinOp * wop, EWin * ewin, const char *prm)
{
EWin *ewin;
char windowid[FILEPATH_LEN_MAX];
char operation[FILEPATH_LEN_MAX];
char param1[FILEPATH_LEN_MAX];
const char *p;
const WinOp *wop;
char param1[128], param2[128];
unsigned int val;
char on;
int a, b;
if (params == NULL)
{
IpcPrintf("Error: no window specified");
goto done;
}
operation[0] = 0;
param1[0] = 0;
windowid[0] = 0;
word(params, 1, windowid);
ewin = IpcFindEwin(windowid);
if (!ewin)
{
IpcPrintf("Error: no such window: %s", windowid);
goto done;
}
word(params, 2, operation);
word(params, 3, param1);
if (!operation[0])
{
IpcPrintf("Error: no operation specified");
goto done;
}
wop = EwinOpFind(operation);
if (!wop)
{
IpcPrintf("Error: unknown operation");
goto done;
}
param1[0] = param2[0] = '\0';
sscanf(prm, "%128s %128s", param1, param2);
switch (wop->op)
{
@ -466,19 +548,18 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
break;
case EWIN_OP_TITLE:
p = atword(params, 3);
if (!p)
if (!prm[0])
{
IpcPrintf("Error: no title specified");
goto done;
}
if (!strcmp(p, "?"))
if (!strcmp(prm, "?"))
{
IpcPrintf("title: %s", ewin->icccm.wm_name);
goto done;
}
_EFREE(ewin->icccm.wm_name);
ewin->icccm.wm_name = Estrdup(p);
ewin->icccm.wm_name = Estrdup(prm);
XStoreName(disp, _EwinGetClientXwin(ewin), ewin->icccm.wm_name);
EwinBorderUpdateInfo(ewin);
break;
@ -555,14 +636,15 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
else if (!strcmp(param1, "move"))
{
a = b = 0;
sscanf(params, "%*s %*s %*s %i %i", &a, &b);
sscanf(prm, "%*s %i %i", &a, &b);
EwinMoveToArea(ewin, ewin->area_x + a, ewin->area_y + b);
}
else
{
a = ewin->area_x;
b = ewin->area_y;
sscanf(params, "%*s %*s %i %i", &a, &b);
sscanf(param1, "%i", &a);
sscanf(param2, "%i", &b);
EwinMoveToArea(ewin, a, b);
}
break;
@ -575,7 +657,7 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
}
if (!strcmp(param1, "ptr"))
{
ActionMoveStart(ewin, 1, 0, 0);
ActionMoveStart(ewin, 1, 0, Mode.nogroup);
}
else if (!strcmp(param1, "?"))
{
@ -589,7 +671,10 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
}
else
{
sscanf(params, "%*s %*s %i %i", &a, &b);
a = EoGetX(ewin);
b = EoGetY(ewin);
sscanf(param1, "%i", &a);
sscanf(param2, "%i", &b);
EwinOpMove(ewin, OPSRC_USER, a, b);
}
break;
@ -620,7 +705,10 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
}
else
{
sscanf(params, "%*s %*s %i %i", &a, &b);
a = ewin->client.w;
b = ewin->client.h;
sscanf(param1, "%i", &a);
sscanf(param2, "%i", &b);
EwinOpResize(ewin, OPSRC_USER, a, b);
}
break;
@ -628,8 +716,8 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
case EWIN_OP_MOVE_REL:
if (!param1[0])
goto done;
sscanf(params, "%*s %*s %i %i", &a, &b);
a = b = 0;
sscanf(prm, "%i %i", &a, &b);
a += EoGetX(ewin);
b += EoGetY(ewin);
EwinOpMove(ewin, OPSRC_USER, a, b);
@ -638,8 +726,8 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
case EWIN_OP_SIZE_REL:
if (!param1[0])
goto done;
sscanf(params, "%*s %*s %i %i", &a, &b);
a = b = 0;
sscanf(prm, "%i %i", &a, &b);
a += ewin->client.w;
b += ewin->client.h;
EwinOpResize(ewin, OPSRC_USER, a, b);
@ -708,7 +796,7 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
break;
case EWIN_OP_SNAP:
SnapshotEwinParse(ewin, atword(params, 3));
SnapshotEwinParse(ewin, prm);
break;
case EWIN_OP_SKIP_LISTS:
@ -810,6 +898,58 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
return;
}
static void
IPC_WinOps(const char *params, Client * c __UNUSED__)
{
char match[128];
char operation[128];
const char *p;
EWin **lst;
int i, num, flags;
const WinOp *wop;
if (!params)
{
IpcPrintf("Error: no window specified");
return;
}
match[0] = operation[0] = '\0';
num = 0;
sscanf(params, "%128s %128s %n", match, operation, &num);
p = params + num;
if (!operation[0])
{
IpcPrintf("Error: no operation specified");
return;
}
wop = EwinOpFind(operation);
if (!wop)
{
IpcPrintf("Error: unknown operation");
return;
}
lst = IpcFindEwins(match, &num, &flags);
if (!lst)
{
IpcPrintf("No windows matching %s\n", match);
return;
}
if (flags)
Mode.nogroup = 1;
for (i = 0; i < num; i++)
IpcWinop(wop, lst[i], p);
Mode.nogroup = 0;
Efree(lst);
}
static void
IPC_Remember(const char *params, Client * c __UNUSED__)
{
@ -1045,30 +1185,27 @@ EwinShowInfo(const EWin * ewin)
static void
IPC_EwinInfo(const char *params, Client * c __UNUSED__)
{
char param1[FILEPATH_LEN_MAX];
EWin *ewin;
char match[FILEPATH_LEN_MAX];
EWin **lst;
int i, num;
if (params == NULL)
if (!params)
return;
sscanf(params, "%1000s", param1);
sscanf(params, "%1000s", match);
if (!strcmp(param1, "all"))
lst = IpcFindEwins(match, &num, NULL);
if (!lst)
{
EWin *const *lst;
int i, num;
lst = EwinListGetAll(&num);
for (i = 0; i < num; i++)
EwinShowInfo(lst[i]);
IpcPrintf("No windows matching %s\n", match);
return;
}
else
for (i = 0; i < num; i++)
{
ewin = IpcFindEwin(param1);
if (ewin)
EwinShowInfo(ewin);
else
IpcPrintf("No matching EWin found\n");
EwinShowInfo(lst[i]);
if (i != num - 1)
IpcPrintf("\n");
}
}