]> Dogcows Code - chaz/tint2/blob - src/panel.c
fixed issue and test svn
[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 server_refresh_root_pixmap ();
35
36 draw (&panel.area);
37 refresh (&panel.area);
38
39 if (panel.clock.time1_format) {
40 if (panel.clock.area.redraw)
41 panel.refresh = 1;
42 if (draw (&panel.clock.area)) {
43 panel.clock.area.redraw = 1;
44 draw (&panel.clock.area);
45 resize_clock();
46 resize_taskbar();
47 redraw(&panel.area);
48 }
49 refresh (&panel.clock.area);
50 }
51
52 // TODO: ne pas afficher les taskbar invisibles
53 //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue;
54 Task *tsk;
55 Taskbar *tskbar;
56 GSList *l0;
57 for (l0 = panel.area.list; l0 ; l0 = l0->next) {
58 tskbar = l0->data;
59 draw (&tskbar->area);
60 refresh (&tskbar->area);
61
62 GSList *l1;
63 for (l1 = tskbar->area.list; l1 ; l1 = l1->next) {
64 tsk = l1->data;
65 draw(&tsk->area);
66
67 if (tsk == panel.task_active) refresh (&tsk->area_active);
68 else refresh (&tsk->area);
69 }
70 }
71
72 XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0);
73 XFlush(server.dsp);
74 panel.refresh = 0;
75 }
76
77
78 void set_panel_properties (Window win)
79 {
80 XStoreName (server.dsp, win, "tint2");
81
82 // TODO: check if the name is really needed for a panel/taskbar ?
83 gsize len;
84 gchar *name = g_locale_to_utf8("tint2", -1, NULL, &len, NULL);
85 if (name != NULL) {
86 XChangeProperty(server.dsp, win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 8, PropModeReplace, (unsigned char *) name, (int) len);
87 g_free(name);
88 }
89
90 // Dock
91 long val = server.atom._NET_WM_WINDOW_TYPE_DOCK;
92 XChangeProperty (server.dsp, win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &val, 1);
93
94 // Reserved space
95 long struts [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
96 if (panel.position & TOP) {
97 struts[2] = panel.area.height + panel.marginy;
98 struts[8] = server.posx;
99 struts[9] = server.posx + panel.area.width;
100 }
101 else {
102 struts[3] = panel.area.height + panel.marginy;
103 struts[10] = server.posx;
104 struts[11] = server.posx + panel.area.width;
105 }
106 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12);
107 // Old specification
108 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4);
109
110 // Sticky and below other window
111 val = 0xFFFFFFFF;
112 XChangeProperty (server.dsp, win, server.atom._NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1);
113 Atom state[4];
114 state[0] = server.atom._NET_WM_STATE_SKIP_PAGER;
115 state[1] = server.atom._NET_WM_STATE_SKIP_TASKBAR;
116 state[2] = server.atom._NET_WM_STATE_STICKY;
117 state[3] = server.atom._NET_WM_STATE_BELOW;
118 XChangeProperty (server.dsp, win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, 4);
119
120 // Fixed position
121 XSizeHints size_hints;
122 size_hints.flags = PPosition;
123 XChangeProperty (server.dsp, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32, PropModeReplace, (unsigned char *) &size_hints, sizeof (XSizeHints) / 4);
124
125 // Unfocusable
126 XWMHints wmhints;
127 wmhints.flags = InputHint;
128 wmhints.input = False;
129 XChangeProperty (server.dsp, win, XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, (unsigned char *) &wmhints, sizeof (XWMHints) / 4);
130 }
131
132
133 void window_draw_panel ()
134 {
135 Window win;
136
137 /* panel position determined here */
138 if (panel.position & LEFT) server.posx = server.monitor[panel.monitor].x + panel.marginx;
139 else {
140 if (panel.position & RIGHT) server.posx = server.monitor[panel.monitor].x + server.monitor[panel.monitor].width - panel.area.width - panel.marginx;
141 else server.posx = server.monitor[panel.monitor].x + ((server.monitor[panel.monitor].width - panel.area.width) / 2);
142 }
143 if (panel.position & TOP) server.posy = server.monitor[panel.monitor].y + panel.marginy;
144 else server.posy = server.monitor[panel.monitor].y + server.monitor[panel.monitor].height - panel.area.height - panel.marginy;
145
146 /* Catch some events */
147 XSetWindowAttributes att = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, ExposureMask|ButtonPressMask|ButtonReleaseMask, NoEventMask, False, 0, 0 };
148
149 /* XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib) */
150 if (window.main_win) XDestroyWindow(server.dsp, window.main_win);
151 win = XCreateWindow (server.dsp, server.root_win, server.posx, server.posy, panel.area.width, panel.area.height, 0, server.depth, InputOutput, CopyFromParent, CWEventMask, &att);
152
153 set_panel_properties (win);
154 window.main_win = win;
155
156 // replaced : server.gc = DefaultGC (server.dsp, 0);
157 if (server.gc) XFree(server.gc);
158 XGCValues gcValues;
159 server.gc = XCreateGC(server.dsp, win, (unsigned long) 0, &gcValues);
160
161 XMapWindow (server.dsp, win);
162 XFlush (server.dsp);
163 }
164
165
166 void resize_clock()
167 {
168 panel.clock.area.posx = panel.area.width - panel.clock.area.width - panel.area.paddingx - panel.area.border.width;
169 }
170
171
172 // initialise taskbar posx and width
173 void resize_taskbar()
174 {
175 int taskbar_width, modulo_width, taskbar_on_screen;
176
177 if (panel.mode == MULTI_DESKTOP) taskbar_on_screen = panel.nb_desktop;
178 else taskbar_on_screen = panel.nb_monitor;
179
180 taskbar_width = panel.area.width - (2 * panel.area.paddingx) - (2 * panel.area.border.width);
181 if (panel.clock.time1_format)
182 taskbar_width -= (panel.clock.area.width + panel.area.paddingx);
183 taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) / taskbar_on_screen;
184
185 if (taskbar_on_screen > 1)
186 modulo_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) % taskbar_on_screen;
187 else
188 modulo_width = 0;
189
190 int posx, modulo, i;
191 Taskbar *tskbar;
192 GSList *l0;
193 for (i = 0, l0 = panel.area.list; l0 ; i++, l0 = l0->next) {
194 if ((i % taskbar_on_screen) == 0) {
195 posx = panel.area.border.width + panel.area.paddingx;
196 modulo = modulo_width;
197 }
198 else posx += taskbar_width + panel.area.paddingx;
199
200 tskbar = l0->data;
201 tskbar->area.posx = posx;
202 tskbar->area.width = taskbar_width;
203 if (modulo) {
204 tskbar->area.width++;
205 modulo--;
206 }
207
208 resize_tasks(tskbar);
209 }
210 }
211
212
This page took 0.044725 seconds and 5 git commands to generate.