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

View File

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

28
frame.c
View File

@@ -183,9 +183,14 @@ void reparent(Client *c)
getwmstate(c); getwmstate(c);
if(XGetTransientForHint(dpy, c->window, &leader) && if(XGetTransientForHint(dpy, c->window, &leader) &&
!XFindContext(dpy, leader, client_context, (XPointer *)&lc)) !XFindContext(dpy, leader, client_context, (XPointer *)&lc) &&
c->scr = lc->scr; lc != NULL) {
else if(XGetTextProperty(dpy, c->window, &screen_prop, amiwm_screen)) { 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)) {
do { do {
if(s->root == scr->root && if(s->root == scr->root &&
(!s->deftitle[screen_prop.nitems])&&!strncmp(s->deftitle, (!s->deftitle[screen_prop.nitems])&&!strncmp(s->deftitle,
@@ -298,8 +303,9 @@ void reparent(Client *c)
cb=(resizable(c->sizehints)? prefs.sizeborder:0); cb=(resizable(c->sizehints)? prefs.sizeborder:0);
c->close=creategadget(c, c->parent, 0, 0, 19, scr->bh); c->close=creategadget(c, c->parent, 0, 0, 19, scr->bh);
c->drag=creategadget(c, c->parent, 19, 0, 1, 1); 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; c->iconify=None;
}
else else
c->iconify=creategadget(c, c->parent, 0, 0, 23, scr->bh); c->iconify=creategadget(c, c->parent, 0, 0, 23, scr->bh);
if(cb) if(cb)
@@ -322,7 +328,8 @@ void reparent(Client *c)
#endif #endif
XMapSubwindows(dpy, c->parent); XMapSubwindows(dpy, c->parent);
sendconfig(c); sendconfig(c);
setstringprop(c->window, amiwm_screen, scr->deftitle); if (scr->deftitle != NULL)
setstringprop(c->window, amiwm_screen, scr->deftitle);
if(prefs.focus == FOC_CLICKTOTYPE) if(prefs.focus == FOC_CLICKTOTYPE)
XGrabButton(dpy, Button1, AnyModifier, c->parent, True, XGrabButton(dpy, Button1, AnyModifier, c->parent, True,
ButtonPressMask, GrabModeSync, GrabModeAsync, None, wm_curs); ButtonPressMask, GrabModeSync, GrabModeAsync, None, wm_curs);
@@ -747,16 +754,7 @@ void gadgetunclicked(Client *c, XEvent *e)
/* XWarpPointer(dpy, None, c->zoom, 0, 0, 0, 0, 23/2, scr->h5); */ /* XWarpPointer(dpy, None, c->zoom, 0, 0, 0, 0, 23/2, scr->h5); */
sendconfig(c); sendconfig(c);
} else if(w==c->iconify) { } else if(w==c->iconify) {
if(!(c->icon)) iconify(c);
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);
} }
} }
clickwindow=None; 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 void propertychange(Client *, Atom);
extern long _getprop(Window, Atom, Atom, long, char **); extern long _getprop(Window, Atom, Atom, long, char **);
extern void getwflags(Client *); 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; 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; s->icons=i;
if(i->client) { if(i->client) {
reparent_client(s, 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) if(os)
selecticon(i); selecticon(i);
@@ -630,3 +635,46 @@ void free_icon_pms(struct IconPixmaps *pms)
free_color_store(dpy, &pms->cs); free_color_store(dpy, &pms->cs);
free_color_store(dpy, &pms->cs2); 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 selecticon(Icon *);
extern void deselecticon(Icon *); extern void deselecticon(Icon *);
extern void free_icon_pms(struct IconPixmaps *pms); extern void free_icon_pms(struct IconPixmaps *pms);
extern void iconify(Client *);
extern void deiconify(Icon *);
#endif #endif

23
main.c
View File

@@ -730,7 +730,6 @@ void do_icon_double_click(Scrn *scr)
{ {
extern Atom amiwm_appiconmsg; extern Atom amiwm_appiconmsg;
Icon *i, *next; Icon *i, *next;
Client *c;
for(i=scr->firstselected; i; i=next) { for(i=scr->firstselected; i; i=next) {
next=i->nextselected; next=i->nextselected;
@@ -738,18 +737,7 @@ void do_icon_double_click(Scrn *scr)
dispatch_event_to_broker(mkcmessage(i->window, amiwm_appiconmsg, 0), dispatch_event_to_broker(mkcmessage(i->window, amiwm_appiconmsg, 0),
0, i->module); 0, i->module);
} else { } else {
if(i->labelwin) deiconify(i);
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);
}
} }
} }
} }
@@ -1239,14 +1227,7 @@ int main(int argc, char *argv[])
case IconicState: case IconicState:
if(c->parent == c->scr->root) if(c->parent == c->scr->root)
reparent(c); reparent(c);
if(!(c->icon)) iconify(c);
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);
break; break;
} }
} }

View File

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

View File

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