]> Dogcows Code - chaz/tint2/blob - src/panel.c
fixed bug with active task
[chaz/tint2] / src / panel.c
1 /**************************************************************************
2 *
3 * Copyright (C) 2008 Pål Staurland (staura@gmail.com)
4 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 **************************************************************************/
18
19 #include <X11/Xlib.h>
20 #include <X11/Xutil.h>
21 #include <X11/Xatom.h>
22 #include <cairo.h>
23 #include <cairo-xlib.h>
24 #include <pango/pangocairo.h>
25
26 #include "server.h"
27 #include "window.h"
28 #include "task.h"
29 #include "panel.h"
30
31
32 void visual_refresh ()
33 {
34 if (!panel.area.pix.pmap)
35 set_panel_background();
36
37 if (server.pmap) XFreePixmap (server.dsp, server.pmap);
38 server.pmap = server_create_pixmap (panel.area.width, panel.area.height);
39 XCopyArea (server.dsp, panel.area.pix.pmap, server.pmap, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0);
40
41 // draw child object
42 GSList *l = panel.area.list;
43 for (; l ; l = l->next)
44 refresh (l->data);
45
46 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
47 XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, panel.area.paddingx, 0, panel.area.width-(2*panel.area.paddingx), panel.area.height, 0, 0);
48 XFlush (server.dsp);
49 panel.refresh = 0;
50 }
51
52
53 void set_panel_properties (Window win)
54 {
55 XStoreName (server.dsp, win, "tint2");
56
57 // TODO: check if the name is really needed for a panel/taskbar ?
58 gsize len;
59 gchar *name = g_locale_to_utf8("tint2", -1, NULL, &len, NULL);
60 if (name != NULL) {
61 XChangeProperty(server.dsp, win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 8, PropModeReplace, (unsigned char *) name, (int) len);
62 g_free(name);
63 }
64
65 // Dock
66 long val = server.atom._NET_WM_WINDOW_TYPE_DOCK;
67 XChangeProperty (server.dsp, win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &val, 1);
68
69 // Reserved space
70 long struts [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
71 if (panel.position & TOP) {
72 struts[2] = panel.area.height + panel.marginy;
73 struts[8] = server.posx;
74 struts[9] = server.posx + panel.area.width;
75 }
76 else {
77 struts[3] = panel.area.height + panel.marginy;
78 struts[10] = server.posx;
79 struts[11] = server.posx + panel.area.width;
80 }
81 // Old specification : fluxbox need _NET_WM_STRUT.
82 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4);
83 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12);
84
85 // Sticky and below other window
86 val = 0xFFFFFFFF;
87 XChangeProperty (server.dsp, win, server.atom._NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1);
88 Atom state[4];
89 state[0] = server.atom._NET_WM_STATE_SKIP_PAGER;
90 state[1] = server.atom._NET_WM_STATE_SKIP_TASKBAR;
91 state[2] = server.atom._NET_WM_STATE_STICKY;
92 state[3] = server.atom._NET_WM_STATE_BELOW;
93 XChangeProperty (server.dsp, win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, 4);
94
95 // Fixed position
96 XSizeHints size_hints;
97 size_hints.flags = PPosition;
98 XChangeProperty (server.dsp, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32, PropModeReplace, (unsigned char *) &size_hints, sizeof (XSizeHints) / 4);
99
100 // Unfocusable
101 XWMHints wmhints;
102 wmhints.flags = InputHint;
103 wmhints.input = False;
104 XChangeProperty (server.dsp, win, XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, (unsigned char *) &wmhints, sizeof (XWMHints) / 4);
105
106 // Undecorated
107 long prop[5] = { 2, 0, 0, 0, 0 };
108 XChangeProperty(server.dsp, win, server.atom._MOTIF_WM_HINTS, server.atom._MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *) prop, 5);
109 }
110
111
112 void window_draw_panel ()
113 {
114 Window win;
115
116 /* panel position determined here */
117 if (panel.position & LEFT) server.posx = server.monitor[panel.monitor].x + panel.marginx;
118 else {
119 if (panel.position & RIGHT) server.posx = server.monitor[panel.monitor].x + server.monitor[panel.monitor].width - panel.area.width - panel.marginx;
120 else server.posx = server.monitor[panel.monitor].x + ((server.monitor[panel.monitor].width - panel.area.width) / 2);
121 }
122 if (panel.position & TOP) server.posy = server.monitor[panel.monitor].y + panel.marginy;
123 else server.posy = server.monitor[panel.monitor].y + server.monitor[panel.monitor].height - panel.area.height - panel.marginy;
124
125 /* Catch some events */
126 XSetWindowAttributes att = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, ExposureMask|ButtonPressMask|ButtonReleaseMask, NoEventMask, False, 0, 0 };
127
128 // XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib)
129 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
130 if (window.main_win) XDestroyWindow(server.dsp, window.main_win);
131 win = XCreateWindow (server.dsp, server.root_win, server.posx+panel.area.paddingx, server.posy, panel.area.width-(2*panel.area.paddingx), panel.area.height, 0, server.depth, InputOutput, CopyFromParent, CWEventMask, &att);
132
133 set_panel_properties (win);
134 window.main_win = win;
135
136 // replaced : server.gc = DefaultGC (server.dsp, 0);
137 if (server.gc) XFree(server.gc);
138 XGCValues gcValues;
139 server.gc = XCreateGC(server.dsp, win, (unsigned long) 0, &gcValues);
140 if (server.gc_root) XFree(server.gc_root);
141 server.gc_root = XCreateGC(server.dsp, server.root_win, (unsigned long) 0, &gcValues);
142
143 XMapWindow (server.dsp, win);
144 XFlush (server.dsp);
145 }
146
147
148 void visible_object()
149 {
150 if (panel.area.list) {
151 g_slist_free(panel.area.list);
152 panel.area.list = 0;
153 }
154
155 // list of visible objects
156 // start with clock because draw(clock) can resize others object
157 if (panel.clock.time1_format)
158 panel.area.list = g_slist_append(panel.area.list, &panel.clock);
159
160 int i, j;
161 Taskbar *taskbar;
162 for (i=0 ; i < panel.nb_desktop ; i++) {
163 for (j=0 ; j < panel.nb_monitor ; j++) {
164 taskbar = &panel.taskbar[index(i,j)];
165 if (panel.mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) continue;
166
167 panel.area.list = g_slist_append(panel.area.list, taskbar);
168 }
169 }
170 set_redraw(&panel.area);
171 panel.refresh = 1;
172 }
173
174
175 void set_panel_background()
176 {
177 Pixmap wall = get_root_pixmap();
178
179 panel.area.pix.pmap = server_create_pixmap (panel.area.width, panel.area.height);
180
181 // add layer of root pixmap
182 XCopyArea (server.dsp, wall, panel.area.pix.pmap, server.gc, server.posx, server.posy, panel.area.width, panel.area.height, 0, 0);
183
184 // draw background panel
185 cairo_surface_t *cs;
186 cairo_t *c;
187 cs = cairo_xlib_surface_create (server.dsp, panel.area.pix.pmap, server.visual, panel.area.width, panel.area.height);
188 c = cairo_create (cs);
189
190 draw_background (&panel.area, c, 0);
191
192 cairo_destroy (c);
193 cairo_surface_destroy (cs);
194
195 // copy background panel on desktop window
196 XCopyArea (server.dsp, panel.area.pix.pmap, server.root_win, server.gc_root, 0, 0, panel.area.width, panel.area.height, server.posx, server.posy);
197
198 set_redraw (&panel.area);
199 }
200
201
This page took 0.049247 seconds and 5 git commands to generate.