|  | @@ -39,7 +39,7 @@ void Mouse::setCursor( int cursor ) {
 | 
	
		
			
			| 39 | 39 |                                xcursor, CurrentTime );
 | 
	
		
			
			| 40 | 40 |  }
 | 
	
		
			
			| 41 | 41 |  
 | 
	
		
			
			| 42 |  | -Mouse::Mouse(X11* x11, bool nodecorations ) {
 | 
	
		
			
			|  | 42 | +Mouse::Mouse(X11* x11, bool nodecorations, Window ignoreWindow ) {
 | 
	
		
			
			| 43 | 43 |      this->x11 = x11;
 | 
	
		
			
			| 44 | 44 |      currentCursor = XC_cross;
 | 
	
		
			
			| 45 | 45 |      xcursor = XCreateFontCursor( x11->display, XC_cross );
 | 
	
	
		
			
			|  | @@ -47,22 +47,9 @@ Mouse::Mouse(X11* x11, bool nodecorations ) {
 | 
	
		
			
			| 47 | 47 |      XGrabPointer( x11->display, x11->root, True,
 | 
	
		
			
			| 48 | 48 |                    PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
 | 
	
		
			
			| 49 | 49 |                    GrabModeAsync, GrabModeAsync, None, xcursor, CurrentTime );
 | 
	
		
			
			| 50 |  | -
 | 
	
		
			
			| 51 |  | -    Window root;
 | 
	
		
			
			| 52 |  | -    int mx, my;
 | 
	
		
			
			| 53 |  | -    int wx, wy;
 | 
	
		
			
			| 54 |  | -    unsigned int mask;
 | 
	
		
			
			| 55 |  | -    if ( nodecorations ) {
 | 
	
		
			
			| 56 |  | -        // Get the deepest available window if we don't want decorations.
 | 
	
		
			
			| 57 |  | -        Window child = x11->root;
 | 
	
		
			
			| 58 |  | -        while( child ) {
 | 
	
		
			
			| 59 |  | -            hoverWindow = child;
 | 
	
		
			
			| 60 |  | -            XQueryPointer( x11->display, child, &root, &child, &mx, &my, &wx, &wy, &mask );
 | 
	
		
			
			| 61 |  | -        }
 | 
	
		
			
			| 62 |  | -    } else {
 | 
	
		
			
			| 63 |  | -        XQueryPointer( x11->display, x11->root, &root, &hoverWindow, &mx, &my, &wx, &wy, &mask );
 | 
	
		
			
			| 64 |  | -    }
 | 
	
		
			
			| 65 |  | -    selectAllInputs( x11->root, nodecorations );
 | 
	
		
			
			|  | 50 | +    this->nodecorations = nodecorations;
 | 
	
		
			
			|  | 51 | +    this->ignoreWindow = ignoreWindow;
 | 
	
		
			
			|  | 52 | +    hoverWindow = findWindow(x11->root);
 | 
	
		
			
			| 66 | 53 |  }
 | 
	
		
			
			| 67 | 54 |  
 | 
	
		
			
			| 68 | 55 |  Mouse::~Mouse() {
 | 
	
	
		
			
			|  | @@ -74,6 +61,13 @@ void Mouse::update() {
 | 
	
		
			
			| 74 | 61 |      while ( XCheckTypedEvent( x11->display, ButtonPress, &event ) ) {
 | 
	
		
			
			| 75 | 62 |  		setButton( event.xbutton.button, 1 );
 | 
	
		
			
			| 76 | 63 |  	}
 | 
	
		
			
			|  | 64 | +    bool findNewWindow = false;
 | 
	
		
			
			|  | 65 | +    while ( XCheckTypedEvent( x11->display, MotionNotify, &event ) ) {
 | 
	
		
			
			|  | 66 | +        findNewWindow = true;
 | 
	
		
			
			|  | 67 | +	}
 | 
	
		
			
			|  | 68 | +    if ( findNewWindow ) {
 | 
	
		
			
			|  | 69 | +        hoverWindow = findWindow(x11->root);
 | 
	
		
			
			|  | 70 | +    }
 | 
	
		
			
			| 77 | 71 |      while ( XCheckTypedEvent( x11->display, ButtonRelease, &event ) ) {
 | 
	
		
			
			| 78 | 72 |  		setButton( event.xbutton.button, 0 );
 | 
	
		
			
			| 79 | 73 |  	}
 | 
	
	
		
			
			|  | @@ -82,17 +76,36 @@ void Mouse::update() {
 | 
	
		
			
			| 82 | 76 |  	}
 | 
	
		
			
			| 83 | 77 |  }
 | 
	
		
			
			| 84 | 78 |  
 | 
	
		
			
			| 85 |  | -// This cheesy function makes sure we get all EnterNotify events on ALL the windows.
 | 
	
		
			
			| 86 |  | -void Mouse::selectAllInputs( Window win, bool nodecorations ) {
 | 
	
		
			
			|  | 79 | +Window Mouse::findWindow( Window foo ) {
 | 
	
		
			
			|  | 80 | +    glm::vec2 pos = getMousePos();
 | 
	
		
			
			| 87 | 81 |      Window root, parent;
 | 
	
		
			
			| 88 | 82 |      Window* children;
 | 
	
		
			
			| 89 | 83 |      unsigned int nchildren;
 | 
	
		
			
			| 90 |  | -    XQueryTree( x11->display, win, &root, &parent, &children, &nchildren );
 | 
	
		
			
			| 91 |  | -    for ( unsigned int i=0;i<nchildren;i++ ) {
 | 
	
		
			
			| 92 |  | -            XSelectInput( x11->display, children[ i ], EnterWindowMask );
 | 
	
		
			
			| 93 |  | -        if ( nodecorations ) {
 | 
	
		
			
			| 94 |  | -            selectAllInputs( children[i], nodecorations );
 | 
	
		
			
			|  | 84 | +    Window selectedWindow;
 | 
	
		
			
			|  | 85 | +    XQueryTree( x11->display, foo, &root, &parent, &children, &nchildren );
 | 
	
		
			
			|  | 86 | +    // The children are ordered, so we traverse backwards.
 | 
	
		
			
			|  | 87 | +    if ( !children || nchildren <= 0 ) {
 | 
	
		
			
			|  | 88 | +        return foo;
 | 
	
		
			
			|  | 89 | +    }
 | 
	
		
			
			|  | 90 | +    for( int i=nchildren-1;i>=0;i-- ) {
 | 
	
		
			
			|  | 91 | +        if ( children[i] == ignoreWindow ) {
 | 
	
		
			
			|  | 92 | +            continue;
 | 
	
		
			
			|  | 93 | +        }
 | 
	
		
			
			|  | 94 | +        glm::vec4 rect = getWindowGeometry(children[i], false);
 | 
	
		
			
			|  | 95 | +        float a = pos.x - rect.x;
 | 
	
		
			
			|  | 96 | +        float b = pos.y - rect.y;
 | 
	
		
			
			|  | 97 | +        if ( a <= rect.z && a >= 0 ) {
 | 
	
		
			
			|  | 98 | +            if ( b <= rect.w && b >= 0 ) {
 | 
	
		
			
			|  | 99 | +                selectedWindow = children[i];
 | 
	
		
			
			|  | 100 | +                if ( !nodecorations ) {
 | 
	
		
			
			|  | 101 | +                    XFree(children);
 | 
	
		
			
			|  | 102 | +                    return selectedWindow;
 | 
	
		
			
			|  | 103 | +                } else {
 | 
	
		
			
			|  | 104 | +                    XFree(children);
 | 
	
		
			
			|  | 105 | +                    return findWindow( selectedWindow );
 | 
	
		
			
			|  | 106 | +                }
 | 
	
		
			
			|  | 107 | +            }
 | 
	
		
			
			| 95 | 108 |          }
 | 
	
		
			
			| 96 | 109 |      }
 | 
	
		
			
			| 97 |  | -    free( children );
 | 
	
		
			
			|  | 110 | +    return foo;
 | 
	
		
			
			| 98 | 111 |  }
 |