]> Dogcows Code - chaz/tint2/blob - src/panel.c
New import
[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 /*
40 pour version 0.7
41 gestion du systray
42 positionnement et taille fixe du systray (objet systray)
43 détection des notifications (détection des icones, ajout a la liste)
44 ajouter la transparence des icones
45 gérer le redimentionnement des éléments
46 => voir si lon peut faire abstraction sur le positionnement des objets ?
47 sachant que certains objets (task, taskbar) on une taille définit par l'extérieur
48 et d'autres objets (clock, systray) on une taille définit par l'intérieur
49
50 gestion du layout
51 voir le positionnement des taskbar, task et systray
52 définir panel_layout dans la configuration
53 comment gérer le multi panel avec des layouts différents
54
55 vérifier le niveau d'abstraction du code
56 utiliser la fonction draw(obj) récurrente sur Taskbar, Task, Systray, Clock
57 est ce compatible avec l'affichage de la tache active et les changement de taille -> redessine le panel
58
59 correction de bugs :
60 memory, segfault
61 background
62 remettre en place single_desktop avec nouveau layout
63 remettre en place multi_monitor avec nouveau layout
64 vérifier le changement de configuration
65
66 pour version 0.8
67 gestion du thème
68 voir la gestion du dégradé sur le bord et le fond (inkscape)
69 faut-il trois coordonnées de padding x, y, x inter-objects
70
71 gestion du zoom
72 définir le zoom du panel
73
74 */
75
76 if (panel.clock.time1_format) {
77 if (panel.clock.area.redraw)
78 panel.refresh = 1;
79 if (draw (&panel.clock.area)) {
80 panel.clock.area.redraw = 1;
81 draw (&panel.clock.area);
82 resize_clock();
83 resize_taskbar();
84 redraw(&panel.area);
85 }
86 refresh (&panel.clock.area);
87 }
88
89 // TODO: ne pas afficher les taskbar invisibles
90 //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue;
91 Task *tsk;
92 Taskbar *tskbar;
93 GSList *l0;
94 for (l0 = panel.area.list; l0 ; l0 = l0->next) {
95 tskbar = l0->data;
96 draw (&tskbar->area);
97 refresh (&tskbar->area);
98
99 GSList *l1;
100 for (l1 = tskbar->area.list; l1 ; l1 = l1->next) {
101 tsk = l1->data;
102 draw(&tsk->area);
103
104 if (tsk == panel.task_active) refresh (&tsk->area_active);
105 else refresh (&tsk->area);
106 }
107 }
108
109 XCopyArea (server.dsp, server.pmap, window.main_win, server.gc, 0, 0, panel.area.width, panel.area.height, 0, 0);
110 XFlush(server.dsp);
111 panel.refresh = 0;
112 }
113
114
115 void set_panel_properties (Window win)
116 {
117 XStoreName (server.dsp, win, "tint2");
118
119 // TODO: check if the name is really needed for a panel/taskbar ?
120 gsize len;
121 gchar *name = g_locale_to_utf8("tint2", -1, NULL, &len, NULL);
122 if (name != NULL) {
123 XChangeProperty(server.dsp, win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 8, PropModeReplace, (unsigned char *) name, (int) len);
124 g_free(name);
125 }
126
127 // Dock
128 long val = server.atom._NET_WM_WINDOW_TYPE_DOCK;
129 XChangeProperty (server.dsp, win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *) &val, 1);
130
131 // Reserved space
132 long struts [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
133 if (panel.position & TOP) {
134 struts[2] = panel.area.height + panel.marginy;
135 struts[8] = server.posx;
136 struts[9] = server.posx + panel.area.width;
137 }
138 else {
139 struts[3] = panel.area.height + panel.marginy;
140 struts[10] = server.posx;
141 struts[11] = server.posx + panel.area.width;
142 }
143 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT_PARTIAL, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 12);
144 // Old specification
145 XChangeProperty (server.dsp, win, server.atom._NET_WM_STRUT, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &struts, 4);
146
147 // Sticky and below other window
148 val = 0xFFFFFFFF;
149 XChangeProperty (server.dsp, win, server.atom._NET_WM_DESKTOP, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1);
150 Atom state[4];
151 state[0] = server.atom._NET_WM_STATE_SKIP_PAGER;
152 state[1] = server.atom._NET_WM_STATE_SKIP_TASKBAR;
153 state[2] = server.atom._NET_WM_STATE_STICKY;
154 state[3] = server.atom._NET_WM_STATE_BELOW;
155 XChangeProperty (server.dsp, win, server.atom._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *) state, 4);
156
157 // Fixed position
158 XSizeHints size_hints;
159 size_hints.flags = PPosition;
160 XChangeProperty (server.dsp, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32, PropModeReplace, (unsigned char *) &size_hints, sizeof (XSizeHints) / 4);
161
162 // Unfocusable
163 XWMHints wmhints;
164 wmhints.flags = InputHint;
165 wmhints.input = False;
166 XChangeProperty (server.dsp, win, XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, (unsigned char *) &wmhints, sizeof (XWMHints) / 4);
167 }
168
169
170 void window_draw_panel ()
171 {
172 Window win;
173
174 /* panel position determined here */
175 if (panel.position & LEFT) server.posx = server.monitor[panel.monitor].x + panel.marginx;
176 else {
177 if (panel.position & RIGHT) server.posx = server.monitor[panel.monitor].x + server.monitor[panel.monitor].width - panel.area.width - panel.marginx;
178 else server.posx = server.monitor[panel.monitor].x + ((server.monitor[panel.monitor].width - panel.area.width) / 2);
179 }
180 if (panel.position & TOP) server.posy = server.monitor[panel.monitor].y + panel.marginy;
181 else server.posy = server.monitor[panel.monitor].y + server.monitor[panel.monitor].height - panel.area.height - panel.marginy;
182
183 /* Catch some events */
184 XSetWindowAttributes att = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, ExposureMask|ButtonPressMask|ButtonReleaseMask, NoEventMask, False, 0, 0 };
185
186 /* XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib) */
187 if (window.main_win) XDestroyWindow(server.dsp, window.main_win);
188 win = XCreateWindow (server.dsp, server.root_win, server.posx, server.posy, panel.area.width, panel.area.height, 0, server.depth, InputOutput, CopyFromParent, CWEventMask, &att);
189
190 set_panel_properties (win);
191 window.main_win = win;
192
193 // replaced : server.gc = DefaultGC (server.dsp, 0);
194 if (server.gc) XFree(server.gc);
195 XGCValues gcValues;
196 server.gc = XCreateGC(server.dsp, win, (unsigned long) 0, &gcValues);
197
198 XMapWindow (server.dsp, win);
199 XFlush (server.dsp);
200 }
201
202
203 void resize_clock()
204 {
205 panel.clock.area.posx = panel.area.width - panel.clock.area.width - panel.area.paddingx - panel.area.border.width;
206 }
207
208
209 // initialise taskbar posx and width
210 void resize_taskbar()
211 {
212 int taskbar_width, modulo_width, taskbar_on_screen;
213
214 if (panel.mode == MULTI_DESKTOP) taskbar_on_screen = panel.nb_desktop;
215 else taskbar_on_screen = panel.nb_monitor;
216
217 taskbar_width = panel.area.width - (2 * panel.area.paddingx) - (2 * panel.area.border.width);
218 if (panel.clock.time1_format)
219 taskbar_width -= (panel.clock.area.width + panel.area.paddingx);
220 taskbar_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) / taskbar_on_screen;
221
222 if (taskbar_on_screen > 1)
223 modulo_width = (taskbar_width - ((taskbar_on_screen-1) * panel.area.paddingx)) % taskbar_on_screen;
224 else
225 modulo_width = 0;
226
227 int posx, modulo, i;
228 Taskbar *tskbar;
229 GSList *l0;
230 for (i = 0, l0 = panel.area.list; l0 ; i++, l0 = l0->next) {
231 if ((i % taskbar_on_screen) == 0) {
232 posx = panel.area.border.width + panel.area.paddingx;
233 modulo = modulo_width;
234 }
235 else posx += taskbar_width + panel.area.paddingx;
236
237 tskbar = l0->data;
238 tskbar->area.posx = posx;
239 tskbar->area.width = taskbar_width;
240 if (modulo) {
241 tskbar->area.width++;
242 modulo--;
243 }
244
245 resize_tasks(tskbar);
246 }
247 }
248
249
This page took 0.055072 seconds and 5 git commands to generate.