]> Dogcows Code - chaz/tint2/blob - src/panel.c
WM menu in left and right padding
[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.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.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 draw (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
107
108 void window_draw_panel ()
109 {
110 Window win;
111
112 /* panel position determined here */
113 if (panel.position & LEFT) server.posx = server.monitor[panel.monitor].x + panel.marginx;
114 else {
115 if (panel.position & RIGHT) server.posx = server.monitor[panel.monitor].x + server.monitor[panel.monitor].width - panel.area.width - panel.marginx;
116 else server.posx = server.monitor[panel.monitor].x + ((server.monitor[panel.monitor].width - panel.area.width) / 2);
117 }
118 if (panel.position & TOP) server.posy = server.monitor[panel.monitor].y + panel.marginy;
119 else server.posy = server.monitor[panel.monitor].y + server.monitor[panel.monitor].height - panel.area.height - panel.marginy;
120
121 /* Catch some events */
122 XSetWindowAttributes att = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, ExposureMask|ButtonPressMask|ButtonReleaseMask, NoEventMask, False, 0, 0 };
123
124 // XCreateWindow(display, parent, x, y, w, h, border, depth, class, visual, mask, attrib)
125 // main_win doesn't include panel.area.paddingx, so we have WM capabilities on left and right.
126 if (window.main_win) XDestroyWindow(server.dsp, window.main_win);
127 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);
128
129 set_panel_properties (win);
130 window.main_win = win;
131
132 // replaced : server.gc = DefaultGC (server.dsp, 0);
133 if (server.gc) XFree(server.gc);
134 XGCValues gcValues;
135 server.gc = XCreateGC(server.dsp, win, (unsigned long) 0, &gcValues);
136 if (server.gc_root) XFree(server.gc_root);
137 server.gc_root = XCreateGC(server.dsp, server.root_win, (unsigned long) 0, &gcValues);
138
139 XMapWindow (server.dsp, win);
140 XFlush (server.dsp);
141 }
142
143
144 void visible_object()
145 {
146 if (panel.area.list) {
147 g_slist_free(panel.area.list);
148 panel.area.list = 0;
149 }
150
151 // list of visible objects
152 // start with clock because draw(clock) can resize others object
153 if (panel.clock.time1_format)
154 panel.area.list = g_slist_append(panel.area.list, &panel.clock);
155
156 int i, j;
157 Taskbar *taskbar;
158 for (i=0 ; i < panel.nb_desktop ; i++) {
159 for (j=0 ; j < panel.nb_monitor ; j++) {
160 taskbar = &panel.taskbar[index(i,j)];
161 if (panel.mode != MULTI_DESKTOP && taskbar->desktop != server.desktop) continue;
162
163 panel.area.list = g_slist_append(panel.area.list, taskbar);
164 }
165 }
166 redraw(&panel.area);
167 panel.refresh = 1;
168 }
169
170
171 void set_panel_background()
172 {
173 Pixmap wall = get_root_pixmap();
174
175 panel.area.pmap = server_create_pixmap (panel.area.width, panel.area.height);
176
177 // add layer of root pixmap
178 XCopyArea (server.dsp, wall, panel.area.pmap, server.gc, server.posx, server.posy, panel.area.width, panel.area.height, 0, 0);
179
180 // draw background panel
181 cairo_surface_t *cs;
182 cairo_t *c;
183 cs = cairo_xlib_surface_create (server.dsp, panel.area.pmap, server.visual, panel.area.width, panel.area.height);
184 c = cairo_create (cs);
185
186 draw_background (&panel.area, c);
187
188 cairo_destroy (c);
189 cairo_surface_destroy (cs);
190
191 // copy background panel on desktop window
192 XCopyArea (server.dsp, panel.area.pmap, server.root_win, server.gc_root, 0, 0, panel.area.width, panel.area.height, server.posx, server.posy);
193
194 redraw (&panel.area);
195 }
196
197
This page took 0.050134 seconds and 5 git commands to generate.