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
);
39 if (panel
.clock
.time1_format
) {
40 if (panel
.clock
.area
.redraw
)
42 if (draw (&panel
.clock
.area
)) {
43 panel
.clock
.area
.redraw
= 1;
44 draw (&panel
.clock
.area
);
49 refresh (&panel
.clock
.area
);
52 // TODO: ne pas afficher les taskbar invisibles
53 //if (panel.mode != MULTI_DESKTOP && desktop != server.desktop) continue;
57 for (l0
= panel
.area
.list
; l0
; l0
= l0
->next
) {
60 refresh (&tskbar
->area
);
63 for (l1
= tskbar
->area
.list
; l1
; l1
= l1
->next
) {
67 if (tsk
== panel
.task_active
) refresh (&tsk
->area_active
);
68 else refresh (&tsk
->area
);
72 XCopyArea (server
.dsp
, server
.pmap
, window
.main_win
, server
.gc
, 0, 0, panel
.area
.width
, panel
.area
.height
, 0, 0);
78 void set_panel_properties (Window win
)
80 XStoreName (server
.dsp
, win
, "tint2");
82 // TODO: check if the name is really needed for a panel/taskbar ?
84 gchar
*name
= g_locale_to_utf8("tint2", -1, NULL
, &len
, NULL
);
86 XChangeProperty(server
.dsp
, win
, server
.atom
._NET_WM_NAME
, server
.atom
.UTF8_STRING
, 8, PropModeReplace
, (unsigned char *) name
, (int) len
);
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);
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
;
102 struts
[3] = panel
.area
.height
+ panel
.marginy
;
103 struts
[10] = server
.posx
;
104 struts
[11] = server
.posx
+ panel
.area
.width
;
106 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT_PARTIAL
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 12);
108 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_STRUT
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &struts
, 4);
110 // Sticky and below other window
112 XChangeProperty (server
.dsp
, win
, server
.atom
._NET_WM_DESKTOP
, XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &val
, 1);
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);
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);
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);
133 void window_draw_panel ()
137 /* panel position determined here */
138 if (panel
.position
& LEFT
) server
.posx
= server
.monitor
[panel
.monitor
].x
+ panel
.marginx
;
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);
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
;
146 /* Catch some events */
147 XSetWindowAttributes att
= { ParentRelative
, 0L, 0, 0L, 0, 0, Always
, 0L, 0L, False
, ExposureMask
|ButtonPressMask
|ButtonReleaseMask
, NoEventMask
, False
, 0, 0 };
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
);
153 set_panel_properties (win
);
154 window
.main_win
= win
;
156 // replaced : server.gc = DefaultGC (server.dsp, 0);
157 if (server
.gc
) XFree(server
.gc
);
159 server
.gc
= XCreateGC(server
.dsp
, win
, (unsigned long) 0, &gcValues
);
161 XMapWindow (server
.dsp
, win
);
168 panel
.clock
.area
.posx
= panel
.area
.width
- panel
.clock
.area
.width
- panel
.area
.paddingx
- panel
.area
.border
.width
;
172 // initialise taskbar posx and width
173 void resize_taskbar()
175 int taskbar_width
, modulo_width
, taskbar_on_screen
;
177 if (panel
.mode
== MULTI_DESKTOP
) taskbar_on_screen
= panel
.nb_desktop
;
178 else taskbar_on_screen
= panel
.nb_monitor
;
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
;
185 if (taskbar_on_screen
> 1)
186 modulo_width
= (taskbar_width
- ((taskbar_on_screen
-1) * panel
.area
.paddingx
)) % taskbar_on_screen
;
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
;
198 else posx
+= taskbar_width
+ panel
.area
.paddingx
;
201 tskbar
->area
.posx
= posx
;
202 tskbar
->area
.width
= taskbar_width
;
204 tskbar
->area
.width
++;
208 resize_tasks(tskbar
);