bool MapRequestHandler::processEvent(XEvent* event) {
    Window windowID = event->xmaprequest.window;
    qDebug() << "[+] MapRequest event 0x" << hex << windowID;

    // Si la ventana es un cliente
    if(this->wl->existClient(windowID)) {
        qDebug() << "\tLa ventana es un cliente";
        XWindow* xwindow = this->wl->getXWindowByClientID(windowID);

        // Si el cliente bypassea el WM
        if(xwindow->bypassWM()) {
            qDebug() << "\tEl cliente bypassea el WM";
            return false;

        // Si no lo bypassea
        } else {

            // Si la ventana se mapea por primera vez
            if(xwindow->getState() == WithdrawnState) {
                qDebug() << "\tEl cliente se mapea por primera vez";

                if(xwindow->needFrame()) {
                    qDebug() << "\tAñadiendo un marco al cliente";
                    xwindow->addFrame();

                    // No hace falta añadir el cliente a la lista por que ya se
                    // añadió en CreateNotifyHandler

                    qDebug() << "\tAñadiendo el marco (0x" << hex
                             << xwindow->getFrameID() << ") a la lista";
                    wl->addFrame(xwindow->getFrameID(), xwindow);
                } else
                    qDebug() << "\tEl cliente no necesita marco";

                qDebug() << "\tMapeando la ventana";
                xwindow->setState(NormalState);

                qDebug() << "\tAñadiendo la ventana de la lista del EWMH";
                this->wl->addToManagedWindows(xwindow);

                qDebug() << "\tActualizando la ventana activa";
                this->wl->setActiveWindow(this->wl->getTopWindow());
            }

            return true;
        }

    // Si la ventana es un marco
    } else if(this->wl->existFrame(windowID)) {
        qDebug() << "\tLa ventana es un marco";
        return false;

    // Si no se ni un marco ni un cliente
    } else {
        qDebug() << "\tLa ventana no es ni un cliente ni un marco";
        return false;
    }

}
bool ClientMessageHandler::processEvent(XEvent* event) {
    Window windowID = event->xclient.window;
    qDebug() << "[+] ClientMessage event 0x" << hex << windowID;
    AtomList* al = AtomList::getInstance();

    qDebug() << "\tPropiedad a cambiar: " << XGetAtomName(
            QX11Info::display(), event->xclient.message_type);

    // Si la ventana es un cliente
    if(this->wl->existClient(windowID)) {
        qDebug() << "\tLa ventana es un cliente";
        XWindow* xwindow = this->wl->getXWindowByClientID(windowID);

        //----------------------------------------------------------------------

        // ICCCM

        if(event->xclient.message_type == al->getAtom("WM_CHANGE_STATE")
                        && event->xclient.format == 32
                        && event->xclient.data.l[0] == IconicState) {
                    qDebug() << "\tSe solicita minimizar el cliente";
                    xwindow->setState(IconicState);
                    return true;


        //----------------------------------------------------------------------

        // EWMH

        } else if(event->xclient.message_type
                == al->getAtom("_NET_ACTIVE_WINDOW")) {
            EWMHRoot ewmh;
            ewmh.receivedActiveWindow(this->wl, xwindow);

        } else if(event->xclient.message_type
                == al->getAtom("_NET_CLOSE_WINDOW")) {
            EWMHRoot ewmh;
            ewmh.receivedCloseWindow(xwindow);
        }


        // TODO Se debería recibir _NET_WM_USER_TIME para poder hacer activas
        //      las ventanas al clickar en cualquier parte, no solo en el marco,
        //      pero no se recibe :(

        return false;

    // Si la ventana es un marco
    } else if(wl->existFrame(windowID)) {
        qDebug() << "\tLa ventana es un marco";

        // XdndLeave
        // XdndEnter
        // XdndPosition

        return false;

    // Si no es ni un marco ni un cliente
    } else {
        qDebug() << "\tLa ventana no es ni un cliente ni un marco";

        // _NET_SHOWING_DESKTOP

        return false;
    }
}