1 /**************************************************************************
3 * Copyright (C) 2008 Pål Staurland (staura@gmail.com)
4 * Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
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.
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 **************************************************************************/
20 #include <X11/Xutil.h>
21 #include <X11/Xatom.h>
23 #include <cairo-xlib.h>
24 #include <pango/pangocairo.h>
32 void visual_refresh ()
34 server_refresh_root_pixmap ();
37 refresh (&panel
.area
);
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
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
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
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
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
72 définir le zoom du panel
76 if (panel
.clock
.time1_format
) {
77 if (panel
.clock
.area
.redraw
)
79 if (draw (&panel
.clock
.area
)) {
80 panel
.clock
.area
.redraw
= 1;
81 draw (&panel
.clock
.area
);
86 refresh (&panel
.clock
.area
);
89 // TODO: ne pas afficher les taskbar invisibles
90 //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue;
94 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
97 refresh (&tskbar
->area
);
100 for (l1
= tskbar
->area
.list
; l1
; l1
= l1
->next
) {
104 if (tsk
== panel
.task_active
) refresh (&tsk
->area_active
);
105 else refresh (&tsk
->area
);
109 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
115 void set_panel_properties (Window win
)
117 XStoreName (server
.dsp
, win
, "tint2");
119 // TODO: check if the name is really needed for a panel/taskbar ?
121 gchar
*name
= g_locale_to_utf8("tint2", -1, NULL
, &len
, NULL
);
123 XChangeProperty(server
.dsp
, win
, server
.atom
._NET_WM_NAME
, server
.atom
.UTF8_STRING
, 8, PropModeReplace
, (unsigned char *) name
, (int) len
);
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);
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
;
139 struts
[3] = panel
.area
.height
+ panel
.marginy
;
140 struts
[10] = server
.posx
;
141 struts
[11] = server
.posx
+ panel
.area
.width
;
143 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT_PARTIAL
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 12);
145 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 4);
147 // Sticky and below other window
149 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_DESKTOP
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
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);
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);
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);
170 void window_draw_panel ()
174 /* panel position determined here */
175 if (panel
.position
& LEFT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ panel
.marginx
;
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);
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
;
183 /* Catch some events */
184 XSetWindowAttributes att
= { ParentRelative
, 0L, 0, 0L, 0, 0, Always
, 0L, 0L, False
, ExposureMask
|ButtonPressMask
|ButtonReleaseMask
, NoEventMask
, False
, 0, 0 };
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
);
190 set_panel_properties (win
);
191 window
.main_win
= win
;
193 // replaced : server.gc = DefaultGC (server.dsp, 0);
194 if (server
.gc
) XFree(server
.gc
);
196 server
.gc
= XCreateGC(server
.dsp
, win
, (unsigned long) 0, &gcValues
);
198 XMapWindow (server
.dsp
, win
);
205 panel
.clock
.area
.posx
= panel
.area
.width
- panel
.clock
.area
.width
- panel
.area
.paddingx
- panel
.area
.border
.width
;
209 // initialise taskbar posx and width
210 void resize_taskbar()
212 int taskbar_width
, modulo_width
, taskbar_on_screen
;
214 if (panel
.mode
== MULTI_DESKTOP
) taskbar_on_screen
= panel
.nb_desktop
;
215 else taskbar_on_screen
= panel
.nb_monitor
;
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
;
222 if (taskbar_on_screen
> 1)
223 modulo_width
= (taskbar_width
- ((taskbar_on_screen
-1) * panel
.area
.paddingx
)) % taskbar_on_screen
;
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
;
235 else posx
+= taskbar_width
+ panel
.area
.paddingx
;
238 tskbar
->area
.posx
= posx
;
239 tskbar
->area
.width
= taskbar_width
;
241 tskbar
->area
.width
++;
245 resize_tasks(tskbar
);