]>
Dogcows Code - chaz/openbox/blob - src/xeventhandler.cc
ba60edf7e5c9e4e6e61b71585963f1b9854d9a79
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
3 #include "xeventhandler.hh"
4 #include "otk/display.hh"
10 OBXEventHandler::OBXEventHandler()
12 _lasttime
= 1; // 0 is CurrentTime, so set to minimum
15 void OBXEventHandler::buttonPress(const XButtonEvent
&e
)
22 void OBXEventHandler::buttonRelease(const XButtonEvent
&e
)
29 void OBXEventHandler::keyPress(const XKeyEvent
&e
)
35 void OBXEventHandler::motion(const XMotionEvent
&e
)
39 // the pointer is on the wrong screen
40 if (! e
.same_screen
) return;
45 void OBXEventHandler::enterNotify(const XCrossingEvent
&e
)
49 BScreen *screen = (BScreen *) 0;
50 BlackboxWindow *win = (BlackboxWindow *) 0;
52 if (e->xcrossing.mode == NotifyGrab) break;
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))) {
59 win->enterNotifyEvent(&e->xcrossing);
65 void OBXEventHandler::leaveNotify(const XCrossingEvent
&e
)
69 BlackboxWindow *win = (BlackboxWindow *) 0;
71 if ((win = searchWindow(e->xcrossing.window)))
72 win->leaveNotifyEvent(&e->xcrossing);
77 void OBXEventHandler::configureRequest(const XConfigureRequestEvent
&e
)
80 /* BlackboxWindow *win = (BlackboxWindow *) 0;
82 if ((win = searchWindow(e->xconfigurerequest.window))) {
83 win->configureRequestEvent(&e->xconfigurerequest);
85 if (validateWindow(e->xconfigurerequest.window)) {
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;
96 XConfigureWindow(otk::OBDisplay::display, e->xconfigurerequest.window,
97 e->xconfigurerequest.value_mask, &xwc);
104 void OBXEventHandler::mapRequest(const XMapRequestEvent
&e
)
107 printf("MapRequest for 0x%lx\n", e
.window
);
110 BlackboxWindow *win = searchWindow(e->xmaprequest.window);
114 if (win->isIconic()) {
118 if (win->isShaded()) {
123 if (focus && (win->isTransient() || win->getScreen()->doFocusNew()) &&
125 win->setInputFocus();
127 BScreen *screen = searchScreen(e->xmaprequest.parent);
132 we got a map request for a window who's parent isn't root. this
133 can happen in only one circumstance:
135 a client window unmapped a managed window, and then remapped it
136 somewhere between unmapping the client window and reparenting it
139 regardless of how it happens, we need to find the screen that
143 XWindowAttributes wattrib;
144 if (! XGetWindowAttributes(otk::OBDisplay::display,
145 e->xmaprequest.window,
147 // failed to get the window attributes, perhaps the window has
148 // now been destroyed?
152 screen = searchScreen(wattrib.root);
153 assert(screen != 0); // this should never happen
155 screen->manageWindow(e->xmaprequest.window);
161 void OBXEventHandler::unmapNotify(const XUnmapEvent
&e
)
165 BlackboxWindow *win = (BlackboxWindow *) 0;
166 BScreen *screen = (BScreen *) 0;
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);
177 void OBXEventHandler::destroyNotify(const XDestroyWindowEvent
&e
)
181 BlackboxWindow *win = (BlackboxWindow *) 0;
182 BScreen *screen = (BScreen *) 0;
183 BWindowGroup *group = (BWindowGroup *) 0;
185 if ((win = searchWindow(e->xdestroywindow.window))) {
186 win->destroyNotifyEvent(&e->xdestroywindow);
187 } else if ((group = searchGroup(e->xdestroywindow.window))) {
189 } else if ((screen = searchSystrayWindow(e->xunmap.window))) {
190 screen->removeSystrayWindow(e->xunmap.window);
196 void OBXEventHandler::reparentNotify(const XReparentEvent
&e
)
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.
206 BlackboxWindow *win = searchWindow(e->xreparent.window);
208 win->reparentNotifyEvent(&e->xreparent);
213 void OBXEventHandler::propertyNotify(const XPropertyEvent
&e
)
217 BlackboxWindow *win = (BlackboxWindow *) 0;
218 BScreen *screen = (BScreen *) 0;
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);
228 void OBXEventHandler::expose(const XExposeEvent
&first
)
230 // compress expose events
231 XEvent e
; e
.xexpose
= first
;
233 otk::Rect
area(e
.xexpose
.x
, e
.xexpose
.y
, e
.xexpose
.width
,
235 while (XCheckTypedWindowEvent(otk::OBDisplay::display
,
236 e
.xexpose
.window
, Expose
, &e
)) {
239 area
|= otk::Rect(e
.xexpose
.x
, e
.xexpose
.y
, e
.xexpose
.width
,
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();
250 BlackboxWindow *win = (BlackboxWindow *) 0;
252 if ((win = searchWindow(e->xexpose.window)))
253 win->exposeEvent(&e->xexpose);
258 void OBXEventHandler::colormapNotify(const XColormapEvent
&e
)
262 BScreen *screen = searchScreen(e->xcolormap.window);
264 screen->setRootColormapInstalled((e->xcolormap.state ==
265 ColormapInstalled) ? True : False);
270 void OBXEventHandler::focusIn(const XFocusChangeEvent
&e
)
272 if (e
.detail
!= NotifyNonlinear
&&
273 e
.detail
!= NotifyAncestor
) {
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)
284 BlackboxWindow *win = searchWindow(e.window);
286 if (! win->isFocused())
287 win->setFocusFlag(True);
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.
295 e->xfocus.window = None;
297 no_focus = False; // focusing is back on
303 void OBXEventHandler::focusOut(const XFocusChangeEvent
&e
)
305 if (e
.detail
!= NotifyNonlinear
) {
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)
315 BlackboxWindow *win = searchWindow(e->xfocus.window);
316 if (win && win->isFocused()) {
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
325 // don't check the current focus if FocusOut was generated during a grab
326 bool check_focus = (e->xfocus.mode == NotifyNormal);
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).
335 if (XCheckTypedEvent(otk::OBDisplay::display, FocusIn, &event)) {
337 process_event(&event);
338 if (event.xfocus.window == None) {
347 Second, we query the X server for the current input focus.
348 to make sure that we keep a consistent state.
351 BlackboxWindow *focus;
354 XGetInputFocus(otk::OBDisplay::display, &w, &revert);
355 focus = searchWindow(w);
359 focus got from "win" to "focus" under some very strange
360 circumstances, and we need to make sure that the focus indication
364 setFocusedWindow(focus);
366 // we have no idea where focus went... so we set it to somewhere
376 void OBXEventHandler::shapeEvent(const XShapeEvent
&e
)
378 XShapeEvent
*shape_event
= (XShapeEvent
*) e
;
379 BlackboxWindow
*win
= searchWindow(e
->xany
.window
);
381 if (win
&& shape_event
->kind
== ShapeBounding
)
382 win
->shapeEvent(shape_event
);
387 void OBXEventHandler::clientMessage(const XClientMessageEvent
&e
)
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);
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)) {
405 BlackboxWindow *win = searchWindow(e->xclient.window);
408 BScreen *screen = win->getScreen();
411 win->deiconify(False, False);
412 if (! win->isStuck() &&
413 (win->getWorkspaceNumber() != screen->getCurrentWorkspaceID())) {
415 screen->changeWorkspaceID(win->getWorkspaceNumber());
417 if (win->isVisible() && win->setInputFocus()) {
418 win->getScreen()->getWorkspace(win->getWorkspaceNumber())->
420 win->installColormap(True);
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);
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)) {
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)) {
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);
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);
466 void OBXEventHandler::handle(const XEvent
&e
)
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
474 key events are only bindable to presses. key releases are ignored.
476 mouse enter/leave can be bound to for the entire window
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
484 buttonPress(e
.xbutton
);
487 buttonRelease(e
.xbutton
);
496 enterNotify(e
.xcrossing
);
499 leaveNotify(e
.xcrossing
);
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
);
510 mapRequest(e
.xmaprequest
);
514 unmapNotify(e
.xunmap
);
518 destroyNotify(e
.xdestroywindow
);
522 reparentNotify(e
.xreparent
);
526 propertyNotify(e
.xproperty
);
534 colormapNotify(e
.xcolormap
);
546 clientMessage(e
.xclient
);
550 if (e
.type
== otk::OBDisplay::shapeEventBase())
556 case ClientMessage: {
This page took 0.057488 seconds and 4 git commands to generate.