make dialog clients be iconified/re-screened with their respective leader client

This commit is contained in:
Lucas de Sena
2026-02-04 16:12:48 +00:00
parent 0a400a366a
commit 6685043266
10 changed files with 107 additions and 50 deletions

View File

@@ -153,6 +153,9 @@ void open_fscrn(Client *c)
c->fsscr = scr = openscreen(NULL, scr->root);
c->reparenting = 1;
XReparentWindow(dpy, c->window, scr->back, 0, 0);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next)
if (dialog->leader == c)
reparent_client(c->fsscr, dialog);
XResizeWindow(dpy, c->window, scr->width, scr->height);
realizescreens();
scr = c->fsscr;
@@ -177,6 +180,9 @@ void close_fscrn(Client *c, int state)
scr = c->scr;
if (state != IconicState)
XMapWindow(dpy, c->parent);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next)
if (dialog->leader == c)
reparent_client(c->scr, dialog);
}
void setclientstate(Client *c, int state)
@@ -348,6 +354,9 @@ void rmclient(Client *c)
XDeleteContext(dpy, c->window, client_context);
if (c->sizehints)
XFree(c->sizehints);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next)
if (dialog->leader == c)
dialog->leader = NULL;
free(c);
}
@@ -432,6 +441,7 @@ reparent_client(Scrn *s, Client *client)
client->scr = s;
if(client->parent != client->scr->root)
XReparentWindow(dpy, client->parent, s->back, client->x, client->y);
if (s->deftitle != NULL)
setstringprop(client->window, amiwm_screen, s->deftitle);
sendconfig(client);
}

View File

@@ -15,6 +15,7 @@ struct _Scrn;
* @colormap: current colormap.
*/
typedef struct _Client {
struct _Client *leader;
struct _Client *next;
struct _Scrn *scr, *fsscr;
struct _Icon *icon;

24
frame.c
View File

@@ -183,9 +183,14 @@ void reparent(Client *c)
getwmstate(c);
if(XGetTransientForHint(dpy, c->window, &leader) &&
!XFindContext(dpy, leader, client_context, (XPointer *)&lc))
!XFindContext(dpy, leader, client_context, (XPointer *)&lc) &&
lc != NULL) {
c->leader = lc;
if (lc->fsscr != NULL)
c->scr = lc->fsscr;
else
c->scr = lc->scr;
else if(XGetTextProperty(dpy, c->window, &screen_prop, amiwm_screen)) {
} else if(XGetTextProperty(dpy, c->window, &screen_prop, amiwm_screen)) {
do {
if(s->root == scr->root &&
(!s->deftitle[screen_prop.nitems])&&!strncmp(s->deftitle,
@@ -298,8 +303,9 @@ void reparent(Client *c)
cb=(resizable(c->sizehints)? prefs.sizeborder:0);
c->close=creategadget(c, c->parent, 0, 0, 19, scr->bh);
c->drag=creategadget(c, c->parent, 19, 0, 1, 1);
if(c->wflags&WF_NOICONIFY)
if(c->wflags&WF_NOICONIFY || c->leader != NULL) {
c->iconify=None;
}
else
c->iconify=creategadget(c, c->parent, 0, 0, 23, scr->bh);
if(cb)
@@ -322,6 +328,7 @@ void reparent(Client *c)
#endif
XMapSubwindows(dpy, c->parent);
sendconfig(c);
if (scr->deftitle != NULL)
setstringprop(c->window, amiwm_screen, scr->deftitle);
if(prefs.focus == FOC_CLICKTOTYPE)
XGrabButton(dpy, Button1, AnyModifier, c->parent, True,
@@ -747,16 +754,7 @@ void gadgetunclicked(Client *c, XEvent *e)
/* XWarpPointer(dpy, None, c->zoom, 0, 0, 0, 0, 23/2, scr->h5); */
sendconfig(c);
} else if(w==c->iconify) {
if(!(c->icon))
createicon(c);
XUnmapWindow(dpy, c->parent);
/* XUnmapWindow(dpy, c->window); */
adjusticon(c->icon);
XMapWindow(dpy, c->icon->window);
if(c->icon->labelwidth)
XMapWindow(dpy, c->icon->labelwin);
c->icon->mapped=1;
setclientstate(c, IconicState);
iconify(c);
}
}
clickwindow=None;

9
icc.c
View File

@@ -353,3 +353,12 @@ void handle_client_message(Client *c, XClientMessageEvent *xcme)
}
}
}
Window get_transient_for(Window w)
{
Window transient_for = None;
if (!XGetTransientForHint(dpy, w, &transient_for))
return None;
return transient_for;
}

1
icc.h
View File

@@ -15,6 +15,7 @@ extern void setstringprop(Window, Atom, char *);
extern void propertychange(Client *, Atom);
extern long _getprop(Window, Atom, Atom, long, char **);
extern void getwflags(Client *);
extern Window get_transient_for(Window);
extern Atom wm_state, wm_change_state, wm_protocols, wm_delete, wm_take_focus, wm_colormaps, wm_hints, amiwm_screen, swm_vroot;

48
icon.c
View File

@@ -157,6 +157,11 @@ void reparenticon(Icon *i, Scrn *s, int x, int y)
s->icons=i;
if(i->client) {
reparent_client(s, i->client);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next) {
if (dialog->leader == i->client) {
reparent_client(s, dialog);
}
}
}
if(os)
selecticon(i);
@@ -630,3 +635,46 @@ void free_icon_pms(struct IconPixmaps *pms)
free_color_store(dpy, &pms->cs);
free_color_store(dpy, &pms->cs2);
}
void iconify(Client *c)
{
if(!(c->icon))
createicon(c);
XUnmapWindow(dpy, c->parent);
adjusticon(c->icon);
XMapWindow(dpy, c->icon->window);
if(c->icon->labelwidth)
XMapWindow(dpy, c->icon->labelwin);
c->icon->mapped=1;
setclientstate(c, IconicState);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next) {
if (dialog->leader == c) {
XUnmapWindow(dpy, dialog->parent);
setclientstate(dialog, IconicState);
}
}
}
void deiconify(Icon *i)
{
Client *c = i->client;
if(i->labelwin)
XUnmapWindow(dpy, i->labelwin);
if(i->window)
XUnmapWindow(dpy, i->window);
i->mapped=0;
deselecticon(i);
if (c != NULL) {
XMapWindow(dpy, c->window);
if(c->parent!=c->scr->root && !c->fullscreen)
XMapRaised(dpy, c->parent);
setclientstate(c, NormalState);
for (Client *dialog = clients; dialog != NULL; dialog = dialog->next) {
if (dialog->leader == c) {
XMapRaised(dpy, dialog->parent);
setclientstate(dialog, NormalState);
}
}
}
}

2
icon.h
View File

@@ -39,5 +39,7 @@ extern void adjusticon(Icon *);
extern void selecticon(Icon *);
extern void deselecticon(Icon *);
extern void free_icon_pms(struct IconPixmaps *pms);
extern void iconify(Client *);
extern void deiconify(Icon *);
#endif

23
main.c
View File

@@ -730,7 +730,6 @@ void do_icon_double_click(Scrn *scr)
{
extern Atom amiwm_appiconmsg;
Icon *i, *next;
Client *c;
for(i=scr->firstselected; i; i=next) {
next=i->nextselected;
@@ -738,18 +737,7 @@ void do_icon_double_click(Scrn *scr)
dispatch_event_to_broker(mkcmessage(i->window, amiwm_appiconmsg, 0),
0, i->module);
} else {
if(i->labelwin)
XUnmapWindow(dpy, i->labelwin);
if(i->window)
XUnmapWindow(dpy, i->window);
i->mapped=0;
deselecticon(i);
if((c=(i->client))) {
XMapWindow(dpy, c->window);
if(c->parent!=c->scr->root && !c->fullscreen)
XMapRaised(dpy, c->parent);
setclientstate(c, NormalState);
}
deiconify(i);
}
}
}
@@ -1239,14 +1227,7 @@ int main(int argc, char *argv[])
case IconicState:
if(c->parent == c->scr->root)
reparent(c);
if(!(c->icon))
createicon(c);
adjusticon(c->icon);
XMapWindow(dpy, c->icon->window);
if(c->icon->labelwidth)
XMapWindow(dpy, c->icon->labelwin);
c->icon->mapped=1;
setclientstate(c, IconicState);
iconify(c);
break;
}
}

View File

@@ -41,7 +41,6 @@ extern void remove_fd_from_set(int);
extern void raiselowerclient(Client *, int);
extern void wberror(Scrn *, char *);
extern void reparent(Client *);
extern Icon *createappicon(struct module *, Window, char *,
Pixmap, Pixmap, Pixmap, int, int);

View File

@@ -122,46 +122,54 @@ static void scanwins()
unsigned int i, nwins;
Client *c;
Window dw1, dw2, *wins;
XWindowAttributes *pattr=NULL;
XPointer dummy;
Scrn *s=scr;
XGrabServer(dpy);
XQueryTree(dpy, scr->root, &dw1, &dw2, &wins, &nwins);
if(nwins && (pattr=calloc(nwins, sizeof(XWindowAttributes)))) {
for (i = 0; i < nwins; i++)
XGetWindowAttributes(dpy, wins[i], pattr+i);
for (int scan_dialogs = 0; nwins > 0 && scan_dialogs <= 1; scan_dialogs++) {
for (i = 0; i < nwins; i++) {
XWindowAttributes attr;
Window leader = None;
XGetTransientForHint(dpy, wins[i], &leader);
if (!scan_dialogs && leader != None)
continue; /* first pass; skip dialogs */
if (scan_dialogs && leader == None)
continue; /* second pass; skip leaders */
XGetWindowAttributes(dpy, wins[i], &attr);
if (!XFindContext(dpy, wins[i], client_context, &dummy))
continue;
if (pattr[i].override_redirect) {
if (attr.override_redirect) {
if(scr->back!=scr->root && XFindContext(dpy, wins[i], screen_context, &dummy))
assimilate(wins[i], pattr[i].x, pattr[i].y);
assimilate(wins[i], attr.x, attr.y);
continue;
}
c = createclient(wins[i]);
if (c != 0 && c->window == wins[i]) {
if (pattr[i].map_state == IsViewable) {
if (c != NULL && c->window == wins[i]) {
if (attr.map_state == IsViewable) {
c->state=NormalState;
getstate(c);
reparent(c);
if(c->state==IconicState) {
if(c->state==IconicState && c->leader == NULL) {
createicon(c);
adjusticon(c->icon);
XMapWindow(dpy, c->icon->window);
if(c->icon->labelwidth)
XMapWindow(dpy, c->icon->labelwin);
c->icon->mapped=1;
} else if(c->state==NormalState)
} else if(c->state==NormalState) {
XMapRaised(dpy, c->parent);
else
} else {
XRaiseWindow(dpy, c->parent);
}
c->reparenting=1;
scr=s;
}
}
}
free(pattr);
}
XUngrabServer(dpy);
XFree((void *) wins);
cleanupicons();
}