client.c
changeset 26 e8f627998d6f
parent 23 95ffdfd0a819
child 27 f96fb3fd8203
equal deleted inserted replaced
25:e238dc4844d7 26:e8f627998d6f
     8 #include <X11/Xatom.h>
     8 #include <X11/Xatom.h>
     9 
     9 
    10 #include "util.h"
    10 #include "util.h"
    11 #include "wm.h"
    11 #include "wm.h"
    12 
    12 
    13 #define CLIENT_MASK		(StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
    13 static void
       
    14 resize_title(Client *c)
       
    15 {
       
    16 	c->tw = textw(&brush.font, c->name) + bh;
       
    17 	if(c->tw > c->w)
       
    18 		c->tw = c->w + 2;
       
    19 	c->tx = c->x + c->w - c->tw + 2;
       
    20 	c->ty = c->y;
       
    21 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
       
    22 }
    14 
    23 
    15 void
    24 void
    16 update_name(Client *c)
    25 update_name(Client *c)
    17 {
    26 {
    18 	XTextProperty name;
    27 	XTextProperty name;
    35 			strncpy(c->name, *list, sizeof(c->name));
    44 			strncpy(c->name, *list, sizeof(c->name));
    36 			XFreeStringList(list);
    45 			XFreeStringList(list);
    37 		}
    46 		}
    38 	}
    47 	}
    39 	XFree(name.value);
    48 	XFree(name.value);
       
    49 	resize_title(c);
    40 }
    50 }
    41 
    51 
    42 void
    52 void
    43 update_size(Client *c)
    53 update_size(Client *c)
    44 {
    54 {
    72 	else
    82 	else
    73 		c->minw = c->minh = 0;
    83 		c->minw = c->minh = 0;
    74 }
    84 }
    75 
    85 
    76 void
    86 void
       
    87 raise(Client *c)
       
    88 {
       
    89 	XRaiseWindow(dpy, c->win);
       
    90 	XRaiseWindow(dpy, c->title);
       
    91 }
       
    92 
       
    93 void
       
    94 lower(Client *c)
       
    95 {
       
    96 	XLowerWindow(dpy, c->title);
       
    97 	XLowerWindow(dpy, c->win);
       
    98 }
       
    99 
       
   100 void
    77 focus(Client *c)
   101 focus(Client *c)
    78 {
   102 {
    79 	Client **l, *old;
   103 	Client **l, *old;
    80 
   104 
    81 	old = stack;
   105 	old = stack;
    82 	for(l=&stack; *l && *l != c; l=&(*l)->snext);
   106 	for(l = &stack; *l && *l != c; l = &(*l)->snext);
    83 	eassert(*l == c);
   107 	eassert(*l == c);
    84 	*l = c->snext;
   108 	*l = c->snext;
    85 	c->snext = stack;
   109 	c->snext = stack;
    86 	stack = c;
   110 	stack = c;
    87 	XRaiseWindow(dpy, c->win);
       
    88 	XRaiseWindow(dpy, c->title);
       
    89 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
       
    90 	if(old && old != c) {
   111 	if(old && old != c) {
    91 		XMapWindow(dpy, old->title);
   112 		XMapWindow(dpy, old->title);
    92 		draw_client(old);
   113 		draw_client(old);
    93 	}
   114 	}
    94 	XUnmapWindow(dpy, c->title);
   115 	XUnmapWindow(dpy, c->title);
    95 	draw_bar();
   116 	draw_client(old);
    96 	discard_events(EnterWindowMask);
   117 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
    97 	XFlush(dpy);
   118 	XFlush(dpy);
    98 }
   119 }
    99 
   120 
   100 void
   121 void
   101 manage(Window w, XWindowAttributes *wa)
   122 manage(Window w, XWindowAttributes *wa)
   105 
   126 
   106 	c = emallocz(sizeof(Client));
   127 	c = emallocz(sizeof(Client));
   107 	c->win = w;
   128 	c->win = w;
   108 	c->tx = c->x = wa->x;
   129 	c->tx = c->x = wa->x;
   109 	c->ty = c->y = wa->y;
   130 	c->ty = c->y = wa->y;
       
   131 	if(c->y < bh)
       
   132 		c->ty = c->y += bh;
   110 	c->tw = c->w = wa->width;
   133 	c->tw = c->w = wa->width;
   111 	c->h = wa->height;
   134 	c->h = wa->height;
   112 	c->th = barrect.height;
   135 	c->th = bh;
   113 	update_size(c);
   136 	update_size(c);
   114 	XSetWindowBorderWidth(dpy, c->win, 1);
   137 	XSetWindowBorderWidth(dpy, c->win, 1);
   115 	XSetWindowBorder(dpy, c->win, brush.border);
   138 	XSetWindowBorder(dpy, c->win, brush.border);
   116 	XSelectInput(dpy, c->win, CLIENT_MASK);
   139 	XSelectInput(dpy, c->win,
       
   140 			StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
   117 	XGetTransientForHint(dpy, c->win, &c->trans);
   141 	XGetTransientForHint(dpy, c->win, &c->trans);
   118 	twa.override_redirect = 1;
   142 	twa.override_redirect = 1;
   119 	twa.background_pixmap = ParentRelative;
   143 	twa.background_pixmap = ParentRelative;
   120 	twa.event_mask = ExposureMask;
   144 	twa.event_mask = ExposureMask;
   121 
   145 
   128 	for(l=&clients; *l; l=&(*l)->next);
   152 	for(l=&clients; *l; l=&(*l)->next);
   129 	c->next = *l; /* *l == nil */
   153 	c->next = *l; /* *l == nil */
   130 	*l = c;
   154 	*l = c;
   131 	c->snext = stack;
   155 	c->snext = stack;
   132 	stack = c;
   156 	stack = c;
   133 	XMapWindow(dpy, c->win);
   157 	XMapRaised(dpy, c->win);
   134 	XMapWindow(dpy, c->title);
   158 	XMapRaised(dpy, c->title);
   135 	XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
   159 	XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
   136 			GrabModeAsync, GrabModeSync, None, None);
   160 			GrabModeAsync, GrabModeSync, None, None);
   137 	XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
   161 	XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
   138 			GrabModeAsync, GrabModeSync, None, None);
   162 			GrabModeAsync, GrabModeSync, None, None);
   139 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   163 	XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
   145 void
   169 void
   146 resize(Client *c)
   170 resize(Client *c)
   147 {
   171 {
   148 	XConfigureEvent e;
   172 	XConfigureEvent e;
   149 
   173 
       
   174 	resize_title(c);
   150 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   175 	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
   151 	e.type = ConfigureNotify;
   176 	e.type = ConfigureNotify;
   152 	e.event = c->win;
   177 	e.event = c->win;
   153 	e.window = c->win;
   178 	e.window = c->win;
   154 	e.x = c->x;
   179 	e.x = c->x;
   156 	e.width = c->w;
   181 	e.width = c->w;
   157 	e.height = c->h;
   182 	e.height = c->h;
   158 	e.border_width = 0;
   183 	e.border_width = 0;
   159 	e.above = None;
   184 	e.above = None;
   160 	e.override_redirect = False;
   185 	e.override_redirect = False;
   161 	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
       
   162 	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
   186 	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
   163 	XSelectInput(dpy, c->win, CLIENT_MASK);
       
   164 	XFlush(dpy);
   187 	XFlush(dpy);
   165 }
   188 }
   166 
   189 
   167 static int
   190 static int
   168 dummy_error_handler(Display *dpy, XErrorEvent *error)
   191 dummy_error_handler(Display *dpy, XErrorEvent *error)
   217 }
   240 }
   218 
   241 
   219 void
   242 void
   220 draw_client(Client *c)
   243 draw_client(Client *c)
   221 {
   244 {
   222 	if(c == stack)
   245 	if(c == stack) {
   223 		draw_bar();
   246 		draw_bar();
   224 
   247 		return;
   225 	c->tw = textwidth(&brush.font, c->name) + labelheight(&brush.font);
   248 	}
   226 	c->tx = c->x + c->w - c->tw + 2;
   249 
   227 	c->ty = c->y;
   250 	brush.x = brush.y = 0;
   228 	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
   251 	brush.w = c->tw;
   229 
   252 	brush.h = c->th;
   230 	brush.rect.x = brush.rect.y = 0;
       
   231 	brush.rect.width = c->tw;
       
   232 	brush.rect.height = c->th;
       
   233 
   253 
   234 	draw(dpy, &brush, True, c->name);
   254 	draw(dpy, &brush, True, c->name);
   235 	XCopyArea(dpy, brush.drawable, c->title, brush.gc,
   255 	XCopyArea(dpy, brush.drawable, c->title, brush.gc,
   236 			0, 0, c->tw, c->th, 0, 0);
   256 			0, 0, c->tw, c->th, 0, 0);
   237 	XFlush(dpy);
   257 	XFlush(dpy);