]>
Dogcows Code - chaz/openbox/blob - src/xeventhandler.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
3 #include "xeventhandler.hh"
6 #include "otk/display.hh"
12 OBXEventHandler::OBXEventHandler()
14 _lasttime
= 1; // 0 is CurrentTime, so set to minimum
17 void OBXEventHandler::buttonPress(const XButtonEvent
&e
)
24 void OBXEventHandler::buttonRelease(const XButtonEvent
&e
)
31 void OBXEventHandler::keyPress(const XKeyEvent
&e
)
37 void OBXEventHandler::motion(const XMotionEvent
&e
)
41 // the pointer is on the wrong screen
42 if (! e
.same_screen
) return;
47 void OBXEventHandler::enterNotify(const XCrossingEvent
&e
)
51 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
55 BScreen *screen = (BScreen *) 0;
56 BlackboxWindow *win = (BlackboxWindow *) 0;
58 if (e->xcrossing.mode == NotifyGrab) break;
60 if ((e->xcrossing.window == e->xcrossing.root) &&
61 (screen = searchScreen(e->xcrossing.window))) {
62 screen->getImageControl()->installRootColormap();
63 } else if ((win = searchWindow(e->xcrossing.window))) {
65 win->enterNotifyEvent(&e->xcrossing);
71 void OBXEventHandler::leaveNotify(const XCrossingEvent
&e
)
75 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
79 BlackboxWindow *win = (BlackboxWindow *) 0;
81 if ((win = searchWindow(e->xcrossing.window)))
82 win->leaveNotifyEvent(&e->xcrossing);
87 void OBXEventHandler::configureRequest(const XConfigureRequestEvent
&e
)
89 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
92 /* BlackboxWindow *win = (BlackboxWindow *) 0;
94 if ((win = searchWindow(e->xconfigurerequest.window))) {
95 win->configureRequestEvent(&e->xconfigurerequest);
97 if (validateWindow(e->xconfigurerequest.window)) {
100 xwc.x = e->xconfigurerequest.x;
101 xwc.y = e->xconfigurerequest.y;
102 xwc.width = e->xconfigurerequest.width;
103 xwc.height = e->xconfigurerequest.height;
104 xwc.border_width = e->xconfigurerequest.border_width;
105 xwc.sibling = e->xconfigurerequest.above;
106 xwc.stack_mode = e->xconfigurerequest.detail;
108 XConfigureWindow(otk::OBDisplay::display, e->xconfigurerequest.window,
109 e->xconfigurerequest.value_mask, &xwc);
116 void OBXEventHandler::mapRequest(const XMapRequestEvent
&e
)
119 printf("MapRequest for 0x%lx\n", e
.window
);
122 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
125 // XXX: uniconify and/or unshade the window
127 // XXX: manage the window, i.e. grab events n shit
128 Openbox::instance
->addClient(e
.window
, new OBClient(e
.window
));
132 BlackboxWindow *win = searchWindow(e->xmaprequest.window);
136 if (win->isIconic()) {
140 if (win->isShaded()) {
145 if (focus && (win->isTransient() || win->getScreen()->doFocusNew()) &&
147 win->setInputFocus();
149 BScreen *screen = searchScreen(e->xmaprequest.parent);
154 we got a map request for a window who's parent isn't root. this
155 can happen in only one circumstance:
157 a client window unmapped a managed window, and then remapped it
158 somewhere between unmapping the client window and reparenting it
161 regardless of how it happens, we need to find the screen that
165 XWindowAttributes wattrib;
166 if (! XGetWindowAttributes(otk::OBDisplay::display,
167 e->xmaprequest.window,
169 // failed to get the window attributes, perhaps the window has
170 // now been destroyed?
174 screen = searchScreen(wattrib.root);
175 assert(screen != 0); // this should never happen
177 screen->manageWindow(e->xmaprequest.window);
183 void OBXEventHandler::unmapNotify(const XUnmapEvent
&e
)
185 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
188 // XXX: unmanage the window, i.e. ungrab events n reparent n shit
189 Openbox::instance
->removeClient(e
.window
);
193 void OBXEventHandler::destroyNotify(const XDestroyWindowEvent
&e
)
195 // XXX: window group leaders can come through here too!
197 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
200 // XXX: unmanage the window, i.e. ungrab events n reparent n shit
201 Openbox::instance
->removeClient(e
.window
);
205 void OBXEventHandler::reparentNotify(const XReparentEvent
&e
)
208 this event is quite rare and is usually handled in unmapNotify
209 however, if the window is unmapped when the reparent event occurs
210 the window manager never sees it because an unmap event is not sent
211 to an already unmapped window.
213 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
217 BlackboxWindow *win = searchWindow(e->xreparent.window);
219 win->reparentNotifyEvent(&e->xreparent);
224 void OBXEventHandler::propertyNotify(const XPropertyEvent
&e
)
228 OBClient
*client
= Openbox::instance
->findClient(e
.window
);
235 void OBXEventHandler::expose(const XExposeEvent
&first
)
237 OBClient
*client
= Openbox::instance
->findClient(first
.window
);
240 // compress expose events
241 XEvent e
; e
.xexpose
= first
;
243 otk::Rect
area(e
.xexpose
.x
, e
.xexpose
.y
, e
.xexpose
.width
,
245 while (XCheckTypedWindowEvent(otk::OBDisplay::display
,
246 e
.xexpose
.window
, Expose
, &e
)) {
249 area
|= otk::Rect(e
.xexpose
.x
, e
.xexpose
.y
, e
.xexpose
.width
,
253 // use the merged area
254 e
.xexpose
.x
= area
.x();
255 e
.xexpose
.y
= area
.y();
256 e
.xexpose
.width
= area
.width();
257 e
.xexpose
.height
= area
.height();
260 // XXX: make the decorations redraw!
264 void OBXEventHandler::colormapNotify(const XColormapEvent
&e
)
268 BScreen *screen = searchScreen(e->xcolormap.window);
270 screen->setRootColormapInstalled((e->xcolormap.state ==
271 ColormapInstalled) ? True : False);
276 void OBXEventHandler::focusIn(const XFocusChangeEvent
&e
)
278 if (e
.detail
!= NotifyNonlinear
&&
279 e
.detail
!= NotifyAncestor
) {
281 don't process FocusIns when:
282 1. the new focus window isn't an ancestor or inferior of the old
283 focus window (NotifyNonlinear)
284 make sure to allow the FocusIn when the old focus window was an
285 ancestor but didn't have a parent, such as root (NotifyAncestor)
290 BlackboxWindow *win = searchWindow(e.window);
292 if (! win->isFocused())
293 win->setFocusFlag(True);
296 set the event window to None. when the FocusOut event handler calls
297 this function recursively, it uses this as an indication that focus
298 has moved to a known window.
301 e->xfocus.window = None;
303 no_focus = False; // focusing is back on
309 void OBXEventHandler::focusOut(const XFocusChangeEvent
&e
)
311 if (e
.detail
!= NotifyNonlinear
) {
313 don't process FocusOuts when:
314 2. the new focus window isn't an ancestor or inferior of the old
315 focus window (NotifyNonlinear)
321 BlackboxWindow *win = searchWindow(e->xfocus.window);
322 if (win && win->isFocused()) {
325 before we mark "win" as unfocused, we need to verify that focus is
326 going to a known location, is in a known location, or set focus
331 // don't check the current focus if FocusOut was generated during a grab
332 bool check_focus = (e->xfocus.mode == NotifyNormal);
335 First, check if there is a pending FocusIn event waiting. if there
336 is, process it and determine if focus has moved to another window
337 (the FocusIn event handler sets the window in the event
338 structure to None to indicate this).
341 if (XCheckTypedEvent(otk::OBDisplay::display, FocusIn, &event)) {
343 process_event(&event);
344 if (event.xfocus.window == None) {
353 Second, we query the X server for the current input focus.
354 to make sure that we keep a consistent state.
357 BlackboxWindow *focus;
360 XGetInputFocus(otk::OBDisplay::display, &w, &revert);
361 focus = searchWindow(w);
365 focus got from "win" to "focus" under some very strange
366 circumstances, and we need to make sure that the focus indication
370 setFocusedWindow(focus);
372 // we have no idea where focus went... so we set it to somewhere
382 void OBXEventHandler::shapeEvent(const XShapeEvent
&e
)
384 XShapeEvent
*shape_event
= (XShapeEvent
*) e
;
385 BlackboxWindow
*win
= searchWindow(e
->xany
.window
);
387 if (win
&& shape_event
->kind
== ShapeBounding
)
388 win
->shapeEvent(shape_event
);
393 void OBXEventHandler::clientMessage(const XClientMessageEvent
&e
)
398 } else if (e->xclient.message_type ==
399 xatom->getAtom(XAtom::blackbox_change_workspace) ||
400 e->xclient.message_type ==
401 xatom->getAtom(XAtom::net_current_desktop)) {
402 // NET_CURRENT_DESKTOP message
403 BScreen *screen = searchScreen(e->xclient.window);
405 unsigned int workspace = e->xclient.data.l[0];
406 if (screen && workspace < screen->getWorkspaceCount())
407 screen->changeWorkspaceID(workspace);
408 } else if (e->xclient.message_type ==
409 xatom->getAtom(XAtom::net_active_window)) {
411 BlackboxWindow *win = searchWindow(e->xclient.window);
414 BScreen *screen = win->getScreen();
417 win->deiconify(False, False);
418 if (! win->isStuck() &&
419 (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID())) {
421 screen->changeWorkspaceID(win->getWorkspaceNumber());
423 if (win->isVisible() && win->setInputFocus()) {
424 win->getScreen()->getWorkspace(win->getWorkspaceNumber())->
426 win->installColormap(True);
429 } else if (e->xclient.message_type ==
430 xatom->getAtom(XAtom::net_number_of_desktops)) {
431 // NET_NUMBER_OF_DESKTOPS
432 BScreen *screen = searchScreen(e->xclient.window);
434 if (e->xclient.data.l[0] > 0)
435 screen->changeWorkspaceCount((unsigned) e->xclient.data.l[0]);
436 } else if (e->xclient.message_type ==
437 xatom->getAtom(XAtom::net_close_window)) {
439 BlackboxWindow *win = searchWindow(e->xclient.window);
440 if (win && win->validateClient())
441 win->close(); // could this be smarter?
442 } else if (e->xclient.message_type ==
443 xatom->getAtom(XAtom::net_wm_moveresize)) {
445 BlackboxWindow *win = searchWindow(e->xclient.window);
446 if (win && win->validateClient()) {
447 int x_root = e->xclient.data.l[0],
448 y_root = e->xclient.data.l[1];
449 if ((Atom) e->xclient.data.l[2] ==
450 xatom->getAtom(XAtom::net_wm_moveresize_move)) {
451 win->beginMove(x_root, y_root);
453 if ((Atom) e->xclient.data.l[2] ==
454 xatom->getAtom(XAtom::net_wm_moveresize_size_topleft))
455 win->beginResize(x_root, y_root, BlackboxWindow::TopLeft);
456 else if ((Atom) e->xclient.data.l[2] ==
457 xatom->getAtom(XAtom::net_wm_moveresize_size_topright))
458 win->beginResize(x_root, y_root, BlackboxWindow::TopRight);
459 else if ((Atom) e->xclient.data.l[2] ==
460 xatom->getAtom(XAtom::net_wm_moveresize_size_bottomleft))
461 win->beginResize(x_root, y_root, BlackboxWindow::BottomLeft);
462 else if ((Atom) e->xclient.data.l[2] ==
463 xatom->getAtom(XAtom::net_wm_moveresize_size_bottomright))
464 win->beginResize(x_root, y_root, BlackboxWindow::BottomRight);
472 void OBXEventHandler::handle(const XEvent
&e
)
474 /* mouse button events can get translated into:
475 press - button was pressed down
476 release - buttons was released
477 click - button was pressed and released on the same window
478 double click - clicked twice on the same widget in a given time and area
480 key events are only bindable to presses. key releases are ignored.
482 mouse enter/leave can be bound to for the entire window
487 // These types of XEvent's can be bound to actions by the user, and so end
488 // up getting passed off to the OBBindingMapper class at some point
490 buttonPress(e
.xbutton
);
493 buttonRelease(e
.xbutton
);
502 enterNotify(e
.xcrossing
);
505 leaveNotify(e
.xcrossing
);
509 // These types of XEvent's can not be bound to actions by the user and so
510 // will simply be handled in this class
511 case ConfigureRequest
:
512 configureRequest(e
.xconfigurerequest
);
516 mapRequest(e
.xmaprequest
);
520 unmapNotify(e
.xunmap
);
524 destroyNotify(e
.xdestroywindow
);
528 reparentNotify(e
.xreparent
);
532 propertyNotify(e
.xproperty
);
540 colormapNotify(e
.xcolormap
);
552 clientMessage(e
.xclient
);
556 if (e
.type
== otk::OBDisplay::shapeEventBase())
562 case ClientMessage: {
This page took 0.05749 seconds and 4 git commands to generate.