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; |
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, |
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); |