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 *EwinFindByFrame(Window win);
EWin *EwinFindByClient(Window win); EWin *EwinFindByClient(Window win);
EWin *EwinFindByChildren(Window win); EWin *EwinFindByChildren(Window win);
EWin *EwinFindByString(const char *win, int type);
EWin **EwinListTransients(const EWin * ewin, int *num, int group); EWin **EwinListTransients(const EWin * ewin, int *num, int group);
EWin **EwinListTransientFor(const EWin * ewin, int *num); EWin **EwinListTransientFor(const EWin * ewin, int *num);

View File

@ -96,52 +96,6 @@ EwinFindByChildren(Window win)
return NULL; 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 ** EWin **
ListWinGroupMembersForEwin(const EWin * ewin, int action, char nogroup, ListWinGroupMembersForEwin(const EWin * ewin, int action, char nogroup,
int *pnum) int *pnum)

333
src/ipc.c
View File

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