Skip to content

Commit

Permalink
Add -Await option to icesh to wait for and select new client windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
gijsbers committed Jun 28, 2024
1 parent 5c00dfc commit 7c5ff31
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
5 changes: 5 additions & 0 deletions man/icesh.pod
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ the same process identifier as one of the selected windows.

Selects the IceWM taskbar.

=item B<-A>, B<-Await>

Wait for one or more new client windows to appear and make that the new
selection.

=back

=head2 FILTER OPTIONS
Expand Down
74 changes: 66 additions & 8 deletions src/icesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ class YProperty {
if (type) fType = type;
if (leng) fLength = leng;
if (fWindow && fProp && fLength) {
fRequest = fProp;
fStatus = XGetWindowProperty(display, fWindow, fProp, 0L,
fLength, False, fType, &type,
&fFormat, &fCount, &fAfter, &fData);
Expand Down Expand Up @@ -559,7 +560,11 @@ class YProperty {
int fFormat, fStatus;

YProperty& operator=(const YProperty& copy);

public:
static Atom fRequest;
};
Atom YProperty::fRequest;

class YCardinal : public YProperty {
public:
Expand Down Expand Up @@ -999,8 +1004,11 @@ class YWindowTree {
}
}

static YWindowTree lastClientList;

void getClientList() {
getWindowList(ATOM_NET_CLIENT_LIST);
lastClientList = *this;
}

void getSystrayList() {
Expand Down Expand Up @@ -1357,6 +1365,7 @@ class YWindowTree {
vector<Window> fChildren;
YTreeLeaf fLeaf;
};
YWindowTree YWindowTree::lastClientList;

YTreeIter::operator Window() const { return fTree[fIndex]; }
YTreeLeaf* YTreeIter::operator->() { return fTree.leaf(fIndex); }
Expand Down Expand Up @@ -1470,6 +1479,7 @@ class IceSh {
bool desktop();
bool wmcheck();
bool change();
void await();
bool loop();
bool pick();
bool sync();
Expand Down Expand Up @@ -2861,6 +2871,46 @@ bool IceSh::guiEvents()
return true;
}

void IceSh::await()
{
windowList.release();
YWindowTree old = YWindowTree::lastClientList;
if (old == false)
old.getClientList();

running = true;
sighandler_t previous = signal(SIGINT, catcher);
XSelectInput(display, root, PropertyChangeMask);
while (running) {
if (XPending(display)) {
XEvent xev = { 0 };
XNextEvent(display, &xev);
if (xev.type == PropertyNotify &&
xev.xproperty.atom == ATOM_NET_CLIENT_LIST &&
xev.xproperty.state == PropertyNewValue)
{
YWindowTree now;
now.getClientList();
for (YTreeIter window(now); window; ++window) {
if (old.have(window) == false)
windowList.append(window);
}
if (windowList)
break;
old = now;
}
}
else {
int fd = ConnectionNumber(display);
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
select(fd + 1, SELECT_TYPE_ARG234 &rfds, nullptr, nullptr, nullptr);
}
}
signal(SIGINT, previous);
}

bool IceSh::icewmAction()
{
static const Symbol sa[] = {
Expand Down Expand Up @@ -4361,6 +4411,11 @@ void IceSh::flag(char* arg)
selecting = true;
return;
}
if (isOptArg(arg, "-Await", "")) {
await();
selecting = true;
return;
}
if (isOptArg(arg, "+group", "")) {
extendGroup();
return;
Expand Down Expand Up @@ -4900,19 +4955,22 @@ int IceSh::xerrors(Display* dpy, XErrorEvent* evt) {
}

void IceSh::xerror(XErrorEvent* evt) {
char message[80], req[80], number[80];
const int size = 80;
char message[size], req[size], number[size];

if (evt->request_code == X_GetWindowAttributes)
return;

snprintf(number, 80, "%d", evt->request_code);
XGetErrorDatabaseText(display, "XRequest",
number, "",
req, sizeof(req));
if (evt->request_code == X_GetProperty)
snprintf(req, size, "X_GetProperty(%s)", atomName(YProperty::fRequest));
else {
snprintf(number, size, "%d", evt->request_code);
XGetErrorDatabaseText(display, "XRequest", number,
"", req, sizeof(req));
}
if (req[0] == 0)
snprintf(req, 80, "[request_code=%d]", evt->request_code);
snprintf(req, size, "[request_code=%d]", evt->request_code);

if (XGetErrorText(display, evt->error_code, message, 80) != Success)
if (XGetErrorText(display, evt->error_code, message, size) != Success)
*message = '\0';

tlog("%s(0x%lx): %s", req, evt->resourceid, message);
Expand Down

0 comments on commit 7c5ff31

Please sign in to comment.