]> Dogcows Code - chaz/openbox/blob - src/xeventhandler.cc
moving strut into its own .hh. adding OBClient class
[chaz/openbox] / src / xeventhandler.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
2
3 #include "xeventhandler.hh"
4 #include "otk/display.hh"
5 #include "otk/rect.hh"
6
7 namespace ob {
8
9
10 OBXEventHandler::OBXEventHandler()
11 {
12 _lasttime = 1; // 0 is CurrentTime, so set to minimum
13 }
14
15 void OBXEventHandler::buttonPress(const XButtonEvent &e)
16 {
17 _lasttime = e.time;
18
19 }
20
21
22 void OBXEventHandler::buttonRelease(const XButtonEvent &e)
23 {
24 _lasttime = e.time;
25
26 }
27
28
29 void OBXEventHandler::keyPress(const XKeyEvent &e)
30 {
31 _lasttime = e.time;
32 }
33
34
35 void OBXEventHandler::motion(const XMotionEvent &e)
36 {
37 _lasttime = e.time;
38
39 // the pointer is on the wrong screen
40 if (! e.same_screen) return;
41
42 }
43
44
45 void OBXEventHandler::enterNotify(const XCrossingEvent &e)
46 {
47 _lasttime = e.time;
48 /*
49 BScreen *screen = (BScreen *) 0;
50 BlackboxWindow *win = (BlackboxWindow *) 0;
51
52 if (e->xcrossing.mode == NotifyGrab) break;
53
54 if ((e->xcrossing.window == e->xcrossing.root) &&
55 (screen = searchScreen(e->xcrossing.window))) {
56 screen->getImageControl()->installRootColormap();
57 } else if ((win = searchWindow(e->xcrossing.window))) {
58 if (! no_focus)
59 win->enterNotifyEvent(&e->xcrossing);
60 }
61 */
62 }
63
64
65 void OBXEventHandler::leaveNotify(const XCrossingEvent &e)
66 {
67 _lasttime = e.time;
68 /*
69 BlackboxWindow *win = (BlackboxWindow *) 0;
70
71 if ((win = searchWindow(e->xcrossing.window)))
72 win->leaveNotifyEvent(&e->xcrossing);
73 */
74 }
75
76
77 void OBXEventHandler::configureRequest(const XConfigureRequestEvent &e)
78 {
79 (void)e;
80 /* BlackboxWindow *win = (BlackboxWindow *) 0;
81
82 if ((win = searchWindow(e->xconfigurerequest.window))) {
83 win->configureRequestEvent(&e->xconfigurerequest);
84 } else {
85 if (validateWindow(e->xconfigurerequest.window)) {
86 XWindowChanges xwc;
87
88 xwc.x = e->xconfigurerequest.x;
89 xwc.y = e->xconfigurerequest.y;
90 xwc.width = e->xconfigurerequest.width;
91 xwc.height = e->xconfigurerequest.height;
92 xwc.border_width = e->xconfigurerequest.border_width;
93 xwc.sibling = e->xconfigurerequest.above;
94 xwc.stack_mode = e->xconfigurerequest.detail;
95
96 XConfigureWindow(otk::OBDisplay::display, e->xconfigurerequest.window,
97 e->xconfigurerequest.value_mask, &xwc);
98 }
99 }
100 */
101 }
102
103
104 void OBXEventHandler::mapRequest(const XMapRequestEvent &e)
105 {
106 #ifdef DEBUG
107 printf("MapRequest for 0x%lx\n", e.window);
108 #endif // DEBUG
109 /*
110 BlackboxWindow *win = searchWindow(e->xmaprequest.window);
111
112 if (win) {
113 bool focus = False;
114 if (win->isIconic()) {
115 win->deiconify();
116 focus = True;
117 }
118 if (win->isShaded()) {
119 win->shade();
120 focus = True;
121 }
122
123 if (focus && (win->isTransient() || win->getScreen()->doFocusNew()) &&
124 win->isVisible())
125 win->setInputFocus();
126 } else {
127 BScreen *screen = searchScreen(e->xmaprequest.parent);
128
129 if (! screen) {
130 */
131 /*
132 we got a map request for a window who's parent isn't root. this
133 can happen in only one circumstance:
134
135 a client window unmapped a managed window, and then remapped it
136 somewhere between unmapping the client window and reparenting it
137 to root.
138
139 regardless of how it happens, we need to find the screen that
140 the window is on
141 */
142 /*
143 XWindowAttributes wattrib;
144 if (! XGetWindowAttributes(otk::OBDisplay::display,
145 e->xmaprequest.window,
146 &wattrib)) {
147 // failed to get the window attributes, perhaps the window has
148 // now been destroyed?
149 break;
150 }
151
152 screen = searchScreen(wattrib.root);
153 assert(screen != 0); // this should never happen
154 }
155 screen->manageWindow(e->xmaprequest.window);
156 }
157 */
158 }
159
160
161 void OBXEventHandler::unmapNotify(const XUnmapEvent &e)
162 {
163 (void)e;
164 /*
165 BlackboxWindow *win = (BlackboxWindow *) 0;
166 BScreen *screen = (BScreen *) 0;
167
168 if ((win = searchWindow(e->xunmap.window))) {
169 win->unmapNotifyEvent(&e->xunmap);
170 } else if ((screen = searchSystrayWindow(e->xunmap.window))) {
171 screen->removeSystrayWindow(e->xunmap.window);
172 }
173 */
174 }
175
176
177 void OBXEventHandler::destroyNotify(const XDestroyWindowEvent &e)
178 {
179 (void)e;
180 /*
181 BlackboxWindow *win = (BlackboxWindow *) 0;
182 BScreen *screen = (BScreen *) 0;
183 BWindowGroup *group = (BWindowGroup *) 0;
184
185 if ((win = searchWindow(e->xdestroywindow.window))) {
186 win->destroyNotifyEvent(&e->xdestroywindow);
187 } else if ((group = searchGroup(e->xdestroywindow.window))) {
188 delete group;
189 } else if ((screen = searchSystrayWindow(e->xunmap.window))) {
190 screen->removeSystrayWindow(e->xunmap.window);
191 }
192 */
193 }
194
195
196 void OBXEventHandler::reparentNotify(const XReparentEvent &e)
197 {
198 (void)e;
199 /*
200 this event is quite rare and is usually handled in unmapNotify
201 however, if the window is unmapped when the reparent event occurs
202 the window manager never sees it because an unmap event is not sent
203 to an already unmapped window.
204 */
205 /*
206 BlackboxWindow *win = searchWindow(e->xreparent.window);
207 if (win)
208 win->reparentNotifyEvent(&e->xreparent);
209 */
210 }
211
212
213 void OBXEventHandler::propertyNotify(const XPropertyEvent &e)
214 {
215 _lasttime = e.time;
216 /*
217 BlackboxWindow *win = (BlackboxWindow *) 0;
218 BScreen *screen = (BScreen *) 0;
219
220 if ((win = searchWindow(e->xproperty.window)))
221 win->propertyNotifyEvent(&e->xproperty);
222 else if ((screen = searchScreen(e->xproperty.window)))
223 screen->propertyNotifyEvent(&e->xproperty);
224 */
225 }
226
227
228 void OBXEventHandler::expose(const XExposeEvent &first)
229 {
230 // compress expose events
231 XEvent e; e.xexpose = first;
232 unsigned int i = 0;
233 otk::Rect area(e.xexpose.x, e.xexpose.y, e.xexpose.width,
234 e.xexpose.height);
235 while (XCheckTypedWindowEvent(otk::OBDisplay::display,
236 e.xexpose.window, Expose, &e)) {
237 i++;
238 // merge expose area
239 area |= otk::Rect(e.xexpose.x, e.xexpose.y, e.xexpose.width,
240 e.xexpose.height);
241 }
242 if ( i > 0 ) {
243 // use the merged area
244 e.xexpose.x = area.x();
245 e.xexpose.y = area.y();
246 e.xexpose.width = area.width();
247 e.xexpose.height = area.height();
248 }
249 /*
250 BlackboxWindow *win = (BlackboxWindow *) 0;
251
252 if ((win = searchWindow(e->xexpose.window)))
253 win->exposeEvent(&e->xexpose);
254 */
255 }
256
257
258 void OBXEventHandler::colormapNotify(const XColormapEvent &e)
259 {
260 (void)e;
261 /*
262 BScreen *screen = searchScreen(e->xcolormap.window);
263 if (screen)
264 screen->setRootColormapInstalled((e->xcolormap.state ==
265 ColormapInstalled) ? True : False);
266 */
267 }
268
269
270 void OBXEventHandler::focusIn(const XFocusChangeEvent &e)
271 {
272 if (e.detail != NotifyNonlinear &&
273 e.detail != NotifyAncestor) {
274 /*
275 don't process FocusIns when:
276 1. the new focus window isn't an ancestor or inferior of the old
277 focus window (NotifyNonlinear)
278 make sure to allow the FocusIn when the old focus window was an
279 ancestor but didn't have a parent, such as root (NotifyAncestor)
280 */
281 return;
282 }
283 /*
284 BlackboxWindow *win = searchWindow(e.window);
285 if (win) {
286 if (! win->isFocused())
287 win->setFocusFlag(True);
288 */
289 /*
290 set the event window to None. when the FocusOut event handler calls
291 this function recursively, it uses this as an indication that focus
292 has moved to a known window.
293 */
294 /*
295 e->xfocus.window = None;
296
297 no_focus = False; // focusing is back on
298 }
299 */
300 }
301
302
303 void OBXEventHandler::focusOut(const XFocusChangeEvent &e)
304 {
305 if (e.detail != NotifyNonlinear) {
306 /*
307 don't process FocusOuts when:
308 2. the new focus window isn't an ancestor or inferior of the old
309 focus window (NotifyNonlinear)
310 */
311 return;
312 }
313
314 /*
315 BlackboxWindow *win = searchWindow(e->xfocus.window);
316 if (win && win->isFocused()) {
317 */
318 /*
319 before we mark "win" as unfocused, we need to verify that focus is
320 going to a known location, is in a known location, or set focus
321 to a known location.
322 */
323 /*
324 XEvent event;
325 // don't check the current focus if FocusOut was generated during a grab
326 bool check_focus = (e->xfocus.mode == NotifyNormal);
327 */
328 /*
329 First, check if there is a pending FocusIn event waiting. if there
330 is, process it and determine if focus has moved to another window
331 (the FocusIn event handler sets the window in the event
332 structure to None to indicate this).
333 */
334 /*
335 if (XCheckTypedEvent(otk::OBDisplay::display, FocusIn, &event)) {
336
337 process_event(&event);
338 if (event.xfocus.window == None) {
339 // focus has moved
340 check_focus = False;
341 }
342 }
343
344 if (check_focus) {
345 */
346 /*
347 Second, we query the X server for the current input focus.
348 to make sure that we keep a consistent state.
349 */
350 /*
351 BlackboxWindow *focus;
352 Window w;
353 int revert;
354 XGetInputFocus(otk::OBDisplay::display, &w, &revert);
355 focus = searchWindow(w);
356 if (focus) {
357 */
358 /*
359 focus got from "win" to "focus" under some very strange
360 circumstances, and we need to make sure that the focus indication
361 is correct.
362 */
363 /*
364 setFocusedWindow(focus);
365 } else {
366 // we have no idea where focus went... so we set it to somewhere
367 setFocusedWindow(0);
368 }
369 }
370 }
371 */
372 }
373
374
375 #ifdef SHAPE
376 void OBXEventHandler::shapeEvent(const XShapeEvent &e)
377 {
378 XShapeEvent *shape_event = (XShapeEvent *) e;
379 BlackboxWindow *win = searchWindow(e->xany.window);
380
381 if (win && shape_event->kind == ShapeBounding)
382 win->shapeEvent(shape_event);
383 }
384 #endif // SHAPE
385
386
387 void OBXEventHandler::clientMessage(const XClientMessageEvent &e)
388 {
389 if (e.format != 32)
390 return;
391 /*
392 } else if (e->xclient.message_type ==
393 xatom->getAtom(XAtom::blackbox_change_workspace) ||
394 e->xclient.message_type ==
395 xatom->getAtom(XAtom::net_current_desktop)) {
396 // NET_CURRENT_DESKTOP message
397 BScreen *screen = searchScreen(e->xclient.window);
398
399 unsigned int workspace = e->xclient.data.l[0];
400 if (screen && workspace < screen->getWorkspaceCount())
401 screen->changeWorkspaceID(workspace);
402 } else if (e->xclient.message_type ==
403 xatom->getAtom(XAtom::net_active_window)) {
404 // NET_ACTIVE_WINDOW
405 BlackboxWindow *win = searchWindow(e->xclient.window);
406
407 if (win) {
408 BScreen *screen = win->getScreen();
409
410 if (win->isIconic())
411 win->deiconify(False, False);
412 if (! win->isStuck() &&
413 (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID())) {
414 no_focus = True;
415 screen->changeWorkspaceID(win->getWorkspaceNumber());
416 }
417 if (win->isVisible() && win->setInputFocus()) {
418 win->getScreen()->getWorkspace(win->getWorkspaceNumber())->
419 raiseWindow(win);
420 win->installColormap(True);
421 }
422 }
423 } else if (e->xclient.message_type ==
424 xatom->getAtom(XAtom::net_number_of_desktops)) {
425 // NET_NUMBER_OF_DESKTOPS
426 BScreen *screen = searchScreen(e->xclient.window);
427
428 if (e->xclient.data.l[0] > 0)
429 screen->changeWorkspaceCount((unsigned) e->xclient.data.l[0]);
430 } else if (e->xclient.message_type ==
431 xatom->getAtom(XAtom::net_close_window)) {
432 // NET_CLOSE_WINDOW
433 BlackboxWindow *win = searchWindow(e->xclient.window);
434 if (win && win->validateClient())
435 win->close(); // could this be smarter?
436 } else if (e->xclient.message_type ==
437 xatom->getAtom(XAtom::net_wm_moveresize)) {
438 // NET_WM_MOVERESIZE
439 BlackboxWindow *win = searchWindow(e->xclient.window);
440 if (win && win->validateClient()) {
441 int x_root = e->xclient.data.l[0],
442 y_root = e->xclient.data.l[1];
443 if ((Atom) e->xclient.data.l[2] ==
444 xatom->getAtom(XAtom::net_wm_moveresize_move)) {
445 win->beginMove(x_root, y_root);
446 } else {
447 if ((Atom) e->xclient.data.l[2] ==
448 xatom->getAtom(XAtom::net_wm_moveresize_size_topleft))
449 win->beginResize(x_root, y_root, BlackboxWindow::TopLeft);
450 else if ((Atom) e->xclient.data.l[2] ==
451 xatom->getAtom(XAtom::net_wm_moveresize_size_topright))
452 win->beginResize(x_root, y_root, BlackboxWindow::TopRight);
453 else if ((Atom) e->xclient.data.l[2] ==
454 xatom->getAtom(XAtom::net_wm_moveresize_size_bottomleft))
455 win->beginResize(x_root, y_root, BlackboxWindow::BottomLeft);
456 else if ((Atom) e->xclient.data.l[2] ==
457 xatom->getAtom(XAtom::net_wm_moveresize_size_bottomright))
458 win->beginResize(x_root, y_root, BlackboxWindow::BottomRight);
459 }
460 }
461 }
462 */
463 }
464
465
466 void OBXEventHandler::handle(const XEvent &e)
467 {
468 /* mouse button events can get translated into:
469 press - button was pressed down
470 release - buttons was released
471 click - button was pressed and released on the same window
472 double click - clicked twice on the same widget in a given time and area
473
474 key events are only bindable to presses. key releases are ignored.
475
476 mouse enter/leave can be bound to for the entire window
477 */
478
479 switch (e.type) {
480
481 // These types of XEvent's can be bound to actions by the user, and so end
482 // up getting passed off to the OBBindingMapper class at some point
483 case ButtonPress:
484 buttonPress(e.xbutton);
485 break;
486 case ButtonRelease:
487 buttonRelease(e.xbutton);
488 break;
489 case KeyPress:
490 keyPress(e.xkey);
491 break;
492 case MotionNotify:
493 motion(e.xmotion);
494 break;
495 case EnterNotify:
496 enterNotify(e.xcrossing);
497 break;
498 case LeaveNotify:
499 leaveNotify(e.xcrossing);
500 break;
501
502
503 // These types of XEvent's can not be bound to actions by the user and so
504 // will simply be handled in this class
505 case ConfigureRequest:
506 configureRequest(e.xconfigurerequest);
507 break;
508
509 case MapRequest:
510 mapRequest(e.xmaprequest);
511 break;
512
513 case UnmapNotify:
514 unmapNotify(e.xunmap);
515 break;
516
517 case DestroyNotify:
518 destroyNotify(e.xdestroywindow);
519 break;
520
521 case ReparentNotify:
522 reparentNotify(e.xreparent);
523 break;
524
525 case PropertyNotify:
526 propertyNotify(e.xproperty);
527 break;
528
529 case Expose:
530 expose(e.xexpose);
531 break;
532
533 case ColormapNotify:
534 colormapNotify(e.xcolormap);
535 break;
536
537 case FocusIn:
538 focusIn(e.xfocus);
539 break;
540
541 case FocusOut:
542 focusOut(e.xfocus);
543 break;
544
545 case ClientMessage:
546 clientMessage(e.xclient);
547
548 default:
549 #ifdef SHAPE
550 if (e.type == otk::OBDisplay::shapeEventBase())
551 shapeEvent(e);
552 #endif // SHAPE
553 break;
554
555 /*
556 case ClientMessage: {
557 break;
558 }
559
560 */
561 } // switch
562 }
563
564
565 }
This page took 0.059976 seconds and 4 git commands to generate.