remove textwidth_primitive
[awesome.git] / ewmh.c
bloba9d6b9529ad783a1d8c0bf068e2f684207afbf7d
1 /*
2 * ewmh.c - EWMH support functions
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <X11/Xatom.h>
23 #include <X11/Xmd.h>
25 #include "ewmh.h"
26 #include "util.h"
27 #include "tag.h"
28 #include "focus.h"
29 #include "screen.h"
30 #include "layout.h"
32 extern AwesomeConf globalconf;
34 static Atom net_supported;
35 static Atom net_client_list;
36 static Atom net_number_of_desktops;
37 static Atom net_current_desktop;
38 static Atom net_desktop_names;
39 static Atom net_active_window;
41 static Atom net_close_window;
43 static Atom net_wm_name;
44 static Atom net_wm_icon_name;
45 static Atom net_wm_window_type;
46 static Atom net_wm_window_type_normal;
47 static Atom net_wm_window_type_dock;
48 static Atom net_wm_window_type_splash;
49 static Atom net_wm_icon;
50 static Atom net_wm_state;
51 static Atom net_wm_state_sticky;
52 static Atom net_wm_state_fullscreen;
54 static Atom utf8_string;
56 typedef struct
58 const char *name;
59 Atom *atom;
60 } AtomItem;
62 static AtomItem AtomNames[] =
64 { "_NET_SUPPORTED", &net_supported },
65 { "_NET_CLIENT_LIST", &net_client_list },
66 { "_NET_NUMBER_OF_DESKTOPS", &net_number_of_desktops },
67 { "_NET_CURRENT_DESKTOP", &net_current_desktop },
68 { "_NET_DESKTOP_NAMES", &net_desktop_names },
69 { "_NET_ACTIVE_WINDOW", &net_active_window },
71 { "_NET_CLOSE_WINDOW", &net_close_window },
73 { "_NET_WM_NAME", &net_wm_name },
74 { "_NET_WM_ICON_NAME", &net_wm_icon_name },
75 { "_NET_WM_WINDOW_TYPE", &net_wm_window_type },
76 { "_NET_WM_WINDOW_TYPE_NORMAL", &net_wm_window_type_normal },
77 { "_NET_WM_WINDOW_TYPE_DOCK", &net_wm_window_type_dock },
78 { "_NET_WM_WINDOW_TYPE_SPLASH", &net_wm_window_type_splash },
79 { "_NET_WM_ICON", &net_wm_icon },
80 { "_NET_WM_STATE", &net_wm_state },
81 { "_NET_WM_STATE_STICKY", &net_wm_state_sticky },
82 { "_NET_WM_STATE_FULLSCREEN", &net_wm_state_fullscreen },
84 { "UTF8_STRING", &utf8_string },
87 #define ATOM_NUMBER (sizeof(AtomNames)/sizeof(AtomItem))
89 #define _NET_WM_STATE_REMOVE 0
90 #define _NET_WM_STATE_ADD 1
91 #define _NET_WM_STATE_TOGGLE 2
93 void
94 ewmh_init_atoms(void)
96 unsigned int i;
97 char *names[ATOM_NUMBER];
98 Atom atoms[ATOM_NUMBER];
100 for(i = 0; i < ATOM_NUMBER; i++)
101 names[i] = (char *) AtomNames[i].name;
102 XInternAtoms(globalconf.display, names, ATOM_NUMBER, False, atoms);
103 for(i = 0; i < ATOM_NUMBER; i++)
104 *AtomNames[i].atom = atoms[i];
107 void
108 ewmh_set_supported_hints(int phys_screen)
110 Atom atom[ATOM_NUMBER];
111 int i = 0;
113 atom[i++] = net_supported;
114 atom[i++] = net_client_list;
115 atom[i++] = net_number_of_desktops;
116 atom[i++] = net_current_desktop;
117 atom[i++] = net_desktop_names;
118 atom[i++] = net_active_window;
120 atom[i++] = net_close_window;
122 atom[i++] = net_wm_name;
123 atom[i++] = net_wm_icon_name;
124 atom[i++] = net_wm_window_type;
125 atom[i++] = net_wm_window_type_normal;
126 atom[i++] = net_wm_window_type_dock;
127 atom[i++] = net_wm_window_type_splash;
128 atom[i++] = net_wm_icon;
129 atom[i++] = net_wm_state;
130 atom[i++] = net_wm_state_sticky;
131 atom[i++] = net_wm_state_fullscreen;
133 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
134 net_supported, XA_ATOM, 32,
135 PropModeReplace, (unsigned char *) atom, i);
138 void
139 ewmh_update_net_client_list(int phys_screen)
141 Window *wins;
142 Client *c;
143 int n = 0;
145 for(c = globalconf.clients; c; c = c->next)
146 if(c->phys_screen == phys_screen)
147 n++;
149 wins = p_new(Window, n + 1);
151 for(n = 0, c = globalconf.clients; c; c = c->next, n++)
152 if(c->phys_screen == phys_screen)
153 wins[n] = c->win;
155 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
156 net_client_list, XA_WINDOW, 32, PropModeReplace, (unsigned char *) wins, n);
158 p_delete(&wins);
159 XFlush(globalconf.display);
162 void
163 ewmh_update_net_numbers_of_desktop(int phys_screen)
165 CARD32 count = 0;
166 Tag *tag;
168 for(tag = globalconf.screens[phys_screen].tags; tag; tag = tag->next)
169 count++;
171 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
172 net_number_of_desktops, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &count, 1);
175 void
176 ewmh_update_net_current_desktop(int phys_screen)
178 CARD32 count = 0;
179 Tag *tag, **curtags = get_current_tags(phys_screen);
181 for(tag = globalconf.screens[phys_screen].tags; tag != curtags[0]; tag = tag->next)
182 count++;
184 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
185 net_current_desktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &count, 1);
187 p_delete(&curtags);
190 void
191 ewmh_update_net_desktop_names(int phys_screen)
193 char buf[1024], *pos;
194 ssize_t len, curr_size;
195 Tag *tag;
197 pos = buf;
198 len = 0;
199 for(tag = globalconf.screens[phys_screen].tags; tag; tag = tag->next)
201 curr_size = a_strlen(tag->name);
202 a_strcpy(pos, sizeof(buf), tag->name);
203 pos += curr_size + 1;
204 len += curr_size + 1;
207 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
208 net_desktop_names, utf8_string, 8, PropModeReplace, (unsigned char *) buf, len);
211 void
212 ewmh_update_net_active_window(int phys_screen)
214 Window win;
215 Client *sel = focus_get_current_client(phys_screen);
217 win = sel ? sel->win : None;
219 XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen),
220 net_active_window, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &win, 1);
223 static void
224 ewmh_process_state_atom(Client *c, Atom state, int set)
226 if(state == net_wm_state_sticky)
228 Tag *tag;
229 for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
230 tag_client(c, tag);
232 else if(state == net_wm_state_fullscreen)
234 Area area = get_screen_area(c->screen, NULL, NULL);
235 /* reset max attribute */
236 if(set == _NET_WM_STATE_REMOVE)
237 c->ismax = True;
238 else if(set == _NET_WM_STATE_ADD)
239 c->ismax = False;
240 client_maximize(c, area.x, area.y, area.width, area.height);
242 else
243 printf("%s received unknown window state %s\n", c->name, XGetAtomName(globalconf.display, state));
246 static void
247 ewmh_process_window_type_atom(Client *c, Atom state)
249 if(state == net_wm_window_type_normal)
251 /* do nothing */
253 else if(state == net_wm_window_type_dock
254 || state == net_wm_window_type_splash)
256 c->border = 0;
257 c->skip = True;
258 c->isfixed = True;
259 c->isfloating = True;
261 else
262 printf("%s received unknown window type %s\n", c->name, XGetAtomName(globalconf.display, state));
264 void
265 ewmh_process_client_message(XClientMessageEvent *ev)
267 Client *c;
268 int screen;
270 if(ev->message_type == net_current_desktop)
271 for(screen = 0; screen < ScreenCount(globalconf.display); screen++)
272 if(ev->window == RootWindow(globalconf.display, screen))
273 tag_view(screen, ev->data.l[0]);
275 if(ev->message_type == net_close_window)
277 if((c = get_client_bywin(globalconf.clients, ev->window)))
278 client_kill(c);
280 else if(ev->message_type == net_wm_state)
282 if((c = get_client_bywin(globalconf.clients, ev->window)))
284 ewmh_process_state_atom(c, (Atom) ev->data.l[1], ev->data.l[0]);
285 if(ev->data.l[2])
286 ewmh_process_state_atom(c, (Atom) ev->data.l[2], ev->data.l[0]);
291 void
292 ewmh_check_client_hints(Client *c)
294 int format;
295 Atom real, *state;
296 unsigned char *data = NULL;
297 unsigned long i, n, extra;
299 if(XGetWindowProperty(globalconf.display, c->win, net_wm_state, 0L, LONG_MAX, False,
300 XA_ATOM, &real, &format, &n, &extra,
301 (unsigned char **) &data) == Success && data)
303 state = (Atom *) data;
304 for(i = 0; i < n; i++)
305 ewmh_process_state_atom(c, state[i], _NET_WM_STATE_ADD);
307 XFree(data);
310 if(XGetWindowProperty(globalconf.display, c->win, net_wm_window_type, 0L, LONG_MAX, False,
311 XA_ATOM, &real, &format, &n, &extra,
312 (unsigned char **) &data) == Success && data)
314 state = (Atom *) data;
315 for(i = 0; i < n; i++)
316 ewmh_process_window_type_atom(c, state[i]);
318 XFree(data);
322 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80