sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-preview-all-windows-6.5.diff (10545B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 9efa774..f462e32 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -95,6 +95,7 @@ static const Key keys[] = {
      6  	TAGKEYS(                        XK_8,                      7)
      7  	TAGKEYS(                        XK_9,                      8)
      8  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
      9 + 	{ MODKEY,                       XK_r,      previewallwin,  {0} },
     10  };
     11  
     12  /* button definitions */
     13 diff --git a/config.mk b/config.mk
     14 index 8efca9a..8d7c303 100644
     15 --- a/config.mk
     16 +++ b/config.mk
     17 @@ -23,7 +23,7 @@ FREETYPEINC = /usr/include/freetype2
     18  
     19  # includes and libs
     20  INCS = -I${X11INC} -I${FREETYPEINC}
     21 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
     22 +LIBS = -L${X11LIB} -lX11 -lXrender -lXcomposite ${XINERAMALIBS} ${FREETYPELIBS}
     23  
     24  # flags
     25  CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
     26 diff --git a/dwm.c b/dwm.c
     27 index 67c6b2b..0ddd58e 100644
     28 --- a/dwm.c
     29 +++ b/dwm.c
     30 @@ -40,6 +40,8 @@
     31  #include <X11/extensions/Xinerama.h>
     32  #endif /* XINERAMA */
     33  #include <X11/Xft/Xft.h>
     34 +#include <X11/extensions/Xcomposite.h>
     35 +#include <X11/extensions/Xrender.h>
     36  
     37  #include "drw.h"
     38  #include "util.h"
     39 @@ -84,6 +86,16 @@ typedef struct {
     40  
     41  typedef struct Monitor Monitor;
     42  typedef struct Client Client;
     43 +
     44 +typedef struct Preview Preview;
     45 +struct Preview {
     46 +  XImage *orig_image;
     47 +  XImage *scaled_image;
     48 +  Window win;
     49 +  unsigned int x, y;
     50 +  Preview *next;
     51 +};
     52 +
     53  struct Client {
     54  	char name[256];
     55  	float mina, maxa;
     56 @@ -97,6 +109,7 @@ struct Client {
     57  	Client *snext;
     58  	Monitor *mon;
     59  	Window win;
     60 +  Preview pre;
     61  };
     62  
     63  typedef struct {
     64 @@ -233,6 +246,10 @@ static int xerror(Display *dpy, XErrorEvent *ee);
     65  static int xerrordummy(Display *dpy, XErrorEvent *ee);
     66  static int xerrorstart(Display *dpy, XErrorEvent *ee);
     67  static void zoom(const Arg *arg);
     68 +static void previewallwin();
     69 +static void setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi);
     70 +static XImage *getwindowximage(Client *c);
     71 +static XImage *scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch);
     72  
     73  /* variables */
     74  static const char broken[] = "broken";
     75 @@ -2140,6 +2157,212 @@ zoom(const Arg *arg)
     76  	pop(c);
     77  }
     78  
     79 +void
     80 +previewallwin(){
     81 +  int composite_event_base, composite_error_base;
     82 +  if (!XCompositeQueryExtension(dpy, &composite_event_base, &composite_error_base)) {
     83 +    fprintf(stderr, "Error: XComposite extension not available.\n");
     84 +    return;
     85 +  }
     86 +  Monitor *m = selmon;
     87 +  Client *c, *focus_c = NULL;
     88 +  unsigned int n;
     89 +  for (n = 0, c = m->clients; c; c = c->next, n++){
     90 +    /* If you hit actualfullscreen patch Unlock the notes below */
     91 +    // if (c->isfullscreen)
     92 +    //   togglefullscr(&(Arg){0});
     93 +    /* If you hit awesomebar patch Unlock the notes below */
     94 +    // if (HIDDEN(c))
     95 +    //   continue;
     96 +    c->pre.orig_image = getwindowximage(c);
     97 +  }
     98 +  if (n == 0)
     99 +    return;
    100 +  setpreviewwindowsizepositions(n, m, 60, 15);
    101 +  XEvent event;
    102 +  for(c = m->clients; c; c = c->next){
    103 +    if (!c->pre.win)
    104 +      c->pre.win = XCreateSimpleWindow(dpy, root, c->pre.x, c->pre.y, c->pre.scaled_image->width, c->pre.scaled_image->height, 1, BlackPixel(dpy, screen), WhitePixel(dpy, screen));
    105 +    else
    106 +      XMoveResizeWindow(dpy, c->pre.win, c->pre.x, c->pre.y, c->pre.scaled_image->width, c->pre.scaled_image->height);
    107 +    XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel);
    108 +    XSetWindowBorderWidth(dpy, c->pre.win, borderpx);
    109 +    XUnmapWindow(dpy, c->win);
    110 +    if (c->pre.win){
    111 +      XSelectInput(dpy, c->pre.win, ButtonPress | EnterWindowMask | LeaveWindowMask );
    112 +      XMapWindow(dpy, c->pre.win);
    113 +      XPutImage(dpy, c->pre.win, drw->gc, c->pre.scaled_image, 0, 0, 0, 0, c->pre.scaled_image->width, c->pre.scaled_image->height);
    114 +    }
    115 +  }
    116 +  while (1) {
    117 +      XNextEvent(dpy, &event);
    118 +      if (event.type == ButtonPress) 
    119 +          if (event.xbutton.button == Button1){
    120 +            for(c = m->clients; c; c = c->next){
    121 +              XUnmapWindow(dpy, c->pre.win);
    122 +              if (event.xbutton.window == c->pre.win){
    123 +                selmon->seltags ^= 1; /* toggle sel tagset */
    124 +                m->tagset[selmon->seltags] = c->tags;
    125 +                focus_c = c;
    126 +                focus(NULL);
    127 +                /* If you hit awesomebar patch Unlock the notes below */
    128 +                // if (HIDDEN(c)){
    129 +                //   showwin(c);
    130 +                //   continue;
    131 +                // }
    132 +              }
    133 +              /* If you hit awesomebar patch Unlock the notes below; 
    134 +               * And you should add the following line to "hidewin" Function
    135 +               * c->pre.orig_image = getwindowximage(c);
    136 +               * */
    137 +              // if (HIDDEN(c)){
    138 +              //   continue;
    139 +              // }
    140 +              XMapWindow(dpy, c->win);
    141 +              XDestroyImage(c->pre.orig_image);
    142 +              XDestroyImage(c->pre.scaled_image);
    143 +            }
    144 +            break;
    145 +          }
    146 +      if (event.type == EnterNotify)
    147 +          for(c = m->clients; c; c = c->next)
    148 +              if (event.xcrossing.window == c->pre.win){
    149 +                  XSetWindowBorder(dpy, c->pre.win, scheme[SchemeSel][ColBorder].pixel);
    150 +                  break;
    151 +              }
    152 +      if (event.type == LeaveNotify)
    153 +          for(c = m->clients; c; c = c->next)
    154 +              if (event.xcrossing.window == c->pre.win){
    155 +                  XSetWindowBorder(dpy, c->pre.win, scheme[SchemeNorm][ColBorder].pixel);
    156 +                  break;
    157 +              }
    158 +  }
    159 +  arrange(m);
    160 +  focus(focus_c);
    161 +}
    162 +
    163 +void
    164 +setpreviewwindowsizepositions(unsigned int n, Monitor *m, unsigned int gappo, unsigned int gappi){
    165 +  unsigned int i, j;
    166 +  unsigned int cx, cy, cw, ch, cmaxh;
    167 +  unsigned int cols, rows;
    168 +  Client *c, *tmpc;
    169 +
    170 +  if (n == 1) {
    171 +    c = m->clients;
    172 +    cw = (m->ww - 2 * gappo) * 0.8;
    173 +    ch = (m->wh - 2 * gappo) * 0.9;
    174 +    c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
    175 +    c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width) / 2;
    176 +    c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2;
    177 +    return;
    178 +  }
    179 +  if (n == 2) {
    180 +    c = m->clients;
    181 +    cw = (m->ww - 2 * gappo - gappi) / 2;
    182 +    ch = (m->wh - 2 * gappo) * 0.7;
    183 +    c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
    184 +    c->next->pre.scaled_image = scaledownimage(c->next->pre.orig_image, cw, ch);
    185 +    c->pre.x = m->mx + (m->mw - c->pre.scaled_image->width - gappi - c->next->pre.scaled_image->width) / 2;
    186 +    c->pre.y = m->my + (m->mh - c->pre.scaled_image->height) / 2;
    187 +    c->next->pre.x = c->pre.x + c->pre.scaled_image->width + gappi;
    188 +    c->next->pre.y = m->my + (m->mh - c->next->pre.scaled_image->height) / 2;
    189 +    return;
    190 +  }
    191 +  for (cols = 0; cols <= n / 2; cols++)
    192 +    if (cols * cols >= n)
    193 +      break;
    194 +  rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols;
    195 +  ch = (m->wh - 2 * gappo) / rows;
    196 +  cw = (m->ww - 2 * gappo) / cols;
    197 +  c = m->clients;
    198 +  cy = 0;
    199 +  for (i = 0; i < rows; i++) {
    200 +    cx = 0;
    201 +    cmaxh = 0;
    202 +    tmpc = c;
    203 +    for (int j = 0; j < cols; j++) {
    204 +      if (!c)
    205 +        break;
    206 +      c->pre.scaled_image = scaledownimage(c->pre.orig_image, cw, ch);
    207 +      c->pre.x = cx;
    208 +      cmaxh = c->pre.scaled_image->height > cmaxh ? c->pre.scaled_image->height : cmaxh;
    209 +      cx += c->pre.scaled_image->width + gappi;
    210 +      c = c->next;
    211 +    }
    212 +    c = tmpc;
    213 +    cx = m->wx + (m->ww - cx) / 2;
    214 +    for (j = 0; j < cols; j++) {
    215 +      if (!c)
    216 +        break;
    217 +      c->pre.x += cx;
    218 +      c->pre.y = cy + (cmaxh - c->pre.scaled_image->height) / 2;
    219 +      c = c->next;
    220 +    }
    221 +    cy += cmaxh + gappi;
    222 +  }
    223 +  cy = m->wy + (m->wh - cy) / 2;
    224 +  for (c = m->clients; c; c = c->next)
    225 +    c->pre.y += cy;
    226 +}
    227 +
    228 +XImage
    229 +*getwindowximage(Client *c) {
    230 +  XCompositeRedirectWindow(dpy, c->win, CompositeRedirectAutomatic);
    231 +  XWindowAttributes attr;
    232 +  XGetWindowAttributes( dpy, c->win, &attr );
    233 +  XRenderPictFormat *format = XRenderFindVisualFormat( dpy, attr.visual );
    234 +  int hasAlpha = ( format->type == PictTypeDirect && format->direct.alphaMask );
    235 +  XRenderPictureAttributes pa;
    236 +  pa.subwindow_mode = IncludeInferiors;
    237 +  Picture picture = XRenderCreatePicture( dpy, c->win, format, CPSubwindowMode, &pa );
    238 +  Pixmap pixmap = XCreatePixmap(dpy, root, c->w, c->h, 32);
    239 +  XRenderPictureAttributes pa2;
    240 +  XRenderPictFormat *format2 = XRenderFindStandardFormat(dpy, PictStandardARGB32);
    241 +  Picture pixmapPicture = XRenderCreatePicture( dpy, pixmap, format2, 0, &pa2 );
    242 +  XRenderColor color;
    243 +  color.red = 0x0000;
    244 +  color.green = 0x0000;
    245 +  color.blue = 0x0000;
    246 +  color.alpha = 0x0000;
    247 +  XRenderFillRectangle (dpy, PictOpSrc, pixmapPicture, &color, 0, 0, c->w, c->h);
    248 +  XRenderComposite(dpy, hasAlpha ? PictOpOver : PictOpSrc, picture, 0,
    249 +                   pixmapPicture, 0, 0, 0, 0, 0, 0,
    250 +                   c->w, c->h);
    251 +  XImage* temp = XGetImage( dpy, pixmap, 0, 0, c->w, c->h, AllPlanes, ZPixmap );
    252 +  temp->red_mask = format2->direct.redMask << format2->direct.red;
    253 +  temp->green_mask = format2->direct.greenMask << format2->direct.green;
    254 +  temp->blue_mask = format2->direct.blueMask << format2->direct.blue;
    255 +  temp->depth = DefaultDepth(dpy, screen);
    256 +  XCompositeUnredirectWindow(dpy, c->win, CompositeRedirectAutomatic);
    257 +  return temp;
    258 +}
    259 +
    260 +XImage
    261 +*scaledownimage(XImage *orig_image, unsigned int cw, unsigned int ch) {
    262 +  int factor_w = orig_image->width / cw + 1;
    263 +  int factor_h = orig_image->height / ch + 1;
    264 +  int scale_factor = factor_w > factor_h ? factor_w : factor_h;
    265 +  int scaled_width = orig_image->width / scale_factor;
    266 +  int scaled_height = orig_image->height / scale_factor;
    267 +  XImage *scaled_image = XCreateImage(dpy, DefaultVisual(dpy, DefaultScreen(dpy)),
    268 +                                      orig_image->depth,
    269 +                                      ZPixmap, 0, NULL,
    270 +                                      scaled_width, scaled_height,
    271 +                                      32, 0);
    272 +  scaled_image->data = malloc(scaled_image->height * scaled_image->bytes_per_line);
    273 +  for (int y = 0; y < scaled_height; y++) {
    274 +      for (int x = 0; x < scaled_width; x++) {
    275 +          int orig_x = x * scale_factor;
    276 +          int orig_y = y * scale_factor;
    277 +          unsigned long pixel = XGetPixel(orig_image, orig_x, orig_y);
    278 +          XPutPixel(scaled_image, x, y, pixel);
    279 +      }
    280 +  }
    281 +  scaled_image->depth = orig_image->depth;
    282 +  return scaled_image;
    283 +}
    284 +
    285  int
    286  main(int argc, char *argv[])
    287  {