aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Ewmh.cc146
1 files changed, 128 insertions, 18 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index f715ccc..3f5bd86 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -19,12 +19,13 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: Ewmh.cc,v 1.2 2002/10/11 10:20:33 fluxgen Exp $ 22// $Id: Ewmh.cc,v 1.3 2002/10/16 19:03:57 fluxgen Exp $
23 23
24#include "Ewmh.hh" 24#include "Ewmh.hh"
25 25
26#include "Screen.hh" 26#include "Screen.hh"
27#include "Window.hh" 27#include "Window.hh"
28#include "fluxbox.hh"
28 29
29#include <iostream> 30#include <iostream>
30using namespace std; 31using namespace std;
@@ -62,14 +63,21 @@ void Ewmh::initForScreen(const BScreen &screen) {
62 63
63 //set supported atoms 64 //set supported atoms
64 Atom atomsupported[] = { 65 Atom atomsupported[] = {
66 // window properties
65 m_net_wm_state, 67 m_net_wm_state,
66 // states that we support: 68 // states that we support:
67 m_net_wm_state_sticky, 69 m_net_wm_state_sticky,
68 m_net_wm_state_shaded, 70 m_net_wm_state_shaded,
69 71
72 m_net_wm_desktop,
73
74 // root properties
70 m_net_client_list, 75 m_net_client_list,
71 m_net_number_of_desktops, 76 m_net_number_of_desktops,
72 m_net_current_desktop, 77 m_net_current_desktop,
78 m_net_active_window,
79 m_net_close_window,
80 m_net_moveresize_window,
73 m_net_desktop_names, 81 m_net_desktop_names,
74 m_net_supporting_wm_check 82 m_net_supporting_wm_check
75 }; 83 };
@@ -80,23 +88,36 @@ void Ewmh::initForScreen(const BScreen &screen) {
80 88
81 89
82} 90}
91
83void Ewmh::setupWindow(FluxboxWindow &win) { 92void Ewmh::setupWindow(FluxboxWindow &win) {
84/* 93
85 Display *disp = BaseDisplay::getXDisplay(); 94 Display *disp = BaseDisplay::getXDisplay();
86 Atom ret_type; 95 Atom ret_type;
87 int fmt; 96 int fmt;
88 unsigned long nitems, bytes_after; 97 unsigned long nitems, bytes_after;
89 long flags, *data = 0; 98 long *data = 0;
90 99/*
91 if (XGetWindowProperty(disp, win.getClientWindow(), 100 if (XGetWindowProperty(disp, win.getClientWindow(),
92 m_net_wm_state, 0, 1, False, XA_CARDINAL, 101 m_net_wm_state, 0, 1, False, XA_CARDINAL,
93 &ret_type, &fmt, &nitems, &bytes_after, 102 &ret_type, &fmt, &nitems, &bytes_after,
94 (unsigned char **) &data) == Success && data) { 103 (unsigned char **) &data) == Success && data) {
95 flags = *data; 104 flags = *data;
96 setState(win, flags); 105 setState(win, flags);
97 XFree (data); 106 XFree(data);
98 } 107 }
99*/ 108*/
109 if (XGetWindowProperty(disp, win.getClientWindow(),
110 m_net_wm_desktop, 0, 1, False, XA_CARDINAL,
111 &ret_type, &fmt, &nitems, &bytes_after,
112 (unsigned char **) &data) == Success && data) {
113 unsigned int desktop = static_cast<unsigned int>(*data);
114 if (desktop == 0xFFFFFFFF && !win.isStuck())
115 win.stick();
116 else if (win.getScreen())
117 win.getScreen()->sendToWorkspace(desktop, &win, false);
118
119 XFree(data);
120 }
100} 121}
101 122
102void Ewmh::updateClientList(const BScreen &screen) { 123void Ewmh::updateClientList(const BScreen &screen) {
@@ -134,7 +155,7 @@ void Ewmh::updateClientList(const BScreen &screen) {
134 XA_CARDINAL, 32, 155 XA_CARDINAL, 32,
135 PropModeReplace, (unsigned char *)wl, num); 156 PropModeReplace, (unsigned char *)wl, num);
136 157
137 delete wl; 158 delete [] wl;
138} 159}
139 160
140void Ewmh::updateWorkspaceNames(const BScreen &screen) { 161void Ewmh::updateWorkspaceNames(const BScreen &screen) {
@@ -183,24 +204,113 @@ void Ewmh::updateHints(FluxboxWindow &win) {
183} 204}
184 205
185void Ewmh::updateWorkspace(FluxboxWindow &win) { 206void Ewmh::updateWorkspace(FluxboxWindow &win) {
207 int workspace = win.getWorkspaceNumber();
208 if (win.isStuck())
209 workspace = 0xFFFFFFFF; // appear on all desktops/workspaces
186 210
211 XChangeProperty(BaseDisplay::getXDisplay(), win.getClientWindow(),
212 m_net_wm_desktop, XA_CARDINAL, 32, PropModeReplace,
213 (unsigned char *)&workspace, 1);
187} 214}
188 215
189bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen *screen, FluxboxWindow *win) { 216// return true if we did handle the atom here
190 if (win != 0) { 217bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * const screen, FluxboxWindow * const win) {
191 if (ce.message_type == m_net_wm_state) { 218
192 if (ce.data.l[0] == STATE_REMOVE) { 219 if (ce.message_type == m_net_wm_desktop) {
193 setState(*win, ce.data.l[1], false); 220 if (screen == 0)
194 setState(*win, ce.data.l[2], false); 221 return true;
195 } else if (ce.data.l[0] == STATE_ADD) { 222 // ce.data.l[0] = workspace number
196 setState(*win, ce.data.l[1], true); 223 // valid window and workspace number?
197 setState(*win, ce.data.l[2], true); 224 if (win == 0 || static_cast<unsigned int>(ce.data.l[0]) >= screen->getCount())
198 } else if (ce.data.l[0] == STATE_TOGGLE) { 225 return true;
199 toggleState(*win, ce.data.l[1]); 226
200 toggleState(*win, ce.data.l[2]); 227 screen->sendToWorkspace(ce.data.l[0], win, false);
228 return true;
229 } else if (ce.message_type == m_net_wm_state) {
230 if (win == 0)
231 return true;
232 // ce.data.l[0] = the action (remove, add or toggle)
233 // ce.data.l[1] = the first property to alter
234 // ce.data.l[2] = second property to alter (can be zero)
235 if (ce.data.l[0] == STATE_REMOVE) {
236 setState(*win, ce.data.l[1], false);
237 setState(*win, ce.data.l[2], false);
238 } else if (ce.data.l[0] == STATE_ADD) {
239 setState(*win, ce.data.l[1], true);
240 setState(*win, ce.data.l[2], true);
241 } else if (ce.data.l[0] == STATE_TOGGLE) {
242 toggleState(*win, ce.data.l[1]);
243 toggleState(*win, ce.data.l[2]);
244 }
245 return true;
246 } else if (ce.message_type == m_net_number_of_desktops) {
247 if (screen == 0)
248 return true;
249 // ce.data.l[0] = number of workspaces
250
251 // no need to alter number of desktops if they are the same
252 // or if requested number of workspace is less than zero
253 if (screen->getCount() == static_cast<unsigned int>(ce.data.l[0]) ||
254 ce.data.l[0] < 0)
255 return true;
256
257 if (screen->getCount() > static_cast<unsigned int>(ce.data.l[0])) {
258 // remove last workspace until we have
259 // the same number of workspaces
260 while (screen->getCount() != static_cast<unsigned int>(ce.data.l[0])) {
261 screen->removeLastWorkspace();
262 if (screen->getCount() == 1) // must have at least one workspace
263 break;
264 }
265 } else { // add workspaces to screen until workspace count match the requested size
266 while (screen->getCount() != static_cast<unsigned int>(ce.data.l[0])) {
267 screen->addWorkspace();
201 } 268 }
202 } 269 }
270
271 return true;
272 } else if (ce.message_type == m_net_current_desktop) {
273 if (screen == 0)
274 return true;
275 // ce.data.l[0] = workspace number
276
277 // prevent out of range value
278 if (static_cast<unsigned int>(ce.data.l[0]) >= screen->getCount())
279 return true;
280 screen->changeWorkspaceID(ce.data.l[0]);
281 return true;
282 } else if (ce.message_type == m_net_active_window) {
283
284 // make sure we have a valid window
285 if (win == 0)
286 return true;
287 // ce.window = window to focus
288
289 // should move set focus somewhere else
290 // so we don't need fluxbox depedencies here
291 Fluxbox::instance()->setFocusedWindow(win);
292 return true;
293 } else if (ce.message_type == m_net_close_window) {
294 if (win == 0)
295 return true;
296 // ce.window = window to close (which in this case is the win argument)
297 win->close();
298 return true;
299 } else if (ce.message_type == m_net_moveresize_window) {
300 if (win == 0)
301 return true;
302 // ce.data.l[0] = gravity and flags
303 // ce.data.l[1] = x
304 // ce.data.l[2] = y
305 // ce.data.l[3] = width
306 // ce.data.l[4] = height
307 // TODO: gravity and flags
308 win->configure(ce.data.l[1], ce.data.l[2],
309 ce.data.l[3], ce.data.l[4]);
310 return true;
203 } 311 }
312
313 // we didn't handle the ce.message_type here
204 return false; 314 return false;
205} 315}
206 316