fix: tag preview multi-monitor crash

This commit is contained in:
speedie 2023-01-22 13:54:06 +01:00
parent cc34587075
commit e458d29c98
3 changed files with 85 additions and 43 deletions

View file

@ -29,7 +29,7 @@ options:
@echo @echo
.c.o: .c.o:
${CC} -c ${CFLAGS} $< ${CC} -c ${CFLAGS} -g $<
${OBJ}: options.mk ${OBJ}: options.mk

View file

@ -16,7 +16,7 @@ PAGEDIR = "/home/anon/Projects/speediegq/projects"
FREETYPELIBS = -lfontconfig -lXft FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2 FREETYPEINC = /usr/include/freetype2
EXCFLAGS = -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-array-bounds EXCFLAGS = -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-array-bounds
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Ofast -march=native ${INCS} ${CPPFLAGS} ${EXCFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -O2 -march=native ${INCS} ${CPPFLAGS} ${EXCFLAGS}
LDFLAGS = ${LIBS} -g LDFLAGS = ${LIBS} -g
# OpenBSD support # OpenBSD support

124
speedwm.c
View file

@ -313,10 +313,10 @@ struct Monitor {
#endif #endif
#if USETAGPREVIEW #if USETAGPREVIEW
int previewshow; int previewshow;
int scalepreview;
Window tagwin; Window tagwin;
Pixmap *tagmap; Pixmap *tagmap;
#endif #endif
int scalepreview;
float mfact; /* mfact value */ float mfact; /* mfact value */
float cfact; /* cfact value */ float cfact; /* cfact value */
int ltaxis[4]; int ltaxis[4];
@ -777,6 +777,7 @@ static void zoom(const Arg *arg);
#if USETAGPREVIEW #if USETAGPREVIEW
static void showtagpreview(unsigned int i); static void showtagpreview(unsigned int i);
static void takepreview(void); static void takepreview(void);
static void updatepreviews(Monitor *m);
#endif #endif
/* We will keep this one, in order to keep keybinds.h clean. */ /* We will keep this one, in order to keep keybinds.h clean. */
@ -1077,9 +1078,9 @@ applyrules(Client *c)
if (r->floath >= 0) if (r->floath >= 0)
c->h = r->floath; c->h = r->floath;
} }
for (m = mons; m && m->num != r->monitor; m = m->next); for (m = mons; m && m->num != r->monitor; m = m->next)
if (m) if (m)
c->mon = m; c->mon = m;
} }
} }
if (ch.res_class) if (ch.res_class)
@ -1494,7 +1495,6 @@ cleanup(void)
#endif #endif
} }
/* clean up on the selected monitor only */
void void
cleanupmon(Monitor *mon) cleanupmon(Monitor *mon)
{ {
@ -1510,11 +1510,11 @@ cleanupmon(Monitor *mon)
size_t i; size_t i;
for (i = 0; i < LENGTH(ftags); i++) for (i = 0; i < LENGTH(ftags); i++)
if (mon->tagmap[i]) if (m->tagmap[i])
XFreePixmap(dpy, mon->tagmap[i]); XFreePixmap(dpy, m->tagmap[i]);
free(mon->tagmap); free(m->tagmap);
XUnmapWindow(dpy, mon->tagwin); XUnmapWindow(dpy, m->tagwin);
XDestroyWindow(dpy, mon->tagwin); XDestroyWindow(dpy, m->tagwin);
#endif #endif
free(mon); free(mon);
} }
@ -1637,6 +1637,10 @@ configurenotify(XEvent *e)
for (bar = m->bar; bar; bar = bar->next) for (bar = m->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
#if USETAGPREVIEW
updatepreviews(m);
#endif
} }
focus(NULL); focus(NULL);
arrange(NULL); arrange(NULL);
@ -2961,6 +2965,7 @@ showwin(Client *c)
void void
showhide(Client *c) showhide(Client *c)
{ {
return;
if (!c) if (!c)
return; return;
if (ISVISIBLE(c)) { if (ISVISIBLE(c)) {
@ -5107,6 +5112,7 @@ setup(void)
tw = DisplayWidth(dpy, screen); tw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen); sh = DisplayHeight(dpy, screen);
root = RootWindow(dpy, screen); root = RootWindow(dpy, screen);
xinitvisual(); xinitvisual();
drw = drw_create(dpy, screen, root, tw, sh, visual, depth, cmap); drw = drw_create(dpy, screen, root, tw, sh, visual, depth, cmap);
if (!drw_font_create(drw, font)) if (!drw_font_create(drw, font))
@ -5208,9 +5214,11 @@ setup(void)
setcurrentdesktop(); setcurrentdesktop();
setdesktopnames(); setdesktopnames();
setviewport(); setviewport();
XDeleteProperty(dpy, root, netatom[NetClientList]); XDeleteProperty(dpy, root, netatom[NetClientList]);
XDeleteProperty(dpy, root, netatom[NetClientInfo]); XDeleteProperty(dpy, root, netatom[NetClientInfo]);
XDeleteProperty(dpy, root, netatom[NetClientListStacking]); XDeleteProperty(dpy, root, netatom[NetClientListStacking]);
/* select events */ /* select events */
wa.cursor = cursor[CurNormal]->cursor; wa.cursor = cursor[CurNormal]->cursor;
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
@ -5713,15 +5721,9 @@ updatebars(void)
.colormap = cmap, .colormap = cmap,
.event_mask = ButtonPressMask|ExposureMask|PointerMotionMask .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
}; };
XClassHint ch = {"speedwm", "speedwm"}; XClassHint ch = {"speedwm", "speedwm"};
for (m = mons; m; m = m->next) { for (m = mons; m; m = m->next) {
#if USETAGPREVIEW
m->tagwin = XCreateWindow(dpy, root, m->wx + x_pad, bar->by + bh + y_pad + selmon->gapsizeov / 2, m->mw / selmon->scalepreview, m->mh / selmon->scalepreview, 0,
depth, CopyFromParent, visual, CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
XUnmapWindow(dpy, m->tagwin);
#endif
for (bar = m->bar; bar; bar = bar->next) { for (bar = m->bar; bar; bar = bar->next) {
if (!bar->win) { if (!bar->win) {
bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, depth, bar->win = XCreateWindow(dpy, root, bar->bx, bar->by, bar->bw, bar->bh, 0, depth,
@ -6169,7 +6171,7 @@ view(const Arg *arg)
focus(NULL); focus(NULL);
arrange(NULL); arrange(NULL);
updatecurrentdesktop(); // updatecurrentdesktop();
} }
pid_t pid_t
@ -6578,6 +6580,7 @@ inplacerotate(const Arg *arg)
if (arg->i == 2) insertclient(selmon->clients, stail, 0); if (arg->i == 2) insertclient(selmon->clients, stail, 0);
if (arg->i == -2) insertclient(stail, selmon->clients, 1); if (arg->i == -2) insertclient(stail, selmon->clients, 1);
/* stack xor master rotate */ /* stack xor master rotate */
if (arg->i == -1 && selidx >= selmon->mastercount) insertclient(stail, shead, 1); if (arg->i == -1 && selidx >= selmon->mastercount) insertclient(stail, shead, 1);
if (arg->i == 1 && selidx >= selmon->mastercount) insertclient(shead, stail, 0); if (arg->i == 1 && selidx >= selmon->mastercount) insertclient(shead, stail, 0);
@ -6599,17 +6602,19 @@ inplacerotate(const Arg *arg)
void void
showtagpreview(unsigned int i) showtagpreview(unsigned int i)
{ {
if (!selmon->previewshow || !selmon->tagmap[i]) { if (!selmon->tagwin)
XUnmapWindow(dpy, selmon->tagwin); return;
return;
}
XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[i]); if (selmon->tagmap[i] && selmon->previewshow) {
XCopyArea(dpy, selmon->tagmap[i], selmon->tagwin, drw->gc, 0, 0, XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[i]);
selmon->mw / selmon->scalepreview, selmon->mh / selmon->scalepreview, XCopyArea(dpy, selmon->tagmap[i], selmon->tagwin, drw->gc, 0, 0,
0, 0); selmon->mw / selmon->scalepreview, selmon->mh / selmon->scalepreview,
XSync(dpy, False); 0, 0);
XMapRaised(dpy, selmon->tagwin); XSync(dpy, False);
XMapRaised(dpy, selmon->tagwin);
} else {
XUnmapWindow(dpy, selmon->tagwin);
}
} }
void void
@ -6618,25 +6623,35 @@ takepreview(void)
Client *c; Client *c;
Imlib_Image image; Imlib_Image image;
unsigned int occ = 0, i; unsigned int occ = 0, i;
Monitor *m = selmon;
for (c = selmon->clients; c; c = c->next) if (!m->tagwin) {
if (!selmon->hideemptytags) updatepreviews(m);
/* failsafe, should prevent crashing if updatepreviews(m) doesn't create tagwin */
if (!m->tagwin) {
return;
}
}
for (c = m->clients; c; c = c->next)
if (!m->hideemptytags)
occ |= c->tags; occ |= c->tags;
else else
occ |= c->tags == 255 ? 0 : c->tags; occ |= c->tags == 255 ? 0 : c->tags;
for (i = 0; i < LENGTH(ftags); i++) { for (i = 0; i < LENGTH(ftags); i++) {
/* searching for tags that are occupied && selected */ /* searching for tags that are occupied && selected */
if (!(occ & 1 << i) || !(selmon->tagset[selmon->seltags] & 1 << i)) if (!(occ & 1 << i) || !(m->tagset[m->seltags] & 1 << i))
continue; continue;
if (selmon->tagmap[i]) { /* tagmap exist, clean it */ if (m->tagmap[i]) { /* tagmap exist, clean it */
XFreePixmap(dpy, selmon->tagmap[i]); XFreePixmap(dpy, m->tagmap[i]);
selmon->tagmap[i] = 0; m->tagmap[i] = 0;
} }
selmon->previewshow = 0; m->previewshow = 0;
XUnmapWindow(dpy, selmon->tagwin); XUnmapWindow(dpy, m->tagwin);
XSync(dpy, False); XSync(dpy, False);
if (!(image = imlib_create_image(tw, sh))) { if (!(image = imlib_create_image(tw, sh))) {
@ -6651,16 +6666,43 @@ takepreview(void)
imlib_context_set_drawable(root); imlib_context_set_drawable(root);
if (!barpreview) if (!barpreview)
imlib_copy_drawable_to_image(0, selmon->wx, selmon->wy, selmon->ww ,selmon->wh, 0, 0, 1); imlib_copy_drawable_to_image(0, m->wx, m->wy, m->ww, m->wh, 0, 0, 1);
else else
imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1); imlib_copy_drawable_to_image(0, m->mx, m->my, m->mw, m->mh, 0, 0, 1);
selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / selmon->scalepreview, selmon->mh / selmon->scalepreview, depth); m->tagmap[i] = XCreatePixmap(dpy, m->tagwin, m->mw / m->scalepreview, m->mh / m->scalepreview, depth);
imlib_context_set_drawable(selmon->tagmap[i]); imlib_context_set_drawable(m->tagmap[i]);
imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw, selmon->mh, 0, 0, selmon->mw / selmon->scalepreview, selmon->mh / selmon->scalepreview); imlib_render_image_part_on_drawable_at_size(0, 0, m->mw, m->mh, 0, 0, m->mw / m->scalepreview, m->mh / m->scalepreview);
imlib_free_image(); imlib_free_image();
} }
} }
void
updatepreviews(Monitor *m)
{
int x_pad = sp;
int y_pad = vp;
if (m->tagwin) {
XMoveResizeWindow(dpy, m->tagwin, m->mx, m->bar->by + bh, m->mw / m->scalepreview, m->mh / m->scalepreview);
return;
}
XSetWindowAttributes wa = {
.override_redirect = True,
.background_pixel = 0,
.border_pixel = 0,
.colormap = cmap,
.event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
};
m->tagwin = XCreateWindow(dpy, root, m->wx + x_pad, m->bar->by + bh + y_pad + m->gapsizeov / 2, m->mw / m->scalepreview, m->mh / m->scalepreview, 0,
depth, CopyFromParent, visual, CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
XMapRaised(dpy, m->tagwin);
XUnmapWindow(dpy, m->tagwin);
}
#endif #endif
void void