1 module gui.bar;
2 
3 import cboxapp;
4 import types;
5 import gui.cursor;
6 import window;
7 import old;
8 import legacy;
9 import utils;
10 import config;
11 import kernel;
12 import helper.x11;
13 import monitor;
14 import std.stdio;
15 import theme.manager;
16 
17 import deimos.X11.X;
18 import deimos.X11.Xlib;
19 import deimos.X11.keysymdef;
20 import deimos.X11.Xutil;
21 import deimos.X11.Xatom;
22 
23 void drawbar(Monitor *m) 
24 {
25     uint occ = 0, urg = 0;
26 
27     foreach(c; m.clients.range!"next") {
28         occ |= c.tags;
29         if(c.isurgent) {
30             urg |= c.tags;
31         }
32     }
33 
34     int x = 0, w;
35 
36     ClrScheme sel = ThemeManager.instance().getScheme(SchemeSel);
37     ClrScheme norm = ThemeManager.instance().getScheme(SchemeNorm);
38     
39     foreach(i, tag; tags) {
40         w = TEXTW(tag);
41         drw.setscheme((m.tagset[m.seltags] & (1 << i)) 
42             ? &sel
43             : &norm);
44         drw.text(x, 0, w, bh, tag, urg & 1 << i);
45         drw.rect(x, 0, w, bh, m == selmon && selmon.sel && selmon.sel.tags & 1 << i,
46                  occ & 1 << i, urg & 1 << i);
47         x += w;
48     }
49 
50     int xx = x;
51     
52     if(m == selmon) { /* status is only drawn on selected monitor */
53         w = TEXTW(stext);
54         x = m.mw - w;
55 
56         if(x < xx) {
57             x = xx;
58             w = m.mw - xx;
59         }
60 
61         drw.setscheme(&norm);
62         drw.text(x, 0, w, bh, stext, 0);
63     } else {
64         x = m.mw;
65     }
66 
67     if((w = x - xx) > bh) {
68         x = xx;
69         if(m.sel) {
70             drw.setscheme(m == selmon ? &sel : &norm);
71             drw.text(x, 0, w, bh, m.sel.name, 0);
72             drw.rect(x, 0, w, bh, m.sel.isfixed, m.sel.isfloating, 0);
73         } else {
74             drw.setscheme(&norm);
75             drw.text(x, 0, w, bh, null, 0);
76         }
77     }
78 
79     drw.map(m.barwin, 0, 0, m.mw, bh);
80 }
81 
82 void drawbars()
83 {
84     foreach(m; mons.range) {
85         drawbar(m);
86     }
87 }
88 
89 void updatebars()
90 {
91     Client *c;
92     XSetWindowAttributes wa = {
93 		override_redirect : True,
94 		background_pixmap : ParentRelative,
95 		event_mask :  ButtonPressMask|ExposureMask
96     };
97 
98     foreach(m; mons.range) {
99         if (m.barwin)
100             continue;
101         
102         m.barwin = XCreateWindow(
103         	AppDisplay.instance().dpy, 
104         	rootWin, 
105         	m.wx, 
106         	m.by, 
107         	m.ww, 
108         	bh, 
109         	0, 
110         	DefaultDepth(AppDisplay.instance().dpy, screen),
111             CopyFromParent, 
112             DefaultVisual(AppDisplay.instance().dpy, screen),
113             CWOverrideRedirect|CWBackPixmap|CWEventMask, 
114             &wa
115         );
116 
117         XDefineCursor(AppDisplay.instance().dpy, m.barwin, cursor[CurNormal].cursor);
118 
119         //sendevent(c, XInternAtom(AppDisplay.instance().dpy, cast(char*)("_NET_WM_STATE_ABOVE"), false));
120         XMapRaised(AppDisplay.instance().dpy, m.barwin);
121         //sendevent(c, XInternAtom(AppDisplay.instance().dpy, cast(char*)("_NET_WM_STATE_ABOVE"), false));
122     }
123 }
124 
125 void updatebarpos(Monitor *m) 
126 {
127     
128     m.wy = m.my;
129     m.wh = m.mh;
130     if(m.showbar) {
131         m.wh -= bh;
132         m.by = m.topbar ? m.wy : m.wy + m.wh;
133         m.wy = m.topbar ? m.wy + bh : m.wy;
134     } else
135         m.by = -bh;
136 }
137 
138 void togglebar(const Arg *arg) 
139 {
140     selmon.showbar = !selmon.showbar;
141     updatebarpos(selmon);
142     XMoveResizeWindow(AppDisplay.instance().dpy, selmon.barwin, selmon.wx, selmon.by, selmon.ww, bh);
143     arrange(selmon);
144 }
145 
146 void updatestatus() 
147 {
148     if(!X11Helper.gettextprop(rootWin, XA_WM_NAME, stext)) {
149         stext = "ddwm-"~VERSION;
150     }
151     drawbar(selmon);
152 }
153 
154