fix: tag preview multi-monitor crash
This commit is contained in:
parent
cc34587075
commit
e458d29c98
2
Makefile
2
Makefile
|
@ -29,7 +29,7 @@ options:
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
${CC} -c ${CFLAGS} $<
|
${CC} -c ${CFLAGS} -g $<
|
||||||
|
|
||||||
${OBJ}: options.mk
|
${OBJ}: options.mk
|
||||||
|
|
||||||
|
|
2
host.mk
2
host.mk
|
@ -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
124
speedwm.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue